am 6d73a98d: AI 149478: Reorganized the PDK TOC.   Added Dalvik content to TOC.

Merge commit '6d73a98d6df871fbd7f19af61d84a2eb1d993b4b' into donut

* commit '6d73a98d6df871fbd7f19af61d84a2eb1d993b4b':
  AI 149478: Reorganized the PDK TOC.
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..452fd81
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+*~
+*.bak
+*.pyc
+Thumbs.db
+
diff --git a/apps/Development/res/layout/radio_issue.xml b/apps/Development/res/layout/radio_issue.xml
deleted file mode 100644
index b13b6bb..0000000
--- a/apps/Development/res/layout/radio_issue.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<!--
-**
-** 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.
-*/
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent" android:layout_height="fill_parent"
-    android:orientation="vertical">
-
-    <LinearLayout
-        android:layout_width="fill_parent" android:layout_height="wrap_content"
-        android:orientation="horizontal">
-
-        <Button android:id="@+id/submit" 
-            android:textSize="14sp" 
-            android:layout_marginTop="8dip"
-            android:layout_width="wrap_content" android:layout_height="wrap_content" 
-            android:text="@string/radio_issue_submit_text"
-            />	         
-        <TextView android:id="@+id/instructions"
-            android:textSize="14sp" 
-            android:layout_marginTop="10dip"
-            android:layout_marginLeft="4dip"
-            android:layout_width="wrap_content" android:layout_height="wrap_content" 
-            android:text="@string/radio_issue_instructions_text"
-            />
-
-    </LinearLayout>
-
-    <EditText android:id="@+id/report_text"
-        android:layout_width="fill_parent"
-        android:layout_height="fill_parent"
-        android:textSize="14sp"
-        />
-
-</LinearLayout>
diff --git a/apps/Development/res/values/strings.xml b/apps/Development/res/values/strings.xml
index 74f411d..5c3c953 100644
--- a/apps/Development/res/values/strings.xml
+++ b/apps/Development/res/values/strings.xml
@@ -91,9 +91,6 @@
     <string name="monkey_screen_start_text">Start</string>
     <string name="monkey_screen_initial_activity_label">Initial Activity: </string>
 
-    <string name="radio_issue_submit_text">Submit report</string>
-    <string name="radio_issue_instructions_text">Enter a description of the issue.</string>
-
     <string name="show_activity_clear_on_background_label">Clear on Background</string>
     <string name="show_activity_task_affinity_label">Task Affinity</string>
     <string name="show_activity_process_label">Process</string>
diff --git a/apps/Development/src/com/android/development/RadioIssueReport.java b/apps/Development/src/com/android/development/RadioIssueReport.java
deleted file mode 100644
index b1a95f4..0000000
--- a/apps/Development/src/com/android/development/RadioIssueReport.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-
-package com.android.development;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.os.SystemProperties;
-import android.provider.Checkin;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
-import android.telephony.ServiceState;
-import android.text.format.DateFormat;
-import static com.android.internal.util.CharSequences.forAsciiBytes;
-import android.util.Log;
-import android.view.View.OnClickListener;
-import android.view.View;
-import android.widget.Button;
-import android.widget.EditText;
-
-import com.google.android.collect.Maps;
-
-import java.io.DataInputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.net.Socket;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.Map;
-
-/**
- * Report radio issues to the StatisticsService.
- */
-public class RadioIssueReport extends Activity
-{
-    private static final String TAG = "RadioIssue";
-    private static final int HEADER_SIZE = 24;
-    private static final String RADIO_BUFFER_OPTIONS = "-b radio\n-d\n";
-
-    /** List of system properties to snapshot. */
-    private static String[] SYSTEM_PROPERTIES = {
-        "net.gsm.radio-reset",
-        "net.gsm.attempt-gprs",
-        "net.gsm.succeed-gprs",
-        "net.gsm.disconnect",
-        "net.ppp.sent",
-        "net.ppp.received",
-        "gsm.version.baseband",
-        "gsm.version.ril-impl",
-    };
-
-    private Button          mSubmitButton;
-    private EditText        mReportText;
-    private ServiceState mServiceState;
-    private Phone.State     mPhoneState;
-    private int             mSignalStrength;
-    private Phone.DataState mDataState;
-    private String          mRadioLog;
-
-    /** Snapshot of interesting variables relevant to the radio. */
-    private Map<String, String> mRadioState;
-
-    @Override
-    public void
-    onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        setContentView(R.layout.radio_issue);
-
-        initSubmitButton();
-        initReportText();
-
-        mRadioState = snapState();
-    }
-
-    /**
-     * @return a snapshot of phone state variables to report.
-     */
-    private static Map<String, String> snapState() {
-        Map<String, String> state = Maps.newHashMap();
-
-        // Capture a bunch of system properties
-        for (String property: SYSTEM_PROPERTIES) {
-            String value = SystemProperties.get(property);
-            state.put(property, SystemProperties.get(property));
-        }
-
-        Phone phone = PhoneFactory.getDefaultPhone();
-        state.put("phone-data", phone.getDataConnectionState().toString());
-        state.put("phone-service", phone.getServiceState().toString());
-        state.put("phone-signal", String.valueOf(phone.getSignalStrengthASU()));
-        state.put("phone-state", phone.getState().toString());
-
-        try {
-            state.put("radio-log", getRadioLog());
-        } catch (IOException e) {
-            Log.e(TAG, "Error reading radio log", e);
-        }
-
-        return state;
-    }
-
-    private void initSubmitButton() {
-        mSubmitButton = (Button) findViewById(R.id.submit);
-        mSubmitButton.setOnClickListener(mSubmitButtonHandler);
-    }
-
-    private void initReportText() {
-        mReportText = (EditText) findViewById(R.id.report_text);
-        mReportText.requestFocus();
-    }
-
-    OnClickListener mSubmitButtonHandler = new OnClickListener() {
-        public void onClick(View v) {
-            // Include the user-supplied report text.
-            mRadioState.put("user-report", mReportText.getText().toString());
-
-            // Dump the state variables directly into the report.
-            Checkin.logEvent(getContentResolver(),
-                    Checkin.Events.Tag.RADIO_BUG_REPORT,
-                    mRadioState.toString());
-
-            finish();
-        }
-    };
-
-    // Largely stolen from LogViewer.java
-    private static String getRadioLog() throws IOException {
-        Socket sock = new Socket("127.0.0.1", 5040);
-        DataInputStream in = new DataInputStream(sock.getInputStream());
-        StringBuilder log = new StringBuilder();
-
-        // Set options
-        sock.getOutputStream().write(RADIO_BUFFER_OPTIONS.getBytes());
-        sock.getOutputStream().write('\n');
-        sock.getOutputStream().write('\n');
-
-        // Read in the log
-        try {
-            Calendar cal = new GregorianCalendar();
-
-            while (true) {
-                int length = in.readInt();
-                long when = (long)in.readInt();
-                byte[] bytes = new byte[length-4];
-                in.readFully(bytes);
-
-                int tagEnd = next0(bytes, HEADER_SIZE-4);
-                int fileEnd = next0(bytes, tagEnd + 1);
-                int messageEnd = next0(bytes, fileEnd + 1);
-
-                CharSequence tag
-                        = forAsciiBytes(bytes, HEADER_SIZE-4, tagEnd);
-                CharSequence message
-                        = forAsciiBytes(bytes, fileEnd + 1, messageEnd);
-
-                cal.setTimeInMillis(when*1000);
-                log.append(DateFormat.format("MM-dd kk:mm:ss ", cal));
-                log.append(tag)
-                   .append(": ")
-                   .append(message)
-                   .append("\n");
-            }
-        } catch (EOFException e) {
-            Log.d(TAG, "reached end of stream");
-        }
-
-        return log.toString();
-    }
-
-    private static int next0(byte[] bytes, int start) {
-        for (int current = start; current < bytes.length; current++) {
-            if (bytes[current] == 0)
-                return current;
-        }
-        return bytes.length;
-    }
-}
diff --git a/apps/Fallback/res/values-es-rUS/strings.xml b/apps/Fallback/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..0ce5751
--- /dev/null
+++ b/apps/Fallback/res/values-es-rUS/strings.xml
@@ -0,0 +1,21 @@
+<?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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="appTitle">"Fallback"</string>
+    <string name="title">"Acción no admitida"</string>
+    <string name="error">"Esa acción no se admite actualmente."</string>
+</resources>
diff --git a/apps/SdkSetup/src/com/android/sdksetup/DefaultActivity.java b/apps/SdkSetup/src/com/android/sdksetup/DefaultActivity.java
index db6385c..56f43a4 100644
--- a/apps/SdkSetup/src/com/android/sdksetup/DefaultActivity.java
+++ b/apps/SdkSetup/src/com/android/sdksetup/DefaultActivity.java
@@ -38,9 +38,7 @@
 
         // Enable the GPS.
         // Not needed since this SDK will contain the Settings app.
-        LocationManager locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
         Settings.Secure.putString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED, LocationManager.GPS_PROVIDER);
-        locationManager.updateProviders();
         
         // enable install from non market
         Settings.Secure.putInt(getContentResolver(), Settings.Secure.INSTALL_NON_MARKET_APPS, 1);
diff --git a/build/sdk.atree b/build/sdk.atree
index b34a82a..bd5fabe 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -118,6 +118,7 @@
 # sdkmanager
 bin/android tools/android
 framework/sdklib.jar tools/lib/sdklib.jar
+framework/sdkuilib.jar tools/lib/sdkuilib.jar
 framework/sdkmanager.jar tools/lib/sdkmanager.jar
 
 # emulator
diff --git a/build/tools/make_windows_sdk.sh b/build/tools/make_windows_sdk.sh
index de26705..0ce9caa 100755
--- a/build/tools/make_windows_sdk.sh
+++ b/build/tools/make_windows_sdk.sh
@@ -13,8 +13,12 @@
 # will make some rm/mv commands to fail.
 FORCE="1" 
 
+PROG_NAME="$0"
 SDK_ZIP="$1"
 DIST_DIR="$2"
+TEMP_DIR="$3"
+[ -z "$TEMP_DIR" ] && TEMP_DIR=${TMP:-/tmp}
+
 
 function die() {
   echo "Error:" $*
@@ -22,9 +26,23 @@
   exit 1
 }
 
+function usage() {
+  echo "Usage: ${PROG_NAME} linux_or_mac_sdk.zip output_dir [temp_dir]"
+  echo "If temp_dir is not given, \$TMP is used. If that's missing, /tmp is used."
+  status
+  exit 2
+}
+
+function status() {
+  echo "Current values:"
+  echo "- Input  SDK: ${SDK_ZIP:-missing}"
+  echo "- Output dir: ${DIST_DIR:-missing}"
+  echo "- Temp   dir: ${TEMP_DIR:-missing}"
+}
+
 function check() {
-    [ -f "$SDK_ZIP" ] || die "Pass the path of an existing Linux/Darwin SDK .zip as first parameter"
-    [ -d "$DIST_DIR" ] || die "Pass the output directory as second parameter"
+    [ -f "$SDK_ZIP" ] || usage
+    [ -d "$DIST_DIR" ] || usage
 
     # Use the BUILD_ID as SDK_NUMBER if defined, otherwise try to get it from the
     # provided zip filename.
@@ -72,21 +90,22 @@
     echo
     echo "Packaging..."
     DEST_NAME="android-sdk_${SDK_NUMBER}_windows"
-    DEST="$DIST_DIR/$DEST_NAME"
     DEST_NAME_ZIP="${DEST_NAME}.zip"
 
+    TEMP_SDK_DIR="$TEMP_DIR/$DEST_NAME"
+
     # Unzip current linux/mac SDK and rename using the windows name
-    if [[ -n "$FORCE" || ! -d "$DEST" ]]; then
-        [ -e "$DEST" ] && rm -rfv "$DEST"  # cleanup dest first if exists
+    if [[ -n "$FORCE" || ! -d "$TEMP_SDK_DIR" ]]; then
+        [ -e "$TEMP_SDK_DIR" ] && rm -rfv "$TEMP_SDK_DIR"  # cleanup dest first if exists
         UNZIPPED=`basename "$SDK_ZIP"`
-        UNZIPPED="$DIST_DIR/${UNZIPPED/.zip/}"
+        UNZIPPED="$TEMP_DIR/${UNZIPPED/.zip/}"
         [ -e "$UNZIPPED" ] && rm -rfv "$UNZIPPED"  # cleanup unzip dir (if exists)
-        unzip "$SDK_ZIP" -d "$DIST_DIR"
-        mv -v "$UNZIPPED" "$DEST"
+        unzip "$SDK_ZIP" -d "$TEMP_DIR"
+        mv -v "$UNZIPPED" "$TEMP_SDK_DIR"
     fi
     
     # Assert that the package contains only one platform
-    PLATFORMS="$DEST/platforms"
+    PLATFORMS="$TEMP_SDK_DIR/platforms"
     THE_PLATFORM=`echo $PLATFORMS/*`
     PLATFORM_TOOLS=$THE_PLATFORM/tools
     echo "Platform found: " $THE_PLATFORM
@@ -97,23 +116,24 @@
 
 
     # USB Driver for ADB
-    mkdir -pv $DEST/usb_driver/x86
-    cp -rv development/host/windows/prebuilt/usb/driver/* $DEST/usb_driver/x86/
-    mkdir -pv $DEST/usb_driver/amd64
-    cp -rv development/host/windows/prebuilt/usb/driver_amd_64/* $DEST/usb_driver/amd64/
+    mkdir -pv $TEMP_SDK_DIR/usb_driver/x86
+    cp -rv development/host/windows/prebuilt/usb/driver/* $TEMP_SDK_DIR/usb_driver/x86/
+    mkdir -pv $TEMP_SDK_DIR/usb_driver/x86_64
+    cp -rv development/host/windows/prebuilt/usb/driver_amd_64/* $TEMP_SDK_DIR/usb_driver/x86_64/
 
     # Remove obsolete stuff from tools & platform
-    TOOLS="$DEST/tools"
-    LIB="$DEST/tools/lib"
-    rm -v "$TOOLS"/{adb,emulator,traceview,draw9patch,hierarchyviewer,apkbuilder,ddms,dmtracedump,hprof-conv,mksdcard,sqlite3,android}
-    rm -v --force "$LIB"/*.so "$LIB"/*.jnilib
-    rm -v "$PLATFORM_TOOLS"/{aapt,aidl,dx,dexdump}
+    TOOLS="$TEMP_SDK_DIR/tools"
+    LIB="$TEMP_SDK_DIR/tools/lib"
+    rm -v "$TOOLS"/{adb,android,apkbuilder,ddms,dmtracedump,draw9patch,emulator}
+    rm -v "$TOOLS"/{hierarchyviewer,hprof-conv,mksdcard,sqlite3,traceview}
+    rm -vf "$LIB"/*.so "$LIB"/*.jnilib
+    rm -v  "$PLATFORM_TOOLS"/{aapt,aidl,dx,dexdump}
 
 
     # Copy all the new stuff in tools
     # Note: some tools are first copied here and then moved in platforms/<name>/tools/
     cp -v out/host/windows-x86/bin/*.{exe,dll} "$TOOLS"
-    cp -v prebuilt/windows/swt/*.{jar,dll} "$LIB"
+    cp -v prebuilt/windows/swt/*.{jar,dll}     "$LIB"
 
     # If you want the emulator NOTICE in the tools dir, uncomment the following line:
     # cp -v external/qemu/NOTICE "$TOOLS"/emulator_NOTICE.txt
@@ -134,7 +154,7 @@
     JETCREATOR="$JET/JetCreator"
     JETDEMOCONTENT="$JET/demo_content"
     JETLOGICTEMPLATES="$JET/logic_templates"
-    JETDOC="$DEST/docs/JetCreator"
+    JETDOC="$TEMP_SDK_DIR/docs/JetCreator"
 
     # need to rm these folders since a Mac SDK will have them and it might create a conflict
     rm -rfv "$JET"
@@ -162,14 +182,18 @@
 
     # Fix EOL chars to make window users happy - fix all files at the top level only
     # as well as all batch files including those in platforms/<name>/tools/
-    find "$DIST_DIR" -maxdepth 1 -type f -writable -print0 | xargs -0 unix2dos -D
-    find "$DIST_DIR" -maxdepth 3 -name "*.bat" -type f -writable -print0 | xargs -0 unix2dos -D
+    find "$TEMP_SDK_DIR" -maxdepth 1 -type f -writable -print0 | xargs -0 unix2dos -D
+    find "$TEMP_SDK_DIR" -maxdepth 3 -name "*.bat" -type f -writable -print0 | xargs -0 unix2dos -D
 
-    # Done.. Zip it
-    pushd "$DIST_DIR" > /dev/null
+    # Done.. Zip it. Clean the temp folder ONLY if the zip worked (to easy debugging)
+    pushd "$TEMP_DIR" > /dev/null
     [ -e "$DEST_NAME_ZIP" ] && rm -rfv "$DEST_NAME_ZIP"
     zip -9r "$DEST_NAME_ZIP" "$DEST_NAME" && rm -rfv "$DEST_NAME"
     popd > /dev/null
+
+    # Now move the final zip from the temp dest to the final dist dir
+    mv -v "$TEMP_DIR/$DEST_NAME_ZIP" "$DIST_DIR/$DEST_NAME_ZIP"
+
     echo "Done"
     echo
     echo "Resulting SDK is in $DIST_DIR/$DEST_NAME_ZIP"
@@ -181,6 +205,7 @@
 }
 
 check
+status
 build
 package
 
diff --git a/cmds/monkey/src/com/android/commands/monkey/Monkey.java b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
index 00fb40c..5e9f07c 100644
--- a/cmds/monkey/src/com/android/commands/monkey/Monkey.java
+++ b/cmds/monkey/src/com/android/commands/monkey/Monkey.java
@@ -130,7 +130,8 @@
     
     float[] mFactors = new float[MonkeySourceRandom.FACTORZ_COUNT];    
     MonkeyEventSource mEventSource;
-
+    private MonkeyNetworkMonitor mNetworkMonitor = new MonkeyNetworkMonitor();
+    
     /**
      * Monitor operations happening in the system.
      */
@@ -222,14 +223,14 @@
             return 1;
         }
     }
-    
+  
     /**
      * Run the procrank tool to insert system status information into the debug report.
      */
     private void reportProcRank() {
       commandLineReport("procrank", "procrank");
     }
-    
+  
     /**
      * Run "cat /data/anr/traces.txt".  Wait about 5 seconds first, to let the asynchronous
      * report writing complete.
@@ -362,7 +363,7 @@
         
         if (mScriptFileName != null) {
             // script mode, ignore other options
-            mEventSource = new MonkeySourceScript(mScriptFileName);
+            mEventSource = new MonkeySourceScript(mScriptFileName, mThrottle);
             mEventSource.setVerbose(mVerbose);
         } else {
             // random source by default
@@ -401,7 +402,9 @@
             signalPersistentProcesses();
         }
         
+        mNetworkMonitor.start();
         int crashedAtCycle = runMonkeyCycles();
+        mNetworkMonitor.stop();
 
         synchronized (this) {
             if (mRequestAnrTraces) {
@@ -423,6 +426,7 @@
         
         try {
             mAm.setActivityWatcher(null);
+            mNetworkMonitor.unregister(mAm);
         } catch (RemoteException e) {
             // just in case this was latent (after mCount cycles), make sure
             // we report it
@@ -442,6 +446,9 @@
             System.out.print(" flips=");
             System.out.println(mDroppedFlipEvents);
         }
+        
+        // report network stats
+        mNetworkMonitor.dump();
 
         if (crashedAtCycle < mCount - 1) {
             System.err.println("** System appears to have crashed at event "
@@ -602,6 +609,7 @@
 
         try {
             mAm.setActivityWatcher(new ActivityWatcher());
+            mNetworkMonitor.register(mAm);
         } catch (RemoteException e) {
             System.err.println("** Failed talking with activity manager!");
             return false;
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java
index 7176073..d926be8 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java
@@ -51,6 +51,14 @@
     }
     
     /**
+     * @return true if it is safe to throttle after this event, and false otherwise.
+     */
+    public boolean isThrottlable() {
+        return true;
+    }
+    
+    
+    /**
      * a method for injecting event
      * @param iwm wires to current window manager
      * @param iam wires to current activity manager
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyEventQueue.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyEventQueue.java
new file mode 100644
index 0000000..dfe389a
--- /dev/null
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyEventQueue.java
@@ -0,0 +1,41 @@
+/*
+ * 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.commands.monkey;
+
+import java.util.LinkedList;
+
+/**
+ * class for keeping a monkey event queue
+ */
+@SuppressWarnings("serial")
+public class MonkeyEventQueue extends LinkedList<MonkeyEvent> {   
+
+    private long mThrottle;
+    
+    public MonkeyEventQueue(long throttle) {
+        super();
+        mThrottle = throttle;
+    }
+    
+    @Override
+    public void addLast(MonkeyEvent e) {
+        super.add(e);
+        if (e.isThrottlable()) {
+            super.add(new MonkeyThrottleEvent(mThrottle));
+        }
+    }
+}
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java
index c1e0ffc..877ebb5 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java
@@ -92,6 +92,11 @@
     }
 
     @Override
+    public boolean isThrottlable() {
+        return (getAction() == KeyEvent.ACTION_UP);
+    }
+    
+    @Override
     public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
         if (verbose > 1) {
             String note;
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyMotionEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyMotionEvent.java
index 2657061..81c64b4 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyMotionEvent.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyMotionEvent.java
@@ -20,6 +20,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.view.IWindowManager;
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 
 
@@ -124,6 +125,11 @@
     }
 
     @Override
+    public boolean isThrottlable() {
+        return (getAction() == KeyEvent.ACTION_UP);
+    }
+    
+    @Override
     public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) {
         
         String note;
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyNetworkMonitor.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyNetworkMonitor.java
new file mode 100644
index 0000000..e8d9812
--- /dev/null
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyNetworkMonitor.java
@@ -0,0 +1,105 @@
+/**
+** 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.commands.monkey;
+
+import android.app.IActivityManager;
+import android.app.IIntentReceiver;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.SystemClock;
+
+/**
+ * Class for monitoring network connectivity during monkey runs.
+ */
+public class MonkeyNetworkMonitor extends IIntentReceiver.Stub {
+    private static final boolean LDEBUG = false;
+    private final IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
+    private long mCollectionStartTime; // time we started collecting data
+    private long mEventTime; // time of last event (connect, disconnect, etc.)
+    private int mLastNetworkType = -1; // unknown
+    private long mWifiElapsedTime = 0;  // accumulated time spent on wifi since start()
+    private long mMobileElapsedTime = 0; // accumulated time spent on mobile since start()
+    private long mElapsedTime = 0; // amount of time spent between start() and stop()
+    
+    public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
+            boolean ordered) throws RemoteException {
+        NetworkInfo ni = (NetworkInfo) intent.getParcelableExtra(
+                ConnectivityManager.EXTRA_NETWORK_INFO);
+        if (LDEBUG) System.out.println("Network state changed: " 
+                + "type=" + ni.getType() + ", state="  + ni.getState());
+        updateNetworkStats();
+        if (NetworkInfo.State.CONNECTED == ni.getState()) {
+            if (LDEBUG) System.out.println("Network connected");
+            mLastNetworkType = ni.getType();
+        } else if (NetworkInfo.State.DISCONNECTED == ni.getState()) {
+            if (LDEBUG) System.out.println("Network not connected");
+            mLastNetworkType = -1; // unknown since we're disconnected
+        }
+        mEventTime = SystemClock.elapsedRealtime();
+    }
+
+    private void updateNetworkStats() {
+        long timeNow = SystemClock.elapsedRealtime();
+        long delta = timeNow - mEventTime;
+        switch (mLastNetworkType) {
+            case ConnectivityManager.TYPE_MOBILE:
+                if (LDEBUG) System.out.println("Adding to mobile: " + delta);
+                mMobileElapsedTime += delta;
+                break;
+            case ConnectivityManager.TYPE_WIFI:
+                if (LDEBUG) System.out.println("Adding to wifi: " + delta);
+                mWifiElapsedTime += delta;
+                break;
+            default:
+                if (LDEBUG) System.out.println("Unaccounted for: " + delta);
+                break;
+        }
+        mElapsedTime = timeNow - mCollectionStartTime;
+    }
+
+    public void start() {
+        mWifiElapsedTime = 0;
+        mMobileElapsedTime = 0;
+        mElapsedTime = 0;
+        mEventTime = mCollectionStartTime = SystemClock.elapsedRealtime();
+    }
+
+    public void register(IActivityManager am) throws RemoteException {
+        if (LDEBUG) System.out.println("registering Receiver");
+        am.registerReceiver(null, this, filter, null); 
+    }
+    
+    public void unregister(IActivityManager am) throws RemoteException {
+        if (LDEBUG) System.out.println("unregistering Receiver");
+        am.unregisterReceiver(this);
+    }
+    
+    public void stop() {
+        updateNetworkStats();
+    }
+    
+    public void dump() {
+        System.out.println("## Network stats: elapsed time=" + mElapsedTime + "ms (" 
+                + mMobileElapsedTime + "ms mobile, "
+                + mWifiElapsedTime + "ms wifi, "
+                + (mElapsedTime - mMobileElapsedTime - mWifiElapsedTime) + "ms not connected)");
+    }
+ }
\ No newline at end of file
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
index 902d8e8..5f9c10f 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java
@@ -31,7 +31,7 @@
 /**
  * monkey event queue
  */
-public class MonkeySourceRandom implements MonkeyEventSource{    
+public class MonkeySourceRandom implements MonkeyEventSource {    
     /** Key events that move around the UI. */
     private static final int[] NAV_KEYS = {
         KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN,
@@ -168,7 +168,7 @@
     private float[] mFactors = new float[FACTORZ_COUNT];
     private ArrayList<ComponentName> mMainApps;
     private int mEventCount = 0;  //total number of events generated so far
-    private LinkedList<MonkeyEvent> mQ = new LinkedList<MonkeyEvent>();
+    private MonkeyEventQueue mQ;
     private Random mRandom;    
     private int mVerbose = 0;
     private long mThrottle = 0;
@@ -203,7 +203,7 @@
         mRandom = new SecureRandom();
         mRandom.setSeed((seed == 0) ? -1 : seed);
         mMainApps = MainApps;
-        mThrottle = throttle;
+        mQ = new MonkeyEventQueue(throttle);
     }
 
     /**
@@ -336,7 +336,6 @@
                 downAt, MotionEvent.ACTION_UP, x, y, 0);        
         e.setIntermediateNote(false);        
         mQ.addLast(e);
-        addThrottle();
     }
   
     /**
@@ -387,7 +386,6 @@
             e.setIntermediateNote(false);        
             mQ.addLast(e);
         }        
-        addThrottle();
     }
     
     /** 
@@ -420,13 +418,11 @@
             MonkeyActivityEvent e = new MonkeyActivityEvent(mMainApps.get(
                     mRandom.nextInt(mMainApps.size())));
             mQ.addLast(e);
-            addThrottle();
             return;
         } else if (cls < mFactors[FACTOR_FLIP]) {
             MonkeyFlipEvent e = new MonkeyFlipEvent(mKeyboardOpen);
             mKeyboardOpen = !mKeyboardOpen;
             mQ.addLast(e);
-            addThrottle();
             return;
         } else {
             lastKey = 1 + mRandom.nextInt(KeyEvent.getMaxKeyCode() - 1);
@@ -437,8 +433,6 @@
         
         e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, lastKey);
         mQ.addLast(e);
-        
-        addThrottle();
     }
     
     public boolean validate() {
@@ -472,8 +466,4 @@
         mQ.removeFirst();        
         return e;
     }
-    
-    private void addThrottle() {
-        mQ.addLast(new MonkeyThrottleEvent(MonkeyEvent.EVENT_TYPE_THROTTLE, mThrottle));
-    }
 }
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java
index aadda9f..869af2c 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceScript.java
@@ -35,18 +35,19 @@
  *      type= raw events
  *      count= 10
  *      speed= 1.0
+ *      start data >>
  *      captureDispatchPointer(5109520,5109520,0,230.75429,458.1814,0.20784314,
  *          0.06666667,0,0.0,0.0,65539,0)
  *      captureDispatchKey(5113146,5113146,0,20,0,0,0,0)
  *      captureDispatchFlip(true)
  *      ...
  */
-public class MonkeySourceScript implements MonkeyEventSource{    
+public class MonkeySourceScript implements MonkeyEventSource {    
     private int mEventCountInScript = 0;  //total number of events in the file
     private int mVerbose = 0;
     private double mSpeed = 1.0;
     private String mScriptFileName; 
-    private LinkedList<MonkeyEvent> mQ = new LinkedList<MonkeyEvent>();
+    private MonkeyEventQueue mQ;
     
     private static final String HEADER_TYPE = "type=";
     private static final String HEADER_COUNT = "count=";
@@ -80,12 +81,14 @@
     // a line at the end of the header
     private static final String STARTING_DATA_LINE = "start data >>";    
     private boolean mFileOpened = false;    
+    
     FileInputStream mFStream;
     DataInputStream mInputStream;
     BufferedReader mBufferReader;
     
-    public MonkeySourceScript(String filename) {
+    public MonkeySourceScript(String filename, long throttle) {
         mScriptFileName = filename;
+        mQ = new MonkeyEventQueue(throttle);
     }
     
     /**
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyThrottleEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyThrottleEvent.java
index 3d7d48a..0b4e6b6 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeyThrottleEvent.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyThrottleEvent.java
@@ -16,11 +16,10 @@
 
 package com.android.commands.monkey;
 
+import java.util.List;
+
 import android.app.IActivityManager;
-import android.os.RemoteException;
-import android.os.SystemClock;
 import android.view.IWindowManager;
-import android.view.MotionEvent;
 
 
 /**
@@ -29,8 +28,8 @@
 public class MonkeyThrottleEvent extends MonkeyEvent {
     private long mThrottle; 
         
-    public MonkeyThrottleEvent(int type, long throttle) {
-        super(type);
+    public MonkeyThrottleEvent(long throttle) {
+        super(MonkeyEvent.EVENT_TYPE_THROTTLE);
         mThrottle = throttle;
     }  
 
diff --git a/docs/copyright-templates/asm.txt b/docs/copyright-templates/asm.txt
new file mode 100644
index 0000000..95a9022
--- /dev/null
+++ b/docs/copyright-templates/asm.txt
@@ -0,0 +1,13 @@
+; 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.
diff --git a/docs/copyright-templates/bash.txt b/docs/copyright-templates/bash.txt
new file mode 100644
index 0000000..ecf510e
--- /dev/null
+++ b/docs/copyright-templates/bash.txt
@@ -0,0 +1,15 @@
+#!/bin/bash
+#
+# 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.
diff --git a/docs/copyright-templates/bsd/c.txt b/docs/copyright-templates/bsd/c.txt
new file mode 100644
index 0000000..c574b4a
--- /dev/null
+++ b/docs/copyright-templates/bsd/c.txt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
diff --git a/docs/copyright-templates/c.txt b/docs/copyright-templates/c.txt
new file mode 100644
index 0000000..7cd7083
--- /dev/null
+++ b/docs/copyright-templates/c.txt
@@ -0,0 +1,15 @@
+/*
+ * 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.
+ */
diff --git a/docs/copyright-templates/java.txt b/docs/copyright-templates/java.txt
new file mode 100644
index 0000000..7cd7083
--- /dev/null
+++ b/docs/copyright-templates/java.txt
@@ -0,0 +1,15 @@
+/*
+ * 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.
+ */
diff --git a/docs/copyright-templates/make.txt b/docs/copyright-templates/make.txt
new file mode 100644
index 0000000..e4b376e
--- /dev/null
+++ b/docs/copyright-templates/make.txt
@@ -0,0 +1,13 @@
+# 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.
diff --git a/docs/copyright-templates/plain.txt b/docs/copyright-templates/plain.txt
new file mode 100644
index 0000000..4549ecb
--- /dev/null
+++ b/docs/copyright-templates/plain.txt
@@ -0,0 +1,13 @@
+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.
diff --git a/docs/copyright-templates/sh.txt b/docs/copyright-templates/sh.txt
new file mode 100644
index 0000000..e53137d
--- /dev/null
+++ b/docs/copyright-templates/sh.txt
@@ -0,0 +1,15 @@
+#!/bin/sh
+#
+# 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.
diff --git a/docs/copyright-templates/xml.txt b/docs/copyright-templates/xml.txt
new file mode 100644
index 0000000..2a9d2b6
--- /dev/null
+++ b/docs/copyright-templates/xml.txt
@@ -0,0 +1,15 @@
+<?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.
+-->
diff --git a/docs/howto_SDK_git_cygwin.txt b/docs/howto_SDK_git_cygwin.txt
new file mode 100644
index 0000000..42da18b
--- /dev/null
+++ b/docs/howto_SDK_git_cygwin.txt
@@ -0,0 +1,180 @@
+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.
+
+
+Subject: How to get the android source code using Cygwin and Git
+Date:    2009/04/27
+Updated: 2009/05/21
+
+
+Table of content:
+  1- Goals and Requirements
+  2- Getting the code, the simple way
+  3- SSH issues
+  4- Advanced Tricks
+
+
+-------------------------
+1- Goals and Requirements
+-------------------------
+
+This document explains how to checkout the Android source from the git
+repositories under Windows.
+
+As stated in development/docs/howto_build_SDK.txt, one can't build the whole
+Android source code under Windows. You can only build a the SDK tools for
+Windows.
+
+There are a number of caveats in checking out the code from Git under Windows. 
+This document tries to explain them.
+
+First you will need to meet the following requirements:
+- You must have Cygwin installed.
+  See http://www.cygwin.com/
+
+- You must install Cyginw using the "Unix / Binary" mode.
+  If you don't do that, git will fail to properly compute some SHA1 keys.
+
+- You need the "git" and "curl" packages to checkout the code.
+  If you plan to contribute, you might want to get "gitk" also.
+
+  Note: if you want to build the SDK, check the howto_build_SDK.txt file
+  for a list of extra required packages.
+
+
+-----------------------------------
+2- Getting the code, the simple way
+-----------------------------------
+
+Out of the box, "repo" and "git" will work just fine under Cygwin:
+
+  $ repo init -u git://android.git.kernel.org/platform/manifest.git
+  $ repo sync
+
+And you're done. You can build as explained in howto_build_SDK.txt and ignore
+the rest of this document.
+
+
+-------------
+3- SSH issues
+-------------
+
+If you maintain your own private repository using an SSH server, you might get
+some "mux/ssh" errors. In this case try this:
+
+  $ repo init -u ssh://my.private.ssh.repo/platform/manifest.git
+  $ export GIT_SSH=ssh
+  $ repo sync
+
+
+------------------
+4- Advanced Tricks
+------------------
+
+There is one remaining issue with the default repo/git options:
+
+If you plan on contributing, you will notice that even after a fresh "repo
+sync" some projects are marked as having modified files. This happens on the
+"bionic" and the "external/iptables" project. The issue is that they have files
+which have the same name yet differ only by their case-sensitivity. Since the
+Windows filesystem is not case-sensitive, this confuses Git.
+
+Solution: we can simply ignore these projects as they are not needed to build
+the Windows SDK.
+
+To do this you just need to create a file .repo/local_manifest.xml that
+provides a list of projects to ignore:
+
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest>
+  <remove-project name="platform/external/iptables" />
+</manifest>
+
+The other thing we can do is tell git not to track the files that cause
+problems:
+
+  cd bionic
+  git update-index --assume-unchanged \
+    libc/kernel/common/linux/netfilter/xt_CONNMARK.h \
+    libc/kernel/common/linux/netfilter/xt_MARK.h \
+    libc/kernel/common/linux/netfilter_ipv6/ip6t_HL.h
+
+  cd external/tcpdump;
+  git update-index --assume-unchanged \
+    tests/print-X.new \
+    tests/print-XX.new
+
+
+Here's a script that takes care of all these details. It performs the repo
+init, creates the appropriate local_manifest.xml, does a repo sync as
+needed and tell git to ignore the offending files:
+
+------------
+#!/bin/bash
+
+set -e  # fail on errors
+
+URL=ssh://android-git.corp.google.com:29418/platform/manifest.git
+BRANCH=donut
+if [ "$1" == "-b" ]; then shift; BRANCH=$1; shift; fi
+
+# repo init if there's no .repo directory
+if [[ ! -d .repo ]]; then
+    repo init -u $URL -b $BRANCH
+fi
+
+# create a local_manifest to exclude projects that cause problems under Windows
+# due to the case-insenstivines of the file system.
+L=.repo/local_manifest.xml
+if [[ ! -f $L ]]; then
+
+    cat > $L <<EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest>
+<remove-project name="platform/external/iptables" />
+</manifest>
+EOF
+fi
+
+# sync using the native ssh client if necessary
+[[ $URL != ${URL/ssh/} ]] && export GIT_SSH=ssh
+repo sync $@
+
+
+# These files cause trouble too, we need to ignore them
+(cd bionic;
+git update-index --assume-unchanged \
+    libc/kernel/common/linux/netfilter/xt_CONNMARK.h \
+    libc/kernel/common/linux/netfilter/xt_MARK.h \
+    libc/kernel/common/linux/netfilter_ipv6/ip6t_HL.h
+)
+(cd external/tcpdump;
+git update-index --assume-unchanged \
+    tests/print-X.new \
+    tests/print-XX.new
+)
+------------
+
+Simply extract this to a "my_sync.sh" file and try the following:
+  $ mkdir android_src
+  $ cd android_src
+  $ chmod +x mysync.sh
+  $ ./mysync.sh
+
+
+-end-
+
+
+
+
diff --git a/emulator/qemud/qemud.c b/emulator/qemud/qemud.c
index c578145..92b2a2b 100644
--- a/emulator/qemud/qemud.c
+++ b/emulator/qemud/qemud.c
@@ -849,6 +849,10 @@
 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)
     {
@@ -856,9 +860,6 @@
         f->closing = 1;
         fdhandler_remove(f);
         fdhandler_prepend(f, &f->list->closing);
-
-        /* notify the receiver that we're closing */
-        receiver_close(f->receiver);
         return;
     }
 
diff --git a/emulator/qtools/Android.mk b/emulator/qtools/Android.mk
index afbb3e8..149390c 100644
--- a/emulator/qtools/Android.mk
+++ b/emulator/qtools/Android.mk
@@ -97,6 +97,14 @@
 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)
@@ -139,3 +147,11 @@
 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
index 593f460..1f35867 100644
--- a/emulator/qtools/armdis.cpp
+++ b/emulator/qtools/armdis.cpp
@@ -5,7 +5,7 @@
 #include "armdis.h"
 #include "opcode.h"
 
-static char *cond_names[] = {
+static const char *cond_names[] = {
     "eq",
     "ne",
     "cs",
@@ -32,7 +32,7 @@
     "ROR"
 };
 
-static char* cond_to_str(int cond) {
+static const char* cond_to_str(int cond) {
     return cond_names[cond];
 }
 
@@ -180,7 +180,7 @@
         sprintf(rd_str, "r%d, ", rd);
     }
 
-    char *sbit_str = "";
+    const char *sbit_str = "";
     if (bit_s && !(flags & kNoSbit))
         sbit_str = "s";
 
@@ -282,15 +282,15 @@
 
     const char *opname = opcode_names[opcode];
 
-    char *bang = "";
+    const char *bang = "";
     if (write_back)
         bang = "!";
 
-    char *carret = "";
+    const char *carret = "";
     if (bit_s)
         carret = "^";
 
-    char *comma = "";
+    const char *comma = "";
     tmp_list[0] = 0;
     for (int ii = 0; ii < 16; ++ii) {
         if (reg_list & (1 << ii)) {
@@ -300,7 +300,7 @@
         }
     }
 
-    char *addr_mode = "";
+    const char *addr_mode = "";
     if (is_pre) {
         if (is_up) {
             addr_mode = "ib";
@@ -333,19 +333,19 @@
     uint8_t rd = (insn >> 12) & 0xf;
     uint16_t offset = insn & 0xfff;
 
-    char *opname = "ldr";
+    const char *opname = "ldr";
     if (!is_load)
         opname = "str";
 
-    char *bang = "";
+    const char *bang = "";
     if (write_back)
         bang = "!";
 
-    char *minus = "";
+    const char *minus = "";
     if (is_up == 0)
         minus = "-";
 
-    char *byte = "";
+    const char *byte = "";
     if (is_byte)
         byte = "b";
 
@@ -359,7 +359,7 @@
                         opname, cond_to_str(cond), byte, rd, rn, minus, offset, bang);
             }
         } else {
-            char *transfer = "";
+            const char *transfer = "";
             if (write_back)
                 transfer = "t";
             sprintf(ptr, "%s%s%s%s\tr%d, [r%d], #%s%u",
@@ -394,7 +394,7 @@
         return ptr;
     }
 
-    char *transfer = "";
+    const char *transfer = "";
     if (write_back)
         transfer = "t";
 
@@ -432,11 +432,11 @@
     uint8_t rm = insn & 0xf;
     uint8_t offset = (((insn >> 8) & 0xf) << 4) | (insn & 0xf);
 
-    char *opname = "ldr";
+    const char *opname = "ldr";
     if (is_load == 0)
         opname = "str";
 
-    char *width = "";
+    const char *width = "";
     if (bits_65 == 1)
         width = "h";
     else if (bits_65 == 2)
@@ -444,10 +444,10 @@
     else
         width = "sh";
 
-    char *bang = "";
+    const char *bang = "";
     if (write_back)
         bang = "!";
-    char *minus = "";
+    const char *minus = "";
     if (is_up == 0)
         minus = "-";
 
@@ -587,7 +587,7 @@
     uint8_t is_up = (insn >> 23) & 0x1;
     uint8_t rn = (insn >> 16) & 0xf;
 
-    char *minus = "";
+    const char *minus = "";
     if (is_up == 0)
         minus = "-";
 
diff --git a/emulator/qtools/callstack.h b/emulator/qtools/callstack.h
index b869956..8982330 100644
--- a/emulator/qtools/callstack.h
+++ b/emulator/qtools/callstack.h
@@ -32,7 +32,9 @@
     typedef SYM symbol_type;
     static const uint32_t kCausedException = 0x01;
     static const uint32_t kInterpreted     = 0x02;
-    static const uint32_t kPopBarrier      = (kCausedException | kInterpreted);
+    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
@@ -43,7 +45,8 @@
 
 template <class FRAME, class BASE = CallStackBase>
 class CallStack : public BASE {
-  public:
+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;
@@ -56,7 +59,7 @@
     void    threadStart(uint64_t time);
     void    threadStop(uint64_t time);
 
-    // Set to true if you don't want to see any Java methods
+    // Set to true if you don't want to see any Java methods ever
     void    setNativeOnly(bool nativeOnly) {
         mNativeOnly = nativeOnly;
     }
@@ -64,38 +67,36 @@
     int         getStackLevel() { return mTop; }
 
     uint64_t    getGlobalTime(uint64_t time) { return time + mSkippedTime; }
-    void        showStack();
-    void        showSnapshotStack();
-
-  private:
-    enum Action { NONE, PUSH, POP };
-
-    Action      getAction(BBEvent *event, symbol_type *function);
-    Action      getMethodAction(BBEvent *event, symbol_type *function);
-    void        doSimplePush(symbol_type *function, uint32_t addr,
-                             uint64_t time);
-    void        doSimplePop(uint64_t time);
-    void        doPush(BBEvent *event, symbol_type *function);
-    void        doPop(BBEvent *event, symbol_type *function, Action methodAction);
-
-    void        transitionToJava();
-    void        transitionFromJava(uint64_t time);
-
-    TraceReaderType *mTrace;
-    bool        mNativeOnly;
-
-    symbol_type mDummyFunction;
-    region_type mDummyRegion;
+    void        showStack(FILE *stream);
 
     int         mNumFrames;
     FRAME       *mFrames;
     int         mTop;           // index of the next stack frame to write
 
-    int         mJavaTop;
+private:
+    enum Action { NONE, PUSH, POP, NATIVE_PUSH };
 
-    int         mSnapshotNumFrames;
-    FRAME       *mSnapshotFrames;
-    int         mSnapshotTop;   // index of the next stack frame to write
+    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;
@@ -124,10 +125,7 @@
     mNumFrames = numFrames;
     mFrames = new FRAME[mNumFrames];
     mTop = 0;
-
-    mSnapshotNumFrames = numFrames;
-    mSnapshotFrames = new FRAME[mSnapshotNumFrames];
-    mSnapshotTop = 0;
+    mAllowNativeFrames = true;
 
     memset(&mDummyFunction, 0, sizeof(symbol_type));
     memset(&mDummyRegion, 0, sizeof(region_type));
@@ -138,7 +136,6 @@
     memset(&mUserEvent, 0, sizeof(BBEvent));
     mSkippedTime = 0;
     mLastRunTime = 0;
-    mJavaTop = 0;
 
     // Read the first two methods from the trace if we haven't already read
     // from the method trace yet.
@@ -168,11 +165,29 @@
         // instead.
         if (function->vm_sym != NULL)
             function = function->vm_sym;
+    } else {
+        doMethodAction(event, function);
     }
 
     Action action = getAction(event, function);
-    Action methodAction = getMethodAction(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.
@@ -197,11 +212,16 @@
             doPush(event, function);
         }
     }
+#endif
 
     // If the stack is now empty, then push the current function.
     if (mTop == 0) {
         uint64_t time = event->time - mSkippedTime;
-        doSimplePush(function, 0, time);
+        int flags = 0;
+        if (function->vm_sym != NULL) {
+            flags = FRAME::kInterpreted;
+        }
+        doSimplePush(function, 0, time, 0);
     }
 
     mPrevFunction = function;
@@ -366,8 +386,11 @@
 
     // 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();
+        showStack(stderr);
 #endif
         fprintf(stderr, "Error: stack overflow (%d frames)\n", mTop);
         exit(1);
@@ -391,17 +414,20 @@
     }
 
 #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();
+        showStack(stderr);
     }
 #endif
 
-    // If the previous function was a vector table, then pop it
+    // 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 ((mPrevFunction->flags & symbol_type::kIsVectorTable) && mTop > 0) {
+    if (mTop > 0
+        && (mFrames[mTop - 1].function->flags & symbol_type::kIsVectorTable)) {
         retAddr = mFrames[mTop - 1].addr;
         doSimplePop(time);
     }
@@ -426,9 +452,10 @@
         && 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();
+        showStack(stderr);
 #endif
         do {
             // Pop off the kernel frames until we reach the one that
@@ -445,6 +472,7 @@
             }
         } while (mTop > 0);
 #if 0
+        // For debugging
         printf("  doPush() popping to level %d, using retAddr 0x%08x\n",
                mTop, retAddr);
 #endif
@@ -456,44 +484,33 @@
     if ((function->flags & symbol_type::kIsVectorStart) && mTop > 0)
         mFrames[mTop - 1].flags |= FRAME::kCausedException;
 
-    doSimplePush(function, retAddr, time);
+    // 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)
+void CallStack<FRAME, BASE>::doSimplePush(symbol_type *function, uint32_t addr,
+                                          uint64_t time, int flags)
 {
     // Check for stack overflow
     if (mTop >= mNumFrames) {
-        showStack();
+        showStack(stderr);
         fprintf(stderr, "too many stack frames (%d)\n", mTop);
         exit(1);
     }
 
-    // Keep track of the number of Java methods we push on the stack.
-    if (!mNativeOnly && function->vm_sym != NULL) {
-        // If we are pushing the first Java method on the stack, then
-        // save a snapshot of the stack so that we can clean things up
-        // later when we pop off the last Java stack frame.
-        if (mJavaTop == 0) {
-            transitionToJava();
-        }
-        mJavaTop += 1;
-    }
-
     mFrames[mTop].addr = addr;
     mFrames[mTop].function = function;
-    mFrames[mTop].flags = 0;
+    mFrames[mTop].flags = flags;
     mFrames[mTop].time = time;
     mFrames[mTop].global_time = time + mSkippedTime;
 
-    // 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.
-    if (function->vm_sym != NULL) {
-        mFrames[mTop].flags = FRAME::kInterpreted;
-    }
-
     mFrames[mTop].push(mTop, time, this);
     mTop += 1;
 }
@@ -508,17 +525,25 @@
     mTop -= 1;
     mFrames[mTop].pop(mTop, time, this);
 
-    // Keep track of the number of Java methods we have on the stack.
-    symbol_type *function = mFrames[mTop].function;
-    if (!mNativeOnly && function->vm_sym != NULL) {
-        mJavaTop -= 1;
+    if (mNativeOnly)
+        return;
 
-        // When there are no more Java stack frames, then clean up
-        // the client's stack.  We need to do this because the client
-        // doesn't see the changes to the native stack underlying the
-        // fake Java stack until the last Java method is popped off.
-        if (mJavaTop == 0) {
-            transitionFromJava(time);
+    // 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;
         }
     }
 }
@@ -565,7 +590,13 @@
             // 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.
+                // 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;
             }
@@ -604,9 +635,11 @@
         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();
+        showStack(stderr);
     }
 #endif
 
@@ -654,20 +687,45 @@
 }
 
 template<class FRAME, class BASE>
-typename CallStack<FRAME, BASE>::Action
-CallStack<FRAME, BASE>::getMethodAction(BBEvent *event, symbol_type *function)
+void CallStack<FRAME, BASE>::doMethodPop(BBEvent *event, uint32_t addr,
+                                         const uint32_t flags)
 {
-    if (function->vm_sym == NULL && mPrevFunction->vm_sym == NULL) {
-        return NONE;
+    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;
+            }
+        }
     }
 
-    Action action = NONE;
-    uint32_t prevAddr = mPrevFunction->addr + mPrevFunction->region->base_addr;
-    uint32_t addr = function->addr + function->region->base_addr;
+    // 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.
+    // 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)) {
@@ -675,86 +733,43 @@
         }
     }
 
-    if (event->time >= sCurrentMethod.time) {
-        if (addr == sCurrentMethod.addr || prevAddr == sCurrentMethod.addr) {
-            action = (sCurrentMethod.flags == 0) ? PUSH : POP;
-            // We found a match, so read the next record.
-            sCurrentMethod = sNextMethod;
-            if (sNextMethod.time != ~0ull && 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;
         }
     }
-    return action;
 }
 
-// When the first Java method is pushed on the stack, this method is
-// called to save a snapshot of the current native stack so that the
-// client's view of the native stack can be patched up later when the
-// Java stack is empty.
 template<class FRAME, class BASE>
-void CallStack<FRAME, BASE>::transitionToJava()
+void CallStack<FRAME, BASE>::showStack(FILE *stream)
 {
-    mSnapshotTop = mTop;
+    fprintf(stream, "mTop: %d skippedTime: %llu\n", mTop, mSkippedTime);
     for (int ii = 0; ii < mTop; ++ii) {
-        mSnapshotFrames[ii] = mFrames[ii];
-    }
-}
-
-// When the Java stack becomes empty, the native stack becomes
-// visible.  This method is called when the Java stack becomes empty
-// to patch up the client's view of the native stack, which may have
-// changed underneath the Java stack.  The stack snapshot is used to
-// create a sequence of pops and pushes to make the client's view of
-// the native stack match the current native stack.
-template<class FRAME, class BASE>
-void CallStack<FRAME, BASE>::transitionFromJava(uint64_t time)
-{
-    int top = mTop;
-    if (top > mSnapshotTop) {
-        top = mSnapshotTop;
-    }
-    for (int ii = 0; ii < top; ++ii) {
-        if (mSnapshotFrames[ii].function->addr == mFrames[ii].function->addr) {
-            continue;
-        }
-
-        // Pop off all the rest of the frames from the snapshot
-        for (int jj = top - 1; jj >= ii; --jj) {
-            mSnapshotFrames[jj].pop(jj, time, this);
-        }
-
-        // Push the new frames from the native stack
-        for (int jj = ii; jj < mTop; ++jj) {
-            mFrames[jj].push(jj, time, this);
-        }
-        break;
-    }
-}
-
-template<class FRAME, class BASE>
-void CallStack<FRAME, BASE>::showStack()
-{
-    fprintf(stderr, "mTop: %d skippedTime: %llu\n", mTop, mSkippedTime);
-    for (int ii = 0; ii < mTop; ++ii) {
-        fprintf(stderr, "  %d: t %d gt %d f %x 0x%08x 0x%08x %s\n",
+        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, mFrames[ii].function->addr,
+                mFrames[ii].addr, addr,
                 mFrames[ii].function->name);
     }
 }
 
-template<class FRAME, class BASE>
-void CallStack<FRAME, BASE>::showSnapshotStack()
-{
-    fprintf(stderr, "mSnapshotTop: %d\n", mSnapshotTop);
-    for (int ii = 0; ii < mSnapshotTop; ++ii) {
-        fprintf(stderr, "  %d: t %d f %x 0x%08x 0x%08x %s\n",
-                ii, mSnapshotFrames[ii].time, mSnapshotFrames[ii].flags,
-                mSnapshotFrames[ii].addr, mSnapshotFrames[ii].function->addr,
-                mSnapshotFrames[ii].function->name);
-    }
-}
-
 #endif /* CALL_STACK_H */
diff --git a/emulator/qtools/check_stack.cpp b/emulator/qtools/check_stack.cpp
new file mode 100644
index 0000000..b4d14d3
--- /dev/null
+++ b/emulator/qtools/check_stack.cpp
@@ -0,0 +1,270 @@
+// 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/coverage.cpp b/emulator/qtools/coverage.cpp
index fb1fe52..790f721 100644
--- a/emulator/qtools/coverage.cpp
+++ b/emulator/qtools/coverage.cpp
@@ -137,7 +137,7 @@
             continue;
         if (strcmp(psym->name, ".plt") == 0)
             continue;
-        char *ksym = " ";
+        const char *ksym = " ";
         if (psym->region->flags & region_type::kIsKernelRegion)
             ksym = "k";
         printf("%s %s %s\n", ksym, psym->name, psym->region->path);
diff --git a/emulator/qtools/dump_regions.cpp b/emulator/qtools/dump_regions.cpp
new file mode 100644
index 0000000..57389f9
--- /dev/null
+++ b/emulator/qtools/dump_regions.cpp
@@ -0,0 +1,59 @@
+#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/hash_table.h b/emulator/qtools/hash_table.h
index 45786ec..4ea9ed5 100644
--- a/emulator/qtools/hash_table.h
+++ b/emulator/qtools/hash_table.h
@@ -21,6 +21,7 @@
     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();
@@ -121,6 +122,31 @@
 }
 
 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
diff --git a/emulator/qtools/parse_options-inl.h b/emulator/qtools/parse_options-inl.h
index f218cc1..beb9df4 100644
--- a/emulator/qtools/parse_options-inl.h
+++ b/emulator/qtools/parse_options-inl.h
@@ -42,6 +42,14 @@
   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)
 {
diff --git a/emulator/qtools/post_trace.cpp b/emulator/qtools/post_trace.cpp
index 99525fb..becfc2b 100644
--- a/emulator/qtools/post_trace.cpp
+++ b/emulator/qtools/post_trace.cpp
@@ -137,7 +137,7 @@
   double insn_per_sec = 0;
   if (elapsed_secs != 0)
     insn_per_sec = num_dynamic_insn / elapsed_secs;
-  char *suffix = "";
+  const char *suffix = "";
   if (insn_per_sec >= 1000000) {
     insn_per_sec /= 1000000.0;
     suffix = "M";
diff --git a/emulator/qtools/profile_pid.cpp b/emulator/qtools/profile_pid.cpp
index aa37847..11acbf9 100644
--- a/emulator/qtools/profile_pid.cpp
+++ b/emulator/qtools/profile_pid.cpp
@@ -76,7 +76,7 @@
     sum_time += pstate->cpu_time;
     double per = 100.0 * pstate->cpu_time / total_time;
     double sum_per = 100.0 * sum_time / total_time;
-    char *print_flags = "";
+    const char *print_flags = "";
     if ((pstate->flags & ProcessState::kCalledExec) == 0)
       print_flags = "T";
     if (pstate->name == NULL)
@@ -84,10 +84,11 @@
     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 ii = 1; ii < pstate->argc; ++ii) {
-      printf(" %s", pstate->argv[ii]);
+    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
index 9d14a03..0b056cc 100644
--- a/emulator/qtools/profile_trace.cpp
+++ b/emulator/qtools/profile_trace.cpp
@@ -118,7 +118,7 @@
         double per = 100.0 * sym->elapsed / total;
         double sum_per = 100.0 * sum / total;
         double secs = 1.0 * sym->elapsed / kMHz;
-        char *ksym = " ";
+        const char *ksym = " ";
         if (sym->region->flags & region_type::kIsKernelRegion)
             ksym = "k";
         printf("%12.2f %11lld %6.2f %6.2f  %s %s\n",
diff --git a/emulator/qtools/q2dm.cpp b/emulator/qtools/q2dm.cpp
index 7f987dc..74dbaeb 100644
--- a/emulator/qtools/q2dm.cpp
+++ b/emulator/qtools/q2dm.cpp
@@ -208,7 +208,7 @@
         if (pStack == NULL) {
             pStack = new CallStackType(event.pid, kNumStackFrames, trace);
             stacks[event.pid] = pStack;
-            char *name = trace->GetProcessName(event.pid);
+            const char *name = trace->GetProcessName(event.pid);
             dmtrace->addThread(event.pid, name);
         }
 
@@ -267,7 +267,6 @@
         }
     }
 
-
     dmtrace->close();
     delete dmtrace;
     delete trace;
diff --git a/emulator/qtools/read_addr.cpp b/emulator/qtools/read_addr.cpp
index 38fc62a..1c8c20f 100644
--- a/emulator/qtools/read_addr.cpp
+++ b/emulator/qtools/read_addr.cpp
@@ -20,7 +20,7 @@
 
     if (trace->ReadAddr(&time, &addr, &flags))
       break;
-    char *op = "ld";
+    const char *op = "ld";
     if (flags == 1)
         op = "st";
     printf("%lld 0x%08x %s\n", time, addr, op);
diff --git a/emulator/qtools/read_method.cpp b/emulator/qtools/read_method.cpp
index e48edad..6aa0c1a 100644
--- a/emulator/qtools/read_method.cpp
+++ b/emulator/qtools/read_method.cpp
@@ -9,6 +9,66 @@
 
 #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",
@@ -34,9 +94,14 @@
         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,
@@ -46,7 +111,27 @@
                    method_record.time, proc->pid, method_record.addr,
                    method_record.flags);
         }
-        proc->DumpStack();
+
+        // 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/stack_dump.cpp b/emulator/qtools/stack_dump.cpp
index b5014ef..f685cd0 100644
--- a/emulator/qtools/stack_dump.cpp
+++ b/emulator/qtools/stack_dump.cpp
@@ -15,17 +15,40 @@
 #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)
 {
-    printf("%llu en thr %d %3d", time, base->getId(), stackLevel);
+    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);
@@ -33,7 +56,13 @@
 
 void MyFrame::pop(int stackLevel, uint64_t time, CallStackBase *base)
 {
-    printf("%llu x  thr %d %3d", time, base->getId(), stackLevel);
+    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);
@@ -43,18 +72,36 @@
 static const int kMaxThreads = (32 * 1024);
 CallStackType *stacks[kMaxThreads];
 
-static uint64_t debugTime;
-
 void Usage(const char *program)
 {
-    fprintf(stderr, "Usage: %s [options] trace_name elf_file\n",
+    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);
@@ -66,9 +113,6 @@
     trace->Open(qemu_trace_file);
     trace->ReadKernelSymbols(elf_file);
     trace->SetRoot(root);
-    TraceHeader *qheader = trace->GetHeader();
-    uint64_t startTime = qheader->start_sec;
-    startTime = (startTime << 32) | qheader->start_usec;
 
     BBEvent event;
     while (1) {
@@ -93,6 +137,13 @@
 
         // 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) {
diff --git a/emulator/qtools/thumbdis.cpp b/emulator/qtools/thumbdis.cpp
index f4294dd..07c482f 100644
--- a/emulator/qtools/thumbdis.cpp
+++ b/emulator/qtools/thumbdis.cpp
@@ -46,7 +46,7 @@
 {
     unsigned short value, mask;  /* recognise instruction if (op&mask)==value */
     Opcode opcode;
-    char * assembler;            /* how to disassemble this instruction */
+    const char * assembler;      /* how to disassemble this instruction */
 };
 
 /* format of the assembler string :
@@ -216,7 +216,7 @@
 #define BDISP23(x,y) ((((((x) & 0x07ff) << 11) | ((y) & 0x07ff)) \
                      ^ 0x200000) - 0x200000) /* 23bit */
 
-static char * arm_conditional[] =
+static const char * arm_conditional[] =
 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
  "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
 
@@ -281,7 +281,7 @@
         if ((insn1 & insn->mask) != insn->value)
             continue;
 
-        char * c = insn->assembler;
+        const char * c = insn->assembler;
 
         /* Special processing for Thumb 2-instruction BL sequence:  */
         if (!*c) { /* Check for empty (not NULL) assembler string.  */
diff --git a/emulator/qtools/trace_reader.cpp b/emulator/qtools/trace_reader.cpp
index b38c0b4..d2af64f 100644
--- a/emulator/qtools/trace_reader.cpp
+++ b/emulator/qtools/trace_reader.cpp
@@ -131,7 +131,7 @@
     delete decoder_;
 }
 
-void BBReader::Open(char *filename)
+void BBReader::Open(const char *filename)
 {
     // Initialize the class variables
     memset(&nextrec_, 0, sizeof(TimeRec));
@@ -268,7 +268,7 @@
     delete decoder_;
 }
 
-void InsnReader::Open(char *filename)
+void InsnReader::Open(const char *filename)
 {
     prev_time_ = 0;
     time_diff_ = 0;
@@ -310,7 +310,7 @@
 }
 
 // Returns true if there is an error opening the file
-bool AddrReader::Open(char *filename, char *suffix)
+bool AddrReader::Open(const char *filename, const char *suffix)
 {
     struct stat stat_buf;
 
@@ -367,7 +367,7 @@
     delete decoder_;
 }
 
-void ExcReader::Open(char *filename)
+void ExcReader::Open(const char *filename)
 {
     prev_time_ = 0;
     prev_recnum_ = 0;
@@ -421,7 +421,7 @@
     delete decoder_;
 }
 
-void PidReader::Open(char *filename)
+void PidReader::Open(const char *filename)
 {
     prev_time_ = 0;
 
@@ -561,7 +561,7 @@
     delete decoder_;
 }
 
-bool MethodReader::Open(char *filename)
+bool MethodReader::Open(const char *filename)
 {
     struct stat stat_buf;
 
@@ -686,8 +686,8 @@
     delete[] static_filename_;
 }
 
-void TraceReaderBase::ReadTraceHeader(FILE *fstream, char *filename,
-                                      char *tracename, TraceHeader *header)
+void TraceReaderBase::ReadTraceHeader(FILE *fstream, const char *filename,
+                                      const char *tracename, TraceHeader *header)
 {
     int rval = fread(header, sizeof(TraceHeader), 1, fstream);
     if (rval != 1) {
@@ -721,7 +721,7 @@
 }
 
 
-void TraceReaderBase::Open(char *filename)
+void TraceReaderBase::Open(const char *filename)
 {
     char *fname;
     FILE *fstream;
@@ -840,7 +840,7 @@
     }
 }
 
-void TraceReaderBase::ParseDexList(char *filename)
+void TraceReaderBase::ParseDexList(const char *filename)
 {
     struct stat stat_buf;
     static const int kBufSize = 4096;
diff --git a/emulator/qtools/trace_reader.h b/emulator/qtools/trace_reader.h
index 4123014..b91cb1b 100644
--- a/emulator/qtools/trace_reader.h
+++ b/emulator/qtools/trace_reader.h
@@ -62,6 +62,19 @@
             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;
@@ -100,6 +113,11 @@
         static const int kHasKernelRegion       = 0x08;
         static const int kHasFirstMmap          = 0x10;
 
+        struct methodFrame {
+            uint32_t    addr;
+            bool        isNative;
+        };
+
         ProcessState() {
             cpu_time = 0;
             tgid = 0;
@@ -153,7 +171,7 @@
         }
 
         // Dumps the stack contents to standard output.  For debugging.
-        void            DumpStack();
+        void            DumpStack(FILE *stream);
 
         uint64_t        cpu_time;
         uint64_t        start_time;
@@ -165,7 +183,7 @@
         uint32_t        flags;
         int             argc;
         char            **argv;
-        char            *name;
+        const char      *name;
         int             nregions;        // num regions in use
         int             max_regions;     // max regions allocated
         region_type     **regions;
@@ -173,7 +191,7 @@
         ProcessState    *addr_manager;   // the address space manager process
         ProcessState    *next;
         int             method_stack_top;
-        uint32_t        method_stack[kMaxMethodStackSize];
+        methodFrame     method_stack[kMaxMethodStackSize];
         symbol_type     *current_method_sym;
     };
 
@@ -184,12 +202,13 @@
     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();
-    char                *GetProcessName(int pid);
+    const char          *GetProcessName(int pid);
     void                SetRoot(const char *root)       { root_ = root; }
     void                SetDemangle(bool demangle)      { demangle_ = demangle; }
     bool                ReadMethodSymbol(MethodRec *method_record,
@@ -217,6 +236,10 @@
     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);
@@ -276,11 +299,14 @@
     hash_entry_type *ptr;
     for (ptr = hash_->GetFirst(); ptr; ptr = hash_->GetNext()) {
         region_type *region = ptr->value;
-        int nsymbols = region->nsymbols;
-        for (int ii = 0; ii < nsymbols; ii++) {
-            delete[] region->symbols[ii].name;
+        // 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->symbols;
         delete[] region->path;
 
         // Do not delete the region itself here.  Each region
@@ -422,7 +448,7 @@
 }
 
 template<class T>
-char* TraceReader<T>::GetProcessName(int pid)
+const char* TraceReader<T>::GetProcessName(int pid)
 {
     if (pid < 0 || pid >= kNumPids || processes_[pid] == NULL)
         return "(unknown)";
@@ -923,6 +949,63 @@
 }
 
 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
@@ -941,6 +1024,20 @@
 }
 
 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)
 {
@@ -965,6 +1062,30 @@
 }
 
 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)
@@ -1004,15 +1125,12 @@
             uint32_t sym_addr = addr - cached_func_->region->base_addr;
             if (sym_addr >= cached_func_->addr
                 && sym_addr < (cached_func_ + 1)->addr) {
-                // If this function is the virtual machine interpreter, then
-                // read the method trace to find the "real" method name based
-                // on the current time and pid.
-                if (cached_func_->flags & symbol_type::kIsInterpreter) {
-                    symbol_type *sym = FindCurrentMethod(pid, time);
-                    if (sym != NULL) {
-                        sym->vm_sym = cached_func_;
-                        return sym;
-                    }
+
+                // 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_;
             }
@@ -1037,15 +1155,11 @@
     if (cached_func_ != NULL) {
         cached_func_->region = region;
 
-        // If this function is the virtual machine interpreter, then
-        // read the method trace to find the "real" method name based
-        // on the current time and pid.
-        if (cached_func_->flags & symbol_type::kIsInterpreter) {
-            symbol_type *sym = FindCurrentMethod(pid, time);
-            if (sym != NULL) {
-                sym->vm_sym = cached_func_;
-                return sym;
-            }
+        // 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;
         }
     }
 
@@ -1139,11 +1253,17 @@
         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) {
+            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;
@@ -1165,8 +1285,6 @@
                 } else {
                     region->nsymbols = existing_region->nsymbols;
                     region->symbols = existing_region->symbols;
-                    region->path = existing_region->path;
-                    delete[] event->path;
                     region->flags |= region_type::kSharedSymbols;
                 }
 
@@ -1263,10 +1381,12 @@
 }
 
 template <class T>
-void TraceReader<T>::ProcessState::DumpStack()
+void TraceReader<T>::ProcessState::DumpStack(FILE *stream)
 {
+    const char *native;
     for (int ii = 0; ii < method_stack_top; ii++) {
-        printf("%2d: 0x%08x\n", ii, method_stack[ii]);
+        native = method_stack[ii].isNative ? "n" : " ";
+        fprintf(stream, "%2d: %s 0x%08x\n", ii, native, method_stack[ii].addr);
     }
 }
 
@@ -1276,13 +1396,17 @@
 {
     uint32_t addr;
     int top = pstate->method_stack_top;
-    if (method_rec->flags == kMethodEnter) {
+    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] = method_rec->addr;
+        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 {
@@ -1292,14 +1416,27 @@
             return;
         }
         top -= 1;
-        addr = pstate->method_stack[top];
-        if (addr != method_rec->addr) {
+        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);
-            for (int ii = 0; ii <= top; ii++) {
-                fprintf(stderr, "  %d: 0x%x\n", ii, pstate->method_stack[ii]);
-            }
+            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);
         }
 
@@ -1309,8 +1446,17 @@
             pstate->current_method_sym = NULL;
             return;
         }
-        addr = pstate->method_stack[top - 1];
+        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;
@@ -1323,6 +1469,11 @@
     }
 }
 
+// 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)
diff --git a/emulator/qtools/trace_reader_base.h b/emulator/qtools/trace_reader_base.h
index 281d085..416c3d1 100644
--- a/emulator/qtools/trace_reader_base.h
+++ b/emulator/qtools/trace_reader_base.h
@@ -83,7 +83,7 @@
 
     friend class BBReader;
 
-    void                Open(char *filename);
+    void                Open(const char *filename);
     void                Close();
     void                WriteHeader(TraceHeader *header);
     inline bool         ReadBB(BBEvent *event);
@@ -120,10 +120,10 @@
 
   private:
     int          FindNumInsns(uint64_t bb_num, uint64_t bb_start_time);
-    void         ReadTraceHeader(FILE *fstream, char *filename,
-                                char *tracename, TraceHeader *header);
+    void         ReadTraceHeader(FILE *fstream, const char *filename,
+                                const char *tracename, TraceHeader *header);
     PidEvent     *FindMmapDexFileEvent();
-    void         ParseDexList(char *filename);
+    void         ParseDexList(const char *filename);
 
     char         *static_filename_;
     FILE         *static_fstream_;
@@ -159,7 +159,7 @@
   public:
     explicit BBReader(TraceReaderBase *trace);
     ~BBReader();
-    void     Open(char *filename);
+    void     Open(const char *filename);
     void     Close();
     bool     ReadBB(BBEvent *event);
 
@@ -193,7 +193,7 @@
     InsnReader();
     ~InsnReader();
 
-    void        Open(char *filename);
+    void        Open(const char *filename);
     void        Close();
     uint64_t    ReadInsnTime(uint64_t min_time);
 
@@ -209,7 +209,7 @@
     AddrReader();
     ~AddrReader();
 
-    bool        Open(char *filename, char *suffix);
+    bool        Open(const char *filename, const char *suffix);
     void        Close();
     bool        ReadAddr(uint64_t *time, uint32_t *addr);
 
@@ -225,7 +225,7 @@
     ExcReader();
     ~ExcReader();
 
-    void        Open(char *filename);
+    void        Open(const char *filename);
     void        Close();
     bool        ReadExc(uint64_t *time, uint32_t *current_pc,
                         uint64_t *recnum, uint32_t *target_pc,
@@ -243,7 +243,7 @@
     PidReader();
     ~PidReader();
 
-    void        Open(char *filename);
+    void        Open(const char *filename);
     void        Close();
     bool        ReadPidEvent(struct PidEvent *event);
     void        Dispose(struct PidEvent *event);
@@ -258,7 +258,7 @@
     MethodReader();
     ~MethodReader();
 
-    bool        Open(char *filename);
+    bool        Open(const char *filename);
     void        Close();
     bool        ReadMethod(MethodRec *method_record);
 
diff --git a/emulator/sensors/sensors_qemu.c b/emulator/sensors/sensors_qemu.c
index 85a5af4..0cc636a 100644
--- a/emulator/sensors/sensors_qemu.c
+++ b/emulator/sensors/sensors_qemu.c
@@ -34,6 +34,7 @@
 #include <errno.h>
 #include <string.h>
 #include <cutils/log.h>
+#include <cutils/native_handle.h>
 #include <cutils/sockets.h>
 #include <hardware/sensors.h>
 
@@ -123,16 +124,19 @@
 /* this must return a file descriptor that will be used to read
  * the sensors data (it is passed to data__data_open() below
  */
-static int
+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);
-    return ctl->fd;
+    handle = native_handle_create(1, 0);
+    handle->data[0] = ctl->fd;
+    return handle;
 }
 
 static int
@@ -244,7 +248,7 @@
 }
 
 static int
-data__data_open(struct sensors_data_device_t *dev, int fd)
+data__data_open(struct sensors_data_device_t *dev, native_handle_t* handle)
 {
     SensorData*  data = (void*)dev;
     int i;
@@ -258,7 +262,9 @@
     data->timeStart      = 0;
     data->timeOffset     = 0;
 
-    data->events_fd = dup(fd);
+    data->events_fd = dup(handle->data[0]);
+    native_handle_close(handle);
+    native_handle_delete(handle);
     return 0;
 }
 
diff --git a/emulator/tools/Android.mk b/emulator/tools/Android.mk
new file mode 100644
index 0000000..c9d9613
--- /dev/null
+++ b/emulator/tools/Android.mk
@@ -0,0 +1,36 @@
+# 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
new file mode 100644
index 0000000..09105fc
--- /dev/null
+++ b/emulator/tools/qemu-props.c
@@ -0,0 +1,114 @@
+/*
+ * 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/ide/eclipse/.classpath b/ide/eclipse/.classpath
index a871dc0..281349b 100644
--- a/ide/eclipse/.classpath
+++ b/ide/eclipse/.classpath
@@ -36,6 +36,7 @@
 	<classpathentry kind="src" path="frameworks/base/cmds/pm/src"/>
 	<classpathentry kind="src" path="frameworks/base/cmds/svc/src"/>
 	<classpathentry kind="src" path="frameworks/base/core/java"/>
+	<classpathentry kind="src" path="frameworks/base/core/config/sdk"/>
 	<classpathentry kind="src" path="frameworks/base/graphics/java"/>
 	<classpathentry kind="src" path="frameworks/base/im/java"/>
 	<classpathentry kind="src" path="frameworks/base/location/java"/>
@@ -47,6 +48,7 @@
 	<classpathentry kind="src" path="frameworks/base/services/java"/>
 	<classpathentry kind="src" path="frameworks/base/telephony/java"/>
 	<classpathentry kind="src" path="frameworks/base/test-runner"/>
+	<classpathentry kind="src" path="frameworks/base/tts/java"/>
 	<classpathentry kind="src" path="frameworks/base/wifi/java"/>
 	<classpathentry kind="src" path="frameworks/policies/base/phone"/>
 	<classpathentry kind="src" path="development/samples/ApiDemos/src"/>
@@ -101,6 +103,7 @@
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/location/java"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/telephony/java"/>
+	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/tts/java"/>
 	<classpathentry kind="src" path="out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/wifi/java"/>
 	<classpathentry kind="src" path="out/target/common/R"/>
 	<classpathentry kind="src" path="external/tagsoup/src"/>
diff --git a/ndk/Android.mk b/ndk/Android.mk
new file mode 100644
index 0000000..1ce424d
--- /dev/null
+++ b/ndk/Android.mk
@@ -0,0 +1,3 @@
+# Please keep this file empty. It is only used to avoid breaking the Android build
+# when the NDK sources are stored in the git repository alongside the rest of the
+# platform.
diff --git a/ndk/GNUmakefile b/ndk/GNUmakefile
new file mode 100644
index 0000000..3cd1635
--- /dev/null
+++ b/ndk/GNUmakefile
@@ -0,0 +1,18 @@
+# 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.
+#
+
+# DO NOT MODIFY THIS FILE
+include build/core/main.mk
+# END OF FILE
diff --git a/ndk/README.TXT b/ndk/README.TXT
new file mode 100644
index 0000000..4c5ff7f
--- /dev/null
+++ b/ndk/README.TXT
@@ -0,0 +1,33 @@
+            Android Native Development Kit (NDK)
+
+
+Welcome, this NDK is designed to allow Android application developers
+to include native code in their Android application packages, compiled
+as JNI shared libraries.
+
+A high-level overview of the NDK's features and limitations can be found
+in docs/OVERVIEW.TXT. Please read this document as it contains crucial
+information for correct usage.
+
+See docs/STABLE-APIS.TXT for the list of frozen binary APIs exposed by
+this NDK, as well as the corresponding system image versions that support
+them.
+
+Before using the NDK, you will need to follow the steps described by
+docs/INSTALL.TXT which lists the NDK pre-requisites and the steps needed
+to set it up properly on your machine.
+
+We recommend developers to make themselves familiar with JNI concepts. Also
+note that the NDK is *not* a good way to write non-JNI native code for the
+Android platform.
+
+See docs/HOWTO.TXT for a few useful tips and tricks when using the NDK.
+
+See docs/SYSTEM-ISSUES.TXT for a list of important issues related to
+the Android system images that all NDK developers should be aware of.
+
+Finally, discussions related to the Android NDK happen on the public
+"android-ndk" forum located at the following address:
+
+    http://groups.google.com/group/android-ndk
+
diff --git a/ndk/apps/hello-jni/Application.mk b/ndk/apps/hello-jni/Application.mk
new file mode 100644
index 0000000..f5ac839
--- /dev/null
+++ b/ndk/apps/hello-jni/Application.mk
@@ -0,0 +1,2 @@
+APP_PROJECT_PATH := $(call my-dir)/project
+APP_MODULES      := hello-jni
diff --git a/ndk/apps/hello-jni/project/AndroidManifest.xml b/ndk/apps/hello-jni/project/AndroidManifest.xml
new file mode 100644
index 0000000..b6307c7
--- /dev/null
+++ b/ndk/apps/hello-jni/project/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.example.hellojni"
+      android:versionCode="1"
+      android:versionName="1.0">
+    <uses-sdk android:minSdkVersion="3" />
+    <application android:label="@string/app_name">
+        <activity android:name=".HelloJni"
+                  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/ndk/apps/hello-jni/project/default.properties b/ndk/apps/hello-jni/project/default.properties
new file mode 100644
index 0000000..4513a1e
--- /dev/null
+++ b/ndk/apps/hello-jni/project/default.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+# 
+# This file must be checked in Version Control Systems.
+# 
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-3
diff --git a/ndk/apps/hello-jni/project/libs/armeabi/.gitignore b/ndk/apps/hello-jni/project/libs/armeabi/.gitignore
new file mode 100644
index 0000000..bd01364
--- /dev/null
+++ b/ndk/apps/hello-jni/project/libs/armeabi/.gitignore
@@ -0,0 +1 @@
+lib*.so
diff --git a/ndk/apps/hello-jni/project/res/values/strings.xml b/ndk/apps/hello-jni/project/res/values/strings.xml
new file mode 100644
index 0000000..c526073
--- /dev/null
+++ b/ndk/apps/hello-jni/project/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">HelloJni</string>
+</resources>
diff --git a/ndk/apps/hello-jni/project/src/com/example/hellojni/HelloJni.java b/ndk/apps/hello-jni/project/src/com/example/hellojni/HelloJni.java
new file mode 100644
index 0000000..97ab6d9
--- /dev/null
+++ b/ndk/apps/hello-jni/project/src/com/example/hellojni/HelloJni.java
@@ -0,0 +1,66 @@
+/*
+ * 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.example.hellojni;
+
+import android.app.Activity;
+import android.widget.TextView;
+import android.os.Bundle;
+
+
+public class HelloJni extends Activity
+{
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+
+        /* Create a TextView and set its content.
+         * the text is retrieved by calling a native
+         * function.
+         */
+        TextView  tv = new TextView(this);
+        tv.setText( stringFromJNI() );
+        setContentView(tv);
+    }
+
+    /* A native method that is implemented by the
+     * 'hello-jni' native library, which is packaged
+     * with this application.
+     */
+    public native String  stringFromJNI();
+
+    /* This is another native method declaration that is *not*
+     * implemented by 'hello-jni'. This is simply to show that
+     * you can declare as many native methods in your Java code
+     * as you want, their implementation is searched in the
+     * currently loaded native libraries only the first time
+     * you call them.
+     *
+     * Trying to call this function will result in a
+     * java.lang.UnsatisfiedLinkError exception !
+     */
+    public native String  unimplementedStringFromJNI();
+
+    /* this is used to load the 'hello-jni' library on application
+     * startup. The library has already been unpacked into
+     * /data/data/com.example.HelloJni/lib/libhello-jni.so at
+     * installation time by the package manager.
+     */
+    static {
+        System.loadLibrary("hello-jni");
+    }
+}
diff --git a/ndk/apps/hello-jni/project/tests/AndroidManifest.xml b/ndk/apps/hello-jni/project/tests/AndroidManifest.xml
new file mode 100644
index 0000000..d6be01e
--- /dev/null
+++ b/ndk/apps/hello-jni/project/tests/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?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="com.example.HelloJni.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 com.example.HelloJni.  To run the tests use the command:
+    "adb shell am instrument -w com.example.HelloJni.tests/android.test.InstrumentationTestRunner"
+    -->
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="com.example.HelloJni"
+                     android:label="Tests for HelloJni"/>
+</manifest>
diff --git a/ndk/apps/hello-jni/project/tests/default.properties b/ndk/apps/hello-jni/project/tests/default.properties
new file mode 100644
index 0000000..4513a1e
--- /dev/null
+++ b/ndk/apps/hello-jni/project/tests/default.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+# 
+# This file must be checked in Version Control Systems.
+# 
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-3
diff --git a/ndk/apps/hello-jni/project/tests/src/com/example/HelloJni/HelloJniTest.java b/ndk/apps/hello-jni/project/tests/src/com/example/HelloJni/HelloJniTest.java
new file mode 100644
index 0000000..519d857
--- /dev/null
+++ b/ndk/apps/hello-jni/project/tests/src/com/example/HelloJni/HelloJniTest.java
@@ -0,0 +1,21 @@
+package com.example.HelloJni;
+
+import android.test.ActivityInstrumentationTestCase;
+
+/**
+ * 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 com.example.HelloJni.HelloJniTest \
+ * com.example.HelloJni.tests/android.test.InstrumentationTestRunner
+ */
+public class HelloJniTest extends ActivityInstrumentationTestCase<HelloJni> {
+
+    public HelloJniTest() {
+        super("com.example.HelloJni", HelloJni.class);
+    }
+
+}
diff --git a/ndk/apps/two-libs/Application.mk b/ndk/apps/two-libs/Application.mk
new file mode 100644
index 0000000..a2fd402
--- /dev/null
+++ b/ndk/apps/two-libs/Application.mk
@@ -0,0 +1,2 @@
+APP_PROJECT_PATH := $(call my-dir)/project
+APP_MODULES      := twolib-first twolib-second
diff --git a/ndk/apps/two-libs/project/AndroidManifest.xml b/ndk/apps/two-libs/project/AndroidManifest.xml
new file mode 100644
index 0000000..8ed9917
--- /dev/null
+++ b/ndk/apps/two-libs/project/AndroidManifest.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.example.twolibs"
+      android:versionCode="1"
+      android:versionName="1.0">
+    <uses-sdk android:minSdkVersion="3" />
+    <application android:label="@string/app_name">
+        <activity android:name=".TwoLibs"
+                  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/ndk/apps/two-libs/project/default.properties b/ndk/apps/two-libs/project/default.properties
new file mode 100644
index 0000000..4513a1e
--- /dev/null
+++ b/ndk/apps/two-libs/project/default.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+# 
+# This file must be checked in Version Control Systems.
+# 
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-3
diff --git a/ndk/apps/two-libs/project/libs/armeabi/.gitignore b/ndk/apps/two-libs/project/libs/armeabi/.gitignore
new file mode 100644
index 0000000..bd01364
--- /dev/null
+++ b/ndk/apps/two-libs/project/libs/armeabi/.gitignore
@@ -0,0 +1 @@
+lib*.so
diff --git a/ndk/apps/two-libs/project/res/values/strings.xml b/ndk/apps/two-libs/project/res/values/strings.xml
new file mode 100644
index 0000000..ae57f1f
--- /dev/null
+++ b/ndk/apps/two-libs/project/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">TwoLib</string>
+</resources>
diff --git a/ndk/apps/two-libs/project/src/com/example/twolibs/TwoLibs.java b/ndk/apps/two-libs/project/src/com/example/twolibs/TwoLibs.java
new file mode 100644
index 0000000..ef9da01
--- /dev/null
+++ b/ndk/apps/two-libs/project/src/com/example/twolibs/TwoLibs.java
@@ -0,0 +1,46 @@
+/*
+ * 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.example.twolibs;
+
+import android.app.Activity;
+import android.widget.TextView;
+import android.os.Bundle;
+
+public class TwoLibs extends Activity
+{
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+
+        TextView  tv = new TextView(this);
+        int       x  = 1000;
+        int       y  = 42;
+
+        // here, we dynamically load the library at runtime
+        // before calling the native method.
+        //
+        System.loadLibrary("twolib-second");
+
+        int  z = add(x, y);
+
+        tv.setText( "The sum of " + x + " and " + y + " is " + z );
+        setContentView(tv);
+    }
+
+    public native int add(int  x, int  y);
+}
diff --git a/ndk/apps/two-libs/project/tests/AndroidManifest.xml b/ndk/apps/two-libs/project/tests/AndroidManifest.xml
new file mode 100644
index 0000000..a7dd602
--- /dev/null
+++ b/ndk/apps/two-libs/project/tests/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?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="com.example.TwoLib.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 com.example.TwoLib.  To run the tests use the command:
+    "adb shell am instrument -w com.example.TwoLib.tests/android.test.InstrumentationTestRunner"
+    -->
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="com.example.TwoLib"
+                     android:label="Tests for TwoLib"/>
+</manifest>
diff --git a/ndk/apps/two-libs/project/tests/default.properties b/ndk/apps/two-libs/project/tests/default.properties
new file mode 100644
index 0000000..4513a1e
--- /dev/null
+++ b/ndk/apps/two-libs/project/tests/default.properties
@@ -0,0 +1,11 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+# 
+# This file must be checked in Version Control Systems.
+# 
+# To customize properties used by the Ant build system use,
+# "build.properties", and override values to adapt the script to your
+# project structure.
+
+# Project target.
+target=android-3
diff --git a/ndk/apps/two-libs/project/tests/src/com/example/TwoLib/TwoLibTest.java b/ndk/apps/two-libs/project/tests/src/com/example/TwoLib/TwoLibTest.java
new file mode 100644
index 0000000..2924502
--- /dev/null
+++ b/ndk/apps/two-libs/project/tests/src/com/example/TwoLib/TwoLibTest.java
@@ -0,0 +1,21 @@
+package com.example.TwoLib;
+
+import android.test.ActivityInstrumentationTestCase;
+
+/**
+ * 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 com.example.TwoLib.TwoLibTest \
+ * com.example.TwoLib.tests/android.test.InstrumentationTestRunner
+ */
+public class TwoLibTest extends ActivityInstrumentationTestCase<TwoLib> {
+
+    public TwoLibTest() {
+        super("com.example.TwoLib", TwoLib.class);
+    }
+
+}
diff --git a/ndk/build/core/add-application.mk b/ndk/build/core/add-application.mk
new file mode 100644
index 0000000..e402652
--- /dev/null
+++ b/ndk/build/core/add-application.mk
@@ -0,0 +1,62 @@
+# 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 script is used to record an application definition in the
+# NDK build system, before performing any build whatsoever.
+#
+# It is included repeatedly from build/core/main.mk and expects a
+# variable named '_application_mk' which points to a given Application.mk
+# file that will be included here. The latter must define a few variables
+# to describe the application to the build system, and the rest of the
+# code here will perform book-keeping and basic checks
+#
+
+$(call assert-defined, _application_mk)
+
+$(call clear-vars, $(NDK_APP_VARS))
+
+include $(_application_mk)
+
+$(call check-required-vars,$(NDK_APP_VARS_REQUIRED),$(_application_mk))
+
+# strip the 'lib' prefix in front of APP_MODULES modules
+APP_MODULES := $(call strip-lib-prefix,$(APP_MODULES))
+
+# check that APP_OPTIM, if defined, is either 'release' or 'debug'
+$(if $(filter-out release debug,$(APP_OPTIM)),\
+  $(call __ndk_info, The APP_OPTIM defined in $(_application_mk) must only be 'release' or 'debug')\
+  $(call __ndk_error,Aborting)\
+)
+
+_dir  := $(patsubst %/,%,$(dir $(_application_mk)))
+_name := $(notdir $(_dir))
+_app  := NDK_APP.$(_name)
+
+$(if $(strip $(APP.$(_app).defined)),\
+  $(call __ndk_info,Weird, the application $(_name) is already defined by $(APP.$(_app).defined))\
+  $(call __ndk_error,Aborting)\
+)
+
+APP.$(_app).defined := $(_application_mk)
+
+# Record all app-specific variable definitions
+$(foreach __name,$(NDK_APP_VARS),\
+  $(eval $(_app).$(__name) := $($(__name)))\
+)
+
+# Record the Application.mk for debugging
+$(_app).Application.mk := $(_application_mk)
+
+NDK_ALL_APPS += $(_name)
diff --git a/ndk/build/core/add-toolchain.mk b/ndk/build/core/add-toolchain.mk
new file mode 100644
index 0000000..498d624
--- /dev/null
+++ b/ndk/build/core/add-toolchain.mk
@@ -0,0 +1,65 @@
+# 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 script is included repeatedly by main.mk to add a new toolchain
+# definition to the NDK build system.
+#
+# 'toolchain_config' must be defined as the path of a toolchain
+# configuration file (config.mk) that will be included here.
+#
+$(call assert-defined, _config_mk)
+
+# The list of variables that must or may be defined
+# by the toolchain configuration file
+#
+NDK_TOOLCHAIN_VARS_REQUIRED := TOOLCHAIN_ABIS
+NDK_TOOLCHAIN_VARS_OPTIONAL :=
+
+# Clear variables that are supposed to be defined by the config file
+$(call clear-vars,$(NDK_TOOLCHAIN_VARS_REQUIRED))
+$(call clear-vars,$(NDK_TOOLCHAIN_VARS_OPTIONAL))
+
+# Include the config file
+include $(_config_mk)
+
+# Check that the proper variables were defined
+$(call check-required-vars,$(NDK_TOOLCHAIN_VARS_REQUIRED),$(_config_mk))
+
+# Check that the file didn't do something stupid
+$(call assert-defined, _config_mk)
+
+# Now record the toolchain-specific informatio
+_dir  := $(patsubst %/,%,$(dir $(_config_mk)))
+_name := $(notdir $(_dir))
+_abis := $(TOOLCHAIN_ABIS)
+
+_toolchain := NDK_TOOLCHAIN.$(_name)
+
+# check that the toolchain name is unique
+$(if $(strip $($(_toolchain).defined)),\
+  $(call __ndk_error,Toolchain $(_name) defined in $(_parent) is\
+                     already defined in $(NDK_TOOLCHAIN.$(_name).defined)))
+
+$(_toolchain).defined := $(_toolchain_config)
+$(_toolchain).abis    := $(_abis)
+$(_toolchain).setup   := $(wildcard $(_dir)/setup.mk)
+
+$(if $(strip $($(_toolchain).setup)),,\
+  $(call __ndk_error, Toolchain $(_name) lacks a setup.mk in $(_dir)))
+
+NDK_ALL_TOOLCHAINS += $(_name)
+NDK_ALL_ABIS       += $(_abis)
+
+# done
diff --git a/ndk/build/core/build-binary.mk b/ndk/build/core/build-binary.mk
new file mode 100644
index 0000000..1446a7d
--- /dev/null
+++ b/ndk/build/core/build-binary.mk
@@ -0,0 +1,136 @@
+# 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.
+#
+
+# we expect the 'my' variable to be defined, either to
+# 'HOST_' or 'TARGET_', and this allows us to call the
+# appropriate compiler with $($(my)CC)
+#
+$(call assert-defined,my)
+
+# LOCAL_MAKEFILE must also exist and name the Android.mk that
+# included the module build script.
+#
+$(call assert-defined,LOCAL_MAKEFILE)
+
+include $(BUILD_SYSTEM)/build-module.mk
+
+# list of generated object files
+LOCAL_OBJECTS :=
+
+# always define ANDROID when building binaries
+#
+LOCAL_CFLAGS := -DANDROID $(LOCAL_CFLAGS)
+
+#
+# Add the default system shared libraries to the build
+#
+ifndef LOCAL_IS_HOST_MODULE
+  ifeq ($(LOCAL_SYSTEM_SHARED_LIBRARIES),none)
+    LOCAL_SHARED_LIBRARIES += $(TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES)
+  else
+    LOCAL_SHARED_LIBRARIES += $(LOCAL_SYSTEM_SHARED_LIBRARIES)
+  endif
+endif
+
+
+#
+# Check LOCAL_CPP_EXTENSION, use '.cpp' by default
+#
+LOCAL_CPP_EXTENSION := $(strip $(LOCAL_CPP_EXTENSION))
+ifeq ($(LOCAL_CPP_EXTENSION),)
+  LOCAL_CPP_EXTENSION := .cpp
+else
+  ifneq ($(words $(LOCAL_CPP_EXTENSION)),1)
+    $(call __ndk_log, LOCAL_CPP_EXTENSION in $(LOCAL_MAKEFILE) must be one word only, not '$(LOCAL_CPP_EXTENSION)')
+    $(call __ndk_error, Aborting)
+  endif
+endif
+
+#
+# If LOCAL_ALLOW_UNDEFINED_SYMBOLS, the linker will allow the generation
+# of a binary that uses undefined symbols.
+#
+ifeq ($(strip $(LOCAL_ALLOW_UNDEFINED_SYMBOLS)),)
+  LOCAL_LDFLAGS := $(LOCAL_LDFLAGS) $($(my)NO_UNDEFINED_LDFLAGS)
+endif
+
+#
+# The original Android build system allows you to use the .arm prefix
+# to a source file name to indicate that it should be defined in either
+# 'thumb' or 'arm' mode, depending on the value of LOCAL_ARM_MODE
+#
+# First, check LOCAL_ARM_MODE, it should be empty, 'thumb' or 'arm'
+# We make the default 'thumb'
+#
+LOCAL_ARM_MODE := $(strip $(LOCAL_ARM_MODE))
+ifeq ($(LOCAL_ARM_MODE),)
+  LOCAL_ARM_MODE := thumb
+else
+  ifneq ($(words $(LOCAL_ARM_MODE)),1)
+      $(call __ndk_log,   LOCAL_ARM_MODE in $(LOCAL_MAKEFILE) must be one word, not '$(LOCAL_ARM_MODE)')
+      $(call __ndk_error, Aborting)
+  endif
+  # check that LOCAL_ARM_MODE is defined to either 'arm' or 'thumb'
+  $(if $(filter-out thumb arm, $(LOCAL_ARM_MODE)),\
+      $(call __ndk_log,   LOCAL_ARM_MODE must be defined to either 'arm' or 'thumb' in $(LOCAL_MAKEFILE), not '$(LOCAL_ARM_MODE)')\
+      $(call __ndk_error, Aborting)\
+  )
+endif
+
+LOCAL_ARM_TEXT_arm   = arm$(space)$(space)
+LOCAL_ARM_TEXT_thumb = thumb
+
+LOCAL_ARM_CFLAGS := $(TARGET_$(LOCAL_ARM_MODE)_$(LOCAL_BUILD_MODE)_CFLAGS)
+LOCAL_ARM_TEXT   := $(LOCAL_ARM_TEXT_$(LOCAL_ARM_MODE))
+
+# As a special case, the original Android build system
+# allows one to specify that certain source files can be
+# forced to build in ARM mode by using a '.arm' suffix
+# after the extension, e.g.
+#
+#  LOCAL_SRC_FILES := foo.c.arm
+#
+# to build source file $(LOCAL_PATH)/foo.c as ARM
+#
+
+#
+# Build C source files into .o
+#
+
+# XXX: TODO: support LOCAL_ARM_MODE
+
+arm_sources := $(LOCAL_SRC_FILES:%.arm)
+
+c_sources := $(filter %.c, \
+                 $(LOCAL_SRC_FILES) \
+                 $(arm_sources:%.arm=%))
+
+s_sources := $(filter %.S, \
+                 $(LOCAL_SRC_FILES) \
+                 $(arm_sources:%.arm=%))
+
+cpp_sources := $(filter %$(LOCAL_CPP_EXTENSION), \
+                   $(LOCAL_SRC_FILES) \
+                   $(arm_sources:%.arm=%))
+
+#
+# The following will update LOCAL_OBJECTS and LOCAL_DEPENDENCY_DIRS
+#
+$(foreach src,$(c_sources),   $(call compile-c-source,$(src)))
+$(foreach src,$(s_sources),   $(call compile-s-source,$(src)))
+$(foreach src,$(cpp_sources), $(call compile-cpp-source,$(src)))
+
+ALL_DEPENDENCY_DIRS += $(sort $(LOCAL_DEPENDENCY_DIRS))
+CLEAN_OBJS_DIRS     += $(LOCAL_OBJS_DIR)
diff --git a/ndk/build/core/build-executable.mk b/ndk/build/core/build-executable.mk
new file mode 100644
index 0000000..aedcabd
--- /dev/null
+++ b/ndk/build/core/build-executable.mk
@@ -0,0 +1,72 @@
+# 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 included from Android.mk files to build a target-specific
+# executable program
+#
+
+LOCAL_BUILD_SCRIPT := BUILD_EXECUTABLE
+LOCAL_MODULE_CLASS := EXECUTABLE
+LOCAL_MAKEFILE     := $(local-makefile)
+
+$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT))
+$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
+
+# only adjust the build if this module is needed by the current app
+ifneq ($(filter $(LOCAL_MODULE),$(NDK_APP_MODULES)),)
+
+# we are building target objects
+my := TARGET_
+
+LOCAL_BUILT_MODULE := $(call executable-path,$(LOCAL_MODULE))
+LOCAL_OBJS_DIR     := $(TARGET_OBJS)/$(LOCAL_MODULE)
+
+include $(BUILD_SYSTEM)/build-binary.mk
+
+LOCAL_STATIC_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_STATIC_LIBRARIES))
+LOCAL_SHARED_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_SHARED_LIBRARIES))
+
+static_libraries := $(call map,static-library-path,$(LOCAL_STATIC_LIBRARIES))
+shared_libraries := $(call map,shared-library-path,$(LOCAL_SHARED_LIBRARIES)) \
+                    $(TARGET_PREBUILT_SHARED_LIBRARIES)
+
+$(LOCAL_BUILT_MODULE): $(static_libraries) $(shared_libraries)
+
+LOCAL_LDLIBS := $(_module_libs) $(LOCAL_LDLIBS)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_STATIC_LIBRARIES := $(static_libraries)
+$(LOCAL_BUILT_MODULE): PRIVATE_SHARED_LIBRARIES := $(shared_libraries)
+$(LOCAL_BUILT_MODULE): PRIVATE_OBJECTS          := $(LOCAL_OBJECTS)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_LDFLAGS := $(TARGET_LDFLAGS) $(LOCAL_LDFLAGS)
+$(LOCAL_BUILT_MODULE): PRIVATE_LDLIBS  := $(LOCAL_LDLIBS) $(TARGET_LDLIBS)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_NAME := $(notdir $(LOCAL_BUILT_MODULE))
+$(LOCAL_BUILT_MODULE): PRIVATE_DEST := $(NDK_APP_DEST)
+$(LOCAL_BUILT_MODULE): PRIVATE_SRC  := $(LOCAL_BUILT_MODULE)
+$(LOCAL_BUILT_MODULE): PRIVATE_DST  := $(PRIVATE_DEST)/$(PRIVATE_NAME)
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS)
+	@ mkdir -p $(dir $@)
+	@ echo "Executable     : $(PRIVATE_NAME)"
+	$(hide) $(cmd-build-executable)
+	@ echo "Install        : $(PRIVATE_NAME) => $(PRIVATE_DEST)"
+	$(hide) mkdir -p $(PRIVATE_DEST)
+	$(hide) install -p $(PRIVATE_SRC) $(PRIVATE_DST)
+	$(hide) $(call cmd-strip, $(PRIVATE_DST))
+
+ALL_EXECUTABLES += $(LOCAL_BUILT_MODULE)
+
+endif # filter LOCAL_MODULE in NDK_APP_MODULES
diff --git a/ndk/build/core/build-module.mk b/ndk/build/core/build-module.mk
new file mode 100644
index 0000000..83cc38c
--- /dev/null
+++ b/ndk/build/core/build-module.mk
@@ -0,0 +1,78 @@
+# 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.
+#
+
+#
+# Base rules shared to control the build of all modules.
+# This should be included from build-binary.mk
+#
+
+$(call assert-defined,LOCAL_MODULE_CLASS LOCAL_BUILD_SCRIPT LOCAL_BUILT_MODULE)
+
+# Check LOCAL_IS_HOST_MODULE and define 'my' as either HOST_ or TARGET_
+#
+LOCAL_IS_HOST_MODULE := $(strip $(LOCAL_IS_HOST_MODULE))
+ifdef LOCAL_IS_HOST_MODULE
+  ifneq ($(LOCAL_IS_HOST_MODULE),true)
+    $(call __ndk_log,$(LOCAL_PATH): LOCAL_IS_HOST_MODULE must be "true" or empty, not "$(LOCAL_IS_HOST_MODULE)")
+  endif
+  my := HOST_
+else
+  my := TARGET_
+endif
+
+# Compute 'intermediates' which is the location where we're going to store
+# intermediate generated files like object (.o) files.
+#
+intermediates := $($(my)OBJS)
+
+# LOCAL_INTERMEDIATES lists the targets that are generated by this module
+#
+LOCAL_INTERMEDIATES := $(LOCAL_BUILT_MODULE)
+
+# LOCAL_BUILD_MODE will be either arm or thumb
+#
+ifneq ($(NDK_APP_OPTIM),)
+    LOCAL_BUILD_MODE := $(NDK_APP_OPTIM)
+else
+    LOCAL_BUILD_MODE := thumb
+endif
+
+#
+# Ensure that 'make <module>' and 'make clean-<module>' work
+#
+.PHONY: $(LOCAL_MODULE)
+$(LOCAL_MODULE): $(LOCAL_BUILT_MODULE)
+
+cleantarget := clean-$(LOCAL_MODULE)
+.PHONY: $(cleantarget)
+clean: $(cleantarget)
+
+$(cleantarget): PRIVATE_MODULE      := $(LOCAL_MODULE)
+$(cleantarget): PRIVATE_CLEAN_FILES := $(PRIVATE_CLEAN_FILES) \
+                                       $(LOCAL_BUILT_MODULE) \
+                                       $(LOCAL_INSTALLED_MODULE) \
+                                       $(intermediates)
+
+$(cleantarget)::
+	@echo "Clean: $(PRIVATE_MODULE)"
+	$(hide) rm -rf $(PRIVATE_CLEAN_FILES)
+
+#
+# Register module
+#
+
+ALL_MODULES += $(LOCAL_MODULE)
+
+
diff --git a/ndk/build/core/build-shared-library.mk b/ndk/build/core/build-shared-library.mk
new file mode 100644
index 0000000..7cf9841
--- /dev/null
+++ b/ndk/build/core/build-shared-library.mk
@@ -0,0 +1,82 @@
+# 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 included from Android.mk files to build a target-specific
+# executable program
+#
+
+LOCAL_BUILD_SCRIPT := BUILD_SHARED_LIBRARY
+LOCAL_MODULE_CLASS := SHARED_LIBRARY
+LOCAL_MAKEFILE     := $(local-makefile)
+
+$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT))
+$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
+
+# only adjust the build if this module is needed by the current app
+ifneq ($(filter $(LOCAL_MODULE),$(NDK_APP_MODULES)),)
+
+# we are building target objects
+my := TARGET_
+
+LOCAL_BUILT_MODULE := $(call shared-library-path,$(LOCAL_MODULE))
+LOCAL_OBJS_DIR     := $(TARGET_OBJS)/$(LOCAL_MODULE)
+
+include $(BUILD_SYSTEM)/build-binary.mk
+
+LOCAL_STATIC_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_STATIC_LIBRARIES))
+LOCAL_SHARED_LIBRARIES := $(call strip-lib-prefix,$(LOCAL_SHARED_LIBRARIES))
+
+static_libraries := $(call map,static-library-path,$(LOCAL_STATIC_LIBRARIES))
+shared_libraries := $(call map,shared-library-path,$(LOCAL_SHARED_LIBRARIES)) \
+                    $(TARGET_PREBUILT_SHARED_LIBRARIES)
+
+$(LOCAL_BUILT_MODULE): $(static_libraries) $(shared_libraries)
+
+LOCAL_LDLIBS := $(_module_libs) $(LOCAL_LDLIBS)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_STATIC_LIBRARIES := $(static_libraries)
+$(LOCAL_BUILT_MODULE): PRIVATE_SHARED_LIBRARIES := $(shared_libraries)
+$(LOCAL_BUILT_MODULE): PRIVATE_OBJECTS          := $(LOCAL_OBJECTS)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_LDFLAGS := $(TARGET_LDFLAGS) $(LOCAL_LDFLAGS)
+$(LOCAL_BUILT_MODULE): PRIVATE_LDLIBS  := $(LOCAL_LDLIBS) $(TARGET_LDLIBS)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_NAME := $(notdir $(LOCAL_BUILT_MODULE))
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS)
+	@ mkdir -p $(dir $@)
+	@ echo "SharedLibrary  : $(PRIVATE_NAME)"
+	$(hide) $(cmd-build-shared-library)
+
+ALL_SHARED_LIBRARIES += $(LOCAL_BUILT_MODULE)
+
+# Installed module handling
+#
+LOCAL_INSTALLED_MODULE := $(NDK_APP_DEST)/$(notdir $(LOCAL_BUILT_MODULE))
+
+$(LOCAL_INSTALLED_MODULE): PRIVATE_NAME := $(notdir $(LOCAL_BUILT_MODULE))
+$(LOCAL_INSTALLED_MODULE): PRIVATE_SRC  := $(LOCAL_BUILT_MODULE)
+$(LOCAL_INSTALLED_MODULE): PRIVATE_DEST := $(NDK_APP_DEST)
+$(LOCAL_INSTALLED_MODULE): PRIVATE_DST  := $(LOCAL_INSTALLED_MODULE)
+
+$(LOCAL_INSTALLED_MODULE): $(LOCAL_BUILT_MODULE)
+	@ echo "Install        : $(PRIVATE_NAME) => $(PRIVATE_DEST)"
+	$(hide) mkdir -p $(PRIVATE_DEST)
+	$(hide) install -p $(PRIVATE_SRC) $(PRIVATE_DST)
+	$(hide) $(call cmd-strip, $(PRIVATE_DST))
+
+ALL_INSTALLED_MODULES += $(LOCAL_INSTALLED_MODULE)
+
+endif # filter LOCAL_MODULE in NDK_APP_MODULES
diff --git a/ndk/build/core/build-static-library.mk b/ndk/build/core/build-static-library.mk
new file mode 100644
index 0000000..3bbf75e
--- /dev/null
+++ b/ndk/build/core/build-static-library.mk
@@ -0,0 +1,64 @@
+# 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 included from Android.mk files to build a target-specific
+# executable program
+#
+
+LOCAL_BUILD_SCRIPT := BUILD_STATIC_LIBRARY
+LOCAL_MODULE_CLASS := STATIC_LIBRARY
+LOCAL_MAKEFILE     := $(local-makefile)
+
+$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT))
+$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
+
+# only adjust the build if this module is needed by the current app
+ifneq ($(filter $(LOCAL_MODULE),$(NDK_APP_MODULES)),)
+
+# we are building target objects
+my := TARGET_
+
+LOCAL_BUILT_MODULE := $(call static-library-path,$(LOCAL_MODULE))
+LOCAL_OBJS_DIR     := $(TARGET_OBJS)/$(LOCAL_MODULE)
+
+include $(BUILD_SYSTEM)/build-binary.mk
+
+static_libraries := $(call map,static-library-path,$(LOCAL_STATIC_LIBRARIES))
+shared_libraries := $(call map,shared-library-path,$(LOCAL_SHARED_LIBRARIES)) \
+                    $(TARGET_PREBUILT_SHARED_LIBRARIES)
+
+$(LOCAL_BUILT_MODULE): $(static_libraries) $(shared_libraries)
+
+LOCAL_LDLIBS := $(_module_libs) $(LOCAL_LDLIBS)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_STATIC_LIBRARIES := $(static_libraries)
+$(LOCAL_BUILT_MODULE): PRIVATE_SHARED_LIBRARIES := $(shared_libraries)
+$(LOCAL_BUILT_MODULE): PRIVATE_OBJECTS          := $(LOCAL_OBJECTS)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_LDFLAGS := $(TARGET_LDFLAGS) $(LOCAL_LDFLAGS)
+$(LOCAL_BUILT_MODULE): PRIVATE_LDLIBS  := $(LOCAL_LDLIBS) $(TARGET_LDLIBS)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_NAME := $(notdir $(LOCAL_BUILT_MODULE))
+$(LOCAL_BUILT_MODULE): PRIVATE_SRC  := $(LOCAL_BUILT_MODULE)
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS)
+	@ mkdir -p $(dir $@)
+	@ echo "StaticLibrary  : $(PRIVATE_NAME)"
+	$(hide) rm -rf $@
+	$(hide) $(cmd-build-static-library)
+
+ALL_STATIC_LIBRARIES += $(LOCAL_BUILT_MODULE)
+
+endif # filter LOCAL_MODULE in NDK_APP_MODULES
diff --git a/ndk/build/core/clear-vars.mk b/ndk/build/core/clear-vars.mk
new file mode 100644
index 0000000..0d27022
--- /dev/null
+++ b/ndk/build/core/clear-vars.mk
@@ -0,0 +1,33 @@
+# 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 included repeatedly from Android.mk files in order to clean
+# the module-specific variables from the environment,
+
+NDK_LOCAL_VARS := \
+  LOCAL_MODULE \
+  LOCAL_SRC_FILES \
+  LOCAL_CFLAGS \
+  LOCAL_LDFLAGS \
+  LOCAL_ARFLAGS \
+  LOCAL_CPP_EXTENSION \
+  LOCAL_STATIC_LIBRARIES \
+  LOCAL_STATIC_WHOLE_LIBRARIES \
+  LOCAL_SHARED_LIBRARIES \
+  LOCAL_MAKEFILE \
+  LOCAL_NO_UNDEFINED_SYMBOLS \
+
+$(call clear-vars, $(NDK_LOCAL_VARS))
+
diff --git a/ndk/build/core/definitions.mk b/ndk/build/core/definitions.mk
new file mode 100644
index 0000000..1a425de
--- /dev/null
+++ b/ndk/build/core/definitions.mk
@@ -0,0 +1,483 @@
+# 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.
+#
+# Common definitions for the Android NDK build system
+#
+
+# We use the GNU Make Standard Library
+include build/gmsl/gmsl
+
+# This is the Android NDK version number as a list of three items:
+# major, minor, revision
+#
+ndk_version := 1 0 0
+
+# Used to output warnings and error from the library, it's possible to
+# disable any warnings or errors by overriding these definitions
+# manually or by setting GMSL_NO_WARNINGS or GMSL_NO_ERRORS
+
+__ndk_name    := Android NDK
+__ndk_info     = $(info $(__ndk_name): $1 $2 $3 $4 $5)
+__ndk_warning  = $(warning $(__ndk_name): $1 $2 $3 $4 $5)
+__ndk_error    = $(error $(__ndk_name): $1 $2 $3 $4 $5)
+
+ifdef NDK_NO_WARNINGS
+__ndk_warning :=
+endif
+ifdef NDK_NO_ERRORS
+__ndk_error :=
+endif
+
+# If NDK_TRACE is enabled then calls to the library functions are
+# traced to stdout using warning messages with their arguments
+
+ifdef NDK_TRACE
+__ndk_tr1 = $(warning $0('$1'))
+__ndk_tr2 = $(warning $0('$1','$2'))
+__ndk_tr3 = $(warning $0('$1','$2','$3'))
+else
+__ndk_tr1 :=
+__ndk_tr2 :=
+__ndk_tr3 :=
+endif
+
+# -----------------------------------------------------------------------------
+# Function : ndk_log
+# Arguments: 1: text to print when NDK_LOG is defined
+# Returns  : None
+# Usage    : $(call ndk_log,<some text>)
+# -----------------------------------------------------------------------------
+ifdef NDK_LOG
+ndk_log = $(info $(__ndk_name): $1)
+else
+ndk_log :=
+endif
+
+
+# -----------------------------------------------------------------------------
+# Macro    : empty
+# Returns  : an empty macro
+# Usage    : $(empty)
+# -----------------------------------------------------------------------------
+empty :=
+
+# -----------------------------------------------------------------------------
+# Macro    : space
+# Returns  : a single space
+# Usage    : $(space)
+# -----------------------------------------------------------------------------
+space  := $(empty) $(empty)
+
+# -----------------------------------------------------------------------------
+# Function : last2
+# Arguments: a list
+# Returns  : the penultimate (next-to-last) element of a list
+# Usage    : $(call last2, <LIST>)
+# -----------------------------------------------------------------------------
+last2 = $(word $(words $1), x $1)
+
+# -----------------------------------------------------------------------------
+# Function : last3
+# Arguments: a list
+# Returns  : the antepenultimate (second-next-to-last) element of a list
+# Usage    : $(call last3, <LIST>)
+# -----------------------------------------------------------------------------
+last3 = $(word $(words $1), x x $1)
+
+# -----------------------------------------------------------------------------
+# Macro    : this-makefile
+# Returns  : the name of the current Makefile in the inclusion stack
+# Usage    : $(this-makefile)
+# -----------------------------------------------------------------------------
+this-makefile = $(lastword $(MAKEFILE_LIST))
+
+# -----------------------------------------------------------------------------
+# Macro    : local-makefile
+# Returns  : the name of the last parsed Android.mk file
+# Usage    : $(local-makefile)
+# -----------------------------------------------------------------------------
+local-makefile = $(lastword $(filter %Android.mk,$(MAKEFILE_LIST)))
+
+# -----------------------------------------------------------------------------
+# Function : assert-defined
+# Arguments: 1: list of variable names
+# Returns  : None
+# Usage    : $(call assert-defined, VAR1 VAR2 VAR3...)
+# Rationale: Checks that all variables listed in $1 are defined, or abort the
+#            build
+# -----------------------------------------------------------------------------
+assert-defined = $(foreach __varname,$(strip $1),\
+  $(if $(strip $($(__varname))),,\
+    $(call __ndk_error, Assertion failure: $(__varname) is not defined)\
+  )\
+)
+
+# -----------------------------------------------------------------------------
+# Function : clear-vars
+# Arguments: 1: list of variable names
+#            2: file where the variable should be defined
+# Returns  : None
+# Usage    : $(call clear-vars, VAR1 VAR2 VAR3...)
+# Rationale: Clears/undefines all variables in argument list
+# -----------------------------------------------------------------------------
+clear-vars = $(foreach __varname,$1,$(eval $(__varname) := $(empty)))
+
+# -----------------------------------------------------------------------------
+# Function : check-required-vars
+# Arguments: 1: list of variable names
+#            2: file where the variable(s) should be defined
+# Returns  : None
+# Usage    : $(call check-required-vars, VAR1 VAR2 VAR3..., <file>)
+# Rationale: Checks that all required vars listed in $1 were defined by $2
+#            or abort the build with an error
+# -----------------------------------------------------------------------------
+check-required-vars = $(foreach __varname,$1,\
+  $(if $(strip $($(__varname))),,\
+    $(call __ndk_info, Required variable $(__varname) is not defined by $2)\
+    $(call __ndk_error,Aborting)\
+  )\
+)
+
+# -----------------------------------------------------------------------------
+# Function : modules-clear
+# Arguments: None
+# Returns  : None
+# Usage    : $(call modules-clear)
+# Rationale: clears the list of defined modules known by the build system
+# -----------------------------------------------------------------------------
+modules-clear = $(eval __ndk_modules := $(empty_set))
+
+# -----------------------------------------------------------------------------
+# Function : modules-add
+# Arguments: 1: module name
+#            2: path to Android.mk where the module is defined
+# Returns  : None
+# Usage    : $(call modules-add,<modulename>,<Android.mk path>)
+# Rationale: add a new module. If it is already defined, print an error message
+#            and abort.
+# -----------------------------------------------------------------------------
+modules-add = \
+  $(if $(call set_is_member,$(__ndk_modules),$1),\
+       $(call __ndk_info,Trying to define local module '$1' in $2.)\
+       $(call __ndk_info,But this module was already defined by $(__ndk_modules.$1).)\
+       $(call __ndk_error,Aborting.)\
+  )\
+  $(eval __ndk_modules := $(call set_insert,$(__ndk_modules),$1))\
+  $(eval __ndk_modules.$1 := $2)\
+
+# -----------------------------------------------------------------------------
+# Function : check-user-define
+# Arguments: 1: name of variable that must be defined by the user
+#            2: name of Makefile where the variable should be defined
+#            3: name/description of the Makefile where the check is done, which
+#               must be included by $2
+# Returns  : None
+# -----------------------------------------------------------------------------
+check-user-define = $(if $(strip $($1)),,\
+  $(call __ndk_error,Missing $1 before including $3 in $2))
+
+# -----------------------------------------------------------------------------
+# This is used to check that LOCAL_MODULE is properly defined by an Android.mk
+# file before including one of the $(BUILD_SHARED_LIBRARY), etc... files.
+#
+# Function : check-user-LOCAL_MODULE
+# Arguments: 1: name/description of the included build Makefile where the
+#               check is done
+# Returns  : None
+# Usage    : $(call check-user-LOCAL_MODULE, BUILD_SHARED_LIBRARY)
+# -----------------------------------------------------------------------------
+check-defined-LOCAL_MODULE = \
+  $(call check-user-define,LOCAL_MODULE,$(local-makefile),$(1)) \
+  $(if $(call seq,$(words $(LOCAL_MODULE)),1),,\
+    $(call __ndk_info,LOCAL_MODULE definition in $(local-makefile) must not contain space)\
+    $(call __ndk_error,Please correct error. Aborting)\
+  )
+
+# -----------------------------------------------------------------------------
+# Strip any 'lib' prefix in front of a given string.
+#
+# Function : strip-lib-prefix
+# Arguments: 1: module name
+# Returns  : module name, without any 'lib' prefix if any
+# Usage    : $(call strip-lib-prefix,$(LOCAL_MODULE))
+# -----------------------------------------------------------------------------
+strip-lib-prefix = $(1:lib%=%)
+
+# -----------------------------------------------------------------------------
+# This is used to strip any lib prefix from LOCAL_MODULE, then check that
+# the corresponding module name is not already defined.
+#
+# Function : check-user-LOCAL_MODULE
+# Arguments: 1: path of Android.mk where this LOCAL_MODULE is defined
+# Returns  : None
+# Usage    : $(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
+# -----------------------------------------------------------------------------
+check-LOCAL_MODULE = \
+  $(eval LOCAL_MODULE := $$(call strip-lib-prefix,$$(LOCAL_MODULE)))\
+  $(call modules-add,$(LOCAL_MODULE),$1)
+
+# -----------------------------------------------------------------------------
+# Macro    : my-dir
+# Returns  : the directory of the current Makefile
+# Usage    : $(my-dir)
+# -----------------------------------------------------------------------------
+my-dir = $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
+
+# -----------------------------------------------------------------------------
+# Function : all-makefiles-under
+# Arguments: 1: directory path
+# Returns  : a list of all makefiles immediately below some directory
+# Usage    : $(call all-makefiles-under, <some path>)
+# -----------------------------------------------------------------------------
+all-makefiles-under = $(wildcard $1/*/Android.mk)
+
+# -----------------------------------------------------------------------------
+# Macro    : all-subdir-makefiles
+# Returns  : list of all makefiles in subdirectories of the current Makefile's
+#            location
+# Usage    : $(all-subdir-makefiles)
+# -----------------------------------------------------------------------------
+all-subdir-makefiles = $(call all-makefiles-under,$(call my-dir))
+
+
+# =============================================================================
+#
+# Application.mk support
+#
+# =============================================================================
+
+# the list of variables that *must* be defined in Application.mk files
+NDK_APP_VARS_REQUIRED := APP_MODULES APP_PROJECT_PATH
+
+# the list of variables that *may* be defined in Application.mk files
+NDK_APP_VARS_OPTIONAL := APP_OPTIM APP_CPPFLAGS APP_CFLAGS APP_CXXFLAGS
+
+# the list of all variables that may appear in an Application.mk file
+NDK_APP_VARS := $(NDK_APP_VARS_REQUIRED) $(NDK_APP_VARS_OPTIONAL)
+
+# =============================================================================
+#
+# Android.mk support
+#
+# =============================================================================
+
+
+# =============================================================================
+#
+# Generated files support
+#
+# =============================================================================
+
+
+# -----------------------------------------------------------------------------
+# Function  : host-static-library-path
+# Arguments : 1: library module name (e.g. 'foo')
+# Returns   : location of generated host library name (e.g. '..../libfoo.a)
+# Usage     : $(call host-static-library-path,<modulename>)
+# -----------------------------------------------------------------------------
+host-static-library-path = $(HOST_OUT)/lib$1.a
+
+# -----------------------------------------------------------------------------
+# Function  : host-executable-path
+# Arguments : 1: executable module name (e.g. 'foo')
+# Returns   : location of generated host executable name (e.g. '..../foo)
+# Usage     : $(call host-executable-path,<modulename>)
+# -----------------------------------------------------------------------------
+host-executable-path = $(HOST_OUT)/$1$(HOST_EXE)
+
+# -----------------------------------------------------------------------------
+# Function  : static-library-path
+# Arguments : 1: library module name (e.g. 'foo')
+# Returns   : location of generated static library name (e.g. '..../libfoo.a)
+# Usage     : $(call static-library-path,<modulename>)
+# -----------------------------------------------------------------------------
+static-library-path = $(TARGET_OUT)/lib$1.a
+
+# -----------------------------------------------------------------------------
+# Function  : shared-library-path
+# Arguments : 1: library module name (e.g. 'foo')
+# Returns   : location of generated shared library name (e.g. '..../libfoo.so)
+# Usage     : $(call shared-library-path,<modulename>)
+# -----------------------------------------------------------------------------
+shared-library-path = $(TARGET_OUT)/lib$1.so
+
+# -----------------------------------------------------------------------------
+# Function  : executable-path
+# Arguments : 1: executable module name (e.g. 'foo')
+# Returns   : location of generated exectuable name (e.g. '..../foo)
+# Usage     : $(call executable-path,<modulename>)
+# -----------------------------------------------------------------------------
+executable-path = $(TARGET_OUT)/$1
+
+# =============================================================================
+#
+# Build commands support
+#
+# =============================================================================
+
+# -----------------------------------------------------------------------------
+# Macro    : hide
+# Returns  : nothing
+# Usage    : $(hide)<make commands>
+# Rationale: To be used as a prefix for Make build commands to hide them
+#            by default during the build. To show them, set V=1 in your
+#            environment or command-line.
+#
+#            For example:
+#
+#                foo.o: foo.c
+#                -->|$(hide) <build-commands>
+#
+#            Where '-->|' stands for a single tab character.
+#
+# -----------------------------------------------------------------------------
+ifeq ($(V),1)
+hide = $(empty)
+else
+hide = @
+endif
+
+# -----------------------------------------------------------------------------
+# Template  : ev-compile-c-source
+# Arguments : 1: single C source file name (relative to LOCAL_PATH)
+#             2: target object file (without path)
+# Returns   : None
+# Usage     : $(eval $(call ev-compile-c-source,<srcfile>,<objfile>)
+# Rationale : Internal template evaluated by compile-c-source and
+#             compile-s-source
+# -----------------------------------------------------------------------------
+define  ev-compile-c-source
+_SRC:=$$(LOCAL_PATH)/$(1)
+_OBJ:=$$(LOCAL_OBJS_DIR)/$(2)
+
+$$(_OBJ): PRIVATE_SRC      := $$(_SRC)
+$$(_OBJ): PRIVATE_OBJ      := $$(_OBJ)
+$$(_OBJ): PRIVATE_MODULE   := $$(LOCAL_MODULE)
+$$(_OBJ): PRIVATE_ARM_MODE := $$(LOCAL_ARM_MODE)
+$$(_OBJ): PRIVATE_ARM_TEXT := $$(LOCAL_ARM_TEXT)
+$$(_OBJ): PRIVATE_CC       := $$($$(my)CC)
+$$(_OBJ): PRIVATE_CFLAGS   := $$($$(my)CFLAGS) \
+                              $$($$(my)_$(LOCAL_ARM_MODE)_$(LOCAL_BUILD_MODE)_CFLAGS) \
+                              -I$$(LOCAL_PATH) \
+                              $$(LOCAL_CFLAGS) \
+                              $$(NDK_APP_CPPFLAGS) \
+                              $$(NDK_APP_CFLAGS) \
+                              $$(LOCAL_ARM_CFLAGS)
+
+$$(_OBJ): $$(_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK)
+	@mkdir -p $$(dir $$(PRIVATE_OBJ))
+	@echo "Compile $$(PRIVATE_ARM_TEXT)  : $$(PRIVATE_MODULE) <= $$(PRIVATE_SRC)"
+	$(hide) $$(PRIVATE_CC) $$(PRIVATE_CFLAGS) -c \
+	-MMD -MP -MF $$(PRIVATE_OBJ).d.tmp \
+	$$(PRIVATE_SRC) \
+	-o $$(PRIVATE_OBJ)
+	$$(call cmd-process-deps,$$(PRIVATE_OBJ))
+
+LOCAL_OBJECTS         += $$(_OBJ)
+LOCAL_DEPENDENCY_DIRS += $$(dir $$(_OBJ))
+endef
+
+# -----------------------------------------------------------------------------
+# Function  : compile-c-source
+# Arguments : 1: single C source file name (relative to LOCAL_PATH)
+# Returns   : None
+# Usage     : $(call compile-c-source,<srcfile>)
+# Rationale : Setup everything required to build a single C source file
+# -----------------------------------------------------------------------------
+compile-c-source = $(eval $(call ev-compile-c-source,$1,$(1:%.c=%.o)))
+
+# -----------------------------------------------------------------------------
+# Function  : compile-s-source
+# Arguments : 1: single Assembly source file name (relative to LOCAL_PATH)
+# Returns   : None
+# Usage     : $(call compile-s-source,<srcfile>)
+# Rationale : Setup everything required to build a single Assembly source file
+# -----------------------------------------------------------------------------
+compile-s-source = $(eval $(call ev-compile-s-source,$1,$(1:%.S=%.o)))
+
+
+# -----------------------------------------------------------------------------
+# Template  : ev-compile-cpp-source
+# Arguments : 1: single C++ source file name (relative to LOCAL_PATH)
+#             2: target object file (without path)
+# Returns   : None
+# Usage     : $(eval $(call ev-compile-cpp-source,<srcfile>,<objfile>)
+# Rationale : Internal template evaluated by compile-cpp-source
+# -----------------------------------------------------------------------------
+
+define  ev-compile-cpp-source
+_SRC:=$$(LOCAL_PATH)/$(1)
+_OBJ:=$$(LOCAL_OBJS_DIR)/$(2)
+
+$$(_OBJ): PRIVATE_SRC      := $$(_SRC)
+$$(_OBJ): PRIVATE_OBJ      := $$(_OBJ)
+$$(_OBJ): PRIVATE_MODULE   := $$(LOCAL_MODULE)
+$$(_OBJ): PRIVATE_ARM_MODE := $$(LOCAL_ARM_MODE)
+$$(_OBJ): PRIVATE_ARM_TEXT := $$(LOCAL_ARM_TEXT)
+$$(_OBJ): PRIVATE_CXX      := $$($$(my)CXX)
+$$(_OBJ): PRIVATE_CXXFLAGS := $$($$(my)CXXFLAGS) \
+                              $$($$(my)_$(LOCAL_ARM_MODE)_$(LOCAL_BUILD_MODE)_CFLAGS) \
+                              -I$$(LOCAL_PATH) \
+                              $$(LOCAL_CFLAGS) \
+                              $$(NDK_APP_CPPFLAGS) \
+                              $$(NDK_APP_CXXFLAGS) \
+                              $$(LOCAL_ARM_CFLAGS)
+
+$$(_OBJ): $$(_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK)
+	@mkdir -p $$(dir $$(PRIVATE_OBJ))
+	@echo "Compile++ $$(PRIVATE_ARM_TEXT): $$(PRIVATE_MODULE) <= $$(PRIVATE_SRC)"
+	$(hide) $$(PRIVATE_CXX) $$(PRIVATE_CXXFLAGS) -c \
+	-MMD -MP -MF $$(PRIVATE_OBJ).d.tmp \
+	$$(PRIVATE_SRC) \
+	-o $$(PRIVATE_OBJ)
+	$$(call cmd-process-deps,$$(PRIVATE_OBJ))
+
+LOCAL_OBJECTS         += $$(_OBJ)
+LOCAL_DEPENDENCY_DIRS += $$(dir $$(_OBJ))
+endef
+
+# -----------------------------------------------------------------------------
+# Function  : compile-cpp-source
+# Arguments : 1: single C++ source file name (relative to LOCAL_PATH)
+# Returns   : None
+# Usage     : $(call compile-c-source,<srcfile>)
+# Rationale : Setup everything required to build a single C++ source file
+# -----------------------------------------------------------------------------
+compile-cpp-source = $(eval $(call ev-compile-cpp-source,$1,$(1:%$(LOCAL_CPP_EXTENSION)=%.o)))
+
+# -----------------------------------------------------------------------------
+# Command   : cmd-process-deps
+# Arguments : 1: object file path
+# Returns   : None
+# Usage     : $(call cmd-process-deps,<objectfile>)
+# Rationale : To be used as a Make build command to process the dependencies
+#             generated by the compiler (in <obj>.d.tmp) into ones suited
+#             for our build system. See the comments in build/core/mkdeps.sh
+#             for more details.
+# -----------------------------------------------------------------------------
+cmd-process-deps = $(hide) $(BUILD_SYSTEM)/mkdeps.sh $(1) $(1).d.tmp $(1).d
+
+# -----------------------------------------------------------------------------
+# Command   : cmd-install-file
+# Arguments : 1: source file
+#             2: destination file
+# Returns   : None
+# Usage     : $(call cmd-install-file,<srcfile>,<dstfile>)
+# Rationale : To be used as a Make build command to copy/install a file to
+#             a given location.
+# -----------------------------------------------------------------------------
+define cmd-install-file
+@mkdir -p $(dir $2)
+$(hide) cp -fp $1 $2
+endef
diff --git a/ndk/build/core/main.mk b/ndk/build/core/main.mk
new file mode 100644
index 0000000..a07e3b3
--- /dev/null
+++ b/ndk/build/core/main.mk
@@ -0,0 +1,294 @@
+# 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.
+#
+
+# ====================================================================
+#
+# Define the main configuration variables, and read the host-specific
+# configuration file that is normally generated by build/host-setup.sh
+#
+# ====================================================================
+
+# Include common definitions
+include build/core/definitions.mk
+
+# The location of the build system files
+BUILD_SYSTEM := build/core
+
+# Where all generated files will be stored during a build
+NDK_OUT := out
+
+# Read the host-specific configuration file in $(NDK_OUT)
+#
+HOST_CONFIG_MAKE := $(NDK_OUT)/host/config.mk
+
+ifeq ($(strip $(wildcard $(HOST_CONFIG_MAKE))),)
+    $(call __ndk_info,\
+    The configuration file '$(HOST_CONFIG_MAKE)' doesnt' exist.)
+    $(call __ndk_info,\
+       Please run 'build/host-setup.sh' to generate it.)
+    $(call __ndk_error, Aborting)
+endif
+
+include $(HOST_CONFIG_MAKE)
+HOST_PREBUILT_TAG := $(HOST_TAG)
+
+# Location where all prebuilt binaries for a given host architectures
+# will be stored.
+HOST_PREBUILT := build/prebuilt/$(HOST_TAG)
+
+# Where all app-specific generated files will be stored
+NDK_APP_OUT := $(NDK_OUT)/apps
+
+# Where all host-specific generated files will be stored
+NDK_HOST_OUT := $(NDK_OUT)/host/$(HOST_TAG)
+
+# ====================================================================
+#
+# Read all toolchain-specific configuration files.
+#
+# Each toolchain must have a corresponding config.mk file located
+# in build/toolchains/<name>/ that will be included here.
+#
+# Each one of these files should define the following variables:
+#   TOOLCHAIN_NAME   toolchain name (e.g. arm-eabi-4.2.1)
+#   TOOLCHAIN_ABIS   list of target ABIs supported by the toolchain.
+#
+# Then, it should include $(ADD_TOOLCHAIN) which will perform
+# book-keeping for the build system.
+#
+# ====================================================================
+
+# the build script to include in each toolchain config.mk
+ADD_TOOLCHAIN := $(BUILD_SYSTEM)/add-toolchain.mk
+
+# the list of all toolchains in this NDK
+NDK_ALL_TOOLCHAINS :=
+NDK_ALL_ABIS       :=
+
+TOOLCHAIN_CONFIGS := $(wildcard build/toolchains/*/config.mk)
+$(foreach _config_mk,$(TOOLCHAIN_CONFIGS),\
+  $(eval include $(BUILD_SYSTEM)/add-toolchain.mk)\
+)
+
+#$(info ALL_TOOLCHAINS=$(ALL_TOOLCHAINS))
+NDK_TARGET_TOOLCHAIN := $(firstword $(NDK_ALL_TOOLCHAINS))
+$(call ndk_log, Default toolchain is $(NDK_TARGET_TOOLCHAIN))
+
+NDK_ALL_TOOLCHAINS   := $(call uniq,$(NDK_ALL_TOOLCHAINS))
+NDK_ALL_ABIS         := $(call uniq,$(NDK_ALL_ABIS))
+
+$(call ndk_log, This NDK supports the following toolchains and target ABIs:)
+$(foreach tc,$(NDK_ALL_TOOLCHAINS),\
+    $(call ndk_log, $(space)$(space)$(tc):  $(NDK_TOOLCHAIN.$(tc).abis))\
+)
+
+# ====================================================================
+#
+# Read all application configuration files
+#
+# Each 'application' must have a corresponding Application.mk file
+# located in apps/<name> where <name> is a liberal name that doesn't
+# contain any space in it, used to uniquely identify the
+#
+# Each one of these files should define the following required
+# variables:
+#
+#   APP_MODULES   the list of modules needed by this application
+#
+#   APP_PROJECT_PATH
+#                 path to the Java project root directory where the
+#                 generated binaries will be copied to. The NDK will
+#                 place them in appropriate locations so they are
+#                 properly picked by aapt, the Android Packager tool,
+#                 when generating your applications.
+#
+# As well as the following *optional* variables:
+#
+#   APP_OPTIM     either 'release' or 'debug'
+#
+#   APP_CPPFLAGS  extra flags passed when building C and C++ sources
+#                 of application modules
+#
+#   APP_CFLAGS    extra flags passed when building C sources of
+#                 application's modules (not C++ ones)
+#
+#   APP_CXXFLAGS  extra flags passed when building C++ sources of
+#                 application's modules (not C ones)
+#
+# ====================================================================
+
+NDK_ALL_APPS :=
+
+NDK_APPLICATIONS := $(wildcard apps/*/Application.mk)
+$(foreach _application_mk, $(NDK_APPLICATIONS),\
+  $(eval include $(BUILD_SYSTEM)/add-application.mk)\
+)
+
+# clean up environment, just to be safe
+$(call clear-vars, $(NDK_APP_VARS))
+
+ifeq ($(strip $(NDK_ALL_APPS)),)
+  $(call __ndk_info,\
+    The NDK could not find a proper application description under apps/*/Application.mk)
+  $(call __ndk_info,\
+    Please follow the instructions in docs/NDK-APPS.TXT to write one.)
+  $(call __ndk_error, Aborting)
+endif
+
+ifeq ($(strip $(APP)),)
+  $(call __ndk_info,\
+    The APP variable is undefined or empty.)
+  $(call __ndk_info,\
+    Please define it to one of: $(NDK_ALL_APPS))
+  $(call __ndk_info,\
+    You can also add new applications by writing an Application.mk file.)
+  $(call __ndk_info,\
+    See docs/APPLICATION-MK.TXT for details.)
+  $(call __ndk_error, Aborting)
+endif
+
+# now check that APP doesn't contain an unknown app name
+# if it does, we ignore them if there is at least one known
+# app name in the list. Otherwise, abort with an error message
+#
+_unknown_apps := $(filter-out $(NDK_ALL_APPS),$(APP))
+_known_apps   := $(filter     $(NDK_ALL_APPS),$(APP))
+
+NDK_APPS := $(APP)
+
+$(if $(_unknown_apps),\
+  $(if $(_known_apps),\
+    $(call __ndk_info,WARNING:\
+        Removing unknown names from APP variable: $(_unknown_apps))\
+    $(eval NDK_APPS := $(_known_apps))\
+   ,\
+    $(call __ndk_info,\
+        The APP variable contains unknown app names: $(_unknown_apps))\
+    $(call __ndk_info,\
+        Please use one of: $(NDK_ALL_APPS))\
+    $(call __ndk_error, Aborting)\
+  )\
+)
+
+$(call __ndk_info,Building for application '$(NDK_APPS)')
+
+# ====================================================================
+#
+# Prepare the build for parsing Android.mk files
+#
+# ====================================================================
+
+# These phony targets are used to control various stages of the build
+.PHONY: all \
+        host_libraries host_executables \
+        installed_modules \
+        executables libraries static_libraries shared_libraries \
+        clean clean-config clean-objs-dir \
+        clean-executables clean-libraries \
+        clean-installed-modules
+
+# These macros are used in Android.mk to include the corresponding
+# build script that will parse the LOCAL_XXX variable definitions.
+#
+CLEAR_VARS                := $(BUILD_SYSTEM)/clear-vars.mk
+BUILD_HOST_EXECUTABLE     := $(BUILD_SYSTEM)/build-host-executable.mk
+BUILD_HOST_STATIC_LIBRARY := $(BUILD_SYSTEM)/build-host-static-library.mk
+BUILD_STATIC_LIBRARY      := $(BUILD_SYSTEM)/build-static-library.mk
+BUILD_SHARED_LIBRARY      := $(BUILD_SYSTEM)/build-shared-library.mk
+BUILD_EXECUTABLE          := $(BUILD_SYSTEM)/build-executable.mk
+
+ANDROID_MK_INCLUDED := \
+  $(CLEAR_VARS) \
+  $(BUILD_HOST_EXECUTABLE) \
+  $(BUILD_HOST_STATIC_LIBRARY) \
+  $(BUILD_STATIC_LIBRARY) \
+  $(BUILD_SHARED_LIBRARY) \
+  $(BUILD_EXECUTABLE) \
+
+
+# this is the list of directories containing dependency information
+# generated during the build. It will be updated by build scripts
+# when module definitions are parsed.
+#
+ALL_DEPENDENCY_DIRS :=
+
+# this is the list of all generated files that we would need to clean
+ALL_HOST_EXECUTABLES      :=
+ALL_HOST_STATIC_LIBRARIES :=
+ALL_STATIC_LIBRARIES      :=
+ALL_SHARED_LIBRARIES      :=
+ALL_EXECUTABLES           :=
+ALL_INSTALLED_MODULES     :=
+
+# the first rule
+all: installed_modules host_libraries host_executables
+
+# ====================================================================
+#
+# For each platform/abi combo supported by the application, we should
+# setup the toolchain and parse all module definitions files again
+# to build the right dependency tree.
+#
+# All this work is performed by build/core/setup-toolchain.mk
+#
+# ====================================================================
+
+
+# XXX: For now, only support one platform and one target ABI with
+#      only one toolchain.
+#
+TARGET_PLATFORM  := android-1.5
+TARGET_ARCH_ABI  := arm
+TARGET_ARCH      := arm
+TARGET_TOOLCHAIN := $(NDK_TARGET_TOOLCHAIN)
+
+include build/core/setup-toolchain.mk
+
+# ====================================================================
+#
+# Now finish the build preparation with a few rules that depend on
+# what has been effectively parsed and recorded previously
+#
+# ====================================================================
+
+clean: clean-intermediates clean-installed-modules
+
+distclean: clean clean-config
+
+installed_modules: libraries $(ALL_INSTALLED_MODULES)
+host_libraries: $(HOST_STATIC_LIBRARIES)
+host_executables: $(HOST_EXECUTABLES)
+
+static_libraries: $(STATIC_LIBRARIES)
+shared_libraries: $(SHARED_LIBRARIES)
+executables: $(EXECUTABLES)
+
+libraries: static_libraries shared_libraries
+
+clean-host-intermediates:
+	$(hide) rm -rf $(HOST_EXECUTABLES) $(HOST_STATIC_LIBRARIES)
+
+clean-intermediates: clean-host-intermediates
+	$(hide) rm -rf $(EXECUTABLES) $(STATIC_LIBRARIES) $(SHARED_LIBRARIES)
+
+clean-installed-modules:
+	$(hide) rm -rf $(ALL_INSTALLED_MODULES)
+
+clean-config:
+	$(hide) rm -f $(CONFIG_MAKE) $(CONFIG_H)
+
+# include dependency information
+ALL_DEPENDENCY_DIRS := $(sort $(ALL_DEPENDENCY_DIRS))
+-include $(wildcard $(ALL_DEPENDENCY_DIRS:%=%/*.d))
diff --git a/ndk/build/core/mkdeps.sh b/ndk/build/core/mkdeps.sh
new file mode 100755
index 0000000..abecec7
--- /dev/null
+++ b/ndk/build/core/mkdeps.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+#
+# 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.
+#
+# This script is used to transform the dependency files generated by GCC
+# For example, a typical .d file will have a line like:
+#
+#    source.o: /full/path/to/source.c other.h headers.h
+#    ...
+#
+# the script is used to replace 'source.o' to a full path, as in
+#
+#    objs/intermediates/emulator/source.o: /full/path/to/source.c other.h headers.h
+#
+# parameters
+#
+# $1: object file (full path)
+# $2: source dependency file to modify (erased on success)
+# $3: target source dependency file
+#
+
+# quote the object path. we change a single '.' into
+# a '\.' since this will be parsed by sed.
+#
+OBJECT=`echo $1 | sed -e s/\\\\./\\\\\\\\./g`
+#echo OBJECT=$OBJECT
+
+OBJ_NAME=`basename $OBJECT`
+#echo OBJ_NAME=$OBJ_NAME
+
+# we replace $OBJ_NAME with $OBJECT only if $OBJ_NAME starts the line
+# that's because some versions of GCC (e.g. 4.2.3) already produce
+# a correct dependency line with the full path to the object file.
+# In this case, we don't want to touch anything
+#
+cat $2 | sed -e s%^$OBJ_NAME%$OBJECT%g > $3 && rm -f $2
+
+
+
diff --git a/ndk/build/core/ndk-common.sh b/ndk/build/core/ndk-common.sh
new file mode 100644
index 0000000..c89ffd9
--- /dev/null
+++ b/ndk/build/core/ndk-common.sh
@@ -0,0 +1,396 @@
+# 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.
+#
+
+# A collection of shell function definitions used by various build scripts
+# in the Android NDK (Native Development Kit)
+#
+
+# Get current script name into PROGNAME
+PROGNAME=`basename $0`
+
+# Put location of Android NDK into ANDROID_NDK_ROOT and
+# perform a tiny amount of sanity check
+#
+if [ -z "$ANDROID_NDK_ROOT" ] ; then
+    if [ ! -f build/core/ndk-common.sh ] ; then
+        echo "Please define ANDROID_NDK_ROOT to point to the root of your"
+        echo "Android NDK installation."
+        exit 1
+    fi
+    ANDROID_NDK_ROOT=.
+fi
+
+if [ ! -d $ANDROID_NDK_ROOT ] ; then
+    echo "ERROR: Your ANDROID_NDK_ROOT variable does not point to a directory."
+    exit 1
+fi
+
+if [ ! -f $ANDROID_NDK_ROOT/build/core/ndk-common.sh ] ; then
+    echo "ERROR: Your ANDROID_NDK_ROOT variable does not point to a valid directory."
+    exit 1
+fi
+
+## Logging support
+##
+VERBOSE=${VERBOSE-yes}
+VERBOSE2=${VERBOSE2-no}
+
+log ()
+{
+    if [ "$VERBOSE" = "yes" ] ; then
+        echo "$1"
+    fi
+}
+
+log2 ()
+{
+    if [ "$VERBOSE2" = "yes" ] ; then
+        echo "$1"
+    fi
+}
+
+## Utilities
+##
+
+# return the value of a given named variable
+# $1: variable name
+#
+# example:
+#    FOO=BAR
+#    BAR=ZOO
+#    echo `var_value $FOO`
+#    will print 'ZOO'
+#
+var_value ()
+{
+    # find a better way to do that ?
+    eval echo "$`echo $1`"
+}
+
+# convert to uppercase
+# assumes tr is installed on the platform ?
+#
+to_uppercase ()
+{
+    echo $1 | tr "[:lower:]" "[:upper:]"
+}
+
+## Normalize OS and CPU
+##
+HOST_ARCH=`uname -m`
+case "$HOST_ARCH" in
+    i?86) HOST_ARCH=x86
+    ;;
+    amd64) HOST_ARCH=x86_64
+    ;;
+    powerpc) HOST_ARCH=ppc
+    ;;
+esac
+
+log2 "HOST_ARCH=$HOST_ARCH"
+
+# at this point, the supported values for CPU are:
+#   x86
+#   x86_64
+#   ppc
+#
+# other values may be possible but haven't been tested
+#
+HOST_EXE=""
+HOST_OS=`uname -s`
+case "$HOST_OS" in
+    Darwin)
+        HOST_OS=darwin
+        ;;
+    Linux)
+        # note that building  32-bit binaries on x86_64 is handled later
+        HOST_OS=linux
+        ;;
+    FreeBsd)  # note: this is not tested
+        HOST_OS=freebsd
+        ;;
+    CYGWIN*|*_NT-*)
+        HOST_OS=windows
+        HOST_EXE=.exe
+        if [ "x$OSTYPE" = xcygwin ] ; then
+            HOST_OS=cygwin
+            HOST_CFLAGS="$CFLAGS -mno-cygwin"
+            HOST_LDFLAGS="$LDFLAGS -mno-cygwin"
+        fi
+        ;;
+esac
+
+log2 "HOST_OS=$HOST_OS"
+log2 "HOST_EXE=$HOST_EXE"
+
+# at this point, the value of HOST_OS should be one of the following:
+#   linux
+#   darwin
+#    windows (MSys)
+#    cygwin
+#
+# Note that cygwin is treated as a special case because it behaves very differently
+# for a few things. Other values may be possible but have not been tested
+#
+
+# define HOST_TAG as a unique tag used to identify both the host OS and CPU
+# supported values are:
+#
+#   linux-x86
+#   linux-x86_64
+#   darwin-x86
+#   darwin-ppc
+#   windows
+#
+# other values are possible but were not tested.
+#
+compute_host_tag ()
+{
+    case "$HOST_OS" in
+        windows|cygwin)
+            HOST_TAG="windows"
+            ;;
+        *)  HOST_TAG="${HOST_OS}-${HOST_ARCH}"
+    esac
+    log2 "HOST_TAG=$HOST_TAG"
+}
+
+compute_host_tag
+
+# Compute the number of host CPU cores an HOST_NUM_CPUS
+#
+case "$HOST_OS" in
+    linux)
+        HOST_NUM_CPUS=`cat /proc/cpuinfo | grep processor | wc -l`
+        ;;
+    darwin|freebsd)
+        HOST_NUM_CPUS=`sysctl -n hw.ncpu`
+        ;;
+    windows|cygwin)
+        HOST_NUM_CPUS=$NUMBER_OF_PROCESSORS
+        ;;
+    *)  # let's play safe here
+        HOST_NUM_CPUS=1
+esac
+
+log2 "HOST_NUM_CPUS=$HOST_NUM_CPUS"
+
+# If BUILD_NUM_CPUS is not already defined in your environment,
+# define it as the double of HOST_NUM_CPUS. This is used to
+# run Make commends in parralles, as in 'make -j$BUILD_NUM_CPUS'
+#
+if [ -z "$BUILD_NUM_CPUS" ] ; then
+    BUILD_NUM_CPUS=`expr $HOST_NUM_CPUS \* 2`
+fi
+
+log2 "BUILD_NUM_CPUS=$BUILD_NUM_CPUS"
+
+
+##  HOST TOOLCHAIN SUPPORT
+##
+
+# force the generation of 32-bit binaries on 64-bit systems
+#
+FORCE_32BIT=no
+force_32bit_binaries ()
+{
+    if [ "$HOST_ARCH" = x86_64 ] ; then
+        log2 "Forcing generation of 32-bit host binaries on $HOST_ARCH"
+        FORCE_32BIT=yes
+        HOST_ARCH=x86
+        log2 "HOST_ARCH=$HOST_ARCH"
+        compute_host_tag
+    fi
+}
+
+# On Windows, cygwin binaries will be generated by default, but
+# you can force mingw ones that do not link to cygwin.dll if you
+# call this function.
+#
+disable_cygwin ()
+{
+    if [ $OS = cygwin ] ; then
+        log2 "Disabling cygwin binaries generation"
+        CFLAGS="$CFLAGS -mno-cygwin"
+        LDFLAGS="$LDFLAGS -mno-cygwin"
+        OS=windows
+        HOST_OS=windows
+        compute_host_tag
+    fi
+}
+
+# Various probes are going to need to run a small C program
+TMPC=/tmp/android-$$-test.c
+TMPO=/tmp/android-$$-test.o
+TMPE=/tmp/android-$$-test$EXE
+TMPL=/tmp/android-$$-test.log
+
+# cleanup temporary files
+clean_temp ()
+{
+    rm -f $TMPC $TMPO $TMPL $TMPE
+}
+
+# cleanup temp files then exit with an error
+clean_exit ()
+{
+    clean_temp
+    exit 1
+}
+
+# this function will setup the compiler and linker and check that they work as advertised
+# note that you should call 'force_32bit_binaries' before this one if you want it to
+# generate 32-bit binaries on 64-bit systems (that support it).
+#
+setup_toolchain ()
+{
+    if [ -z "$CC" ] ; then
+        CC=gcc
+    fi
+
+    log2 "Using '$CC' as the C compiler"
+
+    # check that we can compile a trivial C program with this compiler
+    cat > $TMPC <<EOF
+int main(void) {}
+EOF
+
+    if [ "$FORCE_32BIT" = yes ] ; then
+        CFLAGS="$CFLAGS -m32"
+        LDFLAGS="$LDFLAGS -m32"
+        compile
+        if [ $? != 0 ] ; then
+            # sometimes, we need to also tell the assembler to generate 32-bit binaries
+            # this is highly dependent on your GCC installation (and no, we can't set
+            # this flag all the time)
+            CFLAGS="$CFLAGS -Wa,--32"
+            compile
+        fi
+    fi
+
+    compile
+    if [ $? != 0 ] ; then
+        echo "your C compiler doesn't seem to work:"
+        cat $TMPL
+        clean_exit
+    fi
+    log "CC         : compiler check ok ($CC)"
+
+    # check that we can link the trivial program into an executable
+    if [ -z "$LD" ] ; then
+        LD=$CC
+    fi
+    link
+    if [ $? != 0 ] ; then
+        OLD_LD=$LD
+        LD=gcc
+        compile
+        link
+        if [ $? != 0 ] ; then
+            LD=$OLD_LD
+            echo "your linker doesn't seem to work:"
+            cat $TMPL
+            clean_exit
+        fi
+    fi
+    log2 "Using '$LD' as the linker"
+    log "LD         : linker check ok ($LD)"
+
+    # check the C++ compiler
+    if [ -z "$CXX" ] ; then
+        CXX=g++
+    fi
+    if [ -z "$CXXFLAGS" ] ; then
+        CXXFLAGS=$CFLAGS
+    fi
+
+    log2 "Using '$CXX' as the C++ compiler"
+
+    cat > $TMPC <<EOF
+#include <iostream>
+using namespace std;
+int main()
+{
+  cout << "Hello World!" << endl;
+  return 0;
+}
+EOF
+
+    compile_cpp
+    if [ $? != 0 ] ; then
+        echo "your C++ compiler doesn't seem to work"
+        cat $TMPL
+        clean_exit
+    fi
+
+    log "CXX        : C++ compiler check ok ($CXX)"
+
+    # XXX: TODO perform AR checks
+    AR=ar
+    ARFLAGS=
+}
+
+# try to compile the current source file in $TMPC into an object
+# stores the error log into $TMPL
+#
+compile ()
+{
+    log2 "Object     : $CC -o $TMPO -c $CFLAGS $TMPC"
+    $CC -o $TMPO -c $CFLAGS $TMPC 2> $TMPL
+}
+
+compile_cpp ()
+{
+    log2 "Object     : $CXX -o $TMPO -c $CXXFLAGS $TMPC"
+    $CXX -o $TMPO -c $CXXFLAGS $TMPC 2> $TMPL
+}
+
+# try to link the recently built file into an executable. error log in $TMPL
+#
+link()
+{
+    log2 "Link      : $LD -o $TMPE $TMPO $LDFLAGS"
+    $LD -o $TMPE $TMPO $LDFLAGS 2> $TMPL
+}
+
+# run a command
+#
+execute()
+{
+    log2 "Running: $*"
+    $*
+}
+
+# perform a simple compile / link / run of the source file in $TMPC
+compile_exec_run()
+{
+    log2 "RunExec    : $CC -o $TMPE $CFLAGS $TMPC"
+    compile
+    if [ $? != 0 ] ; then
+        echo "Failure to compile test program"
+        cat $TMPC
+        cat $TMPL
+        clean_exit
+    fi
+    link
+    if [ $? != 0 ] ; then
+        echo "Failure to link test program"
+        cat $TMPC
+        echo "------"
+        cat $TMPL
+        clean_exit
+    fi
+    $TMPE
+}
diff --git a/ndk/build/core/setup-app.mk b/ndk/build/core/setup-app.mk
new file mode 100644
index 0000000..7f7e8b4
--- /dev/null
+++ b/ndk/build/core/setup-app.mk
@@ -0,0 +1,68 @@
+# 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 included repeatedly from build/core/setup-toolchain.mk
+# and is used to prepare for app-specific build rules.
+#
+
+$(call assert-defined,_app)
+
+# the location of generated files for this app
+HOST_OUT    := $(NDK_APP_OUT)/$(_app)/$(HOST_TAG)
+HOST_OBJS   := $(HOST_OUT)/objs
+
+TARGET_OUT  := $(NDK_APP_OUT)/$(_app)/$(TARGET_ABI)
+TARGET_OBJS := $(TARGET_OUT)/objs
+
+TARGET_GDB_SETUP := $(TARGET_OUT)/setup.gdb
+
+# ok, let's parse all Android.mk source files in order to build
+# the modules for this app.
+#
+
+# Restore the APP_XXX variables just for this pass as NDK_APP_XXX
+#
+NDK_APP_NAME           := $(_app)
+NDK_APP_APPLICATION_MK := $(NDK_APP.$(_app).Application.mk)
+
+$(foreach __name,$(NDK_APP_VARS),\
+  $(eval NDK_$(__name) := $(NDK_APP.$(_app).$(__name)))\
+)
+
+# set release/debug build flags
+#
+ifeq ($(NDK_APP_OPTIM),debug)
+  NDK_APP_CPPFLAGS := -O0 -g $(NDK_APP_CPPFLAGS)
+else
+  NDK_APP_CPPFLAGS := -O2 -DNDEBUG -g $(NDK_APP_CPPFLAGS)
+endif
+
+# compute NDK_APP_DEST as the destination directory for the generated files
+NDK_APP_DEST := $(NDK_APP_PROJECT_PATH)/libs/$(TARGET_ABI_SUBDIR)
+
+# make the application depend on the modules it requires
+.PHONY: ndk-app-$(_app)
+ndk-app-$(_app): $(NDK_APP_MODULES)
+all: ndk-app-$(_app)
+
+# free the dictionary of LOCAL_MODULE definitions
+$(call modules-clear)
+
+# now parse all Android.mk build files
+#
+# this will include stuff like build/core/static-library.mk and others
+# for each module to be defined.
+#
+include sources/*/Android.mk
diff --git a/ndk/build/core/setup-toolchain.mk b/ndk/build/core/setup-toolchain.mk
new file mode 100644
index 0000000..12cebce
--- /dev/null
+++ b/ndk/build/core/setup-toolchain.mk
@@ -0,0 +1,45 @@
+# 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 included repeatedly from build/core/main.mk and is used
+# to setup the target toolchain for a given platform/abi combination.
+#
+
+$(call assert-defined,TARGET_TOOLCHAIN TARGET_PLATFORM TARGET_ARCH TARGET_ARCH_ABI)
+$(call assert-defined,NDK_APPS)
+
+TARGET_ABI := $(TARGET_PLATFORM)-$(TARGET_ARCH_ABI)
+
+# setup sysroot-related variables. The SYSROOT point to a directory
+# that contains all public header files for a given platform, plus
+# some libraries and object files used for linking the generated
+# target files properly.
+#
+SYSROOT := build/platforms/$(TARGET_PLATFORM)/arch-$(TARGET_ARCH_ABI)
+
+TARGET_CRTBEGIN_STATIC_O  := $(SYSROOT)/usr/lib/crtbegin_static.o
+TARGET_CRTBEGIN_DYNAMIC_O := $(SYSROOT)/usr/lib/crtbegin_dynamic.o
+TARGET_CRTEND_O           := $(SYSROOT)/usr/lib/crtend_android.o
+
+TARGET_PREBUILT_SHARED_LIBRARIES := libc libstdc++ libm
+TARGET_PREBUILT_SHARED_LIBRARIES := $(TARGET_PREBUILT_SHARED_LIBRARIES:%=$(SYSROOT)/usr/lib/%.so)
+
+# now call the toolchain-specific setup script
+include $(NDK_TOOLCHAIN.$(TARGET_TOOLCHAIN).setup)
+
+# For each app, compute intermediate directories and parse module sources
+$(foreach _app,$(NDK_APPS),\
+  $(eval include $(BUILD_SYSTEM)/setup-app.mk)\
+)
diff --git a/ndk/build/gmsl/README b/ndk/build/gmsl/README
new file mode 100644
index 0000000..152ada6
--- /dev/null
+++ b/ndk/build/gmsl/README
@@ -0,0 +1,27 @@
+GNU Make Standard Library
+-------------------------
+
+1. Visit http://gmsl.sf.net for more details
+
+2. To use the GMSL in your Makefile make sure that you have the files
+
+   gmsl
+   __gmsl
+
+   Add 
+
+   include gmsl
+
+   to your Makefile(s).
+
+3. To run the GMSL test suite have 
+
+   gmsl
+   __gmsl
+   gmsl-tests
+
+   And then run
+
+   make -f gmsl-tests
+
+ 
\ No newline at end of file
diff --git a/ndk/build/gmsl/__gmsl b/ndk/build/gmsl/__gmsl
new file mode 100644
index 0000000..596ff19
--- /dev/null
+++ b/ndk/build/gmsl/__gmsl
@@ -0,0 +1,854 @@
+# ----------------------------------------------------------------------------
+#
+# GNU Make Standard Library (GMSL)
+#
+# A library of functions to be used with GNU Make's $(call) that
+# provides functionality not available in standard GNU Make.
+#
+# Copyright (c) 2005-2007 John Graham-Cumming
+#
+# This file is part of GMSL
+#
+# 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 the John Graham-Cumming 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "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 THE
+# COPYRIGHT OWNER OR CONTRIBUTORS 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.
+#
+# ----------------------------------------------------------------------------
+
+# This is the GNU Make Standard Library version number as a list with
+# three items: major, minor, revision
+
+gmsl_version := 1 0 11
+
+# Used to output warnings and error from the library, it's possible to
+# disable any warnings or errors by overriding these definitions
+# manually or by setting GMSL_NO_WARNINGS or GMSL_NO_ERRORS
+
+__gmsl_name := GNU Make Standard Library
+__gmsl_warning = $(warning $(__gmsl_name): $1)
+__gmsl_error = $(error $(__gmsl_name): $1)
+
+ifdef GMSL_NO_WARNINGS
+__gmsl_warning :=
+endif
+ifdef GMSL_NO_ERRORS
+__gmsl_error :=
+endif
+
+# If GMSL_TRACE is enabled then calls to the library functions are
+# traced to stdout using warning messages with their arguments
+
+ifdef GMSL_TRACE
+__gmsl_tr1 = $(warning $0('$1'))
+__gmsl_tr2 = $(warning $0('$1','$2'))
+__gmsl_tr3 = $(warning $0('$1','$2','$3'))
+else
+__gmsl_tr1 :=
+__gmsl_tr2 :=
+__gmsl_tr3 :=
+endif
+
+# Figure out whether we have $(eval) or not (GNU Make 3.80 and above)
+# if we do not then output a warning message, if we do then some
+# functions will be enabled.
+
+__gmsl_have_eval := $(false)
+__gmsl_ignore := $(eval __gmsl_have_eval := $(true))
+
+# If this is being run with Electric Cloud's emake then warn that
+# their $(eval) support is incomplete.
+
+ifdef ECLOUD_BUILD_ID
+$(warning You are using Electric Cloud's emake which has incomplete $$(eval) support)
+__gmsl_have_eval := $(false)
+endif
+
+# See if we have $(lastword) (GNU Make 3.81 and above)
+
+__gmsl_have_lastword := $(lastword $(false) $(true))
+
+# See if we have native or and and (GNU Make 3.81 and above)
+
+__gmsl_have_or := $(if $(filter-out undefined,  \
+    $(origin or)),$(call or,$(true),$(false)))
+__gmsl_have_and := $(if $(filter-out undefined, \
+    $(origin and)),$(call and,$(true),$(true)))
+
+ifneq ($(__gmsl_have_eval),$(true))
+$(call __gmsl_warning,GNU Make $(MAKE_VERSION) does not support $$$$(eval): some functions disabled)
+endif
+
+# ----------------------------------------------------------------------------
+# Function:  gmsl_compatible
+# Arguments: List containing the desired library version number (maj min rev)
+# Returns:   $(true) if this version of the library is compatible
+#            with the requested version number, otherwise $(false)
+# ----------------------------------------------------------------------------
+gmsl_compatible = $(strip                                                 \
+    $(if $(call gt,$(word 1,$1),$(word 1,$(gmsl_version))),               \
+        $(false),                                                         \
+        $(if $(call lt,$(word 1,$1),$(word 1,$(gmsl_version))),           \
+            $(true),                                                      \
+            $(if $(call gt,$(word 2,$1),$(word 2,$(gmsl_version))),       \
+                $(false),                                                 \
+                $(if $(call lt,$(word 2,$1),$(word 2,$(gmsl_version))),   \
+                    $(true),                                              \
+                    $(call lte,$(word 3,$1),$(word 3,$(gmsl_version))))))))
+
+# ###########################################################################
+# LOGICAL OPERATORS
+# ###########################################################################
+
+# not is defined in gmsl
+
+# ----------------------------------------------------------------------------
+# Function:  and
+# Arguments: Two boolean values
+# Returns:   Returns $(true) if both of the booleans are true
+# ----------------------------------------------------------------------------
+ifneq ($(__gmsl_have_and),$(true))
+and = $(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(false))
+endif
+
+# ----------------------------------------------------------------------------
+# Function:  or
+# Arguments: Two boolean values
+# Returns:   Returns $(true) if either of the booleans is true
+# ----------------------------------------------------------------------------
+ifneq ($(__gmsl_have_or),$(true))
+or = $(__gmsl_tr2)$(if $1$2,$(true),$(false))
+endif
+
+# ----------------------------------------------------------------------------
+# Function:  xor
+# Arguments: Two boolean values
+# Returns:   Returns $(true) if exactly one of the booleans is true
+# ----------------------------------------------------------------------------
+xor = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(if $2,$(true),$(false)))
+
+# ----------------------------------------------------------------------------
+# Function:  nand
+# Arguments: Two boolean values
+# Returns:   Returns value of 'not and'
+# ----------------------------------------------------------------------------
+nand = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(true))
+
+# ----------------------------------------------------------------------------
+# Function:  nor
+# Arguments: Two boolean values
+# Returns:   Returns value of 'not or'
+# ----------------------------------------------------------------------------
+nor = $(__gmsl_tr2)$(if $1$2,$(false),$(true))
+
+# ----------------------------------------------------------------------------
+# Function:  xnor
+# Arguments: Two boolean values
+# Returns:   Returns value of 'not xor'
+# ----------------------------------------------------------------------------
+xnor =$(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(if $2,$(false),$(true)))
+
+# ###########################################################################
+# LIST MANIPULATION FUNCTIONS
+# ###########################################################################
+
+# ----------------------------------------------------------------------------
+# Function:  first (same as LISP's car, or head)
+# Arguments: 1: A list
+# Returns:   Returns the first element of a list
+# ----------------------------------------------------------------------------
+first = $(__gmsl_tr1)$(firstword $1)
+
+# ----------------------------------------------------------------------------
+# Function:  last
+# Arguments: 1: A list
+# Returns:   Returns the last element of a list
+# ----------------------------------------------------------------------------
+ifeq ($(__gmsl_have_lastword),$(true))
+last = $(__gmsl_tr1)$(lastword $1)
+else
+last = $(__gmsl_tr1)$(if $1,$(word $(words $1),$1))
+endif
+
+# ----------------------------------------------------------------------------
+# Function:  rest (same as LISP's cdr, or tail)
+# Arguments: 1: A list
+# Returns:   Returns the list with the first element removed
+# ----------------------------------------------------------------------------
+rest = $(__gmsl_tr1)$(wordlist 2,$(words $1),$1)
+
+# ----------------------------------------------------------------------------
+# Function:  chop
+# Arguments: 1: A list
+# Returns:   Returns the list with the last element removed
+# ----------------------------------------------------------------------------
+chop = $(__gmsl_tr1)$(wordlist 2,$(words $1),x $1)
+
+# ----------------------------------------------------------------------------
+# Function:  map
+# Arguments: 1: Name of function to $(call) for each element of list
+#            2: List to iterate over calling the function in 1
+# Returns:   The list after calling the function on each element
+# ----------------------------------------------------------------------------
+map = $(__gmsl_tr2)$(strip $(foreach a,$2,$(call $1,$a)))
+
+# ----------------------------------------------------------------------------
+# Function:  pairmap
+# Arguments: 1: Name of function to $(call) for each pair of elements
+#            2: List to iterate over calling the function in 1
+#            3: Second list to iterate over calling the function in 1
+# Returns:   The list after calling the function on each pair of elements
+# ----------------------------------------------------------------------------
+pairmap = $(strip $(__gmsl_tr3)\
+          $(if $2$3,$(call $1,$(call first,$2),$(call first,$3))     \
+                        $(call pairmap,$1,$(call rest,$2),$(call rest,$3))))
+
+# ----------------------------------------------------------------------------
+# Function:  leq
+# Arguments: 1: A list to compare against...
+#            2: ...this list
+# Returns:   Returns $(true) if the two lists are identical
+# ----------------------------------------------------------------------------
+leq = $(__gmsl_tr2)$(strip $(if $(call seq,$(words $1),$(words $2)),     \
+          $(call __gmsl_list_equal,$1,$2),$(false)))
+
+__gmsl_list_equal = $(if $(strip $1),                                       \
+                        $(if $(call seq,$(call first,$1),$(call first,$2)), \
+                            $(call __gmsl_list_equal,                       \
+                                $(call rest,$1),                            \
+                                $(call rest,$2)),                           \
+                            $(false)),                                      \
+                     $(true))
+
+# ----------------------------------------------------------------------------
+# Function:  lne
+# Arguments: 1: A list to compare against...
+#            2: ...this list
+# Returns:   Returns $(true) if the two lists are different
+# ----------------------------------------------------------------------------
+lne = $(__gmsl_tr2)$(call not,$(call leq,$1,$2))
+
+# ----------------------------------------------------------------------------
+# Function:  reverse
+# Arguments: 1: A list to reverse
+# Returns:   The list with its elements in reverse order
+# ----------------------------------------------------------------------------
+reverse =$(__gmsl_tr1)$(strip $(if $1,$(call reverse,$(call rest,$1)) \
+                        $(call first,$1)))
+
+# ----------------------------------------------------------------------------
+# Function:  uniq
+# Arguments: 1: A list from which to remove repeated elements
+# Returns:   The list with duplicate elements removed without reordering
+# ----------------------------------------------------------------------------
+uniq = $(strip $(__gmsl_tr1)$(if $1,$(call uniq,$(call chop,$1)) \
+            $(if $(filter $(call last,$1),$(call chop,$1)),,$(call last,$1))))
+
+# ----------------------------------------------------------------------------
+# Function:  length
+# Arguments: 1: A list
+# Returns:   The number of elements in the list
+# ----------------------------------------------------------------------------
+length = $(__gmsl_tr1)$(words $1)
+
+# ###########################################################################
+# STRING MANIPULATION FUNCTIONS
+# ###########################################################################
+
+# Helper function that translates any GNU Make 'true' value (i.e. a
+# non-empty string) to our $(true)
+
+__gmsl_make_bool = $(if $(strip $1),$(true),$(false))
+
+# ----------------------------------------------------------------------------
+# Function:  seq
+# Arguments: 1: A string to compare against...
+#            2: ...this string
+# Returns:   Returns $(true) if the two strings are identical
+# ----------------------------------------------------------------------------
+seq = $(__gmsl_tr2)$(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),$(false),$(true))
+
+# ----------------------------------------------------------------------------
+# Function:  sne
+# Arguments: 1: A string to compare against...
+#            2: ...this string
+# Returns:   Returns $(true) if the two strings are not the same
+# ----------------------------------------------------------------------------
+sne = $(__gmsl_tr2)$(call not,$(call seq,$1,$2))
+
+# ----------------------------------------------------------------------------
+# Function:  split
+# Arguments: 1: The character to split on
+#            2: A string to split
+# Returns:   Splits a string into a list separated by spaces at the split
+#            character in the first argument
+# ----------------------------------------------------------------------------
+split = $(__gmsl_tr2)$(strip $(subst $1, ,$2))
+
+# ----------------------------------------------------------------------------
+# Function:  merge
+# Arguments: 1: The character to put between fields
+#            2: A list to merge into a string
+# Returns:   Merges a list into a single string, list elements are separated
+#            by the character in the first argument
+# ----------------------------------------------------------------------------
+merge = $(__gmsl_tr2)$(strip $(if $2,                                     \
+            $(if $(call seq,1,$(words $2)),                               \
+                $2,$(call first,$2)$1$(call merge,$1,$(call rest,$2)))))
+
+ifdef __gmsl_have_eval
+# ----------------------------------------------------------------------------
+# Function:  tr
+# Arguments: 1: The list of characters to translate from 
+#            2: The list of characters to translate to
+#            3: The text to translate
+# Returns:   Returns the text after translating characters
+# ----------------------------------------------------------------------------
+tr = $(strip $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)              \
+     $(eval __gmsl_t := $3)                                               \
+     $(foreach c,                                                         \
+         $(join $(addsuffix :,$1),$2),                                    \
+         $(eval __gmsl_t :=                                               \
+             $(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)), \
+                 $(__gmsl_t))))$(__gmsl_t))
+
+# Common character classes for use with the tr function.  Each of
+# these is actually a variable declaration and must be wrapped with
+# $() or ${} to be used.
+
+[A-Z] := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z #
+[a-z] := a b c d e f g h i j k l m n o p q r s t u v w x y z #
+[0-9] := 0 1 2 3 4 5 6 7 8 9 #
+[A-F] := A B C D E F #
+
+# ----------------------------------------------------------------------------
+# Function:  uc
+# Arguments: 1: Text to upper case
+# Returns:   Returns the text in upper case
+# ----------------------------------------------------------------------------
+uc = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call tr,$([a-z]),$([A-Z]),$1)
+
+# ----------------------------------------------------------------------------
+# Function:  lc
+# Arguments: 1: Text to lower case
+# Returns:   Returns the text in lower case
+# ----------------------------------------------------------------------------
+lc = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call tr,$([A-Z]),$([a-z]),$1)
+
+# ----------------------------------------------------------------------------
+# Function:  strlen
+# Arguments: 1: A string
+# Returns:   Returns the length of the string
+# ----------------------------------------------------------------------------
+__gmsl_characters := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+__gmsl_characters += a b c d e f g h i j k l m n o p q r s t u v w x y z
+__gmsl_characters += 0 1 2 3 4 5 6 7 8 9
+__gmsl_characters += ` ~ ! @ \# $$ % ^ & * ( ) - _ = +
+__gmsl_characters += { } [ ] \ : ; ' " < > , . / ? |
+
+# Aside: if you read the above you might think that the lower-case
+# letter x is missing, and that that's an error.  It is missing, but
+# it's not an error.  __gmsl_characters is used by the strlen
+# function.  strlen works by transforming every character and space
+# into the letter x and then counting the x's.  Since there's no need
+# to transform x into x I omitted it.
+
+# This results in __gmsl_space containing just a space
+
+__gmsl_space := 
+__gmsl_space +=
+
+strlen = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(strip $(eval __temp := $(subst $(__gmsl_space),x,$1))$(foreach a,$(__gmsl_characters),$(eval __temp := $$(subst $$a,x,$(__temp))))$(eval __temp := $(subst x,x ,$(__temp)))$(words $(__temp)))
+
+# This results in __gmsl_newline containing just a newline
+
+define __gmsl_newline
+
+
+endef
+
+# This results in __gmsl_tab containing a tab
+
+__gmsl_tab :=	#
+
+# ----------------------------------------------------------------------------
+# Function:  substr
+# Arguments: 1: A string
+# 	     2: Start position (first character is 1)
+#	     3: End position (inclusive)
+# Returns:   A substring.  
+# Note:      The string in $1 must not contain a §
+# ----------------------------------------------------------------------------
+
+substr = $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)$(strip $(eval __temp := $$(subst $$(__gmsl_space),§ ,$$1))$(foreach a,$(__gmsl_characters),$(eval __temp := $$(subst $$a,$$a$$(__gmsl_space),$(__temp))))$(eval __temp := $(wordlist $2,$3,$(__temp))))$(subst §,$(__gmsl_space),$(subst $(__gmsl_space),,$(__temp)))
+
+endif # __gmsl_have_eval
+
+# ###########################################################################
+# SET MANIPULATION FUNCTIONS
+# ###########################################################################
+
+# Sets are represented by sorted, deduplicated lists.  To create a set
+# from a list use set_create, or start with the empty_set and
+# set_insert individual elements
+
+# This is the empty set
+empty_set := 
+
+# ----------------------------------------------------------------------------
+# Function:  set_create
+# Arguments: 1: A list of set elements
+# Returns:   Returns the newly created set
+# ----------------------------------------------------------------------------
+set_create = $(__gmsl_tr1)$(sort $1)
+
+# ----------------------------------------------------------------------------
+# Function:  set_insert
+# Arguments: 1: A single element to add to a set
+#            2: A set
+# Returns:   Returns the set with the element added
+# ----------------------------------------------------------------------------
+set_insert = $(__gmsl_tr2)$(sort $1 $2)
+
+# ----------------------------------------------------------------------------
+# Function:  set_remove
+# Arguments: 1: A single element to remove from a set
+#            2: A set
+# Returns:   Returns the set with the element removed
+# ----------------------------------------------------------------------------
+set_remove = $(__gmsl_tr2)$(filter-out $1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  set_is_member
+# Arguments: 1: A single element 
+#            2: A set
+# Returns:   Returns $(true) if the element is in the set
+# ----------------------------------------------------------------------------
+set_is_member = $(__gmsl_tr2)$(if $(filter $1,$2),$(true),$(false))
+
+# ----------------------------------------------------------------------------
+# Function:  set_union
+# Arguments: 1: A set
+#            2: Another set
+# Returns:   Returns the union of the two sets
+# ----------------------------------------------------------------------------
+set_union = $(__gmsl_tr2)$(sort $1 $2)
+
+# ----------------------------------------------------------------------------
+# Function:  set_intersection
+# Arguments: 1: A set
+#            2: Another set
+# Returns:   Returns the intersection of the two sets
+# ----------------------------------------------------------------------------
+set_intersection = $(__gmsl_tr2)$(filter $1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  set_is_subset
+# Arguments: 1: A set
+#            2: Another set
+# Returns:   Returns $(true) if the first set is a subset of the second
+# ----------------------------------------------------------------------------
+set_is_subset = $(__gmsl_tr2)$(call set_equal,$(call set_intersection,$1,$2),$1)
+
+# ----------------------------------------------------------------------------
+# Function:  set_equal
+# Arguments: 1: A set
+#            2: Another set
+# Returns:   Returns $(true) if the two sets are identical
+# ----------------------------------------------------------------------------
+set_equal = $(__gmsl_tr2)$(call seq,$1,$2)
+
+# ###########################################################################
+# ARITHMETIC LIBRARY
+# ###########################################################################
+
+# Integers a represented by lists with the equivalent number of x's.
+# For example the number 4 is x x x x.  The maximum integer that the
+# library can handle as _input_ is __gmsl_input_int which is defined
+# here as 65536
+
+__gmsl_sixteen := x x x x x x x x x x x x x x x x
+__gmsl_input_int := $(foreach a,$(__gmsl_sixteen),         \
+                        $(foreach b,$(__gmsl_sixteen),     \
+                            $(foreach c,$(__gmsl_sixteen), \
+                                $(__gmsl_sixteen)))))
+
+# ----------------------------------------------------------------------------
+# Function:  int_decode
+# Arguments: 1: A number of x's representation
+# Returns:   Returns the integer for human consumption that is represented
+#            by the string of x's
+# ----------------------------------------------------------------------------
+int_decode = $(__gmsl_tr1)$(words $1)
+
+# ----------------------------------------------------------------------------
+# Function:  int_encode
+# Arguments: 1: A number in human-readable integer form
+# Returns:   Returns the integer encoded as a string of x's
+# ----------------------------------------------------------------------------
+int_encode = $(__gmsl_tr1)$(wordlist 1,$1,$(__gmsl_input_int))
+
+# The arithmetic library functions come in two forms: one form of each
+# function takes integers as arguments and the other form takes the
+# encoded form (x's created by a call to int_encode).  For example,
+# there are two plus functions:
+#
+# plus        Called with integer arguments and returns an integer
+# int_plus    Called with encoded arguments and returns an encoded result
+#
+# plus will be slower than int_plus because its arguments and result
+# have to be translated between the x's format and integers.  If doing
+# a complex calculation use the int_* forms with a single encoding of
+# inputs and single decoding of the output.  For simple calculations
+# the direct forms can be used.
+
+# Helper function used to wrap an int_* function into a function that
+# takes a pair of integers, perhaps a function and returns an integer
+# result
+__gmsl_int_wrap = $(call int_decode,$(call $1,$(call int_encode,$2),$(call int_encode,$3)))
+__gmsl_int_wrap1 = $(call int_decode,$(call $1,$(call int_encode,$2)))
+__gmsl_int_wrap2 = $(call $1,$(call int_encode,$2),$(call int_encode,$3))
+
+# ----------------------------------------------------------------------------
+# Function:  int_plus
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the sum of the two numbers in x's representation
+# ----------------------------------------------------------------------------
+int_plus = $(strip $(__gmsl_tr2)$1 $2)
+
+# ----------------------------------------------------------------------------
+# Function:  plus (wrapped version of int_plus)
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the sum of the two integers
+# ----------------------------------------------------------------------------
+plus = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_plus,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  int_subtract
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the difference of the two numbers in x's representation,
+#            or outputs an error on a numeric underflow
+# ----------------------------------------------------------------------------
+int_subtract = $(strip $(__gmsl_tr2)$(if $(call int_gte,$1,$2), \
+                $(filter-out xx,$(join $1,$2)),                 \
+                $(call __gmsl_warning,Subtraction underflow)))
+
+# ----------------------------------------------------------------------------
+# Function:  subtract (wrapped version of int_subtract)
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the difference of the two integers,
+#            or outputs an error on a numeric underflow
+# ----------------------------------------------------------------------------
+subtract = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_subtract,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  int_multiply
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the product of the two numbers in x's representation
+# ----------------------------------------------------------------------------
+int_multiply = $(strip $(__gmsl_tr2)$(foreach a,$1,$2))
+
+# ----------------------------------------------------------------------------
+# Function:  multiply (wrapped version of int_multiply)
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the product of the two integers
+# ----------------------------------------------------------------------------
+multiply = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_multiply,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  int_divide
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the result of integer division of argument 1 divided
+#            by argument 2 in x's representation
+# ----------------------------------------------------------------------------
+int_divide = $(__gmsl_tr2)$(strip $(if $2,                                 \
+                 $(if $(call int_gte,$1,$2),                               \
+                     x $(call int_divide,$(call int_subtract,$1,$2),$2),), \
+                 $(call __gmsl_error,Division by zero)))
+
+# ----------------------------------------------------------------------------
+# Function:  divide (wrapped version of int_divide)
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the integer division of the first argument by the second
+# ----------------------------------------------------------------------------
+divide = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_divide,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  int_max, int_min
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the maximum or minimum of its arguments in x's
+#            representation
+# ----------------------------------------------------------------------------
+int_max = $(__gmsl_tr2)$(subst xx,x,$(join $1,$2))
+int_min = $(__gmsl_tr2)$(subst xx,x,$(filter xx,$(join $1,$2)))
+
+# ----------------------------------------------------------------------------
+# Function:  max, min
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the maximum or minimum of its integer arguments
+# ----------------------------------------------------------------------------
+max = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_max,$1,$2)
+min = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_min,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function: int_gt, int_gte, int_lt, int_lte, int_eq, int_ne
+# Arguments: Two x's representation numbers to be compared
+# Returns:   $(true) or $(false)
+#
+# int_gt    First argument greater than second argument
+# int_gte   First argument greater than or equal to second argument
+# int_lt    First argument less than second argument 
+# int_lte   First argument less than or equal to second argument
+# int_eq    First argument is numerically equal to the second argument
+# int_ne    First argument is not numerically equal to the second argument
+# ----------------------------------------------------------------------------
+int_gt = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
+                          $(filter-out $(words $2), \
+                              $(words $(call int_max,$1,$2))))
+int_gte = $(__gmsl_tr2)$(call __gmsl_make_bool,     \
+                           $(call int_gt,$1,$2)$(call int_eq,$1,$2))
+int_lt = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
+                          $(filter-out $(words $1), \
+                              $(words $(call int_max,$1,$2))))
+int_lte = $(__gmsl_tr2)$(call __gmsl_make_bool,     \
+                           $(call int_lt,$1,$2)$(call int_eq,$1,$2))
+int_eq = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
+                          $(filter $(words $1),$(words $2)))
+int_ne = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
+                          $(filter-out $(words $1),$(words $2)))
+
+# ----------------------------------------------------------------------------
+# Function: gt, gte, lt, lte, eq, ne
+# Arguments: Two integers to be compared
+# Returns:   $(true) or $(false)
+#
+# gt    First argument greater than second argument
+# gte   First argument greater than or equal to second argument
+# lt    First argument less than second argument 
+# lte   First argument less than or equal to second argument
+# eq    First argument is numerically equal to the second argument
+# ne    First argument is not numerically equal to the second argument
+# ----------------------------------------------------------------------------
+gt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gt,$1,$2)
+gte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gte,$1,$2)
+lt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lt,$1,$2)
+lte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lte,$1,$2)
+eq = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_eq,$1,$2)
+ne = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_ne,$1,$2)
+
+# increment adds 1 to its argument, decrement subtracts 1.  Note that
+# decrement does not range check and hence will not underflow, but
+# will incorrectly say that 0 - 1 = 0
+
+# ----------------------------------------------------------------------------
+# Function:  int_inc
+# Arguments: 1: A number in x's representation
+# Returns:   The number incremented by 1 in x's representation
+# ----------------------------------------------------------------------------
+int_inc = $(strip $(__gmsl_tr1)$1 x)
+
+# ----------------------------------------------------------------------------
+# Function:  inc
+# Arguments: 1: An integer
+# Returns:   The argument incremented by 1
+# ----------------------------------------------------------------------------
+inc = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_inc,$1)
+
+# ----------------------------------------------------------------------------
+# Function:  int_dec
+# Arguments: 1: A number in x's representation
+# Returns:   The number decremented by 1 in x's representation
+# ----------------------------------------------------------------------------
+int_dec = $(__gmsl_tr1)$(strip $(if $(call sne,0,$(words $1)), \
+              $(wordlist 2,$(words $1),$1),                    \
+              $(call __gmsl_warning,Decrement underflow)))
+
+# ----------------------------------------------------------------------------
+# Function:  dec
+# Arguments: 1: An integer
+# Returns:   The argument decremented by 1
+# ----------------------------------------------------------------------------
+dec = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_dec,$1)
+
+# double doubles its argument, and halve halves it
+
+# ----------------------------------------------------------------------------
+# Function:  int_double
+# Arguments: 1: A number in x's representation
+# Returns:   The number doubled (i.e. * 2) and returned in x's representation
+# ----------------------------------------------------------------------------
+int_double = $(strip $(__gmsl_tr1)$1 $1)
+
+# ----------------------------------------------------------------------------
+# Function:  double
+# Arguments: 1: An integer
+# Returns:   The integer times 2
+# ----------------------------------------------------------------------------
+double = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_double,$1)
+
+# ----------------------------------------------------------------------------
+# Function:  int_halve
+# Arguments: 1: A number in x's representation
+# Returns:   The number halved (i.e. / 2) and returned in x's representation
+# ----------------------------------------------------------------------------
+int_halve = $(__gmsl_tr1)$(strip $(subst xx,x,$(filter-out xy x y, \
+                             $(join $1,$(foreach a,$1,y x)))))
+
+# ----------------------------------------------------------------------------
+# Function:  halve
+# Arguments: 1: An integer
+# Returns:   The integer divided by 2
+# ----------------------------------------------------------------------------
+halve = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_halve,$1)
+
+ifdef __gmsl_have_eval
+# ###########################################################################
+# ASSOCIATIVE ARRAYS
+# ###########################################################################
+
+# ----------------------------------------------------------------------------
+# Function:  set
+# Arguments: 1: Name of associative array
+#            2: The key value to associate
+#            3: The value associated with the key
+# Returns:   None
+# ----------------------------------------------------------------------------
+set = $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)$(eval __gmsl_aa_$1_$2 = $3)
+
+# ----------------------------------------------------------------------------
+# Function:  get
+# Arguments: 1: Name of associative array
+#            2: The key to retrieve
+# Returns:   The value stored in the array for that key
+# ----------------------------------------------------------------------------
+get = $(strip $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(if $(filter-out undefined,$(origin __gmsl_aa_$1_$2)), \
+    $(__gmsl_aa_$1_$2)))
+
+# ----------------------------------------------------------------------------
+# Function:  keys
+# Arguments: 1: Name of associative array
+# Returns:   Returns a list of all defined keys in the array
+# ----------------------------------------------------------------------------
+keys = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(sort $(patsubst __gmsl_aa_$1_%,%, \
+                  $(filter __gmsl_aa_$1_%,$(.VARIABLES))))
+
+# ----------------------------------------------------------------------------
+# Function:  defined
+# Arguments: 1: Name of associative array
+#            2: The key to test
+# Returns:   Returns true if the key is defined (i.e. not empty)
+# ----------------------------------------------------------------------------
+defined = $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(call sne,$(call get,$1,$2),)
+
+endif # __gmsl_have_eval
+
+ifdef __gmsl_have_eval
+# ###########################################################################
+# NAMED STACKS
+# ###########################################################################
+
+# ----------------------------------------------------------------------------
+# Function:  push
+# Arguments: 1: Name of stack
+#            2: Value to push onto the top of the stack (must not contain
+#               a space)
+# Returns:   None
+# ----------------------------------------------------------------------------
+push = $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(eval __gmsl_stack_$1 := $2 $(if $(filter-out undefined,\
+    $(origin __gmsl_stack_$1)),$(__gmsl_stack_$1)))
+
+# ----------------------------------------------------------------------------
+# Function:  pop
+# Arguments: 1: Name of stack
+# Returns:   Top element from the stack after removing it
+# ----------------------------------------------------------------------------
+pop = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(strip $(if $(filter-out undefined,$(origin __gmsl_stack_$1)), \
+    $(call first,$(__gmsl_stack_$1))                                       \
+    $(eval __gmsl_stack_$1 := $(call rest,$(__gmsl_stack_$1)))))
+
+# ----------------------------------------------------------------------------
+# Function:  peek
+# Arguments: 1: Name of stack
+# Returns:   Top element from the stack without removing it
+# ----------------------------------------------------------------------------
+peek = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call first,$(__gmsl_stack_$1))
+
+# ----------------------------------------------------------------------------
+# Function:  depth
+# Arguments: 1: Name of stack
+# Returns:   Number of items on the stack
+# ----------------------------------------------------------------------------
+depth = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(words $(__gmsl_stack_$1))
+
+endif # __gmsl_have_eval
+
+# ###########################################################################
+# DEBUGGING FACILITIES
+# ###########################################################################
+
+# ----------------------------------------------------------------------------
+# Target:    gmsl-print-%
+# Arguments: The % should be replaced by the name of a variable that you
+#            wish to print out.
+# Action:    Echos the name of the variable that matches the % and its value.
+#            For example, 'make gmsl-print-SHELL' will output the value of
+#            the SHELL variable
+# ----------------------------------------------------------------------------
+gmsl-print-%: ; @echo $* = $($*)
+
+# ----------------------------------------------------------------------------
+# Function:  assert
+# Arguments: 1: A boolean that must be true or the assertion will fail
+#            2: The message to print with the assertion
+# Returns:   None
+# ----------------------------------------------------------------------------
+assert = $(if $1,,$(call __gmsl_error,Assertion failure: $2))
+
+# ----------------------------------------------------------------------------
+# Function:  assert_exists
+# Arguments: 1: Name of file that must exist, if it is missing an assertion
+#               will be generated
+# Returns:   None
+# ----------------------------------------------------------------------------
+assert_exists = $(call assert,$(wildcard $1),file '$1' missing)
+
+# ----------------------------------------------------------------------------
+# Function:  assert_no_dollar
+# Arguments: 1: Name of a function being executd
+#            2: Arguments to check
+# Returns:   None
+# ----------------------------------------------------------------------------
+assert_no_dollar = $(call assert,$(call not,$(findstring $$,$2)),$1 called with a dollar sign in argument)
diff --git a/ndk/build/gmsl/gmsl b/ndk/build/gmsl/gmsl
new file mode 100644
index 0000000..2ff2897
--- /dev/null
+++ b/ndk/build/gmsl/gmsl
@@ -0,0 +1,89 @@
+# ----------------------------------------------------------------------------
+#
+# GNU Make Standard Library (GMSL)
+#
+# A library of functions to be used with GNU Make's $(call) that
+# provides functionality not available in standard GNU Make.
+#
+# Copyright (c) 2005-2008 John Graham-Cumming
+#
+# This file is part of GMSL
+#
+# 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 the John Graham-Cumming 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "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 THE
+# COPYRIGHT OWNER OR CONTRIBUTORS 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.
+#
+# ----------------------------------------------------------------------------
+
+# Determine if the library has already been included and if so don't
+# bother including it again
+
+ifndef __gmsl_included
+
+# Standard definitions for true and false.  true is any non-empty
+# string, false is an empty string. These are intended for use with
+# $(if).
+
+true  := T
+false :=
+
+# ----------------------------------------------------------------------------
+# Function:  not
+# Arguments: 1: A boolean value
+# Returns:   Returns the opposite of the arg. (true -> false, false -> true)
+# ----------------------------------------------------------------------------
+not = $(if $1,$(false),$(true))
+
+# Prevent reinclusion of the library
+
+__gmsl_included := $(true)
+
+# Try to determine where this file is located.  If the caller did
+# include /foo/gmsl then extract the /foo/ so that __gmsl gets
+# included transparently
+
+ifneq ($(MAKEFILE_LIST),)
+__gmsl_root := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
+
+# If there are any spaces in the path in __gmsl_root then give up
+
+ifeq (1,$(words $(__gmsl_root)))
+__gmsl_root := $(patsubst %gmsl,%,$(__gmsl_root))
+else
+__gmsl_root :=
+endif
+
+include $(__gmsl_root)__gmsl
+
+else
+
+include __gmsl
+
+endif
+
+endif # __gmsl_included
+
diff --git a/ndk/build/gmsl/gmsl-tests b/ndk/build/gmsl/gmsl-tests
new file mode 100644
index 0000000..b205be6
--- /dev/null
+++ b/ndk/build/gmsl/gmsl-tests
@@ -0,0 +1,647 @@
+# ----------------------------------------------------------------------------
+#
+# GNU Make Standard Library (GMSL) Test Suite
+#
+# Test suite for the GMSL
+#
+# Copyright (c) 2005-2007 John Graham-Cumming
+#
+# This file is part of GMSL
+#
+# 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 the John Graham-Cumming 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "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 THE
+# COPYRIGHT OWNER OR CONTRIBUTORS 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.
+#
+# ----------------------------------------------------------------------------
+
+.PHONY: all
+all:
+	@echo
+	@echo Test Summary
+	@echo ------------
+	@echo "$(call int_decode,$(passed)) tests passed; $(call int_decode,$(failed)) tests failed"
+
+include gmsl
+
+passed :=
+failed :=
+
+ECHO := /bin/echo
+
+start_test = $(shell $(ECHO) -n "Testing '$1': " >&2)$(eval current_test := OK)
+stop_test  = $(shell $(ECHO) " $(current_test)" >&2)
+test_pass = .$(eval passed := $(call int_inc,$(passed)))
+test_fail = X$(eval failed := $(call int_inc,$(failed)))$(eval current_test := ERROR '$1' != '$2')
+test_assert = $(if $(filter undefined,$(origin 2)),$(eval 2 :=))$(shell $(ECHO) -n $(if $(call seq,$1,$2),$(call test_pass,$1,$2),$(call test_fail,$1,$2)) >&2)
+
+$(call start_test,not)
+$(call test_assert,$(call not,$(true)),$(false))
+$(call test_assert,$(call not,$(false)),$(true))
+$(call stop_test)
+
+$(call start_test,or)
+$(call test_assert,$(call or,$(true),$(true)),$(true))
+$(call test_assert,$(call or,$(true),$(false)),$(true))
+$(call test_assert,$(call or,$(false),$(true)),$(true))
+$(call test_assert,$(call or,$(false),$(false)),$(false))
+$(call stop_test)
+
+$(call start_test,and)
+$(call test_assert,$(call and,$(true),$(true)),$(true))
+$(call test_assert,$(call and,$(true),$(false)),$(false))
+$(call test_assert,$(call and,$(false),$(true)),$(false))
+$(call test_assert,$(call and,$(false),$(false)),$(false))
+$(call stop_test)
+
+$(call start_test,xor)
+$(call test_assert,$(call xor,$(true),$(true)),$(false))
+$(call test_assert,$(call xor,$(true),$(false)),$(true))
+$(call test_assert,$(call xor,$(false),$(true)),$(true))
+$(call test_assert,$(call xor,$(false),$(false)),$(false))
+$(call stop_test)
+
+$(call start_test,nand)
+$(call test_assert,$(call nand,$(true),$(true)),$(false))
+$(call test_assert,$(call nand,$(true),$(false)),$(true))
+$(call test_assert,$(call nand,$(false),$(true)),$(true))
+$(call test_assert,$(call nand,$(false),$(false)),$(true))
+$(call stop_test)
+
+$(call start_test,nor)
+$(call test_assert,$(call nor,$(true),$(true)),$(false))
+$(call test_assert,$(call nor,$(true),$(false)),$(false))
+$(call test_assert,$(call nor,$(false),$(true)),$(false))
+$(call test_assert,$(call nor,$(false),$(false)),$(true))
+$(call stop_test)
+
+$(call start_test,xnor)
+$(call test_assert,$(call xnor,$(true),$(true)),$(true))
+$(call test_assert,$(call xnor,$(true),$(false)),$(false))
+$(call test_assert,$(call xnor,$(false),$(true)),$(false))
+$(call test_assert,$(call xnor,$(false),$(false)),$(true))
+$(call stop_test)
+
+$(call start_test,first)
+$(call test_assert,$(call first,1 2 3),1)
+$(call test_assert,$(call first,1),1)
+$(call test_assert,$(call first,),)
+$(call stop_test)
+
+$(call start_test,last)
+$(call test_assert,$(call last,1 2 3),3)
+$(call test_assert,$(call last,1),1)
+$(call test_assert,$(call last,),)
+$(call stop_test)
+
+$(call start_test,rest)
+$(call test_assert,$(call rest,1 2 3),2 3)
+$(call test_assert,$(call rest,1),)
+$(call test_assert,$(call rest,),)
+$(call stop_test)
+
+$(call start_test,chop)
+$(call test_assert,$(call chop,1 2 3),1 2)
+$(call test_assert,$(call chop,1 2 3 4),1 2 3)
+$(call test_assert,$(call chop,1),)
+$(call test_assert,$(call chop,),)
+$(call stop_test)
+
+$(call start_test,length)
+$(call test_assert,$(call length,1 2 3),3)
+$(call test_assert,$(call length,1 2 3 4),4)
+$(call test_assert,$(call length,1),1)
+$(call test_assert,$(call length,),0)
+$(call stop_test)
+
+$(call start_test,map)
+$(call test_assert,$(call map,origin,__undefined map MAKE),undefined file default)
+$(call test_assert,$(call map,origin,),)
+$(call stop_test)
+
+joinem = $1$2
+$(call start_test,pairmap)
+$(call test_assert,$(call pairmap,addsuffix,2 1 3,a b c),a2 b1 c3)
+$(call test_assert,$(call pairmap,addprefix,2 1 3,a b c d),2a 1b 3c d)
+$(call test_assert,$(call pairmap,addprefix,2 1 3 4,a b c),2a 1b 3c)
+$(call test_assert,$(call pairmap,joinem,2 1 3 4,a b c),2a 1b 3c 4)
+$(call stop_test)
+
+$(call start_test,seq)
+$(call test_assert,$(call seq,abc,abc),T)
+$(call test_assert,$(call seq,x,),)
+$(call test_assert,$(call seq,,x),)
+$(call test_assert,$(call seq,x,x),T)
+$(call test_assert,$(call seq,a%c,abc),)
+$(call test_assert,$(call seq,abc,a%c),)
+$(call test_assert,$(call seq,abc,ABC),)
+$(call test_assert,$(call seq,abc,),)
+$(call test_assert,$(call seq,,),T)
+$(call test_assert,$(call seq,a b c,a b c),T)
+$(call test_assert,$(call seq,aa% bb% cc,aa% bb% cc),T)
+$(call test_assert,$(call seq,aa% bb% cc,aa% bb cc),)
+$(call test_assert,$(call seq,aa% bb% cc,xx yy zz),)
+$(call stop_test)
+
+$(call start_test,sne)
+$(call test_assert,$(call sne,abc,abc),)
+$(call test_assert,$(call sne,x,),T)
+$(call test_assert,$(call sne,,x),T)
+$(call test_assert,$(call sne,x,x),)
+$(call test_assert,$(call sne,abc,ABC),T)
+$(call test_assert,$(call sne,abc,),T)
+$(call test_assert,$(call sne,,),)
+$(call test_assert,$(call sne,a b c,a b c),)
+$(call test_assert,$(call sne,aa% bb% cc,aa% bb% cc),)
+$(call test_assert,$(call sne,aa% bb% cc,aa% bb cc),T)
+$(call stop_test)
+
+$(call start_test,strlen)
+$(call test_assert,$(call strlen,),0)
+$(call test_assert,$(call strlen,a),1)
+$(call test_assert,$(call strlen,a b),3)
+$(call test_assert,$(call strlen,a ),2)
+$(call test_assert,$(call strlen, a),2)
+$(call test_assert,$(call strlen,  ),2)
+$(call test_assert,$(call strlen,   ),3)
+$(call test_assert,$(call strlen,    ),4)
+$(call stop_test)
+
+$(call start_test,substr)
+$(call test_assert,$(call substr,xyz,1,1),x)
+$(call test_assert,$(call substr,xyz,1,2),xy)
+$(call test_assert,$(call substr,xyz,2,3),yz)
+$(call test_assert,$(call substr,some string,1,1),s)
+$(call test_assert,$(call substr,some string,1,2),so)
+$(call test_assert,$(call substr,some string,1,3),som)
+$(call test_assert,$(call substr,some string,1,4),some)
+$(call test_assert,$(call substr,some string,1,5),some )
+$(call test_assert,$(call substr,some string,1,6),some s)
+$(call test_assert,$(call substr,some string,5,5), )
+$(call test_assert,$(call substr,some string,5,6), s)
+$(call test_assert,$(call substr,some string,5,7), st)
+$(call test_assert,$(call substr,some string,5,8), str)
+$(call test_assert,$(call substr,some string,1,100),some string)
+$(call stop_test)
+
+$(call start_test,lc)
+$(call test_assert,$(call lc,The Quick Brown Fox),the quick brown fox)
+$(call test_assert,$(call lc,the1 quick2 brown3 fox4),the1 quick2 brown3 fox4)
+$(call test_assert,$(call lc,The_),the_)
+$(call test_assert,$(call lc,),)
+$(call stop_test)
+
+$(call start_test,uc)
+$(call test_assert,$(call uc,The Quick Brown Fox),THE QUICK BROWN FOX)
+$(call test_assert,$(call uc,the1 quick2 brown3 fox4),THE1 QUICK2 BROWN3 FOX4)
+$(call test_assert,$(call uc,The_),THE_)
+$(call test_assert,$(call uc,),)
+$(call stop_test)
+
+$(call start_test,tr)
+$(call test_assert,$(call tr,A B C,1 2 3,CAPITAL),31PIT1L)
+$(call test_assert,$(call tr,a b c,1 2 3,CAPITAL),CAPITAL)
+$(call test_assert,$(call tr,E L I,3 1 1,I AM ELITE),1 AM 311T3)
+$(call stop_test)
+
+$(call start_test,leq)
+$(call test_assert,$(call leq,1 2 3,1 2 3),T)
+$(call test_assert,$(call leq,1 2 3,1 2 3 4),)
+$(call test_assert,$(call leq,1 2 3 4,1 2 3),)
+$(call test_assert,$(call leq,1,1),T)
+$(call test_assert,$(call leq,,),T)
+$(call stop_test)
+
+$(call start_test,lne)
+$(call test_assert,$(call lne,1 2 3,1 2 3),)
+$(call test_assert,$(call lne,1 2 3,1 2 3 4),T)
+$(call test_assert,$(call lne,1 2 3 4,1 2 3),T)
+$(call test_assert,$(call lne,1,1),)
+$(call test_assert,$(call lne,,),)
+$(call stop_test)
+
+$(call start_test,empty_set)
+$(call test_assert,$(empty_set),)
+$(call test_assert,$(empty_set),$(call set_create,))
+$(call stop_test)
+
+$(call start_test,set_create)
+$(call test_assert,$(call set_create,),)
+$(call test_assert,$(call set_create,1 2 2 3),1 2 3)
+$(call test_assert,$(call set_create,2 1 1 2 2 3),1 2 3)
+$(call test_assert,$(call set_create,1),1)
+$(call stop_test)
+
+$(call start_test,set_insert)
+$(call test_assert,$(call set_insert,1,$(empty_set)),1)
+$(call test_assert,$(call set_insert,1,$(call set_create,1)),1)
+$(call test_assert,$(call set_insert,1,$(call set_create,1 2)),1 2)
+$(call test_assert,$(call set_insert,0,$(call set_create,1 2)),0 1 2)
+$(call stop_test)
+
+$(call start_test,set_remove)
+$(call test_assert,$(call set_remove,1,$(empty_set)),$(empty_set))
+$(call test_assert,$(call set_remove,1,$(call set_create,1 2)),2)
+$(call test_assert,$(call set_remove,1,$(call set_create,1 11 2)),11 2)
+$(call test_assert,$(call set_remove,0,$(call set_create,1 2)),1 2)
+$(call stop_test)
+
+$(call start_test,set_is_member)
+$(call test_assert,$(call set_is_member,1,$(empty_set)),)
+$(call test_assert,$(call set_is_member,1,$(call set_create,2 3)),)
+$(call test_assert,$(call set_is_member,1,$(call set_create,1 2 3)),T)
+$(call test_assert,$(call set_is_member,1,$(call set_create,1)),T)
+$(call stop_test)
+
+$(call start_test,set_union)
+$(call test_assert,$(call set_union,,),)
+$(call test_assert,$(call set_union,1 2,),1 2)
+$(call test_assert,$(call set_union,,3 4),3 4)
+$(call test_assert,$(call set_union,1 2,3 4),1 2 3 4)
+$(call test_assert,$(call set_union,1 2 3,3 4 5),1 2 3 4 5)
+$(call stop_test)
+
+$(call start_test,set_intersection)
+$(call test_assert,$(call set_intersection,,),)
+$(call test_assert,$(call set_intersection,1 2,),)
+$(call test_assert,$(call set_intersection,,3 4),)
+$(call test_assert,$(call set_intersection,1 2,3 4),)
+$(call test_assert,$(call set_intersection,1 2 3 4,3 4 5),3 4)
+$(call stop_test)
+
+$(call start_test,set_is_subset)
+$(call test_assert,$(call set_is_subset,,),T)
+$(call test_assert,$(call set_is_subset,1 2,),)
+$(call test_assert,$(call set_is_subset,,3 4),T)
+$(call test_assert,$(call set_is_subset,1 2,3 4),)
+$(call test_assert,$(call set_is_subset,1 2,1 2 3 4 5),T)
+$(call test_assert,$(call set_is_subset,1 2,1 2),T)
+$(call test_assert,$(call set_is_subset,1 2,1 3 4 5),)
+$(call stop_test)
+
+$(call start_test,set_equal)
+$(call test_assert,$(call set_equal,,),T)
+$(call test_assert,$(call set_equal,1,),)
+$(call test_assert,$(call set_equal,,1),)
+$(call test_assert,$(call set_equal,1,1),T)
+$(call test_assert,$(call set_equal,1 2,),)
+$(call test_assert,$(call set_equal,,1 2),)
+$(call test_assert,$(call set_equal,1 2,1 2 3),)
+$(call stop_test)
+
+$(call start_test,int_encode)
+$(call test_assert,$(call int_encode,0),)
+$(call test_assert,$(call int_encode,1),x)
+$(call test_assert,$(call int_encode,2),x x)
+$(call test_assert,$(call int_encode,10),x x x x x x x x x x)
+$(call stop_test)
+
+$(call start_test,int_decode)
+$(call test_assert,$(call int_decode,),0)
+$(call test_assert,$(call int_decode,x),1)
+$(call test_assert,$(call int_decode,x x),2)
+$(call test_assert,$(call int_decode,x x x x x x x x x x),10)
+$(call stop_test)
+
+$(call start_test,int_plus)
+$(call test_assert,$(call int_plus,$(call int_encode,3),$(call int_encode,4)),$(call int_encode,7))
+$(call test_assert,$(call int_plus,$(call int_encode,0),$(call int_encode,4)),$(call int_encode,4))
+$(call test_assert,$(call int_plus,$(call int_encode,3),$(call int_encode,0)),$(call int_encode,3))
+$(call test_assert,$(call int_plus,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_plus,$(call int_encode,1),$(call int_encode,0)),$(call int_encode,1))
+$(call stop_test)
+
+$(call start_test,plus)
+$(call test_assert,$(call plus,3,4),7)
+$(call test_assert,$(call plus,4,3),7)
+$(call test_assert,$(call plus,0,4),4)
+$(call test_assert,$(call plus,3,0),3)
+$(call test_assert,$(call plus,0,0),0)
+$(call stop_test)
+
+__gmsl_warning = $1
+$(call start_test,int_subtract)
+$(call test_assert,$(call int_subtract,$(call int_encode,3),$(call int_encode,4)),Subtraction underflow)
+$(call test_assert,$(call int_subtract,$(call int_encode,4),$(call int_encode,3)),$(call int_encode,1))
+$(call test_assert,$(call int_subtract,$(call int_encode,3),$(call int_encode,0)),$(call int_encode,3))
+$(call test_assert,$(call int_subtract,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_subtract,$(call int_encode,1),$(call int_encode,0)),$(call int_encode,1))
+$(call stop_test)
+
+__gmsl_warning = x x x x x x x x x x
+$(call start_test,subtract)
+$(call test_assert,$(call subtract,3,4),10)
+$(call test_assert,$(call subtract,4,3),1)
+$(call test_assert,$(call subtract,3,0),3)
+$(call test_assert,$(call subtract,0,0),0)
+$(call stop_test)
+
+$(call start_test,int_multiply)
+$(call test_assert,$(call int_multiply,$(call int_encode,3),$(call int_encode,4)),$(call int_encode,12))
+$(call test_assert,$(call int_multiply,$(call int_encode,4),$(call int_encode,3)),$(call int_encode,12))
+$(call test_assert,$(call int_multiply,$(call int_encode,3),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_multiply,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_multiply,$(call int_encode,1),$(call int_encode,0)),$(call int_encode,0))
+$(call stop_test)
+
+$(call start_test,multiply)
+$(call test_assert,$(call multiply,3,4),12)
+$(call test_assert,$(call multiply,4,3),12)
+$(call test_assert,$(call multiply,3,0),0)
+$(call test_assert,$(call multiply,0,3),0)
+$(call test_assert,$(call multiply,0,0),0)
+$(call stop_test)
+
+__gmsl_error = $1
+$(call start_test,int_divide)
+$(call test_assert,$(call int_divide,$(call int_encode,3),$(call int_encode,4)),$(call int_encode,0))
+$(call test_assert,$(call int_divide,$(call int_encode,4),$(call int_encode,3)),$(call int_encode,1))
+$(call test_assert,$(call int_divide,$(call int_encode,31),$(call int_encode,3)),$(call int_encode,10))
+$(call test_assert,$(call int_divide,$(call int_encode,30),$(call int_encode,3)),$(call int_encode,10))
+$(call test_assert,$(call int_divide,$(call int_encode,29),$(call int_encode,3)),$(call int_encode,9))
+$(call test_assert,$(call int_divide,$(call int_encode,0),$(call int_encode,1)),$(call int_encode,0))
+$(call test_assert,$(call int_divide,$(call int_encode,1),$(call int_encode,0)),Division by zero)
+$(call stop_test)
+
+__gmsl_error = x x x x x x x x x x
+$(call start_test,divide)
+$(call test_assert,$(call divide,3,4),0)
+$(call test_assert,$(call divide,4,3),1)
+$(call test_assert,$(call divide,21,2),10)
+$(call test_assert,$(call divide,20,2),10)
+$(call test_assert,$(call divide,19,2),9)
+$(call test_assert,$(call divide,1,0),10)
+$(call stop_test)
+
+$(call start_test,associative array)
+$(call test_assert,$(call get,myarray,key1),)
+$(call set,myarray,key1,value1)
+$(call test_assert,$(call get,myarray,key1),value1)
+$(call test_assert,$(call get,myarray,key2),)
+$(call test_assert,$(call get,myarray1,key1),)
+$(call test_assert,$(call defined,myarray,key1),T)
+$(call test_assert,$(call defined,myarray,key2),)
+$(call test_assert,$(call defined,myarray1,key1),)
+$(call set,myarray,key2,value2)
+$(call test_assert,$(call keys,myarray),key1 key2)
+$(call test_assert,$(call keys,myarray1),)
+$(call stop_test)
+
+$(call start_test,named stack)
+$(call test_assert,$(call pop,mystack),)
+$(call test_assert,$(call push,mystack,e2))
+$(call push,mystack,e1)
+$(call test_assert,$(call pop,mystack),e1)
+$(call test_assert,$(call pop,mystack),e2)
+$(call push,mystack,f3)
+$(call push,mystack,f1)
+$(call test_assert,$(call pop,mystack),f1)
+$(call push,mystack,f2)
+$(call test_assert,$(call peek,mystack),f2)
+$(call test_assert,$(call depth,mystack),2)
+$(call test_assert,$(call pop,mystack),f2)
+$(call test_assert,$(call depth,mystack),1)
+$(call test_assert,$(call pop,myotherstack),)
+$(call stop_test)
+
+$(call start_test,reverse)
+$(call test_assert,$(call reverse,),)
+$(call test_assert,$(call reverse,1),1)
+$(call test_assert,$(call reverse,1 2),2 1)
+$(call test_assert,$(call reverse,1 2 3),3 2 1)
+$(call stop_test)
+
+$(call start_test,uniq)
+$(call test_assert,$(call uniq,),)
+$(call test_assert,$(call uniq,a),a)
+$(call test_assert,$(call uniq,a a),a)
+$(call test_assert,$(call uniq,a aa),a aa)
+$(call test_assert,$(call uniq,a aa a),a aa)
+$(call test_assert,$(call uniq,a b ba ab b a a ba a),a b ba ab)
+$(call stop_test)
+
+c:=,
+$(call start_test,split)
+$(call test_assert,$(call split,$c,comma$cseparated$cstring),comma separated string)
+$(call test_assert,$(call split,*,star*field*record),star field record)
+$(call test_assert,$(call split,*,star*),star)
+$(call test_assert,$(call split,*,star*field),star field)
+$(call test_assert,$(call split,*,star****field),star field)
+$(call test_assert,$(call split,*,),)
+$(call stop_test)
+
+$(call start_test,merge)
+$(call test_assert,$(call merge,$c,list of things),list$cof$cthings)
+$(call test_assert,$(call merge,*,list of things),list*of*things)
+$(call test_assert,$(call merge,*,list),list)
+$(call test_assert,$(call merge,*,),)
+$(call stop_test)
+
+$(call start_test,int_max)
+$(call test_assert,$(call int_max,$(call int_encode,2),$(call int_encode,1)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,1),$(call int_encode,2)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,2),$(call int_encode,0)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,0),$(call int_encode,2)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,2),$(call int_encode,2)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call stop_test)
+
+$(call start_test,max)
+$(call test_assert,$(call max,2,1),2)
+$(call test_assert,$(call max,1,2),2)
+$(call test_assert,$(call max,2,0),2)
+$(call test_assert,$(call max,0,2),2)
+$(call test_assert,$(call max,2,2),2)
+$(call test_assert,$(call max,0,0),0)
+$(call stop_test)
+
+$(call start_test,int_min)
+$(call test_assert,$(call int_min,$(call int_encode,2),$(call int_encode,1)),$(call int_encode,1))
+$(call test_assert,$(call int_min,$(call int_encode,1),$(call int_encode,2)),$(call int_encode,1))
+$(call test_assert,$(call int_min,$(call int_encode,2),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_min,$(call int_encode,0),$(call int_encode,2)),$(call int_encode,0))
+$(call test_assert,$(call int_min,$(call int_encode,2),$(call int_encode,2)),$(call int_encode,2))
+$(call test_assert,$(call int_min,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call stop_test)
+
+$(call start_test,min)
+$(call test_assert,$(call min,2,1),1)
+$(call test_assert,$(call min,1,2),1)
+$(call test_assert,$(call min,2,0),0)
+$(call test_assert,$(call min,0,2),0)
+$(call test_assert,$(call min,2,2),2)
+$(call test_assert,$(call min,0,0),0)
+$(call stop_test)
+
+__gmsl_error = $1
+$(call start_test,assert functions)
+$(call test_assert,$(call assert,$(true),ignore),)
+$(call test_assert,$(call assert,$(false),failed),Assertion failure: failed)
+$(call test_assert,$(call assert_exists,gmsl-tests),)
+$(call test_assert,$(call assert_exists,MISSING-gmsl-tests),Assertion failure: file 'MISSING-gmsl-tests' missing)
+$(call stop_test)
+
+$(call start_test,int_inc)
+$(call test_assert,$(call int_inc,$(call int_encode,0)),$(call int_encode,1))
+$(call test_assert,$(call int_inc,$(call int_encode,1)),$(call int_encode,2))
+$(call test_assert,$(call int_inc,$(call int_encode,4)),$(call int_encode,5))
+$(call test_assert,$(call int_inc,$(call int_encode,10)),$(call int_encode,11))
+$(call stop_test)
+
+$(call start_test,inc)
+$(call test_assert,$(call inc,0),1)
+$(call test_assert,$(call inc,1),2)
+$(call test_assert,$(call inc,4),5)
+$(call test_assert,$(call inc,10),11)
+$(call stop_test)
+
+__gmsl_warning = $1
+$(call start_test,int_dec)
+$(call test_assert,$(call int_dec,$(call int_encode,0)),Decrement underflow)
+$(call test_assert,$(call int_dec,$(call int_encode,1)),$(call int_encode,0))
+$(call test_assert,$(call int_dec,$(call int_encode,4)),$(call int_encode,3))
+$(call test_assert,$(call int_dec,$(call int_encode,10)),$(call int_encode,9))
+$(call stop_test)
+
+__gmsl_warning = x x x x x x x x x x
+$(call start_test,dec)
+$(call test_assert,$(call dec,0),10)
+$(call test_assert,$(call dec,1),0)
+$(call test_assert,$(call dec,4),3)
+$(call test_assert,$(call dec,10),9)
+$(call stop_test)
+
+$(call start_test,int_double)
+$(call test_assert,$(call int_double,$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_double,$(call int_encode,1)),$(call int_encode,2))
+$(call test_assert,$(call int_double,$(call int_encode,4)),$(call int_encode,8))
+$(call stop_test)
+
+$(call start_test,double)
+$(call test_assert,$(call double,0),0)
+$(call test_assert,$(call double,1),2)
+$(call test_assert,$(call double,4),8)
+$(call stop_test)
+
+$(call start_test,int_halve)
+$(call test_assert,$(call int_halve,$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_halve,$(call int_encode,2)),$(call int_encode,1))
+$(call test_assert,$(call int_halve,$(call int_encode,8)),$(call int_encode,4))
+$(call test_assert,$(call int_halve,$(call int_encode,7)),$(call int_encode,3))
+$(call stop_test)
+
+$(call start_test,halve)
+$(call test_assert,$(call halve,0),0)
+$(call test_assert,$(call halve,2),1)
+$(call test_assert,$(call halve,8),4)
+$(call test_assert,$(call halve,7),3)
+$(call stop_test) 
+
+$(call start_test,gt)
+$(call test_assert,$(call gt,2,3),)
+$(call test_assert,$(call gt,3,2),$(true))
+$(call test_assert,$(call gt,2,2),)
+$(call stop_test)
+
+$(call start_test,gte)
+$(call test_assert,$(call gte,2,3),)
+$(call test_assert,$(call gte,3,2),$(true))
+$(call test_assert,$(call gte,2,2),$(true))
+$(call stop_test)
+
+$(call start_test,lt)
+$(call test_assert,$(call lt,2,3),$(true))
+$(call test_assert,$(call lt,3,2),)
+$(call test_assert,$(call lt,2,2),)
+$(call stop_test)
+
+$(call start_test,lte)
+$(call test_assert,$(call lte,2,3),$(true))
+$(call test_assert,$(call lte,3,2),)
+$(call test_assert,$(call lte,2,2),$(true))
+$(call stop_test)
+
+$(call start_test,eq)
+$(call test_assert,$(call eq,2,3),)
+$(call test_assert,$(call eq,3,2),)
+$(call test_assert,$(call eq,2,2),$(true))
+$(call stop_test)
+
+$(call start_test,ne)
+$(call test_assert,$(call ne,2,3),$(true))
+$(call test_assert,$(call ne,3,2),$(true))
+$(call test_assert,$(call ne,2,2),)
+$(call stop_test)
+
+$(call start_test,int_gt)
+$(call test_assert,$(call int_gt,$(call int_encode,2),$(call int_encode,3)),)
+$(call test_assert,$(call int_gt,$(call int_encode,3),$(call int_encode,2)),$(true))
+$(call test_assert,$(call int_gt,$(call int_encode,2),$(call int_encode,2)),)
+$(call stop_test)
+
+$(call start_test,int_gte)
+$(call test_assert,$(call int_gte,$(call int_encode,2),$(call int_encode,3)),)
+$(call test_assert,$(call int_gte,$(call int_encode,3),$(call int_encode,2)),$(true))
+$(call test_assert,$(call int_gte,$(call int_encode,2),$(call int_encode,2)),$(true))
+$(call stop_test)
+
+$(call start_test,int_lt)
+$(call test_assert,$(call int_lt,$(call int_encode,2),$(call int_encode,3)),$(true))
+$(call test_assert,$(call int_lt,$(call int_encode,3),$(call int_encode,2)),)
+$(call test_assert,$(call int_lt,$(call int_encode,2),$(call int_encode,2)),)
+$(call stop_test)
+
+$(call start_test,int_lte)
+$(call test_assert,$(call int_lte,$(call int_encode,2),$(call int_encode,3)),$(true))
+$(call test_assert,$(call int_lte,$(call int_encode,3),$(call int_encode,2)),)
+$(call test_assert,$(call int_lte,$(call int_encode,2),$(call int_encode,2)),$(true))
+$(call stop_test)
+
+$(call start_test,int_eq)
+$(call test_assert,$(call int_eq,$(call int_encode,2),$(call int_encode,3)),)
+$(call test_assert,$(call int_eq,$(call int_encode,3),$(call int_encode,2)),)
+$(call test_assert,$(call int_eq,$(call int_encode,2),$(call int_encode,2)),$(true))
+$(call stop_test)
+
+$(call start_test,int_ne)
+$(call test_assert,$(call int_ne,$(call int_encode,2),$(call int_encode,3)),$(true))
+$(call test_assert,$(call int_ne,$(call int_encode,3),$(call int_encode,2)),$(true))
+$(call test_assert,$(call int_ne,$(call int_encode,2),$(call int_encode,2)),)
+$(call stop_test)
+
+$(call start_test,gmsl_compatible)
+$(call test_assert,$(call gmsl_compatible,$(gmsl_version)),$(true))
+$(call test_assert,$(call gmsl_compatible,0 9 0),$(true))
+$(call test_assert,$(call gmsl_compatible,0 0 1),$(true))
+$(call test_assert,$(call gmsl_compatible,0 0 0),$(true))
+$(call test_assert,$(call gmsl_compatible,2 0 0),)
+$(call test_assert,$(call gmsl_compatible,1 1 0),)
+$(call test_assert,$(call gmsl_compatible,1 0 8),$(true))
+$(call test_assert,$(call gmsl_compatible,1 0 8),$(true))
+$(call test_assert,$(call gmsl_compatible,1 0 10),$(true))
+$(call test_assert,$(call gmsl_compatible,1 0 11),$(true))
+$(call test_assert,$(call gmsl_compatible,1 0 12),)
+$(call stop_test)
diff --git a/ndk/build/gmsl/index.html b/ndk/build/gmsl/index.html
new file mode 100644
index 0000000..8cc93ae
--- /dev/null
+++ b/ndk/build/gmsl/index.html
@@ -0,0 +1,687 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+  <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
+  <title>GNU Make Standard Library</title></head>
+
+<body>
+<h1>GNU Make Standard Library</h1>
+The GNU Make Standard Library (GMSL) is a collection of functions
+implemented using native GNU Make functionality that provide list and
+string manipulation, integer arithmetic, associative arrays, stacks,
+and debugging facilities.&nbsp; The GMSL is released under the BSD License.<br>
+<br>
+<a href="http://sourceforge.net/projects/gmsl/">[Project Page]</a> <a href="http://sourceforge.net/project/showfiles.php?group_id=129887">[Download]</a>
+<a href="http://sourceforge.net/forum/forum.php?forum_id=443916">[Discussion
+Forum]</a><br>
+<h2>Using GMSL</h2>
+The two files needed are <span style="font-family: monospace;">gmsl</span>
+and <span style="font-family: monospace;">__gmsl</span>.&nbsp; To
+include the GMSL in your Makefile do<br>
+<pre style="margin-left: 40px;">include gmsl</pre>
+<span style="font-family: monospace;">gmsl</span> automatically includes<span style="font-family: monospace;"> __gmsl</span>.&nbsp; To check that
+you have the right version of <span style="font-family: monospace;">gmsl</span>
+use the <span style="font-family: monospace;">gmsl_compatible</span>
+function (see
+below). The current version is <span style="font-family: monospace;">1
+0 11</span>.<br>
+<br>
+The GMSL package also includes a test suite for GMSL.&nbsp; Just run <span style="font-family: monospace;">make -f gmsl-tests</span>.<br>
+<h2>Logical Operators</h2>GMSL has boolean $(true) (a non-empty string)
+and $(false) (an empty string).&nbsp; The following operators can be
+used with those variables.<br>
+<br>
+<hr style="width: 100%; height: 2px;"><span style="font-weight: bold;">not</span><br>
+
+<br>
+
+<span style="font-family: monospace;">Arguments: A boolean value</span><br style="font-family: monospace;">
+
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if the boolean is $(false) and vice versa</span><br style="font-family: monospace;">
+
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;"></span><span style="font-weight: bold;">and</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if both of the booleans are true</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">or</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if either of the booleans is true</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">xor</span><br style="font-weight: bold;">
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if exactly one of the booleans is true</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">nand</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns value of 'not and'</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">nor</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns value of 'not or'</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">xnor</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns value of 'not xor'</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;">
+<h2>List Manipulation Functions</h2>
+&nbsp;A list is a string of characters; the list separator is a space.<br>
+
+<br>
+<hr style="width: 100%; height: 2px;"><b>first</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the first element of a list<br>
+</span>
+<hr><b>last</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the last element of a list<br>
+</span>
+<hr><b>rest</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the list with the first element
+removed<br>
+</span>
+<hr><b>chop</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the list with the last element removed<br>
+</span>
+<hr><b>map</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of function to
+$(call) for each element of list<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: List to
+iterate over calling the function in 1<br>
+Returns:&nbsp;&nbsp;&nbsp;The list after calling the function on each
+element<br>
+</span>
+<hr><b>pairmap</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of function to
+$(call) for each pair of elements<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: List to
+iterate over calling the function in 1<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: Second
+list to iterate over calling the function in 1<br>
+Returns:&nbsp;&nbsp;&nbsp;The list after calling the function on each
+pair of elements<br>
+</span>
+<hr><b>leq</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to compare
+against...<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
+list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two lists are identical<br>
+</span>
+<hr><b>lne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to compare
+against...<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
+list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two lists are different<br>
+</span>
+<hr><b>reverse</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to reverse<br>
+Returns:&nbsp;&nbsp;&nbsp;The list with its elements in reverse order<br>
+</span>
+<hr><b>uniq</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to deduplicate<br>
+Returns:&nbsp;&nbsp;&nbsp;The list with elements in order without duplicates<br>
+</span>
+<hr><b>length</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;The number of elements in the list<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>String Manipulation Functions</h2>
+A string is any sequence of characters.<br>
+<br>
+<hr style="width: 100%; height: 2px;"><b>seq</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string to compare
+against...<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
+string<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two strings are
+identical<br>
+</span>
+<hr><b>sne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string to compare
+against...<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
+string<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two strings are not
+the same<br>
+</span>
+<hr><b>strlen</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the length of the string<br>
+</span>
+<hr><b>substr</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Start offset (first character is 1)<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: Ending offset (inclusive)<br>Returns:&nbsp;&nbsp;&nbsp;Returns a substring<br>
+</span>
+<hr><b>split</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: The character to
+split on<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: A
+string to split<br>
+Returns:&nbsp;&nbsp;&nbsp;Splits a string into a list separated by
+spaces at the split<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; character
+in the first argument<br>
+</span>
+<hr><b>merge</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: The character to
+put between fields<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: A list
+to merge into a string<br>
+Returns:&nbsp;&nbsp;&nbsp;Merges a list into a single string, list
+elements are separated<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by the
+character in the first argument<br>
+</span>
+<hr><b>tr</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: The list of
+characters to translate from <br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The
+list of characters to translate to<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: The
+text to translate<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the text after translating characters<br>
+</span>
+<hr><b>uc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Text to upper case<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the text in upper case<br>
+</span>
+<hr><b>lc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Text to lower case<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the text in lower case<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Set Manipulation Functions</h2>
+Sets are represented by sorted, deduplicated lists.  To create a set
+from a list use <span style="font-family:
+monospace;">set_create</span>, or start with the <span
+style="font-family: monospace;">empty_set</span> and <span
+style="font-family: monospace;">set_insert</span> individual elements.
+The empty set is defined as <span style="font-family:
+monospace;">empty_set</span>.<p>
+
+<hr><b>set_create</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list of set elements<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the newly created set<br>
+</span>
+
+<hr><b>set_insert</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A single element to add to a set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: A set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the set with the element added<br>
+</span>
+
+<hr><b>set_remove</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A single element to remove from a set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: A set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the set with the element removed<br>
+</span>
+
+<hr><b>set_is_member</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A single element<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: A set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the element is in the set<br>
+</span>
+
+<hr><b>set_union</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the union of the two sets<br>
+</span>
+
+<hr><b>set_intersection</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the intersection of the two sets<br>
+</span>
+
+<hr><b>set_is_subset</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the first set is a subset of the second<br>
+</span>
+
+<hr><b>set_equal</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two sets are identical<br>
+</span>
+
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Integer Arithmetic Functions</h2>
+Integers are represented by lists with the equivalent number of
+x's.&nbsp; For example the number 4 is x x x x.&nbsp; The maximum
+integer that the library can handle as <span style="font-style: italic;">input</span> (i.e. as the argument to a
+call to <span style="font-family: monospace;">int_encode</span>) is
+65536. There is no limit on integer size for internal computations or
+output.<br>
+<br>
+The arithmetic library functions come in two forms: one form of each
+function takes integers as arguments and the other form takes the
+encoded form (x's created by a call to <span style="font-family: monospace;">int_encode</span>).&nbsp; For example,
+there are two plus functions: <span style="font-family: monospace;">plus</span>
+(called with integer arguments and returns an integer) and <span style="font-family: monospace;">int_plus</span> (called with encoded
+arguments and returns an encoded result).<br>
+<br>
+<span style="font-family: monospace;">plus</span> will be slower than <span style="font-family: monospace;">int_plus</span> because its arguments
+and result have to be translated between the x's format and
+integers.&nbsp; If doing a complex calculation use the <span style="font-family: monospace;">int_*</span> forms with a single
+encoding of inputs and single decoding of the output.&nbsp; For simple
+calculations the direct forms can be used.<br>
+<br>
+<hr style="width: 100%; height: 2px;"><b>int_decode</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number of x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the integer for human consumption
+that is represented<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by the
+string of x's<br>
+</span>
+<hr><b>int_encode</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in
+human-readable integer form<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the integer encoded as a string of x's<br>
+</span>
+<hr><b>int_plus</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the sum of the two numbers in x's
+representation<br>
+</span>
+<hr><b>plus (wrapped version of int_plus)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the sum of the two integers<br>
+</span>
+<hr><b>int_subtract</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the difference of the two numbers in
+x's representation,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or outputs
+an error on a numeric underflow<br>
+</span>
+<hr><b>subtract (wrapped version of int_subtract)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the difference of the two integers,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or outputs
+an error on a numeric underflow<br>
+</span>
+<hr><b>int_multiply</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the product of the two numbers in x's
+representation<br>
+</span>
+<hr><b>multiply (wrapped version of int_multiply)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the product of the two integers<br>
+</span>
+<hr><b>int_divide</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the result of integer division of
+argument 1 divided<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by
+argument 2 in x's representation<br>
+</span>
+<hr><b>divide (wrapped version of int_divide)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the integer division of the first
+argument by the second<br>
+</span>
+<hr><b>int_max, int_min</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the maximum or minimum of its
+arguments in x's<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+representation<br>
+</span>
+<hr><b>max, min</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the maximum or minimum of its integer
+arguments<br>
+</span>
+<hr><b>int_gt, int_gte, int_lt, int_lte, int_eq, int_ne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two x's representation
+numbers to be compared<br>
+Returns:&nbsp;&nbsp;&nbsp;$(true) or $(false)<br>
+<br>
+int_gt First argument greater than second argument<br>
+int_gte First argument greater than or equal to second argument<br>
+int_lt First argument less than second argument <br>
+int_lte First argument less than or equal to second argument<br>
+int_eq First argument is numerically equal to the second argument<br>
+int_ne First argument is not numerically equal to the second argument<br>
+</span>
+<hr><b>gt, gte, lt, lte, eq, ne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two integers to be
+compared<br>
+Returns:&nbsp;&nbsp;&nbsp;$(true) or $(false)<br>
+<br>
+gt First argument greater than second argument<br>
+gte First argument greater than or equal to second argument<br>
+lt First argument less than second argument <br>
+lte First argument less than or equal to second argument<br>
+eq First argument is numerically equal to the second argument<br>
+ne First argument is not numerically equal to the second argument<br>
+</span>
+increment adds 1 to its argument, decrement subtracts 1. Note that<br>
+decrement does not range check and hence will not underflow, but<br>
+will incorrectly say that 0 - 1 = 0<br>
+<hr><b>int_inc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;The number incremented by 1 in x's
+representation<br>
+</span>
+<hr><b>inc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns:&nbsp;&nbsp;&nbsp;The argument incremented by 1<br>
+</span>
+<hr><b>int_dec</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;The number decremented by 1 in x's
+representation<br>
+</span>
+<hr><b>dec</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns:&nbsp;&nbsp;&nbsp;The argument decremented by 1<br>
+</span>
+<hr><b>int_double</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;The number doubled (i.e. * 2) and returned in
+x's representation<br>
+</span>
+<hr><b>double</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns:&nbsp;&nbsp;&nbsp;The integer times 2<br>
+</span>
+<hr><b>int_halve</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;The number halved (i.e. / 2) and returned in
+x's representation<br>
+</span>
+<hr><b>halve</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns:&nbsp;&nbsp;&nbsp;The integer divided by 2<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Associative Arrays</h2>
+An associate array maps a key value (a string with no spaces in it) to
+a single value (any string).&nbsp;&nbsp;&nbsp; <br>
+<b><br>
+</b>
+<hr style="width: 100%; height: 2px;"><b>set</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The key
+value to associate<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: The
+value associated with the key<br>
+Returns:&nbsp;&nbsp;&nbsp;None<br>
+</span>
+<hr><b>get</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The key
+to retrieve<br>
+Returns:&nbsp;&nbsp;&nbsp;The value stored in the array for that key<br>
+</span>
+<hr><b>keys</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns a list of all defined keys in the
+array<br>
+</span>
+<hr><b>defined</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The key
+to test<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns true if the key is defined (i.e. not
+empty)<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Named Stacks</h2>
+A stack is an ordered list of strings (with no spaces in them).<br>
+<br>
+<hr style="width: 100%; height: 2px;"><b>push</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Value
+to push onto the top of the stack (must not contain<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a space)<br>
+Returns:&nbsp;&nbsp;&nbsp;None<br>
+</span>
+<hr><b>pop</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+Returns:&nbsp;&nbsp;&nbsp;Top element from the stack after removing it<br>
+</span>
+<hr><b>peek</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+Returns:&nbsp;&nbsp;&nbsp;Top element from the stack without removing it<br>
+</span>
+<hr><b>depth</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+Returns:&nbsp;&nbsp;&nbsp;Number of items on the stack<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Miscellaneous and Debugging Facilities</h2>
+GMSL defines the following constants; all are accessed as normal GNU
+Make variables by wrapping them in <span style="font-family: monospace;">$()</span> or <span style="font-family: monospace;">${}</span>.<br>
+<br>
+<table style="text-align: left;" border="1" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td><span style="font-style: italic;">Constant</span><br>
+      </td>
+      <td><span style="font-style: italic;">Value</span><br>
+      </td>
+      <td><span style="font-style: italic;">Purpose</span><br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">true</span><br>
+      </td>
+      <td><span style="font-family: monospace;">T</span><br>
+      </td>
+      <td>Boolean for <span style="font-family: monospace;">$(if)</span>
+and return from&nbsp; GMSL functions<br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">false</span><br>
+      </td>
+      <td><br>
+      </td>
+      <td>Boolean for <span style="font-family: monospace;">$(if)</span>
+and return from GMSL functions<br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">gmsl_version</span><br>
+      </td>
+      <td><span style="font-family: monospace;">1 0 0</span><br>
+      </td>
+      <td>GMSL version number as list: major minor revision<br>
+      </td>
+    </tr>
+  </tbody>
+</table>
+<span style="font-weight: bold;"><br>
+gmsl_compatible</span><span style="font-family: monospace;"><br>
+<br>
+Arguments: List containing the desired library version number (maj min
+rev)<br>
+</span><span style="font-family: monospace;">Returns:&nbsp;&nbsp;
+$(true) if this version of the library is compatible<br>
+</span><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+with the requested version number, otherwise $(false)</span>
+<hr><b>gmsl-print-% (target not a function)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: The % should be
+replaced by the name of a variable that you<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wish to
+print out.<br>
+Action:&nbsp;&nbsp;&nbsp; Echos the name of the variable that matches
+the % and its value.<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For
+example, 'make gmsl-print-SHELL' will output the value of<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the SHELL
+variable<br>
+</span>
+<hr><b>assert</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A boolean that must
+be true or the assertion will fail<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The
+message to print with the assertion<br>
+Returns:&nbsp;&nbsp;&nbsp;None<br>
+</span>
+<hr><b>assert_exists</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of file that
+must exist, if it is missing an assertion<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; will be
+generated<br>
+Returns:&nbsp;&nbsp;&nbsp;None<br>
+</span>
+<hr style="width: 100%; height: 2px;"><br>
+GMSL has a number of environment variables (or command-line overrides)
+that control various bits of functionality:<br>
+<br>
+<table style="text-align: left;" border="1" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td><span style="font-style: italic;">Variable</span><br>
+      </td>
+      <td><span style="font-style: italic;">Purpose</span><br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">GMSL_NO_WARNINGS</span><br>
+      </td>
+      <td>If set prevents GMSL from outputting warning messages:
+artithmetic functions generate underflow warnings.<br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">GMSL_NO_ERRORS</span><br>
+      </td>
+      <td>If set prevents GMSL from generating fatal errors: division
+by zero or failed assertions are fatal.<br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">GMSL_TRACE</span><br>
+      </td>
+      <td>Enables function tracing.&nbsp; Calls to GMSL functions will
+result in name and arguments being traced.<br>
+      </td>
+    </tr>
+  </tbody>
+</table>
+<span style="font-family: monospace;"></span><br>
+<hr>
+Copyright (c) 2005-2006 <a href="http://www.jgc.org/">John Graham-Cumming</a>.<br>
+<hr style="width: 100%; height: 2px;">
+<table style="width: 100%; text-align: left;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="width: 50%;">John Graham-Cumming's work on this
+project was sponsored by <a href="http://www.electric-cloud.com/">Electric
+Cloud, Inc</a>.<br>
+      <a href="http://www.electric-cloud.com/"><img alt="" src="http://gmsl.sf.net/ec_logo.gif" style="border: 0px solid ; width: 223px; height: 47px;"></a><br>
+      </td>
+      <td align="right">
+      <p><a href="http://sourceforge.net/"><img src="http://sourceforge.net/sflogo.php?group_id=129887&amp;type=1" alt="SourceForge.net Logo" border="0" height="31" width="88"></a></p>
+      </td>
+    </tr>
+  </tbody>
+</table>
+</body></html>
diff --git a/ndk/build/host-setup.sh b/ndk/build/host-setup.sh
new file mode 100755
index 0000000..e94944e
--- /dev/null
+++ b/ndk/build/host-setup.sh
@@ -0,0 +1,102 @@
+#!/bin/sh
+#
+# 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.
+#
+#  A shell script used to configure the host-specific parts of the NDK
+#  build system. This will create out/host/config-host.make based on
+#  your host system and additionnal command-line options.
+#
+
+# include common function and variable definitions
+source `dirname $0`/core/ndk-common.sh
+
+OUT_DIR=out
+HOST_CONFIG=$OUT_DIR/host/config.mk
+
+## Build configuration file support
+## you must define $config_mk before calling this function
+##
+create_config_mk ()
+{
+    # create the directory if needed
+    local  config_dir
+    config_mk=${config_mk:-$HOST_CONFIG}
+    config_dir=`dirname $config_mk`
+    mkdir -p $config_dir 2> $TMPL
+    if [ $? != 0 ] ; then
+        echo "Can't create directory for host config file: $config_dir"
+        exit 1
+    fi
+
+    # re-create the start of the configuration file
+    log "Generate   : $config_mk"
+
+    echo "# This file was autogenerated by $PROGNAME. Do not edit !" > $config_mk
+}
+
+add_config ()
+{
+    echo "$1" >> $config_mk
+}
+
+echo "Detecting host toolchain."
+echo ""
+
+force_32bit_binaries
+setup_toolchain
+
+create_config_mk
+
+add_config "HOST_OS       := $HOST_OS"
+add_config "HOST_ARCH     := $HOST_ARCH"
+add_config "HOST_TAG      := $HOST_TAG"
+add_config "HOST_CC       := $CC"
+add_config "HOST_CFLAGS   := $CFLAGS"
+add_config "HOST_CXX      := $CXX"
+add_config "HOST_CXXFLAGS := $CXXFLAGS"
+add_config "HOST_LD       := $LD"
+add_config "HOST_LDFLAGS  := $LDFLAGS"
+add_config "HOST_AR       := $AR"
+add_config "HOST_ARFLAGS  := $ARFLAGS"
+
+## Check that the toolchains we need are installed
+## Otherwise, instruct the user to download them from the web site
+
+TOOLCHAINS=arm-eabi-4.2.1
+
+EXT=""
+[ "Windows_NT" == "$OS" ] && EXT=".exe"
+
+for tc in $TOOLCHAINS; do
+    echo "Toolchain  : Checking for $tc prebuilt binaries"
+    COMPILER_PATTERN=$ANDROID_NDK_ROOT/build/prebuilt/$HOST_TAG/$tc/bin/*-gcc${EXT}
+    COMPILERS=`ls $COMPILER_PATTERN 2> /dev/null`
+    if [ -z $COMPILERS ] ; then
+        echo ""
+        echo "ERROR:"
+        echo "It seems you do not have the correct $tc toolchain binaries."
+        echo "Please go to the official Android NDK web site and download the"
+        echo "appropriate NDK package for your platform ($HOST_TAG)."
+        echo "See http://developer.android.com/sdk/index.html"
+        echo ""
+        echo "ABORTING."
+        echo ""
+        exit 1
+    fi
+done
+
+echo ""
+echo "Host setup complete. Please read docs/OVERVIEW.TXT if you don't know what to do."
+echo ""
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/alloca.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/alloca.h
new file mode 120000
index 0000000..ac859df
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/alloca.h
@@ -0,0 +1 @@
+../../../common/include/alloca.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/android/log.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/android/log.h
new file mode 120000
index 0000000..da91a66
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/android/log.h
@@ -0,0 +1 @@
+../../../../common/include/android/log.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/arm/fenv.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/arm/fenv.h
new file mode 100644
index 0000000..e7a8860
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/arm/fenv.h
@@ -0,0 +1,217 @@
+/*-
+ * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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.
+ *
+ * $FreeBSD: src/lib/msun/arm/fenv.h,v 1.5 2005/03/16 19:03:45 das Exp $
+ */
+
+#ifndef	_FENV_H_
+#define	_FENV_H_
+
+#include <sys/_types.h>
+
+typedef	__uint32_t	fenv_t;
+typedef	__uint32_t	fexcept_t;
+
+/* Exception flags */
+#define	FE_INVALID	0x0001
+#define	FE_DIVBYZERO	0x0002
+#define	FE_OVERFLOW	0x0004
+#define	FE_UNDERFLOW	0x0008
+#define	FE_INEXACT	0x0010
+#define	FE_ALL_EXCEPT	(FE_DIVBYZERO | FE_INEXACT | \
+			 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
+
+/* Rounding modes */
+#define	FE_TONEAREST	0x0000
+#define	FE_TOWARDZERO	0x0001
+#define	FE_UPWARD	0x0002
+#define	FE_DOWNWARD	0x0003
+#define	_ROUND_MASK	(FE_TONEAREST | FE_DOWNWARD | \
+			 FE_UPWARD | FE_TOWARDZERO)
+__BEGIN_DECLS
+
+/* Default floating-point environment */
+extern const fenv_t	__fe_dfl_env;
+#define	FE_DFL_ENV	(&__fe_dfl_env)
+
+/* We need to be able to map status flag positions to mask flag positions */
+#define _FPUSW_SHIFT	16
+#define	_ENABLE_MASK	(FE_ALL_EXCEPT << _FPUSW_SHIFT)
+
+#ifdef	ARM_HARD_FLOAT
+#define	__rfs(__fpsr)	__asm __volatile("rfs %0" : "=r" (*(__fpsr)))
+#define	__wfs(__fpsr)	__asm __volatile("wfs %0" : : "r" (__fpsr))
+#else
+#define __rfs(__fpsr)
+#define __wfs(__fpsr)
+#endif
+
+static __inline int
+feclearexcept(int __excepts)
+{
+	fexcept_t __fpsr;
+
+	__rfs(&__fpsr);
+	__fpsr &= ~__excepts;
+	__wfs(__fpsr);
+	return (0);
+}
+
+static __inline int
+fegetexceptflag(fexcept_t *__flagp, int __excepts)
+{
+	fexcept_t __fpsr;
+
+	__rfs(&__fpsr);
+	*__flagp = __fpsr & __excepts;
+	return (0);
+}
+
+static __inline int
+fesetexceptflag(const fexcept_t *__flagp, int __excepts)
+{
+	fexcept_t __fpsr;
+
+	__rfs(&__fpsr);
+	__fpsr &= ~__excepts;
+	__fpsr |= *__flagp & __excepts;
+	__wfs(__fpsr);
+	return (0);
+}
+
+static __inline int
+feraiseexcept(int __excepts)
+{
+	fexcept_t __ex = __excepts;
+
+	fesetexceptflag(&__ex, __excepts);	/* XXX */
+	return (0);
+}
+
+static __inline int
+fetestexcept(int __excepts)
+{
+	fexcept_t __fpsr;
+
+	__rfs(&__fpsr);
+	return (__fpsr & __excepts);
+}
+
+static __inline int
+fegetround(void)
+{
+
+	/*
+	 * Apparently, the rounding mode is specified as part of the
+	 * instruction format on ARM, so the dynamic rounding mode is
+	 * indeterminate.  Some FPUs may differ.
+	 */
+	return (-1);
+}
+
+static __inline int
+fesetround(int __round)
+{
+
+	return (-1);
+}
+
+static __inline int
+fegetenv(fenv_t *__envp)
+{
+
+	__rfs(__envp);
+	return (0);
+}
+
+static __inline int
+feholdexcept(fenv_t *__envp)
+{
+	fenv_t __env;
+
+	__rfs(&__env);
+	*__envp = __env;
+	__env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
+	__wfs(__env);
+	return (0);
+}
+
+static __inline int
+fesetenv(const fenv_t *__envp)
+{
+
+	__wfs(*__envp);
+	return (0);
+}
+
+static __inline int
+feupdateenv(const fenv_t *__envp)
+{
+	fexcept_t __fpsr;
+
+	__rfs(&__fpsr);
+	__wfs(*__envp);
+	feraiseexcept(__fpsr & FE_ALL_EXCEPT);
+	return (0);
+}
+
+#if __BSD_VISIBLE
+
+static __inline int
+feenableexcept(int __mask)
+{
+	fenv_t __old_fpsr, __new_fpsr;
+
+	__rfs(&__old_fpsr);
+	__new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT;
+	__wfs(__new_fpsr);
+	return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+}
+
+static __inline int
+fedisableexcept(int __mask)
+{
+	fenv_t __old_fpsr, __new_fpsr;
+
+	__rfs(&__old_fpsr);
+	__new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
+	__wfs(__new_fpsr);
+	return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+}
+
+static __inline int
+fegetexcept(void)
+{
+	fenv_t __fpsr;
+
+	__rfs(&__fpsr);
+	return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT);
+}
+
+#endif /* __BSD_VISIBLE */
+
+__END_DECLS
+
+#endif	/* !_FENV_H_ */
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/arpa/inet.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/arpa/inet.h
new file mode 120000
index 0000000..760a19d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/arpa/inet.h
@@ -0,0 +1 @@
+../../../../common/include/arpa/inet.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/arpa/nameser.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/arpa/nameser.h
new file mode 120000
index 0000000..73f9311
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/arpa/nameser.h
@@ -0,0 +1 @@
+../../../../common/include/arpa/nameser.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/4level-fixup.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/4level-fixup.h
new file mode 120000
index 0000000..4493a92
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/4level-fixup.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/4level-fixup.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/audit_dir_write.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/audit_dir_write.h
new file mode 120000
index 0000000..6576f52
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/audit_dir_write.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/audit_dir_write.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/__ffs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/__ffs.h
new file mode 120000
index 0000000..9a68edc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/__ffs.h
@@ -0,0 +1 @@
+../../../../../common/include/asm-generic/bitops/__ffs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/atomic.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/atomic.h
new file mode 120000
index 0000000..32afeb4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/atomic.h
@@ -0,0 +1 @@
+../../../../../common/include/asm-generic/bitops/atomic.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/ffz.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/ffz.h
new file mode 120000
index 0000000..50c5214
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/ffz.h
@@ -0,0 +1 @@
+../../../../../common/include/asm-generic/bitops/ffz.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/find.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/find.h
new file mode 120000
index 0000000..9b40acd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/find.h
@@ -0,0 +1 @@
+../../../../../common/include/asm-generic/bitops/find.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/fls.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/fls.h
new file mode 120000
index 0000000..5171887
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/fls.h
@@ -0,0 +1 @@
+../../../../../common/include/asm-generic/bitops/fls.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/fls64.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/fls64.h
new file mode 120000
index 0000000..8728e6a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/fls64.h
@@ -0,0 +1 @@
+../../../../../common/include/asm-generic/bitops/fls64.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/le.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/le.h
new file mode 120000
index 0000000..91b46c7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/le.h
@@ -0,0 +1 @@
+../../../../../common/include/asm-generic/bitops/le.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/non-atomic.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/non-atomic.h
new file mode 120000
index 0000000..177973e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bitops/non-atomic.h
@@ -0,0 +1 @@
+../../../../../common/include/asm-generic/bitops/non-atomic.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bug.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bug.h
new file mode 120000
index 0000000..d898f3a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/bug.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/bug.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/cputime.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/cputime.h
new file mode 120000
index 0000000..7892fb4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/cputime.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/cputime.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/emergency-restart.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/emergency-restart.h
new file mode 120000
index 0000000..3005c74
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/emergency-restart.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/emergency-restart.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/errno-base.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/errno-base.h
new file mode 120000
index 0000000..7b7d9bd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/errno-base.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/errno-base.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/errno.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/errno.h
new file mode 120000
index 0000000..bdd6dd4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/errno.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/errno.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/fcntl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/fcntl.h
new file mode 120000
index 0000000..3506aa8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/fcntl.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/fcntl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/futex.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/futex.h
new file mode 120000
index 0000000..cbd47bf
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/futex.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/futex.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/ioctl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/ioctl.h
new file mode 120000
index 0000000..7a11623
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/ioctl.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/ioctl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/ipc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/ipc.h
new file mode 120000
index 0000000..339894e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/ipc.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/ipc.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/local.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/local.h
new file mode 120000
index 0000000..0e9344d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/local.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/local.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/memory_model.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/memory_model.h
new file mode 120000
index 0000000..3bbc82b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/memory_model.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/memory_model.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/mman.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/mman.h
new file mode 120000
index 0000000..fbab125
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/mman.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/mman.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/mutex-xchg.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/mutex-xchg.h
new file mode 120000
index 0000000..c7bc238
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/mutex-xchg.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/mutex-xchg.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/percpu.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/percpu.h
new file mode 120000
index 0000000..2d899db
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/percpu.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/percpu.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/pgtable-nopud.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/pgtable-nopud.h
new file mode 120000
index 0000000..ac2157e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/pgtable-nopud.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/pgtable-nopud.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/pgtable.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/pgtable.h
new file mode 120000
index 0000000..4c70646
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/pgtable.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/pgtable.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/poll.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/poll.h
new file mode 120000
index 0000000..2bd359a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/poll.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/poll.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/resource.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/resource.h
new file mode 120000
index 0000000..28f331a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/resource.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/resource.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/sections.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/sections.h
new file mode 120000
index 0000000..c6885f3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/sections.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/sections.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/siginfo.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/siginfo.h
new file mode 120000
index 0000000..d38f211
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/siginfo.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/siginfo.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/signal.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/signal.h
new file mode 120000
index 0000000..05ca352
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/signal.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/signal.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/tlb.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/tlb.h
new file mode 120000
index 0000000..94baa95
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/tlb.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/tlb.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/topology.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/topology.h
new file mode 120000
index 0000000..e85b48f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/topology.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/topology.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/xor.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/xor.h
new file mode 120000
index 0000000..baf2118
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm-generic/xor.h
@@ -0,0 +1 @@
+../../../../common/include/asm-generic/xor.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/a.out.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/a.out.h
new file mode 100644
index 0000000..e8f17dc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/a.out.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ARM_A_OUT_H__
+#define __ARM_A_OUT_H__
+
+#include <linux/personality.h>
+#include <asm/types.h>
+
+struct exec
+{
+ __u32 a_info;
+ __u32 a_text;
+ __u32 a_data;
+ __u32 a_bss;
+ __u32 a_syms;
+ __u32 a_entry;
+ __u32 a_trsize;
+ __u32 a_drsize;
+};
+
+#define N_TXTADDR(a) (0x00008000)
+
+#define N_TRSIZE(a) ((a).a_trsize)
+#define N_DRSIZE(a) ((a).a_drsize)
+#define N_SYMSIZE(a) ((a).a_syms)
+
+#define M_ARM 103
+
+#ifndef LIBRARY_START_TEXT
+#define LIBRARY_START_TEXT (0x00c00000)
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/board-perseus2.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/board-perseus2.h
new file mode 100644
index 0000000..c6c5413
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/board-perseus2.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARCH_OMAP_PERSEUS2_H
+#define __ASM_ARCH_OMAP_PERSEUS2_H
+
+#include <asm/arch/fpga.h>
+
+#ifndef OMAP_SDRAM_DEVICE
+#define OMAP_SDRAM_DEVICE D256M_1X16_4B
+#endif
+
+#define MAXIRQNUM IH_BOARD_BASE
+#define MAXFIQNUM MAXIRQNUM
+#define MAXSWINUM MAXIRQNUM
+
+#define NR_IRQS (MAXIRQNUM + 1)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/board.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/board.h
new file mode 100644
index 0000000..a7a4c66
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/board.h
@@ -0,0 +1,163 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _OMAP_BOARD_H
+#define _OMAP_BOARD_H
+
+#include <linux/types.h>
+
+#include <asm/arch/gpio-switch.h>
+
+#define OMAP_TAG_CLOCK 0x4f01
+#define OMAP_TAG_MMC 0x4f02
+#define OMAP_TAG_SERIAL_CONSOLE 0x4f03
+#define OMAP_TAG_USB 0x4f04
+#define OMAP_TAG_LCD 0x4f05
+#define OMAP_TAG_GPIO_SWITCH 0x4f06
+#define OMAP_TAG_UART 0x4f07
+#define OMAP_TAG_FBMEM 0x4f08
+#define OMAP_TAG_STI_CONSOLE 0x4f09
+#define OMAP_TAG_CAMERA_SENSOR 0x4f0a
+#define OMAP_TAG_BT 0x4f0b
+
+#define OMAP_TAG_BOOT_REASON 0x4f80
+#define OMAP_TAG_FLASH_PART 0x4f81
+#define OMAP_TAG_VERSION_STR 0x4f82
+
+struct omap_clock_config {
+
+ u8 system_clock_type;
+};
+
+struct omap_mmc_conf {
+ unsigned enabled:1;
+
+ unsigned nomux:1;
+
+ unsigned cover:1;
+
+ unsigned wire4:1;
+ s16 power_pin;
+ s16 switch_pin;
+ s16 wp_pin;
+};
+
+struct omap_mmc_config {
+ struct omap_mmc_conf mmc[2];
+};
+
+struct omap_serial_console_config {
+ u8 console_uart;
+ u32 console_speed;
+};
+
+struct omap_sti_console_config {
+ unsigned enable:1;
+ u8 channel;
+};
+
+struct omap_camera_sensor_config {
+ u16 reset_gpio;
+ int (*power_on)(void * data);
+ int (*power_off)(void * data);
+};
+
+struct omap_usb_config {
+
+ unsigned register_host:1;
+ unsigned register_dev:1;
+ u8 otg;
+
+ u8 hmc_mode;
+
+ u8 rwc;
+
+ u8 pins[3];
+};
+
+struct omap_lcd_config {
+ char panel_name[16];
+ char ctrl_name[16];
+ s16 nreset_gpio;
+ u8 data_lines;
+};
+
+struct device;
+struct fb_info;
+struct omap_backlight_config {
+ int default_intensity;
+ int (*set_power)(struct device *dev, int state);
+ int (*check_fb)(struct fb_info *fb);
+};
+
+struct omap_fbmem_config {
+ u32 start;
+ u32 size;
+};
+
+struct omap_pwm_led_platform_data {
+ const char *name;
+ int intensity_timer;
+ int blink_timer;
+ void (*set_power)(struct omap_pwm_led_platform_data *self, int on_off);
+};
+
+struct omap_gpio_switch_config {
+ char name[12];
+ u16 gpio;
+ int flags:4;
+ int type:4;
+ int key_code:24;
+};
+
+struct omap_uart_config {
+
+ unsigned int enabled_uarts;
+};
+
+struct omap_flash_part_config {
+ char part_table[0];
+};
+
+struct omap_boot_reason_config {
+ char reason_str[12];
+};
+
+struct omap_version_config {
+ char component[12];
+ char version[12];
+};
+
+struct omap_board_config_entry {
+ u16 tag;
+ u16 len;
+ u8 data[0];
+};
+
+struct omap_board_config_kernel {
+ u16 tag;
+ const void *data;
+};
+
+struct omap_bluetooth_config {
+ u8 chip_type;
+ u8 bt_uart;
+ u8 bd_addr[6];
+ u8 bt_sysclk;
+ int bt_wakeup_gpio;
+ int host_wakeup_gpio;
+ int reset_gpio;
+};
+
+#define omap_get_config(tag, type)   ((const type *) __omap_get_config((tag), sizeof(type), 0))
+#define omap_get_nr_config(tag, type, nr)   ((const type *) __omap_get_config((tag), sizeof(type), (nr)))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/cpu.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/cpu.h
new file mode 100644
index 0000000..fa7a408
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/cpu.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARCH_OMAP_CPU_H
+#define __ASM_ARCH_OMAP_CPU_H
+
+#define omap2_cpu_rev() ((system_rev >> 8) & 0x0f)
+
+#undef MULTI_OMAP1
+#undef MULTI_OMAP2
+#undef OMAP_NAME
+
+#define GET_OMAP_CLASS (system_rev & 0xff)
+
+#define IS_OMAP_CLASS(class, id)  static inline int is_omap ##class (void)  {   return (GET_OMAP_CLASS == (id)) ? 1 : 0;  }
+
+#define GET_OMAP_SUBCLASS ((system_rev >> 20) & 0x0fff)
+
+#define IS_OMAP_SUBCLASS(subclass, id)  static inline int is_omap ##subclass (void)  {   return (GET_OMAP_SUBCLASS == (id)) ? 1 : 0;  }
+
+#define cpu_is_omap7xx() 0
+#define cpu_is_omap15xx() 0
+#define cpu_is_omap16xx() 0
+#define cpu_is_omap24xx() 0
+#define cpu_is_omap242x() 0
+#define cpu_is_omap243x() 0
+#ifdef MULTI_OMAP1
+#else
+#endif
+#define GET_OMAP_TYPE ((system_rev >> 16) & 0xffff)
+#define IS_OMAP_TYPE(type, id)  static inline int is_omap ##type (void)  {   return (GET_OMAP_TYPE == (id)) ? 1 : 0;  }
+#define cpu_is_omap310() 0
+#define cpu_is_omap730() 0
+#define cpu_is_omap1510() 0
+#define cpu_is_omap1610() 0
+#define cpu_is_omap5912() 0
+#define cpu_is_omap1611() 0
+#define cpu_is_omap1621() 0
+#define cpu_is_omap1710() 0
+#define cpu_is_omap2420() 0
+#define cpu_is_omap2422() 0
+#define cpu_is_omap2423() 0
+#define cpu_is_omap2430() 0
+#ifdef MULTI_OMAP1
+#else
+#endif
+#define cpu_class_is_omap1() (cpu_is_omap730() || cpu_is_omap15xx() ||   cpu_is_omap16xx())
+#define cpu_class_is_omap2() cpu_is_omap24xx()
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/dma.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/dma.h
new file mode 100644
index 0000000..5e5be76
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/dma.h
@@ -0,0 +1,318 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARCH_DMA_H
+#define __ASM_ARCH_DMA_H
+
+#define OMAP_DMA_BASE (0xfffed800)
+#define OMAP_DMA_GCR (OMAP_DMA_BASE + 0x400)
+#define OMAP_DMA_GSCR (OMAP_DMA_BASE + 0x404)
+#define OMAP_DMA_GRST (OMAP_DMA_BASE + 0x408)
+#define OMAP_DMA_HW_ID (OMAP_DMA_BASE + 0x442)
+#define OMAP_DMA_PCH2_ID (OMAP_DMA_BASE + 0x444)
+#define OMAP_DMA_PCH0_ID (OMAP_DMA_BASE + 0x446)
+#define OMAP_DMA_PCH1_ID (OMAP_DMA_BASE + 0x448)
+#define OMAP_DMA_PCHG_ID (OMAP_DMA_BASE + 0x44a)
+#define OMAP_DMA_PCHD_ID (OMAP_DMA_BASE + 0x44c)
+#define OMAP_DMA_CAPS_0_U (OMAP_DMA_BASE + 0x44e)
+#define OMAP_DMA_CAPS_0_L (OMAP_DMA_BASE + 0x450)
+#define OMAP_DMA_CAPS_1_U (OMAP_DMA_BASE + 0x452)
+#define OMAP_DMA_CAPS_1_L (OMAP_DMA_BASE + 0x454)
+#define OMAP_DMA_CAPS_2 (OMAP_DMA_BASE + 0x456)
+#define OMAP_DMA_CAPS_3 (OMAP_DMA_BASE + 0x458)
+#define OMAP_DMA_CAPS_4 (OMAP_DMA_BASE + 0x45a)
+#define OMAP_DMA_PCH2_SR (OMAP_DMA_BASE + 0x460)
+#define OMAP_DMA_PCH0_SR (OMAP_DMA_BASE + 0x480)
+#define OMAP_DMA_PCH1_SR (OMAP_DMA_BASE + 0x482)
+#define OMAP_DMA_PCHD_SR (OMAP_DMA_BASE + 0x4c0)
+
+#define OMAP24XX_DMA_BASE (L4_24XX_BASE + 0x56000)
+#define OMAP_DMA4_REVISION (OMAP24XX_DMA_BASE + 0x00)
+#define OMAP_DMA4_GCR_REG (OMAP24XX_DMA_BASE + 0x78)
+#define OMAP_DMA4_IRQSTATUS_L0 (OMAP24XX_DMA_BASE + 0x08)
+#define OMAP_DMA4_IRQSTATUS_L1 (OMAP24XX_DMA_BASE + 0x0c)
+#define OMAP_DMA4_IRQSTATUS_L2 (OMAP24XX_DMA_BASE + 0x10)
+#define OMAP_DMA4_IRQSTATUS_L3 (OMAP24XX_DMA_BASE + 0x14)
+#define OMAP_DMA4_IRQENABLE_L0 (OMAP24XX_DMA_BASE + 0x18)
+#define OMAP_DMA4_IRQENABLE_L1 (OMAP24XX_DMA_BASE + 0x1c)
+#define OMAP_DMA4_IRQENABLE_L2 (OMAP24XX_DMA_BASE + 0x20)
+#define OMAP_DMA4_IRQENABLE_L3 (OMAP24XX_DMA_BASE + 0x24)
+#define OMAP_DMA4_SYSSTATUS (OMAP24XX_DMA_BASE + 0x28)
+#define OMAP_DMA4_CAPS_0 (OMAP24XX_DMA_BASE + 0x64)
+#define OMAP_DMA4_CAPS_2 (OMAP24XX_DMA_BASE + 0x6c)
+#define OMAP_DMA4_CAPS_3 (OMAP24XX_DMA_BASE + 0x70)
+#define OMAP_DMA4_CAPS_4 (OMAP24XX_DMA_BASE + 0x74)
+
+#define OMAP_LOGICAL_DMA_CH_COUNT 32  
+
+#define OMAP_DMA_CCR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x80)
+#define OMAP_DMA_CLNK_CTRL_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x84)
+#define OMAP_DMA_CICR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x88)
+#define OMAP_DMA_CSR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x8c)
+#define OMAP_DMA_CSDP_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x90)
+#define OMAP_DMA_CEN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x94)
+#define OMAP_DMA_CFN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x98)
+#define OMAP_DMA_CSEI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xa4)
+#define OMAP_DMA_CSFI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xa8)
+#define OMAP_DMA_CDEI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xac)
+#define OMAP_DMA_CDFI_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xb0)
+#define OMAP_DMA_CSAC_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xb4)
+#define OMAP_DMA_CDAC_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xb8)
+
+#define OMAP1_DMA_CSSA_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x08)
+#define OMAP1_DMA_CSSA_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0a)
+#define OMAP1_DMA_CDSA_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0c)
+#define OMAP1_DMA_CDSA_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x0e)
+#define OMAP1_DMA_COLOR_L_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x20)
+#define OMAP1_DMA_CCR2_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x24)
+#define OMAP1_DMA_COLOR_U_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x22)
+#define OMAP1_DMA_LCH_CTRL_REG(n) __REG16(OMAP_DMA_BASE + 0x40 * (n) + 0x2a)
+
+#define OMAP2_DMA_CSSA_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0x9c)
+#define OMAP2_DMA_CDSA_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xa0)
+#define OMAP2_DMA_CCEN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xbc)
+#define OMAP2_DMA_CCFN_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xc0)
+#define OMAP2_DMA_COLOR_REG(n) __REG32(OMAP24XX_DMA_BASE + 0x60 * (n) + 0xc4)
+
+#define OMAP_DMA_NO_DEVICE 0
+#define OMAP_DMA_MCSI1_TX 1
+#define OMAP_DMA_MCSI1_RX 2
+#define OMAP_DMA_I2C_RX 3
+#define OMAP_DMA_I2C_TX 4
+#define OMAP_DMA_EXT_NDMA_REQ 5
+#define OMAP_DMA_EXT_NDMA_REQ2 6
+#define OMAP_DMA_UWIRE_TX 7
+#define OMAP_DMA_MCBSP1_TX 8
+#define OMAP_DMA_MCBSP1_RX 9
+#define OMAP_DMA_MCBSP3_TX 10
+#define OMAP_DMA_MCBSP3_RX 11
+#define OMAP_DMA_UART1_TX 12
+#define OMAP_DMA_UART1_RX 13
+#define OMAP_DMA_UART2_TX 14
+#define OMAP_DMA_UART2_RX 15
+#define OMAP_DMA_MCBSP2_TX 16
+#define OMAP_DMA_MCBSP2_RX 17
+#define OMAP_DMA_UART3_TX 18
+#define OMAP_DMA_UART3_RX 19
+#define OMAP_DMA_CAMERA_IF_RX 20
+#define OMAP_DMA_MMC_TX 21
+#define OMAP_DMA_MMC_RX 22
+#define OMAP_DMA_NAND 23
+#define OMAP_DMA_IRQ_LCD_LINE 24
+#define OMAP_DMA_MEMORY_STICK 25
+#define OMAP_DMA_USB_W2FC_RX0 26
+#define OMAP_DMA_USB_W2FC_RX1 27
+#define OMAP_DMA_USB_W2FC_RX2 28
+#define OMAP_DMA_USB_W2FC_TX0 29
+#define OMAP_DMA_USB_W2FC_TX1 30
+#define OMAP_DMA_USB_W2FC_TX2 31
+
+#define OMAP_DMA_CRYPTO_DES_IN 32
+#define OMAP_DMA_SPI_TX 33
+#define OMAP_DMA_SPI_RX 34
+#define OMAP_DMA_CRYPTO_HASH 35
+#define OMAP_DMA_CCP_ATTN 36
+#define OMAP_DMA_CCP_FIFO_NOT_EMPTY 37
+#define OMAP_DMA_CMT_APE_TX_CHAN_0 38
+#define OMAP_DMA_CMT_APE_RV_CHAN_0 39
+#define OMAP_DMA_CMT_APE_TX_CHAN_1 40
+#define OMAP_DMA_CMT_APE_RV_CHAN_1 41
+#define OMAP_DMA_CMT_APE_TX_CHAN_2 42
+#define OMAP_DMA_CMT_APE_RV_CHAN_2 43
+#define OMAP_DMA_CMT_APE_TX_CHAN_3 44
+#define OMAP_DMA_CMT_APE_RV_CHAN_3 45
+#define OMAP_DMA_CMT_APE_TX_CHAN_4 46
+#define OMAP_DMA_CMT_APE_RV_CHAN_4 47
+#define OMAP_DMA_CMT_APE_TX_CHAN_5 48
+#define OMAP_DMA_CMT_APE_RV_CHAN_5 49
+#define OMAP_DMA_CMT_APE_TX_CHAN_6 50
+#define OMAP_DMA_CMT_APE_RV_CHAN_6 51
+#define OMAP_DMA_CMT_APE_TX_CHAN_7 52
+#define OMAP_DMA_CMT_APE_RV_CHAN_7 53
+#define OMAP_DMA_MMC2_TX 54
+#define OMAP_DMA_MMC2_RX 55
+#define OMAP_DMA_CRYPTO_DES_OUT 56
+
+#define OMAP24XX_DMA_NO_DEVICE 0
+#define OMAP24XX_DMA_XTI_DMA 1  
+#define OMAP24XX_DMA_EXT_DMAREQ0 2  
+#define OMAP24XX_DMA_EXT_DMAREQ1 3  
+#define OMAP24XX_DMA_GPMC 4  
+#define OMAP24XX_DMA_GFX 5  
+#define OMAP24XX_DMA_DSS 6  
+#define OMAP24XX_DMA_VLYNQ_TX 7  
+#define OMAP24XX_DMA_CWT 8  
+#define OMAP24XX_DMA_AES_TX 9  
+#define OMAP24XX_DMA_AES_RX 10  
+#define OMAP24XX_DMA_DES_TX 11  
+#define OMAP24XX_DMA_DES_RX 12  
+#define OMAP24XX_DMA_SHA1MD5_RX 13  
+#define OMAP24XX_DMA_EXT_DMAREQ2 14  
+#define OMAP24XX_DMA_EXT_DMAREQ3 15  
+#define OMAP24XX_DMA_EXT_DMAREQ4 16  
+#define OMAP24XX_DMA_EAC_AC_RD 17  
+#define OMAP24XX_DMA_EAC_AC_WR 18  
+#define OMAP24XX_DMA_EAC_MD_UL_RD 19  
+#define OMAP24XX_DMA_EAC_MD_UL_WR 20  
+#define OMAP24XX_DMA_EAC_MD_DL_RD 21  
+#define OMAP24XX_DMA_EAC_MD_DL_WR 22  
+#define OMAP24XX_DMA_EAC_BT_UL_RD 23  
+#define OMAP24XX_DMA_EAC_BT_UL_WR 24  
+#define OMAP24XX_DMA_EAC_BT_DL_RD 25  
+#define OMAP24XX_DMA_EAC_BT_DL_WR 26  
+#define OMAP24XX_DMA_I2C1_TX 27  
+#define OMAP24XX_DMA_I2C1_RX 28  
+#define OMAP24XX_DMA_I2C2_TX 29  
+#define OMAP24XX_DMA_I2C2_RX 30  
+#define OMAP24XX_DMA_MCBSP1_TX 31  
+#define OMAP24XX_DMA_MCBSP1_RX 32  
+#define OMAP24XX_DMA_MCBSP2_TX 33  
+#define OMAP24XX_DMA_MCBSP2_RX 34  
+#define OMAP24XX_DMA_SPI1_TX0 35  
+#define OMAP24XX_DMA_SPI1_RX0 36  
+#define OMAP24XX_DMA_SPI1_TX1 37  
+#define OMAP24XX_DMA_SPI1_RX1 38  
+#define OMAP24XX_DMA_SPI1_TX2 39  
+#define OMAP24XX_DMA_SPI1_RX2 40  
+#define OMAP24XX_DMA_SPI1_TX3 41  
+#define OMAP24XX_DMA_SPI1_RX3 42  
+#define OMAP24XX_DMA_SPI2_TX0 43  
+#define OMAP24XX_DMA_SPI2_RX0 44  
+#define OMAP24XX_DMA_SPI2_TX1 45  
+#define OMAP24XX_DMA_SPI2_RX1 46  
+
+#define OMAP24XX_DMA_UART1_TX 49  
+#define OMAP24XX_DMA_UART1_RX 50  
+#define OMAP24XX_DMA_UART2_TX 51  
+#define OMAP24XX_DMA_UART2_RX 52  
+#define OMAP24XX_DMA_UART3_TX 53  
+#define OMAP24XX_DMA_UART3_RX 54  
+#define OMAP24XX_DMA_USB_W2FC_TX0 55  
+#define OMAP24XX_DMA_USB_W2FC_RX0 56  
+#define OMAP24XX_DMA_USB_W2FC_TX1 57  
+#define OMAP24XX_DMA_USB_W2FC_RX1 58  
+#define OMAP24XX_DMA_USB_W2FC_TX2 59  
+#define OMAP24XX_DMA_USB_W2FC_RX2 60  
+#define OMAP24XX_DMA_MMC1_TX 61  
+#define OMAP24XX_DMA_MMC1_RX 62  
+#define OMAP24XX_DMA_MS 63  
+#define OMAP24XX_DMA_EXT_DMAREQ5 64  
+
+#define OMAP1510_DMA_LCD_BASE (0xfffedb00)
+#define OMAP1510_DMA_LCD_CTRL (OMAP1510_DMA_LCD_BASE + 0x00)
+#define OMAP1510_DMA_LCD_TOP_F1_L (OMAP1510_DMA_LCD_BASE + 0x02)
+#define OMAP1510_DMA_LCD_TOP_F1_U (OMAP1510_DMA_LCD_BASE + 0x04)
+#define OMAP1510_DMA_LCD_BOT_F1_L (OMAP1510_DMA_LCD_BASE + 0x06)
+#define OMAP1510_DMA_LCD_BOT_F1_U (OMAP1510_DMA_LCD_BASE + 0x08)
+
+#define OMAP1610_DMA_LCD_BASE (0xfffee300)
+#define OMAP1610_DMA_LCD_CSDP (OMAP1610_DMA_LCD_BASE + 0xc0)
+#define OMAP1610_DMA_LCD_CCR (OMAP1610_DMA_LCD_BASE + 0xc2)
+#define OMAP1610_DMA_LCD_CTRL (OMAP1610_DMA_LCD_BASE + 0xc4)
+#define OMAP1610_DMA_LCD_TOP_B1_L (OMAP1610_DMA_LCD_BASE + 0xc8)
+#define OMAP1610_DMA_LCD_TOP_B1_U (OMAP1610_DMA_LCD_BASE + 0xca)
+#define OMAP1610_DMA_LCD_BOT_B1_L (OMAP1610_DMA_LCD_BASE + 0xcc)
+#define OMAP1610_DMA_LCD_BOT_B1_U (OMAP1610_DMA_LCD_BASE + 0xce)
+#define OMAP1610_DMA_LCD_TOP_B2_L (OMAP1610_DMA_LCD_BASE + 0xd0)
+#define OMAP1610_DMA_LCD_TOP_B2_U (OMAP1610_DMA_LCD_BASE + 0xd2)
+#define OMAP1610_DMA_LCD_BOT_B2_L (OMAP1610_DMA_LCD_BASE + 0xd4)
+#define OMAP1610_DMA_LCD_BOT_B2_U (OMAP1610_DMA_LCD_BASE + 0xd6)
+#define OMAP1610_DMA_LCD_SRC_EI_B1 (OMAP1610_DMA_LCD_BASE + 0xd8)
+#define OMAP1610_DMA_LCD_SRC_FI_B1_L (OMAP1610_DMA_LCD_BASE + 0xda)
+#define OMAP1610_DMA_LCD_SRC_EN_B1 (OMAP1610_DMA_LCD_BASE + 0xe0)
+#define OMAP1610_DMA_LCD_SRC_FN_B1 (OMAP1610_DMA_LCD_BASE + 0xe4)
+#define OMAP1610_DMA_LCD_LCH_CTRL (OMAP1610_DMA_LCD_BASE + 0xea)
+#define OMAP1610_DMA_LCD_SRC_FI_B1_U (OMAP1610_DMA_LCD_BASE + 0xf4)
+
+#define OMAP1_DMA_TOUT_IRQ (1 << 0)
+#define OMAP_DMA_DROP_IRQ (1 << 1)
+#define OMAP_DMA_HALF_IRQ (1 << 2)
+#define OMAP_DMA_FRAME_IRQ (1 << 3)
+#define OMAP_DMA_LAST_IRQ (1 << 4)
+#define OMAP_DMA_BLOCK_IRQ (1 << 5)
+#define OMAP1_DMA_SYNC_IRQ (1 << 6)
+#define OMAP2_DMA_PKT_IRQ (1 << 7)
+#define OMAP2_DMA_TRANS_ERR_IRQ (1 << 8)
+#define OMAP2_DMA_SECURE_ERR_IRQ (1 << 9)
+#define OMAP2_DMA_SUPERVISOR_ERR_IRQ (1 << 10)
+#define OMAP2_DMA_MISALIGNED_ERR_IRQ (1 << 11)
+
+#define OMAP_DMA_DATA_TYPE_S8 0x00
+#define OMAP_DMA_DATA_TYPE_S16 0x01
+#define OMAP_DMA_DATA_TYPE_S32 0x02
+
+#define OMAP_DMA_SYNC_ELEMENT 0x00
+#define OMAP_DMA_SYNC_FRAME 0x01
+#define OMAP_DMA_SYNC_BLOCK 0x02
+
+#define OMAP_DMA_PORT_EMIFF 0x00
+#define OMAP_DMA_PORT_EMIFS 0x01
+#define OMAP_DMA_PORT_OCP_T1 0x02
+#define OMAP_DMA_PORT_TIPB 0x03
+#define OMAP_DMA_PORT_OCP_T2 0x04
+#define OMAP_DMA_PORT_MPUI 0x05
+
+#define OMAP_DMA_AMODE_CONSTANT 0x00
+#define OMAP_DMA_AMODE_POST_INC 0x01
+#define OMAP_DMA_AMODE_SINGLE_IDX 0x02
+#define OMAP_DMA_AMODE_DOUBLE_IDX 0x03
+
+enum {
+ OMAP_LCD_DMA_B1_TOP,
+ OMAP_LCD_DMA_B1_BOTTOM,
+ OMAP_LCD_DMA_B2_TOP,
+ OMAP_LCD_DMA_B2_BOTTOM
+};
+
+enum omap_dma_burst_mode {
+ OMAP_DMA_DATA_BURST_DIS = 0,
+ OMAP_DMA_DATA_BURST_4,
+ OMAP_DMA_DATA_BURST_8,
+ OMAP_DMA_DATA_BURST_16,
+};
+
+enum omap_dma_color_mode {
+ OMAP_DMA_COLOR_DIS = 0,
+ OMAP_DMA_CONSTANT_FILL,
+ OMAP_DMA_TRANSPARENT_COPY
+};
+
+enum omap_dma_write_mode {
+ OMAP_DMA_WRITE_NON_POSTED = 0,
+ OMAP_DMA_WRITE_POSTED,
+ OMAP_DMA_WRITE_LAST_NON_POSTED
+};
+
+struct omap_dma_channel_params {
+ int data_type;
+ int elem_count;
+ int frame_count;
+
+ int src_port;
+ int src_amode;
+ unsigned long src_start;
+ int src_ei;
+ int src_fi;
+
+ int dst_port;
+ int dst_amode;
+ unsigned long dst_start;
+ int dst_ei;
+ int dst_fi;
+
+ int trigger;
+ int sync_mode;
+ int src_or_dst_synch;
+
+ int ie;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/fpga.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/fpga.h
new file mode 100644
index 0000000..a1b210d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/fpga.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARCH_OMAP_FPGA_H
+#define __ASM_ARCH_OMAP_FPGA_H
+
+#define omap1510_fpga_init_irq() (0)
+
+#define fpga_read(reg) __raw_readb(reg)
+#define fpga_write(val, reg) __raw_writeb(val, reg)
+
+#define H2P2_DBG_FPGA_BASE 0xE8000000  
+#define H2P2_DBG_FPGA_SIZE SZ_4K  
+#define H2P2_DBG_FPGA_START 0x04000000  
+
+#define H2P2_DBG_FPGA_ETHR_START (H2P2_DBG_FPGA_START + 0x300)
+#define H2P2_DBG_FPGA_FPGA_REV (H2P2_DBG_FPGA_BASE + 0x10)  
+#define H2P2_DBG_FPGA_BOARD_REV (H2P2_DBG_FPGA_BASE + 0x12)  
+#define H2P2_DBG_FPGA_GPIO (H2P2_DBG_FPGA_BASE + 0x14)  
+#define H2P2_DBG_FPGA_LEDS (H2P2_DBG_FPGA_BASE + 0x16)  
+#define H2P2_DBG_FPGA_MISC_INPUTS (H2P2_DBG_FPGA_BASE + 0x18)  
+#define H2P2_DBG_FPGA_LAN_STATUS (H2P2_DBG_FPGA_BASE + 0x1A)  
+#define H2P2_DBG_FPGA_LAN_RESET (H2P2_DBG_FPGA_BASE + 0x1C)  
+
+struct h2p2_dbg_fpga {
+
+ u16 smc91x[8];
+
+ u16 fpga_rev;
+ u16 board_rev;
+ u16 gpio_outputs;
+ u16 leds;
+
+ u16 misc_inputs;
+ u16 lan_status;
+ u16 lan_reset;
+ u16 reserved0;
+
+ u16 ps2_data;
+ u16 ps2_ctrl;
+
+};
+
+#define H2P2_DBG_FPGA_LED_GREEN (1 << 15)
+#define H2P2_DBG_FPGA_LED_AMBER (1 << 14)
+#define H2P2_DBG_FPGA_LED_RED (1 << 13)
+#define H2P2_DBG_FPGA_LED_BLUE (1 << 12)
+
+#define H2P2_DBG_FPGA_LOAD_METER (1 << 0) 
+#define H2P2_DBG_FPGA_LOAD_METER_SIZE 11
+#define H2P2_DBG_FPGA_LOAD_METER_MASK ((1 << H2P2_DBG_FPGA_LOAD_METER_SIZE) - 1)
+
+#define H2P2_DBG_FPGA_P2_LED_TIMER (1 << 0)
+#define H2P2_DBG_FPGA_P2_LED_IDLE (1 << 1)
+
+#define OMAP1510_FPGA_BASE 0xE8000000  
+#define OMAP1510_FPGA_SIZE SZ_4K
+#define OMAP1510_FPGA_START 0x08000000  
+
+#define OMAP1510_FPGA_REV_LOW (OMAP1510_FPGA_BASE + 0x0)
+#define OMAP1510_FPGA_REV_HIGH (OMAP1510_FPGA_BASE + 0x1)
+
+#define OMAP1510_FPGA_LCD_PANEL_CONTROL (OMAP1510_FPGA_BASE + 0x2)
+#define OMAP1510_FPGA_LED_DIGIT (OMAP1510_FPGA_BASE + 0x3)
+#define INNOVATOR_FPGA_HID_SPI (OMAP1510_FPGA_BASE + 0x4)
+#define OMAP1510_FPGA_POWER (OMAP1510_FPGA_BASE + 0x5)
+
+#define OMAP1510_FPGA_ISR_LO (OMAP1510_FPGA_BASE + 0x6)
+#define OMAP1510_FPGA_ISR_HI (OMAP1510_FPGA_BASE + 0x7)
+
+#define OMAP1510_FPGA_IMR_LO (OMAP1510_FPGA_BASE + 0x8)
+#define OMAP1510_FPGA_IMR_HI (OMAP1510_FPGA_BASE + 0x9)
+
+#define OMAP1510_FPGA_HOST_RESET (OMAP1510_FPGA_BASE + 0xa)
+#define OMAP1510_FPGA_RST (OMAP1510_FPGA_BASE + 0xb)
+
+#define OMAP1510_FPGA_AUDIO (OMAP1510_FPGA_BASE + 0xc)
+#define OMAP1510_FPGA_DIP (OMAP1510_FPGA_BASE + 0xe)
+#define OMAP1510_FPGA_FPGA_IO (OMAP1510_FPGA_BASE + 0xf)
+#define OMAP1510_FPGA_UART1 (OMAP1510_FPGA_BASE + 0x14)
+#define OMAP1510_FPGA_UART2 (OMAP1510_FPGA_BASE + 0x15)
+#define OMAP1510_FPGA_OMAP1510_STATUS (OMAP1510_FPGA_BASE + 0x16)
+#define OMAP1510_FPGA_BOARD_REV (OMAP1510_FPGA_BASE + 0x18)
+#define OMAP1510P1_PPT_DATA (OMAP1510_FPGA_BASE + 0x100)
+#define OMAP1510P1_PPT_STATUS (OMAP1510_FPGA_BASE + 0x101)
+#define OMAP1510P1_PPT_CONTROL (OMAP1510_FPGA_BASE + 0x102)
+
+#define OMAP1510_FPGA_TOUCHSCREEN (OMAP1510_FPGA_BASE + 0x204)
+
+#define INNOVATOR_FPGA_INFO (OMAP1510_FPGA_BASE + 0x205)
+#define INNOVATOR_FPGA_LCD_BRIGHT_LO (OMAP1510_FPGA_BASE + 0x206)
+#define INNOVATOR_FPGA_LCD_BRIGHT_HI (OMAP1510_FPGA_BASE + 0x207)
+#define INNOVATOR_FPGA_LED_GRN_LO (OMAP1510_FPGA_BASE + 0x208)
+#define INNOVATOR_FPGA_LED_GRN_HI (OMAP1510_FPGA_BASE + 0x209)
+#define INNOVATOR_FPGA_LED_RED_LO (OMAP1510_FPGA_BASE + 0x20a)
+#define INNOVATOR_FPGA_LED_RED_HI (OMAP1510_FPGA_BASE + 0x20b)
+#define INNOVATOR_FPGA_CAM_USB_CONTROL (OMAP1510_FPGA_BASE + 0x20c)
+#define INNOVATOR_FPGA_EXP_CONTROL (OMAP1510_FPGA_BASE + 0x20d)
+#define INNOVATOR_FPGA_ISR2 (OMAP1510_FPGA_BASE + 0x20e)
+#define INNOVATOR_FPGA_IMR2 (OMAP1510_FPGA_BASE + 0x210)
+
+#define OMAP1510_FPGA_ETHR_START (OMAP1510_FPGA_START + 0x300)
+
+#define OMAP1510_FPGA_RESET_VALUE 0x42
+
+#define OMAP1510_FPGA_PCR_IF_PD0 (1 << 7)
+#define OMAP1510_FPGA_PCR_COM2_EN (1 << 6)
+#define OMAP1510_FPGA_PCR_COM1_EN (1 << 5)
+#define OMAP1510_FPGA_PCR_EXP_PD0 (1 << 4)
+#define OMAP1510_FPGA_PCR_EXP_PD1 (1 << 3)
+#define OMAP1510_FPGA_PCR_48MHZ_CLK (1 << 2)
+#define OMAP1510_FPGA_PCR_4MHZ_CLK (1 << 1)
+#define OMAP1510_FPGA_PCR_RSRVD_BIT0 (1 << 0)
+
+#define OMAP1510_FPGA_HID_SCLK (1<<0)  
+#define OMAP1510_FPGA_HID_MOSI (1<<1)  
+#define OMAP1510_FPGA_HID_nSS (1<<2)  
+#define OMAP1510_FPGA_HID_nHSUS (1<<3)  
+#define OMAP1510_FPGA_HID_MISO (1<<4)  
+#define OMAP1510_FPGA_HID_ATN (1<<5)  
+#define OMAP1510_FPGA_HID_rsrvd (1<<6)
+#define OMAP1510_FPGA_HID_RESETn (1<<7)  
+
+#define OMAP1510_INT_FPGA (IH_GPIO_BASE + 13)
+
+#define OMAP1510_IH_FPGA_BASE IH_BOARD_BASE
+#define OMAP1510_INT_FPGA_ATN (OMAP1510_IH_FPGA_BASE + 0)
+#define OMAP1510_INT_FPGA_ACK (OMAP1510_IH_FPGA_BASE + 1)
+#define OMAP1510_INT_FPGA2 (OMAP1510_IH_FPGA_BASE + 2)
+#define OMAP1510_INT_FPGA3 (OMAP1510_IH_FPGA_BASE + 3)
+#define OMAP1510_INT_FPGA4 (OMAP1510_IH_FPGA_BASE + 4)
+#define OMAP1510_INT_FPGA5 (OMAP1510_IH_FPGA_BASE + 5)
+#define OMAP1510_INT_FPGA6 (OMAP1510_IH_FPGA_BASE + 6)
+#define OMAP1510_INT_FPGA7 (OMAP1510_IH_FPGA_BASE + 7)
+#define OMAP1510_INT_FPGA8 (OMAP1510_IH_FPGA_BASE + 8)
+#define OMAP1510_INT_FPGA9 (OMAP1510_IH_FPGA_BASE + 9)
+#define OMAP1510_INT_FPGA10 (OMAP1510_IH_FPGA_BASE + 10)
+#define OMAP1510_INT_FPGA11 (OMAP1510_IH_FPGA_BASE + 11)
+#define OMAP1510_INT_FPGA12 (OMAP1510_IH_FPGA_BASE + 12)
+#define OMAP1510_INT_ETHER (OMAP1510_IH_FPGA_BASE + 13)
+#define OMAP1510_INT_FPGAUART1 (OMAP1510_IH_FPGA_BASE + 14)
+#define OMAP1510_INT_FPGAUART2 (OMAP1510_IH_FPGA_BASE + 15)
+#define OMAP1510_INT_FPGA_TS (OMAP1510_IH_FPGA_BASE + 16)
+#define OMAP1510_INT_FPGA17 (OMAP1510_IH_FPGA_BASE + 17)
+#define OMAP1510_INT_FPGA_CAM (OMAP1510_IH_FPGA_BASE + 18)
+#define OMAP1510_INT_FPGA_RTC_A (OMAP1510_IH_FPGA_BASE + 19)
+#define OMAP1510_INT_FPGA_RTC_B (OMAP1510_IH_FPGA_BASE + 20)
+#define OMAP1510_INT_FPGA_CD (OMAP1510_IH_FPGA_BASE + 21)
+#define OMAP1510_INT_FPGA22 (OMAP1510_IH_FPGA_BASE + 22)
+#define OMAP1510_INT_FPGA23 (OMAP1510_IH_FPGA_BASE + 23)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/gpio-switch.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/gpio-switch.h
new file mode 100644
index 0000000..20ea3f2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/gpio-switch.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARCH_OMAP_GPIO_SWITCH_H
+#define __ASM_ARCH_OMAP_GPIO_SWITCH_H
+
+#include <linux/types.h>
+
+#define OMAP_GPIO_SWITCH_TYPE_COVER 0x0000
+#define OMAP_GPIO_SWITCH_TYPE_CONNECTION 0x0001
+#define OMAP_GPIO_SWITCH_TYPE_ACTIVITY 0x0002
+#define OMAP_GPIO_SWITCH_FLAG_INVERTED 0x0001
+#define OMAP_GPIO_SWITCH_FLAG_OUTPUT 0x0002
+
+struct omap_gpio_switch {
+ const char *name;
+ s16 gpio;
+ unsigned flags:4;
+ unsigned type:4;
+
+ u16 debounce_rising;
+
+ u16 debounce_falling;
+
+ void (* notify)(void *data, int state);
+ void *notify_data;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/gpio.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/gpio.h
new file mode 100644
index 0000000..332246d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/gpio.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARCH_OMAP_GPIO_H
+#define __ASM_ARCH_OMAP_GPIO_H
+
+#include <asm/hardware.h>
+#include <asm/arch/irqs.h>
+#include <asm/io.h>
+
+#define OMAP_MPUIO_BASE (void __iomem *)0xfffb5000
+
+#define OMAP_MPUIO_INPUT_LATCH 0x00
+#define OMAP_MPUIO_OUTPUT 0x04
+#define OMAP_MPUIO_IO_CNTL 0x08
+#define OMAP_MPUIO_KBR_LATCH 0x10
+#define OMAP_MPUIO_KBC 0x14
+#define OMAP_MPUIO_GPIO_EVENT_MODE 0x18
+#define OMAP_MPUIO_GPIO_INT_EDGE 0x1c
+#define OMAP_MPUIO_KBD_INT 0x20
+#define OMAP_MPUIO_GPIO_INT 0x24
+#define OMAP_MPUIO_KBD_MASKIT 0x28
+#define OMAP_MPUIO_GPIO_MASKIT 0x2c
+#define OMAP_MPUIO_GPIO_DEBOUNCING 0x30
+#define OMAP_MPUIO_LATCH 0x34
+
+#define OMAP_MPUIO(nr) (OMAP_MAX_GPIO_LINES + (nr))
+#define OMAP_GPIO_IS_MPUIO(nr) ((nr) >= OMAP_MAX_GPIO_LINES)
+
+#define OMAP_GPIO_IRQ(nr) (OMAP_GPIO_IS_MPUIO(nr) ?   IH_MPUIO_BASE + ((nr) & 0x0f) :   IH_GPIO_BASE + (nr))
+
+struct omap_machine_gpio_bank {
+ int start;
+ int end;
+
+ void (*set_gpio_direction)(int gpio, int is_input);
+ void (*set_gpio_dataout)(int gpio, int enable);
+ int (*get_gpio_datain)(int gpio);
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/hardware.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/hardware.h
new file mode 100644
index 0000000..e515ee8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/hardware.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARCH_OMAP_HARDWARE_H
+#define __ASM_ARCH_OMAP_HARDWARE_H
+
+#include <asm/sizes.h>
+#ifndef __ASSEMBLER__
+#include <asm/types.h>
+#include <asm/arch/cpu.h>
+#endif
+#include <asm/arch/io.h>
+#include <asm/arch/serial.h>
+
+#define OMAP_MPU_TIMER1_BASE (0xfffec500)
+#define OMAP_MPU_TIMER2_BASE (0xfffec600)
+#define OMAP_MPU_TIMER3_BASE (0xfffec700)
+#define MPU_TIMER_FREE (1 << 6)
+#define MPU_TIMER_CLOCK_ENABLE (1 << 5)
+#define MPU_TIMER_AR (1 << 1)
+#define MPU_TIMER_ST (1 << 0)
+
+#define CLKGEN_REG_BASE (0xfffece00)
+#define ARM_CKCTL (CLKGEN_REG_BASE + 0x0)
+#define ARM_IDLECT1 (CLKGEN_REG_BASE + 0x4)
+#define ARM_IDLECT2 (CLKGEN_REG_BASE + 0x8)
+#define ARM_EWUPCT (CLKGEN_REG_BASE + 0xC)
+#define ARM_RSTCT1 (CLKGEN_REG_BASE + 0x10)
+#define ARM_RSTCT2 (CLKGEN_REG_BASE + 0x14)
+#define ARM_SYSST (CLKGEN_REG_BASE + 0x18)
+#define ARM_IDLECT3 (CLKGEN_REG_BASE + 0x24)
+
+#define CK_RATEF 1
+#define CK_IDLEF 2
+#define CK_ENABLEF 4
+#define CK_SELECTF 8
+#define SETARM_IDLE_SHIFT
+
+#define DPLL_CTL (0xfffecf00)
+
+#define DSP_CONFIG_REG_BASE (0xe1008000)
+#define DSP_CKCTL (DSP_CONFIG_REG_BASE + 0x0)
+#define DSP_IDLECT1 (DSP_CONFIG_REG_BASE + 0x4)
+#define DSP_IDLECT2 (DSP_CONFIG_REG_BASE + 0x8)
+#define DSP_RSTCT2 (DSP_CONFIG_REG_BASE + 0x14)
+
+#define ULPD_REG_BASE (0xfffe0800)
+#define ULPD_IT_STATUS (ULPD_REG_BASE + 0x14)
+#define ULPD_SETUP_ANALOG_CELL_3 (ULPD_REG_BASE + 0x24)
+#define ULPD_CLOCK_CTRL (ULPD_REG_BASE + 0x30)
+#define DIS_USB_PVCI_CLK (1 << 5)  
+#define USB_MCLK_EN (1 << 4)  
+#define ULPD_SOFT_REQ (ULPD_REG_BASE + 0x34)
+#define SOFT_UDC_REQ (1 << 4)
+#define SOFT_USB_CLK_REQ (1 << 3)
+#define SOFT_DPLL_REQ (1 << 0)
+#define ULPD_DPLL_CTRL (ULPD_REG_BASE + 0x3c)
+#define ULPD_STATUS_REQ (ULPD_REG_BASE + 0x40)
+#define ULPD_APLL_CTRL (ULPD_REG_BASE + 0x4c)
+#define ULPD_POWER_CTRL (ULPD_REG_BASE + 0x50)
+#define ULPD_SOFT_DISABLE_REQ_REG (ULPD_REG_BASE + 0x68)
+#define DIS_MMC2_DPLL_REQ (1 << 11)
+#define DIS_MMC1_DPLL_REQ (1 << 10)
+#define DIS_UART3_DPLL_REQ (1 << 9)
+#define DIS_UART2_DPLL_REQ (1 << 8)
+#define DIS_UART1_DPLL_REQ (1 << 7)
+#define DIS_USB_HOST_DPLL_REQ (1 << 6)
+#define ULPD_SDW_CLK_DIV_CTRL_SEL (ULPD_REG_BASE + 0x74)
+#define ULPD_CAM_CLK_CTRL (ULPD_REG_BASE + 0x7c)
+
+#define OMAP_MPU_WATCHDOG_BASE (0xfffec800)
+#define OMAP_WDT_TIMER (OMAP_MPU_WATCHDOG_BASE + 0x0)
+#define OMAP_WDT_LOAD_TIM (OMAP_MPU_WATCHDOG_BASE + 0x4)
+#define OMAP_WDT_READ_TIM (OMAP_MPU_WATCHDOG_BASE + 0x4)
+#define OMAP_WDT_TIMER_MODE (OMAP_MPU_WATCHDOG_BASE + 0x8)
+
+#define MOD_CONF_CTRL_0 0xfffe1080
+#define MOD_CONF_CTRL_1 0xfffe1110
+
+#define FUNC_MUX_CTRL_0 0xfffe1000
+#define FUNC_MUX_CTRL_1 0xfffe1004
+#define FUNC_MUX_CTRL_2 0xfffe1008
+#define COMP_MODE_CTRL_0 0xfffe100c
+#define FUNC_MUX_CTRL_3 0xfffe1010
+#define FUNC_MUX_CTRL_4 0xfffe1014
+#define FUNC_MUX_CTRL_5 0xfffe1018
+#define FUNC_MUX_CTRL_6 0xfffe101C
+#define FUNC_MUX_CTRL_7 0xfffe1020
+#define FUNC_MUX_CTRL_8 0xfffe1024
+#define FUNC_MUX_CTRL_9 0xfffe1028
+#define FUNC_MUX_CTRL_A 0xfffe102C
+#define FUNC_MUX_CTRL_B 0xfffe1030
+#define FUNC_MUX_CTRL_C 0xfffe1034
+#define FUNC_MUX_CTRL_D 0xfffe1038
+#define PULL_DWN_CTRL_0 0xfffe1040
+#define PULL_DWN_CTRL_1 0xfffe1044
+#define PULL_DWN_CTRL_2 0xfffe1048
+#define PULL_DWN_CTRL_3 0xfffe104c
+#define PULL_DWN_CTRL_4 0xfffe10ac
+
+#define FUNC_MUX_CTRL_E 0xfffe1090
+#define FUNC_MUX_CTRL_F 0xfffe1094
+#define FUNC_MUX_CTRL_10 0xfffe1098
+#define FUNC_MUX_CTRL_11 0xfffe109c
+#define FUNC_MUX_CTRL_12 0xfffe10a0
+#define PU_PD_SEL_0 0xfffe10b4
+#define PU_PD_SEL_1 0xfffe10b8
+#define PU_PD_SEL_2 0xfffe10bc
+#define PU_PD_SEL_3 0xfffe10c0
+#define PU_PD_SEL_4 0xfffe10c4
+
+#define OMAP_TIMER32K_BASE 0xFFFBC400
+
+#define TIPB_PUBLIC_CNTL_BASE 0xfffed300
+#define MPU_PUBLIC_TIPB_CNTL (TIPB_PUBLIC_CNTL_BASE + 0x8)
+#define TIPB_PRIVATE_CNTL_BASE 0xfffeca00
+#define MPU_PRIVATE_TIPB_CNTL (TIPB_PRIVATE_CNTL_BASE + 0x8)
+
+#define MPUI_BASE (0xfffec900)
+#define MPUI_CTRL (MPUI_BASE + 0x0)
+#define MPUI_DEBUG_ADDR (MPUI_BASE + 0x4)
+#define MPUI_DEBUG_DATA (MPUI_BASE + 0x8)
+#define MPUI_DEBUG_FLAG (MPUI_BASE + 0xc)
+#define MPUI_STATUS_REG (MPUI_BASE + 0x10)
+#define MPUI_DSP_STATUS (MPUI_BASE + 0x14)
+#define MPUI_DSP_BOOT_CONFIG (MPUI_BASE + 0x18)
+#define MPUI_DSP_API_CONFIG (MPUI_BASE + 0x1c)
+
+#define OMAP_LPG1_BASE 0xfffbd000
+#define OMAP_LPG2_BASE 0xfffbd800
+#define OMAP_LPG1_LCR (OMAP_LPG1_BASE + 0x00)
+#define OMAP_LPG1_PMR (OMAP_LPG1_BASE + 0x04)
+#define OMAP_LPG2_LCR (OMAP_LPG2_BASE + 0x00)
+#define OMAP_LPG2_PMR (OMAP_LPG2_BASE + 0x04)
+
+#define OMAP_PWL_BASE 0xfffb5800
+#define OMAP_PWL_ENABLE (OMAP_PWL_BASE + 0x00)
+#define OMAP_PWL_CLK_ENABLE (OMAP_PWL_BASE + 0x04)
+
+#include "omap730.h"
+#include "omap1510.h"
+#include "omap24xx.h"
+#include "omap16xx.h"
+
+#ifndef __ASSEMBLER__
+
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/io.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/io.h
new file mode 100644
index 0000000..12ac3d4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/io.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#include <asm/hardware.h>
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
+#define __mem_pci(a) (a)
+
+#define PCIO_BASE 0
+
+#ifndef __ASSEMBLER__
+
+#define omap_readb(a) (*(volatile unsigned char *)IO_ADDRESS(a))
+#define omap_readw(a) (*(volatile unsigned short *)IO_ADDRESS(a))
+#define omap_readl(a) (*(volatile unsigned int *)IO_ADDRESS(a))
+
+#define omap_writeb(v,a) (*(volatile unsigned char *)IO_ADDRESS(a) = (v))
+#define omap_writew(v,a) (*(volatile unsigned short *)IO_ADDRESS(a) = (v))
+#define omap_writel(v,a) (*(volatile unsigned int *)IO_ADDRESS(a) = (v))
+
+typedef struct { volatile u16 offset[256]; } __regbase16;
+#define __REGV16(vaddr) ((__regbase16 *)((vaddr)&~0xff))   ->offset[((vaddr)&0xff)>>1]
+#define __REG16(paddr) __REGV16(io_p2v(paddr))
+
+typedef struct { volatile u8 offset[4096]; } __regbase8;
+#define __REGV8(vaddr) ((__regbase8 *)((vaddr)&~4095))   ->offset[((vaddr)&4095)>>0]
+#define __REG8(paddr) __REGV8(io_p2v(paddr))
+
+typedef struct { volatile u32 offset[4096]; } __regbase32;
+#define __REGV32(vaddr) ((__regbase32 *)((vaddr)&~4095))   ->offset[((vaddr)&4095)>>2]
+#define __REG32(paddr) __REGV32(io_p2v(paddr))
+
+#else
+
+#define __REG8(paddr) io_p2v(paddr)
+#define __REG16(paddr) io_p2v(paddr)
+#define __REG32(paddr) io_p2v(paddr)
+
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/irqs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/irqs.h
new file mode 100644
index 0000000..3e94487
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/irqs.h
@@ -0,0 +1,242 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARCH_OMAP15XX_IRQS_H
+#define __ASM_ARCH_OMAP15XX_IRQS_H
+
+#define INT_CAMERA 1
+#define INT_FIQ 3
+#define INT_RTDX 6
+#define INT_DSP_MMU_ABORT 7
+#define INT_HOST 8
+#define INT_ABORT 9
+#define INT_DSP_MAILBOX1 10
+#define INT_DSP_MAILBOX2 11
+#define INT_BRIDGE_PRIV 13
+#define INT_GPIO_BANK1 14
+#define INT_UART3 15
+#define INT_TIMER3 16
+#define INT_DMA_CH0_6 19
+#define INT_DMA_CH1_7 20
+#define INT_DMA_CH2_8 21
+#define INT_DMA_CH3 22
+#define INT_DMA_CH4 23
+#define INT_DMA_CH5 24
+#define INT_DMA_LCD 25
+#define INT_TIMER1 26
+#define INT_WD_TIMER 27
+#define INT_BRIDGE_PUB 28
+#define INT_TIMER2 30
+#define INT_LCD_CTRL 31
+
+#define INT_1510_IH2_IRQ 0
+#define INT_1510_RES2 2
+#define INT_1510_SPI_TX 4
+#define INT_1510_SPI_RX 5
+#define INT_1510_RES12 12
+#define INT_1510_LB_MMU 17
+#define INT_1510_RES18 18
+#define INT_1510_LOCAL_BUS 29
+
+#define INT_1610_IH2_IRQ 0
+#define INT_1610_IH2_FIQ 2
+#define INT_1610_McBSP2_TX 4
+#define INT_1610_McBSP2_RX 5
+#define INT_1610_LCD_LINE 12
+#define INT_1610_GPTIMER1 17
+#define INT_1610_GPTIMER2 18
+#define INT_1610_SSR_FIFO_0 29
+
+#define INT_730_IH2_FIQ 0
+#define INT_730_IH2_IRQ 1
+#define INT_730_USB_NON_ISO 2
+#define INT_730_USB_ISO 3
+#define INT_730_ICR 4
+#define INT_730_EAC 5
+#define INT_730_GPIO_BANK1 6
+#define INT_730_GPIO_BANK2 7
+#define INT_730_GPIO_BANK3 8
+#define INT_730_McBSP2TX 10
+#define INT_730_McBSP2RX 11
+#define INT_730_McBSP2RX_OVF 12
+#define INT_730_LCD_LINE 14
+#define INT_730_GSM_PROTECT 15
+#define INT_730_TIMER3 16
+#define INT_730_GPIO_BANK5 17
+#define INT_730_GPIO_BANK6 18
+#define INT_730_SPGIO_WR 29
+
+#define IH2_BASE 32
+
+#define INT_KEYBOARD (1 + IH2_BASE)
+#define INT_uWireTX (2 + IH2_BASE)
+#define INT_uWireRX (3 + IH2_BASE)
+#define INT_I2C (4 + IH2_BASE)
+#define INT_MPUIO (5 + IH2_BASE)
+#define INT_USB_HHC_1 (6 + IH2_BASE)
+#define INT_McBSP3TX (10 + IH2_BASE)
+#define INT_McBSP3RX (11 + IH2_BASE)
+#define INT_McBSP1TX (12 + IH2_BASE)
+#define INT_McBSP1RX (13 + IH2_BASE)
+#define INT_UART2 (14 + IH2_BASE)
+#define INT_UART1 (15 + IH2_BASE)
+#define INT_BT_MCSI1TX (16 + IH2_BASE)
+#define INT_BT_MCSI1RX (17 + IH2_BASE)
+#define INT_USB_W2FC (20 + IH2_BASE)
+#define INT_1WIRE (21 + IH2_BASE)
+#define INT_OS_TIMER (22 + IH2_BASE)
+#define INT_MMC (23 + IH2_BASE)
+#define INT_GAUGE_32K (24 + IH2_BASE)
+#define INT_RTC_TIMER (25 + IH2_BASE)
+#define INT_RTC_ALARM (26 + IH2_BASE)
+#define INT_MEM_STICK (27 + IH2_BASE)
+#define INT_DSP_MMU (28 + IH2_BASE)
+
+#define INT_1510_COM_SPI_RO (31 + IH2_BASE)
+
+#define INT_1610_FAC (0 + IH2_BASE)
+#define INT_1610_USB_HHC_2 (7 + IH2_BASE)
+#define INT_1610_USB_OTG (8 + IH2_BASE)
+#define INT_1610_SoSSI (9 + IH2_BASE)
+#define INT_1610_SoSSI_MATCH (19 + IH2_BASE)
+#define INT_1610_McBSP2RX_OF (31 + IH2_BASE)
+#define INT_1610_STI (32 + IH2_BASE)
+#define INT_1610_STI_WAKEUP (33 + IH2_BASE)
+#define INT_1610_GPTIMER3 (34 + IH2_BASE)
+#define INT_1610_GPTIMER4 (35 + IH2_BASE)
+#define INT_1610_GPTIMER5 (36 + IH2_BASE)
+#define INT_1610_GPTIMER6 (37 + IH2_BASE)
+#define INT_1610_GPTIMER7 (38 + IH2_BASE)
+#define INT_1610_GPTIMER8 (39 + IH2_BASE)
+#define INT_1610_GPIO_BANK2 (40 + IH2_BASE)
+#define INT_1610_GPIO_BANK3 (41 + IH2_BASE)
+#define INT_1610_MMC2 (42 + IH2_BASE)
+#define INT_1610_CF (43 + IH2_BASE)
+#define INT_1610_WAKE_UP_REQ (46 + IH2_BASE)
+#define INT_1610_GPIO_BANK4 (48 + IH2_BASE)
+#define INT_1610_SPI (49 + IH2_BASE)
+#define INT_1610_DMA_CH6 (53 + IH2_BASE)
+#define INT_1610_DMA_CH7 (54 + IH2_BASE)
+#define INT_1610_DMA_CH8 (55 + IH2_BASE)
+#define INT_1610_DMA_CH9 (56 + IH2_BASE)
+#define INT_1610_DMA_CH10 (57 + IH2_BASE)
+#define INT_1610_DMA_CH11 (58 + IH2_BASE)
+#define INT_1610_DMA_CH12 (59 + IH2_BASE)
+#define INT_1610_DMA_CH13 (60 + IH2_BASE)
+#define INT_1610_DMA_CH14 (61 + IH2_BASE)
+#define INT_1610_DMA_CH15 (62 + IH2_BASE)
+#define INT_1610_NAND (63 + IH2_BASE)
+
+#define INT_730_HW_ERRORS (0 + IH2_BASE)
+#define INT_730_NFIQ_PWR_FAIL (1 + IH2_BASE)
+#define INT_730_CFCD (2 + IH2_BASE)
+#define INT_730_CFIREQ (3 + IH2_BASE)
+#define INT_730_I2C (4 + IH2_BASE)
+#define INT_730_PCC (5 + IH2_BASE)
+#define INT_730_MPU_EXT_NIRQ (6 + IH2_BASE)
+#define INT_730_SPI_100K_1 (7 + IH2_BASE)
+#define INT_730_SYREN_SPI (8 + IH2_BASE)
+#define INT_730_VLYNQ (9 + IH2_BASE)
+#define INT_730_GPIO_BANK4 (10 + IH2_BASE)
+#define INT_730_McBSP1TX (11 + IH2_BASE)
+#define INT_730_McBSP1RX (12 + IH2_BASE)
+#define INT_730_McBSP1RX_OF (13 + IH2_BASE)
+#define INT_730_UART_MODEM_IRDA_2 (14 + IH2_BASE)
+#define INT_730_UART_MODEM_1 (15 + IH2_BASE)
+#define INT_730_MCSI (16 + IH2_BASE)
+#define INT_730_uWireTX (17 + IH2_BASE)
+#define INT_730_uWireRX (18 + IH2_BASE)
+#define INT_730_SMC_CD (19 + IH2_BASE)
+#define INT_730_SMC_IREQ (20 + IH2_BASE)
+#define INT_730_HDQ_1WIRE (21 + IH2_BASE)
+#define INT_730_TIMER32K (22 + IH2_BASE)
+#define INT_730_MMC_SDIO (23 + IH2_BASE)
+#define INT_730_UPLD (24 + IH2_BASE)
+#define INT_730_USB_HHC_1 (27 + IH2_BASE)
+#define INT_730_USB_HHC_2 (28 + IH2_BASE)
+#define INT_730_USB_GENI (29 + IH2_BASE)
+#define INT_730_USB_OTG (30 + IH2_BASE)
+#define INT_730_CAMERA_IF (31 + IH2_BASE)
+#define INT_730_RNG (32 + IH2_BASE)
+#define INT_730_DUAL_MODE_TIMER (33 + IH2_BASE)
+#define INT_730_DBB_RF_EN (34 + IH2_BASE)
+#define INT_730_MPUIO_KEYPAD (35 + IH2_BASE)
+#define INT_730_SHA1_MD5 (36 + IH2_BASE)
+#define INT_730_SPI_100K_2 (37 + IH2_BASE)
+#define INT_730_RNG_IDLE (38 + IH2_BASE)
+#define INT_730_MPUIO (39 + IH2_BASE)
+#define INT_730_LLPC_LCD_CTRL_CAN_BE_OFF (40 + IH2_BASE)
+#define INT_730_LLPC_OE_FALLING (41 + IH2_BASE)
+#define INT_730_LLPC_OE_RISING (42 + IH2_BASE)
+#define INT_730_LLPC_VSYNC (43 + IH2_BASE)
+#define INT_730_WAKE_UP_REQ (46 + IH2_BASE)
+#define INT_730_DMA_CH6 (53 + IH2_BASE)
+#define INT_730_DMA_CH7 (54 + IH2_BASE)
+#define INT_730_DMA_CH8 (55 + IH2_BASE)
+#define INT_730_DMA_CH9 (56 + IH2_BASE)
+#define INT_730_DMA_CH10 (57 + IH2_BASE)
+#define INT_730_DMA_CH11 (58 + IH2_BASE)
+#define INT_730_DMA_CH12 (59 + IH2_BASE)
+#define INT_730_DMA_CH13 (60 + IH2_BASE)
+#define INT_730_DMA_CH14 (61 + IH2_BASE)
+#define INT_730_DMA_CH15 (62 + IH2_BASE)
+#define INT_730_NAND (63 + IH2_BASE)
+
+#define INT_24XX_SYS_NIRQ 7
+#define INT_24XX_SDMA_IRQ0 12
+#define INT_24XX_SDMA_IRQ1 13
+#define INT_24XX_SDMA_IRQ2 14
+#define INT_24XX_SDMA_IRQ3 15
+#define INT_24XX_CAM_IRQ 24
+#define INT_24XX_DSS_IRQ 25
+#define INT_24XX_GPIO_BANK1 29
+#define INT_24XX_GPIO_BANK2 30
+#define INT_24XX_GPIO_BANK3 31
+#define INT_24XX_GPIO_BANK4 32
+#define INT_24XX_GPTIMER1 37
+#define INT_24XX_GPTIMER2 38
+#define INT_24XX_GPTIMER3 39
+#define INT_24XX_GPTIMER4 40
+#define INT_24XX_GPTIMER5 41
+#define INT_24XX_GPTIMER6 42
+#define INT_24XX_GPTIMER7 43
+#define INT_24XX_GPTIMER8 44
+#define INT_24XX_GPTIMER9 45
+#define INT_24XX_GPTIMER10 46
+#define INT_24XX_GPTIMER11 47
+#define INT_24XX_GPTIMER12 48
+#define INT_24XX_MCBSP1_IRQ_TX 59
+#define INT_24XX_MCBSP1_IRQ_RX 60
+#define INT_24XX_MCBSP2_IRQ_TX 62
+#define INT_24XX_MCBSP2_IRQ_RX 63
+#define INT_24XX_UART1_IRQ 72
+#define INT_24XX_UART2_IRQ 73
+#define INT_24XX_UART3_IRQ 74
+#define INT_24XX_MMC_IRQ 83
+
+#define OMAP_MAX_GPIO_LINES 192
+#define IH_GPIO_BASE (128 + IH2_BASE)
+#define IH_MPUIO_BASE (OMAP_MAX_GPIO_LINES + IH_GPIO_BASE)
+#define IH_BOARD_BASE (16 + IH_MPUIO_BASE)
+
+#define OMAP_IRQ_BIT(irq) (1 << ((irq) % 32))
+
+#ifndef __ASSEMBLY__
+
+#endif
+
+#include <asm/hardware.h>
+
+#ifndef NR_IRQS
+#define NR_IRQS IH_BOARD_BASE
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/mcbsp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/mcbsp.h
new file mode 100644
index 0000000..cae5e3b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/mcbsp.h
@@ -0,0 +1,185 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARCH_OMAP_MCBSP_H
+#define __ASM_ARCH_OMAP_MCBSP_H
+
+#include <asm/hardware.h>
+
+#define OMAP730_MCBSP1_BASE 0xfffb1000
+#define OMAP730_MCBSP2_BASE 0xfffb1800
+
+#define OMAP1510_MCBSP1_BASE 0xe1011800
+#define OMAP1510_MCBSP2_BASE 0xfffb1000
+#define OMAP1510_MCBSP3_BASE 0xe1017000
+
+#define OMAP1610_MCBSP1_BASE 0xe1011800
+#define OMAP1610_MCBSP2_BASE 0xfffb1000
+#define OMAP1610_MCBSP3_BASE 0xe1017000
+
+#define OMAP24XX_MCBSP1_BASE 0x48074000
+#define OMAP24XX_MCBSP2_BASE 0x48076000
+
+#define OMAP_MCBSP_READ(base, reg) __raw_readw((base) + OMAP_MCBSP_REG_##reg)
+#define OMAP_MCBSP_WRITE(base, reg, val) __raw_writew((val), (base) + OMAP_MCBSP_REG_##reg)
+
+#define RRST 0x0001
+#define RRDY 0x0002
+#define RFULL 0x0004
+#define RSYNC_ERR 0x0008
+#define RINTM(value) ((value)<<4)  
+#define ABIS 0x0040
+#define DXENA 0x0080
+#define CLKSTP(value) ((value)<<11)  
+#define RJUST(value) ((value)<<13)  
+#define DLB 0x8000
+
+#define XRST 0x0001
+#define XRDY 0x0002
+#define XEMPTY 0x0004
+#define XSYNC_ERR 0x0008
+#define XINTM(value) ((value)<<4)  
+#define GRST 0x0040
+#define FRST 0x0080
+#define SOFT 0x0100
+#define FREE 0x0200
+
+#define CLKRP 0x0001
+#define CLKXP 0x0002
+#define FSRP 0x0004
+#define FSXP 0x0008
+#define DR_STAT 0x0010
+#define DX_STAT 0x0020
+#define CLKS_STAT 0x0040
+#define SCLKME 0x0080
+#define CLKRM 0x0100
+#define CLKXM 0x0200
+#define FSRM 0x0400
+#define FSXM 0x0800
+#define RIOEN 0x1000
+#define XIOEN 0x2000
+#define IDLE_EN 0x4000
+
+#define RWDLEN1(value) ((value)<<5)  
+#define RFRLEN1(value) ((value)<<8)  
+
+#define XWDLEN1(value) ((value)<<5)  
+#define XFRLEN1(value) ((value)<<8)  
+
+#define RDATDLY(value) (value)  
+#define RFIG 0x0004
+#define RCOMPAND(value) ((value)<<3)  
+#define RWDLEN2(value) ((value)<<5)  
+#define RFRLEN2(value) ((value)<<8)  
+#define RPHASE 0x8000
+
+#define XDATDLY(value) (value)  
+#define XFIG 0x0004
+#define XCOMPAND(value) ((value)<<3)  
+#define XWDLEN2(value) ((value)<<5)  
+#define XFRLEN2(value) ((value)<<8)  
+#define XPHASE 0x8000
+
+#define CLKGDV(value) (value)  
+#define FWID(value) ((value)<<8)  
+
+#define FPER(value) (value)  
+#define FSGM 0x1000
+#define CLKSM 0x2000
+#define CLKSP 0x4000
+#define GSYNC 0x8000
+
+#define RMCM 0x0001
+#define RCBLK(value) ((value)<<2)  
+#define RPABLK(value) ((value)<<5)  
+#define RPBBLK(value) ((value)<<7)  
+
+#define XMCM(value) (value)  
+#define XCBLK(value) ((value)<<2)  
+#define XPABLK(value) ((value)<<5)  
+#define XPBBLK(value) ((value)<<7)  
+
+struct omap_mcbsp_reg_cfg {
+ u16 spcr2;
+ u16 spcr1;
+ u16 rcr2;
+ u16 rcr1;
+ u16 xcr2;
+ u16 xcr1;
+ u16 srgr2;
+ u16 srgr1;
+ u16 mcr2;
+ u16 mcr1;
+ u16 pcr0;
+ u16 rcerc;
+ u16 rcerd;
+ u16 xcerc;
+ u16 xcerd;
+ u16 rcere;
+ u16 rcerf;
+ u16 xcere;
+ u16 xcerf;
+ u16 rcerg;
+ u16 rcerh;
+ u16 xcerg;
+ u16 xcerh;
+};
+
+typedef enum {
+ OMAP_MCBSP1 = 0,
+ OMAP_MCBSP2,
+ OMAP_MCBSP3,
+} omap_mcbsp_id;
+
+typedef int __bitwise omap_mcbsp_io_type_t;
+#define OMAP_MCBSP_IRQ_IO ((__force omap_mcbsp_io_type_t) 1)
+#define OMAP_MCBSP_POLL_IO ((__force omap_mcbsp_io_type_t) 2)
+
+typedef enum {
+ OMAP_MCBSP_WORD_8 = 0,
+ OMAP_MCBSP_WORD_12,
+ OMAP_MCBSP_WORD_16,
+ OMAP_MCBSP_WORD_20,
+ OMAP_MCBSP_WORD_24,
+ OMAP_MCBSP_WORD_32,
+} omap_mcbsp_word_length;
+
+typedef enum {
+ OMAP_MCBSP_CLK_RISING = 0,
+ OMAP_MCBSP_CLK_FALLING,
+} omap_mcbsp_clk_polarity;
+
+typedef enum {
+ OMAP_MCBSP_FS_ACTIVE_HIGH = 0,
+ OMAP_MCBSP_FS_ACTIVE_LOW,
+} omap_mcbsp_fs_polarity;
+
+typedef enum {
+ OMAP_MCBSP_CLK_STP_MODE_NO_DELAY = 0,
+ OMAP_MCBSP_CLK_STP_MODE_DELAY,
+} omap_mcbsp_clk_stp_mode;
+
+typedef enum {
+ OMAP_MCBSP_SPI_MASTER = 0,
+ OMAP_MCBSP_SPI_SLAVE,
+} omap_mcbsp_spi_mode;
+
+struct omap_mcbsp_spi_cfg {
+ omap_mcbsp_spi_mode spi_mode;
+ omap_mcbsp_clk_polarity rx_clock_polarity;
+ omap_mcbsp_clk_polarity tx_clock_polarity;
+ omap_mcbsp_fs_polarity fsx_polarity;
+ u8 clk_div;
+ omap_mcbsp_clk_stp_mode clk_stp_mode;
+ omap_mcbsp_word_length word_length;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/memory.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/memory.h
new file mode 100644
index 0000000..8b064b8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/memory.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define __virt_to_bus(x) __virt_to_phys(x)
+#define __bus_to_virt(x) __phys_to_virt(x)
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/mtd-xip.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/mtd-xip.h
new file mode 100644
index 0000000..9b60aef
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/mtd-xip.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ARCH_OMAP_MTD_XIP_H__
+#define __ARCH_OMAP_MTD_XIP_H__
+
+#include <asm/hardware.h>
+#define OMAP_MPU_TIMER_BASE (0xfffec500)
+#define OMAP_MPU_TIMER_OFFSET 0x100
+
+typedef struct {
+ u32 cntl;
+ u32 load_tim;
+ u32 read_tim;
+} xip_omap_mpu_timer_regs_t;
+
+#define xip_omap_mpu_timer_base(n)  ((volatile xip_omap_mpu_timer_regs_t*)IO_ADDRESS(OMAP_MPU_TIMER_BASE +   (n)*OMAP_MPU_TIMER_OFFSET))
+
+#define xip_irqpending()   (omap_readl(OMAP_IH1_ITR) & ~omap_readl(OMAP_IH1_MIR))
+#define xip_currtime() (~xip_omap_mpu_timer_read(0))
+#define xip_elapsed_since(x) (signed)((~xip_omap_mpu_timer_read(0) - (x)) / 6)
+#define xip_cpu_idle() asm volatile ("mcr p15, 0, %0, c7, c0, 4" :: "r" (1))
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/mux.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/mux.h
new file mode 100644
index 0000000..72da54e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/mux.h
@@ -0,0 +1,391 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARCH_MUX_H
+#define __ASM_ARCH_MUX_H
+
+#define PU_PD_SEL_NA 0  
+#define PULL_DWN_CTRL_NA 0  
+
+#define MUX_REG(reg, mode_offset, mode) .mux_reg = FUNC_MUX_CTRL_##reg,   .mask_offset = mode_offset,   .mask = mode,
+
+#define PULL_REG(reg, bit, status) .pull_reg = PULL_DWN_CTRL_##reg,   .pull_bit = bit,   .pull_val = status,
+
+#define PU_PD_REG(reg, status) .pu_pd_reg = PU_PD_SEL_##reg,   .pu_pd_val = status,
+
+#define MUX_REG_730(reg, mode_offset, mode)   .mux_reg = OMAP730_IO_CONF_##reg,   .mask_offset = mode_offset,   .mask = mode,
+
+#define PULL_REG_730(reg, bit, status) .pull_reg = OMAP730_IO_CONF_##reg,   .pull_bit = bit,   .pull_val = status,
+
+#define MUX_CFG(desc, mux_reg, mode_offset, mode,   pull_reg, pull_bit, pull_status,   pu_pd_reg, pu_pd_status, debug_status)  {   .name = desc,   .debug = debug_status,   MUX_REG(mux_reg, mode_offset, mode)   PULL_REG(pull_reg, pull_bit, !pull_status)   PU_PD_REG(pu_pd_reg, pu_pd_status)  },
+
+#define MUX_CFG_730(desc, mux_reg, mode_offset, mode,   pull_bit, pull_status, debug_status) {   .name = desc,   .debug = debug_status,   MUX_REG_730(mux_reg, mode_offset, mode)   PULL_REG_730(mux_reg, pull_bit, pull_status)   PU_PD_REG(NA, 0)  },
+
+#define MUX_CFG_24XX(desc, reg_offset, mode,   pull_en, pull_mode, dbg)  {   .name = desc,   .debug = dbg,   .mux_reg = reg_offset,   .mask = mode,   .pull_val = pull_en,   .pu_pd_val = pull_mode,  },
+
+#define PULL_DISABLED 0
+#define PULL_ENABLED 1
+
+#define PULL_DOWN 0
+#define PULL_UP 1
+
+struct pin_config {
+ char *name;
+ unsigned char busy;
+ unsigned char debug;
+
+ const char *mux_reg_name;
+ const unsigned int mux_reg;
+ const unsigned char mask_offset;
+ const unsigned char mask;
+
+ const char *pull_name;
+ const unsigned int pull_reg;
+ const unsigned char pull_val;
+ const unsigned char pull_bit;
+
+ const char *pu_pd_name;
+ const unsigned int pu_pd_reg;
+ const unsigned char pu_pd_val;
+};
+
+enum omap730_index {
+
+ E2_730_KBR0,
+ J7_730_KBR1,
+ E1_730_KBR2,
+ F3_730_KBR3,
+ D2_730_KBR4,
+ AA20_730_KBR5,
+ V17_730_KBR6,
+ C2_730_KBC0,
+ D3_730_KBC1,
+ E4_730_KBC2,
+ F4_730_KBC3,
+ E3_730_KBC4,
+
+ AA17_730_USB_DM,
+ W16_730_USB_PU_EN,
+ W17_730_USB_VBUSI,
+
+ V19_730_GPIO_15,
+ M19_730_GPIO_77,
+ C21_730_GPIO_121_122,
+ K19_730_GPIO_126,
+ K15_730_GPIO_127,
+
+ P15_730_GPIO_16_17,
+
+ M15_730_GPIO_83,
+ N20_730_GPIO_82,
+ N18_730_GPIO_81,
+ N19_730_GPIO_80,
+ L15_730_GPIO_76,
+
+ UART1_CTS_RTS,
+ OMAP_730_GPIOS_42_43,
+ UART1_TX_RX,
+ OMAP_730_GPIOS_40_41,
+ UART1_USB_RX_TX,
+ UART1_USB_RTS,
+ UART1_USB_CTS
+};
+
+enum omap1xxx_index {
+
+ UART1_TX = 0,
+ UART1_RTS,
+
+ UART2_TX,
+ UART2_RX,
+ UART2_CTS,
+ UART2_RTS,
+
+ UART3_TX,
+ UART3_RX,
+ UART3_CTS,
+ UART3_RTS,
+ UART3_CLKREQ,
+ UART3_BCLK,
+ Y15_1610_UART3_RTS,
+
+ PWT,
+ PWL,
+
+ R18_USB_VBUS,
+ R18_1510_USB_GPIO0,
+ W4_USB_PUEN,
+ W4_USB_CLKO,
+ W4_USB_HIGHZ,
+ W4_GPIO58,
+
+ USB1_SUSP,
+ USB1_SEO,
+ W13_1610_USB1_SE0,
+ USB1_TXEN,
+ USB1_TXD,
+ USB1_VP,
+ USB1_VM,
+ USB1_RCV,
+ USB1_SPEED,
+ R13_1610_USB1_SPEED,
+ R13_1710_USB1_SE0,
+
+ USB2_SUSP,
+ USB2_VP,
+ USB2_TXEN,
+ USB2_VM,
+ USB2_RCV,
+ USB2_SEO,
+ USB2_TXD,
+
+ R18_1510_GPIO0,
+ R19_1510_GPIO1,
+ M14_1510_GPIO2,
+
+ P18_1610_GPIO3,
+ Y15_1610_GPIO17,
+
+ R18_1710_GPIO0,
+ V2_1710_GPIO10,
+ N21_1710_GPIO14,
+ W15_1710_GPIO40,
+
+ MPUIO2,
+ N15_1610_MPUIO2,
+ MPUIO4,
+ MPUIO5,
+ T20_1610_MPUIO5,
+ W11_1610_MPUIO6,
+ V10_1610_MPUIO7,
+ W11_1610_MPUIO9,
+ V10_1610_MPUIO10,
+ W10_1610_MPUIO11,
+ E20_1610_MPUIO13,
+ U20_1610_MPUIO14,
+ E19_1610_MPUIO15,
+
+ MCBSP2_CLKR,
+ MCBSP2_CLKX,
+ MCBSP2_DR,
+ MCBSP2_DX,
+ MCBSP2_FSR,
+ MCBSP2_FSX,
+
+ MCBSP3_CLKX,
+
+ BALLOUT_V8_ARMIO3,
+ N20_HDQ,
+
+ W8_1610_MMC2_DAT0,
+ V8_1610_MMC2_DAT1,
+ W15_1610_MMC2_DAT2,
+ R10_1610_MMC2_DAT3,
+ Y10_1610_MMC2_CLK,
+ Y8_1610_MMC2_CMD,
+ V9_1610_MMC2_CMDDIR,
+ V5_1610_MMC2_DATDIR0,
+ W19_1610_MMC2_DATDIR1,
+ R18_1610_MMC2_CLKIN,
+
+ M19_1610_ETM_PSTAT0,
+ L15_1610_ETM_PSTAT1,
+ L18_1610_ETM_PSTAT2,
+ L19_1610_ETM_D0,
+ J19_1610_ETM_D6,
+ J18_1610_ETM_D7,
+
+ P20_1610_GPIO4,
+ V9_1610_GPIO7,
+ W8_1610_GPIO9,
+ N20_1610_GPIO11,
+ N19_1610_GPIO13,
+ P10_1610_GPIO22,
+ V5_1610_GPIO24,
+ AA20_1610_GPIO_41,
+ W19_1610_GPIO48,
+ M7_1610_GPIO62,
+ V14_16XX_GPIO37,
+ R9_16XX_GPIO18,
+ L14_16XX_GPIO49,
+
+ V19_1610_UWIRE_SCLK,
+ U18_1610_UWIRE_SDI,
+ W21_1610_UWIRE_SDO,
+ N14_1610_UWIRE_CS0,
+ P15_1610_UWIRE_CS3,
+ N15_1610_UWIRE_CS1,
+
+ U19_1610_SPIF_SCK,
+ U18_1610_SPIF_DIN,
+ P20_1610_SPIF_DIN,
+ W21_1610_SPIF_DOUT,
+ R18_1610_SPIF_DOUT,
+ N14_1610_SPIF_CS0,
+ N15_1610_SPIF_CS1,
+ T19_1610_SPIF_CS2,
+ P15_1610_SPIF_CS3,
+
+ L3_1610_FLASH_CS2B_OE,
+ M8_1610_FLASH_CS2B_WE,
+
+ MMC_CMD,
+ MMC_DAT1,
+ MMC_DAT2,
+ MMC_DAT0,
+ MMC_CLK,
+ MMC_DAT3,
+
+ M15_1710_MMC_CLKI,
+ P19_1710_MMC_CMDDIR,
+ P20_1710_MMC_DATDIR0,
+
+ W9_USB0_TXEN,
+ AA9_USB0_VP,
+ Y5_USB0_RCV,
+ R9_USB0_VM,
+ V6_USB0_TXD,
+ W5_USB0_SE0,
+ V9_USB0_SPEED,
+ V9_USB0_SUSP,
+
+ W9_USB2_TXEN,
+ AA9_USB2_VP,
+ Y5_USB2_RCV,
+ R9_USB2_VM,
+ V6_USB2_TXD,
+ W5_USB2_SE0,
+
+ R13_1610_UART1_TX,
+ V14_16XX_UART1_RX,
+ R14_1610_UART1_CTS,
+ AA15_1610_UART1_RTS,
+ R9_16XX_UART2_RX,
+ L14_16XX_UART3_RX,
+
+ I2C_SCL,
+ I2C_SDA,
+
+ F18_1610_KBC0,
+ D20_1610_KBC1,
+ D19_1610_KBC2,
+ E18_1610_KBC3,
+ C21_1610_KBC4,
+ G18_1610_KBR0,
+ F19_1610_KBR1,
+ H14_1610_KBR2,
+ E20_1610_KBR3,
+ E19_1610_KBR4,
+ N19_1610_KBR5,
+
+ T20_1610_LOW_PWR,
+
+ V5_1710_MCLK_ON,
+ V5_1710_MCLK_OFF,
+ R10_1610_MCLK_ON,
+ R10_1610_MCLK_OFF,
+
+ P11_1610_CF_CD2,
+ R11_1610_CF_IOIS16,
+ V10_1610_CF_IREQ,
+ W10_1610_CF_RESET,
+ W11_1610_CF_CD1,
+};
+
+enum omap24xx_index {
+
+ M19_24XX_I2C1_SCL,
+ L15_24XX_I2C1_SDA,
+ J15_24XX_I2C2_SCL,
+ H19_24XX_I2C2_SDA,
+
+ W19_24XX_SYS_NIRQ,
+
+ W14_24XX_SYS_CLKOUT,
+
+ L3_GPMC_WAIT0,
+ N7_GPMC_WAIT1,
+ M1_GPMC_WAIT2,
+ P1_GPMC_WAIT3,
+
+ Y15_24XX_MCBSP2_CLKX,
+ R14_24XX_MCBSP2_FSX,
+ W15_24XX_MCBSP2_DR,
+ V15_24XX_MCBSP2_DX,
+
+ M21_242X_GPIO11,
+ AA10_242X_GPIO13,
+ AA6_242X_GPIO14,
+ AA4_242X_GPIO15,
+ Y11_242X_GPIO16,
+ AA12_242X_GPIO17,
+ AA8_242X_GPIO58,
+ Y20_24XX_GPIO60,
+ W4__24XX_GPIO74,
+ M15_24XX_GPIO92,
+ V14_24XX_GPIO117,
+
+ V4_242X_GPIO49,
+ W2_242X_GPIO50,
+ U4_242X_GPIO51,
+ V3_242X_GPIO52,
+ V2_242X_GPIO53,
+ V6_242X_GPIO53,
+ T4_242X_GPIO54,
+ Y4_242X_GPIO54,
+ T3_242X_GPIO55,
+ U2_242X_GPIO56,
+
+ AA10_242X_DMAREQ0,
+ AA6_242X_DMAREQ1,
+ E4_242X_DMAREQ2,
+ G4_242X_DMAREQ3,
+ D3_242X_DMAREQ4,
+ E3_242X_DMAREQ5,
+
+ P20_24XX_TSC_IRQ,
+
+ K15_24XX_UART3_TX,
+ K14_24XX_UART3_RX,
+
+ G19_24XX_MMC_CLKO,
+ H18_24XX_MMC_CMD,
+ F20_24XX_MMC_DAT0,
+ H14_24XX_MMC_DAT1,
+ E19_24XX_MMC_DAT2,
+ D19_24XX_MMC_DAT3,
+ F19_24XX_MMC_DAT_DIR0,
+ E20_24XX_MMC_DAT_DIR1,
+ F18_24XX_MMC_DAT_DIR2,
+ E18_24XX_MMC_DAT_DIR3,
+ G18_24XX_MMC_CMD_DIR,
+ H15_24XX_MMC_CLKI,
+
+ T19_24XX_KBR0,
+ R19_24XX_KBR1,
+ V18_24XX_KBR2,
+ M21_24XX_KBR3,
+ E5__24XX_KBR4,
+ M18_24XX_KBR5,
+ R20_24XX_KBC0,
+ M14_24XX_KBC1,
+ H19_24XX_KBC2,
+ V17_24XX_KBC3,
+ P21_24XX_KBC4,
+ L14_24XX_KBC5,
+ N19_24XX_KBC6,
+
+ B3__24XX_KBR5,
+ AA4_24XX_KBC2,
+ B13_24XX_KBC6,
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/omap24xx.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/omap24xx.h
new file mode 100644
index 0000000..37def2f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/omap24xx.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARCH_OMAP24XX_H
+#define __ASM_ARCH_OMAP24XX_H
+
+#define L4_24XX_BASE 0x48000000
+#define L3_24XX_BASE 0x68000000
+
+#define OMAP24XX_IC_BASE (L4_24XX_BASE + 0xfe000)
+#define VA_IC_BASE IO_ADDRESS(OMAP24XX_IC_BASE)
+#define OMAP24XX_IVA_INTC_BASE 0x40000000
+#define IRQ_SIR_IRQ 0x0040
+
+#define OMAP24XX_32KSYNCT_BASE (L4_24XX_BASE + 0x4000)
+#define OMAP24XX_PRCM_BASE (L4_24XX_BASE + 0x8000)
+#define OMAP24XX_SDRC_BASE (L3_24XX_BASE + 0x9000)
+
+#define OMAP242X_CONTROL_STATUS (L4_24XX_BASE + 0x2f8)
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/serial.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/serial.h
new file mode 100644
index 0000000..6ab8613
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/serial.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARCH_SERIAL_H
+#define __ASM_ARCH_SERIAL_H
+
+#define OMAP_MAX_NR_PORTS 3
+#define OMAP1510_BASE_BAUD (12000000/16)
+#define OMAP16XX_BASE_BAUD (48000000/16)
+
+#define is_omap_port(p) ({int __ret = 0;   if (p == IO_ADDRESS(OMAP_UART1_BASE) ||   p == IO_ADDRESS(OMAP_UART2_BASE) ||   p == IO_ADDRESS(OMAP_UART3_BASE))   __ret = 1;   __ret;   })
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/timex.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/timex.h
new file mode 100644
index 0000000..2c9234c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/timex.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARCH_OMAP_TIMEX_H
+#define __ASM_ARCH_OMAP_TIMEX_H
+
+#define CLOCK_TICK_RATE (HZ * 100000UL)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/vmalloc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/vmalloc.h
new file mode 100644
index 0000000..f2b5b44
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/arch/vmalloc.h
@@ -0,0 +1,13 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
+
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/atomic.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/atomic.h
new file mode 100644
index 0000000..6f1921a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/atomic.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_ATOMIC_H
+#define __ASM_ARM_ATOMIC_H
+
+#include <linux/compiler.h>
+
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i) { (i) }
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/auxvec.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/auxvec.h
new file mode 100644
index 0000000..c7e839c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/auxvec.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASMARM_AUXVEC_H
+#define __ASMARM_AUXVEC_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/bitops.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/bitops.h
new file mode 100644
index 0000000..ff76a68
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/bitops.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_BITOPS_H
+#define __ASM_ARM_BITOPS_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/byteorder.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/byteorder.h
new file mode 100644
index 0000000..4da37bf
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/byteorder.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_BYTEORDER_H
+#define __ASM_ARM_BYTEORDER_H
+
+#include <linux/compiler.h>
+#include <asm/types.h>
+
+static inline __attribute_const__ __u32 ___arch__swab32(__u32 x)
+{
+ __u32 t;
+
+#ifndef __thumb__
+ if (!__builtin_constant_p(x)) {
+
+ asm ("eor\t%0, %1, %1, ror #16" : "=r" (t) : "r" (x));
+ } else
+#endif
+ t = x ^ ((x << 16) | (x >> 16));
+
+ x = (x << 24) | (x >> 8);
+ t &= ~0x00FF0000;
+ x ^= (t >> 8);
+
+ return x;
+}
+
+#define __arch__swab32(x) ___arch__swab32(x)
+
+#ifndef __STRICT_ANSI__
+#define __BYTEORDER_HAS_U64__
+#define __SWAB_64_THRU_32__
+#endif
+
+#ifdef __ARMEB__
+#include <linux/byteorder/big_endian.h>
+#else
+#include <linux/byteorder/little_endian.h>
+#endif
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/cache.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/cache.h
new file mode 100644
index 0000000..be26423
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/cache.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASMARM_CACHE_H
+#define __ASMARM_CACHE_H
+
+#define L1_CACHE_SHIFT 5
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/cacheflush.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/cacheflush.h
new file mode 100644
index 0000000..3ffa87a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/cacheflush.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_CACHEFLUSH_H
+#define _ASMARM_CACHEFLUSH_H
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/glue.h>
+#include <asm/shmparam.h>
+
+#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
+
+#undef _CACHE
+#undef MULTI_CACHE
+
+#if !defined(_CACHE) && !defined(MULTI_CACHE)
+#error Unknown cache maintainence model
+#endif
+
+#define PG_dcache_dirty PG_arch_1
+
+struct cpu_cache_fns {
+ void (*flush_kern_all)(void);
+ void (*flush_user_all)(void);
+ void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
+
+ void (*coherent_kern_range)(unsigned long, unsigned long);
+ void (*coherent_user_range)(unsigned long, unsigned long);
+ void (*flush_kern_dcache_page)(void *);
+
+ void (*dma_inv_range)(unsigned long, unsigned long);
+ void (*dma_clean_range)(unsigned long, unsigned long);
+ void (*dma_flush_range)(unsigned long, unsigned long);
+};
+
+#ifdef MULTI_CACHE
+
+#define __cpuc_flush_kern_all cpu_cache.flush_kern_all
+#define __cpuc_flush_user_all cpu_cache.flush_user_all
+#define __cpuc_flush_user_range cpu_cache.flush_user_range
+#define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range
+#define __cpuc_coherent_user_range cpu_cache.coherent_user_range
+#define __cpuc_flush_dcache_page cpu_cache.flush_kern_dcache_page
+
+#define dmac_inv_range cpu_cache.dma_inv_range
+#define dmac_clean_range cpu_cache.dma_clean_range
+#define dmac_flush_range cpu_cache.dma_flush_range
+
+#else
+
+#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
+#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all)
+#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range)
+#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range)
+#define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range)
+#define __cpuc_flush_dcache_page __glue(_CACHE,_flush_kern_dcache_page)
+
+#define dmac_inv_range __glue(_CACHE,_dma_inv_range)
+#define dmac_clean_range __glue(_CACHE,_dma_clean_range)
+#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
+
+#endif
+
+#define flush_cache_vmap(start, end) flush_cache_all()
+#define flush_cache_vunmap(start, end) flush_cache_all()
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len)   do {   memcpy(dst, src, len);   flush_ptrace_access(vma, page, vaddr, dst, len, 1);  } while (0)
+
+#define copy_from_user_page(vma, page, vaddr, dst, src, len)   do {   memcpy(dst, src, len);   } while (0)
+
+#define flush_cache_all() __cpuc_flush_kern_all()
+#define flush_cache_user_range(vma,start,end)   __cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end))
+#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e)
+#define clean_dcache_area(start,size) cpu_dcache_clean_area(start, size)
+
+#define flush_dcache_mmap_lock(mapping)   write_lock_irq(&(mapping)->tree_lock)
+#define flush_dcache_mmap_unlock(mapping)   write_unlock_irq(&(mapping)->tree_lock)
+
+#define flush_icache_user_range(vma,page,addr,len)   flush_dcache_page(page)
+
+#define flush_icache_page(vma,page) do { } while (0)
+
+#define __cacheid_present(val) (val != read_cpuid(CPUID_ID))
+#define __cacheid_vivt(val) ((val & (15 << 25)) != (14 << 25))
+#define __cacheid_vipt(val) ((val & (15 << 25)) == (14 << 25))
+#define __cacheid_vipt_nonaliasing(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25))
+#define __cacheid_vipt_aliasing(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25 | 1 << 23))
+
+#define cache_is_vivt()   ({   unsigned int __val = read_cpuid(CPUID_CACHETYPE);   (!__cacheid_present(__val)) || __cacheid_vivt(__val);   })
+
+#define cache_is_vipt()   ({   unsigned int __val = read_cpuid(CPUID_CACHETYPE);   __cacheid_present(__val) && __cacheid_vipt(__val);   })
+
+#define cache_is_vipt_nonaliasing()   ({   unsigned int __val = read_cpuid(CPUID_CACHETYPE);   __cacheid_present(__val) &&   __cacheid_vipt_nonaliasing(__val);   })
+
+#define cache_is_vipt_aliasing()   ({   unsigned int __val = read_cpuid(CPUID_CACHETYPE);   __cacheid_present(__val) &&   __cacheid_vipt_aliasing(__val);   })
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/cputime.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/cputime.h
new file mode 100644
index 0000000..4a4097f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/cputime.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ARM_CPUTIME_H
+#define __ARM_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/delay.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/delay.h
new file mode 100644
index 0000000..631fd9b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/delay.h
@@ -0,0 +1,22 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_DELAY_H
+#define __ASM_ARM_DELAY_H
+
+#include <asm/param.h>  
+
+#define MAX_UDELAY_MS 2
+
+#define udelay(n)   (__builtin_constant_p(n) ?   ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() :   __const_udelay((n) * ((2199023U*HZ)>>11))) :   __udelay(n))
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/div64.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/div64.h
new file mode 100644
index 0000000..c03a0e4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/div64.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_DIV64
+#define __ASM_ARM_DIV64
+
+#include <asm/system.h>
+
+#ifdef __ARMEB__
+#define __xh "r0"
+#define __xl "r1"
+#else
+#define __xl "r0"
+#define __xh "r1"
+#endif
+
+#define do_div(n,base)  ({   register unsigned int __base asm("r4") = base;   register unsigned long long __n asm("r0") = n;   register unsigned long long __res asm("r2");   register unsigned int __rem asm(__xh);   asm( __asmeq("%0", __xh)   __asmeq("%1", "r2")   __asmeq("%2", "r0")   __asmeq("%3", "r4")   "bl	__do_div64"   : "=r" (__rem), "=r" (__res)   : "r" (__n), "r" (__base)   : "ip", "lr", "cc");   n = __res;   __rem;  })
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/dma-mapping.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/dma-mapping.h
new file mode 100644
index 0000000..7e65009
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/dma-mapping.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef ASMARM_DMA_MAPPING_H
+#define ASMARM_DMA_MAPPING_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/dma.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/dma.h
new file mode 100644
index 0000000..7eeeb78
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/dma.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_DMA_H
+#define __ASM_ARM_DMA_H
+
+typedef unsigned int dmach_t;
+
+#include <linux/spinlock.h>
+#include <asm/system.h>
+#include <asm/scatterlist.h>
+#include <asm/arch/dma.h>
+
+#ifndef MAX_DMA_ADDRESS
+#define MAX_DMA_ADDRESS 0xffffffff
+#endif
+
+typedef unsigned int dmamode_t;
+
+#define DMA_MODE_MASK 3
+
+#define DMA_MODE_READ 0
+#define DMA_MODE_WRITE 1
+#define DMA_MODE_CASCADE 2
+#define DMA_AUTOINIT 4
+
+#define clear_dma_ff(channel)
+
+#define set_dma_addr(channel, addr)   __set_dma_addr(channel, bus_to_virt(addr))
+
+#ifndef NO_DMA
+#define NO_DMA 255
+#endif
+
+#define isa_dma_bridge_buggy (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/domain.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/domain.h
new file mode 100644
index 0000000..973109e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/domain.h
@@ -0,0 +1,32 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_PROC_DOMAIN_H
+#define __ASM_PROC_DOMAIN_H
+
+#define DOMAIN_KERNEL 0
+#define DOMAIN_TABLE 0
+#define DOMAIN_USER 1
+#define DOMAIN_IO 2
+
+#define DOMAIN_NOACCESS 0
+#define DOMAIN_CLIENT 1
+#define DOMAIN_MANAGER 3
+
+#define domain_val(dom,type) ((type) << (2*(dom)))
+
+#ifndef __ASSEMBLY__
+
+#define set_domain(x) do { } while (0)
+#define modify_domain(dom,type) do { } while (0)
+
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/dyntick.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/dyntick.h
new file mode 100644
index 0000000..1f323f2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/dyntick.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_DYNTICK_H
+#define _ASMARM_DYNTICK_H
+
+#include <asm/mach/time.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/elf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/elf.h
new file mode 100644
index 0000000..e9d095e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/elf.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASMARM_ELF_H
+#define __ASMARM_ELF_H
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+#ifdef __KERNEL
+#include <asm/procinfo.h>
+#endif
+
+typedef unsigned long elf_greg_t;
+typedef unsigned long elf_freg_t[3];
+
+#define EM_ARM 40
+#define EF_ARM_APCS26 0x08
+#define EF_ARM_SOFT_FLOAT 0x200
+#define EF_ARM_EABI_MASK 0xFF000000
+
+#define R_ARM_NONE 0
+#define R_ARM_PC24 1
+#define R_ARM_ABS32 2
+#define R_ARM_CALL 28
+#define R_ARM_JUMP24 29
+
+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_fp elf_fpregset_t;
+
+#define elf_check_arch(x) ( ((x)->e_machine == EM_ARM) && (ELF_PROC_OK((x))) )
+
+#define ELF_CLASS ELFCLASS32
+#ifdef __ARMEB__
+#define ELF_DATA ELFDATA2MSB
+#else
+#define ELF_DATA ELFDATA2LSB
+#endif
+#define ELF_ARCH EM_ARM
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE 4096
+
+#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
+
+#define ELF_PLAT_INIT(_r, load_addr) (_r)->ARM_r0 = 0
+
+#define ELF_HWCAP (elf_hwcap)
+
+#define ELF_PLATFORM_SIZE 8
+
+#define ELF_PLATFORM (elf_platform)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/errno.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/errno.h
new file mode 100644
index 0000000..6be7048
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/errno.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ARM_ERRNO_H
+#define _ARM_ERRNO_H
+
+#include <asm-generic/errno.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/fcntl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/fcntl.h
new file mode 100644
index 0000000..42351ea
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/fcntl.h
@@ -0,0 +1,22 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ARM_FCNTL_H
+#define _ARM_FCNTL_H
+
+#define O_DIRECTORY 040000  
+#define O_NOFOLLOW 0100000  
+#define O_DIRECT 0200000  
+#define O_LARGEFILE 0400000
+
+#include <asm-generic/fcntl.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/fpstate.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/fpstate.h
new file mode 100644
index 0000000..b362b14
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/fpstate.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_FPSTATE_H
+#define __ASM_ARM_FPSTATE_H
+
+#ifndef __ASSEMBLY__
+
+struct vfp_hard_struct {
+ __u64 fpregs[16];
+#if __LINUX_ARM_ARCH__ < 6
+ __u32 fpmx_state;
+#endif
+ __u32 fpexc;
+ __u32 fpscr;
+
+ __u32 fpinst;
+ __u32 fpinst2;
+};
+
+union vfp_state {
+ struct vfp_hard_struct hard;
+};
+
+#define FP_HARD_SIZE 35
+
+struct fp_hard_struct {
+ unsigned int save[FP_HARD_SIZE];
+};
+
+#define FP_SOFT_SIZE 35
+
+struct fp_soft_struct {
+ unsigned int save[FP_SOFT_SIZE];
+};
+
+#define IWMMXT_SIZE 0x98
+
+struct iwmmxt_struct {
+ unsigned int save[IWMMXT_SIZE / sizeof(unsigned int)];
+};
+
+union fp_state {
+ struct fp_hard_struct hard;
+ struct fp_soft_struct soft;
+};
+
+#define FP_SIZE (sizeof(union fp_state) / sizeof(int))
+
+struct crunch_state {
+ unsigned int mvdx[16][2];
+ unsigned int mvax[4][3];
+ unsigned int dspsc[2];
+};
+
+#define CRUNCH_SIZE sizeof(struct crunch_state)
+
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/glue.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/glue.h
new file mode 100644
index 0000000..1327b59
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/glue.h
@@ -0,0 +1,11 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/hardirq.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/hardirq.h
new file mode 100644
index 0000000..54207e3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/hardirq.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_HARDIRQ_H
+#define __ASM_HARDIRQ_H
+
+#include <linux/cache.h>
+#include <linux/threads.h>
+#include <asm/irq.h>
+
+typedef struct {
+ unsigned int __softirq_pending;
+ unsigned int local_timer_irqs;
+} ____cacheline_aligned irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>  
+
+#if NR_IRQS > 256
+#define HARDIRQ_BITS 9
+#else
+#define HARDIRQ_BITS 8
+#endif
+
+#if 1 << HARDIRQ_BITS < NR_IRQS
+#error HARDIRQ_BITS is too low!
+#endif
+
+#define __ARCH_IRQ_EXIT_IRQS_DISABLED 1
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/hardware.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/hardware.h
new file mode 100644
index 0000000..0b381d1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/hardware.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_HARDWARE_H
+#define __ASM_HARDWARE_H
+
+#include <asm/arch/hardware.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/hw_irq.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/hw_irq.h
new file mode 100644
index 0000000..a34b390
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/hw_irq.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ARCH_ARM_HW_IRQ_H
+#define _ARCH_ARM_HW_IRQ_H
+
+#include <asm/mach/irq.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ide.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ide.h
new file mode 100644
index 0000000..f52d5ca
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ide.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASMARM_IDE_H
+#define __ASMARM_IDE_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/io.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/io.h
new file mode 100644
index 0000000..6794022
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/io.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_IO_H
+#define __ASM_ARM_IO_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ioctl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ioctl.h
new file mode 100644
index 0000000..6e446b6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ioctl.h
@@ -0,0 +1,12 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/ioctl.h>
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ioctls.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ioctls.h
new file mode 100644
index 0000000..9df82bc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ioctls.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_IOCTLS_H
+#define __ASM_ARM_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+#define TCGETS 0x5401
+#define TCSETS 0x5402
+#define TCSETSW 0x5403
+#define TCSETSF 0x5404
+#define TCGETA 0x5405
+#define TCSETA 0x5406
+#define TCSETAW 0x5407
+#define TCSETAF 0x5408
+#define TCSBRK 0x5409
+#define TCXONC 0x540A
+#define TCFLSH 0x540B
+#define TIOCEXCL 0x540C
+#define TIOCNXCL 0x540D
+#define TIOCSCTTY 0x540E
+#define TIOCGPGRP 0x540F
+#define TIOCSPGRP 0x5410
+#define TIOCOUTQ 0x5411
+#define TIOCSTI 0x5412
+#define TIOCGWINSZ 0x5413
+#define TIOCSWINSZ 0x5414
+#define TIOCMGET 0x5415
+#define TIOCMBIS 0x5416
+#define TIOCMBIC 0x5417
+#define TIOCMSET 0x5418
+#define TIOCGSOFTCAR 0x5419
+#define TIOCSSOFTCAR 0x541A
+#define FIONREAD 0x541B
+#define TIOCINQ FIONREAD
+#define TIOCLINUX 0x541C
+#define TIOCCONS 0x541D
+#define TIOCGSERIAL 0x541E
+#define TIOCSSERIAL 0x541F
+#define TIOCPKT 0x5420
+#define FIONBIO 0x5421
+#define TIOCNOTTY 0x5422
+#define TIOCSETD 0x5423
+#define TIOCGETD 0x5424
+#define TCSBRKP 0x5425  
+#define TIOCSBRK 0x5427  
+#define TIOCCBRK 0x5428  
+#define TIOCGSID 0x5429  
+#define TIOCGPTN _IOR('T',0x30, unsigned int)  
+#define TIOCSPTLCK _IOW('T',0x31, int)  
+
+#define FIONCLEX 0x5450  
+#define FIOCLEX 0x5451
+#define FIOASYNC 0x5452
+#define TIOCSERCONFIG 0x5453
+#define TIOCSERGWILD 0x5454
+#define TIOCSERSWILD 0x5455
+#define TIOCGLCKTRMIOS 0x5456
+#define TIOCSLCKTRMIOS 0x5457
+#define TIOCSERGSTRUCT 0x5458  
+#define TIOCSERGETLSR 0x5459  
+#define TIOCSERGETMULTI 0x545A  
+#define TIOCSERSETMULTI 0x545B  
+
+#define TIOCMIWAIT 0x545C  
+#define TIOCGICOUNT 0x545D  
+#define FIOQSIZE 0x545E
+
+#define TIOCPKT_DATA 0
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_NOSTOP 16
+#define TIOCPKT_DOSTOP 32
+
+#define TIOCSER_TEMT 0x01  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ipcbuf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ipcbuf.h
new file mode 100644
index 0000000..0e47507
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ipcbuf.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASMARM_IPCBUF_H
+#define __ASMARM_IPCBUF_H
+
+struct ipc64_perm
+{
+ __kernel_key_t key;
+ __kernel_uid32_t uid;
+ __kernel_gid32_t gid;
+ __kernel_uid32_t cuid;
+ __kernel_gid32_t cgid;
+ __kernel_mode_t mode;
+ unsigned short __pad1;
+ unsigned short seq;
+ unsigned short __pad2;
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/irq.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/irq.h
new file mode 100644
index 0000000..2085a21
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/irq.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_IRQ_H
+#define __ASM_ARM_IRQ_H
+
+#include <asm/arch/irqs.h>
+
+#ifndef irq_canonicalize
+#define irq_canonicalize(i) (i)
+#endif
+
+#ifndef NR_IRQS
+#define NR_IRQS 128
+#endif
+
+#ifndef NO_IRQ
+#define NO_IRQ ((unsigned int)(-1))
+#endif
+
+struct irqaction;
+
+#define __IRQT_FALEDGE IRQ_TYPE_EDGE_FALLING
+#define __IRQT_RISEDGE IRQ_TYPE_EDGE_RISING
+#define __IRQT_LOWLVL IRQ_TYPE_LEVEL_LOW
+#define __IRQT_HIGHLVL IRQ_TYPE_LEVEL_HIGH
+
+#define IRQT_NOEDGE (0)
+#define IRQT_RISING (__IRQT_RISEDGE)
+#define IRQT_FALLING (__IRQT_FALEDGE)
+#define IRQT_BOTHEDGE (__IRQT_RISEDGE|__IRQT_FALEDGE)
+#define IRQT_LOW (__IRQT_LOWLVL)
+#define IRQT_HIGH (__IRQT_HIGHLVL)
+#define IRQT_PROBE IRQ_TYPE_PROBE
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/linkage.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/linkage.h
new file mode 100644
index 0000000..1fb628e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/linkage.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#define __ALIGN .align 0
+#define __ALIGN_STR ".align 0"
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/local.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/local.h
new file mode 100644
index 0000000..10d6a60
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/local.h
@@ -0,0 +1,12 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm-generic/local.h>
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/locks.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/locks.h
new file mode 100644
index 0000000..f48485c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/locks.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_PROC_LOCKS_H
+#define __ASM_PROC_LOCKS_H
+
+#if __LINUX_ARM_ARCH__ >= 6
+
+#define __down_op(ptr,fail)   ({   __asm__ __volatile__(   "@ down_op\n"  "1:	ldrex	lr, [%0]\n"  "	sub	lr, lr, %1\n"  "	strex	ip, lr, [%0]\n"  "	teq	ip, #0\n"  "	bne	1b\n"  "	teq	lr, #0\n"  "	movmi	ip, %0\n"  "	blmi	" #fail   :   : "r" (ptr), "I" (1)   : "ip", "lr", "cc");   smp_mb();   })
+
+#define __down_op_ret(ptr,fail)   ({   unsigned int ret;   __asm__ __volatile__(   "@ down_op_ret\n"  "1:	ldrex	lr, [%1]\n"  "	sub	lr, lr, %2\n"  "	strex	ip, lr, [%1]\n"  "	teq	ip, #0\n"  "	bne	1b\n"  "	teq	lr, #0\n"  "	movmi	ip, %1\n"  "	movpl	ip, #0\n"  "	blmi	" #fail "\n"  "	mov	%0, ip"   : "=&r" (ret)   : "r" (ptr), "I" (1)   : "ip", "lr", "cc");   smp_mb();   ret;   })
+
+#define __up_op(ptr,wake)   ({   smp_mb();   __asm__ __volatile__(   "@ up_op\n"  "1:	ldrex	lr, [%0]\n"  "	add	lr, lr, %1\n"  "	strex	ip, lr, [%0]\n"  "	teq	ip, #0\n"  "	bne	1b\n"  "	cmp	lr, #0\n"  "	movle	ip, %0\n"  "	blle	" #wake   :   : "r" (ptr), "I" (1)   : "ip", "lr", "cc");   })
+
+#define RW_LOCK_BIAS 0x01000000
+#define RW_LOCK_BIAS_STR "0x01000000"
+
+#define __down_op_write(ptr,fail)   ({   __asm__ __volatile__(   "@ down_op_write\n"  "1:	ldrex	lr, [%0]\n"  "	sub	lr, lr, %1\n"  "	strex	ip, lr, [%0]\n"  "	teq	ip, #0\n"  "	bne	1b\n"  "	teq	lr, #0\n"  "	movne	ip, %0\n"  "	blne	" #fail   :   : "r" (ptr), "I" (RW_LOCK_BIAS)   : "ip", "lr", "cc");   smp_mb();   })
+
+#define __up_op_write(ptr,wake)   ({   smp_mb();   __asm__ __volatile__(   "@ up_op_write\n"  "1:	ldrex	lr, [%0]\n"  "	adds	lr, lr, %1\n"  "	strex	ip, lr, [%0]\n"  "	teq	ip, #0\n"  "	bne	1b\n"  "	movcs	ip, %0\n"  "	blcs	" #wake   :   : "r" (ptr), "I" (RW_LOCK_BIAS)   : "ip", "lr", "cc");   })
+
+#define __down_op_read(ptr,fail)   __down_op(ptr, fail)
+
+#define __up_op_read(ptr,wake)   ({   smp_mb();   __asm__ __volatile__(   "@ up_op_read\n"  "1:	ldrex	lr, [%0]\n"  "	add	lr, lr, %1\n"  "	strex	ip, lr, [%0]\n"  "	teq	ip, #0\n"  "	bne	1b\n"  "	teq	lr, #0\n"  "	moveq	ip, %0\n"  "	bleq	" #wake   :   : "r" (ptr), "I" (1)   : "ip", "lr", "cc");   })
+
+#else
+
+#define __down_op(ptr,fail)   ({   __asm__ __volatile__(   "@ down_op\n"  "	mrs	ip, cpsr\n"  "	orr	lr, ip, #128\n"  "	msr	cpsr_c, lr\n"  "	ldr	lr, [%0]\n"  "	subs	lr, lr, %1\n"  "	str	lr, [%0]\n"  "	msr	cpsr_c, ip\n"  "	movmi	ip, %0\n"  "	blmi	" #fail   :   : "r" (ptr), "I" (1)   : "ip", "lr", "cc");   smp_mb();   })
+
+#define __down_op_ret(ptr,fail)   ({   unsigned int ret;   __asm__ __volatile__(   "@ down_op_ret\n"  "	mrs	ip, cpsr\n"  "	orr	lr, ip, #128\n"  "	msr	cpsr_c, lr\n"  "	ldr	lr, [%1]\n"  "	subs	lr, lr, %2\n"  "	str	lr, [%1]\n"  "	msr	cpsr_c, ip\n"  "	movmi	ip, %1\n"  "	movpl	ip, #0\n"  "	blmi	" #fail "\n"  "	mov	%0, ip"   : "=&r" (ret)   : "r" (ptr), "I" (1)   : "ip", "lr", "cc");   smp_mb();   ret;   })
+
+#define __up_op(ptr,wake)   ({   smp_mb();   __asm__ __volatile__(   "@ up_op\n"  "	mrs	ip, cpsr\n"  "	orr	lr, ip, #128\n"  "	msr	cpsr_c, lr\n"  "	ldr	lr, [%0]\n"  "	adds	lr, lr, %1\n"  "	str	lr, [%0]\n"  "	msr	cpsr_c, ip\n"  "	movle	ip, %0\n"  "	blle	" #wake   :   : "r" (ptr), "I" (1)   : "ip", "lr", "cc");   })
+
+#define RW_LOCK_BIAS 0x01000000
+#define RW_LOCK_BIAS_STR "0x01000000"
+
+#define __down_op_write(ptr,fail)   ({   __asm__ __volatile__(   "@ down_op_write\n"  "	mrs	ip, cpsr\n"  "	orr	lr, ip, #128\n"  "	msr	cpsr_c, lr\n"  "	ldr	lr, [%0]\n"  "	subs	lr, lr, %1\n"  "	str	lr, [%0]\n"  "	msr	cpsr_c, ip\n"  "	movne	ip, %0\n"  "	blne	" #fail   :   : "r" (ptr), "I" (RW_LOCK_BIAS)   : "ip", "lr", "cc");   smp_mb();   })
+
+#define __up_op_write(ptr,wake)   ({   __asm__ __volatile__(   "@ up_op_write\n"  "	mrs	ip, cpsr\n"  "	orr	lr, ip, #128\n"  "	msr	cpsr_c, lr\n"  "	ldr	lr, [%0]\n"  "	adds	lr, lr, %1\n"  "	str	lr, [%0]\n"  "	msr	cpsr_c, ip\n"  "	movcs	ip, %0\n"  "	blcs	" #wake   :   : "r" (ptr), "I" (RW_LOCK_BIAS)   : "ip", "lr", "cc");   smp_mb();   })
+
+#define __down_op_read(ptr,fail)   __down_op(ptr, fail)
+
+#define __up_op_read(ptr,wake)   ({   smp_mb();   __asm__ __volatile__(   "@ up_op_read\n"  "	mrs	ip, cpsr\n"  "	orr	lr, ip, #128\n"  "	msr	cpsr_c, lr\n"  "	ldr	lr, [%0]\n"  "	adds	lr, lr, %1\n"  "	str	lr, [%0]\n"  "	msr	cpsr_c, ip\n"  "	moveq	ip, %0\n"  "	bleq	" #wake   :   : "r" (ptr), "I" (1)   : "ip", "lr", "cc");   })
+
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/mc146818rtc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/mc146818rtc.h
new file mode 100644
index 0000000..5a86724
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/mc146818rtc.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_MC146818RTC_H
+#define _ASM_MC146818RTC_H
+
+#include <asm/arch/irqs.h>
+#include <asm/io.h>
+
+#ifndef RTC_PORT
+#define RTC_PORT(x) (0x70 + (x))
+#define RTC_ALWAYS_BCD 1  
+#endif
+
+#define CMOS_READ(addr) ({  outb_p((addr),RTC_PORT(0));  inb_p(RTC_PORT(1));  })
+#define CMOS_WRITE(val, addr) ({  outb_p((addr),RTC_PORT(0));  outb_p((val),RTC_PORT(1));  })
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/memory.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/memory.h
new file mode 100644
index 0000000..c1137a7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/memory.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_MEMORY_H
+#define __ASM_ARM_MEMORY_H
+
+#ifndef __ASSEMBLY__
+#define UL(x) (x##UL)
+#else
+#define UL(x) (x)
+#endif
+
+#include <linux/compiler.h>
+#include <asm/arch/memory.h>
+#include <asm/sizes.h>
+
+#ifndef TASK_SIZE
+#define TASK_SIZE (CONFIG_DRAM_SIZE)
+#endif
+
+#ifndef TASK_UNMAPPED_BASE
+#define TASK_UNMAPPED_BASE UL(0x00000000)
+#endif
+
+#ifndef PHYS_OFFSET
+#define PHYS_OFFSET (CONFIG_DRAM_BASE)
+#endif
+
+#ifndef END_MEM
+#define END_MEM (CONFIG_DRAM_BASE + CONFIG_DRAM_SIZE)
+#endif
+
+#ifndef PAGE_OFFSET
+#define PAGE_OFFSET (PHYS_OFFSET)
+#endif
+
+#define MODULE_END (END_MEM)
+#define MODULE_START (PHYS_OFFSET)
+
+#ifndef CONSISTENT_DMA_SIZE
+#define CONSISTENT_DMA_SIZE SZ_2M
+#endif
+
+#ifndef __virt_to_phys
+#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
+#endif
+
+#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT)
+#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
+
+#ifndef __ASSEMBLY__
+
+#ifndef ISA_DMA_THRESHOLD
+#define ISA_DMA_THRESHOLD (0xffffffffULL)
+#endif
+
+#ifndef arch_adjust_zones
+#define arch_adjust_zones(node,size,holes) do { } while (0)
+#endif
+
+#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT)
+
+#define __pa(x) __virt_to_phys((unsigned long)(x))
+#define __va(x) ((void *)__phys_to_virt((unsigned long)(x)))
+#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
+#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET
+#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))
+#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
+#define PHYS_TO_NID(addr) (0)
+#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
+#ifndef __arch_page_to_dma
+#define page_to_dma(dev, page) ((dma_addr_t)__virt_to_bus((unsigned long)page_address(page)))
+#define dma_to_virt(dev, addr) ((void *)__bus_to_virt(addr))
+#define virt_to_dma(dev, addr) ((dma_addr_t)__virt_to_bus((unsigned long)(addr)))
+#else
+#define page_to_dma(dev, page) (__arch_page_to_dma(dev, page))
+#define dma_to_virt(dev, addr) (__arch_dma_to_virt(dev, addr))
+#define virt_to_dma(dev, addr) (__arch_virt_to_dma(dev, addr))
+#endif
+#ifndef arch_is_coherent
+#define arch_is_coherent() 0
+#endif
+#endif
+#include <asm-generic/memory_model.h>
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/mman.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/mman.h
new file mode 100644
index 0000000..8f71d1b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/mman.h
@@ -0,0 +1,28 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ARM_MMAN_H__
+#define __ARM_MMAN_H__
+
+#include <asm-generic/mman.h>
+
+#define MAP_GROWSDOWN 0x0100  
+#define MAP_DENYWRITE 0x0800  
+#define MAP_EXECUTABLE 0x1000  
+#define MAP_LOCKED 0x2000  
+#define MAP_NORESERVE 0x4000  
+#define MAP_POPULATE 0x8000  
+#define MAP_NONBLOCK 0x10000  
+
+#define MCL_CURRENT 1  
+#define MCL_FUTURE 2  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/module.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/module.h
new file mode 100644
index 0000000..68b806a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/module.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_ARM_MODULE_H
+#define _ASM_ARM_MODULE_H
+
+struct mod_arch_specific
+{
+ int foo;
+};
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+
+#define MODULE_ARCH_VERMAGIC "ARMv" __stringify(__LINUX_ARM_ARCH__) " "
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/msgbuf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/msgbuf.h
new file mode 100644
index 0000000..84d614c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/msgbuf.h
@@ -0,0 +1,32 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_MSGBUF_H
+#define _ASMARM_MSGBUF_H
+
+struct msqid64_ds {
+ struct ipc64_perm msg_perm;
+ __kernel_time_t msg_stime;
+ unsigned long __unused1;
+ __kernel_time_t msg_rtime;
+ unsigned long __unused2;
+ __kernel_time_t msg_ctime;
+ unsigned long __unused3;
+ unsigned long msg_cbytes;
+ unsigned long msg_qnum;
+ unsigned long msg_qbytes;
+ __kernel_pid_t msg_lspid;
+ __kernel_pid_t msg_lrpid;
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/mtd-xip.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/mtd-xip.h
new file mode 100644
index 0000000..6c53f6f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/mtd-xip.h
@@ -0,0 +1,20 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ARM_MTD_XIP_H__
+#define __ARM_MTD_XIP_H__
+
+#include <asm/hardware.h>
+#include <asm/arch/mtd-xip.h>
+
+#define xip_iprefetch() do { asm volatile (".rep 8; nop; .endr"); } while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/page.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/page.h
new file mode 100644
index 0000000..f980343
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/page.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_PAGE_H
+#define _ASMARM_PAGE_H
+
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/param.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/param.h
new file mode 100644
index 0000000..6814fe3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/param.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_PARAM_H
+#define __ASM_PARAM_H
+
+#define HZ 100
+
+#define EXEC_PAGESIZE 4096
+
+#ifndef NOGROUP
+#define NOGROUP (-1)
+#endif
+
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/percpu.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/percpu.h
new file mode 100644
index 0000000..2500345
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/percpu.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ARM_PERCPU
+#define __ARM_PERCPU
+
+#include <asm-generic/percpu.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/pgalloc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/pgalloc.h
new file mode 100644
index 0000000..5d45e65
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/pgalloc.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_PGALLOC_H
+#define _ASMARM_PGALLOC_H
+
+#include <asm/domain.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/processor.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+
+#define check_pgt_cache() do { } while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/pgtable-hwdef.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/pgtable-hwdef.h
new file mode 100644
index 0000000..47e8675
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/pgtable-hwdef.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_PGTABLE_HWDEF_H
+#define _ASMARM_PGTABLE_HWDEF_H
+
+#define PMD_TYPE_MASK (3 << 0)
+#define PMD_TYPE_FAULT (0 << 0)
+#define PMD_TYPE_TABLE (1 << 0)
+#define PMD_TYPE_SECT (2 << 0)
+#define PMD_BIT4 (1 << 4)
+#define PMD_DOMAIN(x) ((x) << 5)
+#define PMD_PROTECTION (1 << 9)  
+
+#define PMD_SECT_BUFFERABLE (1 << 2)
+#define PMD_SECT_CACHEABLE (1 << 3)
+#define PMD_SECT_XN (1 << 4)  
+#define PMD_SECT_AP_WRITE (1 << 10)
+#define PMD_SECT_AP_READ (1 << 11)
+#define PMD_SECT_TEX(x) ((x) << 12)  
+#define PMD_SECT_APX (1 << 15)  
+#define PMD_SECT_S (1 << 16)  
+#define PMD_SECT_nG (1 << 17)  
+#define PMD_SECT_SUPER (1 << 18)  
+
+#define PMD_SECT_UNCACHED (0)
+#define PMD_SECT_BUFFERED (PMD_SECT_BUFFERABLE)
+#define PMD_SECT_WT (PMD_SECT_CACHEABLE)
+#define PMD_SECT_WB (PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
+#define PMD_SECT_MINICACHE (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE)
+#define PMD_SECT_WBWA (PMD_SECT_TEX(1) | PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE)
+#define PMD_SECT_NONSHARED_DEV (PMD_SECT_TEX(2))
+
+#define PTE_TYPE_MASK (3 << 0)
+#define PTE_TYPE_FAULT (0 << 0)
+#define PTE_TYPE_LARGE (1 << 0)
+#define PTE_TYPE_SMALL (2 << 0)
+#define PTE_TYPE_EXT (3 << 0)  
+#define PTE_BUFFERABLE (1 << 2)
+#define PTE_CACHEABLE (1 << 3)
+
+#define PTE_EXT_XN (1 << 0)  
+#define PTE_EXT_AP_MASK (3 << 4)
+#define PTE_EXT_AP0 (1 << 4)
+#define PTE_EXT_AP1 (2 << 4)
+#define PTE_EXT_AP_UNO_SRO (0 << 4)
+#define PTE_EXT_AP_UNO_SRW (PTE_EXT_AP0)
+#define PTE_EXT_AP_URO_SRW (PTE_EXT_AP1)
+#define PTE_EXT_AP_URW_SRW (PTE_EXT_AP1|PTE_EXT_AP0)
+#define PTE_EXT_TEX(x) ((x) << 6)  
+#define PTE_EXT_APX (1 << 9)  
+#define PTE_EXT_COHERENT (1 << 9)  
+#define PTE_EXT_SHARED (1 << 10)  
+#define PTE_EXT_NG (1 << 11)  
+
+#define PTE_SMALL_AP_MASK (0xff << 4)
+#define PTE_SMALL_AP_UNO_SRO (0x00 << 4)
+#define PTE_SMALL_AP_UNO_SRW (0x55 << 4)
+#define PTE_SMALL_AP_URO_SRW (0xaa << 4)
+#define PTE_SMALL_AP_URW_SRW (0xff << 4)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/pgtable.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/pgtable.h
new file mode 100644
index 0000000..cbac611
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/pgtable.h
@@ -0,0 +1,20 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_PGTABLE_H
+#define _ASMARM_PGTABLE_H
+
+#include <asm-generic/4level-fixup.h>
+#include <asm/proc-fns.h>
+
+#include "pgtable-nommu.h"
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/poll.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/poll.h
new file mode 100644
index 0000000..c5b80a5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/poll.h
@@ -0,0 +1,36 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASMARM_POLL_H
+#define __ASMARM_POLL_H
+
+#define POLLIN 0x0001
+#define POLLPRI 0x0002
+#define POLLOUT 0x0004
+#define POLLERR 0x0008
+#define POLLHUP 0x0010
+#define POLLNVAL 0x0020
+
+#define POLLRDNORM 0x0040
+#define POLLRDBAND 0x0080
+#define POLLWRNORM 0x0100
+#define POLLWRBAND 0x0200
+#define POLLMSG 0x0400
+#define POLLREMOVE 0x1000
+#define POLLRDHUP 0x2000
+
+struct pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/posix_types.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/posix_types.h
new file mode 100644
index 0000000..bc85217
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/posix_types.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ARCH_ARM_POSIX_TYPES_H
+#define __ARCH_ARM_POSIX_TYPES_H
+
+typedef unsigned long __kernel_ino_t;
+typedef unsigned short __kernel_mode_t;
+typedef unsigned short __kernel_nlink_t;
+typedef long __kernel_off_t;
+typedef int __kernel_pid_t;
+typedef unsigned short __kernel_ipc_pid_t;
+typedef unsigned short __kernel_uid_t;
+typedef unsigned short __kernel_gid_t;
+typedef unsigned int __kernel_size_t;
+typedef int __kernel_ssize_t;
+typedef int __kernel_ptrdiff_t;
+typedef long __kernel_time_t;
+typedef long __kernel_suseconds_t;
+typedef long __kernel_clock_t;
+typedef int __kernel_timer_t;
+typedef int __kernel_clockid_t;
+typedef int __kernel_daddr_t;
+typedef char * __kernel_caddr_t;
+typedef unsigned short __kernel_uid16_t;
+typedef unsigned short __kernel_gid16_t;
+typedef unsigned int __kernel_uid32_t;
+typedef unsigned int __kernel_gid32_t;
+
+typedef unsigned short __kernel_old_uid_t;
+typedef unsigned short __kernel_old_gid_t;
+typedef unsigned short __kernel_old_dev_t;
+
+#ifdef __GNUC__
+typedef long long __kernel_loff_t;
+#endif
+
+typedef struct {
+#ifdef __USE_ALL
+ int val[2];
+#else
+ int __val[2];
+#endif
+} __kernel_fsid_t;
+
+#if !defined(__GLIBC__) || __GLIBC__ < 2
+
+#undef __FD_SET
+#define __FD_SET(fd, fdsetp)   (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] |= (1<<((fd) & 31)))
+
+#undef __FD_CLR
+#define __FD_CLR(fd, fdsetp)   (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] &= ~(1<<((fd) & 31)))
+
+#undef __FD_ISSET
+#define __FD_ISSET(fd, fdsetp)   ((((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] & (1<<((fd) & 31))) != 0)
+
+#undef __FD_ZERO
+#define __FD_ZERO(fdsetp)   (memset (fdsetp, 0, sizeof (*(fd_set *)(fdsetp))))
+
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/proc-fns.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/proc-fns.h
new file mode 100644
index 0000000..4a560d0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/proc-fns.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_PROCFNS_H
+#define __ASM_PROCFNS_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/processor.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/processor.h
new file mode 100644
index 0000000..f93cbc1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/processor.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_PROCESSOR_H
+#define __ASM_ARM_PROCESSOR_H
+
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/procinfo.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/procinfo.h
new file mode 100644
index 0000000..d774e0b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/procinfo.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_PROCINFO_H
+#define __ASM_PROCINFO_H
+
+#ifndef __ASSEMBLY__
+
+struct cpu_tlb_fns;
+struct cpu_user_fns;
+struct cpu_cache_fns;
+struct processor;
+
+struct proc_info_list {
+ unsigned int cpu_val;
+ unsigned int cpu_mask;
+ unsigned long __cpu_mm_mmu_flags;
+ unsigned long __cpu_io_mmu_flags;
+ unsigned long __cpu_flush;
+ const char *arch_name;
+ const char *elf_name;
+ unsigned int elf_hwcap;
+ const char *cpu_name;
+ struct processor *proc;
+ struct cpu_tlb_fns *tlb;
+ struct cpu_user_fns *user;
+ struct cpu_cache_fns *cache;
+};
+
+#endif
+
+#define HWCAP_SWP 1
+#define HWCAP_HALF 2
+#define HWCAP_THUMB 4
+#define HWCAP_26BIT 8  
+#define HWCAP_FAST_MULT 16
+#define HWCAP_FPA 32
+#define HWCAP_VFP 64
+#define HWCAP_EDSP 128
+#define HWCAP_JAVA 256
+#define HWCAP_IWMMXT 512
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ptrace.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ptrace.h
new file mode 100644
index 0000000..c6dfea1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/ptrace.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_PTRACE_H
+#define __ASM_ARM_PTRACE_H
+
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+
+#define PTRACE_GETWMMXREGS 18
+#define PTRACE_SETWMMXREGS 19
+
+#define PTRACE_OLDSETOPTIONS 21
+
+#define PTRACE_GET_THREAD_AREA 22
+
+#define PTRACE_SET_SYSCALL 23
+
+#define PTRACE_GETCRUNCHREGS 25
+#define PTRACE_SETCRUNCHREGS 26
+
+#define USR26_MODE 0x00000000
+#define FIQ26_MODE 0x00000001
+#define IRQ26_MODE 0x00000002
+#define SVC26_MODE 0x00000003
+#define USR_MODE 0x00000010
+#define FIQ_MODE 0x00000011
+#define IRQ_MODE 0x00000012
+#define SVC_MODE 0x00000013
+#define ABT_MODE 0x00000017
+#define UND_MODE 0x0000001b
+#define SYSTEM_MODE 0x0000001f
+#define MODE32_BIT 0x00000010
+#define MODE_MASK 0x0000001f
+#define PSR_T_BIT 0x00000020
+#define PSR_F_BIT 0x00000040
+#define PSR_I_BIT 0x00000080
+#define PSR_J_BIT 0x01000000
+#define PSR_Q_BIT 0x08000000
+#define PSR_V_BIT 0x10000000
+#define PSR_C_BIT 0x20000000
+#define PSR_Z_BIT 0x40000000
+#define PSR_N_BIT 0x80000000
+#define PCMASK 0
+
+#define PSR_f 0xff000000  
+#define PSR_s 0x00ff0000  
+#define PSR_x 0x0000ff00  
+#define PSR_c 0x000000ff  
+
+#ifndef __ASSEMBLY__
+
+struct pt_regs {
+ long uregs[18];
+};
+
+#define ARM_cpsr uregs[16]
+#define ARM_pc uregs[15]
+#define ARM_lr uregs[14]
+#define ARM_sp uregs[13]
+#define ARM_ip uregs[12]
+#define ARM_fp uregs[11]
+#define ARM_r10 uregs[10]
+#define ARM_r9 uregs[9]
+#define ARM_r8 uregs[8]
+#define ARM_r7 uregs[7]
+#define ARM_r6 uregs[6]
+#define ARM_r5 uregs[5]
+#define ARM_r4 uregs[4]
+#define ARM_r3 uregs[3]
+#define ARM_r2 uregs[2]
+#define ARM_r1 uregs[1]
+#define ARM_r0 uregs[0]
+#define ARM_ORIG_r0 uregs[17]
+
+#define pc_pointer(v)   ((v) & ~PCMASK)
+
+#define instruction_pointer(regs)   (pc_pointer((regs)->ARM_pc))
+
+#define profile_pc(regs) instruction_pointer(regs)
+
+#endif
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/resource.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/resource.h
new file mode 100644
index 0000000..7546dd4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/resource.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ARM_RESOURCE_H
+#define _ARM_RESOURCE_H
+
+#include <asm-generic/resource.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/scatterlist.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/scatterlist.h
new file mode 100644
index 0000000..a2c06ca
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/scatterlist.h
@@ -0,0 +1,28 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_SCATTERLIST_H
+#define _ASMARM_SCATTERLIST_H
+
+#include <asm/memory.h>
+#include <asm/types.h>
+
+struct scatterlist {
+ struct page *page;
+ unsigned int offset;
+ dma_addr_t dma_address;
+ unsigned int length;
+};
+
+#define sg_dma_address(sg) ((sg)->dma_address)
+#define sg_dma_len(sg) ((sg)->length)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/semaphore.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/semaphore.h
new file mode 100644
index 0000000..7c5618a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/semaphore.h
@@ -0,0 +1,36 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_SEMAPHORE_H
+#define __ASM_ARM_SEMAPHORE_H
+
+#include <linux/linkage.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/rwsem.h>
+
+#include <asm/atomic.h>
+#include <asm/locks.h>
+
+struct semaphore {
+ atomic_t count;
+ int sleepers;
+ wait_queue_head_t wait;
+};
+
+#define __SEMAPHORE_INIT(name, cnt)  {   .count = ATOMIC_INIT(cnt),   .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait),  }
+
+#define __DECLARE_SEMAPHORE_GENERIC(name,count)   struct semaphore name = __SEMAPHORE_INIT(name,count)
+
+#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
+#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/sembuf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/sembuf.h
new file mode 100644
index 0000000..a2f5dd0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/sembuf.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_SEMBUF_H
+#define _ASMARM_SEMBUF_H
+
+struct semid64_ds {
+ struct ipc64_perm sem_perm;
+ __kernel_time_t sem_otime;
+ unsigned long __unused1;
+ __kernel_time_t sem_ctime;
+ unsigned long __unused2;
+ unsigned long sem_nsems;
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/shmbuf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/shmbuf.h
new file mode 100644
index 0000000..1d4d78c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/shmbuf.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_SHMBUF_H
+#define _ASMARM_SHMBUF_H
+
+struct shmid64_ds {
+ struct ipc64_perm shm_perm;
+ size_t shm_segsz;
+ __kernel_time_t shm_atime;
+ unsigned long __unused1;
+ __kernel_time_t shm_dtime;
+ unsigned long __unused2;
+ __kernel_time_t shm_ctime;
+ unsigned long __unused3;
+ __kernel_pid_t shm_cpid;
+ __kernel_pid_t shm_lpid;
+ unsigned long shm_nattch;
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+struct shminfo64 {
+ unsigned long shmmax;
+ unsigned long shmmin;
+ unsigned long shmmni;
+ unsigned long shmseg;
+ unsigned long shmall;
+ unsigned long __unused1;
+ unsigned long __unused2;
+ unsigned long __unused3;
+ unsigned long __unused4;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/shmparam.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/shmparam.h
new file mode 100644
index 0000000..ea53a8d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/shmparam.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_SHMPARAM_H
+#define _ASMARM_SHMPARAM_H
+
+#define SHMLBA (4 * PAGE_SIZE)  
+
+#define __ARCH_FORCE_SHMLBA
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/sigcontext.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/sigcontext.h
new file mode 100644
index 0000000..3c4fcf3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/sigcontext.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_SIGCONTEXT_H
+#define _ASMARM_SIGCONTEXT_H
+
+struct sigcontext {
+ unsigned long trap_no;
+ unsigned long error_code;
+ unsigned long oldmask;
+ unsigned long arm_r0;
+ unsigned long arm_r1;
+ unsigned long arm_r2;
+ unsigned long arm_r3;
+ unsigned long arm_r4;
+ unsigned long arm_r5;
+ unsigned long arm_r6;
+ unsigned long arm_r7;
+ unsigned long arm_r8;
+ unsigned long arm_r9;
+ unsigned long arm_r10;
+ unsigned long arm_fp;
+ unsigned long arm_ip;
+ unsigned long arm_sp;
+ unsigned long arm_lr;
+ unsigned long arm_pc;
+ unsigned long arm_cpsr;
+ unsigned long fault_address;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/siginfo.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/siginfo.h
new file mode 100644
index 0000000..225685e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/siginfo.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_SIGINFO_H
+#define _ASMARM_SIGINFO_H
+
+#include <asm-generic/siginfo.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/signal.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/signal.h
new file mode 100644
index 0000000..212d9f1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/signal.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_SIGNAL_H
+#define _ASMARM_SIGNAL_H
+
+#include <linux/types.h>
+
+struct siginfo;
+
+#define NSIG 32
+typedef unsigned long sigset_t;
+
+#define SIGHUP 1
+#define SIGINT 2
+#define SIGQUIT 3
+#define SIGILL 4
+#define SIGTRAP 5
+#define SIGABRT 6
+#define SIGIOT 6
+#define SIGBUS 7
+#define SIGFPE 8
+#define SIGKILL 9
+#define SIGUSR1 10
+#define SIGSEGV 11
+#define SIGUSR2 12
+#define SIGPIPE 13
+#define SIGALRM 14
+#define SIGTERM 15
+#define SIGSTKFLT 16
+#define SIGCHLD 17
+#define SIGCONT 18
+#define SIGSTOP 19
+#define SIGTSTP 20
+#define SIGTTIN 21
+#define SIGTTOU 22
+#define SIGURG 23
+#define SIGXCPU 24
+#define SIGXFSZ 25
+#define SIGVTALRM 26
+#define SIGPROF 27
+#define SIGWINCH 28
+#define SIGIO 29
+#define SIGPOLL SIGIO
+
+#define SIGPWR 30
+#define SIGSYS 31
+#define SIGUNUSED 31
+
+#define SIGRTMIN 32
+#define SIGRTMAX _NSIG
+
+#define SIGSWI 32
+
+#define SA_NOCLDSTOP 0x00000001
+#define SA_NOCLDWAIT 0x00000002
+#define SA_SIGINFO 0x00000004
+#define SA_THIRTYTWO 0x02000000
+#define SA_RESTORER 0x04000000
+#define SA_ONSTACK 0x08000000
+#define SA_RESTART 0x10000000
+#define SA_NODEFER 0x40000000
+#define SA_RESETHAND 0x80000000
+
+#define SA_NOMASK SA_NODEFER
+#define SA_ONESHOT SA_RESETHAND
+
+#define SS_ONSTACK 1
+#define SS_DISABLE 2
+
+#define MINSIGSTKSZ 2048
+#define SIGSTKSZ 8192
+
+#include <asm-generic/signal.h>
+
+struct sigaction {
+ union {
+ __sighandler_t _sa_handler;
+ void (*_sa_sigaction)(int, struct siginfo *, void *);
+ } _u;
+ sigset_t sa_mask;
+ unsigned long sa_flags;
+ void (*sa_restorer)(void);
+};
+
+#define sa_handler _u._sa_handler
+#define sa_sigaction _u._sa_sigaction
+
+typedef struct sigaltstack {
+ void __user *ss_sp;
+ int ss_flags;
+ size_t ss_size;
+} stack_t;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/sizes.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/sizes.h
new file mode 100644
index 0000000..90c1c71
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/sizes.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __sizes_h
+#define __sizes_h 1
+
+#define SZ_1K 0x00000400
+#define SZ_4K 0x00001000
+#define SZ_8K 0x00002000
+#define SZ_16K 0x00004000
+#define SZ_64K 0x00010000
+#define SZ_128K 0x00020000
+#define SZ_256K 0x00040000
+#define SZ_512K 0x00080000
+
+#define SZ_1M 0x00100000
+#define SZ_2M 0x00200000
+#define SZ_4M 0x00400000
+#define SZ_8M 0x00800000
+#define SZ_16M 0x01000000
+#define SZ_32M 0x02000000
+#define SZ_64M 0x04000000
+#define SZ_128M 0x08000000
+#define SZ_256M 0x10000000
+#define SZ_512M 0x20000000
+
+#define SZ_1G 0x40000000
+#define SZ_2G 0x80000000
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/smp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/smp.h
new file mode 100644
index 0000000..e6c1e41
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/smp.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_SMP_H
+#define __ASM_ARM_SMP_H
+
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/thread_info.h>
+
+#include <asm/arch/smp.h>
+
+#error "<asm-arm/smp.h> included in non-SMP build"
+
+#define raw_smp_processor_id() (current_thread_info()->cpu)
+
+#define PROC_CHANGE_PENALTY 15
+
+struct seq_file;
+
+struct secondary_data {
+ unsigned long pgdir;
+ void *stack;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/socket.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/socket.h
new file mode 100644
index 0000000..1f0050a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/socket.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_SOCKET_H
+#define _ASMARM_SOCKET_H
+
+#include <asm/sockios.h>
+
+#define SOL_SOCKET 1
+
+#define SO_DEBUG 1
+#define SO_REUSEADDR 2
+#define SO_TYPE 3
+#define SO_ERROR 4
+#define SO_DONTROUTE 5
+#define SO_BROADCAST 6
+#define SO_SNDBUF 7
+#define SO_RCVBUF 8
+#define SO_SNDBUFFORCE 32
+#define SO_RCVBUFFORCE 33
+#define SO_KEEPALIVE 9
+#define SO_OOBINLINE 10
+#define SO_NO_CHECK 11
+#define SO_PRIORITY 12
+#define SO_LINGER 13
+#define SO_BSDCOMPAT 14
+
+#define SO_PASSCRED 16
+#define SO_PEERCRED 17
+#define SO_RCVLOWAT 18
+#define SO_SNDLOWAT 19
+#define SO_RCVTIMEO 20
+#define SO_SNDTIMEO 21
+
+#define SO_SECURITY_AUTHENTICATION 22
+#define SO_SECURITY_ENCRYPTION_TRANSPORT 23
+#define SO_SECURITY_ENCRYPTION_NETWORK 24
+
+#define SO_BINDTODEVICE 25
+
+#define SO_ATTACH_FILTER 26
+#define SO_DETACH_FILTER 27
+
+#define SO_PEERNAME 28
+#define SO_TIMESTAMP 29
+#define SCM_TIMESTAMP SO_TIMESTAMP
+
+#define SO_ACCEPTCONN 30
+
+#define SO_PEERSEC 31
+#define SO_PASSSEC 34
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/sockios.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/sockios.h
new file mode 100644
index 0000000..cab86b8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/sockios.h
@@ -0,0 +1,22 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ARCH_ARM_SOCKIOS_H
+#define __ARCH_ARM_SOCKIOS_H
+
+#define FIOSETOWN 0x8901
+#define SIOCSPGRP 0x8902
+#define FIOGETOWN 0x8903
+#define SIOCGPGRP 0x8904
+#define SIOCATMARK 0x8905
+#define SIOCGSTAMP 0x8906  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/spinlock.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/spinlock.h
new file mode 100644
index 0000000..3ae2173
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/spinlock.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_SPINLOCK_H
+#define __ASM_SPINLOCK_H
+
+#if __LINUX_ARM_ARCH__ < 6
+#error SMP not supported on pre-ARMv6 CPUs
+#endif
+
+#define __raw_spin_is_locked(x) ((x)->lock != 0)
+#define __raw_spin_unlock_wait(lock)   do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0)
+
+#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock)
+
+#define rwlock_is_locked(x) (*((volatile unsigned int *)(x)) != 0)
+#define __raw_write_can_lock(x) ((x)->lock == 0x80000000)
+#define __raw_read_can_lock(x) ((x)->lock < 0x80000000)
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/spinlock_types.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/spinlock_types.h
new file mode 100644
index 0000000..ee77f20
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/spinlock_types.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_SPINLOCK_TYPES_H
+#define __ASM_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+#error "please don't include this file directly"
+#endif
+
+typedef struct {
+ volatile unsigned int lock;
+} raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { 0 }
+
+typedef struct {
+ volatile unsigned int lock;
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { 0 }
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/stat.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/stat.h
new file mode 100644
index 0000000..49b85f9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/stat.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_STAT_H
+#define _ASMARM_STAT_H
+
+struct __old_kernel_stat {
+ unsigned short st_dev;
+ unsigned short st_ino;
+ unsigned short st_mode;
+ unsigned short st_nlink;
+ unsigned short st_uid;
+ unsigned short st_gid;
+ unsigned short st_rdev;
+ unsigned long st_size;
+ unsigned long st_atime;
+ unsigned long st_mtime;
+ unsigned long st_ctime;
+};
+
+#define STAT_HAVE_NSEC 
+
+struct stat {
+#ifdef __ARMEB__
+ unsigned short st_dev;
+ unsigned short __pad1;
+#else
+ unsigned long st_dev;
+#endif
+ unsigned long st_ino;
+ unsigned short st_mode;
+ unsigned short st_nlink;
+ unsigned short st_uid;
+ unsigned short st_gid;
+#ifdef __ARMEB__
+ unsigned short st_rdev;
+ unsigned short __pad2;
+#else
+ unsigned long st_rdev;
+#endif
+ unsigned long st_size;
+ unsigned long st_blksize;
+ unsigned long st_blocks;
+ unsigned long st_atime;
+ unsigned long st_atime_nsec;
+ unsigned long st_mtime;
+ unsigned long st_mtime_nsec;
+ unsigned long st_ctime;
+ unsigned long st_ctime_nsec;
+ unsigned long __unused4;
+ unsigned long __unused5;
+};
+
+struct stat64 {
+ unsigned long long st_dev;
+ unsigned char __pad0[4];
+
+#define STAT64_HAS_BROKEN_ST_INO 1
+ unsigned long __st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ unsigned long st_uid;
+ unsigned long st_gid;
+
+ unsigned long long st_rdev;
+ unsigned char __pad3[4];
+
+ long long st_size;
+ unsigned long st_blksize;
+ unsigned long long st_blocks;
+
+ unsigned long st_atime;
+ unsigned long st_atime_nsec;
+
+ unsigned long st_mtime;
+ unsigned long st_mtime_nsec;
+
+ unsigned long st_ctime;
+ unsigned long st_ctime_nsec;
+
+ unsigned long long st_ino;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/statfs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/statfs.h
new file mode 100644
index 0000000..7963eab
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/statfs.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_STATFS_H
+#define _ASMARM_STATFS_H
+
+struct statfs {
+ __u32 f_type;
+ __u32 f_bsize;
+ __u32 f_blocks;
+ __u32 f_bfree;
+ __u32 f_bavail;
+ __u32 f_files;
+ __u32 f_ffree;
+ __kernel_fsid_t f_fsid;
+ __u32 f_namelen;
+ __u32 f_frsize;
+ __u32 f_spare[5];
+};
+
+struct statfs64 {
+ __u32 f_type;
+ __u32 f_bsize;
+ __u64 f_blocks;
+ __u64 f_bfree;
+ __u64 f_bavail;
+ __u64 f_files;
+ __u64 f_ffree;
+ __kernel_fsid_t f_fsid;
+ __u32 f_namelen;
+ __u32 f_frsize;
+ __u32 f_spare[5];
+} __attribute__ ((packed,aligned(4)));
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/suspend.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/suspend.h
new file mode 100644
index 0000000..156c171
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/suspend.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_SUSPEND_H
+#define _ASMARM_SUSPEND_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/system.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/system.h
new file mode 100644
index 0000000..8e85039
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/system.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_SYSTEM_H
+#define __ASM_ARM_SYSTEM_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/termbits.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/termbits.h
new file mode 100644
index 0000000..640bd27
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/termbits.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_TERMBITS_H
+#define __ASM_ARM_TERMBITS_H
+
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
+
+#define NCCS 19
+struct termios {
+ tcflag_t c_iflag;
+ tcflag_t c_oflag;
+ tcflag_t c_cflag;
+ tcflag_t c_lflag;
+ cc_t c_line;
+ cc_t c_cc[NCCS];
+};
+
+#define VINTR 0
+#define VQUIT 1
+#define VERASE 2
+#define VKILL 3
+#define VEOF 4
+#define VTIME 5
+#define VMIN 6
+#define VSWTC 7
+#define VSTART 8
+#define VSTOP 9
+#define VSUSP 10
+#define VEOL 11
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE 14
+#define VLNEXT 15
+#define VEOL2 16
+
+#define IGNBRK 0000001
+#define BRKINT 0000002
+#define IGNPAR 0000004
+#define PARMRK 0000010
+#define INPCK 0000020
+#define ISTRIP 0000040
+#define INLCR 0000100
+#define IGNCR 0000200
+#define ICRNL 0000400
+#define IUCLC 0001000
+#define IXON 0002000
+#define IXANY 0004000
+#define IXOFF 0010000
+#define IMAXBEL 0020000
+#define IUTF8 0040000
+
+#define OPOST 0000001
+#define OLCUC 0000002
+#define ONLCR 0000004
+#define OCRNL 0000010
+#define ONOCR 0000020
+#define ONLRET 0000040
+#define OFILL 0000100
+#define OFDEL 0000200
+#define NLDLY 0000400
+#define NL0 0000000
+#define NL1 0000400
+#define CRDLY 0003000
+#define CR0 0000000
+#define CR1 0001000
+#define CR2 0002000
+#define CR3 0003000
+#define TABDLY 0014000
+#define TAB0 0000000
+#define TAB1 0004000
+#define TAB2 0010000
+#define TAB3 0014000
+#define XTABS 0014000
+#define BSDLY 0020000
+#define BS0 0000000
+#define BS1 0020000
+#define VTDLY 0040000
+#define VT0 0000000
+#define VT1 0040000
+#define FFDLY 0100000
+#define FF0 0000000
+#define FF1 0100000
+
+#define CBAUD 0010017
+#define B0 0000000  
+#define B50 0000001
+#define B75 0000002
+#define B110 0000003
+#define B134 0000004
+#define B150 0000005
+#define B200 0000006
+#define B300 0000007
+#define B600 0000010
+#define B1200 0000011
+#define B1800 0000012
+#define B2400 0000013
+#define B4800 0000014
+#define B9600 0000015
+#define B19200 0000016
+#define B38400 0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CSIZE 0000060
+#define CS5 0000000
+#define CS6 0000020
+#define CS7 0000040
+#define CS8 0000060
+#define CSTOPB 0000100
+#define CREAD 0000200
+#define PARENB 0000400
+#define PARODD 0001000
+#define HUPCL 0002000
+#define CLOCAL 0004000
+#define CBAUDEX 0010000
+#define B57600 0010001
+#define B115200 0010002
+#define B230400 0010003
+#define B460800 0010004
+#define B500000 0010005
+#define B576000 0010006
+#define B921600 0010007
+#define B1000000 0010010
+#define B1152000 0010011
+#define B1500000 0010012
+#define B2000000 0010013
+#define B2500000 0010014
+#define B3000000 0010015
+#define B3500000 0010016
+#define B4000000 0010017
+#define CIBAUD 002003600000  
+#define CMSPAR 010000000000  
+#define CRTSCTS 020000000000  
+
+#define ISIG 0000001
+#define ICANON 0000002
+#define XCASE 0000004
+#define ECHO 0000010
+#define ECHOE 0000020
+#define ECHOK 0000040
+#define ECHONL 0000100
+#define NOFLSH 0000200
+#define TOSTOP 0000400
+#define ECHOCTL 0001000
+#define ECHOPRT 0002000
+#define ECHOKE 0004000
+#define FLUSHO 0010000
+#define PENDIN 0040000
+#define IEXTEN 0100000
+
+#define TCOOFF 0
+#define TCOON 1
+#define TCIOFF 2
+#define TCION 3
+
+#define TCIFLUSH 0
+#define TCOFLUSH 1
+#define TCIOFLUSH 2
+
+#define TCSANOW 0
+#define TCSADRAIN 1
+#define TCSAFLUSH 2
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/termios.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/termios.h
new file mode 100644
index 0000000..ba43ac2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/termios.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_TERMIOS_H
+#define __ASM_ARM_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+ unsigned short ws_row;
+ unsigned short ws_col;
+ unsigned short ws_xpixel;
+ unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+ unsigned short c_iflag;
+ unsigned short c_oflag;
+ unsigned short c_cflag;
+ unsigned short c_lflag;
+ unsigned char c_line;
+ unsigned char c_cc[NCC];
+};
+
+#define TIOCM_LE 0x001
+#define TIOCM_DTR 0x002
+#define TIOCM_RTS 0x004
+#define TIOCM_ST 0x008
+#define TIOCM_SR 0x010
+#define TIOCM_CTS 0x020
+#define TIOCM_CAR 0x040
+#define TIOCM_RNG 0x080
+#define TIOCM_DSR 0x100
+#define TIOCM_CD TIOCM_CAR
+#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
+
+#define N_TTY 0
+#define N_SLIP 1
+#define N_MOUSE 2
+#define N_PPP 3
+#define N_STRIP 4
+#define N_AX25 5
+#define N_X25 6  
+#define N_6PACK 7
+#define N_MASC 8  
+#define N_R3964 9  
+#define N_PROFIBUS_FDL 10  
+#define N_IRDA 11  
+#define N_SMSBLOCK 12  
+#define N_HDLC 13  
+#define N_SYNC_PPP 14
+#define N_HCI 15  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/thread_info.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/thread_info.h
new file mode 100644
index 0000000..a30d2dc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/thread_info.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_THREAD_INFO_H
+#define __ASM_ARM_THREAD_INFO_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/timex.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/timex.h
new file mode 100644
index 0000000..110c471
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/timex.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_TIMEX_H
+#define _ASMARM_TIMEX_H
+
+#include <asm/arch/timex.h>
+
+typedef unsigned long cycles_t;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/tlbflush.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/tlbflush.h
new file mode 100644
index 0000000..70a23dc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/tlbflush.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_TLBFLUSH_H
+#define _ASMARM_TLBFLUSH_H
+
+#define tlb_flush(tlb) ((void) tlb)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/topology.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/topology.h
new file mode 100644
index 0000000..9eccfd4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/topology.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_ARM_TOPOLOGY_H
+#define _ASM_ARM_TOPOLOGY_H
+
+#include <asm-generic/topology.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/types.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/types.h
new file mode 100644
index 0000000..ec60f10
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/types.h
@@ -0,0 +1,36 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_TYPES_H
+#define __ASM_ARM_TYPES_H
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+#endif
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/uaccess.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/uaccess.h
new file mode 100644
index 0000000..21fc3f2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/uaccess.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASMARM_UACCESS_H
+#define _ASMARM_UACCESS_H
+
+#include <linux/sched.h>
+#include <asm/errno.h>
+#include <asm/memory.h>
+#include <asm/domain.h>
+#include <asm/system.h>
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+struct exception_table_entry
+{
+ unsigned long insn, fixup;
+};
+
+#define KERNEL_DS 0x00000000
+#define get_ds() (KERNEL_DS)
+
+#define USER_DS KERNEL_DS
+
+#define segment_eq(a,b) (1)
+#define __addr_ok(addr) (1)
+#define __range_ok(addr,size) (0)
+#define get_fs() (KERNEL_DS)
+
+#define get_user(x,p) __get_user(x,p)
+#define put_user(x,p) __put_user(x,p)
+#define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
+#define __get_user(x,ptr)  ({   long __gu_err = 0;   __get_user_err((x),(ptr),__gu_err);   __gu_err;  })
+#define __get_user_error(x,ptr,err)  ({   __get_user_err((x),(ptr),err);   (void) 0;  })
+#define __get_user_err(x,ptr,err)  do {   unsigned long __gu_addr = (unsigned long)(ptr);   unsigned long __gu_val;   __chk_user_ptr(ptr);   switch (sizeof(*(ptr))) {   case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break;   case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break;   case 4: __get_user_asm_word(__gu_val,__gu_addr,err); break;   default: (__gu_val) = __get_user_bad();   }   (x) = (__typeof__(*(ptr)))__gu_val;  } while (0)
+#define __get_user_asm_byte(x,addr,err)   __asm__ __volatile__(   "1:	ldrbt	%1,[%2],#0\n"   "2:\n"   "	.section .fixup,\"ax\"\n"   "	.align	2\n"   "3:	mov	%0, %3\n"   "	mov	%1, #0\n"   "	b	2b\n"   "	.previous\n"   "	.section __ex_table,\"a\"\n"   "	.align	3\n"   "	.long	1b, 3b\n"   "	.previous"   : "+r" (err), "=&r" (x)   : "r" (addr), "i" (-EFAULT)   : "cc")
+#ifndef __ARMEB__
+#define __get_user_asm_half(x,__gu_addr,err)  ({   unsigned long __b1, __b2;   __get_user_asm_byte(__b1, __gu_addr, err);   __get_user_asm_byte(__b2, __gu_addr + 1, err);   (x) = __b1 | (__b2 << 8);  })
+#else
+#define __get_user_asm_half(x,__gu_addr,err)  ({   unsigned long __b1, __b2;   __get_user_asm_byte(__b1, __gu_addr, err);   __get_user_asm_byte(__b2, __gu_addr + 1, err);   (x) = (__b1 << 8) | __b2;  })
+#endif
+#define __get_user_asm_word(x,addr,err)   __asm__ __volatile__(   "1:	ldrt	%1,[%2],#0\n"   "2:\n"   "	.section .fixup,\"ax\"\n"   "	.align	2\n"   "3:	mov	%0, %3\n"   "	mov	%1, #0\n"   "	b	2b\n"   "	.previous\n"   "	.section __ex_table,\"a\"\n"   "	.align	3\n"   "	.long	1b, 3b\n"   "	.previous"   : "+r" (err), "=&r" (x)   : "r" (addr), "i" (-EFAULT)   : "cc")
+#define __put_user(x,ptr)  ({   long __pu_err = 0;   __put_user_err((x),(ptr),__pu_err);   __pu_err;  })
+#define __put_user_error(x,ptr,err)  ({   __put_user_err((x),(ptr),err);   (void) 0;  })
+#define __put_user_err(x,ptr,err)  do {   unsigned long __pu_addr = (unsigned long)(ptr);   __typeof__(*(ptr)) __pu_val = (x);   __chk_user_ptr(ptr);   switch (sizeof(*(ptr))) {   case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break;   case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break;   case 4: __put_user_asm_word(__pu_val,__pu_addr,err); break;   case 8: __put_user_asm_dword(__pu_val,__pu_addr,err); break;   default: __put_user_bad();   }  } while (0)
+#define __put_user_asm_byte(x,__pu_addr,err)   __asm__ __volatile__(   "1:	strbt	%1,[%2],#0\n"   "2:\n"   "	.section .fixup,\"ax\"\n"   "	.align	2\n"   "3:	mov	%0, %3\n"   "	b	2b\n"   "	.previous\n"   "	.section __ex_table,\"a\"\n"   "	.align	3\n"   "	.long	1b, 3b\n"   "	.previous"   : "+r" (err)   : "r" (x), "r" (__pu_addr), "i" (-EFAULT)   : "cc")
+#ifndef __ARMEB__
+#define __put_user_asm_half(x,__pu_addr,err)  ({   unsigned long __temp = (unsigned long)(x);   __put_user_asm_byte(__temp, __pu_addr, err);   __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err);  })
+#else
+#define __put_user_asm_half(x,__pu_addr,err)  ({   unsigned long __temp = (unsigned long)(x);   __put_user_asm_byte(__temp >> 8, __pu_addr, err);   __put_user_asm_byte(__temp, __pu_addr + 1, err);  })
+#endif
+#define __put_user_asm_word(x,__pu_addr,err)   __asm__ __volatile__(   "1:	strt	%1,[%2],#0\n"   "2:\n"   "	.section .fixup,\"ax\"\n"   "	.align	2\n"   "3:	mov	%0, %3\n"   "	b	2b\n"   "	.previous\n"   "	.section __ex_table,\"a\"\n"   "	.align	3\n"   "	.long	1b, 3b\n"   "	.previous"   : "+r" (err)   : "r" (x), "r" (__pu_addr), "i" (-EFAULT)   : "cc")
+#ifndef __ARMEB__
+#define __reg_oper0 "%R2"
+#define __reg_oper1 "%Q2"
+#else
+#define __reg_oper0 "%Q2"
+#define __reg_oper1 "%R2"
+#endif
+#define __put_user_asm_dword(x,__pu_addr,err)   __asm__ __volatile__(   "1:	strt	" __reg_oper1 ", [%1], #4\n"   "2:	strt	" __reg_oper0 ", [%1], #0\n"   "3:\n"   "	.section .fixup,\"ax\"\n"   "	.align	2\n"   "4:	mov	%0, %3\n"   "	b	3b\n"   "	.previous\n"   "	.section __ex_table,\"a\"\n"   "	.align	3\n"   "	.long	1b, 4b\n"   "	.long	2b, 4b\n"   "	.previous"   : "+r" (err), "+r" (__pu_addr)   : "r" (x), "i" (-EFAULT)   : "cc")
+#define __copy_from_user(to,from,n) (memcpy(to, (void __force *)from, n), 0)
+#define __copy_to_user(to,from,n) (memcpy((void __force *)to, from, n), 0)
+#define __clear_user(addr,n) (memset((void __force *)addr, 0, n), 0)
+
+#define __copy_to_user_inatomic __copy_to_user
+#define __copy_from_user_inatomic __copy_from_user
+#define strlen_user(s) strnlen_user(s, ~0UL >> 1)
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/unaligned.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/unaligned.h
new file mode 100644
index 0000000..8b9b096
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/unaligned.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_UNALIGNED_H
+#define __ASM_ARM_UNALIGNED_H
+
+#include <asm/types.h>
+
+#define __get_unaligned_2_le(__p)   (__p[0] | __p[1] << 8)
+
+#define __get_unaligned_2_be(__p)   (__p[0] << 8 | __p[1])
+
+#define __get_unaligned_4_le(__p)   (__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24)
+
+#define __get_unaligned_4_be(__p)   (__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3])
+
+#define __get_unaligned_le(ptr)   ({   __typeof__(*(ptr)) __v;   __u8 *__p = (__u8 *)(ptr);   switch (sizeof(*(ptr))) {   case 1: __v = *(ptr); break;   case 2: __v = __get_unaligned_2_le(__p); break;   case 4: __v = __get_unaligned_4_le(__p); break;   case 8: {   unsigned int __v1, __v2;   __v2 = __get_unaligned_4_le((__p+4));   __v1 = __get_unaligned_4_le(__p);   __v = ((unsigned long long)__v2 << 32 | __v1);   }   break;   default: __v = __bug_unaligned_x(__p); break;   }   __v;   })
+
+#define __get_unaligned_be(ptr)   ({   __typeof__(*(ptr)) __v;   __u8 *__p = (__u8 *)(ptr);   switch (sizeof(*(ptr))) {   case 1: __v = *(ptr); break;   case 2: __v = __get_unaligned_2_be(__p); break;   case 4: __v = __get_unaligned_4_be(__p); break;   case 8: {   unsigned int __v1, __v2;   __v2 = __get_unaligned_4_be(__p);   __v1 = __get_unaligned_4_be((__p+4));   __v = ((unsigned long long)__v2 << 32 | __v1);   }   break;   default: __v = __bug_unaligned_x(__p); break;   }   __v;   })
+
+#define __put_unaligned_le(val,ptr)   ({   switch (sizeof(*(ptr))) {   case 1:   *(ptr) = (val);   break;   case 2: __put_unaligned_2_le((val),(__u8 *)(ptr));   break;   case 4: __put_unaligned_4_le((val),(__u8 *)(ptr));   break;   case 8: __put_unaligned_8_le((val),(__u8 *)(ptr));   break;   default: __bug_unaligned_x(ptr);   break;   }   (void) 0;   })
+#define __put_unaligned_be(val,ptr)   ({   switch (sizeof(*(ptr))) {   case 1:   *(ptr) = (val);   break;   case 2: __put_unaligned_2_be((val),(__u8 *)(ptr));   break;   case 4: __put_unaligned_4_be((val),(__u8 *)(ptr));   break;   case 8: __put_unaligned_8_be((val),(__u8 *)(ptr));   break;   default: __bug_unaligned_x(ptr);   break;   }   (void) 0;   })
+#ifndef __ARMEB__
+#define get_unaligned __get_unaligned_le
+#define put_unaligned __put_unaligned_le
+#else
+#define get_unaligned __get_unaligned_be
+#define put_unaligned __put_unaligned_be
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/unistd.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/unistd.h
new file mode 100644
index 0000000..9a30ddc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/unistd.h
@@ -0,0 +1,359 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_ARM_UNISTD_H
+#define __ASM_ARM_UNISTD_H
+
+#define __NR_OABI_SYSCALL_BASE 0x900000
+
+#if defined(__thumb__) || defined(__ARM_EABI__)
+#define __NR_SYSCALL_BASE 0
+#else
+#define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE
+#endif
+
+#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0)
+#define __NR_exit (__NR_SYSCALL_BASE+ 1)
+#define __NR_fork (__NR_SYSCALL_BASE+ 2)
+#define __NR_read (__NR_SYSCALL_BASE+ 3)
+#define __NR_write (__NR_SYSCALL_BASE+ 4)
+#define __NR_open (__NR_SYSCALL_BASE+ 5)
+#define __NR_close (__NR_SYSCALL_BASE+ 6)
+
+#define __NR_creat (__NR_SYSCALL_BASE+ 8)
+#define __NR_link (__NR_SYSCALL_BASE+ 9)
+#define __NR_unlink (__NR_SYSCALL_BASE+ 10)
+#define __NR_execve (__NR_SYSCALL_BASE+ 11)
+#define __NR_chdir (__NR_SYSCALL_BASE+ 12)
+#define __NR_time (__NR_SYSCALL_BASE+ 13)
+#define __NR_mknod (__NR_SYSCALL_BASE+ 14)
+#define __NR_chmod (__NR_SYSCALL_BASE+ 15)
+#define __NR_lchown (__NR_SYSCALL_BASE+ 16)
+
+#define __NR_lseek (__NR_SYSCALL_BASE+ 19)
+#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
+#define __NR_mount (__NR_SYSCALL_BASE+ 21)
+#define __NR_umount (__NR_SYSCALL_BASE+ 22)
+#define __NR_setuid (__NR_SYSCALL_BASE+ 23)
+#define __NR_getuid (__NR_SYSCALL_BASE+ 24)
+#define __NR_stime (__NR_SYSCALL_BASE+ 25)
+#define __NR_ptrace (__NR_SYSCALL_BASE+ 26)
+#define __NR_alarm (__NR_SYSCALL_BASE+ 27)
+
+#define __NR_pause (__NR_SYSCALL_BASE+ 29)
+#define __NR_utime (__NR_SYSCALL_BASE+ 30)
+
+#define __NR_access (__NR_SYSCALL_BASE+ 33)
+#define __NR_nice (__NR_SYSCALL_BASE+ 34)
+
+#define __NR_sync (__NR_SYSCALL_BASE+ 36)
+#define __NR_kill (__NR_SYSCALL_BASE+ 37)
+#define __NR_rename (__NR_SYSCALL_BASE+ 38)
+#define __NR_mkdir (__NR_SYSCALL_BASE+ 39)
+#define __NR_rmdir (__NR_SYSCALL_BASE+ 40)
+#define __NR_dup (__NR_SYSCALL_BASE+ 41)
+#define __NR_pipe (__NR_SYSCALL_BASE+ 42)
+#define __NR_times (__NR_SYSCALL_BASE+ 43)
+
+#define __NR_brk (__NR_SYSCALL_BASE+ 45)
+#define __NR_setgid (__NR_SYSCALL_BASE+ 46)
+#define __NR_getgid (__NR_SYSCALL_BASE+ 47)
+
+#define __NR_geteuid (__NR_SYSCALL_BASE+ 49)
+#define __NR_getegid (__NR_SYSCALL_BASE+ 50)
+#define __NR_acct (__NR_SYSCALL_BASE+ 51)
+#define __NR_umount2 (__NR_SYSCALL_BASE+ 52)
+
+#define __NR_ioctl (__NR_SYSCALL_BASE+ 54)
+#define __NR_fcntl (__NR_SYSCALL_BASE+ 55)
+
+#define __NR_setpgid (__NR_SYSCALL_BASE+ 57)
+
+#define __NR_umask (__NR_SYSCALL_BASE+ 60)
+#define __NR_chroot (__NR_SYSCALL_BASE+ 61)
+#define __NR_ustat (__NR_SYSCALL_BASE+ 62)
+#define __NR_dup2 (__NR_SYSCALL_BASE+ 63)
+#define __NR_getppid (__NR_SYSCALL_BASE+ 64)
+#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65)
+#define __NR_setsid (__NR_SYSCALL_BASE+ 66)
+#define __NR_sigaction (__NR_SYSCALL_BASE+ 67)
+
+#define __NR_setreuid (__NR_SYSCALL_BASE+ 70)
+#define __NR_setregid (__NR_SYSCALL_BASE+ 71)
+#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72)
+#define __NR_sigpending (__NR_SYSCALL_BASE+ 73)
+#define __NR_sethostname (__NR_SYSCALL_BASE+ 74)
+#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75)
+#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76)  
+#define __NR_getrusage (__NR_SYSCALL_BASE+ 77)
+#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78)
+#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79)
+#define __NR_getgroups (__NR_SYSCALL_BASE+ 80)
+#define __NR_setgroups (__NR_SYSCALL_BASE+ 81)
+#define __NR_select (__NR_SYSCALL_BASE+ 82)
+#define __NR_symlink (__NR_SYSCALL_BASE+ 83)
+
+#define __NR_readlink (__NR_SYSCALL_BASE+ 85)
+#define __NR_uselib (__NR_SYSCALL_BASE+ 86)
+#define __NR_swapon (__NR_SYSCALL_BASE+ 87)
+#define __NR_reboot (__NR_SYSCALL_BASE+ 88)
+#define __NR_readdir (__NR_SYSCALL_BASE+ 89)
+#define __NR_mmap (__NR_SYSCALL_BASE+ 90)
+#define __NR_munmap (__NR_SYSCALL_BASE+ 91)
+#define __NR_truncate (__NR_SYSCALL_BASE+ 92)
+#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93)
+#define __NR_fchmod (__NR_SYSCALL_BASE+ 94)
+#define __NR_fchown (__NR_SYSCALL_BASE+ 95)
+#define __NR_getpriority (__NR_SYSCALL_BASE+ 96)
+#define __NR_setpriority (__NR_SYSCALL_BASE+ 97)
+
+#define __NR_statfs (__NR_SYSCALL_BASE+ 99)
+#define __NR_fstatfs (__NR_SYSCALL_BASE+100)
+
+#define __NR_socketcall (__NR_SYSCALL_BASE+102)
+#define __NR_syslog (__NR_SYSCALL_BASE+103)
+#define __NR_setitimer (__NR_SYSCALL_BASE+104)
+#define __NR_getitimer (__NR_SYSCALL_BASE+105)
+#define __NR_stat (__NR_SYSCALL_BASE+106)
+#define __NR_lstat (__NR_SYSCALL_BASE+107)
+#define __NR_fstat (__NR_SYSCALL_BASE+108)
+
+#define __NR_vhangup (__NR_SYSCALL_BASE+111)
+
+#define __NR_syscall (__NR_SYSCALL_BASE+113)  
+#define __NR_wait4 (__NR_SYSCALL_BASE+114)
+#define __NR_swapoff (__NR_SYSCALL_BASE+115)
+#define __NR_sysinfo (__NR_SYSCALL_BASE+116)
+#define __NR_ipc (__NR_SYSCALL_BASE+117)
+#define __NR_fsync (__NR_SYSCALL_BASE+118)
+#define __NR_sigreturn (__NR_SYSCALL_BASE+119)
+#define __NR_clone (__NR_SYSCALL_BASE+120)
+#define __NR_setdomainname (__NR_SYSCALL_BASE+121)
+#define __NR_uname (__NR_SYSCALL_BASE+122)
+
+#define __NR_adjtimex (__NR_SYSCALL_BASE+124)
+#define __NR_mprotect (__NR_SYSCALL_BASE+125)
+#define __NR_sigprocmask (__NR_SYSCALL_BASE+126)
+
+#define __NR_init_module (__NR_SYSCALL_BASE+128)
+#define __NR_delete_module (__NR_SYSCALL_BASE+129)
+
+#define __NR_quotactl (__NR_SYSCALL_BASE+131)
+#define __NR_getpgid (__NR_SYSCALL_BASE+132)
+#define __NR_fchdir (__NR_SYSCALL_BASE+133)
+#define __NR_bdflush (__NR_SYSCALL_BASE+134)
+#define __NR_sysfs (__NR_SYSCALL_BASE+135)
+#define __NR_personality (__NR_SYSCALL_BASE+136)
+
+#define __NR_setfsuid (__NR_SYSCALL_BASE+138)
+#define __NR_setfsgid (__NR_SYSCALL_BASE+139)
+#define __NR__llseek (__NR_SYSCALL_BASE+140)
+#define __NR_getdents (__NR_SYSCALL_BASE+141)
+#define __NR__newselect (__NR_SYSCALL_BASE+142)
+#define __NR_flock (__NR_SYSCALL_BASE+143)
+#define __NR_msync (__NR_SYSCALL_BASE+144)
+#define __NR_readv (__NR_SYSCALL_BASE+145)
+#define __NR_writev (__NR_SYSCALL_BASE+146)
+#define __NR_getsid (__NR_SYSCALL_BASE+147)
+#define __NR_fdatasync (__NR_SYSCALL_BASE+148)
+#define __NR__sysctl (__NR_SYSCALL_BASE+149)
+#define __NR_mlock (__NR_SYSCALL_BASE+150)
+#define __NR_munlock (__NR_SYSCALL_BASE+151)
+#define __NR_mlockall (__NR_SYSCALL_BASE+152)
+#define __NR_munlockall (__NR_SYSCALL_BASE+153)
+#define __NR_sched_setparam (__NR_SYSCALL_BASE+154)
+#define __NR_sched_getparam (__NR_SYSCALL_BASE+155)
+#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156)
+#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157)
+#define __NR_sched_yield (__NR_SYSCALL_BASE+158)
+#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159)
+#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160)
+#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161)
+#define __NR_nanosleep (__NR_SYSCALL_BASE+162)
+#define __NR_mremap (__NR_SYSCALL_BASE+163)
+#define __NR_setresuid (__NR_SYSCALL_BASE+164)
+#define __NR_getresuid (__NR_SYSCALL_BASE+165)
+
+#define __NR_poll (__NR_SYSCALL_BASE+168)
+#define __NR_nfsservctl (__NR_SYSCALL_BASE+169)
+#define __NR_setresgid (__NR_SYSCALL_BASE+170)
+#define __NR_getresgid (__NR_SYSCALL_BASE+171)
+#define __NR_prctl (__NR_SYSCALL_BASE+172)
+#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173)
+#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174)
+#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175)
+#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176)
+#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177)
+#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178)
+#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179)
+#define __NR_pread64 (__NR_SYSCALL_BASE+180)
+#define __NR_pwrite64 (__NR_SYSCALL_BASE+181)
+#define __NR_chown (__NR_SYSCALL_BASE+182)
+#define __NR_getcwd (__NR_SYSCALL_BASE+183)
+#define __NR_capget (__NR_SYSCALL_BASE+184)
+#define __NR_capset (__NR_SYSCALL_BASE+185)
+#define __NR_sigaltstack (__NR_SYSCALL_BASE+186)
+#define __NR_sendfile (__NR_SYSCALL_BASE+187)
+
+#define __NR_vfork (__NR_SYSCALL_BASE+190)
+#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191)  
+#define __NR_mmap2 (__NR_SYSCALL_BASE+192)
+#define __NR_truncate64 (__NR_SYSCALL_BASE+193)
+#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194)
+#define __NR_stat64 (__NR_SYSCALL_BASE+195)
+#define __NR_lstat64 (__NR_SYSCALL_BASE+196)
+#define __NR_fstat64 (__NR_SYSCALL_BASE+197)
+#define __NR_lchown32 (__NR_SYSCALL_BASE+198)
+#define __NR_getuid32 (__NR_SYSCALL_BASE+199)
+#define __NR_getgid32 (__NR_SYSCALL_BASE+200)
+#define __NR_geteuid32 (__NR_SYSCALL_BASE+201)
+#define __NR_getegid32 (__NR_SYSCALL_BASE+202)
+#define __NR_setreuid32 (__NR_SYSCALL_BASE+203)
+#define __NR_setregid32 (__NR_SYSCALL_BASE+204)
+#define __NR_getgroups32 (__NR_SYSCALL_BASE+205)
+#define __NR_setgroups32 (__NR_SYSCALL_BASE+206)
+#define __NR_fchown32 (__NR_SYSCALL_BASE+207)
+#define __NR_setresuid32 (__NR_SYSCALL_BASE+208)
+#define __NR_getresuid32 (__NR_SYSCALL_BASE+209)
+#define __NR_setresgid32 (__NR_SYSCALL_BASE+210)
+#define __NR_getresgid32 (__NR_SYSCALL_BASE+211)
+#define __NR_chown32 (__NR_SYSCALL_BASE+212)
+#define __NR_setuid32 (__NR_SYSCALL_BASE+213)
+#define __NR_setgid32 (__NR_SYSCALL_BASE+214)
+#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215)
+#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216)
+#define __NR_getdents64 (__NR_SYSCALL_BASE+217)
+#define __NR_pivot_root (__NR_SYSCALL_BASE+218)
+#define __NR_mincore (__NR_SYSCALL_BASE+219)
+#define __NR_madvise (__NR_SYSCALL_BASE+220)
+#define __NR_fcntl64 (__NR_SYSCALL_BASE+221)
+
+#define __NR_gettid (__NR_SYSCALL_BASE+224)
+#define __NR_readahead (__NR_SYSCALL_BASE+225)
+#define __NR_setxattr (__NR_SYSCALL_BASE+226)
+#define __NR_lsetxattr (__NR_SYSCALL_BASE+227)
+#define __NR_fsetxattr (__NR_SYSCALL_BASE+228)
+#define __NR_getxattr (__NR_SYSCALL_BASE+229)
+#define __NR_lgetxattr (__NR_SYSCALL_BASE+230)
+#define __NR_fgetxattr (__NR_SYSCALL_BASE+231)
+#define __NR_listxattr (__NR_SYSCALL_BASE+232)
+#define __NR_llistxattr (__NR_SYSCALL_BASE+233)
+#define __NR_flistxattr (__NR_SYSCALL_BASE+234)
+#define __NR_removexattr (__NR_SYSCALL_BASE+235)
+#define __NR_lremovexattr (__NR_SYSCALL_BASE+236)
+#define __NR_fremovexattr (__NR_SYSCALL_BASE+237)
+#define __NR_tkill (__NR_SYSCALL_BASE+238)
+#define __NR_sendfile64 (__NR_SYSCALL_BASE+239)
+#define __NR_futex (__NR_SYSCALL_BASE+240)
+#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241)
+#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242)
+#define __NR_io_setup (__NR_SYSCALL_BASE+243)
+#define __NR_io_destroy (__NR_SYSCALL_BASE+244)
+#define __NR_io_getevents (__NR_SYSCALL_BASE+245)
+#define __NR_io_submit (__NR_SYSCALL_BASE+246)
+#define __NR_io_cancel (__NR_SYSCALL_BASE+247)
+#define __NR_exit_group (__NR_SYSCALL_BASE+248)
+#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249)
+#define __NR_epoll_create (__NR_SYSCALL_BASE+250)
+#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251)
+#define __NR_epoll_wait (__NR_SYSCALL_BASE+252)
+#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253)
+
+#define __NR_set_tid_address (__NR_SYSCALL_BASE+256)
+#define __NR_timer_create (__NR_SYSCALL_BASE+257)
+#define __NR_timer_settime (__NR_SYSCALL_BASE+258)
+#define __NR_timer_gettime (__NR_SYSCALL_BASE+259)
+#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260)
+#define __NR_timer_delete (__NR_SYSCALL_BASE+261)
+#define __NR_clock_settime (__NR_SYSCALL_BASE+262)
+#define __NR_clock_gettime (__NR_SYSCALL_BASE+263)
+#define __NR_clock_getres (__NR_SYSCALL_BASE+264)
+#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265)
+#define __NR_statfs64 (__NR_SYSCALL_BASE+266)
+#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267)
+#define __NR_tgkill (__NR_SYSCALL_BASE+268)
+#define __NR_utimes (__NR_SYSCALL_BASE+269)
+#define __NR_arm_fadvise64_64 (__NR_SYSCALL_BASE+270)
+#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271)
+#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272)
+#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273)
+#define __NR_mq_open (__NR_SYSCALL_BASE+274)
+#define __NR_mq_unlink (__NR_SYSCALL_BASE+275)
+#define __NR_mq_timedsend (__NR_SYSCALL_BASE+276)
+#define __NR_mq_timedreceive (__NR_SYSCALL_BASE+277)
+#define __NR_mq_notify (__NR_SYSCALL_BASE+278)
+#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279)
+#define __NR_waitid (__NR_SYSCALL_BASE+280)
+#define __NR_socket (__NR_SYSCALL_BASE+281)
+#define __NR_bind (__NR_SYSCALL_BASE+282)
+#define __NR_connect (__NR_SYSCALL_BASE+283)
+#define __NR_listen (__NR_SYSCALL_BASE+284)
+#define __NR_accept (__NR_SYSCALL_BASE+285)
+#define __NR_getsockname (__NR_SYSCALL_BASE+286)
+#define __NR_getpeername (__NR_SYSCALL_BASE+287)
+#define __NR_socketpair (__NR_SYSCALL_BASE+288)
+#define __NR_send (__NR_SYSCALL_BASE+289)
+#define __NR_sendto (__NR_SYSCALL_BASE+290)
+#define __NR_recv (__NR_SYSCALL_BASE+291)
+#define __NR_recvfrom (__NR_SYSCALL_BASE+292)
+#define __NR_shutdown (__NR_SYSCALL_BASE+293)
+#define __NR_setsockopt (__NR_SYSCALL_BASE+294)
+#define __NR_getsockopt (__NR_SYSCALL_BASE+295)
+#define __NR_sendmsg (__NR_SYSCALL_BASE+296)
+#define __NR_recvmsg (__NR_SYSCALL_BASE+297)
+#define __NR_semop (__NR_SYSCALL_BASE+298)
+#define __NR_semget (__NR_SYSCALL_BASE+299)
+#define __NR_semctl (__NR_SYSCALL_BASE+300)
+#define __NR_msgsnd (__NR_SYSCALL_BASE+301)
+#define __NR_msgrcv (__NR_SYSCALL_BASE+302)
+#define __NR_msgget (__NR_SYSCALL_BASE+303)
+#define __NR_msgctl (__NR_SYSCALL_BASE+304)
+#define __NR_shmat (__NR_SYSCALL_BASE+305)
+#define __NR_shmdt (__NR_SYSCALL_BASE+306)
+#define __NR_shmget (__NR_SYSCALL_BASE+307)
+#define __NR_shmctl (__NR_SYSCALL_BASE+308)
+#define __NR_add_key (__NR_SYSCALL_BASE+309)
+#define __NR_request_key (__NR_SYSCALL_BASE+310)
+#define __NR_keyctl (__NR_SYSCALL_BASE+311)
+#define __NR_semtimedop (__NR_SYSCALL_BASE+312)
+#define __NR_vserver (__NR_SYSCALL_BASE+313)
+#define __NR_ioprio_set (__NR_SYSCALL_BASE+314)
+#define __NR_ioprio_get (__NR_SYSCALL_BASE+315)
+#define __NR_inotify_init (__NR_SYSCALL_BASE+316)
+#define __NR_inotify_add_watch (__NR_SYSCALL_BASE+317)
+#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+318)
+#define __NR_mbind (__NR_SYSCALL_BASE+319)
+#define __NR_get_mempolicy (__NR_SYSCALL_BASE+320)
+#define __NR_set_mempolicy (__NR_SYSCALL_BASE+321)
+
+#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000)
+#define __ARM_NR_breakpoint (__ARM_NR_BASE+1)
+#define __ARM_NR_cacheflush (__ARM_NR_BASE+2)
+#define __ARM_NR_usr26 (__ARM_NR_BASE+3)
+#define __ARM_NR_usr32 (__ARM_NR_BASE+4)
+#define __ARM_NR_set_tls (__ARM_NR_BASE+5)
+
+#if defined(__ARM_EABI__) && !defined(__KERNEL__)
+#undef __NR_time
+#undef __NR_umount
+#undef __NR_stime
+#undef __NR_alarm
+#undef __NR_utime
+#undef __NR_getrlimit
+#undef __NR_select
+#undef __NR_readdir
+#undef __NR_mmap
+#undef __NR_socketcall
+#undef __NR_syscall
+#undef __NR_ipc
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/user.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/user.h
new file mode 100644
index 0000000..5f25850
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/user.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ARM_USER_H
+#define _ARM_USER_H
+
+#include <asm/page.h>
+#include <asm/ptrace.h>
+
+struct user_fp {
+ struct fp_reg {
+ unsigned int sign1:1;
+ unsigned int unused:15;
+ unsigned int sign2:1;
+ unsigned int exponent:14;
+ unsigned int j:1;
+ unsigned int mantissa1:31;
+ unsigned int mantissa0:32;
+ } fpregs[8];
+ unsigned int fpsr:32;
+ unsigned int fpcr:32;
+ unsigned char ftype[8];
+ unsigned int init_flag;
+};
+
+struct user{
+
+ struct pt_regs regs;
+
+ int u_fpvalid;
+
+ unsigned long int u_tsize;
+ unsigned long int u_dsize;
+ unsigned long int u_ssize;
+ unsigned long start_code;
+ unsigned long start_stack;
+ long int signal;
+ int reserved;
+ struct pt_regs * u_ar0;
+
+ unsigned long magic;
+ char u_comm[32];
+ int u_debugreg[8];
+ struct user_fp u_fp;
+ struct user_fp_struct * u_fp0;
+
+};
+#define NBPG PAGE_SIZE
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/vga.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/vga.h
new file mode 100644
index 0000000..7875dbf
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/asm/vga.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef ASMARM_VGA_H
+#define ASMARM_VGA_H
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+
+#define VGA_MAP_MEM(x,s) (PCIMEM_BASE + (x))
+
+#define vga_readb(x) (*((volatile unsigned char *)x))
+#define vga_writeb(x,y) (*((volatile unsigned char *)y) = (x))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/assert.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/assert.h
new file mode 120000
index 0000000..1572c5b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/assert.h
@@ -0,0 +1 @@
+../../../common/include/assert.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/byteswap.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/byteswap.h
new file mode 120000
index 0000000..153ee73
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/byteswap.h
@@ -0,0 +1 @@
+../../../common/include/byteswap.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/cstddef b/ndk/build/platforms/android-1.5/arch-arm/usr/include/cstddef
new file mode 120000
index 0000000..cec20fd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/cstddef
@@ -0,0 +1 @@
+../../../common/include/cstddef
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/ctype.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/ctype.h
new file mode 120000
index 0000000..f1b315c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/ctype.h
@@ -0,0 +1 @@
+../../../common/include/ctype.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/dirent.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/dirent.h
new file mode 120000
index 0000000..315be03
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/dirent.h
@@ -0,0 +1 @@
+../../../common/include/dirent.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/dlfcn.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/dlfcn.h
new file mode 120000
index 0000000..5748e5a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/dlfcn.h
@@ -0,0 +1 @@
+../../../common/include/dlfcn.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/elf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/elf.h
new file mode 120000
index 0000000..f4e2f5e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/elf.h
@@ -0,0 +1 @@
+../../../common/include/elf.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/endian.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/endian.h
new file mode 100644
index 0000000..04204ed
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/endian.h
@@ -0,0 +1,10 @@
+/*	$OpenBSD: endian.h,v 1.3 2005/12/13 00:35:23 millert Exp $	*/
+
+#ifdef __ARMEB__
+#define _BYTE_ORDER _BIG_ENDIAN
+#else
+#define _BYTE_ORDER _LITTLE_ENDIAN
+#endif
+#define	__STRICT_ALIGNMENT
+#include <sys/types.h>
+#include <sys/endian.h>
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/err.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/err.h
new file mode 120000
index 0000000..de81816
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/err.h
@@ -0,0 +1 @@
+../../../common/include/err.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/errno.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/errno.h
new file mode 120000
index 0000000..2e638ba
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/errno.h
@@ -0,0 +1 @@
+../../../common/include/errno.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/fcntl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/fcntl.h
new file mode 120000
index 0000000..cb8c1df
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/fcntl.h
@@ -0,0 +1 @@
+../../../common/include/fcntl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/features.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/features.h
new file mode 120000
index 0000000..6587ebd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/features.h
@@ -0,0 +1 @@
+../../../common/include/features.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/fnmatch.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/fnmatch.h
new file mode 120000
index 0000000..52c0687
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/fnmatch.h
@@ -0,0 +1 @@
+../../../common/include/fnmatch.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/getopt.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/getopt.h
new file mode 120000
index 0000000..857cf27
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/getopt.h
@@ -0,0 +1 @@
+../../../common/include/getopt.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/grp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/grp.h
new file mode 120000
index 0000000..c599451
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/grp.h
@@ -0,0 +1 @@
+../../../common/include/grp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/inttypes.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/inttypes.h
new file mode 120000
index 0000000..5283d60
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/inttypes.h
@@ -0,0 +1 @@
+../../../common/include/inttypes.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/jni.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/jni.h
new file mode 120000
index 0000000..e49af21
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/jni.h
@@ -0,0 +1 @@
+../../../common/include/jni.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/lastlog.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/lastlog.h
new file mode 120000
index 0000000..fe63cd3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/lastlog.h
@@ -0,0 +1 @@
+../../../common/include/lastlog.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/libgen.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/libgen.h
new file mode 120000
index 0000000..0f626b6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/libgen.h
@@ -0,0 +1 @@
+../../../common/include/libgen.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/limits.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/limits.h
new file mode 120000
index 0000000..60f67bf
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/limits.h
@@ -0,0 +1 @@
+../../../common/include/limits.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/a.out.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/a.out.h
new file mode 120000
index 0000000..e1bffda
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/a.out.h
@@ -0,0 +1 @@
+../../../../common/include/linux/a.out.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/aio_abi.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/aio_abi.h
new file mode 120000
index 0000000..cd94485
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/aio_abi.h
@@ -0,0 +1 @@
+../../../../common/include/linux/aio_abi.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/akm8976.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/akm8976.h
new file mode 120000
index 0000000..1d8b858
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/akm8976.h
@@ -0,0 +1 @@
+../../../../common/include/linux/akm8976.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/android_alarm.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/android_alarm.h
new file mode 120000
index 0000000..383aabd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/android_alarm.h
@@ -0,0 +1 @@
+../../../../common/include/linux/android_alarm.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/android_pmem.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/android_pmem.h
new file mode 120000
index 0000000..2485ad8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/android_pmem.h
@@ -0,0 +1 @@
+../../../../common/include/linux/android_pmem.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/android_power.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/android_power.h
new file mode 120000
index 0000000..05f970a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/android_power.h
@@ -0,0 +1 @@
+../../../../common/include/linux/android_power.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/apm_bios.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/apm_bios.h
new file mode 120000
index 0000000..cbcfb5a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/apm_bios.h
@@ -0,0 +1 @@
+../../../../common/include/linux/apm_bios.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ashmem.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ashmem.h
new file mode 120000
index 0000000..3cc1881
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ashmem.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ashmem.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ata.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ata.h
new file mode 120000
index 0000000..4640b5f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ata.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ata.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atm.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atm.h
new file mode 120000
index 0000000..377242f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atm.h
@@ -0,0 +1 @@
+../../../../common/include/linux/atm.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmapi.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmapi.h
new file mode 120000
index 0000000..0d7f085
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmapi.h
@@ -0,0 +1 @@
+../../../../common/include/linux/atmapi.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmdev.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmdev.h
new file mode 120000
index 0000000..f1f9a5f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmdev.h
@@ -0,0 +1 @@
+../../../../common/include/linux/atmdev.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmioc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmioc.h
new file mode 120000
index 0000000..3b1e711
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmioc.h
@@ -0,0 +1 @@
+../../../../common/include/linux/atmioc.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmppp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmppp.h
new file mode 120000
index 0000000..785c8fb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmppp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/atmppp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmsap.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmsap.h
new file mode 120000
index 0000000..bc0f5a8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/atmsap.h
@@ -0,0 +1 @@
+../../../../common/include/linux/atmsap.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/attribute_container.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/attribute_container.h
new file mode 120000
index 0000000..3834481
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/attribute_container.h
@@ -0,0 +1 @@
+../../../../common/include/linux/attribute_container.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/auto_fs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/auto_fs.h
new file mode 120000
index 0000000..8d3e7b9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/auto_fs.h
@@ -0,0 +1 @@
+../../../../common/include/linux/auto_fs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/autoconf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/autoconf.h
new file mode 120000
index 0000000..41a58f5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/autoconf.h
@@ -0,0 +1 @@
+../../../../common/include/linux/autoconf.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/auxvec.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/auxvec.h
new file mode 120000
index 0000000..5602220
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/auxvec.h
@@ -0,0 +1 @@
+../../../../common/include/linux/auxvec.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/backing-dev.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/backing-dev.h
new file mode 120000
index 0000000..427296e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/backing-dev.h
@@ -0,0 +1 @@
+../../../../common/include/linux/backing-dev.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/binder.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/binder.h
new file mode 120000
index 0000000..39fcca7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/binder.h
@@ -0,0 +1 @@
+../../../../common/include/linux/binder.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/binfmts.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/binfmts.h
new file mode 120000
index 0000000..d938c2f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/binfmts.h
@@ -0,0 +1 @@
+../../../../common/include/linux/binfmts.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/bio.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/bio.h
new file mode 120000
index 0000000..9a8ee71
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/bio.h
@@ -0,0 +1 @@
+../../../../common/include/linux/bio.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/bitmap.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/bitmap.h
new file mode 120000
index 0000000..5db6297
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/bitmap.h
@@ -0,0 +1 @@
+../../../../common/include/linux/bitmap.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/bitops.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/bitops.h
new file mode 120000
index 0000000..5d0fcbb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/bitops.h
@@ -0,0 +1 @@
+../../../../common/include/linux/bitops.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/blkdev.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/blkdev.h
new file mode 120000
index 0000000..fb45957
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/blkdev.h
@@ -0,0 +1 @@
+../../../../common/include/linux/blkdev.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/blkpg.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/blkpg.h
new file mode 120000
index 0000000..bc5f38f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/blkpg.h
@@ -0,0 +1 @@
+../../../../common/include/linux/blkpg.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/blockgroup_lock.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/blockgroup_lock.h
new file mode 120000
index 0000000..587f7f1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/blockgroup_lock.h
@@ -0,0 +1 @@
+../../../../common/include/linux/blockgroup_lock.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/big_endian.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/big_endian.h
new file mode 120000
index 0000000..ce97246
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/big_endian.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/byteorder/big_endian.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/generic.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/generic.h
new file mode 120000
index 0000000..d865701
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/generic.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/byteorder/generic.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/little_endian.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/little_endian.h
new file mode 120000
index 0000000..9b117fa
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/little_endian.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/byteorder/little_endian.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/swab.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/swab.h
new file mode 120000
index 0000000..b3da56e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/swab.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/byteorder/swab.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/swabb.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/swabb.h
new file mode 120000
index 0000000..d6d7ade
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/byteorder/swabb.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/byteorder/swabb.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cache.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cache.h
new file mode 120000
index 0000000..74ed7c9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cache.h
@@ -0,0 +1 @@
+../../../../common/include/linux/cache.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/calc64.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/calc64.h
new file mode 120000
index 0000000..e12ad54
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/calc64.h
@@ -0,0 +1 @@
+../../../../common/include/linux/calc64.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/capability.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/capability.h
new file mode 120000
index 0000000..9674918
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/capability.h
@@ -0,0 +1 @@
+../../../../common/include/linux/capability.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/capi.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/capi.h
new file mode 120000
index 0000000..e937bc1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/capi.h
@@ -0,0 +1 @@
+../../../../common/include/linux/capi.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cdev.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cdev.h
new file mode 120000
index 0000000..aa3f937
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cdev.h
@@ -0,0 +1 @@
+../../../../common/include/linux/cdev.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cdrom.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cdrom.h
new file mode 120000
index 0000000..f8a7cfe
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cdrom.h
@@ -0,0 +1 @@
+../../../../common/include/linux/cdrom.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/circ_buf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/circ_buf.h
new file mode 120000
index 0000000..ada0bca
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/circ_buf.h
@@ -0,0 +1 @@
+../../../../common/include/linux/circ_buf.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/clk.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/clk.h
new file mode 120000
index 0000000..246f4ad
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/clk.h
@@ -0,0 +1 @@
+../../../../common/include/linux/clk.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/coda.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/coda.h
new file mode 120000
index 0000000..e577be5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/coda.h
@@ -0,0 +1 @@
+../../../../common/include/linux/coda.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/coda_fs_i.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/coda_fs_i.h
new file mode 120000
index 0000000..bd7a507
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/coda_fs_i.h
@@ -0,0 +1 @@
+../../../../common/include/linux/coda_fs_i.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/compat.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/compat.h
new file mode 120000
index 0000000..c323a32
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/compat.h
@@ -0,0 +1 @@
+../../../../common/include/linux/compat.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/compiler-gcc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/compiler-gcc.h
new file mode 120000
index 0000000..6609cf6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/compiler-gcc.h
@@ -0,0 +1 @@
+../../../../common/include/linux/compiler-gcc.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/compiler.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/compiler.h
new file mode 120000
index 0000000..c3c0a7c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/compiler.h
@@ -0,0 +1 @@
+../../../../common/include/linux/compiler.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/completion.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/completion.h
new file mode 120000
index 0000000..af28044
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/completion.h
@@ -0,0 +1 @@
+../../../../common/include/linux/completion.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/config.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/config.h
new file mode 120000
index 0000000..71028f6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/config.h
@@ -0,0 +1 @@
+../../../../common/include/linux/config.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/console_struct.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/console_struct.h
new file mode 120000
index 0000000..7aa8514
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/console_struct.h
@@ -0,0 +1 @@
+../../../../common/include/linux/console_struct.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cpu.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cpu.h
new file mode 120000
index 0000000..2608247
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cpu.h
@@ -0,0 +1 @@
+../../../../common/include/linux/cpu.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cpumask.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cpumask.h
new file mode 120000
index 0000000..c8f6de0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/cpumask.h
@@ -0,0 +1 @@
+../../../../common/include/linux/cpumask.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ctype.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ctype.h
new file mode 120000
index 0000000..e008d1e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ctype.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ctype.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dccp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dccp.h
new file mode 120000
index 0000000..bc11d40
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dccp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/dccp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/debug_locks.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/debug_locks.h
new file mode 120000
index 0000000..561a5bc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/debug_locks.h
@@ -0,0 +1 @@
+../../../../common/include/linux/debug_locks.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/delay.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/delay.h
new file mode 120000
index 0000000..d934a13
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/delay.h
@@ -0,0 +1 @@
+../../../../common/include/linux/delay.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/device.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/device.h
new file mode 120000
index 0000000..2440aba
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/device.h
@@ -0,0 +1 @@
+../../../../common/include/linux/device.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dirent.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dirent.h
new file mode 120000
index 0000000..f16f4a4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dirent.h
@@ -0,0 +1 @@
+../../../../common/include/linux/dirent.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dm-ioctl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dm-ioctl.h
new file mode 120000
index 0000000..d7305d2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dm-ioctl.h
@@ -0,0 +1 @@
+../../../../common/include/linux/dm-ioctl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dma-mapping.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dma-mapping.h
new file mode 120000
index 0000000..d8f5664
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dma-mapping.h
@@ -0,0 +1 @@
+../../../../common/include/linux/dma-mapping.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dmaengine.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dmaengine.h
new file mode 120000
index 0000000..31efa05
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/dmaengine.h
@@ -0,0 +1 @@
+../../../../common/include/linux/dmaengine.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/efs_dir.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/efs_dir.h
new file mode 120000
index 0000000..5aae574
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/efs_dir.h
@@ -0,0 +1 @@
+../../../../common/include/linux/efs_dir.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/efs_fs_i.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/efs_fs_i.h
new file mode 120000
index 0000000..1ea12f6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/efs_fs_i.h
@@ -0,0 +1 @@
+../../../../common/include/linux/efs_fs_i.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/efs_fs_sb.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/efs_fs_sb.h
new file mode 120000
index 0000000..9ece7e1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/efs_fs_sb.h
@@ -0,0 +1 @@
+../../../../common/include/linux/efs_fs_sb.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/elevator.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/elevator.h
new file mode 120000
index 0000000..a15375f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/elevator.h
@@ -0,0 +1 @@
+../../../../common/include/linux/elevator.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/elf-em.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/elf-em.h
new file mode 120000
index 0000000..a70534c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/elf-em.h
@@ -0,0 +1 @@
+../../../../common/include/linux/elf-em.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/elf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/elf.h
new file mode 120000
index 0000000..4455674
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/elf.h
@@ -0,0 +1 @@
+../../../../common/include/linux/elf.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/err.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/err.h
new file mode 120000
index 0000000..7bc3976
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/err.h
@@ -0,0 +1 @@
+../../../../common/include/linux/err.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/errno.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/errno.h
new file mode 120000
index 0000000..17901cf
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/errno.h
@@ -0,0 +1 @@
+../../../../common/include/linux/errno.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/errqueue.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/errqueue.h
new file mode 120000
index 0000000..f857679
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/errqueue.h
@@ -0,0 +1 @@
+../../../../common/include/linux/errqueue.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/etherdevice.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/etherdevice.h
new file mode 120000
index 0000000..c6fc657
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/etherdevice.h
@@ -0,0 +1 @@
+../../../../common/include/linux/etherdevice.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ext2_fs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ext2_fs.h
new file mode 120000
index 0000000..6d1ef48
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ext2_fs.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ext2_fs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ext3_fs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ext3_fs.h
new file mode 120000
index 0000000..401d884
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ext3_fs.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ext3_fs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fadvise.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fadvise.h
new file mode 120000
index 0000000..28391d0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fadvise.h
@@ -0,0 +1 @@
+../../../../common/include/linux/fadvise.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fb.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fb.h
new file mode 120000
index 0000000..678e85b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fb.h
@@ -0,0 +1 @@
+../../../../common/include/linux/fb.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fcntl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fcntl.h
new file mode 120000
index 0000000..628a481
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fcntl.h
@@ -0,0 +1 @@
+../../../../common/include/linux/fcntl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fd.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fd.h
new file mode 120000
index 0000000..27d6d08
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fd.h
@@ -0,0 +1 @@
+../../../../common/include/linux/fd.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/file.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/file.h
new file mode 120000
index 0000000..d063b5e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/file.h
@@ -0,0 +1 @@
+../../../../common/include/linux/file.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/filter.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/filter.h
new file mode 120000
index 0000000..54c78a3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/filter.h
@@ -0,0 +1 @@
+../../../../common/include/linux/filter.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fs.h
new file mode 120000
index 0000000..c72717d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/fs.h
@@ -0,0 +1 @@
+../../../../common/include/linux/fs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ftape.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ftape.h
new file mode 120000
index 0000000..59efd2b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ftape.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ftape.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/futex.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/futex.h
new file mode 120000
index 0000000..cbfdedb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/futex.h
@@ -0,0 +1 @@
+../../../../common/include/linux/futex.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/genhd.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/genhd.h
new file mode 120000
index 0000000..4182ac6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/genhd.h
@@ -0,0 +1 @@
+../../../../common/include/linux/genhd.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/gfp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/gfp.h
new file mode 120000
index 0000000..955489e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/gfp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/gfp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hardirq.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hardirq.h
new file mode 120000
index 0000000..01128bd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hardirq.h
@@ -0,0 +1 @@
+../../../../common/include/linux/hardirq.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hdlc/ioctl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hdlc/ioctl.h
new file mode 120000
index 0000000..7679e36
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hdlc/ioctl.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/hdlc/ioctl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hdreg.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hdreg.h
new file mode 120000
index 0000000..35aea04
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hdreg.h
@@ -0,0 +1 @@
+../../../../common/include/linux/hdreg.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hdsmart.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hdsmart.h
new file mode 120000
index 0000000..383f58c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hdsmart.h
@@ -0,0 +1 @@
+../../../../common/include/linux/hdsmart.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/highmem.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/highmem.h
new file mode 120000
index 0000000..0f41fc7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/highmem.h
@@ -0,0 +1 @@
+../../../../common/include/linux/highmem.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hil.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hil.h
new file mode 120000
index 0000000..2bee8bb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/hil.h
@@ -0,0 +1 @@
+../../../../common/include/linux/hil.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/i2c.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/i2c.h
new file mode 120000
index 0000000..514ff43
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/i2c.h
@@ -0,0 +1 @@
+../../../../common/include/linux/i2c.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/icmp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/icmp.h
new file mode 120000
index 0000000..87771a7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/icmp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/icmp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if.h
new file mode 120000
index 0000000..176aae6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if.h
@@ -0,0 +1 @@
+../../../../common/include/linux/if.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_arcnet.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_arcnet.h
new file mode 120000
index 0000000..0d04ae3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_arcnet.h
@@ -0,0 +1 @@
+../../../../common/include/linux/if_arcnet.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_arp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_arp.h
new file mode 120000
index 0000000..536a142
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_arp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/if_arp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_bridge.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_bridge.h
new file mode 120000
index 0000000..ad36ad5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_bridge.h
@@ -0,0 +1 @@
+../../../../common/include/linux/if_bridge.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_ether.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_ether.h
new file mode 120000
index 0000000..4dc3348
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_ether.h
@@ -0,0 +1 @@
+../../../../common/include/linux/if_ether.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_fc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_fc.h
new file mode 120000
index 0000000..087ec19
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_fc.h
@@ -0,0 +1 @@
+../../../../common/include/linux/if_fc.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_fddi.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_fddi.h
new file mode 120000
index 0000000..6c439ad
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_fddi.h
@@ -0,0 +1 @@
+../../../../common/include/linux/if_fddi.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_hippi.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_hippi.h
new file mode 120000
index 0000000..f4febf9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_hippi.h
@@ -0,0 +1 @@
+../../../../common/include/linux/if_hippi.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_packet.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_packet.h
new file mode 120000
index 0000000..d48d404
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_packet.h
@@ -0,0 +1 @@
+../../../../common/include/linux/if_packet.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_ppp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_ppp.h
new file mode 120000
index 0000000..1c0292e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_ppp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/if_ppp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_tr.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_tr.h
new file mode 120000
index 0000000..115cd17
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_tr.h
@@ -0,0 +1 @@
+../../../../common/include/linux/if_tr.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_tun.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_tun.h
new file mode 120000
index 0000000..f127941
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_tun.h
@@ -0,0 +1 @@
+../../../../common/include/linux/if_tun.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_vlan.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_vlan.h
new file mode 120000
index 0000000..f20fce0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/if_vlan.h
@@ -0,0 +1 @@
+../../../../common/include/linux/if_vlan.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/in.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/in.h
new file mode 120000
index 0000000..0e127e0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/in.h
@@ -0,0 +1 @@
+../../../../common/include/linux/in.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/in6.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/in6.h
new file mode 120000
index 0000000..18c3130
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/in6.h
@@ -0,0 +1 @@
+../../../../common/include/linux/in6.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/init.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/init.h
new file mode 120000
index 0000000..488bb0a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/init.h
@@ -0,0 +1 @@
+../../../../common/include/linux/init.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/inotify.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/inotify.h
new file mode 120000
index 0000000..41670ad
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/inotify.h
@@ -0,0 +1 @@
+../../../../common/include/linux/inotify.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/input.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/input.h
new file mode 120000
index 0000000..423edd7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/input.h
@@ -0,0 +1 @@
+../../../../common/include/linux/input.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/interrupt.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/interrupt.h
new file mode 120000
index 0000000..b5cd63c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/interrupt.h
@@ -0,0 +1 @@
+../../../../common/include/linux/interrupt.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ioctl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ioctl.h
new file mode 120000
index 0000000..b30e479
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ioctl.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ioctl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ioport.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ioport.h
new file mode 120000
index 0000000..d90526d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ioport.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ioport.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ioprio.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ioprio.h
new file mode 120000
index 0000000..1634241
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ioprio.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ioprio.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ip.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ip.h
new file mode 120000
index 0000000..e89967b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ip.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ip.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ipc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ipc.h
new file mode 120000
index 0000000..60f3881
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ipc.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ipc.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ipmi_msgdefs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ipmi_msgdefs.h
new file mode 120000
index 0000000..2cfe5ac
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ipmi_msgdefs.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ipmi_msgdefs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ipmi_smi.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ipmi_smi.h
new file mode 120000
index 0000000..9a796a2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ipmi_smi.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ipmi_smi.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ipx.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ipx.h
new file mode 120000
index 0000000..dd5d4b9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ipx.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ipx.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/irq.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/irq.h
new file mode 120000
index 0000000..aa6cf1a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/irq.h
@@ -0,0 +1 @@
+../../../../common/include/linux/irq.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/irq_cpustat.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/irq_cpustat.h
new file mode 120000
index 0000000..4a329b4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/irq_cpustat.h
@@ -0,0 +1 @@
+../../../../common/include/linux/irq_cpustat.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/irqflags.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/irqflags.h
new file mode 120000
index 0000000..fa80886
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/irqflags.h
@@ -0,0 +1 @@
+../../../../common/include/linux/irqflags.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/irqreturn.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/irqreturn.h
new file mode 120000
index 0000000..739fa62
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/irqreturn.h
@@ -0,0 +1 @@
+../../../../common/include/linux/irqreturn.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/jbd.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/jbd.h
new file mode 120000
index 0000000..9594286
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/jbd.h
@@ -0,0 +1 @@
+../../../../common/include/linux/jbd.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/jiffies.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/jiffies.h
new file mode 120000
index 0000000..5accf6a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/jiffies.h
@@ -0,0 +1 @@
+../../../../common/include/linux/jiffies.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kd.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kd.h
new file mode 120000
index 0000000..e7005fa
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kd.h
@@ -0,0 +1 @@
+../../../../common/include/linux/kd.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kdev_t.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kdev_t.h
new file mode 120000
index 0000000..fffcdac
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kdev_t.h
@@ -0,0 +1 @@
+../../../../common/include/linux/kdev_t.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kernel.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kernel.h
new file mode 120000
index 0000000..4b3447c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kernel.h
@@ -0,0 +1 @@
+../../../../common/include/linux/kernel.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kernel_stat.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kernel_stat.h
new file mode 120000
index 0000000..2f1598b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kernel_stat.h
@@ -0,0 +1 @@
+../../../../common/include/linux/kernel_stat.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kernelcapi.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kernelcapi.h
new file mode 120000
index 0000000..78f09ac
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kernelcapi.h
@@ -0,0 +1 @@
+../../../../common/include/linux/kernelcapi.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kexec.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kexec.h
new file mode 120000
index 0000000..883b34f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kexec.h
@@ -0,0 +1 @@
+../../../../common/include/linux/kexec.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/key.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/key.h
new file mode 120000
index 0000000..a43f262
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/key.h
@@ -0,0 +1 @@
+../../../../common/include/linux/key.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/keyboard.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/keyboard.h
new file mode 120000
index 0000000..f1e952c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/keyboard.h
@@ -0,0 +1 @@
+../../../../common/include/linux/keyboard.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/keychord.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/keychord.h
new file mode 120000
index 0000000..4af7a30
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/keychord.h
@@ -0,0 +1 @@
+../../../../common/include/linux/keychord.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/klist.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/klist.h
new file mode 120000
index 0000000..6c121e7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/klist.h
@@ -0,0 +1 @@
+../../../../common/include/linux/klist.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kmod.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kmod.h
new file mode 120000
index 0000000..0fc11ce
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kmod.h
@@ -0,0 +1 @@
+../../../../common/include/linux/kmod.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kobject.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kobject.h
new file mode 120000
index 0000000..1e2eb82
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kobject.h
@@ -0,0 +1 @@
+../../../../common/include/linux/kobject.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kref.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kref.h
new file mode 120000
index 0000000..84f0760
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/kref.h
@@ -0,0 +1 @@
+../../../../common/include/linux/kref.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ktime.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ktime.h
new file mode 120000
index 0000000..bd9e539
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ktime.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ktime.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/limits.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/limits.h
new file mode 120000
index 0000000..998a2f3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/limits.h
@@ -0,0 +1 @@
+../../../../common/include/linux/limits.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/linkage.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/linkage.h
new file mode 120000
index 0000000..9981e49
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/linkage.h
@@ -0,0 +1 @@
+../../../../common/include/linux/linkage.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/list.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/list.h
new file mode 120000
index 0000000..8b5214f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/list.h
@@ -0,0 +1 @@
+../../../../common/include/linux/list.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/lockd/nlm.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/lockd/nlm.h
new file mode 120000
index 0000000..1f70297
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/lockd/nlm.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/lockd/nlm.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/lockd/xdr.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/lockd/xdr.h
new file mode 120000
index 0000000..59987cf
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/lockd/xdr.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/lockd/xdr.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/lockdep.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/lockdep.h
new file mode 120000
index 0000000..6a6ae87
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/lockdep.h
@@ -0,0 +1 @@
+../../../../common/include/linux/lockdep.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/loop.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/loop.h
new file mode 120000
index 0000000..6c91215
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/loop.h
@@ -0,0 +1 @@
+../../../../common/include/linux/loop.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/magic.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/magic.h
new file mode 120000
index 0000000..afafcfd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/magic.h
@@ -0,0 +1 @@
+../../../../common/include/linux/magic.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/major.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/major.h
new file mode 120000
index 0000000..f08b244
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/major.h
@@ -0,0 +1 @@
+../../../../common/include/linux/major.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mc146818rtc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mc146818rtc.h
new file mode 120000
index 0000000..4286741
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mc146818rtc.h
@@ -0,0 +1 @@
+../../../../common/include/linux/mc146818rtc.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mca.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mca.h
new file mode 120000
index 0000000..1f34bde
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mca.h
@@ -0,0 +1 @@
+../../../../common/include/linux/mca.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mempolicy.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mempolicy.h
new file mode 120000
index 0000000..2690b14
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mempolicy.h
@@ -0,0 +1 @@
+../../../../common/include/linux/mempolicy.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mempool.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mempool.h
new file mode 120000
index 0000000..eaed026
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mempool.h
@@ -0,0 +1 @@
+../../../../common/include/linux/mempool.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/miscdevice.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/miscdevice.h
new file mode 120000
index 0000000..7de3342
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/miscdevice.h
@@ -0,0 +1 @@
+../../../../common/include/linux/miscdevice.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mm.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mm.h
new file mode 120000
index 0000000..111cc15
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mm.h
@@ -0,0 +1 @@
+../../../../common/include/linux/mm.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mmc/card.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mmc/card.h
new file mode 120000
index 0000000..0a25330
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mmc/card.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mmc/card.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mmc/host.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mmc/host.h
new file mode 120000
index 0000000..61ab0f6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mmc/host.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mmc/host.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mmc/mmc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mmc/mmc.h
new file mode 120000
index 0000000..ca8b23e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mmc/mmc.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mmc/mmc.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mmzone.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mmzone.h
new file mode 120000
index 0000000..6bd8d97
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mmzone.h
@@ -0,0 +1 @@
+../../../../common/include/linux/mmzone.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mod_devicetable.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mod_devicetable.h
new file mode 120000
index 0000000..1104eb5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mod_devicetable.h
@@ -0,0 +1 @@
+../../../../common/include/linux/mod_devicetable.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/module.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/module.h
new file mode 120000
index 0000000..93b3b19
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/module.h
@@ -0,0 +1 @@
+../../../../common/include/linux/module.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/moduleparam.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/moduleparam.h
new file mode 120000
index 0000000..1f544b7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/moduleparam.h
@@ -0,0 +1 @@
+../../../../common/include/linux/moduleparam.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mount.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mount.h
new file mode 120000
index 0000000..5ac8a42
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mount.h
@@ -0,0 +1 @@
+../../../../common/include/linux/mount.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msdos_fs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msdos_fs.h
new file mode 120000
index 0000000..de01ab3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msdos_fs.h
@@ -0,0 +1 @@
+../../../../common/include/linux/msdos_fs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msg.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msg.h
new file mode 120000
index 0000000..4b5c4f9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msg.h
@@ -0,0 +1 @@
+../../../../common/include/linux/msg.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msm_adsp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msm_adsp.h
new file mode 120000
index 0000000..620ab8d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msm_adsp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/msm_adsp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msm_audio.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msm_audio.h
new file mode 120000
index 0000000..730a831
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msm_audio.h
@@ -0,0 +1 @@
+../../../../common/include/linux/msm_audio.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msm_mdp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msm_mdp.h
new file mode 120000
index 0000000..d4ff409
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/msm_mdp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/msm_mdp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mt9t013.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mt9t013.h
new file mode 120000
index 0000000..8a2b5c0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mt9t013.h
@@ -0,0 +1 @@
+../../../../common/include/linux/mt9t013.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/bbm.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/bbm.h
new file mode 120000
index 0000000..d2d24c5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/bbm.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mtd/bbm.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/blktrans.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/blktrans.h
new file mode 120000
index 0000000..f16b497
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/blktrans.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mtd/blktrans.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/cfi.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/cfi.h
new file mode 120000
index 0000000..468e5e8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/cfi.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mtd/cfi.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/cfi_endian.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/cfi_endian.h
new file mode 120000
index 0000000..3f9e287
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/cfi_endian.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mtd/cfi_endian.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/compatmac.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/compatmac.h
new file mode 120000
index 0000000..ed02458
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/compatmac.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mtd/compatmac.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/flashchip.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/flashchip.h
new file mode 120000
index 0000000..96a349d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/flashchip.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mtd/flashchip.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/map.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/map.h
new file mode 120000
index 0000000..fee2465
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/map.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mtd/map.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/mtd.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/mtd.h
new file mode 120000
index 0000000..7821ca4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/mtd.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mtd/mtd.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/nand.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/nand.h
new file mode 120000
index 0000000..00fe26e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/nand.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mtd/nand.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/nand_ecc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/nand_ecc.h
new file mode 120000
index 0000000..3c780f2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/nand_ecc.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mtd/nand_ecc.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/nftl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/nftl.h
new file mode 120000
index 0000000..b68add4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/nftl.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mtd/nftl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/onenand_regs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/onenand_regs.h
new file mode 120000
index 0000000..cf98f5e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/onenand_regs.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mtd/onenand_regs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/partitions.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/partitions.h
new file mode 120000
index 0000000..1943ac4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtd/partitions.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/mtd/partitions.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtio.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtio.h
new file mode 120000
index 0000000..e4a665b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mtio.h
@@ -0,0 +1 @@
+../../../../common/include/linux/mtio.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mutex-debug.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mutex-debug.h
new file mode 120000
index 0000000..b03b89e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mutex-debug.h
@@ -0,0 +1 @@
+../../../../common/include/linux/mutex-debug.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mutex.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mutex.h
new file mode 120000
index 0000000..adaf51c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/mutex.h
@@ -0,0 +1 @@
+../../../../common/include/linux/mutex.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ncp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ncp.h
new file mode 120000
index 0000000..36de989
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ncp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ncp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ncp_mount.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ncp_mount.h
new file mode 120000
index 0000000..d8e6b48
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ncp_mount.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ncp_mount.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ncp_no.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ncp_no.h
new file mode 120000
index 0000000..4e59a2b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ncp_no.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ncp_no.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/net.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/net.h
new file mode 120000
index 0000000..9ff68ce
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/net.h
@@ -0,0 +1 @@
+../../../../common/include/linux/net.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netdevice.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netdevice.h
new file mode 120000
index 0000000..103b2df
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netdevice.h
@@ -0,0 +1 @@
+../../../../common/include/linux/netdevice.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter.h
new file mode 120000
index 0000000..81c9328
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter.h
@@ -0,0 +1 @@
+../../../../common/include/linux/netfilter.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_common.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_common.h
new file mode 120000
index 0000000..840faca
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_common.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/nf_conntrack_common.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_ftp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_ftp.h
new file mode 120000
index 0000000..3a8e544
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_ftp.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/nf_conntrack_ftp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_sctp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_sctp.h
new file mode 120000
index 0000000..17c5b25
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_sctp.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/nf_conntrack_sctp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_tcp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_tcp.h
new file mode 120000
index 0000000..483187d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_tcp.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/nf_conntrack_tcp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_tuple_common.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_tuple_common.h
new file mode 120000
index 0000000..2335e58
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nf_conntrack_tuple_common.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/nf_conntrack_tuple_common.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nfnetlink.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nfnetlink.h
new file mode 120000
index 0000000..434215d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nfnetlink.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/nfnetlink.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nfnetlink_conntrack.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nfnetlink_conntrack.h
new file mode 120000
index 0000000..87cc812
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/nfnetlink_conntrack.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/nfnetlink_conntrack.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/x_tables.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/x_tables.h
new file mode 120000
index 0000000..d2b9746
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/x_tables.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/x_tables.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_CLASSIFY.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_CLASSIFY.h
new file mode 120000
index 0000000..a3b868a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_CLASSIFY.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_CLASSIFY.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_CONNMARK.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_CONNMARK.h
new file mode 120000
index 0000000..2b7e198
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_CONNMARK.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_CONNMARK.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_CONNSECMARK.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_CONNSECMARK.h
new file mode 120000
index 0000000..725dafb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_CONNSECMARK.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_CONNSECMARK.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_MARK.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_MARK.h
new file mode 120000
index 0000000..eaf3cd7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_MARK.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_MARK.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_NFQUEUE.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_NFQUEUE.h
new file mode 120000
index 0000000..851f571
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_NFQUEUE.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_NFQUEUE.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_SECMARK.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_SECMARK.h
new file mode 120000
index 0000000..02dfc1b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_SECMARK.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_SECMARK.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_comment.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_comment.h
new file mode 120000
index 0000000..141f426
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_comment.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_comment.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_connbytes.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_connbytes.h
new file mode 120000
index 0000000..7e67ee9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_connbytes.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_connbytes.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_connmark.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_connmark.h
new file mode 120000
index 0000000..2f70b94
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_connmark.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_connmark.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_conntrack.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_conntrack.h
new file mode 120000
index 0000000..04a1729
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_conntrack.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_conntrack.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_dccp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_dccp.h
new file mode 120000
index 0000000..6bdc874
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_dccp.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_dccp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_esp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_esp.h
new file mode 120000
index 0000000..a27d0cc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_esp.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_esp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_helper.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_helper.h
new file mode 120000
index 0000000..6b958db
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_helper.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_helper.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_length.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_length.h
new file mode 120000
index 0000000..680ef6b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_length.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_length.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_limit.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_limit.h
new file mode 120000
index 0000000..24bce98
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_limit.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_limit.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_mac.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_mac.h
new file mode 120000
index 0000000..24af1fc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_mac.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_mac.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_mark.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_mark.h
new file mode 120000
index 0000000..6ec390f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_mark.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_mark.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_multiport.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_multiport.h
new file mode 120000
index 0000000..80b337d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_multiport.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_multiport.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_physdev.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_physdev.h
new file mode 120000
index 0000000..c6ad18c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_physdev.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_physdev.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_pkttype.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_pkttype.h
new file mode 120000
index 0000000..3551c0d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_pkttype.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_pkttype.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_quota.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_quota.h
new file mode 120000
index 0000000..fc9f8b0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_quota.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_quota.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_realm.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_realm.h
new file mode 120000
index 0000000..7c0e5f6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_realm.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_realm.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_sctp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_sctp.h
new file mode 120000
index 0000000..cede7c7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_sctp.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_sctp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_state.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_state.h
new file mode 120000
index 0000000..3f2ee91
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_state.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_state.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_statistic.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_statistic.h
new file mode 120000
index 0000000..dc1fe25
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_statistic.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_statistic.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_string.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_string.h
new file mode 120000
index 0000000..c19bebe
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_string.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_string.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_tcpmss.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_tcpmss.h
new file mode 120000
index 0000000..90cf9d5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_tcpmss.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_tcpmss.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_tcpudp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_tcpudp.h
new file mode 120000
index 0000000..4e3f6b5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter/xt_tcpudp.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter/xt_tcpudp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_arp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_arp.h
new file mode 120000
index 0000000..e6172ef
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_arp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/netfilter_arp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_arp/arp_tables.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_arp/arp_tables.h
new file mode 120000
index 0000000..b31b8c2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_arp/arp_tables.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_arp/arp_tables.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_bridge.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_bridge.h
new file mode 120000
index 0000000..f582040
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_bridge.h
@@ -0,0 +1 @@
+../../../../common/include/linux/netfilter_bridge.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4.h
new file mode 120000
index 0000000..1daca65
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4.h
@@ -0,0 +1 @@
+../../../../common/include/linux/netfilter_ipv4.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_conntrack.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_conntrack.h
new file mode 120000
index 0000000..841b2e9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ip_conntrack.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_conntrack_tuple.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
new file mode 120000
index 0000000..109ccef
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_nat.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_nat.h
new file mode 120000
index 0000000..9b17b22
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_nat.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ip_nat.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_nat_rule.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_nat_rule.h
new file mode 120000
index 0000000..fe78e7f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_nat_rule.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ip_nat_rule.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_queue.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_queue.h
new file mode 120000
index 0000000..3ea52ca
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_queue.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ip_queue.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_tables.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_tables.h
new file mode 120000
index 0000000..0f8460d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ip_tables.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ip_tables.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_CLASSIFY.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_CLASSIFY.h
new file mode 120000
index 0000000..f908438
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_CLASSIFY.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_CLASSIFY.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_DSCP.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_DSCP.h
new file mode 120000
index 0000000..29058d2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_DSCP.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_DSCP.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_ECN.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_ECN.h
new file mode 120000
index 0000000..fc1128c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_ECN.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_ECN.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_LOG.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_LOG.h
new file mode 120000
index 0000000..b5dbb55
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_LOG.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_LOG.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_NFQUEUE.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_NFQUEUE.h
new file mode 120000
index 0000000..3686206
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_NFQUEUE.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_NFQUEUE.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_REJECT.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_REJECT.h
new file mode 120000
index 0000000..b3f1023
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_REJECT.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_REJECT.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_TCPMSS.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_TCPMSS.h
new file mode 120000
index 0000000..fd24f6a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_TCPMSS.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_TCPMSS.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_TOS.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_TOS.h
new file mode 120000
index 0000000..bb1a243
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_TOS.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_TOS.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_TTL.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_TTL.h
new file mode 120000
index 0000000..0ad1303
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_TTL.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_TTL.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_ULOG.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_ULOG.h
new file mode 120000
index 0000000..9cc45e5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_ULOG.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_ULOG.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_addrtype.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_addrtype.h
new file mode 120000
index 0000000..3b37d0b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_addrtype.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_addrtype.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_ah.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_ah.h
new file mode 120000
index 0000000..4b846fa
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_ah.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_ah.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_comment.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_comment.h
new file mode 120000
index 0000000..96a07ea
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_comment.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_comment.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_connbytes.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_connbytes.h
new file mode 120000
index 0000000..76120e8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_connbytes.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_connbytes.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_dccp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_dccp.h
new file mode 120000
index 0000000..9be071c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_dccp.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_dccp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_dscp_.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_dscp_.h
new file mode 120000
index 0000000..75879c3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_dscp_.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_dscp_.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_esp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_esp.h
new file mode 120000
index 0000000..9830294
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_esp.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_esp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_hashlimit.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_hashlimit.h
new file mode 120000
index 0000000..67cbcc1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_hashlimit.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_hashlimit.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_helper.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_helper.h
new file mode 120000
index 0000000..b7039dc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_helper.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_helper.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_iprange.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_iprange.h
new file mode 120000
index 0000000..d225d28
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_iprange.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_iprange.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_length.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_length.h
new file mode 120000
index 0000000..268a39e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_length.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_length.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_mac.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_mac.h
new file mode 120000
index 0000000..f3cae5b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_mac.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_mac.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_owner.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_owner.h
new file mode 120000
index 0000000..b082109
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_owner.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_owner.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_physdev.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_physdev.h
new file mode 120000
index 0000000..47258d4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_physdev.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_physdev.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_pkttype.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_pkttype.h
new file mode 120000
index 0000000..dc938c1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_pkttype.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_pkttype.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_realm.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_realm.h
new file mode 120000
index 0000000..c07b56d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_realm.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_realm.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_recent.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_recent.h
new file mode 120000
index 0000000..531cb56
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_recent.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_recent.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_sctp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_sctp.h
new file mode 120000
index 0000000..341f347
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_sctp.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_sctp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_state.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_state.h
new file mode 120000
index 0000000..da5187b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_state.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_state.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_string.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_string.h
new file mode 120000
index 0000000..12d23d4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_string.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_string.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_tos_.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_tos_.h
new file mode 120000
index 0000000..35348cc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv4/ipt_tos_.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv4/ipt_tos_.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6.h
new file mode 120000
index 0000000..0a37d5b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6.h
@@ -0,0 +1 @@
+../../../../common/include/linux/netfilter_ipv6.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6_tables.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6_tables.h
new file mode 120000
index 0000000..dbabff2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6_tables.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6_tables.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_HL.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_HL.h
new file mode 120000
index 0000000..9ade857
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_HL.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6t_HL.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_LOG.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_LOG.h
new file mode 120000
index 0000000..c7b27c9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_LOG.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6t_LOG.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_REJECT.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_REJECT.h
new file mode 120000
index 0000000..fcee66d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_REJECT.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6t_REJECT.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_ah.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_ah.h
new file mode 120000
index 0000000..79151b0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_ah.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6t_ah.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_esp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_esp.h
new file mode 120000
index 0000000..4f116b7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_esp.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6t_esp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_frag.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_frag.h
new file mode 120000
index 0000000..7375205
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_frag.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6t_frag.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_hl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_hl.h
new file mode 120000
index 0000000..d9ed353
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_hl.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6t_hl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_ipv6header.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_ipv6header.h
new file mode 120000
index 0000000..d3bc0ae
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_ipv6header.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6t_ipv6header.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_length.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_length.h
new file mode 120000
index 0000000..cc583e5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_length.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6t_length.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_mac.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_mac.h
new file mode 120000
index 0000000..edb21e3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_mac.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6t_mac.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_opts.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_opts.h
new file mode 120000
index 0000000..7dd0aec
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_opts.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6t_opts.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_owner.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_owner.h
new file mode 120000
index 0000000..cd6bbca
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_owner.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6t_owner.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_physdev.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_physdev.h
new file mode 120000
index 0000000..72d42c8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_physdev.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6t_physdev.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_rt.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_rt.h
new file mode 120000
index 0000000..0ade394
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netfilter_ipv6/ip6t_rt.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/netfilter_ipv6/ip6t_rt.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netlink.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netlink.h
new file mode 120000
index 0000000..91610b8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/netlink.h
@@ -0,0 +1 @@
+../../../../common/include/linux/netlink.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs.h
new file mode 120000
index 0000000..a055478
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs.h
@@ -0,0 +1 @@
+../../../../common/include/linux/nfs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs2.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs2.h
new file mode 120000
index 0000000..c3a9509
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs2.h
@@ -0,0 +1 @@
+../../../../common/include/linux/nfs2.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs3.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs3.h
new file mode 120000
index 0000000..4cd8d7a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs3.h
@@ -0,0 +1 @@
+../../../../common/include/linux/nfs3.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs4.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs4.h
new file mode 120000
index 0000000..4649859
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs4.h
@@ -0,0 +1 @@
+../../../../common/include/linux/nfs4.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs_xdr.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs_xdr.h
new file mode 120000
index 0000000..2f6de25
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfs_xdr.h
@@ -0,0 +1 @@
+../../../../common/include/linux/nfs_xdr.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsacl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsacl.h
new file mode 120000
index 0000000..c44aa13
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsacl.h
@@ -0,0 +1 @@
+../../../../common/include/linux/nfsacl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/auth.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/auth.h
new file mode 120000
index 0000000..f68aa51
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/auth.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/nfsd/auth.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/const.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/const.h
new file mode 120000
index 0000000..fe65cf4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/const.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/nfsd/const.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/debug.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/debug.h
new file mode 120000
index 0000000..789ca95
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/debug.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/nfsd/debug.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/export.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/export.h
new file mode 120000
index 0000000..811763b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/export.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/nfsd/export.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/interface.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/interface.h
new file mode 120000
index 0000000..b19512d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/interface.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/nfsd/interface.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/nfsfh.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/nfsfh.h
new file mode 120000
index 0000000..9f3e60d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/nfsfh.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/nfsd/nfsfh.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/stats.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/stats.h
new file mode 120000
index 0000000..744e2fb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/stats.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/nfsd/stats.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/xdr.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/xdr.h
new file mode 120000
index 0000000..46d7928
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nfsd/xdr.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/nfsd/xdr.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/node.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/node.h
new file mode 120000
index 0000000..e67c59f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/node.h
@@ -0,0 +1 @@
+../../../../common/include/linux/node.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nodemask.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nodemask.h
new file mode 120000
index 0000000..356c720
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nodemask.h
@@ -0,0 +1 @@
+../../../../common/include/linux/nodemask.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/notifier.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/notifier.h
new file mode 120000
index 0000000..a0dfdcf
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/notifier.h
@@ -0,0 +1 @@
+../../../../common/include/linux/notifier.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/numa.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/numa.h
new file mode 120000
index 0000000..f0549f0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/numa.h
@@ -0,0 +1 @@
+../../../../common/include/linux/numa.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nvram.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nvram.h
new file mode 120000
index 0000000..e2bce31
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/nvram.h
@@ -0,0 +1 @@
+../../../../common/include/linux/nvram.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/omap_csmi.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/omap_csmi.h
new file mode 120000
index 0000000..0d2c516
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/omap_csmi.h
@@ -0,0 +1 @@
+../../../../common/include/linux/omap_csmi.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pagemap.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pagemap.h
new file mode 120000
index 0000000..3545504
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pagemap.h
@@ -0,0 +1 @@
+../../../../common/include/linux/pagemap.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/param.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/param.h
new file mode 120000
index 0000000..edd8f98
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/param.h
@@ -0,0 +1 @@
+../../../../common/include/linux/param.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/patchkey.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/patchkey.h
new file mode 120000
index 0000000..628a75c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/patchkey.h
@@ -0,0 +1 @@
+../../../../common/include/linux/patchkey.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pci.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pci.h
new file mode 120000
index 0000000..22b0ec7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pci.h
@@ -0,0 +1 @@
+../../../../common/include/linux/pci.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pci_ids.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pci_ids.h
new file mode 120000
index 0000000..c3475fb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pci_ids.h
@@ -0,0 +1 @@
+../../../../common/include/linux/pci_ids.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pci_regs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pci_regs.h
new file mode 120000
index 0000000..853c226
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pci_regs.h
@@ -0,0 +1 @@
+../../../../common/include/linux/pci_regs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/percpu.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/percpu.h
new file mode 120000
index 0000000..93d6b27
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/percpu.h
@@ -0,0 +1 @@
+../../../../common/include/linux/percpu.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/percpu_counter.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/percpu_counter.h
new file mode 120000
index 0000000..6c839d4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/percpu_counter.h
@@ -0,0 +1 @@
+../../../../common/include/linux/percpu_counter.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/personality.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/personality.h
new file mode 120000
index 0000000..0d6b659
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/personality.h
@@ -0,0 +1 @@
+../../../../common/include/linux/personality.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pfkeyv2.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pfkeyv2.h
new file mode 120000
index 0000000..321bbb6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pfkeyv2.h
@@ -0,0 +1 @@
+../../../../common/include/linux/pfkeyv2.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pkt_cls.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pkt_cls.h
new file mode 120000
index 0000000..58e8899
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pkt_cls.h
@@ -0,0 +1 @@
+../../../../common/include/linux/pkt_cls.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pkt_sched.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pkt_sched.h
new file mode 120000
index 0000000..77b5a47
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pkt_sched.h
@@ -0,0 +1 @@
+../../../../common/include/linux/pkt_sched.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/platform_device.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/platform_device.h
new file mode 120000
index 0000000..baa7b55
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/platform_device.h
@@ -0,0 +1 @@
+../../../../common/include/linux/platform_device.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/plist.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/plist.h
new file mode 120000
index 0000000..4d4e542
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/plist.h
@@ -0,0 +1 @@
+../../../../common/include/linux/plist.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pm.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pm.h
new file mode 120000
index 0000000..1a4339e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pm.h
@@ -0,0 +1 @@
+../../../../common/include/linux/pm.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pnp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pnp.h
new file mode 120000
index 0000000..d7e1bb9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/pnp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/pnp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/poll.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/poll.h
new file mode 120000
index 0000000..23c4b3f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/poll.h
@@ -0,0 +1 @@
+../../../../common/include/linux/poll.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/posix_acl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/posix_acl.h
new file mode 120000
index 0000000..29ae7cd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/posix_acl.h
@@ -0,0 +1 @@
+../../../../common/include/linux/posix_acl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/posix_types.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/posix_types.h
new file mode 120000
index 0000000..bcbcf00
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/posix_types.h
@@ -0,0 +1 @@
+../../../../common/include/linux/posix_types.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ppdev.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ppdev.h
new file mode 120000
index 0000000..3b386a6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ppdev.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ppdev.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ppp_defs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ppp_defs.h
new file mode 120000
index 0000000..309a3d0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ppp_defs.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ppp_defs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/prctl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/prctl.h
new file mode 120000
index 0000000..8bbe96c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/prctl.h
@@ -0,0 +1 @@
+../../../../common/include/linux/prctl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/preempt.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/preempt.h
new file mode 120000
index 0000000..9b59fe3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/preempt.h
@@ -0,0 +1 @@
+../../../../common/include/linux/preempt.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/proc_fs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/proc_fs.h
new file mode 120000
index 0000000..6d310c4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/proc_fs.h
@@ -0,0 +1 @@
+../../../../common/include/linux/proc_fs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ptrace.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ptrace.h
new file mode 120000
index 0000000..2617a6c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ptrace.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ptrace.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/qic117.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/qic117.h
new file mode 120000
index 0000000..7223064
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/qic117.h
@@ -0,0 +1 @@
+../../../../common/include/linux/qic117.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/qnxtypes.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/qnxtypes.h
new file mode 120000
index 0000000..5c767a3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/qnxtypes.h
@@ -0,0 +1 @@
+../../../../common/include/linux/qnxtypes.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/quota.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/quota.h
new file mode 120000
index 0000000..ed68365
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/quota.h
@@ -0,0 +1 @@
+../../../../common/include/linux/quota.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/md.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/md.h
new file mode 120000
index 0000000..e8599ef
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/md.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/raid/md.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/md_k.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/md_k.h
new file mode 120000
index 0000000..20f8ca6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/md_k.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/raid/md_k.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/md_p.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/md_p.h
new file mode 120000
index 0000000..f631a38
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/md_p.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/raid/md_p.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/md_u.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/md_u.h
new file mode 120000
index 0000000..931271c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/md_u.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/raid/md_u.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/xor.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/xor.h
new file mode 120000
index 0000000..b02a69a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/raid/xor.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/raid/xor.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/random.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/random.h
new file mode 120000
index 0000000..0088784
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/random.h
@@ -0,0 +1 @@
+../../../../common/include/linux/random.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rbtree.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rbtree.h
new file mode 120000
index 0000000..f606d94
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rbtree.h
@@ -0,0 +1 @@
+../../../../common/include/linux/rbtree.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rcupdate.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rcupdate.h
new file mode 120000
index 0000000..e93235d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rcupdate.h
@@ -0,0 +1 @@
+../../../../common/include/linux/rcupdate.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/reboot.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/reboot.h
new file mode 120000
index 0000000..c3b86f4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/reboot.h
@@ -0,0 +1 @@
+../../../../common/include/linux/reboot.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/relay.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/relay.h
new file mode 120000
index 0000000..c354e19
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/relay.h
@@ -0,0 +1 @@
+../../../../common/include/linux/relay.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/resource.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/resource.h
new file mode 120000
index 0000000..80a9f86
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/resource.h
@@ -0,0 +1 @@
+../../../../common/include/linux/resource.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/route.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/route.h
new file mode 120000
index 0000000..c81b220
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/route.h
@@ -0,0 +1 @@
+../../../../common/include/linux/route.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rtc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rtc.h
new file mode 120000
index 0000000..eaeecd3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rtc.h
@@ -0,0 +1 @@
+../../../../common/include/linux/rtc.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rtnetlink.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rtnetlink.h
new file mode 120000
index 0000000..064a3d2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rtnetlink.h
@@ -0,0 +1 @@
+../../../../common/include/linux/rtnetlink.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rwsem.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rwsem.h
new file mode 120000
index 0000000..68eab47
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/rwsem.h
@@ -0,0 +1 @@
+../../../../common/include/linux/rwsem.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sched.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sched.h
new file mode 120000
index 0000000..e8ff88b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sched.h
@@ -0,0 +1 @@
+../../../../common/include/linux/sched.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sem.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sem.h
new file mode 120000
index 0000000..5348418
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sem.h
@@ -0,0 +1 @@
+../../../../common/include/linux/sem.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/seq_file.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/seq_file.h
new file mode 120000
index 0000000..2c25e6c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/seq_file.h
@@ -0,0 +1 @@
+../../../../common/include/linux/seq_file.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/seqlock.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/seqlock.h
new file mode 120000
index 0000000..345108e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/seqlock.h
@@ -0,0 +1 @@
+../../../../common/include/linux/seqlock.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/serial_core.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/serial_core.h
new file mode 120000
index 0000000..be40c9a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/serial_core.h
@@ -0,0 +1 @@
+../../../../common/include/linux/serial_core.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/serial_reg.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/serial_reg.h
new file mode 120000
index 0000000..60bd137
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/serial_reg.h
@@ -0,0 +1 @@
+../../../../common/include/linux/serial_reg.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/serio.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/serio.h
new file mode 120000
index 0000000..4d3b062
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/serio.h
@@ -0,0 +1 @@
+../../../../common/include/linux/serio.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/shm.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/shm.h
new file mode 120000
index 0000000..4cd2df0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/shm.h
@@ -0,0 +1 @@
+../../../../common/include/linux/shm.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/signal.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/signal.h
new file mode 120000
index 0000000..10e9b01
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/signal.h
@@ -0,0 +1 @@
+../../../../common/include/linux/signal.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/skbuff.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/skbuff.h
new file mode 120000
index 0000000..5ff4983
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/skbuff.h
@@ -0,0 +1 @@
+../../../../common/include/linux/skbuff.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/slab.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/slab.h
new file mode 120000
index 0000000..04f089d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/slab.h
@@ -0,0 +1 @@
+../../../../common/include/linux/slab.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/smb.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/smb.h
new file mode 120000
index 0000000..3f1cf22
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/smb.h
@@ -0,0 +1 @@
+../../../../common/include/linux/smb.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/smp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/smp.h
new file mode 120000
index 0000000..bfa5942
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/smp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/smp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/smp_lock.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/smp_lock.h
new file mode 120000
index 0000000..76d4cb0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/smp_lock.h
@@ -0,0 +1 @@
+../../../../common/include/linux/smp_lock.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/socket.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/socket.h
new file mode 120000
index 0000000..edc366f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/socket.h
@@ -0,0 +1 @@
+../../../../common/include/linux/socket.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sockios.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sockios.h
new file mode 120000
index 0000000..793adfb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sockios.h
@@ -0,0 +1 @@
+../../../../common/include/linux/sockios.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/soundcard.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/soundcard.h
new file mode 120000
index 0000000..ca37579
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/soundcard.h
@@ -0,0 +1 @@
+../../../../common/include/linux/soundcard.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock.h
new file mode 120000
index 0000000..305c46d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock.h
@@ -0,0 +1 @@
+../../../../common/include/linux/spinlock.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_api_smp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_api_smp.h
new file mode 120000
index 0000000..45bfb4e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_api_smp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/spinlock_api_smp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_api_up.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_api_up.h
new file mode 120000
index 0000000..b54532e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_api_up.h
@@ -0,0 +1 @@
+../../../../common/include/linux/spinlock_api_up.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_types.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_types.h
new file mode 120000
index 0000000..39611b7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_types.h
@@ -0,0 +1 @@
+../../../../common/include/linux/spinlock_types.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_types_up.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_types_up.h
new file mode 120000
index 0000000..d5384d7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_types_up.h
@@ -0,0 +1 @@
+../../../../common/include/linux/spinlock_types_up.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_up.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_up.h
new file mode 120000
index 0000000..46b3c0e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/spinlock_up.h
@@ -0,0 +1 @@
+../../../../common/include/linux/spinlock_up.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/stacktrace.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/stacktrace.h
new file mode 120000
index 0000000..4c18232
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/stacktrace.h
@@ -0,0 +1 @@
+../../../../common/include/linux/stacktrace.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/stat.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/stat.h
new file mode 120000
index 0000000..842159b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/stat.h
@@ -0,0 +1 @@
+../../../../common/include/linux/stat.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/statfs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/statfs.h
new file mode 120000
index 0000000..4ac3b01
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/statfs.h
@@ -0,0 +1 @@
+../../../../common/include/linux/statfs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/stddef.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/stddef.h
new file mode 120000
index 0000000..9b398f1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/stddef.h
@@ -0,0 +1 @@
+../../../../common/include/linux/stddef.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/string.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/string.h
new file mode 120000
index 0000000..414748f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/string.h
@@ -0,0 +1 @@
+../../../../common/include/linux/string.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/stringify.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/stringify.h
new file mode 120000
index 0000000..44dd7ed
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/stringify.h
@@ -0,0 +1 @@
+../../../../common/include/linux/stringify.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/auth.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/auth.h
new file mode 120000
index 0000000..1fbe34f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/auth.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/auth.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/auth_gss.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/auth_gss.h
new file mode 120000
index 0000000..7bc8ad1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/auth_gss.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/auth_gss.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/clnt.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/clnt.h
new file mode 120000
index 0000000..7f11a93
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/clnt.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/clnt.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/debug.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/debug.h
new file mode 120000
index 0000000..c95a429
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/debug.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/debug.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/gss_api.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/gss_api.h
new file mode 120000
index 0000000..e10eba6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/gss_api.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/gss_api.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/gss_asn1.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/gss_asn1.h
new file mode 120000
index 0000000..e860f8e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/gss_asn1.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/gss_asn1.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/gss_err.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/gss_err.h
new file mode 120000
index 0000000..72c7141
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/gss_err.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/gss_err.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/msg_prot.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/msg_prot.h
new file mode 120000
index 0000000..d9cb9ae
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/msg_prot.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/msg_prot.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/sched.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/sched.h
new file mode 120000
index 0000000..84791a7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/sched.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/sched.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/stats.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/stats.h
new file mode 120000
index 0000000..b115bd5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/stats.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/stats.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/svc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/svc.h
new file mode 120000
index 0000000..658a81e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/svc.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/svc.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/svcauth.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/svcauth.h
new file mode 120000
index 0000000..8c3e841
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/svcauth.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/svcauth.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/timer.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/timer.h
new file mode 120000
index 0000000..ce8709d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/timer.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/timer.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/types.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/types.h
new file mode 120000
index 0000000..e7f7656
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/types.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/types.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/xdr.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/xdr.h
new file mode 120000
index 0000000..163e618
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/xdr.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/xdr.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/xprt.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/xprt.h
new file mode 120000
index 0000000..6d29148
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sunrpc/xprt.h
@@ -0,0 +1 @@
+../../../../../common/include/linux/sunrpc/xprt.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/swap.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/swap.h
new file mode 120000
index 0000000..47db73a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/swap.h
@@ -0,0 +1 @@
+../../../../common/include/linux/swap.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sysctl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sysctl.h
new file mode 120000
index 0000000..1252a53
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sysctl.h
@@ -0,0 +1 @@
+../../../../common/include/linux/sysctl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sysdev.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sysdev.h
new file mode 120000
index 0000000..6691343
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sysdev.h
@@ -0,0 +1 @@
+../../../../common/include/linux/sysdev.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sysfs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sysfs.h
new file mode 120000
index 0000000..0cbaad8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/sysfs.h
@@ -0,0 +1 @@
+../../../../common/include/linux/sysfs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/taskstats.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/taskstats.h
new file mode 120000
index 0000000..24a178e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/taskstats.h
@@ -0,0 +1 @@
+../../../../common/include/linux/taskstats.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/taskstats_kern.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/taskstats_kern.h
new file mode 120000
index 0000000..20b2c64
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/taskstats_kern.h
@@ -0,0 +1 @@
+../../../../common/include/linux/taskstats_kern.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/tcp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/tcp.h
new file mode 120000
index 0000000..417237a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/tcp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/tcp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/telephony.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/telephony.h
new file mode 120000
index 0000000..44b4c18
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/telephony.h
@@ -0,0 +1 @@
+../../../../common/include/linux/telephony.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/termios.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/termios.h
new file mode 120000
index 0000000..968db97
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/termios.h
@@ -0,0 +1 @@
+../../../../common/include/linux/termios.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/textsearch.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/textsearch.h
new file mode 120000
index 0000000..e033273
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/textsearch.h
@@ -0,0 +1 @@
+../../../../common/include/linux/textsearch.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/thread_info.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/thread_info.h
new file mode 120000
index 0000000..11a1011
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/thread_info.h
@@ -0,0 +1 @@
+../../../../common/include/linux/thread_info.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/threads.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/threads.h
new file mode 120000
index 0000000..ef3237e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/threads.h
@@ -0,0 +1 @@
+../../../../common/include/linux/threads.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/time.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/time.h
new file mode 120000
index 0000000..2060843
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/time.h
@@ -0,0 +1 @@
+../../../../common/include/linux/time.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/timer.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/timer.h
new file mode 120000
index 0000000..f81d907
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/timer.h
@@ -0,0 +1 @@
+../../../../common/include/linux/timer.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/times.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/times.h
new file mode 120000
index 0000000..8757201
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/times.h
@@ -0,0 +1 @@
+../../../../common/include/linux/times.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/timex.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/timex.h
new file mode 120000
index 0000000..49e520b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/timex.h
@@ -0,0 +1 @@
+../../../../common/include/linux/timex.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/tiocl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/tiocl.h
new file mode 120000
index 0000000..ae6102b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/tiocl.h
@@ -0,0 +1 @@
+../../../../common/include/linux/tiocl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/transport_class.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/transport_class.h
new file mode 120000
index 0000000..735b69b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/transport_class.h
@@ -0,0 +1 @@
+../../../../common/include/linux/transport_class.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/tty.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/tty.h
new file mode 120000
index 0000000..4e874bf
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/tty.h
@@ -0,0 +1 @@
+../../../../common/include/linux/tty.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/types.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/types.h
new file mode 120000
index 0000000..76b2511
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/types.h
@@ -0,0 +1 @@
+../../../../common/include/linux/types.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/udp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/udp.h
new file mode 120000
index 0000000..14ee4b2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/udp.h
@@ -0,0 +1 @@
+../../../../common/include/linux/udp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ufs_fs_i.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ufs_fs_i.h
new file mode 120000
index 0000000..de767a7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ufs_fs_i.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ufs_fs_i.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ufs_fs_sb.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ufs_fs_sb.h
new file mode 120000
index 0000000..a78b9d3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/ufs_fs_sb.h
@@ -0,0 +1 @@
+../../../../common/include/linux/ufs_fs_sb.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/uio.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/uio.h
new file mode 120000
index 0000000..95a105d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/uio.h
@@ -0,0 +1 @@
+../../../../common/include/linux/uio.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/un.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/un.h
new file mode 120000
index 0000000..6d51e94
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/un.h
@@ -0,0 +1 @@
+../../../../common/include/linux/un.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/unistd.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/unistd.h
new file mode 120000
index 0000000..7ef4a0d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/unistd.h
@@ -0,0 +1 @@
+../../../../common/include/linux/unistd.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/usb.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/usb.h
new file mode 120000
index 0000000..7da27d7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/usb.h
@@ -0,0 +1 @@
+../../../../common/include/linux/usb.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/usb_ch9.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/usb_ch9.h
new file mode 120000
index 0000000..d8a2655
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/usb_ch9.h
@@ -0,0 +1 @@
+../../../../common/include/linux/usb_ch9.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/usbdevice_fs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/usbdevice_fs.h
new file mode 120000
index 0000000..b4c8de8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/usbdevice_fs.h
@@ -0,0 +1 @@
+../../../../common/include/linux/usbdevice_fs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/user.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/user.h
new file mode 120000
index 0000000..2bb072e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/user.h
@@ -0,0 +1 @@
+../../../../common/include/linux/user.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/utime.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/utime.h
new file mode 120000
index 0000000..c483c28
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/utime.h
@@ -0,0 +1 @@
+../../../../common/include/linux/utime.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/utsname.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/utsname.h
new file mode 120000
index 0000000..8b0a098
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/utsname.h
@@ -0,0 +1 @@
+../../../../common/include/linux/utsname.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/version.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/version.h
new file mode 120000
index 0000000..cb2ac62
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/version.h
@@ -0,0 +1 @@
+../../../../common/include/linux/version.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/vfs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/vfs.h
new file mode 120000
index 0000000..b815962
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/vfs.h
@@ -0,0 +1 @@
+../../../../common/include/linux/vfs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/videodev.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/videodev.h
new file mode 120000
index 0000000..33e8651
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/videodev.h
@@ -0,0 +1 @@
+../../../../common/include/linux/videodev.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/videodev2.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/videodev2.h
new file mode 120000
index 0000000..9127b40
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/videodev2.h
@@ -0,0 +1 @@
+../../../../common/include/linux/videodev2.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/vmalloc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/vmalloc.h
new file mode 120000
index 0000000..90410fc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/vmalloc.h
@@ -0,0 +1 @@
+../../../../common/include/linux/vmalloc.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/vt.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/vt.h
new file mode 120000
index 0000000..5f1333a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/vt.h
@@ -0,0 +1 @@
+../../../../common/include/linux/vt.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/vt_buffer.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/vt_buffer.h
new file mode 120000
index 0000000..babe241
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/vt_buffer.h
@@ -0,0 +1 @@
+../../../../common/include/linux/vt_buffer.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/wait.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/wait.h
new file mode 120000
index 0000000..ee2730b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/wait.h
@@ -0,0 +1 @@
+../../../../common/include/linux/wait.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/wanrouter.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/wanrouter.h
new file mode 120000
index 0000000..1d1b8f1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/wanrouter.h
@@ -0,0 +1 @@
+../../../../common/include/linux/wanrouter.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/wireless.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/wireless.h
new file mode 120000
index 0000000..43983b5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/wireless.h
@@ -0,0 +1 @@
+../../../../common/include/linux/wireless.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/workqueue.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/workqueue.h
new file mode 120000
index 0000000..3ce0512
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/workqueue.h
@@ -0,0 +1 @@
+../../../../common/include/linux/workqueue.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/xattr.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/xattr.h
new file mode 120000
index 0000000..8cf8b0b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/xattr.h
@@ -0,0 +1 @@
+../../../../common/include/linux/xattr.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/zconf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/zconf.h
new file mode 120000
index 0000000..4dc29e6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/zconf.h
@@ -0,0 +1 @@
+../../../../common/include/linux/zconf.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/zlib.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/zlib.h
new file mode 120000
index 0000000..9d45319
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/zlib.h
@@ -0,0 +1 @@
+../../../../common/include/linux/zlib.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/zorro_ids.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/zorro_ids.h
new file mode 120000
index 0000000..f2220c0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/linux/zorro_ids.h
@@ -0,0 +1 @@
+../../../../common/include/linux/zorro_ids.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/locale.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/locale.h
new file mode 120000
index 0000000..26247fd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/locale.h
@@ -0,0 +1 @@
+../../../common/include/locale.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/_types.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/_types.h
new file mode 100644
index 0000000..6d10e12
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/_types.h
@@ -0,0 +1,127 @@
+/*	$OpenBSD: _types.h,v 1.3 2006/02/14 18:12:58 miod Exp $	*/
+
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)types.h	8.3 (Berkeley) 1/5/94
+ *	@(#)ansi.h	8.2 (Berkeley) 1/4/94
+ */
+
+#ifndef _ARM__TYPES_H_
+#define _ARM__TYPES_H_
+
+
+#if !defined(__ARM_EABI__)
+/* the kernel defines size_t as unsigned int, but g++ wants it to be unsigned long */
+#define _SIZE_T
+#define _SSIZE_T
+#define _PTRDIFF_T
+typedef unsigned long  size_t;
+typedef long           ssize_t;
+typedef long           ptrdiff_t;
+#endif
+
+//#include <linux/types.h>
+
+/* 7.18.1.1 Exact-width integer types */
+typedef	__signed char		__int8_t;
+typedef	unsigned char		__uint8_t;
+typedef	short			__int16_t;
+typedef	unsigned short		__uint16_t;
+typedef	int			__int32_t;
+typedef	unsigned int		__uint32_t;
+/* LONGLONG */
+typedef	long long		__int64_t;
+/* LONGLONG */
+typedef	unsigned long long	__uint64_t;
+
+/* 7.18.1.2 Minimum-width integer types */
+typedef	__int8_t		__int_least8_t;
+typedef	__uint8_t		__uint_least8_t;
+typedef	__int16_t		__int_least16_t;
+typedef	__uint16_t		__uint_least16_t;
+typedef	__int32_t		__int_least32_t;
+typedef	__uint32_t		__uint_least32_t;
+typedef	__int64_t		__int_least64_t;
+typedef	__uint64_t		__uint_least64_t;
+
+/* 7.18.1.3 Fastest minimum-width integer types */
+typedef	__int32_t		__int_fast8_t;
+typedef	__uint32_t		__uint_fast8_t;
+typedef	__int32_t		__int_fast16_t;
+typedef	__uint32_t		__uint_fast16_t;
+typedef	__int32_t		__int_fast32_t;
+typedef	__uint32_t		__uint_fast32_t;
+typedef	__int64_t		__int_fast64_t;
+typedef	__uint64_t		__uint_fast64_t;
+
+/* 7.18.1.4 Integer types capable of holding object pointers */
+typedef	int 			__intptr_t;
+typedef	unsigned int 		__uintptr_t;
+
+/* 7.18.1.5 Greatest-width integer types */
+typedef	__int64_t		__intmax_t;
+typedef	__uint64_t		__uintmax_t;
+
+/* Register size */
+typedef __int32_t		__register_t;
+
+/* VM system types */
+typedef unsigned long		__vaddr_t;
+typedef unsigned long		__paddr_t;
+typedef unsigned long		__vsize_t;
+typedef unsigned long		__psize_t;
+
+/* Standard system types */
+typedef int			__clock_t;
+typedef int			__clockid_t;
+typedef long			__ptrdiff_t;
+typedef	int			__time_t;
+typedef int			__timer_t;
+#if defined(__GNUC__) && __GNUC__ >= 3
+typedef	__builtin_va_list	__va_list;
+#else
+typedef	char *			__va_list;
+#endif
+
+/* Wide character support types */
+#ifndef __cplusplus
+typedef	int			__wchar_t;
+#endif
+typedef int			__wint_t;
+typedef	int			__rune_t;
+typedef	void *			__wctrans_t;
+typedef	void *			__wctype_t;
+
+#ifdef __ARMEB__
+#define _BYTE_ORDER _BIG_ENDIAN
+#else
+#define _BYTE_ORDER _LITTLE_ENDIAN
+#endif
+
+#endif	/* _ARM__TYPES_H_ */
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/asm.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/asm.h
new file mode 100644
index 0000000..c7bd017
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/asm.h
@@ -0,0 +1,130 @@
+/*	$OpenBSD: asm.h,v 1.1 2004/02/01 05:09:49 drahn Exp $	*/
+/*	$NetBSD: asm.h,v 1.4 2001/07/16 05:43:32 matt Exp $	*/
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	from: @(#)asm.h	5.5 (Berkeley) 5/7/91
+ */
+
+#ifndef _ARM32_ASM_H_
+#define _ARM32_ASM_H_
+
+#ifdef __ELF__
+# define _C_LABEL(x)	x
+#else
+# ifdef __STDC__
+#  define _C_LABEL(x)	_ ## x
+# else
+#  define _C_LABEL(x)	_/**/x
+# endif
+#endif
+#define	_ASM_LABEL(x)	x
+
+#ifdef __STDC__
+# define __CONCAT(x,y)	x ## y
+# define __STRING(x)	#x
+#else
+# define __CONCAT(x,y)	x/**/y
+# define __STRING(x)	"x"
+#endif
+
+#ifndef _ALIGN_TEXT
+# define _ALIGN_TEXT .align 0
+#endif
+
+/*
+ * gas/arm uses @ as a single comment character and thus cannot be used here
+ * Instead it recognised the # instead of an @ symbols in .type directives
+ * We define a couple of macros so that assembly code will not be dependant
+ * on one or the other.
+ */
+#define _ASM_TYPE_FUNCTION	#function
+#define _ASM_TYPE_OBJECT	#object
+#define _ENTRY(x) \
+	.text; _ALIGN_TEXT; .globl x; .type x,_ASM_TYPE_FUNCTION; x:
+
+#ifdef GPROF
+# ifdef __ELF__
+#  define _PROF_PROLOGUE	\
+	mov ip, lr; bl __mcount
+# else
+#  define _PROF_PROLOGUE	\
+	mov ip,lr; bl mcount
+# endif
+#else
+# define _PROF_PROLOGUE
+#endif
+
+#define	ENTRY(y)	_ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
+#define	ENTRY_NP(y)	_ENTRY(_C_LABEL(y))
+#define	ASENTRY(y)	_ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
+#define	ASENTRY_NP(y)	_ENTRY(_ASM_LABEL(y))
+
+#define	ASMSTR		.asciz
+
+#if defined(__ELF__) && defined(PIC)
+#ifdef __STDC__
+#define	PIC_SYM(x,y)	x ## ( ## y ## )
+#else
+#define	PIC_SYM(x,y)	x/**/(/**/y/**/)
+#endif
+#else
+#define	PIC_SYM(x,y)	x
+#endif
+
+#ifdef __ELF__
+#define RCSID(x)	.section ".ident"; .asciz x
+#else
+#define RCSID(x)	.text; .asciz x
+#endif
+
+#ifdef __ELF__
+#define	WEAK_ALIAS(alias,sym)						\
+	.weak alias;							\
+	alias = sym
+#endif
+
+#ifdef __STDC__
+#define	WARN_REFERENCES(sym,msg)					\
+	.stabs msg ## ,30,0,0,0 ;					\
+	.stabs __STRING(_C_LABEL(sym)) ## ,1,0,0,0
+#elif defined(__ELF__)
+#define	WARN_REFERENCES(sym,msg)					\
+	.stabs msg,30,0,0,0 ;						\
+	.stabs __STRING(sym),1,0,0,0
+#else
+#define	WARN_REFERENCES(sym,msg)					\
+	.stabs msg,30,0,0,0 ;						\
+	.stabs __STRING(_/**/sym),1,0,0,0
+#endif /* __STDC__ */
+
+#endif /* !_ARM_ASM_H_ */
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/cdefs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/cdefs.h
new file mode 100644
index 0000000..44f1542
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/cdefs.h
@@ -0,0 +1,19 @@
+/*	$OpenBSD: cdefs.h,v 1.2 2005/11/24 20:46:44 deraadt Exp $	*/
+
+#ifndef	_MACHINE_CDEFS_H_
+#define	_MACHINE_CDEFS_H_
+
+#if defined(lint)
+#define __indr_reference(sym,alias)	__lint_equal__(sym,alias)
+#define __warn_references(sym,msg)
+#define __weak_alias(alias,sym)		__lint_equal__(sym,alias)
+#elif defined(__GNUC__) && defined(__STDC__)
+#define __weak_alias(alias,sym)					\
+	__asm__(".weak " __STRING(alias) " ; " __STRING(alias)	\
+	    " = " __STRING(sym));
+#define	__warn_references(sym,msg)				\
+	__asm__(".section .gnu.warning." __STRING(sym)		\
+	    " ; .ascii \"" msg "\" ; .text");
+#endif
+
+#endif /* !_MACHINE_CDEFS_H_ */
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/cpu-features.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/cpu-features.h
new file mode 100644
index 0000000..f836006
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/cpu-features.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _ARM_MACHINE_CPU_FEATURES_H
+#define _ARM_MACHINE_CPU_FEATURES_H
+
+/* The purpose of this file is to define several macros corresponding
+ * to CPU features that may or may not be available at build time on
+ * on the target CPU.
+ *
+ * This is done to abstract us from the various ARM Architecture
+ * quirks and alphabet soup.
+ *
+ * IMPORTANT: We have no intention to support anything below an ARMv4T !
+ */
+
+/* _ARM_ARCH_REVISION is a number corresponding to the ARM revision
+ * we're going to support
+ *
+ * it looks like our toolchain doesn't define __ARM_ARCH__
+ * so try to guess it.
+ *
+ *
+ *
+ */
+#ifndef __ARM_ARCH__
+
+#  if defined __ARM_ARCH_7__   || defined __ARM_ARCH_7A__ || \
+      defined __ARM_ARCH_7R__  || defined __ARM_ARCH_7M__
+
+#    define __ARM_ARCH__ 7
+
+#  elif defined __ARM_ARCH_6__   || defined __ARM_ARCH_6J__ || \
+      defined __ARM_ARCH_6K__  || defined __ARM_ARCH_6Z__ || \
+      defined __ARM_ARCH_6KZ__ || defined __ARM_ARCH_6T2__
+#
+#    define __ARM_ARCH__ 6
+#
+#  elif defined __ARM_ARCH_5__ || defined __ARM_ARCH_5T__ || \
+        defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__
+#
+#    define __ARM_ARCH__ 5
+#
+#  elif defined __ARM_ARCH_4T__
+#
+#    define __ARM_ARCH__ 4
+#
+#  elif defined __ARM_ARCH_4__
+#    error ARMv4 is not supported, please use ARMv4T at a minimum
+#  else
+#    error Unknown or unsupported ARM architecture
+#  endif
+#endif
+
+/* experimental feature used to check that our ARMv4 workarounds
+ * work correctly without a real ARMv4 machine */
+#ifdef BIONIC_EXPERIMENTAL_FORCE_ARMV4
+#  undef  __ARM_ARCH__
+#  define __ARM_ARCH__  4
+#endif
+
+/* define __ARM_HAVE_5TE if we have the ARMv5TE instructions */
+#if __ARM_ARCH__ > 5
+#  define  __ARM_HAVE_5TE  1
+#elif __ARM_ARCH__ == 5
+#  if defined __ARM_ARCH_5TE__ || defined __ARM_ARCH_5TEJ__
+#    define __ARM_HAVE_5TE  1
+#  endif
+#endif
+
+/* instructions introduced in ARMv5 */
+#if __ARM_ARCH__ >= 5
+#  define  __ARM_HAVE_BLX  1
+#  define  __ARM_HAVE_CLZ  1
+#  define  __ARM_HAVE_LDC2 1
+#  define  __ARM_HAVE_MCR2 1
+#  define  __ARM_HAVE_MRC2 1
+#  define  __ARM_HAVE_STC2 1
+#endif
+
+/* ARMv5TE introduces a few instructions */
+#if __ARM_HAVE_5TE
+#  define  __ARM_HAVE_PLD   1
+#  define  __ARM_HAVE_MCRR  1
+#  define  __ARM_HAVE_MRRC  1
+#endif
+
+/* define __ARM_HAVE_HALFWORD_MULTIPLY when half-word multiply instructions
+ * this means variants of: smul, smulw, smla, smlaw, smlal
+ */
+#if __ARM_HAVE_5TE
+#  define  __ARM_HAVE_HALFWORD_MULTIPLY  1
+#endif
+
+/* define __ARM_HAVE_PAIR_LOAD_STORE when 64-bit memory loads and stored
+ * into/from a pair of 32-bit registers is supported throuhg 'ldrd' and 'strd'
+ */
+#if __ARM_HAVE_5TE
+#  define  __ARM_HAVE_PAIR_LOAD_STORE 1
+#endif
+
+/* define __ARM_HAVE_SATURATED_ARITHMETIC is you have the saturated integer
+ * arithmetic instructions: qdd, qdadd, qsub, qdsub
+ */
+#if __ARM_HAVE_5TE
+#  define  __ARM_HAVE_SATURATED_ARITHMETIC 1
+#endif
+
+/* define __ARM_HAVE_PC_INTERWORK when a direct assignment to the
+ * pc register will switch into thumb/ARM mode depending on bit 0
+ * of the new instruction address. Before ARMv5, this was not the
+ * case, and you have to write:
+ *
+ *     mov  r0, [<some address>]
+ *     bx   r0
+ *
+ * instead of:
+ *
+ *     ldr  pc, [<some address>]
+ *
+ * note that this affects any instruction that explicitely changes the
+ * value of the pc register, including ldm { ...,pc } or 'add pc, #offset'
+ */
+#if __ARM_ARCH__ >= 5
+#  define __ARM_HAVE_PC_INTERWORK
+#endif
+
+
+/* Assembly-only macros */
+
+/* define a handy PLD(address) macro since the cache preload
+ * is an optional opcode
+ */
+#if __ARM_HAVE_PLD
+#  define  PLD(reg,offset)    pld    [reg, offset]
+#else
+#  define  PLD(reg,offset)    /* nothing */
+#endif
+
+#endif /* _ARM_MACHINE_CPU_FEATURES_H */
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/exec.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/exec.h
new file mode 100644
index 0000000..227b207
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/exec.h
@@ -0,0 +1,50 @@
+/*	$OpenBSD: exec.h,v 1.9 2003/04/17 03:42:14 drahn Exp $	*/
+/*	$NetBSD: exec.h,v 1.6 1994/10/27 04:16:05 cgd Exp $	*/
+
+/*
+ * Copyright (c) 1993 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
+ */
+
+#ifndef _ARM_EXEC_H_
+#define _ARM_EXEC_H_
+
+#define __LDPGSZ	4096
+
+#define NATIVE_EXEC_ELF
+
+#define ARCH_ELFSIZE		32
+
+#define ELF_TARG_CLASS		ELFCLASS32
+#define ELF_TARG_DATA		ELFDATA2LSB
+#define ELF_TARG_MACH		EM_ARM
+
+#define _NLIST_DO_AOUT
+#define _NLIST_DO_ELF
+
+#define _KERN_DO_AOUT
+#define _KERN_DO_ELF
+
+#endif  /* _ARM_EXEC_H_ */
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/ieee.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/ieee.h
new file mode 100644
index 0000000..5f9b89e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/ieee.h
@@ -0,0 +1,191 @@
+/*	$OpenBSD: ieee.h,v 1.1 2004/02/01 05:09:49 drahn Exp $	*/
+/*	$NetBSD: ieee.h,v 1.2 2001/02/21 17:43:50 bjh21 Exp $	*/
+
+/*
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Lawrence Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)ieee.h	8.1 (Berkeley) 6/11/93
+ */
+
+/*
+ * ieee.h defines the machine-dependent layout of the machine's IEEE
+ * floating point.
+ */
+
+/*
+ * Define the number of bits in each fraction and exponent.
+ *
+ *		     k	         k+1
+ * Note that  1.0 x 2  == 0.1 x 2      and that denorms are represented
+ *
+ *					  (-exp_bias+1)
+ * as fractions that look like 0.fffff x 2             .  This means that
+ *
+ *			 -126
+ * the number 0.10000 x 2    , for instance, is the same as the normalized
+ *
+ *		-127			   -128
+ * float 1.0 x 2    .  Thus, to represent 2    , we need one leading zero
+ *
+ *				  -129
+ * in the fraction; to represent 2    , we need two, and so on.  This
+ *
+ *						     (-exp_bias-fracbits+1)
+ * implies that the smallest denormalized number is 2
+ *
+ * for whichever format we are talking about: for single precision, for
+ *
+ *						-126		-149
+ * instance, we get .00000000000000000000001 x 2    , or 1.0 x 2    , and
+ *
+ * -149 == -127 - 23 + 1.
+ */
+
+/*
+ * The ARM has two sets of FP data formats.  The FPA supports 32-bit, 64-bit
+ * and 96-bit IEEE formats, with the words in big-endian order.  VFP supports
+ * 32-bin and 64-bit IEEE formats with the words in the CPU's native byte
+ * order.
+ *
+ * The FPA also has two packed decimal formats, but we ignore them here.
+ */
+
+#define	SNG_EXPBITS	8
+#define	SNG_FRACBITS	23
+
+#define	DBL_EXPBITS	11
+#define	DBL_FRACBITS	52
+
+#ifndef __VFP_FP__
+#define	E80_EXPBITS	15
+#define	E80_FRACBITS	64
+
+#define	EXT_EXPBITS	15
+#define	EXT_FRACBITS	112
+#endif
+
+struct ieee_single {
+	u_int	sng_frac:23;
+	u_int	sng_exponent:8;
+	u_int	sng_sign:1;
+};
+
+#ifdef __VFP_FP__
+struct ieee_double {
+#ifdef __ARMEB__
+	u_int	dbl_sign:1;
+	u_int	dbl_exp:11;
+	u_int	dbl_frach:20;
+	u_int	dbl_fracl;
+#else /* !__ARMEB__ */
+	u_int	dbl_fracl;
+	u_int	dbl_frach:20;
+	u_int	dbl_exp:11;
+	u_int	dbl_sign:1;
+#endif /* !__ARMEB__ */
+};
+#else /* !__VFP_FP__ */
+struct ieee_double {
+	u_int	dbl_frach:20;
+	u_int	dbl_exp:11;
+	u_int	dbl_sign:1;
+	u_int	dbl_fracl;
+};
+
+union ieee_double_u {
+	double                  dblu_d;
+	struct ieee_double      dblu_dbl;
+};
+
+
+struct ieee_e80 {
+	u_int	e80_exp:15;
+	u_int	e80_zero:16;
+	u_int	e80_sign:1;
+	u_int	e80_frach:31;
+	u_int	e80_j:1;
+	u_int	e80_fracl;
+};
+
+struct ieee_ext {
+	u_int	ext_frach:16;
+	u_int	ext_exp:15;
+	u_int	ext_sign:1;
+	u_int	ext_frachm;
+	u_int	ext_fraclm;
+	u_int	ext_fracl;
+};
+#endif /* !__VFP_FP__ */
+
+/*
+ * Floats whose exponent is in [1..INFNAN) (of whatever type) are
+ * `normal'.  Floats whose exponent is INFNAN are either Inf or NaN.
+ * Floats whose exponent is zero are either zero (iff all fraction
+ * bits are zero) or subnormal values.
+ *
+ * A NaN is a `signalling NaN' if its QUIETNAN bit is clear in its
+ * high fraction; if the bit is set, it is a `quiet NaN'.
+ */
+#define	SNG_EXP_INFNAN	255
+#define	DBL_EXP_INFNAN	2047
+#ifndef __VFP_FP__
+#define	E80_EXP_INFNAN	32767
+#define	EXT_EXP_INFNAN	32767
+#endif /* !__VFP_FP__ */
+
+#if 0
+#define	SNG_QUIETNAN	(1 << 22)
+#define	DBL_QUIETNAN	(1 << 19)
+#ifndef __VFP_FP__
+#define	E80_QUIETNAN	(1 << 15)
+#define	EXT_QUIETNAN	(1 << 15)
+#endif /* !__VFP_FP__ */
+#endif
+
+/*
+ * Exponent biases.
+ */
+#define	SNG_EXP_BIAS	127
+#define	DBL_EXP_BIAS	1023
+#ifndef __VFP_FP__
+#define	E80_EXP_BIAS	16383
+#define	EXT_EXP_BIAS	16383
+#endif /* !__VFP_FP__ */
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/internal_types.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/internal_types.h
new file mode 100644
index 0000000..7e610b0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/internal_types.h
@@ -0,0 +1,10 @@
+/* $OpenBSD: internal_types.h,v 1.2 2004/05/06 15:53:39 drahn Exp $ */
+/* Public domain */
+#ifndef _ARM_INTERNAL_TYPES_H_
+#define _ARM_INTERNAL_TYPES_H_
+
+#ifdef __CHAR_UNSIGNED__
+#define __machine_has_unsigned_chars
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/kernel.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/kernel.h
new file mode 100644
index 0000000..462b8e3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/kernel.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _ARCH_ARM_KERNEL_H
+#define _ARCH_ARM_KERNEL_H
+
+/* this file contains kernel-specific definitions that were optimized out of
+   our processed kernel headers, but still useful nonetheless... */
+
+typedef unsigned long   __kernel_blkcnt_t;
+typedef unsigned long   __kernel_blksize_t;
+
+/* these aren't really defined by the kernel headers though... */
+typedef unsigned long   __kernel_fsblkcnt_t;
+typedef unsigned long   __kernel_fsfilcnt_t;
+typedef unsigned int    __kernel_id_t;
+
+#endif /* _ARCH_ARM_KERNEL_H */
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/limits.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/limits.h
new file mode 100644
index 0000000..f9c04fa
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/limits.h
@@ -0,0 +1,63 @@
+/*	$OpenBSD: limits.h,v 1.3 2006/01/06 22:48:46 millert Exp $	*/
+/*	$NetBSD: limits.h,v 1.4 2003/04/28 23:16:18 bjh21 Exp $	*/
+
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	from: @(#)limits.h	7.2 (Berkeley) 6/28/90
+ */
+
+#ifndef	_ARM32_LIMITS_H_
+#define	_ARM32_LIMITS_H_
+
+#include <sys/cdefs.h>
+
+#define	MB_LEN_MAX	1		/* no multibyte characters */
+
+#ifndef	SIZE_MAX
+#define	SIZE_MAX	UINT_MAX	/* max value for a size_t */
+#endif
+#ifndef SSIZE_MAX
+#define	SSIZE_MAX	INT_MAX		/* max value for a ssize_t */
+#endif
+
+#if __BSD_VISIBLE
+#define	SIZE_T_MAX	UINT_MAX	/* max value for a size_t (historic) */
+
+#define	UQUAD_MAX	0xffffffffffffffffULL		/* max unsigned quad */
+#define	QUAD_MAX	0x7fffffffffffffffLL		/* max signed quad */
+#define	QUAD_MIN	(-0x7fffffffffffffffLL-1)	/* min signed quad */
+
+#endif /* __BSD_VISIBLE */
+
+#define LONGLONG_BIT    64
+#define LONGLONG_MIN    (-9223372036854775807LL-1)
+#define LONGLONG_MAX    9223372036854775807LL
+#define ULONGLONG_MAX   18446744073709551615ULL
+
+#endif	/* _ARM32_LIMITS_H_ */
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/setjmp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/setjmp.h
new file mode 100644
index 0000000..f20cab2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/machine/setjmp.h
@@ -0,0 +1,87 @@
+/*	$OpenBSD: setjmp.h,v 1.1 2004/02/01 05:09:49 drahn Exp $	*/
+/*	$NetBSD: setjmp.h,v 1.2 2001/08/25 14:45:59 bjh21 Exp $	*/
+
+/*
+ * machine/setjmp.h: machine dependent setjmp-related information.
+ */
+
+#ifdef __ELF__
+#define	_JBLEN	64		/* size, in longs, of a jmp_buf */
+#else
+#define	_JBLEN	29		/* size, in longs, of a jmp_buf */
+#endif
+
+/*
+ * NOTE: The internal structure of a jmp_buf is *PRIVATE*
+ *       This information is provided as there is software
+ *       that fiddles with this with obtain the stack pointer
+ *	 (yes really ! and its commercial !).
+ *
+ * Description of the setjmp buffer
+ *
+ * word  0	magic number	(dependant on creator)
+ *       1 -  3	f4		fp register 4
+ *	 4 -  6	f5		fp register 5
+ *	 7 -  9 f6		fp register 6
+ *	10 - 12	f7		fp register 7
+ *	13	fpsr		fp status register
+ *	14	r4		register 4
+ *	15	r5		register 5
+ *	16	r6		register 6
+ *	17	r7		register 7
+ *	18	r8		register 8
+ *	19	r9		register 9
+ *	20	r10		register 10 (sl)
+ *	21	r11		register 11 (fp)
+ *	22	r12		register 12 (ip)
+ *	23	r13		register 13 (sp)
+ *	24	r14		register 14 (lr)
+ *	25	signal mask	(dependant on magic)
+ *	26	(con't)
+ *	27	(con't)
+ *	28	(con't)
+ *
+ * The magic number number identifies the jmp_buf and
+ * how the buffer was created as well as providing
+ * a sanity check
+ *
+ * A side note I should mention - Please do not tamper
+ * with the floating point fields. While they are
+ * always saved and restored at the moment this cannot
+ * be garenteed especially if the compiler happens
+ * to be generating soft-float code so no fp
+ * registers will be used.
+ *
+ * Whilst this can be seen an encouraging people to
+ * use the setjmp buffer in this way I think that it
+ * is for the best then if changes occur compiles will
+ * break rather than just having new builds falling over
+ * mysteriously.
+ */
+
+#define _JB_MAGIC__SETJMP	0x4278f500
+#define _JB_MAGIC_SETJMP	0x4278f501
+
+/* Valid for all jmp_buf's */
+
+#define _JB_MAGIC		 0
+#define _JB_REG_F4		 1
+#define _JB_REG_F5		 4
+#define _JB_REG_F6		 7
+#define _JB_REG_F7		10
+#define _JB_REG_FPSR		13
+#define _JB_REG_R4		14
+#define _JB_REG_R5		15
+#define _JB_REG_R6		16
+#define _JB_REG_R7		17
+#define _JB_REG_R8		18
+#define _JB_REG_R9		19
+#define _JB_REG_R10		20
+#define _JB_REG_R11		21
+#define _JB_REG_R12		22
+#define _JB_REG_R13		23
+#define _JB_REG_R14		24
+
+/* Only valid with the _JB_MAGIC_SETJMP magic */
+
+#define _JB_SIGMASK		25
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/malloc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/malloc.h
new file mode 120000
index 0000000..78a8006
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/malloc.h
@@ -0,0 +1 @@
+../../../common/include/malloc.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/math.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/math.h
new file mode 120000
index 0000000..0d4bdcd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/math.h
@@ -0,0 +1 @@
+../../../common/include/math.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/memory.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/memory.h
new file mode 120000
index 0000000..08375e2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/memory.h
@@ -0,0 +1 @@
+../../../common/include/memory.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/mntent.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/mntent.h
new file mode 120000
index 0000000..43186c4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/mntent.h
@@ -0,0 +1 @@
+../../../common/include/mntent.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/mtd/mtd-abi.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/mtd/mtd-abi.h
new file mode 120000
index 0000000..19a9a51
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/mtd/mtd-abi.h
@@ -0,0 +1 @@
+../../../../common/include/mtd/mtd-abi.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/mtd/mtd-user.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/mtd/mtd-user.h
new file mode 120000
index 0000000..e22b96b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/mtd/mtd-user.h
@@ -0,0 +1 @@
+../../../../common/include/mtd/mtd-user.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/ethertypes.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/ethertypes.h
new file mode 120000
index 0000000..621864d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/ethertypes.h
@@ -0,0 +1 @@
+../../../../common/include/net/ethertypes.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if.h
new file mode 120000
index 0000000..c83fdb9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if.h
@@ -0,0 +1 @@
+../../../../common/include/net/if.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_arp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_arp.h
new file mode 120000
index 0000000..e8e84bb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_arp.h
@@ -0,0 +1 @@
+../../../../common/include/net/if_arp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_dl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_dl.h
new file mode 120000
index 0000000..1a27df4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_dl.h
@@ -0,0 +1 @@
+../../../../common/include/net/if_dl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_ether.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_ether.h
new file mode 120000
index 0000000..591c1db
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_ether.h
@@ -0,0 +1 @@
+../../../../common/include/net/if_ether.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_ieee1394.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_ieee1394.h
new file mode 120000
index 0000000..f0b13ce
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_ieee1394.h
@@ -0,0 +1 @@
+../../../../common/include/net/if_ieee1394.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_packet.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_packet.h
new file mode 120000
index 0000000..4c5bd8d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_packet.h
@@ -0,0 +1 @@
+../../../../common/include/net/if_packet.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_types.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_types.h
new file mode 120000
index 0000000..410430f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/if_types.h
@@ -0,0 +1 @@
+../../../../common/include/net/if_types.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/route.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/route.h
new file mode 120000
index 0000000..ea03206
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/net/route.h
@@ -0,0 +1 @@
+../../../../common/include/net/route.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/netdb.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netdb.h
new file mode 120000
index 0000000..67f7a2f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netdb.h
@@ -0,0 +1 @@
+../../../common/include/netdb.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/ether.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/ether.h
new file mode 120000
index 0000000..e331c47
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/ether.h
@@ -0,0 +1 @@
+../../../../common/include/netinet/ether.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/if_ether.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/if_ether.h
new file mode 120000
index 0000000..5354bb5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/if_ether.h
@@ -0,0 +1 @@
+../../../../common/include/netinet/if_ether.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/in.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/in.h
new file mode 120000
index 0000000..8439fe5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/in.h
@@ -0,0 +1 @@
+../../../../common/include/netinet/in.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/in6.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/in6.h
new file mode 120000
index 0000000..fa5937f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/in6.h
@@ -0,0 +1 @@
+../../../../common/include/netinet/in6.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/in_systm.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/in_systm.h
new file mode 120000
index 0000000..ea70a33
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/in_systm.h
@@ -0,0 +1 @@
+../../../../common/include/netinet/in_systm.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/ip.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/ip.h
new file mode 120000
index 0000000..3eb2097
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/ip.h
@@ -0,0 +1 @@
+../../../../common/include/netinet/ip.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/ip_icmp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/ip_icmp.h
new file mode 120000
index 0000000..2c9024f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/ip_icmp.h
@@ -0,0 +1 @@
+../../../../common/include/netinet/ip_icmp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/tcp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/tcp.h
new file mode 120000
index 0000000..6b0d829
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/tcp.h
@@ -0,0 +1 @@
+../../../../common/include/netinet/tcp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/udp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/udp.h
new file mode 120000
index 0000000..d5e0f6b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netinet/udp.h
@@ -0,0 +1 @@
+../../../../common/include/netinet/udp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/netpacket/packet.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netpacket/packet.h
new file mode 120000
index 0000000..7473ba4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/netpacket/packet.h
@@ -0,0 +1 @@
+../../../../common/include/netpacket/packet.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/new b/ndk/build/platforms/android-1.5/arch-arm/usr/include/new
new file mode 120000
index 0000000..b3e4225
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/new
@@ -0,0 +1 @@
+../../../common/include/new
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/nsswitch.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/nsswitch.h
new file mode 120000
index 0000000..361ce34
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/nsswitch.h
@@ -0,0 +1 @@
+../../../common/include/nsswitch.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/pathconf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/pathconf.h
new file mode 120000
index 0000000..f1c45ca
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/pathconf.h
@@ -0,0 +1 @@
+../../../common/include/pathconf.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/paths.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/paths.h
new file mode 120000
index 0000000..04b00c0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/paths.h
@@ -0,0 +1 @@
+../../../common/include/paths.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/poll.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/poll.h
new file mode 120000
index 0000000..e260aad
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/poll.h
@@ -0,0 +1 @@
+../../../common/include/poll.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/pthread.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/pthread.h
new file mode 120000
index 0000000..e7240fe
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/pthread.h
@@ -0,0 +1 @@
+../../../common/include/pthread.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/pwd.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/pwd.h
new file mode 120000
index 0000000..deefc65
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/pwd.h
@@ -0,0 +1 @@
+../../../common/include/pwd.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/resolv.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/resolv.h
new file mode 120000
index 0000000..645cec6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/resolv.h
@@ -0,0 +1 @@
+../../../common/include/resolv.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sched.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sched.h
new file mode 120000
index 0000000..7eb75bc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sched.h
@@ -0,0 +1 @@
+../../../common/include/sched.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/semaphore.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/semaphore.h
new file mode 120000
index 0000000..5981819
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/semaphore.h
@@ -0,0 +1 @@
+../../../common/include/semaphore.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/setjmp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/setjmp.h
new file mode 120000
index 0000000..927b88e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/setjmp.h
@@ -0,0 +1 @@
+../../../common/include/setjmp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sgtty.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sgtty.h
new file mode 120000
index 0000000..fcfac52
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sgtty.h
@@ -0,0 +1 @@
+../../../common/include/sgtty.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sha1.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sha1.h
new file mode 120000
index 0000000..f4aadd2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sha1.h
@@ -0,0 +1 @@
+../../../common/include/sha1.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/signal.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/signal.h
new file mode 120000
index 0000000..83e2e8e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/signal.h
@@ -0,0 +1 @@
+../../../common/include/signal.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/stdint.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/stdint.h
new file mode 120000
index 0000000..8b0dfbf
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/stdint.h
@@ -0,0 +1 @@
+../../../common/include/stdint.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/stdio.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/stdio.h
new file mode 120000
index 0000000..41d7d04
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/stdio.h
@@ -0,0 +1 @@
+../../../common/include/stdio.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/stdlib.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/stdlib.h
new file mode 120000
index 0000000..de97694
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/stdlib.h
@@ -0,0 +1 @@
+../../../common/include/stdlib.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/stl_pair.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/stl_pair.h
new file mode 120000
index 0000000..bfeaf5b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/stl_pair.h
@@ -0,0 +1 @@
+../../../common/include/stl_pair.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/string.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/string.h
new file mode 120000
index 0000000..ee1c46a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/string.h
@@ -0,0 +1 @@
+../../../common/include/string.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/strings.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/strings.h
new file mode 120000
index 0000000..e3c356d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/strings.h
@@ -0,0 +1 @@
+../../../common/include/strings.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/_errdefs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/_errdefs.h
new file mode 120000
index 0000000..b2a299e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/_errdefs.h
@@ -0,0 +1 @@
+../../../../common/include/sys/_errdefs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/_sigdefs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/_sigdefs.h
new file mode 120000
index 0000000..ea48d37
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/_sigdefs.h
@@ -0,0 +1 @@
+../../../../common/include/sys/_sigdefs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/_system_properties.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/_system_properties.h
new file mode 120000
index 0000000..6054cc4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/_system_properties.h
@@ -0,0 +1 @@
+../../../../common/include/sys/_system_properties.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/_types.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/_types.h
new file mode 120000
index 0000000..936b4d5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/_types.h
@@ -0,0 +1 @@
+../../../../common/include/sys/_types.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/atomics.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/atomics.h
new file mode 120000
index 0000000..0304794
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/atomics.h
@@ -0,0 +1 @@
+../../../../common/include/sys/atomics.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/cdefs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/cdefs.h
new file mode 120000
index 0000000..36eede7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/cdefs.h
@@ -0,0 +1 @@
+../../../../common/include/sys/cdefs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/cdefs_elf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/cdefs_elf.h
new file mode 120000
index 0000000..fa852bf
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/cdefs_elf.h
@@ -0,0 +1 @@
+../../../../common/include/sys/cdefs_elf.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/dirent.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/dirent.h
new file mode 120000
index 0000000..cac02ee
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/dirent.h
@@ -0,0 +1 @@
+../../../../common/include/sys/dirent.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/endian.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/endian.h
new file mode 120000
index 0000000..25109db
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/endian.h
@@ -0,0 +1 @@
+../../../../common/include/sys/endian.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/epoll.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/epoll.h
new file mode 120000
index 0000000..bf93fc6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/epoll.h
@@ -0,0 +1 @@
+../../../../common/include/sys/epoll.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/errno.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/errno.h
new file mode 120000
index 0000000..199ad78
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/errno.h
@@ -0,0 +1 @@
+../../../../common/include/sys/errno.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/exec_elf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/exec_elf.h
new file mode 120000
index 0000000..24e01e6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/exec_elf.h
@@ -0,0 +1 @@
+../../../../common/include/sys/exec_elf.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/file.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/file.h
new file mode 120000
index 0000000..99ab5d3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/file.h
@@ -0,0 +1 @@
+../../../../common/include/sys/file.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/fsuid.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/fsuid.h
new file mode 120000
index 0000000..f5f9974
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/fsuid.h
@@ -0,0 +1 @@
+../../../../common/include/sys/fsuid.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/inotify.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/inotify.h
new file mode 120000
index 0000000..a050653
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/inotify.h
@@ -0,0 +1 @@
+../../../../common/include/sys/inotify.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ioctl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ioctl.h
new file mode 120000
index 0000000..e228a66
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ioctl.h
@@ -0,0 +1 @@
+../../../../common/include/sys/ioctl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ioctl_compat.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ioctl_compat.h
new file mode 120000
index 0000000..dd004de
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ioctl_compat.h
@@ -0,0 +1 @@
+../../../../common/include/sys/ioctl_compat.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ipc.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ipc.h
new file mode 120000
index 0000000..5d275f2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ipc.h
@@ -0,0 +1 @@
+../../../../common/include/sys/ipc.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/klog.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/klog.h
new file mode 120000
index 0000000..4cad4c9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/klog.h
@@ -0,0 +1 @@
+../../../../common/include/sys/klog.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/limits.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/limits.h
new file mode 120000
index 0000000..4f50214
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/limits.h
@@ -0,0 +1 @@
+../../../../common/include/sys/limits.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/linux-syscalls.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/linux-syscalls.h
new file mode 120000
index 0000000..754d7c49
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/linux-syscalls.h
@@ -0,0 +1 @@
+../../../../common/include/sys/linux-syscalls.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/linux-unistd.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/linux-unistd.h
new file mode 120000
index 0000000..9496fde
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/linux-unistd.h
@@ -0,0 +1 @@
+../../../../common/include/sys/linux-unistd.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/mman.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/mman.h
new file mode 120000
index 0000000..bd6a6b8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/mman.h
@@ -0,0 +1 @@
+../../../../common/include/sys/mman.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/mount.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/mount.h
new file mode 120000
index 0000000..0b0a916
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/mount.h
@@ -0,0 +1 @@
+../../../../common/include/sys/mount.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/param.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/param.h
new file mode 120000
index 0000000..16e5bcc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/param.h
@@ -0,0 +1 @@
+../../../../common/include/sys/param.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/poll.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/poll.h
new file mode 120000
index 0000000..a98ab69
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/poll.h
@@ -0,0 +1 @@
+../../../../common/include/sys/poll.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/prctl.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/prctl.h
new file mode 120000
index 0000000..950d2fb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/prctl.h
@@ -0,0 +1 @@
+../../../../common/include/sys/prctl.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ptrace.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ptrace.h
new file mode 120000
index 0000000..3b2714f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ptrace.h
@@ -0,0 +1 @@
+../../../../common/include/sys/ptrace.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/reboot.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/reboot.h
new file mode 120000
index 0000000..8295ffc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/reboot.h
@@ -0,0 +1 @@
+../../../../common/include/sys/reboot.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/resource.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/resource.h
new file mode 120000
index 0000000..72a813f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/resource.h
@@ -0,0 +1 @@
+../../../../common/include/sys/resource.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/select.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/select.h
new file mode 120000
index 0000000..42f2037
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/select.h
@@ -0,0 +1 @@
+../../../../common/include/sys/select.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/sendfile.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/sendfile.h
new file mode 120000
index 0000000..ac4d8a0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/sendfile.h
@@ -0,0 +1 @@
+../../../../common/include/sys/sendfile.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/socket.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/socket.h
new file mode 120000
index 0000000..36a0331
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/socket.h
@@ -0,0 +1 @@
+../../../../common/include/sys/socket.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/socketcalls.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/socketcalls.h
new file mode 120000
index 0000000..5e94809
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/socketcalls.h
@@ -0,0 +1 @@
+../../../../common/include/sys/socketcalls.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/stat.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/stat.h
new file mode 120000
index 0000000..fa00c54
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/stat.h
@@ -0,0 +1 @@
+../../../../common/include/sys/stat.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/statfs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/statfs.h
new file mode 120000
index 0000000..d53806d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/statfs.h
@@ -0,0 +1 @@
+../../../../common/include/sys/statfs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/syscall.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/syscall.h
new file mode 120000
index 0000000..4225c35
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/syscall.h
@@ -0,0 +1 @@
+../../../../common/include/sys/syscall.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/sysconf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/sysconf.h
new file mode 120000
index 0000000..ed9cf1f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/sysconf.h
@@ -0,0 +1 @@
+../../../../common/include/sys/sysconf.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/sysinfo.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/sysinfo.h
new file mode 120000
index 0000000..1693d79
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/sysinfo.h
@@ -0,0 +1 @@
+../../../../common/include/sys/sysinfo.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/syslimits.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/syslimits.h
new file mode 120000
index 0000000..17efa78
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/syslimits.h
@@ -0,0 +1 @@
+../../../../common/include/sys/syslimits.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/sysmacros.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/sysmacros.h
new file mode 120000
index 0000000..fa13eca
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/sysmacros.h
@@ -0,0 +1 @@
+../../../../common/include/sys/sysmacros.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/system_properties.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/system_properties.h
new file mode 120000
index 0000000..286ba9d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/system_properties.h
@@ -0,0 +1 @@
+../../../../common/include/sys/system_properties.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/time.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/time.h
new file mode 120000
index 0000000..b376430
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/time.h
@@ -0,0 +1 @@
+../../../../common/include/sys/time.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/timeb.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/timeb.h
new file mode 120000
index 0000000..fef113e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/timeb.h
@@ -0,0 +1 @@
+../../../../common/include/sys/timeb.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/times.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/times.h
new file mode 120000
index 0000000..53c3a1a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/times.h
@@ -0,0 +1 @@
+../../../../common/include/sys/times.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ttychars.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ttychars.h
new file mode 120000
index 0000000..09c3352
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ttychars.h
@@ -0,0 +1 @@
+../../../../common/include/sys/ttychars.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ttydev.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ttydev.h
new file mode 120000
index 0000000..4735daa
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/ttydev.h
@@ -0,0 +1 @@
+../../../../common/include/sys/ttydev.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/types.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/types.h
new file mode 120000
index 0000000..8829c6b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/types.h
@@ -0,0 +1 @@
+../../../../common/include/sys/types.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/uio.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/uio.h
new file mode 120000
index 0000000..a111200
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/uio.h
@@ -0,0 +1 @@
+../../../../common/include/sys/uio.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/un.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/un.h
new file mode 120000
index 0000000..20d7c68
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/un.h
@@ -0,0 +1 @@
+../../../../common/include/sys/un.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/utime.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/utime.h
new file mode 120000
index 0000000..8494247
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/utime.h
@@ -0,0 +1 @@
+../../../../common/include/sys/utime.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/utsname.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/utsname.h
new file mode 120000
index 0000000..cf985f0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/utsname.h
@@ -0,0 +1 @@
+../../../../common/include/sys/utsname.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/vfs.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/vfs.h
new file mode 120000
index 0000000..c4873c3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/vfs.h
@@ -0,0 +1 @@
+../../../../common/include/sys/vfs.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/vt.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/vt.h
new file mode 120000
index 0000000..55b3ed4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/vt.h
@@ -0,0 +1 @@
+../../../../common/include/sys/vt.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/wait.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/wait.h
new file mode 120000
index 0000000..9f27986
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/sys/wait.h
@@ -0,0 +1 @@
+../../../../common/include/sys/wait.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/syslog.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/syslog.h
new file mode 120000
index 0000000..609c4e1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/syslog.h
@@ -0,0 +1 @@
+../../../common/include/syslog.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/termios.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/termios.h
new file mode 120000
index 0000000..53740f5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/termios.h
@@ -0,0 +1 @@
+../../../common/include/termios.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/thread_db.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/thread_db.h
new file mode 120000
index 0000000..e6b5ced
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/thread_db.h
@@ -0,0 +1 @@
+../../../common/include/thread_db.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/time.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/time.h
new file mode 120000
index 0000000..4ae3e06
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/time.h
@@ -0,0 +1 @@
+../../../common/include/time.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/time64.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/time64.h
new file mode 120000
index 0000000..9e4ca23
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/time64.h
@@ -0,0 +1 @@
+../../../common/include/time64.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/typeinfo b/ndk/build/platforms/android-1.5/arch-arm/usr/include/typeinfo
new file mode 120000
index 0000000..35bacb5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/typeinfo
@@ -0,0 +1 @@
+../../../common/include/typeinfo
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/unistd.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/unistd.h
new file mode 120000
index 0000000..378e20d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/unistd.h
@@ -0,0 +1 @@
+../../../common/include/unistd.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/util.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/util.h
new file mode 120000
index 0000000..c8de0fe
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/util.h
@@ -0,0 +1 @@
+../../../common/include/util.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/utility b/ndk/build/platforms/android-1.5/arch-arm/usr/include/utility
new file mode 120000
index 0000000..f670e68
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/utility
@@ -0,0 +1 @@
+../../../common/include/utility
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/utime.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/utime.h
new file mode 120000
index 0000000..520a474
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/utime.h
@@ -0,0 +1 @@
+../../../common/include/utime.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/utmp.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/utmp.h
new file mode 120000
index 0000000..9fe8b95
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/utmp.h
@@ -0,0 +1 @@
+../../../common/include/utmp.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/wchar.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/wchar.h
new file mode 120000
index 0000000..5a35644
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/wchar.h
@@ -0,0 +1 @@
+../../../common/include/wchar.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/wctype.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/wctype.h
new file mode 120000
index 0000000..2a2a823
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/wctype.h
@@ -0,0 +1 @@
+../../../common/include/wctype.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/zconf.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/zconf.h
new file mode 120000
index 0000000..10d4a1e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/zconf.h
@@ -0,0 +1 @@
+../../../common/include/zconf.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/include/zlib.h b/ndk/build/platforms/android-1.5/arch-arm/usr/include/zlib.h
new file mode 120000
index 0000000..d9e63a4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/include/zlib.h
@@ -0,0 +1 @@
+../../../common/include/zlib.h
\ No newline at end of file
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/lib/crtbegin_dynamic.o b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/crtbegin_dynamic.o
new file mode 100644
index 0000000..63d4efa
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/crtbegin_dynamic.o
Binary files differ
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/lib/crtbegin_static.o b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/crtbegin_static.o
new file mode 100644
index 0000000..d11c79e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/crtbegin_static.o
Binary files differ
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/lib/crtend_android.o b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/crtend_android.o
new file mode 100644
index 0000000..5b76af8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/crtend_android.o
Binary files differ
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libc.a b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libc.a
new file mode 100644
index 0000000..4fdcafc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libc.a
Binary files differ
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libc.so b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libc.so
new file mode 100644
index 0000000..9714e97
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libc.so
Binary files differ
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libdl.so b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libdl.so
new file mode 100644
index 0000000..e2a589c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libdl.so
Binary files differ
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/lib/liblog.so b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/liblog.so
new file mode 100644
index 0000000..92bf1a7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/liblog.so
Binary files differ
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libm.a b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libm.a
new file mode 100644
index 0000000..3e1ccb0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libm.a
Binary files differ
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libm.so b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libm.so
new file mode 100644
index 0000000..87f4446
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libm.so
Binary files differ
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libstdc++.a b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libstdc++.a
new file mode 100644
index 0000000..8f495a5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libstdc++.a
Binary files differ
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libstdc++.so b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libstdc++.so
new file mode 100644
index 0000000..d3d103f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libstdc++.so
Binary files differ
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libthread_db.a b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libthread_db.a
new file mode 100644
index 0000000..9d634be
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libthread_db.a
Binary files differ
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libthread_db.so b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libthread_db.so
new file mode 100644
index 0000000..ea603f0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libthread_db.so
Binary files differ
diff --git a/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libz.so b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libz.so
new file mode 100644
index 0000000..f50a0ff
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/arch-arm/usr/lib/libz.so
Binary files differ
diff --git a/ndk/build/platforms/android-1.5/common/include/alloca.h b/ndk/build/platforms/android-1.5/common/include/alloca.h
new file mode 100644
index 0000000..0c50fc3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/alloca.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _ALLOCA_H
+#define _ALLOCA_H
+
+#define alloca(size)   __builtin_alloca(size)
+
+#endif /* _ALLOCA_H */
+
diff --git a/ndk/build/platforms/android-1.5/common/include/android/log.h b/ndk/build/platforms/android-1.5/common/include/android/log.h
new file mode 100644
index 0000000..0ea4c29
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/android/log.h
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+#ifndef _ANDROID_LOG_H
+#define _ANDROID_LOG_H
+
+/******************************************************************
+ *
+ * IMPORTANT NOTICE:
+ *
+ *   This file is part of Android's set of stable system headers
+ *   exposed by the Android NDK (Native Development Kit) since
+ *   platform release 1.5
+ *
+ *   Third-party source AND binary code relies on the definitions
+ *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
+ *
+ *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
+ *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
+ *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
+ *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
+ */
+
+/*
+ * Support routines to send messages to the Android in-kernel log buffer,
+ * which can later be accessed through the 'logcat' utility.
+ *
+ * Each log message must have
+ *   - a priority
+ *   - a log tag
+ *   - some text
+ *
+ * The tag normally corresponds to the component that emits the log message,
+ * and should be reasonably small.
+ *
+ * Log message text may be truncated to less than an implementation-specific
+ * limit (e.g. 1023 characters max).
+ *
+ * Note that a newline character ("\n") will be appended automatically to your
+ * log message, if not already there. It is not possible to send several messages
+ * and have them appear on a single line in logcat.
+ *
+ * PLEASE USE LOGS WITH MODERATION:
+ *
+ *  - Sending log messages eats CPU and slow down your application and the
+ *    system.
+ *
+ *  - The circular log buffer is pretty small (<64KB), sending many messages
+ *    might push off other important log messages from the rest of the system.
+ *
+ *  - In release builds, only send log messages to account for exceptional
+ *    conditions.
+ *
+ * NOTE: These functions MUST be implemented by /system/lib/liblog.so
+ */
+
+#include <stdarg.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Android log priority values, in ascending priority order.
+ */
+typedef enum android_LogPriority {
+    ANDROID_LOG_UNKNOWN = 0,
+    ANDROID_LOG_DEFAULT,    /* only for SetMinPriority() */
+    ANDROID_LOG_VERBOSE,
+    ANDROID_LOG_DEBUG,
+    ANDROID_LOG_INFO,
+    ANDROID_LOG_WARN,
+    ANDROID_LOG_ERROR,
+    ANDROID_LOG_FATAL,
+    ANDROID_LOG_SILENT,     /* only for SetMinPriority(); must be last */
+} android_LogPriority;
+
+/*
+ * Send a simple string to the log.
+ */
+int __android_log_write(int prio, const char *tag, const char *text);
+
+/*
+ * Send a formatted string to the log, used like printf(fmt,...)
+ */
+int __android_log_print(int prio, const char *tag,  const char *fmt, ...)
+#if defined(__GNUC__)
+    __attribute__ ((format(printf, 3, 4)))
+#endif
+    ;
+
+/*
+ * A variant of __android_log_print() that takes a va_list to list
+ * additional parameters.
+ */
+int __android_log_vprint(int prio, const char *tag,
+                         const char *fmt, va_list ap);
+
+/*
+ * Log an assertion failure and SIGTRAP the process to have a chance
+ * to inspect it, if a debugger is attached. This uses the FATAL priority.
+ */
+void __android_log_assert(const char *cond, const char *tag,
+			  const char *fmt, ...)    
+#if defined(__GNUC__)
+    __attribute__ ((noreturn))
+    __attribute__ ((format(printf, 3, 4)))
+#endif
+    ;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ANDROID_LOG_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/arpa/inet.h b/ndk/build/platforms/android-1.5/common/include/arpa/inet.h
new file mode 100644
index 0000000..3ebb872
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/arpa/inet.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _ARPA_INET_H_
+#define _ARPA_INET_H_
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netinet/in6.h>
+
+__BEGIN_DECLS
+
+typedef uint32_t in_addr_t;
+
+extern uint32_t      inet_addr(const char *);
+
+extern int           inet_aton(const char *, struct in_addr *);
+extern char*         inet_ntoa(struct in_addr);
+
+extern int           inet_pton(int, const char *, void *);
+extern const char*   inet_ntop(int, const void *, char *, size_t);
+
+extern unsigned int  inet_nsap_addr(const char *, unsigned char *, int);
+extern char*         inet_nsap_ntoa(int, const unsigned char *, char *);
+
+__END_DECLS
+
+#endif /* _ARPA_INET_H_ */
+
+
diff --git a/ndk/build/platforms/android-1.5/common/include/arpa/nameser.h b/ndk/build/platforms/android-1.5/common/include/arpa/nameser.h
new file mode 100644
index 0000000..028eadc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/arpa/nameser.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _arpa_nameser_h
+#define _arpa_nameser_h
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+/* this header intentionally blank
+ *
+ * the definitions normally found in <arpa/nameser.h> are
+ * really a bunch of resolver's internal declarations that
+ * should not be exposed to client code in any way
+ */
+
+#endif /* _arpa_nameser_h */
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/4level-fixup.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/4level-fixup.h
new file mode 100644
index 0000000..91ae7f4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/4level-fixup.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _4LEVEL_FIXUP_H
+#define _4LEVEL_FIXUP_H
+
+#define __ARCH_HAS_4LEVEL_HACK
+#define __PAGETABLE_PUD_FOLDED
+
+#define PUD_SIZE PGDIR_SIZE
+#define PUD_MASK PGDIR_MASK
+#define PTRS_PER_PUD 1
+
+#define pud_t pgd_t
+
+#define pmd_alloc(mm, pud, address)   ((unlikely(pgd_none(*(pud))) && __pmd_alloc(mm, pud, address))?   NULL: pmd_offset(pud, address))
+
+#define pud_alloc(mm, pgd, address) (pgd)
+#define pud_offset(pgd, start) (pgd)
+#define pud_none(pud) 0
+#define pud_bad(pud) 0
+#define pud_present(pud) 1
+#define pud_ERROR(pud) do { } while (0)
+#define pud_clear(pud) pgd_clear(pud)
+
+#undef pud_free_tlb
+#define pud_free_tlb(tlb, x) do { } while (0)
+#define pud_free(x) do { } while (0)
+#define __pud_free_tlb(tlb, x) do { } while (0)
+
+#undef pud_addr_end
+#define pud_addr_end(addr, end) (end)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/audit_dir_write.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/audit_dir_write.h
new file mode 100644
index 0000000..1327b59
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/audit_dir_write.h
@@ -0,0 +1,11 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/__ffs.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/__ffs.h
new file mode 100644
index 0000000..3d135bd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/__ffs.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_BITOPS___FFS_H_
+#define _ASM_GENERIC_BITOPS___FFS_H_
+
+#include <asm/types.h>
+
+#if BITS_PER_LONG == 64
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/atomic.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/atomic.h
new file mode 100644
index 0000000..5f53ba9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/atomic.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_BITOPS_ATOMIC_H_
+#define _ASM_GENERIC_BITOPS_ATOMIC_H_
+
+#include <asm/types.h>
+
+#define BITOP_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
+
+#define _atomic_spin_lock_irqsave(l,f) do { local_irq_save(f); } while (0)
+#define _atomic_spin_unlock_irqrestore(l,f) do { local_irq_restore(f); } while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/ffz.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/ffz.h
new file mode 100644
index 0000000..18da271
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/ffz.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_BITOPS_FFZ_H_
+#define _ASM_GENERIC_BITOPS_FFZ_H_
+
+#define ffz(x) __ffs(~(x))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/find.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/find.h
new file mode 100644
index 0000000..8361cfe
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/find.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_BITOPS_FIND_H_
+#define _ASM_GENERIC_BITOPS_FIND_H_
+
+#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
+#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/fls.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/fls.h
new file mode 100644
index 0000000..8adbf31
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/fls.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_BITOPS_FLS_H_
+#define _ASM_GENERIC_BITOPS_FLS_H_
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/fls64.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/fls64.h
new file mode 100644
index 0000000..af77098
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/fls64.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_BITOPS_FLS64_H_
+#define _ASM_GENERIC_BITOPS_FLS64_H_
+
+#include <asm/types.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/le.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/le.h
new file mode 100644
index 0000000..97ca973
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/le.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_BITOPS_LE_H_
+#define _ASM_GENERIC_BITOPS_LE_H_
+
+#include <asm/types.h>
+#include <asm/byteorder.h>
+
+#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
+#define BITOP_LE_SWIZZLE ((BITS_PER_LONG-1) & ~0x7)
+
+#ifdef __LITTLE_ENDIAN
+
+#define generic_test_le_bit(nr, addr) test_bit(nr, addr)
+#define generic___set_le_bit(nr, addr) __set_bit(nr, addr)
+#define generic___clear_le_bit(nr, addr) __clear_bit(nr, addr)
+
+#define generic_test_and_set_le_bit(nr, addr) test_and_set_bit(nr, addr)
+#define generic_test_and_clear_le_bit(nr, addr) test_and_clear_bit(nr, addr)
+
+#define generic___test_and_set_le_bit(nr, addr) __test_and_set_bit(nr, addr)
+#define generic___test_and_clear_le_bit(nr, addr) __test_and_clear_bit(nr, addr)
+
+#define generic_find_next_zero_le_bit(addr, size, offset) find_next_zero_bit(addr, size, offset)
+
+#elif defined(__BIG_ENDIAN)
+
+#define generic_test_le_bit(nr, addr)   test_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+#define generic___set_le_bit(nr, addr)   __set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+#define generic___clear_le_bit(nr, addr)   __clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+
+#define generic_test_and_set_le_bit(nr, addr)   test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+#define generic_test_and_clear_le_bit(nr, addr)   test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+
+#define generic___test_and_set_le_bit(nr, addr)   __test_and_set_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+#define generic___test_and_clear_le_bit(nr, addr)   __test_and_clear_bit((nr) ^ BITOP_LE_SWIZZLE, (addr))
+
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+
+#define generic_find_first_zero_le_bit(addr, size)   generic_find_next_zero_le_bit((addr), (size), 0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/non-atomic.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/non-atomic.h
new file mode 100644
index 0000000..727f736
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/bitops/non-atomic.h
@@ -0,0 +1,20 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
+#define _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
+
+#include <asm/types.h>
+
+#define BITOP_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/bug.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/bug.h
new file mode 100644
index 0000000..d91a135
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/bug.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_BUG_H
+#define _ASM_GENERIC_BUG_H
+
+#include <linux/compiler.h>
+
+#ifndef HAVE_ARCH_BUG
+#define BUG()
+#endif
+
+#ifndef HAVE_ARCH_BUG_ON
+#define BUG_ON(condition) do { if (condition) ; } while(0)
+#endif
+
+#ifndef HAVE_ARCH_WARN_ON
+#define WARN_ON(condition) do { if (condition) ; } while(0)
+#endif
+
+#define WARN_ON_ONCE(condition)  ({   static int __warn_once = 1;   int __ret = 0;     if (unlikely((condition) && __warn_once)) {   __warn_once = 0;   WARN_ON(1);   __ret = 1;   }   __ret;  })
+
+#define WARN_ON_SMP(x) do { } while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/cputime.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/cputime.h
new file mode 100644
index 0000000..0486b87
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/cputime.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_CPUTIME_H
+#define _ASM_GENERIC_CPUTIME_H
+
+#include <linux/time.h>
+#include <linux/jiffies.h>
+
+typedef unsigned long cputime_t;
+
+#define cputime_zero (0UL)
+#define cputime_max ((~0UL >> 1) - 1)
+#define cputime_add(__a, __b) ((__a) + (__b))
+#define cputime_sub(__a, __b) ((__a) - (__b))
+#define cputime_div(__a, __n) ((__a) / (__n))
+#define cputime_halve(__a) ((__a) >> 1)
+#define cputime_eq(__a, __b) ((__a) == (__b))
+#define cputime_gt(__a, __b) ((__a) > (__b))
+#define cputime_ge(__a, __b) ((__a) >= (__b))
+#define cputime_lt(__a, __b) ((__a) < (__b))
+#define cputime_le(__a, __b) ((__a) <= (__b))
+#define cputime_to_jiffies(__ct) (__ct)
+#define jiffies_to_cputime(__hz) (__hz)
+
+typedef u64 cputime64_t;
+
+#define cputime64_zero (0ULL)
+#define cputime64_add(__a, __b) ((__a) + (__b))
+#define cputime64_sub(__a, __b) ((__a) - (__b))
+#define cputime64_to_jiffies64(__ct) (__ct)
+#define jiffies64_to_cputime64(__jif) (__jif)
+#define cputime_to_cputime64(__ct) ((u64) __ct)
+
+#define cputime_to_msecs(__ct) jiffies_to_msecs(__ct)
+#define msecs_to_cputime(__msecs) msecs_to_jiffies(__msecs)
+
+#define cputime_to_secs(jif) ((jif) / HZ)
+#define secs_to_cputime(sec) ((sec) * HZ)
+
+#define timespec_to_cputime(__val) timespec_to_jiffies(__val)
+#define cputime_to_timespec(__ct,__val) jiffies_to_timespec(__ct,__val)
+
+#define timeval_to_cputime(__val) timeval_to_jiffies(__val)
+#define cputime_to_timeval(__ct,__val) jiffies_to_timeval(__ct,__val)
+
+#define cputime_to_clock_t(__ct) jiffies_to_clock_t(__ct)
+#define clock_t_to_cputime(__x) clock_t_to_jiffies(__x)
+
+#define cputime64_to_clock_t(__ct) jiffies_64_to_clock_t(__ct)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/emergency-restart.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/emergency-restart.h
new file mode 100644
index 0000000..619c682
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/emergency-restart.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_EMERGENCY_RESTART_H
+#define _ASM_GENERIC_EMERGENCY_RESTART_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/errno-base.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/errno-base.h
new file mode 100644
index 0000000..2fb4a33
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/errno-base.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_ERRNO_BASE_H
+#define _ASM_GENERIC_ERRNO_BASE_H
+
+#define EPERM 1  
+#define ENOENT 2  
+#define ESRCH 3  
+#define EINTR 4  
+#define EIO 5  
+#define ENXIO 6  
+#define E2BIG 7  
+#define ENOEXEC 8  
+#define EBADF 9  
+#define ECHILD 10  
+#define EAGAIN 11  
+#define ENOMEM 12  
+#define EACCES 13  
+#define EFAULT 14  
+#define ENOTBLK 15  
+#define EBUSY 16  
+#define EEXIST 17  
+#define EXDEV 18  
+#define ENODEV 19  
+#define ENOTDIR 20  
+#define EISDIR 21  
+#define EINVAL 22  
+#define ENFILE 23  
+#define EMFILE 24  
+#define ENOTTY 25  
+#define ETXTBSY 26  
+#define EFBIG 27  
+#define ENOSPC 28  
+#define ESPIPE 29  
+#define EROFS 30  
+#define EMLINK 31  
+#define EPIPE 32  
+#define EDOM 33  
+#define ERANGE 34  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/errno.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/errno.h
new file mode 100644
index 0000000..11dd00f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/errno.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_ERRNO_H
+#define _ASM_GENERIC_ERRNO_H
+
+#include <asm-generic/errno-base.h>
+
+#define EDEADLK 35  
+#define ENAMETOOLONG 36  
+#define ENOLCK 37  
+#define ENOSYS 38  
+#define ENOTEMPTY 39  
+#define ELOOP 40  
+#define EWOULDBLOCK EAGAIN  
+#define ENOMSG 42  
+#define EIDRM 43  
+#define ECHRNG 44  
+#define EL2NSYNC 45  
+#define EL3HLT 46  
+#define EL3RST 47  
+#define ELNRNG 48  
+#define EUNATCH 49  
+#define ENOCSI 50  
+#define EL2HLT 51  
+#define EBADE 52  
+#define EBADR 53  
+#define EXFULL 54  
+#define ENOANO 55  
+#define EBADRQC 56  
+#define EBADSLT 57  
+
+#define EDEADLOCK EDEADLK
+
+#define EBFONT 59  
+#define ENOSTR 60  
+#define ENODATA 61  
+#define ETIME 62  
+#define ENOSR 63  
+#define ENONET 64  
+#define ENOPKG 65  
+#define EREMOTE 66  
+#define ENOLINK 67  
+#define EADV 68  
+#define ESRMNT 69  
+#define ECOMM 70  
+#define EPROTO 71  
+#define EMULTIHOP 72  
+#define EDOTDOT 73  
+#define EBADMSG 74  
+#define EOVERFLOW 75  
+#define ENOTUNIQ 76  
+#define EBADFD 77  
+#define EREMCHG 78  
+#define ELIBACC 79  
+#define ELIBBAD 80  
+#define ELIBSCN 81  
+#define ELIBMAX 82  
+#define ELIBEXEC 83  
+#define EILSEQ 84  
+#define ERESTART 85  
+#define ESTRPIPE 86  
+#define EUSERS 87  
+#define ENOTSOCK 88  
+#define EDESTADDRREQ 89  
+#define EMSGSIZE 90  
+#define EPROTOTYPE 91  
+#define ENOPROTOOPT 92  
+#define EPROTONOSUPPORT 93  
+#define ESOCKTNOSUPPORT 94  
+#define EOPNOTSUPP 95  
+#define EPFNOSUPPORT 96  
+#define EAFNOSUPPORT 97  
+#define EADDRINUSE 98  
+#define EADDRNOTAVAIL 99  
+#define ENETDOWN 100  
+#define ENETUNREACH 101  
+#define ENETRESET 102  
+#define ECONNABORTED 103  
+#define ECONNRESET 104  
+#define ENOBUFS 105  
+#define EISCONN 106  
+#define ENOTCONN 107  
+#define ESHUTDOWN 108  
+#define ETOOMANYREFS 109  
+#define ETIMEDOUT 110  
+#define ECONNREFUSED 111  
+#define EHOSTDOWN 112  
+#define EHOSTUNREACH 113  
+#define EALREADY 114  
+#define EINPROGRESS 115  
+#define ESTALE 116  
+#define EUCLEAN 117  
+#define ENOTNAM 118  
+#define ENAVAIL 119  
+#define EISNAM 120  
+#define EREMOTEIO 121  
+#define EDQUOT 122  
+
+#define ENOMEDIUM 123  
+#define EMEDIUMTYPE 124  
+#define ECANCELED 125  
+#define ENOKEY 126  
+#define EKEYEXPIRED 127  
+#define EKEYREVOKED 128  
+#define EKEYREJECTED 129  
+
+#define EOWNERDEAD 130  
+#define ENOTRECOVERABLE 131  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/fcntl.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/fcntl.h
new file mode 100644
index 0000000..a53b536
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/fcntl.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_FCNTL_H
+#define _ASM_GENERIC_FCNTL_H
+
+#include <linux/types.h>
+
+#define O_ACCMODE 00000003
+#define O_RDONLY 00000000
+#define O_WRONLY 00000001
+#define O_RDWR 00000002
+#ifndef O_CREAT
+#define O_CREAT 00000100  
+#endif
+#ifndef O_EXCL
+#define O_EXCL 00000200  
+#endif
+#ifndef O_NOCTTY
+#define O_NOCTTY 00000400  
+#endif
+#ifndef O_TRUNC
+#define O_TRUNC 00001000  
+#endif
+#ifndef O_APPEND
+#define O_APPEND 00002000
+#endif
+#ifndef O_NONBLOCK
+#define O_NONBLOCK 00004000
+#endif
+#ifndef O_SYNC
+#define O_SYNC 00010000
+#endif
+#ifndef FASYNC
+#define FASYNC 00020000  
+#endif
+#ifndef O_DIRECT
+#define O_DIRECT 00040000  
+#endif
+#ifndef O_LARGEFILE
+#define O_LARGEFILE 00100000
+#endif
+#ifndef O_DIRECTORY
+#define O_DIRECTORY 00200000  
+#endif
+#ifndef O_NOFOLLOW
+#define O_NOFOLLOW 00400000  
+#endif
+#ifndef O_NOATIME
+#define O_NOATIME 01000000
+#endif
+#ifndef O_NDELAY
+#define O_NDELAY O_NONBLOCK
+#endif
+
+#define F_DUPFD 0  
+#define F_GETFD 1  
+#define F_SETFD 2  
+#define F_GETFL 3  
+#define F_SETFL 4  
+#ifndef F_GETLK
+#define F_GETLK 5
+#define F_SETLK 6
+#define F_SETLKW 7
+#endif
+#ifndef F_SETOWN
+#define F_SETOWN 8  
+#define F_GETOWN 9  
+#endif
+#ifndef F_SETSIG
+#define F_SETSIG 10  
+#define F_GETSIG 11  
+#endif
+
+#define FD_CLOEXEC 1  
+
+#ifndef F_RDLCK
+#define F_RDLCK 0
+#define F_WRLCK 1
+#define F_UNLCK 2
+#endif
+
+#ifndef F_EXLCK
+#define F_EXLCK 4  
+#define F_SHLCK 8  
+#endif
+
+#ifndef F_INPROGRESS
+#define F_INPROGRESS 16
+#endif
+
+#define LOCK_SH 1  
+#define LOCK_EX 2  
+#define LOCK_NB 4  
+#define LOCK_UN 8  
+
+#define LOCK_MAND 32  
+#define LOCK_READ 64  
+#define LOCK_WRITE 128  
+#define LOCK_RW 192  
+
+#define F_LINUX_SPECIFIC_BASE 1024
+
+#ifndef HAVE_ARCH_STRUCT_FLOCK
+#ifndef __ARCH_FLOCK_PAD
+#define __ARCH_FLOCK_PAD
+#endif
+
+struct flock {
+ short l_type;
+ short l_whence;
+ off_t l_start;
+ off_t l_len;
+ pid_t l_pid;
+ __ARCH_FLOCK_PAD
+};
+#endif
+
+#ifndef F_GETLK64
+#define F_GETLK64 12  
+#define F_SETLK64 13
+#define F_SETLKW64 14
+#endif
+
+#ifndef HAVE_ARCH_STRUCT_FLOCK64
+#ifndef __ARCH_FLOCK64_PAD
+#define __ARCH_FLOCK64_PAD
+#endif
+
+struct flock64 {
+ short l_type;
+ short l_whence;
+ loff_t l_start;
+ loff_t l_len;
+ pid_t l_pid;
+ __ARCH_FLOCK64_PAD
+};
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/futex.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/futex.h
new file mode 100644
index 0000000..05d3afe
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/futex.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_FUTEX_H
+#define _ASM_GENERIC_FUTEX_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/ioctl.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/ioctl.h
new file mode 100644
index 0000000..cba2b8e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/ioctl.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_IOCTL_H
+#define _ASM_GENERIC_IOCTL_H
+
+#define _IOC_NRBITS 8
+#define _IOC_TYPEBITS 8
+#define _IOC_SIZEBITS 14
+#define _IOC_DIRBITS 2
+
+#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT 0
+#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+#define _IOC_NONE 0U
+#define _IOC_WRITE 1U
+#define _IOC_READ 2U
+
+#define _IOC(dir,type,nr,size)   (((dir) << _IOC_DIRSHIFT) |   ((type) << _IOC_TYPESHIFT) |   ((nr) << _IOC_NRSHIFT) |   ((size) << _IOC_SIZESHIFT))
+
+extern unsigned int __invalid_size_argument_for_IOC;
+#define _IOC_TYPECHECK(t)   ((sizeof(t) == sizeof(t[1]) &&   sizeof(t) < (1 << _IOC_SIZEBITS)) ?   sizeof(t) : __invalid_size_argument_for_IOC)
+
+#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/ipc.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/ipc.h
new file mode 100644
index 0000000..57657a7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/ipc.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_IPC_H
+#define _ASM_GENERIC_IPC_H
+
+struct ipc_kludge {
+ struct msgbuf __user *msgp;
+ long msgtyp;
+};
+
+#define SEMOP 1
+#define SEMGET 2
+#define SEMCTL 3
+#define SEMTIMEDOP 4
+#define MSGSND 11
+#define MSGRCV 12
+#define MSGGET 13
+#define MSGCTL 14
+#define SHMAT 21
+#define SHMDT 22
+#define SHMGET 23
+#define SHMCTL 24
+
+#define DIPC 25
+
+#define IPCCALL(version,op) ((version)<<16 | (op))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/local.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/local.h
new file mode 100644
index 0000000..cae0d54
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/local.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_LOCAL_H
+#define _ASM_GENERIC_LOCAL_H
+
+#include <linux/percpu.h>
+#include <linux/hardirq.h>
+#include <asm/atomic.h>
+#include <asm/types.h>
+
+typedef struct
+{
+ atomic_long_t a;
+} local_t;
+
+#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) }
+
+#define local_read(l) atomic_long_read(&(l)->a)
+#define local_set(l,i) atomic_long_set((&(l)->a),(i))
+#define local_inc(l) atomic_long_inc(&(l)->a)
+#define local_dec(l) atomic_long_dec(&(l)->a)
+#define local_add(i,l) atomic_long_add((i),(&(l)->a))
+#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
+
+#define __local_inc(l) local_set((l), local_read(l) + 1)
+#define __local_dec(l) local_set((l), local_read(l) - 1)
+#define __local_add(i,l) local_set((l), local_read(l) + (i))
+#define __local_sub(i,l) local_set((l), local_read(l) - (i))
+
+#define cpu_local_read(v) local_read(&__get_cpu_var(v))
+#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i))
+#define cpu_local_inc(v) local_inc(&__get_cpu_var(v))
+#define cpu_local_dec(v) local_dec(&__get_cpu_var(v))
+#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v))
+#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v))
+
+#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v))
+#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v))
+#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v))
+#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/memory_model.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/memory_model.h
new file mode 100644
index 0000000..fa7602e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/memory_model.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_MEMORY_MODEL_H
+#define __ASM_MEMORY_MODEL_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/mman.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/mman.h
new file mode 100644
index 0000000..98d2783
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/mman.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_MMAN_H
+#define _ASM_GENERIC_MMAN_H
+
+#define PROT_READ 0x1  
+#define PROT_WRITE 0x2  
+#define PROT_EXEC 0x4  
+#define PROT_SEM 0x8  
+#define PROT_NONE 0x0  
+#define PROT_GROWSDOWN 0x01000000  
+#define PROT_GROWSUP 0x02000000  
+
+#define MAP_SHARED 0x01  
+#define MAP_PRIVATE 0x02  
+#define MAP_TYPE 0x0f  
+#define MAP_FIXED 0x10  
+#define MAP_ANONYMOUS 0x20  
+
+#define MS_ASYNC 1  
+#define MS_INVALIDATE 2  
+#define MS_SYNC 4  
+
+#define MADV_NORMAL 0  
+#define MADV_RANDOM 1  
+#define MADV_SEQUENTIAL 2  
+#define MADV_WILLNEED 3  
+#define MADV_DONTNEED 4  
+
+#define MADV_REMOVE 9  
+#define MADV_DONTFORK 10  
+#define MADV_DOFORK 11  
+
+#define MAP_ANON MAP_ANONYMOUS
+#define MAP_FILE 0
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/mutex-xchg.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/mutex-xchg.h
new file mode 100644
index 0000000..63a557e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/mutex-xchg.h
@@ -0,0 +1,16 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_MUTEX_XCHG_H
+#define _ASM_GENERIC_MUTEX_XCHG_H
+
+#define __mutex_slowpath_needs_to_unlock() 0
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/percpu.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/percpu.h
new file mode 100644
index 0000000..e498300
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/percpu.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_PERCPU_H_
+#define _ASM_GENERIC_PERCPU_H_
+#include <linux/compiler.h>
+
+#define __GENERIC_PER_CPU
+
+#define DEFINE_PER_CPU(type, name)   __typeof__(type) per_cpu__##name
+
+#define per_cpu(var, cpu) (*((void)(cpu), &per_cpu__##var))
+#define __get_cpu_var(var) per_cpu__##var
+#define __raw_get_cpu_var(var) per_cpu__##var
+
+#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
+
+#define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var)
+#define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/pgtable-nopud.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/pgtable-nopud.h
new file mode 100644
index 0000000..585f816
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/pgtable-nopud.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _PGTABLE_NOPUD_H
+#define _PGTABLE_NOPUD_H
+
+#ifndef __ASSEMBLY__
+
+#define __PAGETABLE_PUD_FOLDED
+
+typedef struct { pgd_t pgd; } pud_t;
+
+#define PUD_SHIFT PGDIR_SHIFT
+#define PTRS_PER_PUD 1
+#define PUD_SIZE (1UL << PUD_SHIFT)
+#define PUD_MASK (~(PUD_SIZE-1))
+
+#define pud_ERROR(pud) (pgd_ERROR((pud).pgd))
+#define pgd_populate(mm, pgd, pud) do { } while (0)
+#define set_pgd(pgdptr, pgdval) set_pud((pud_t *)(pgdptr), (pud_t) { pgdval })
+#define pud_val(x) (pgd_val((x).pgd))
+#define __pud(x) ((pud_t) { __pgd(x) } )
+#define pgd_page(pgd) (pud_page((pud_t){ pgd }))
+#define pgd_page_kernel(pgd) (pud_page_kernel((pud_t){ pgd }))
+#define pud_alloc_one(mm, address) NULL
+#define pud_free(x) do { } while (0)
+#define __pud_free_tlb(tlb, x) do { } while (0)
+#undef pud_addr_end
+#define pud_addr_end(addr, end) (end)
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/pgtable.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/pgtable.h
new file mode 100644
index 0000000..a21cdba
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/pgtable.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_PGTABLE_H
+#define _ASM_GENERIC_PGTABLE_H
+
+#ifndef __HAVE_ARCH_PTEP_ESTABLISH
+
+#ifndef __HAVE_ARCH_SET_PTE_ATOMIC
+#define ptep_establish(__vma, __address, __ptep, __entry)  do {   set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry);   flush_tlb_page(__vma, __address);  } while (0)
+#else
+#define ptep_establish(__vma, __address, __ptep, __entry)  do {   set_pte_atomic(__ptep, __entry);   flush_tlb_page(__vma, __address);  } while (0)
+#endif
+#endif
+
+#ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+
+#define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty)  do {   set_pte_at((__vma)->vm_mm, (__address), __ptep, __entry);   flush_tlb_page(__vma, __address);  } while (0)
+#endif
+
+#ifndef __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define ptep_test_and_clear_young(__vma, __address, __ptep)  ({   pte_t __pte = *(__ptep);   int r = 1;   if (!pte_young(__pte))   r = 0;   else   set_pte_at((__vma)->vm_mm, (__address),   (__ptep), pte_mkold(__pte));   r;  })
+#endif
+
+#ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+#define ptep_clear_flush_young(__vma, __address, __ptep)  ({   int __young;   __young = ptep_test_and_clear_young(__vma, __address, __ptep);   if (__young)   flush_tlb_page(__vma, __address);   __young;  })
+#endif
+
+#ifndef __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
+#define ptep_test_and_clear_dirty(__vma, __address, __ptep)  ({   pte_t __pte = *__ptep;   int r = 1;   if (!pte_dirty(__pte))   r = 0;   else   set_pte_at((__vma)->vm_mm, (__address), (__ptep),   pte_mkclean(__pte));   r;  })
+#endif
+
+#ifndef __HAVE_ARCH_PTEP_CLEAR_DIRTY_FLUSH
+#define ptep_clear_flush_dirty(__vma, __address, __ptep)  ({   int __dirty;   __dirty = ptep_test_and_clear_dirty(__vma, __address, __ptep);   if (__dirty)   flush_tlb_page(__vma, __address);   __dirty;  })
+#endif
+
+#ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define ptep_get_and_clear(__mm, __address, __ptep)  ({   pte_t __pte = *(__ptep);   pte_clear((__mm), (__address), (__ptep));   __pte;  })
+#endif
+
+#ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
+#define ptep_get_and_clear_full(__mm, __address, __ptep, __full)  ({   pte_t __pte;   __pte = ptep_get_and_clear((__mm), (__address), (__ptep));   __pte;  })
+#endif
+
+#ifndef __HAVE_ARCH_PTE_CLEAR_FULL
+#define pte_clear_full(__mm, __address, __ptep, __full)  do {   pte_clear((__mm), (__address), (__ptep));  } while (0)
+#endif
+
+#ifndef __HAVE_ARCH_PTEP_CLEAR_FLUSH
+#define ptep_clear_flush(__vma, __address, __ptep)  ({   pte_t __pte;   __pte = ptep_get_and_clear((__vma)->vm_mm, __address, __ptep);   flush_tlb_page(__vma, __address);   __pte;  })
+#endif
+
+#ifndef __HAVE_ARCH_PTEP_SET_WRPROTECT
+struct mm_struct;
+#endif
+#ifndef __HAVE_ARCH_PTE_SAME
+#define pte_same(A,B) (pte_val(A) == pte_val(B))
+#endif
+#ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY
+#define page_test_and_clear_dirty(page) (0)
+#define pte_maybe_dirty(pte) pte_dirty(pte)
+#else
+#define pte_maybe_dirty(pte) (1)
+#endif
+#ifndef __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
+#define page_test_and_clear_young(page) (0)
+#endif
+#ifndef __HAVE_ARCH_PGD_OFFSET_GATE
+#define pgd_offset_gate(mm, addr) pgd_offset(mm, addr)
+#endif
+#ifndef __HAVE_ARCH_LAZY_MMU_PROT_UPDATE
+#define lazy_mmu_prot_update(pte) do { } while (0)
+#endif
+#ifndef __HAVE_ARCH_MOVE_PTE
+#define move_pte(pte, prot, old_addr, new_addr) (pte)
+#endif
+#define pgd_addr_end(addr, end)  ({ unsigned long __boundary = ((addr) + PGDIR_SIZE) & PGDIR_MASK;   (__boundary - 1 < (end) - 1)? __boundary: (end);  })
+#ifndef pud_addr_end
+#define pud_addr_end(addr, end)  ({ unsigned long __boundary = ((addr) + PUD_SIZE) & PUD_MASK;   (__boundary - 1 < (end) - 1)? __boundary: (end);  })
+#endif
+#ifndef pmd_addr_end
+#define pmd_addr_end(addr, end)  ({ unsigned long __boundary = ((addr) + PMD_SIZE) & PMD_MASK;   (__boundary - 1 < (end) - 1)? __boundary: (end);  })
+#endif
+#ifndef __ASSEMBLY__
+
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/poll.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/poll.h
new file mode 100644
index 0000000..b8cd3da
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/poll.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_GENERIC_POLL_H
+#define __ASM_GENERIC_POLL_H
+
+#define POLLIN 0x0001
+#define POLLPRI 0x0002
+#define POLLOUT 0x0004
+#define POLLERR 0x0008
+#define POLLHUP 0x0010
+#define POLLNVAL 0x0020
+
+#define POLLRDNORM 0x0040
+#define POLLRDBAND 0x0080
+#ifndef POLLWRNORM
+#define POLLWRNORM 0x0100
+#endif
+#ifndef POLLWRBAND
+#define POLLWRBAND 0x0200
+#endif
+#ifndef POLLMSG
+#define POLLMSG 0x0400
+#endif
+#ifndef POLLREMOVE
+#define POLLREMOVE 0x1000
+#endif
+#ifndef POLLRDHUP
+#define POLLRDHUP 0x2000
+#endif
+
+struct pollfd {
+ int fd;
+ short events;
+ short revents;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/resource.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/resource.h
new file mode 100644
index 0000000..a7f7dec
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/resource.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_RESOURCE_H
+#define _ASM_GENERIC_RESOURCE_H
+
+#define RLIMIT_CPU 0  
+#define RLIMIT_FSIZE 1  
+#define RLIMIT_DATA 2  
+#define RLIMIT_STACK 3  
+#define RLIMIT_CORE 4  
+
+#ifndef RLIMIT_RSS
+#define RLIMIT_RSS 5  
+#endif
+
+#ifndef RLIMIT_NPROC
+#define RLIMIT_NPROC 6  
+#endif
+
+#ifndef RLIMIT_NOFILE
+#define RLIMIT_NOFILE 7  
+#endif
+
+#ifndef RLIMIT_MEMLOCK
+#define RLIMIT_MEMLOCK 8  
+#endif
+
+#ifndef RLIMIT_AS
+#define RLIMIT_AS 9  
+#endif
+
+#define RLIMIT_LOCKS 10  
+#define RLIMIT_SIGPENDING 11  
+#define RLIMIT_MSGQUEUE 12  
+#define RLIMIT_NICE 13  
+#define RLIMIT_RTPRIO 14  
+
+#define RLIM_NLIMITS 15
+
+#ifndef RLIM_INFINITY
+#define RLIM_INFINITY (~0UL)
+#endif
+
+#ifndef _STK_LIM_MAX
+#define _STK_LIM_MAX RLIM_INFINITY
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/sections.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/sections.h
new file mode 100644
index 0000000..e9eaa46
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/sections.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_SECTIONS_H_
+#define _ASM_GENERIC_SECTIONS_H_
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/siginfo.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/siginfo.h
new file mode 100644
index 0000000..d6743a7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/siginfo.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_SIGINFO_H
+#define _ASM_GENERIC_SIGINFO_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+typedef union sigval {
+ int sival_int;
+ void __user *sival_ptr;
+} sigval_t;
+
+#ifndef __ARCH_SI_PREAMBLE_SIZE
+#define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int))
+#endif
+
+#define SI_MAX_SIZE 128
+#ifndef SI_PAD_SIZE
+#define SI_PAD_SIZE ((SI_MAX_SIZE - __ARCH_SI_PREAMBLE_SIZE) / sizeof(int))
+#endif
+
+#ifndef __ARCH_SI_UID_T
+#define __ARCH_SI_UID_T uid_t
+#endif
+
+#ifndef __ARCH_SI_BAND_T
+#define __ARCH_SI_BAND_T long
+#endif
+
+#ifndef HAVE_ARCH_SIGINFO_T
+
+typedef struct siginfo {
+ int si_signo;
+ int si_errno;
+ int si_code;
+
+ union {
+ int _pad[SI_PAD_SIZE];
+
+ struct {
+ pid_t _pid;
+ __ARCH_SI_UID_T _uid;
+ } _kill;
+
+ struct {
+ timer_t _tid;
+ int _overrun;
+ char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
+ sigval_t _sigval;
+ int _sys_private;
+ } _timer;
+
+ struct {
+ pid_t _pid;
+ __ARCH_SI_UID_T _uid;
+ sigval_t _sigval;
+ } _rt;
+
+ struct {
+ pid_t _pid;
+ __ARCH_SI_UID_T _uid;
+ int _status;
+ clock_t _utime;
+ clock_t _stime;
+ } _sigchld;
+
+ struct {
+ void __user *_addr;
+#ifdef __ARCH_SI_TRAPNO
+ int _trapno;
+#endif
+ } _sigfault;
+
+ struct {
+ __ARCH_SI_BAND_T _band;
+ int _fd;
+ } _sigpoll;
+ } _sifields;
+} siginfo_t;
+
+#endif
+
+#define si_pid _sifields._kill._pid
+#define si_uid _sifields._kill._uid
+#define si_tid _sifields._timer._tid
+#define si_overrun _sifields._timer._overrun
+#define si_sys_private _sifields._timer._sys_private
+#define si_status _sifields._sigchld._status
+#define si_utime _sifields._sigchld._utime
+#define si_stime _sifields._sigchld._stime
+#define si_value _sifields._rt._sigval
+#define si_int _sifields._rt._sigval.sival_int
+#define si_ptr _sifields._rt._sigval.sival_ptr
+#define si_addr _sifields._sigfault._addr
+#ifdef __ARCH_SI_TRAPNO
+#define si_trapno _sifields._sigfault._trapno
+#endif
+#define si_band _sifields._sigpoll._band
+#define si_fd _sifields._sigpoll._fd
+
+#define __SI_KILL 0
+#define __SI_TIMER 0
+#define __SI_POLL 0
+#define __SI_FAULT 0
+#define __SI_CHLD 0
+#define __SI_RT 0
+#define __SI_MESGQ 0
+#define __SI_CODE(T,N) (N)
+
+#define SI_USER 0  
+#define SI_KERNEL 0x80  
+#define SI_QUEUE -1  
+#define SI_TIMER __SI_CODE(__SI_TIMER,-2)  
+#define SI_MESGQ __SI_CODE(__SI_MESGQ,-3)  
+#define SI_ASYNCIO -4  
+#define SI_SIGIO -5  
+#define SI_TKILL -6  
+#define SI_DETHREAD -7  
+
+#define SI_FROMUSER(siptr) ((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr) ((siptr)->si_code > 0)
+
+#define ILL_ILLOPC (__SI_FAULT|1)  
+#define ILL_ILLOPN (__SI_FAULT|2)  
+#define ILL_ILLADR (__SI_FAULT|3)  
+#define ILL_ILLTRP (__SI_FAULT|4)  
+#define ILL_PRVOPC (__SI_FAULT|5)  
+#define ILL_PRVREG (__SI_FAULT|6)  
+#define ILL_COPROC (__SI_FAULT|7)  
+#define ILL_BADSTK (__SI_FAULT|8)  
+#define NSIGILL 8
+
+#define FPE_INTDIV (__SI_FAULT|1)  
+#define FPE_INTOVF (__SI_FAULT|2)  
+#define FPE_FLTDIV (__SI_FAULT|3)  
+#define FPE_FLTOVF (__SI_FAULT|4)  
+#define FPE_FLTUND (__SI_FAULT|5)  
+#define FPE_FLTRES (__SI_FAULT|6)  
+#define FPE_FLTINV (__SI_FAULT|7)  
+#define FPE_FLTSUB (__SI_FAULT|8)  
+#define NSIGFPE 8
+
+#define SEGV_MAPERR (__SI_FAULT|1)  
+#define SEGV_ACCERR (__SI_FAULT|2)  
+#define NSIGSEGV 2
+
+#define BUS_ADRALN (__SI_FAULT|1)  
+#define BUS_ADRERR (__SI_FAULT|2)  
+#define BUS_OBJERR (__SI_FAULT|3)  
+#define NSIGBUS 3
+
+#define TRAP_BRKPT (__SI_FAULT|1)  
+#define TRAP_TRACE (__SI_FAULT|2)  
+#define NSIGTRAP 2
+
+#define CLD_EXITED (__SI_CHLD|1)  
+#define CLD_KILLED (__SI_CHLD|2)  
+#define CLD_DUMPED (__SI_CHLD|3)  
+#define CLD_TRAPPED (__SI_CHLD|4)  
+#define CLD_STOPPED (__SI_CHLD|5)  
+#define CLD_CONTINUED (__SI_CHLD|6)  
+#define NSIGCHLD 6
+
+#define POLL_IN (__SI_POLL|1)  
+#define POLL_OUT (__SI_POLL|2)  
+#define POLL_MSG (__SI_POLL|3)  
+#define POLL_ERR (__SI_POLL|4)  
+#define POLL_PRI (__SI_POLL|5)  
+#define POLL_HUP (__SI_POLL|6)  
+#define NSIGPOLL 6
+
+#define SIGEV_SIGNAL 0  
+#define SIGEV_NONE 1  
+#define SIGEV_THREAD 2  
+#define SIGEV_THREAD_ID 4  
+
+#ifndef __ARCH_SIGEV_PREAMBLE_SIZE
+#define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(int) * 2 + sizeof(sigval_t))
+#endif
+
+#define SIGEV_MAX_SIZE 64
+#define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE - __ARCH_SIGEV_PREAMBLE_SIZE)   / sizeof(int))
+
+typedef struct sigevent {
+ sigval_t sigev_value;
+ int sigev_signo;
+ int sigev_notify;
+ union {
+ int _pad[SIGEV_PAD_SIZE];
+ int _tid;
+
+ struct {
+ void (*_function)(sigval_t);
+ void *_attribute;
+ } _sigev_thread;
+ } _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function _sigev_un._sigev_thread._function
+#define sigev_notify_attributes _sigev_un._sigev_thread._attribute
+#define sigev_notify_thread_id _sigev_un._tid
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/signal.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/signal.h
new file mode 100644
index 0000000..226d99c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/signal.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ASM_GENERIC_SIGNAL_H
+#define __ASM_GENERIC_SIGNAL_H
+
+#include <linux/compiler.h>
+
+#ifndef SIG_BLOCK
+#define SIG_BLOCK 0  
+#endif
+#ifndef SIG_UNBLOCK
+#define SIG_UNBLOCK 1  
+#endif
+#ifndef SIG_SETMASK
+#define SIG_SETMASK 2  
+#endif
+
+#ifndef __ASSEMBLY__
+typedef void __signalfn_t(int);
+typedef __signalfn_t __user *__sighandler_t;
+
+typedef void __restorefn_t(void);
+typedef __restorefn_t __user *__sigrestore_t;
+
+#define SIG_DFL ((__force __sighandler_t)0)  
+#define SIG_IGN ((__force __sighandler_t)1)  
+#define SIG_ERR ((__force __sighandler_t)-1)  
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/tlb.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/tlb.h
new file mode 100644
index 0000000..dc1e79f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/tlb.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC__TLB_H
+#define _ASM_GENERIC__TLB_H
+
+#include <linux/swap.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+
+#define FREE_PTE_NR 1
+#define tlb_fast_mode(tlb) 1
+
+struct mmu_gather {
+ struct mm_struct *mm;
+ unsigned int nr;
+ unsigned int need_flush;
+ unsigned int fullmm;
+ struct page * pages[FREE_PTE_NR];
+};
+
+#define tlb_remove_tlb_entry(tlb, ptep, address)   do {   tlb->need_flush = 1;   __tlb_remove_tlb_entry(tlb, ptep, address);   } while (0)
+#define pte_free_tlb(tlb, ptep)   do {   tlb->need_flush = 1;   __pte_free_tlb(tlb, ptep);   } while (0)
+#ifndef __ARCH_HAS_4LEVEL_HACK
+#define pud_free_tlb(tlb, pudp)   do {   tlb->need_flush = 1;   __pud_free_tlb(tlb, pudp);   } while (0)
+#endif
+#define pmd_free_tlb(tlb, pmdp)   do {   tlb->need_flush = 1;   __pmd_free_tlb(tlb, pmdp);   } while (0)
+#define tlb_migrate_finish(mm) do {} while (0)
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/topology.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/topology.h
new file mode 100644
index 0000000..089b1f2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/topology.h
@@ -0,0 +1,35 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_GENERIC_TOPOLOGY_H
+#define _ASM_GENERIC_TOPOLOGY_H
+
+#ifndef cpu_to_node
+#define cpu_to_node(cpu) (0)
+#endif
+#ifndef parent_node
+#define parent_node(node) (0)
+#endif
+#ifndef node_to_cpumask
+#define node_to_cpumask(node) (cpu_online_map)
+#endif
+#ifndef node_to_first_cpu
+#define node_to_first_cpu(node) (0)
+#endif
+#ifndef pcibus_to_node
+#define pcibus_to_node(node) (-1)
+#endif
+
+#ifndef pcibus_to_cpumask
+#define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ?   CPU_MASK_ALL :   node_to_cpumask(pcibus_to_node(bus))   )
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/asm-generic/xor.h b/ndk/build/platforms/android-1.5/common/include/asm-generic/xor.h
new file mode 100644
index 0000000..6b1e4e8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/asm-generic/xor.h
@@ -0,0 +1,14 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm/processor.h>
+
+#define XOR_TRY_TEMPLATES   do {   xor_speed(&xor_block_8regs);   xor_speed(&xor_block_8regs_p);   xor_speed(&xor_block_32regs);   xor_speed(&xor_block_32regs_p);   } while (0)
diff --git a/ndk/build/platforms/android-1.5/common/include/assert.h b/ndk/build/platforms/android-1.5/common/include/assert.h
new file mode 100644
index 0000000..62470f5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/assert.h
@@ -0,0 +1,65 @@
+/*	$OpenBSD: assert.h,v 1.12 2006/01/31 10:53:51 hshoexer Exp $	*/
+/*	$NetBSD: assert.h,v 1.6 1994/10/26 00:55:44 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)assert.h	8.2 (Berkeley) 1/21/94
+ */
+
+/*
+ * Unlike other ANSI header files, <assert.h> may usefully be included
+ * multiple times, with and without NDEBUG defined.
+ */
+
+#include <sys/cdefs.h>
+
+#undef assert
+#undef _assert
+
+#ifdef NDEBUG
+# define	assert(e)	((void)0)
+# define	_assert(e)	((void)0)
+#else
+# define	_assert(e)	assert(e)
+# if __ISO_C_VISIBLE >= 1999
+#  define	assert(e)	((e) ? (void)0 : __assert2(__FILE__, __LINE__, __func__, #e))
+# else
+#  define	assert(e)	((e) ? (void)0 : __assert(__FILE__, __LINE__, #e))
+# endif
+#endif
+
+__BEGIN_DECLS
+__dead void __assert(const char *, int, const char *);
+__dead void __assert2(const char *, int, const char *, const char *);
+__END_DECLS
diff --git a/ndk/build/platforms/android-1.5/common/include/byteswap.h b/ndk/build/platforms/android-1.5/common/include/byteswap.h
new file mode 100644
index 0000000..16d2ad4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/byteswap.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _BYTESWAP_H_
+#define _BYTESWAP_H_
+
+#include <sys/endian.h>
+
+#define  bswap_16(x)   swap16(x)
+#define  bswap_32(x)   swap32(x)
+#define  bswap_64(x)   swap64(x)
+
+#endif /* _BYTESWAP_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/cstddef b/ndk/build/platforms/android-1.5/common/include/cstddef
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/cstddef
diff --git a/ndk/build/platforms/android-1.5/common/include/ctype.h b/ndk/build/platforms/android-1.5/common/include/ctype.h
new file mode 100644
index 0000000..b5f9ff4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/ctype.h
@@ -0,0 +1,203 @@
+/*	$OpenBSD: ctype.h,v 1.19 2005/12/13 00:35:22 millert Exp $	*/
+/*	$NetBSD: ctype.h,v 1.14 1994/10/26 00:55:47 cgd Exp $	*/
+
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)ctype.h	5.3 (Berkeley) 4/3/91
+ */
+
+#ifndef _CTYPE_H_
+#define _CTYPE_H_
+
+#include <sys/cdefs.h>
+
+#define	_U	0x01
+#define	_L	0x02
+#define	_N	0x04
+#define	_S	0x08
+#define	_P	0x10
+#define	_C	0x20
+#define	_X	0x40
+#define	_B	0x80
+
+__BEGIN_DECLS
+
+extern const char	*_ctype_;
+extern const short	*_tolower_tab_;
+extern const short	*_toupper_tab_;
+
+/* extern __inline is a GNU C extension */
+#ifdef __GNUC__
+#define	__CTYPE_INLINE	extern __inline
+#else
+#define	__CTYPE_INLINE	static __inline
+#endif
+
+#if defined(__GNUC__) || defined(_ANSI_LIBRARY) || defined(lint)
+int	isalnum(int);
+int	isalpha(int);
+int	iscntrl(int);
+int	isdigit(int);
+int	isgraph(int);
+int	islower(int);
+int	isprint(int);
+int	ispunct(int);
+int	isspace(int);
+int	isupper(int);
+int	isxdigit(int);
+int	tolower(int);
+int	toupper(int);
+
+#if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __POSIX_VISIBLE > 200112 \
+    || __XPG_VISIBLE > 600
+int	isblank(int);
+#endif
+
+#if __BSD_VISIBLE || __XPG_VISIBLE
+int	isascii(int);
+int	toascii(int);
+int	_tolower(int);
+int	_toupper(int);
+#endif /* __BSD_VISIBLE || __XPG_VISIBLE */
+
+#endif /* __GNUC__ || _ANSI_LIBRARY || lint */
+
+#if defined(NDEBUG)
+
+__CTYPE_INLINE int isalnum(int c)
+{
+	return (c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_U|_L|_N)));
+}
+
+__CTYPE_INLINE int isalpha(int c)
+{
+	return (c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_U|_L)));
+}
+
+__CTYPE_INLINE int iscntrl(int c)
+{
+	return (c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _C));
+}
+
+__CTYPE_INLINE int isdigit(int c)
+{
+	return (c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _N));
+}
+
+__CTYPE_INLINE int isgraph(int c)
+{
+	return (c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_P|_U|_L|_N)));
+}
+
+__CTYPE_INLINE int islower(int c)
+{
+	return (c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _L));
+}
+
+__CTYPE_INLINE int isprint(int c)
+{
+	return (c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_P|_U|_L|_N|_B)));
+}
+
+__CTYPE_INLINE int ispunct(int c)
+{
+	return (c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _P));
+}
+
+__CTYPE_INLINE int isspace(int c)
+{
+	return (c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _S));
+}
+
+__CTYPE_INLINE int isupper(int c)
+{
+	return (c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)c] & _U));
+}
+
+__CTYPE_INLINE int isxdigit(int c)
+{
+	return (c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)c] & (_N|_X)));
+}
+
+__CTYPE_INLINE int tolower(int c)
+{
+	if ((unsigned int)c > 255)
+		return (c);
+	return ((_tolower_tab_ + 1)[c]);
+}
+
+__CTYPE_INLINE int toupper(int c)
+{
+	if ((unsigned int)c > 255)
+		return (c);
+	return ((_toupper_tab_ + 1)[c]);
+}
+
+#if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __POSIX_VISIBLE > 200112 \
+    || __XPG_VISIBLE > 600
+__CTYPE_INLINE int isblank(int c)
+{
+	return (c == ' ' || c == '\t');
+}
+#endif
+
+#if __BSD_VISIBLE || __XPG_VISIBLE
+__CTYPE_INLINE int isascii(int c)
+{
+	return ((unsigned int)c <= 0177);
+}
+
+__CTYPE_INLINE int toascii(int c)
+{
+	return (c & 0177);
+}
+
+__CTYPE_INLINE int _tolower(int c)
+{
+	return (c - 'A' + 'a');
+}
+
+__CTYPE_INLINE int _toupper(int c)
+{
+	return (c - 'a' + 'A');
+}
+#endif /* __BSD_VISIBLE || __XPG_VISIBLE */
+
+#endif /* NDEBUG */
+
+__END_DECLS
+
+#undef __CTYPE_INLINE
+
+#endif /* !_CTYPE_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/dirent.h b/ndk/build/platforms/android-1.5/common/include/dirent.h
new file mode 100644
index 0000000..55eef7b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/dirent.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _DIRENT_H_
+#define _DIRENT_H_
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+#ifndef DT_UNKNOWN
+#define  DT_UNKNOWN     0
+#define  DT_FIFO        1
+#define  DT_CHR         2
+#define  DT_DIR         4
+#define  DT_BLK         6
+#define  DT_REG         8
+#define  DT_LNK         10
+#define  DT_SOCK        12
+#define  DT_WHT         14
+#endif
+
+/* the following structure is really called dirent64 by the kernel
+ * headers. They also define a struct dirent, but the latter lack
+ * the d_type field which is required by some libraries (e.g. hotplug)
+ * who assume to be able to access it directly. sad...
+ */
+struct dirent {
+    uint64_t         d_ino;
+    int64_t          d_off;
+    unsigned short   d_reclen;
+    unsigned char    d_type;
+    char             d_name[256];
+};
+
+typedef struct DIR  DIR;
+
+extern  int              getdents(unsigned int, struct dirent*, unsigned int);
+extern  DIR*             opendir(const char*  dirpath);
+extern  DIR*             fdopendir(int fd);
+extern  struct dirent*   readdir(DIR*  dirp);
+extern  int              readdir_r(DIR*  dirp, struct dirent *entry, struct dirent **result);
+extern  int              closedir(DIR*  dirp);
+extern  void             rewinddir(DIR *dirp);
+extern  int              dirfd(DIR* dirp);
+extern  int              alphasort(const void *a, const void *b);
+extern  int              scandir(const char *dir, struct dirent ***namelist,
+                                 int(*filter)(const struct dirent *),
+                                 int(*compar)(const struct dirent **, 
+                                              const struct dirent **));
+
+__END_DECLS
+
+#endif /* _DIRENT_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/dlfcn.h b/ndk/build/platforms/android-1.5/common/include/dlfcn.h
new file mode 100644
index 0000000..9582796
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/dlfcn.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef __DLFCN_H__
+#define __DLFCN_H__
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+extern void*        dlopen(const char*  filename, int flag);
+extern int          dlclose(void*  handle);
+extern const char*  dlerror(void);
+extern void*        dlsym(void*  handle, const char*  symbol);
+
+enum {
+  RTLD_NOW  = 0,
+  RTLD_LAZY = 1,
+
+  RTLD_LOCAL  = 0,
+  RTLD_GLOBAL = 2,
+};
+
+#define RTLD_DEFAULT  ((void*) 0xffffffff)
+#define RTLD_NEXT     ((void*) 0xfffffffe)
+
+__END_DECLS
+
+#endif /* __DLFCN_H */
+
+
diff --git a/ndk/build/platforms/android-1.5/common/include/elf.h b/ndk/build/platforms/android-1.5/common/include/elf.h
new file mode 100644
index 0000000..8a86a63
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/elf.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _ELF_H
+#define _ELF_H
+
+/* these definitions are missing from the BSD sources */
+enum {
+    AT_NULL = 0,
+    AT_IGNORE,
+    AT_EXECFD,
+    AT_PHDR,
+    AT_PHENT,
+    AT_PHNUM,
+    AT_PAGESZ,
+    AT_BASE,
+    AT_FLAGS,
+    AT_ENTRY,
+    AT_NOTELF,
+    AT_UID,
+    AT_EUID,
+    AT_GID,
+    AT_EGID,
+    AT_PLATFORM,
+    AT_HWCAP,
+    AT_CLKTCK,
+
+    AT_SECURE = 23
+};
+
+#include <sys/exec_elf.h>
+
+#endif /* _ELF_H */
+
diff --git a/ndk/build/platforms/android-1.5/common/include/endian.h b/ndk/build/platforms/android-1.5/common/include/endian.h
new file mode 100644
index 0000000..475b48c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/endian.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _ENDIAN_H_
+#define _ENDIAN_H_
+
+#include <sys/endian.h>
+
+#endif /* _ENDIAN_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/err.h b/ndk/build/platforms/android-1.5/common/include/err.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/err.h
diff --git a/ndk/build/platforms/android-1.5/common/include/errno.h b/ndk/build/platforms/android-1.5/common/include/errno.h
new file mode 100644
index 0000000..2b2685a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/errno.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _ERRNO_H
+#define _ERRNO_H
+
+#include <sys/cdefs.h>
+#include <linux/errno.h>
+
+__BEGIN_DECLS
+
+/* on Linux, ENOTSUP and EOPNOTSUPP are defined as the same error code
+ * even if 1000.3 states that they should be different
+ */
+#ifndef  ENOTUP
+#define  ENOTSUP  EOPNOTSUPP
+#endif
+
+/* internal function that should *only* be called from system calls */
+/* use errno = xxxx instead in C code                               */
+extern int    __set_errno(int  error);
+
+/* internal function returning the address of the thread-specific errno */
+extern volatile int*   __errno(void);
+
+/* a macro expanding to the errno l-value */
+#define  errno   (*__errno())
+
+__END_DECLS
+
+#endif /* _ERRNO_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/fcntl.h b/ndk/build/platforms/android-1.5/common/include/fcntl.h
new file mode 100644
index 0000000..59e7135
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/fcntl.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _FCNTL_H
+#define _FCNTL_H
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <linux/fcntl.h>
+#include <unistd.h>  /* this is not required, but makes client code much happier */
+
+__BEGIN_DECLS
+
+#ifndef O_ASYNC
+#define O_ASYNC  FASYNC
+#endif
+
+extern int  open(const char*  path, int  mode, ...);
+extern int  openat(int fd, const char*  path, int  mode, ...);
+extern int  unlinkat(int dirfd, const char *pathname, int flags);
+extern int  fcntl(int   fd, int   command, ...);
+extern int  creat(const char*  path, mode_t  mode);
+
+__END_DECLS
+
+#endif /* _FCNTL_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/features.h b/ndk/build/platforms/android-1.5/common/include/features.h
new file mode 100644
index 0000000..343c84d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/features.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _FEATURES_H_
+#define _FEATURES_H_
+
+/* certain Linux-specific programs expect a <features.h> header file
+ * that defines various features macros
+ */
+
+/* we do include a number of BSD extensions */
+#define  _BSD_SOURCE  1
+
+/* we do include a number of GNU extensions */
+#define  _GNU_SOURCE  1
+
+/* C95 support */
+#undef __USE_ISOC95
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199409L
+# define __USE_ISOC95   1
+#endif
+
+/* C99 support */
+#undef __USE_ISOC99
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+# define __USE_ISOC99   1
+#endif
+
+/* Posix support */
+#define  __USE_POSIX   1
+#define  __USE_POSIX2  1
+#define  __USE_XPG     1
+
+#endif /* _FEATURES_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/fnmatch.h b/ndk/build/platforms/android-1.5/common/include/fnmatch.h
new file mode 100644
index 0000000..772b4ef
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/fnmatch.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _FNMATCH_H
+#define _FNMATCH_H
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+#define FNM_NOMATCH      1     /* Match failed. */
+#define FNM_NOSYS        2     /* Function not supported (unused). */
+
+#define FNM_NOESCAPE     0x01        /* Disable backslash escaping. */
+#define FNM_PATHNAME     0x02        /* Slash must be matched by slash. */
+#define FNM_PERIOD       0x04        /* Period must be matched by period. */
+#define FNM_LEADING_DIR  0x08        /* Ignore /<tail> after Imatch. */
+#define FNM_CASEFOLD     0x10        /* Case insensitive search. */
+
+#define FNM_IGNORECASE   FNM_CASEFOLD
+#define FNM_FILE_NAME    FNM_PATHNAME
+
+extern int  fnmatch(const char *pattern, const char *string, int flags);
+
+__END_DECLS
+
+#endif /* _FNMATCH_H */
+
diff --git a/ndk/build/platforms/android-1.5/common/include/getopt.h b/ndk/build/platforms/android-1.5/common/include/getopt.h
new file mode 100644
index 0000000..6b4954b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/getopt.h
@@ -0,0 +1,85 @@
+/*	$OpenBSD: getopt.h,v 1.1 2002/12/03 20:24:29 millert Exp $	*/
+/*	$NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $	*/
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dieter Baron and Thomas Klausner.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 THE FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+#ifndef _GETOPT_H_
+#define _GETOPT_H_
+
+#include <sys/cdefs.h>
+
+/*
+ * GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions
+ */
+#define no_argument        0
+#define required_argument  1
+#define optional_argument  2
+
+struct option {
+	/* name of long option */
+	const char *name;
+	/*
+	 * one of no_argument, required_argument, and optional_argument:
+	 * whether option takes an argument
+	 */
+	int has_arg;
+	/* if not NULL, set *flag to val when option found */
+	int *flag;
+	/* if flag not NULL, value to set *flag to; else return value */
+	int val;
+};
+
+__BEGIN_DECLS
+int	 getopt_long(int, char * const *, const char *,
+	    const struct option *, int *);
+int	 getopt_long_only(int, char * const *, const char *,
+	    const struct option *, int *);
+#ifndef _GETOPT_DEFINED_
+#define _GETOPT_DEFINED_
+int	 getopt(int, char * const *, const char *);
+int	 getsubopt(char **, char * const *, char **);
+
+extern   char *optarg;                  /* getopt(3) external variables */
+extern   int opterr;
+extern   int optind;
+extern   int optopt;
+extern   int optreset;
+extern   char *suboptarg;               /* getsubopt(3) external variable */
+#endif
+__END_DECLS
+ 
+#endif /* !_GETOPT_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/grp.h b/ndk/build/platforms/android-1.5/common/include/grp.h
new file mode 100644
index 0000000..86d99f3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/grp.h
@@ -0,0 +1,82 @@
+/*	$OpenBSD: grp.h,v 1.8 2005/12/13 00:35:22 millert Exp $	*/
+/*	$NetBSD: grp.h,v 1.7 1995/04/29 05:30:40 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)grp.h	8.2 (Berkeley) 1/21/94
+ */
+
+#ifndef _GRP_H_
+#define	_GRP_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#if __BSD_VISIBLE
+#define	_PATH_GROUP		"/etc/group"
+#endif
+
+struct group {
+	char	*gr_name;		/* group name */
+	char	*gr_passwd;		/* group password */
+	gid_t	gr_gid;			/* group id */
+	char	**gr_mem;		/* group members */
+};
+
+__BEGIN_DECLS
+struct group	*getgrgid(gid_t);
+struct group	*getgrnam(const char *);
+#if __BSD_VISIBLE || __POSIX_VISIBLE >= 200112 || __XPG_VISIBLE
+struct group	*getgrent(void);
+void		 setgrent(void);
+void		 endgrent(void);
+int		 getgrgid_r(gid_t, struct group *, char *,
+		    size_t, struct group **);
+int		 getgrnam_r(const char *, struct group *, char *,
+		    size_t, struct group **);
+#endif
+#if __BSD_VISIBLE
+void		 setgrfile(const char *);
+int		 setgroupent(int);
+char		*group_from_gid(gid_t, int);
+#endif
+
+int   getgrouplist (const char *user, gid_t group,
+                  gid_t *groups, int *ngroups);
+
+int   initgroups (const char *user, gid_t group);
+
+__END_DECLS
+
+#endif /* !_GRP_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/inttypes.h b/ndk/build/platforms/android-1.5/common/include/inttypes.h
new file mode 100644
index 0000000..ca303cb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/inttypes.h
@@ -0,0 +1,258 @@
+/*	$OpenBSD: inttypes.h,v 1.9 2006/01/15 00:47:51 millert Exp $	*/
+
+/*
+ * Copyright (c) 1997, 2005 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef	_INTTYPES_H_
+#define	_INTTYPES_H_
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
+/*
+ * 7.8.1 Macros for format specifiers
+ *
+ * Each of the following object-like macros expands to a string
+ * literal containing a conversion specifier, possibly modified by
+ * a prefix such as hh, h, l, or ll, suitable for use within the
+ * format argument of a formatted input/output function when
+ * converting the corresponding integer type.  These macro names
+ * have the general form of PRI (character string literals for the
+ * fprintf family) or SCN (character string literals for the fscanf
+ * family), followed by the conversion specifier, followed by a
+ * name corresponding to a similar typedef name.  For example,
+ * PRIdFAST32 can be used in a format string to print the value of
+ * an integer of type int_fast32_t.
+ */
+
+/* fprintf macros for signed integers */
+#define	PRId8			"d"		/* int8_t */
+#define	PRId16			"d"		/* int16_t */
+#define	PRId32			"d"		/* int32_t */
+#define	PRId64			"lld"		/* int64_t */
+
+#define	PRIdLEAST8		"d"		/* int_least8_t */
+#define	PRIdLEAST16		"d"		/* int_least16_t */
+#define	PRIdLEAST32		"d"		/* int_least32_t */
+#define	PRIdLEAST64		"lld"		/* int_least64_t */
+
+#define	PRIdFAST8		"d"		/* int_fast8_t */
+#define	PRIdFAST16		"d"		/* int_fast16_t */
+#define	PRIdFAST32		"d"		/* int_fast32_t */
+#define	PRIdFAST64		"lld"		/* int_fast64_t */
+
+#define	PRIdMAX			"jd"		/* intmax_t */
+#define	PRIdPTR			"ld"		/* intptr_t */
+
+#define	PRIi8			"i"		/* int8_t */
+#define	PRIi16			"i"		/* int16_t */
+#define	PRIi32			"i"		/* int32_t */
+#define	PRIi64			"lli"		/* int64_t */
+
+#define	PRIiLEAST8		"i"		/* int_least8_t */
+#define	PRIiLEAST16		"i"		/* int_least16_t */
+#define	PRIiLEAST32		"i"		/* int_least32_t */
+#define	PRIiLEAST64		"lli"		/* int_least64_t */
+
+#define	PRIiFAST8		"i"		/* int_fast8_t */
+#define	PRIiFAST16		"i"		/* int_fast16_t */
+#define	PRIiFAST32		"i"		/* int_fast32_t */
+#define	PRIiFAST64		"lli"		/* int_fast64_t */
+
+#define	PRIiMAX			"ji"		/* intmax_t */
+#define	PRIiPTR			"li"		/* intptr_t */
+
+/* fprintf macros for unsigned integers */
+#define	PRIo8			"o"		/* int8_t */
+#define	PRIo16			"o"		/* int16_t */
+#define	PRIo32			"o"		/* int32_t */
+#define	PRIo64			"llo"		/* int64_t */
+
+#define	PRIoLEAST8		"o"		/* int_least8_t */
+#define	PRIoLEAST16		"o"		/* int_least16_t */
+#define	PRIoLEAST32		"o"		/* int_least32_t */
+#define	PRIoLEAST64		"llo"		/* int_least64_t */
+
+#define	PRIoFAST8		"o"		/* int_fast8_t */
+#define	PRIoFAST16		"o"		/* int_fast16_t */
+#define	PRIoFAST32		"o"		/* int_fast32_t */
+#define	PRIoFAST64		"llo"		/* int_fast64_t */
+
+#define	PRIoMAX			"jo"		/* intmax_t */
+#define	PRIoPTR			"lo"		/* intptr_t */
+
+#define	PRIu8			"u"		/* uint8_t */
+#define	PRIu16			"u"		/* uint16_t */
+#define	PRIu32			"u"		/* uint32_t */
+#define	PRIu64			"llu"		/* uint64_t */
+
+#define	PRIuLEAST8		"u"		/* uint_least8_t */
+#define	PRIuLEAST16		"u"		/* uint_least16_t */
+#define	PRIuLEAST32		"u"		/* uint_least32_t */
+#define	PRIuLEAST64		"llu"		/* uint_least64_t */
+
+#define	PRIuFAST8		"u"		/* uint_fast8_t */
+#define	PRIuFAST16		"u"		/* uint_fast16_t */
+#define	PRIuFAST32		"u"		/* uint_fast32_t */
+#define	PRIuFAST64		"llu"		/* uint_fast64_t */
+
+#define	PRIuMAX			"ju"		/* uintmax_t */
+#define	PRIuPTR			"lu"		/* uintptr_t */
+
+#define	PRIx8			"x"		/* uint8_t */
+#define	PRIx16			"x"		/* uint16_t */
+#define	PRIx32			"x"		/* uint32_t */
+#define	PRIx64			"llx"		/* uint64_t */
+
+#define	PRIxLEAST8		"x"		/* uint_least8_t */
+#define	PRIxLEAST16		"x"		/* uint_least16_t */
+#define	PRIxLEAST32		"x"		/* uint_least32_t */
+#define	PRIxLEAST64		"llx"		/* uint_least64_t */
+
+#define	PRIxFAST8		"x"		/* uint_fast8_t */
+#define	PRIxFAST16		"x"		/* uint_fast16_t */
+#define	PRIxFAST32		"x"		/* uint_fast32_t */
+#define	PRIxFAST64		"llx"		/* uint_fast64_t */
+
+#define	PRIxMAX			"jx"		/* uintmax_t */
+#define	PRIxPTR			"lx"		/* uintptr_t */
+
+#define	PRIX8			"X"		/* uint8_t */
+#define	PRIX16			"X"		/* uint16_t */
+#define	PRIX32			"X"		/* uint32_t */
+#define	PRIX64			"llX"		/* uint64_t */
+
+#define	PRIXLEAST8		"X"		/* uint_least8_t */
+#define	PRIXLEAST16		"X"		/* uint_least16_t */
+#define	PRIXLEAST32		"X"		/* uint_least32_t */
+#define	PRIXLEAST64		"llX"		/* uint_least64_t */
+
+#define	PRIXFAST8		"X"		/* uint_fast8_t */
+#define	PRIXFAST16		"X"		/* uint_fast16_t */
+#define	PRIXFAST32		"X"		/* uint_fast32_t */
+#define	PRIXFAST64		"llX"		/* uint_fast64_t */
+
+#define	PRIXMAX			"jX"		/* uintmax_t */
+#define	PRIXPTR			"lX"		/* uintptr_t */
+
+/* fscanf macros for signed integers */
+#define	SCNd8			"hhd"		/* int8_t */
+#define	SCNd16			"hd"		/* int16_t */
+#define	SCNd32			"d"		/* int32_t */
+#define	SCNd64			"lld"		/* int64_t */
+
+#define	SCNdLEAST8		"hhd"		/* int_least8_t */
+#define	SCNdLEAST16		"hd"		/* int_least16_t */
+#define	SCNdLEAST32		"d"		/* int_least32_t */
+#define	SCNdLEAST64		"lld"		/* int_least64_t */
+
+#define	SCNdFAST8		"hhd"		/* int_fast8_t */
+#define	SCNdFAST16		"hd"		/* int_fast16_t */
+#define	SCNdFAST32		"d"		/* int_fast32_t */
+#define	SCNdFAST64		"lld"		/* int_fast64_t */
+
+#define	SCNdMAX			"jd"		/* intmax_t */
+#define	SCNdPTR			"ld"		/* intptr_t */
+
+#define	SCNi8			"hhi"		/* int8_t */
+#define	SCNi16			"hi"		/* int16_t */
+#define	SCNi32			"i"		/* int32_t */
+#define	SCNi64			"lli"		/* int64_t */
+
+#define	SCNiLEAST8		"hhi"		/* int_least8_t */
+#define	SCNiLEAST16		"hi"		/* int_least16_t */
+#define	SCNiLEAST32		"i"		/* int_least32_t */
+#define	SCNiLEAST64		"lli"		/* int_least64_t */
+
+#define	SCNiFAST8		"hhi"		/* int_fast8_t */
+#define	SCNiFAST16		"hi"		/* int_fast16_t */
+#define	SCNiFAST32		"i"		/* int_fast32_t */
+#define	SCNiFAST64		"lli"		/* int_fast64_t */
+
+#define	SCNiMAX			"ji"		/* intmax_t */
+#define	SCNiPTR			"li"		/* intptr_t */
+
+/* fscanf macros for unsigned integers */
+#define	SCNo8			"hho"		/* uint8_t */
+#define	SCNo16			"ho"		/* uint16_t */
+#define	SCNo32			"o"		/* uint32_t */
+#define	SCNo64			"llo"		/* uint64_t */
+
+#define	SCNoLEAST8		"hho"		/* uint_least8_t */
+#define	SCNoLEAST16		"ho"		/* uint_least16_t */
+#define	SCNoLEAST32		"o"		/* uint_least32_t */
+#define	SCNoLEAST64		"llo"		/* uint_least64_t */
+
+#define	SCNoFAST8		"hho"		/* uint_fast8_t */
+#define	SCNoFAST16		"ho"		/* uint_fast16_t */
+#define	SCNoFAST32		"o"		/* uint_fast32_t */
+#define	SCNoFAST64		"llo"		/* uint_fast64_t */
+
+#define	SCNoMAX			"jo"		/* uintmax_t */
+#define	SCNoPTR			"lo"		/* uintptr_t */
+
+#define	SCNu8			"hhu"		/* uint8_t */
+#define	SCNu16			"hu"		/* uint16_t */
+#define	SCNu32			"u"		/* uint32_t */
+#define	SCNu64			"llu"		/* uint64_t */
+
+#define	SCNuLEAST8		"hhu"		/* uint_least8_t */
+#define	SCNuLEAST16		"hu"		/* uint_least16_t */
+#define	SCNuLEAST32		"u"		/* uint_least32_t */
+#define	SCNuLEAST64		"llu"		/* uint_least64_t */
+
+#define	SCNuFAST8		"hhu"		/* uint_fast8_t */
+#define	SCNuFAST16		"hu"		/* uint_fast16_t */
+#define	SCNuFAST32		"u"		/* uint_fast32_t */
+#define	SCNuFAST64		"llu"		/* uint_fast64_t */
+
+#define	SCNuMAX			"ju"		/* uintmax_t */
+#define	SCNuPTR			"lu"		/* uintptr_t */
+
+#define	SCNx8			"hhx"		/* uint8_t */
+#define	SCNx16			"hx"		/* uint16_t */
+#define	SCNx32			"x"		/* uint32_t */
+#define	SCNx64			"llx"		/* uint64_t */
+
+#define	SCNxLEAST8		"hhx"		/* uint_least8_t */
+#define	SCNxLEAST16		"hx"		/* uint_least16_t */
+#define	SCNxLEAST32		"x"		/* uint_least32_t */
+#define	SCNxLEAST64		"llx"		/* uint_least64_t */
+
+#define	SCNxFAST8		"hhx"		/* uint_fast8_t */
+#define	SCNxFAST16		"hx"		/* uint_fast16_t */
+#define	SCNxFAST32		"x"		/* uint_fast32_t */
+#define	SCNxFAST64		"llx"		/* uint_fast64_t */
+
+#define	SCNxMAX			"jx"		/* uintmax_t */
+#define	SCNxPTR			"lx"		/* uintptr_t */
+
+#endif /* __cplusplus || __STDC_FORMAT_MACROS */
+
+typedef struct {
+	intmax_t quot;		/* quotient */
+	intmax_t rem;		/* remainder */
+} imaxdiv_t;
+
+__BEGIN_DECLS
+intmax_t	imaxabs(intmax_t);
+imaxdiv_t	imaxdiv(intmax_t, intmax_t);
+intmax_t	strtoimax(const char *, char **, int);
+uintmax_t	strtoumax(const char *, char **, int);
+__END_DECLS
+
+#endif /* _INTTYPES_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/jni.h b/ndk/build/platforms/android-1.5/common/include/jni.h
new file mode 100644
index 0000000..ad954c8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/jni.h
@@ -0,0 +1,1140 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * JNI specification, as defined by Sun:
+ * http://java.sun.com/javase/6/docs/technotes/guides/jni/spec/jniTOC.html
+ *
+ * Everything here is expected to be VM-neutral.
+ */
+#ifndef _JNI_H
+#define _JNI_H
+
+#include <stdarg.h>
+
+/*
+ * Primitive types that match up with Java equivalents.
+ */
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>      /* C99 */
+typedef uint8_t         jboolean;       /* unsigned 8 bits */
+typedef int8_t          jbyte;          /* signed 8 bits */
+typedef uint16_t        jchar;          /* unsigned 16 bits */
+typedef int16_t         jshort;         /* signed 16 bits */
+typedef int32_t         jint;           /* signed 32 bits */
+typedef int64_t         jlong;          /* signed 64 bits */
+typedef float           jfloat;         /* 32-bit IEEE 754 */
+typedef double          jdouble;        /* 64-bit IEEE 754 */
+#else
+typedef unsigned char   jboolean;       /* unsigned 8 bits */
+typedef signed char     jbyte;          /* signed 8 bits */
+typedef unsigned short  jchar;          /* unsigned 16 bits */
+typedef short           jshort;         /* signed 16 bits */
+typedef int             jint;           /* signed 32 bits */
+typedef long long       jlong;          /* signed 64 bits */
+typedef float           jfloat;         /* 32-bit IEEE 754 */
+typedef double          jdouble;        /* 64-bit IEEE 754 */
+#endif
+
+/* "cardinal indices and sizes" */
+typedef jint            jsize;
+
+#ifdef __cplusplus
+/*
+ * Reference types, in C++
+ */
+class _jobject {};
+class _jclass : public _jobject {};
+class _jstring : public _jobject {};
+class _jarray : public _jobject {};
+class _jobjectArray : public _jarray {};
+class _jbooleanArray : public _jarray {};
+class _jbyteArray : public _jarray {};
+class _jcharArray : public _jarray {};
+class _jshortArray : public _jarray {};
+class _jintArray : public _jarray {};
+class _jlongArray : public _jarray {};
+class _jfloatArray : public _jarray {};
+class _jdoubleArray : public _jarray {};
+class _jthrowable : public _jobject {};
+
+typedef _jobject*       jobject;
+typedef _jclass*        jclass;
+typedef _jstring*       jstring;
+typedef _jarray*        jarray;
+typedef _jobjectArray*  jobjectArray;
+typedef _jbooleanArray* jbooleanArray;
+typedef _jbyteArray*    jbyteArray;
+typedef _jcharArray*    jcharArray;
+typedef _jshortArray*   jshortArray;
+typedef _jintArray*     jintArray;
+typedef _jlongArray*    jlongArray;
+typedef _jfloatArray*   jfloatArray;
+typedef _jdoubleArray*  jdoubleArray;
+typedef _jthrowable*    jthrowable;
+typedef _jobject*       jweak;
+
+
+#else /* not __cplusplus */
+
+/*
+ * Reference types, in C.
+ */
+typedef void*           jobject;
+typedef jobject         jclass;
+typedef jobject         jstring;
+typedef jobject         jarray;
+typedef jarray          jobjectArray;
+typedef jarray          jbooleanArray;
+typedef jarray          jbyteArray;
+typedef jarray          jcharArray;
+typedef jarray          jshortArray;
+typedef jarray          jintArray;
+typedef jarray          jlongArray;
+typedef jarray          jfloatArray;
+typedef jarray          jdoubleArray;
+typedef jobject         jthrowable;
+typedef jobject         jweak;
+
+#endif /* not __cplusplus */
+
+struct _jfieldID;                       /* opaque structure */
+typedef struct _jfieldID* jfieldID;     /* field IDs */
+
+struct _jmethodID;                      /* opaque structure */
+typedef struct _jmethodID* jmethodID;   /* method IDs */
+
+struct JNIInvokeInterface;
+
+typedef union jvalue {
+    jboolean    z;
+    jbyte       b;
+    jchar       c;
+    jshort      s;
+    jint        i;
+    jlong       j;
+    jfloat      f;
+    jdouble     d;
+    jobject     l;
+} jvalue;
+
+typedef enum jobjectRefType {
+    JNIInvalidRefType = 0,
+    JNILocalRefType = 1,
+    JNIGlobalRefType = 2,
+    JNIWeakGlobalRefType = 3
+} jobjectRefType;
+
+typedef struct { 
+    const char* name; 
+    const char* signature; 
+    void*       fnPtr; 
+} JNINativeMethod;
+
+struct _JNIEnv;
+struct _JavaVM;
+typedef const struct JNINativeInterface* C_JNIEnv;
+
+#if defined(__cplusplus)
+typedef _JNIEnv JNIEnv;
+typedef _JavaVM JavaVM;
+#else
+typedef const struct JNINativeInterface* JNIEnv;
+typedef const struct JNIInvokeInterface* JavaVM;
+#endif
+
+/*
+ * Table of interface function pointers.
+ */
+struct JNINativeInterface {
+    void*       reserved0;
+    void*       reserved1;
+    void*       reserved2;
+    void*       reserved3;
+
+    jint        (*GetVersion)(JNIEnv *);
+
+    jclass      (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*,
+                        jsize);
+    jclass      (*FindClass)(JNIEnv*, const char*);
+
+    jmethodID   (*FromReflectedMethod)(JNIEnv*, jobject);
+    jfieldID    (*FromReflectedField)(JNIEnv*, jobject);
+    /* spec doesn't show jboolean parameter */
+    jobject     (*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean);
+
+    jclass      (*GetSuperclass)(JNIEnv*, jclass);
+    jboolean    (*IsAssignableFrom)(JNIEnv*, jclass, jclass);
+
+    /* spec doesn't show jboolean parameter */
+    jobject     (*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean);
+
+    jint        (*Throw)(JNIEnv*, jthrowable);
+    jint        (*ThrowNew)(JNIEnv *, jclass, const char *);
+    jthrowable  (*ExceptionOccurred)(JNIEnv*);
+    void        (*ExceptionDescribe)(JNIEnv*);
+    void        (*ExceptionClear)(JNIEnv*);
+    void        (*FatalError)(JNIEnv*, const char*);
+
+    jint        (*PushLocalFrame)(JNIEnv*, jint);
+    jobject     (*PopLocalFrame)(JNIEnv*, jobject);
+
+    jobject     (*NewGlobalRef)(JNIEnv*, jobject);
+    void        (*DeleteGlobalRef)(JNIEnv*, jobject);
+    void        (*DeleteLocalRef)(JNIEnv*, jobject);
+    jboolean    (*IsSameObject)(JNIEnv*, jobject, jobject);
+
+    jobject     (*NewLocalRef)(JNIEnv*, jobject);
+    jint        (*EnsureLocalCapacity)(JNIEnv*, jint);
+
+    jobject     (*AllocObject)(JNIEnv*, jclass);
+    jobject     (*NewObject)(JNIEnv*, jclass, jmethodID, ...);
+    jobject     (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list);
+    jobject     (*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*);
+
+    jclass      (*GetObjectClass)(JNIEnv*, jobject);
+    jboolean    (*IsInstanceOf)(JNIEnv*, jobject, jclass);
+    jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
+
+    jobject     (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);
+    jobject     (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);
+    jobject     (*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
+    jboolean    (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);
+    jboolean    (*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);
+    jboolean    (*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
+    jbyte       (*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...);
+    jbyte       (*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);
+    jbyte       (*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
+    jchar       (*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...);
+    jchar       (*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);
+    jchar       (*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
+    jshort      (*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...);
+    jshort      (*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);
+    jshort      (*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
+    jint        (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
+    jint        (*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);
+    jint        (*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
+    jlong       (*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...);
+    jlong       (*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);
+    jlong       (*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
+    jfloat      (*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...);
+    jfloat      (*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list);
+    jfloat      (*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
+    jdouble     (*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...);
+    jdouble     (*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list);
+    jdouble     (*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
+    void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
+    void        (*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);
+    void        (*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
+
+    jobject     (*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass,
+                        jmethodID, ...);
+    jobject     (*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass,
+                        jmethodID, va_list);
+    jobject     (*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass,
+                        jmethodID, jvalue*);
+    jboolean    (*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass,
+                        jmethodID, ...);
+    jboolean    (*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass,
+                         jmethodID, va_list);
+    jboolean    (*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass,
+                         jmethodID, jvalue*);
+    jbyte       (*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass,
+                        jmethodID, ...);
+    jbyte       (*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass,
+                        jmethodID, va_list);
+    jbyte       (*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass,
+                        jmethodID, jvalue*);
+    jchar       (*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass,
+                        jmethodID, ...);
+    jchar       (*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass,
+                        jmethodID, va_list);
+    jchar       (*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass,
+                        jmethodID, jvalue*);
+    jshort      (*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass,
+                        jmethodID, ...);
+    jshort      (*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass,
+                        jmethodID, va_list);
+    jshort      (*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass,
+                        jmethodID, jvalue*);
+    jint        (*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass,
+                        jmethodID, ...);
+    jint        (*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass,
+                        jmethodID, va_list);
+    jint        (*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass,
+                        jmethodID, jvalue*);
+    jlong       (*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass,
+                        jmethodID, ...);
+    jlong       (*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass,
+                        jmethodID, va_list);
+    jlong       (*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass,
+                        jmethodID, jvalue*);
+    jfloat      (*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass,
+                        jmethodID, ...);
+    jfloat      (*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass,
+                        jmethodID, va_list);
+    jfloat      (*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass,
+                        jmethodID, jvalue*);
+    jdouble     (*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass,
+                        jmethodID, ...);
+    jdouble     (*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass,
+                        jmethodID, va_list);
+    jdouble     (*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass,
+                        jmethodID, jvalue*);
+    void        (*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass,
+                        jmethodID, ...);
+    void        (*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass,
+                        jmethodID, va_list);
+    void        (*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass,
+                        jmethodID, jvalue*);
+
+    jfieldID    (*GetFieldID)(JNIEnv*, jclass, const char*, const char*);
+
+    jobject     (*GetObjectField)(JNIEnv*, jobject, jfieldID);
+    jboolean    (*GetBooleanField)(JNIEnv*, jobject, jfieldID);
+    jbyte       (*GetByteField)(JNIEnv*, jobject, jfieldID);
+    jchar       (*GetCharField)(JNIEnv*, jobject, jfieldID);
+    jshort      (*GetShortField)(JNIEnv*, jobject, jfieldID);
+    jint        (*GetIntField)(JNIEnv*, jobject, jfieldID);
+    jlong       (*GetLongField)(JNIEnv*, jobject, jfieldID);
+    jfloat      (*GetFloatField)(JNIEnv*, jobject, jfieldID);
+    jdouble     (*GetDoubleField)(JNIEnv*, jobject, jfieldID);
+
+    void        (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject);
+    void        (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean);
+    void        (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte);
+    void        (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar);
+    void        (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort);
+    void        (*SetIntField)(JNIEnv*, jobject, jfieldID, jint);
+    void        (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong);
+    void        (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat);
+    void        (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble);
+
+    jmethodID   (*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);
+
+    jobject     (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...);
+    jobject     (*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list);
+    jobject     (*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
+    jboolean    (*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...);
+    jboolean    (*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID,
+                        va_list);
+    jboolean    (*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID,
+                        jvalue*);
+    jbyte       (*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...);
+    jbyte       (*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list);
+    jbyte       (*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
+    jchar       (*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...);
+    jchar       (*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list);
+    jchar       (*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
+    jshort      (*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...);
+    jshort      (*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list);
+    jshort      (*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
+    jint        (*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...);
+    jint        (*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list);
+    jint        (*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
+    jlong       (*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...);
+    jlong       (*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list);
+    jlong       (*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
+    jfloat      (*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...);
+    jfloat      (*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list);
+    jfloat      (*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
+    jdouble     (*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...);
+    jdouble     (*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list);
+    jdouble     (*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
+    void        (*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);
+    void        (*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list);
+    void        (*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
+
+    jfieldID    (*GetStaticFieldID)(JNIEnv*, jclass, const char*,
+                        const char*);
+
+    jobject     (*GetStaticObjectField)(JNIEnv*, jclass, jfieldID);
+    jboolean    (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID);
+    jbyte       (*GetStaticByteField)(JNIEnv*, jclass, jfieldID);
+    jchar       (*GetStaticCharField)(JNIEnv*, jclass, jfieldID);
+    jshort      (*GetStaticShortField)(JNIEnv*, jclass, jfieldID);
+    jint        (*GetStaticIntField)(JNIEnv*, jclass, jfieldID);
+    jlong       (*GetStaticLongField)(JNIEnv*, jclass, jfieldID);
+    jfloat      (*GetStaticFloatField)(JNIEnv*, jclass, jfieldID);
+    jdouble     (*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID);
+
+    void        (*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject);
+    void        (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean);
+    void        (*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte);
+    void        (*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar);
+    void        (*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort);
+    void        (*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint);
+    void        (*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong);
+    void        (*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat);
+    void        (*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble);
+
+    jstring     (*NewString)(JNIEnv*, const jchar*, jsize);
+    jsize       (*GetStringLength)(JNIEnv*, jstring);
+    const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*);
+    void        (*ReleaseStringChars)(JNIEnv*, jstring, const jchar*);
+    jstring     (*NewStringUTF)(JNIEnv*, const char*);
+    jsize       (*GetStringUTFLength)(JNIEnv*, jstring);
+    /* JNI spec says this returns const jbyte*, but that's inconsistent */
+    const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);
+    void        (*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*);
+    jsize       (*GetArrayLength)(JNIEnv*, jarray);
+    jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject);
+    jobject     (*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize);
+    void        (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject);
+
+    jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize);
+    jbyteArray    (*NewByteArray)(JNIEnv*, jsize);
+    jcharArray    (*NewCharArray)(JNIEnv*, jsize);
+    jshortArray   (*NewShortArray)(JNIEnv*, jsize);
+    jintArray     (*NewIntArray)(JNIEnv*, jsize);
+    jlongArray    (*NewLongArray)(JNIEnv*, jsize);
+    jfloatArray   (*NewFloatArray)(JNIEnv*, jsize);
+    jdoubleArray  (*NewDoubleArray)(JNIEnv*, jsize);
+
+    jboolean*   (*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*);
+    jbyte*      (*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*);
+    jchar*      (*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*);
+    jshort*     (*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*);
+    jint*       (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);
+    jlong*      (*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*);
+    jfloat*     (*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*);
+    jdouble*    (*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*);
+
+    void        (*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray,
+                        jboolean*, jint);
+    void        (*ReleaseByteArrayElements)(JNIEnv*, jbyteArray,
+                        jbyte*, jint);
+    void        (*ReleaseCharArrayElements)(JNIEnv*, jcharArray,
+                        jchar*, jint);
+    void        (*ReleaseShortArrayElements)(JNIEnv*, jshortArray,
+                        jshort*, jint);
+    void        (*ReleaseIntArrayElements)(JNIEnv*, jintArray,
+                        jint*, jint);
+    void        (*ReleaseLongArrayElements)(JNIEnv*, jlongArray,
+                        jlong*, jint);
+    void        (*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray,
+                        jfloat*, jint);
+    void        (*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray,
+                        jdouble*, jint);
+
+    void        (*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray,
+                        jsize, jsize, jboolean*);
+    void        (*GetByteArrayRegion)(JNIEnv*, jbyteArray,
+                        jsize, jsize, jbyte*);
+    void        (*GetCharArrayRegion)(JNIEnv*, jcharArray,
+                        jsize, jsize, jchar*);
+    void        (*GetShortArrayRegion)(JNIEnv*, jshortArray,
+                        jsize, jsize, jshort*);
+    void        (*GetIntArrayRegion)(JNIEnv*, jintArray,
+                        jsize, jsize, jint*);
+    void        (*GetLongArrayRegion)(JNIEnv*, jlongArray,
+                        jsize, jsize, jlong*);
+    void        (*GetFloatArrayRegion)(JNIEnv*, jfloatArray,
+                        jsize, jsize, jfloat*);
+    void        (*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray,
+                        jsize, jsize, jdouble*);
+
+    /* spec shows these without const; some jni.h do, some don't */
+    void        (*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray,
+                        jsize, jsize, const jboolean*);
+    void        (*SetByteArrayRegion)(JNIEnv*, jbyteArray,
+                        jsize, jsize, const jbyte*);
+    void        (*SetCharArrayRegion)(JNIEnv*, jcharArray,
+                        jsize, jsize, const jchar*);
+    void        (*SetShortArrayRegion)(JNIEnv*, jshortArray,
+                        jsize, jsize, const jshort*);
+    void        (*SetIntArrayRegion)(JNIEnv*, jintArray,
+                        jsize, jsize, const jint*);
+    void        (*SetLongArrayRegion)(JNIEnv*, jlongArray,
+                        jsize, jsize, const jlong*);
+    void        (*SetFloatArrayRegion)(JNIEnv*, jfloatArray,
+                        jsize, jsize, const jfloat*);
+    void        (*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray,
+                        jsize, jsize, const jdouble*);
+
+    jint        (*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*,
+                        jint);
+    jint        (*UnregisterNatives)(JNIEnv*, jclass);
+    jint        (*MonitorEnter)(JNIEnv*, jobject);
+    jint        (*MonitorExit)(JNIEnv*, jobject);
+    jint        (*GetJavaVM)(JNIEnv*, JavaVM**);
+
+    void        (*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*);
+    void        (*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*);
+
+    void*       (*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*);
+    void        (*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint);
+
+    const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*);
+    void        (*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*);
+
+    jweak       (*NewWeakGlobalRef)(JNIEnv*, jobject);
+    void        (*DeleteWeakGlobalRef)(JNIEnv*, jweak);
+
+    jboolean    (*ExceptionCheck)(JNIEnv*);
+
+    jobject     (*NewDirectByteBuffer)(JNIEnv*, void*, jlong);
+    void*       (*GetDirectBufferAddress)(JNIEnv*, jobject);
+    jlong       (*GetDirectBufferCapacity)(JNIEnv*, jobject);
+
+    /* added in JNI 1.6 */
+    jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject);
+};
+
+/*
+ * C++ object wrapper.
+ *
+ * This is usually overlaid on a C struct whose first element is a
+ * JNINativeInterface*.  We rely somewhat on compiler behavior.
+ */
+struct _JNIEnv {
+    /* do not rename this; it does not seem to be entirely opaque */
+    const struct JNINativeInterface* functions;
+
+#if defined(__cplusplus)
+
+    jint GetVersion()
+    { return functions->GetVersion(this); }
+
+    jclass DefineClass(const char *name, jobject loader, const jbyte* buf,
+        jsize bufLen)
+    { return functions->DefineClass(this, name, loader, buf, bufLen); }
+
+    jclass FindClass(const char* name)
+    { return functions->FindClass(this, name); }
+
+    jmethodID FromReflectedMethod(jobject method)
+    { return functions->FromReflectedMethod(this, method); }
+
+    jfieldID FromReflectedField(jobject field)
+    { return functions->FromReflectedField(this, field); }
+
+    jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic)
+    { return functions->ToReflectedMethod(this, cls, methodID, isStatic); }
+
+    jclass GetSuperclass(jclass clazz)
+    { return functions->GetSuperclass(this, clazz); }
+
+    jboolean IsAssignableFrom(jclass clazz1, jclass clazz2)
+    { return functions->IsAssignableFrom(this, clazz1, clazz2); }
+
+    jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic)
+    { return functions->ToReflectedField(this, cls, fieldID, isStatic); }
+
+    jint Throw(jthrowable obj)
+    { return functions->Throw(this, obj); }
+
+    jint ThrowNew(jclass clazz, const char* message)
+    { return functions->ThrowNew(this, clazz, message); }
+
+    jthrowable ExceptionOccurred()
+    { return functions->ExceptionOccurred(this); }
+
+    void ExceptionDescribe()
+    { functions->ExceptionDescribe(this); }
+
+    void ExceptionClear()
+    { functions->ExceptionClear(this); }
+
+    void FatalError(const char* msg)
+    { functions->FatalError(this, msg); }
+
+    jint PushLocalFrame(jint capacity)
+    { return functions->PushLocalFrame(this, capacity); }
+
+    jobject PopLocalFrame(jobject result)
+    { return functions->PopLocalFrame(this, result); }
+
+    jobject NewGlobalRef(jobject obj)
+    { return functions->NewGlobalRef(this, obj); }
+
+    void DeleteGlobalRef(jobject globalRef)
+    { functions->DeleteGlobalRef(this, globalRef); }
+
+    void DeleteLocalRef(jobject localRef)
+    { functions->DeleteLocalRef(this, localRef); }
+
+    jboolean IsSameObject(jobject ref1, jobject ref2)
+    { return functions->IsSameObject(this, ref1, ref2); }
+
+    jobject NewLocalRef(jobject ref)
+    { return functions->NewLocalRef(this, ref); }
+
+    jint EnsureLocalCapacity(jint capacity)
+    { return functions->EnsureLocalCapacity(this, capacity); }
+
+    jobject AllocObject(jclass clazz)
+    { return functions->AllocObject(this, clazz); }
+
+    jobject NewObject(jclass clazz, jmethodID methodID, ...)
+    {
+        va_list args;
+        va_start(args, methodID);
+        jobject result = functions->NewObjectV(this, clazz, methodID, args);
+        va_end(args);
+        return result;
+    }
+
+    jobject NewObjectV(jclass clazz, jmethodID methodID, va_list args)
+    { return functions->NewObjectV(this, clazz, methodID, args); }
+
+    jobject NewObjectA(jclass clazz, jmethodID methodID, jvalue* args)
+    { return functions->NewObjectA(this, clazz, methodID, args); }
+
+    jclass GetObjectClass(jobject obj)
+    { return functions->GetObjectClass(this, obj); }
+
+    jboolean IsInstanceOf(jobject obj, jclass clazz)
+    { return functions->IsInstanceOf(this, obj, clazz); }
+
+    jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)
+    { return functions->GetMethodID(this, clazz, name, sig); }
+
+#define CALL_TYPE_METHOD(_jtype, _jname)                                    \
+    _jtype Call##_jname##Method(jobject obj, jmethodID methodID, ...)       \
+    {                                                                       \
+        _jtype result;                                                      \
+        va_list args;                                                       \
+        va_start(args, methodID);                                           \
+        result = functions->Call##_jname##MethodV(this, obj, methodID,      \
+                    args);                                                  \
+        va_end(args);                                                       \
+        return result;                                                      \
+    }
+#define CALL_TYPE_METHODV(_jtype, _jname)                                   \
+    _jtype Call##_jname##MethodV(jobject obj, jmethodID methodID,           \
+        va_list args)                                                       \
+    { return functions->Call##_jname##MethodV(this, obj, methodID, args); }
+#define CALL_TYPE_METHODA(_jtype, _jname)                                   \
+    _jtype Call##_jname##MethodA(jobject obj, jmethodID methodID,           \
+        jvalue* args)                                                       \
+    { return functions->Call##_jname##MethodA(this, obj, methodID, args); }
+
+#define CALL_TYPE(_jtype, _jname)                                           \
+    CALL_TYPE_METHOD(_jtype, _jname)                                        \
+    CALL_TYPE_METHODV(_jtype, _jname)                                       \
+    CALL_TYPE_METHODA(_jtype, _jname)
+
+    CALL_TYPE(jobject, Object)
+    CALL_TYPE(jboolean, Boolean)
+    CALL_TYPE(jbyte, Byte)
+    CALL_TYPE(jchar, Char)
+    CALL_TYPE(jshort, Short)
+    CALL_TYPE(jint, Int)
+    CALL_TYPE(jlong, Long)
+    CALL_TYPE(jfloat, Float)
+    CALL_TYPE(jdouble, Double)
+
+    void CallVoidMethod(jobject obj, jmethodID methodID, ...)
+    {
+        va_list args;
+        va_start(args, methodID);
+        functions->CallVoidMethodV(this, obj, methodID, args);
+        va_end(args);
+    }
+    void CallVoidMethodV(jobject obj, jmethodID methodID, va_list args)
+    { functions->CallVoidMethodV(this, obj, methodID, args); }
+    void CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args)
+    { functions->CallVoidMethodA(this, obj, methodID, args); }
+
+#define CALL_NONVIRT_TYPE_METHOD(_jtype, _jname)                            \
+    _jtype CallNonvirtual##_jname##Method(jobject obj, jclass clazz,        \
+        jmethodID methodID, ...)                                            \
+    {                                                                       \
+        _jtype result;                                                      \
+        va_list args;                                                       \
+        va_start(args, methodID);                                           \
+        result = functions->CallNonvirtual##_jname##MethodV(this, obj,      \
+                    clazz, methodID, args);                                 \
+        va_end(args);                                                       \
+        return result;                                                      \
+    }
+#define CALL_NONVIRT_TYPE_METHODV(_jtype, _jname)                           \
+    _jtype CallNonvirtual##_jname##MethodV(jobject obj, jclass clazz,       \
+        jmethodID methodID, va_list args)                                   \
+    { return functions->CallNonvirtual##_jname##MethodV(this, obj, clazz,   \
+        methodID, args); }
+#define CALL_NONVIRT_TYPE_METHODA(_jtype, _jname)                           \
+    _jtype CallNonvirtual##_jname##MethodA(jobject obj, jclass clazz,       \
+        jmethodID methodID, jvalue* args)                                   \
+    { return functions->CallNonvirtual##_jname##MethodA(this, obj, clazz,   \
+        methodID, args); }
+
+#define CALL_NONVIRT_TYPE(_jtype, _jname)                                   \
+    CALL_NONVIRT_TYPE_METHOD(_jtype, _jname)                                \
+    CALL_NONVIRT_TYPE_METHODV(_jtype, _jname)                               \
+    CALL_NONVIRT_TYPE_METHODA(_jtype, _jname)
+
+    CALL_NONVIRT_TYPE(jobject, Object)
+    CALL_NONVIRT_TYPE(jboolean, Boolean)
+    CALL_NONVIRT_TYPE(jbyte, Byte)
+    CALL_NONVIRT_TYPE(jchar, Char)
+    CALL_NONVIRT_TYPE(jshort, Short)
+    CALL_NONVIRT_TYPE(jint, Int)
+    CALL_NONVIRT_TYPE(jlong, Long)
+    CALL_NONVIRT_TYPE(jfloat, Float)
+    CALL_NONVIRT_TYPE(jdouble, Double)
+
+    void CallNonvirtualVoidMethod(jobject obj, jclass clazz,
+        jmethodID methodID, ...)
+    {
+        va_list args;
+        va_start(args, methodID);
+        functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args);
+        va_end(args);
+    }
+    void CallNonvirtualVoidMethodV(jobject obj, jclass clazz,
+        jmethodID methodID, va_list args)
+    { functions->CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); }
+    void CallNonvirtualVoidMethodA(jobject obj, jclass clazz,
+        jmethodID methodID, jvalue* args)
+    { functions->CallNonvirtualVoidMethodA(this, obj, clazz, methodID, args); }
+
+    jfieldID GetFieldID(jclass clazz, const char* name, const char* sig)
+    { return functions->GetFieldID(this, clazz, name, sig); }
+
+    jobject GetObjectField(jobject obj, jfieldID fieldID)
+    { return functions->GetObjectField(this, obj, fieldID); }
+    jboolean GetBooleanField(jobject obj, jfieldID fieldID)
+    { return functions->GetBooleanField(this, obj, fieldID); }
+    jbyte GetByteField(jobject obj, jfieldID fieldID)
+    { return functions->GetByteField(this, obj, fieldID); }
+    jchar GetCharField(jobject obj, jfieldID fieldID)
+    { return functions->GetCharField(this, obj, fieldID); }
+    jshort GetShortField(jobject obj, jfieldID fieldID)
+    { return functions->GetShortField(this, obj, fieldID); }
+    jint GetIntField(jobject obj, jfieldID fieldID)
+    { return functions->GetIntField(this, obj, fieldID); }
+    jlong GetLongField(jobject obj, jfieldID fieldID)
+    { return functions->GetLongField(this, obj, fieldID); }
+    jfloat GetFloatField(jobject obj, jfieldID fieldID)
+    { return functions->GetFloatField(this, obj, fieldID); }
+    jdouble GetDoubleField(jobject obj, jfieldID fieldID)
+    { return functions->GetDoubleField(this, obj, fieldID); }
+
+    void SetObjectField(jobject obj, jfieldID fieldID, jobject value)
+    { functions->SetObjectField(this, obj, fieldID, value); }
+    void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value)
+    { functions->SetBooleanField(this, obj, fieldID, value); }
+    void SetByteField(jobject obj, jfieldID fieldID, jbyte value)
+    { functions->SetByteField(this, obj, fieldID, value); }
+    void SetCharField(jobject obj, jfieldID fieldID, jchar value)
+    { functions->SetCharField(this, obj, fieldID, value); }
+    void SetShortField(jobject obj, jfieldID fieldID, jshort value)
+    { functions->SetShortField(this, obj, fieldID, value); }
+    void SetIntField(jobject obj, jfieldID fieldID, jint value)
+    { functions->SetIntField(this, obj, fieldID, value); }
+    void SetLongField(jobject obj, jfieldID fieldID, jlong value)
+    { functions->SetLongField(this, obj, fieldID, value); }
+    void SetFloatField(jobject obj, jfieldID fieldID, jfloat value)
+    { functions->SetFloatField(this, obj, fieldID, value); }
+    void SetDoubleField(jobject obj, jfieldID fieldID, jdouble value)
+    { functions->SetDoubleField(this, obj, fieldID, value); }
+
+    jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig)
+    { return functions->GetStaticMethodID(this, clazz, name, sig); }
+
+#define CALL_STATIC_TYPE_METHOD(_jtype, _jname)                             \
+    _jtype CallStatic##_jname##Method(jclass clazz, jmethodID methodID,     \
+        ...)                                                                \
+    {                                                                       \
+        _jtype result;                                                      \
+        va_list args;                                                       \
+        va_start(args, methodID);                                           \
+        result = functions->CallStatic##_jname##MethodV(this, clazz,        \
+                    methodID, args);                                        \
+        va_end(args);                                                       \
+        return result;                                                      \
+    }
+#define CALL_STATIC_TYPE_METHODV(_jtype, _jname)                            \
+    _jtype CallStatic##_jname##MethodV(jclass clazz, jmethodID methodID,    \
+        va_list args)                                                       \
+    { return functions->CallStatic##_jname##MethodV(this, clazz, methodID,  \
+        args); }
+#define CALL_STATIC_TYPE_METHODA(_jtype, _jname)                            \
+    _jtype CallStatic##_jname##MethodA(jclass clazz, jmethodID methodID,    \
+        jvalue* args)                                                       \
+    { return functions->CallStatic##_jname##MethodA(this, clazz, methodID,  \
+        args); }
+
+#define CALL_STATIC_TYPE(_jtype, _jname)                                    \
+    CALL_STATIC_TYPE_METHOD(_jtype, _jname)                                 \
+    CALL_STATIC_TYPE_METHODV(_jtype, _jname)                                \
+    CALL_STATIC_TYPE_METHODA(_jtype, _jname)
+
+    CALL_STATIC_TYPE(jobject, Object)
+    CALL_STATIC_TYPE(jboolean, Boolean)
+    CALL_STATIC_TYPE(jbyte, Byte)
+    CALL_STATIC_TYPE(jchar, Char)
+    CALL_STATIC_TYPE(jshort, Short)
+    CALL_STATIC_TYPE(jint, Int)
+    CALL_STATIC_TYPE(jlong, Long)
+    CALL_STATIC_TYPE(jfloat, Float)
+    CALL_STATIC_TYPE(jdouble, Double)
+
+    void CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...)
+    {
+        va_list args;
+        va_start(args, methodID);
+        functions->CallStaticVoidMethodV(this, clazz, methodID, args);
+        va_end(args);
+    }
+    void CallStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args)
+    { functions->CallStaticVoidMethodV(this, clazz, methodID, args); }
+    void CallStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args)
+    { functions->CallStaticVoidMethodA(this, clazz, methodID, args); }
+
+    jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig)
+    { return functions->GetStaticFieldID(this, clazz, name, sig); }
+
+    jobject GetStaticObjectField(jclass clazz, jfieldID fieldID)
+    { return functions->GetStaticObjectField(this, clazz, fieldID); }
+    jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID)
+    { return functions->GetStaticBooleanField(this, clazz, fieldID); }
+    jbyte GetStaticByteField(jclass clazz, jfieldID fieldID)
+    { return functions->GetStaticByteField(this, clazz, fieldID); }
+    jchar GetStaticCharField(jclass clazz, jfieldID fieldID)
+    { return functions->GetStaticCharField(this, clazz, fieldID); }
+    jshort GetStaticShortField(jclass clazz, jfieldID fieldID)
+    { return functions->GetStaticShortField(this, clazz, fieldID); }
+    jint GetStaticIntField(jclass clazz, jfieldID fieldID)
+    { return functions->GetStaticIntField(this, clazz, fieldID); }
+    jlong GetStaticLongField(jclass clazz, jfieldID fieldID)
+    { return functions->GetStaticLongField(this, clazz, fieldID); }
+    jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID)
+    { return functions->GetStaticFloatField(this, clazz, fieldID); }
+    jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID)
+    { return functions->GetStaticDoubleField(this, clazz, fieldID); }
+
+    void SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value)
+    { functions->SetStaticObjectField(this, clazz, fieldID, value); }
+    void SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value)
+    { functions->SetStaticBooleanField(this, clazz, fieldID, value); }
+    void SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value)
+    { functions->SetStaticByteField(this, clazz, fieldID, value); }
+    void SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value)
+    { functions->SetStaticCharField(this, clazz, fieldID, value); }
+    void SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value)
+    { functions->SetStaticShortField(this, clazz, fieldID, value); }
+    void SetStaticIntField(jclass clazz, jfieldID fieldID, jint value)
+    { functions->SetStaticIntField(this, clazz, fieldID, value); }
+    void SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value)
+    { functions->SetStaticLongField(this, clazz, fieldID, value); }
+    void SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value)
+    { functions->SetStaticFloatField(this, clazz, fieldID, value); }
+    void SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value)
+    { functions->SetStaticDoubleField(this, clazz, fieldID, value); }
+
+    jstring NewString(const jchar* unicodeChars, jsize len)
+    { return functions->NewString(this, unicodeChars, len); }
+
+    jsize GetStringLength(jstring string)
+    { return functions->GetStringLength(this, string); }
+
+    const jchar* GetStringChars(jstring string, jboolean* isCopy)
+    { return functions->GetStringChars(this, string, isCopy); }
+
+    void ReleaseStringChars(jstring string, const jchar* chars)
+    { functions->ReleaseStringChars(this, string, chars); }
+
+    jstring NewStringUTF(const char* bytes)
+    { return functions->NewStringUTF(this, bytes); }
+
+    jsize GetStringUTFLength(jstring string)
+    { return functions->GetStringUTFLength(this, string); }
+
+    const char* GetStringUTFChars(jstring string, jboolean* isCopy)
+    { return functions->GetStringUTFChars(this, string, isCopy); }
+
+    void ReleaseStringUTFChars(jstring string, const char* utf)
+    { functions->ReleaseStringUTFChars(this, string, utf); }
+
+    jsize GetArrayLength(jarray array)
+    { return functions->GetArrayLength(this, array); }
+
+    jobjectArray NewObjectArray(jsize length, jclass elementClass,
+        jobject initialElement)
+    { return functions->NewObjectArray(this, length, elementClass,
+        initialElement); }
+
+    jobject GetObjectArrayElement(jobjectArray array, jsize index)
+    { return functions->GetObjectArrayElement(this, array, index); }
+
+    void SetObjectArrayElement(jobjectArray array, jsize index, jobject value)
+    { functions->SetObjectArrayElement(this, array, index, value); }
+
+    jbooleanArray NewBooleanArray(jsize length)
+    { return functions->NewBooleanArray(this, length); }
+    jbyteArray NewByteArray(jsize length)
+    { return functions->NewByteArray(this, length); }
+    jcharArray NewCharArray(jsize length)
+    { return functions->NewCharArray(this, length); }
+    jshortArray NewShortArray(jsize length)
+    { return functions->NewShortArray(this, length); }
+    jintArray NewIntArray(jsize length)
+    { return functions->NewIntArray(this, length); }
+    jlongArray NewLongArray(jsize length)
+    { return functions->NewLongArray(this, length); }
+    jfloatArray NewFloatArray(jsize length)
+    { return functions->NewFloatArray(this, length); }
+    jdoubleArray NewDoubleArray(jsize length)
+    { return functions->NewDoubleArray(this, length); }
+
+    jboolean* GetBooleanArrayElements(jbooleanArray array, jboolean* isCopy)
+    { return functions->GetBooleanArrayElements(this, array, isCopy); }
+    jbyte* GetByteArrayElements(jbyteArray array, jboolean* isCopy)
+    { return functions->GetByteArrayElements(this, array, isCopy); }
+    jchar* GetCharArrayElements(jcharArray array, jboolean* isCopy)
+    { return functions->GetCharArrayElements(this, array, isCopy); }
+    jshort* GetShortArrayElements(jshortArray array, jboolean* isCopy)
+    { return functions->GetShortArrayElements(this, array, isCopy); }
+    jint* GetIntArrayElements(jintArray array, jboolean* isCopy)
+    { return functions->GetIntArrayElements(this, array, isCopy); }
+    jlong* GetLongArrayElements(jlongArray array, jboolean* isCopy)
+    { return functions->GetLongArrayElements(this, array, isCopy); }
+    jfloat* GetFloatArrayElements(jfloatArray array, jboolean* isCopy)
+    { return functions->GetFloatArrayElements(this, array, isCopy); }
+    jdouble* GetDoubleArrayElements(jdoubleArray array, jboolean* isCopy)
+    { return functions->GetDoubleArrayElements(this, array, isCopy); }
+
+    void ReleaseBooleanArrayElements(jbooleanArray array, jboolean* elems,
+        jint mode)
+    { functions->ReleaseBooleanArrayElements(this, array, elems, mode); }
+    void ReleaseByteArrayElements(jbyteArray array, jbyte* elems,
+        jint mode)
+    { functions->ReleaseByteArrayElements(this, array, elems, mode); }
+    void ReleaseCharArrayElements(jcharArray array, jchar* elems,
+        jint mode)
+    { functions->ReleaseCharArrayElements(this, array, elems, mode); }
+    void ReleaseShortArrayElements(jshortArray array, jshort* elems,
+        jint mode)
+    { functions->ReleaseShortArrayElements(this, array, elems, mode); }
+    void ReleaseIntArrayElements(jintArray array, jint* elems,
+        jint mode)
+    { functions->ReleaseIntArrayElements(this, array, elems, mode); }
+    void ReleaseLongArrayElements(jlongArray array, jlong* elems,
+        jint mode)
+    { functions->ReleaseLongArrayElements(this, array, elems, mode); }
+    void ReleaseFloatArrayElements(jfloatArray array, jfloat* elems,
+        jint mode)
+    { functions->ReleaseFloatArrayElements(this, array, elems, mode); }
+    void ReleaseDoubleArrayElements(jdoubleArray array, jdouble* elems,
+        jint mode)
+    { functions->ReleaseDoubleArrayElements(this, array, elems, mode); }
+
+    void GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
+        jboolean* buf)
+    { functions->GetBooleanArrayRegion(this, array, start, len, buf); }
+    void GetByteArrayRegion(jbyteArray array, jsize start, jsize len,
+        jbyte* buf)
+    { functions->GetByteArrayRegion(this, array, start, len, buf); }
+    void GetCharArrayRegion(jcharArray array, jsize start, jsize len,
+        jchar* buf)
+    { functions->GetCharArrayRegion(this, array, start, len, buf); }
+    void GetShortArrayRegion(jshortArray array, jsize start, jsize len,
+        jshort* buf)
+    { functions->GetShortArrayRegion(this, array, start, len, buf); }
+    void GetIntArrayRegion(jintArray array, jsize start, jsize len,
+        jint* buf)
+    { functions->GetIntArrayRegion(this, array, start, len, buf); }
+    void GetLongArrayRegion(jlongArray array, jsize start, jsize len,
+        jlong* buf)
+    { functions->GetLongArrayRegion(this, array, start, len, buf); }
+    void GetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
+        jfloat* buf)
+    { functions->GetFloatArrayRegion(this, array, start, len, buf); }
+    void GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
+        jdouble* buf)
+    { functions->GetDoubleArrayRegion(this, array, start, len, buf); }
+
+    void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
+        const jboolean* buf)
+    { functions->SetBooleanArrayRegion(this, array, start, len, buf); }
+    void SetByteArrayRegion(jbyteArray array, jsize start, jsize len,
+        const jbyte* buf)
+    { functions->SetByteArrayRegion(this, array, start, len, buf); }
+    void SetCharArrayRegion(jcharArray array, jsize start, jsize len,
+        const jchar* buf)
+    { functions->SetCharArrayRegion(this, array, start, len, buf); }
+    void SetShortArrayRegion(jshortArray array, jsize start, jsize len,
+        const jshort* buf)
+    { functions->SetShortArrayRegion(this, array, start, len, buf); }
+    void SetIntArrayRegion(jintArray array, jsize start, jsize len,
+        const jint* buf)
+    { functions->SetIntArrayRegion(this, array, start, len, buf); }
+    void SetLongArrayRegion(jlongArray array, jsize start, jsize len,
+        const jlong* buf)
+    { functions->SetLongArrayRegion(this, array, start, len, buf); }
+    void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
+        const jfloat* buf)
+    { functions->SetFloatArrayRegion(this, array, start, len, buf); }
+    void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
+        const jdouble* buf)
+    { functions->SetDoubleArrayRegion(this, array, start, len, buf); }
+
+    jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,
+        jint nMethods)
+    { return functions->RegisterNatives(this, clazz, methods, nMethods); }
+
+    jint UnregisterNatives(jclass clazz)
+    { return functions->UnregisterNatives(this, clazz); }
+
+    jint MonitorEnter(jobject obj)
+    { return functions->MonitorEnter(this, obj); }
+
+    jint MonitorExit(jobject obj)
+    { return functions->MonitorExit(this, obj); }
+
+    jint GetJavaVM(JavaVM** vm)
+    { return functions->GetJavaVM(this, vm); }
+
+    void GetStringRegion(jstring str, jsize start, jsize len, jchar* buf)
+    { functions->GetStringRegion(this, str, start, len, buf); }
+
+    void GetStringUTFRegion(jstring str, jsize start, jsize len, char* buf)
+    { return functions->GetStringUTFRegion(this, str, start, len, buf); }
+
+    void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy)
+    { return functions->GetPrimitiveArrayCritical(this, array, isCopy); }
+
+    void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode)
+    { functions->ReleasePrimitiveArrayCritical(this, array, carray, mode); }
+
+    const jchar* GetStringCritical(jstring string, jboolean* isCopy)
+    { return functions->GetStringCritical(this, string, isCopy); }
+
+    void ReleaseStringCritical(jstring string, const jchar* carray)
+    { functions->ReleaseStringCritical(this, string, carray); }
+
+    jweak NewWeakGlobalRef(jobject obj)
+    { return functions->NewWeakGlobalRef(this, obj); }
+
+    void DeleteWeakGlobalRef(jweak obj)
+    { functions->DeleteWeakGlobalRef(this, obj); }
+
+    jboolean ExceptionCheck()
+    { return functions->ExceptionCheck(this); }
+
+    jobject NewDirectByteBuffer(void* address, jlong capacity)
+    { return functions->NewDirectByteBuffer(this, address, capacity); }
+
+    void* GetDirectBufferAddress(jobject buf)
+    { return functions->GetDirectBufferAddress(this, buf); }
+
+    jlong GetDirectBufferCapacity(jobject buf)
+    { return functions->GetDirectBufferCapacity(this, buf); }
+
+    /* added in JNI 1.6 */
+    jobjectRefType GetObjectRefType(jobject obj)
+    { return functions->GetObjectRefType(this, obj); }
+#endif /*__cplusplus*/
+};
+
+
+/*
+ * JNI invocation interface.
+ */
+struct JNIInvokeInterface {
+    void*       reserved0;
+    void*       reserved1;
+    void*       reserved2;
+ 
+    jint        (*DestroyJavaVM)(JavaVM*);
+    jint        (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);
+    jint        (*DetachCurrentThread)(JavaVM*);
+    jint        (*GetEnv)(JavaVM*, void**, jint);
+    jint        (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);
+};
+
+/*
+ * C++ version.
+ */
+struct _JavaVM {
+    const struct JNIInvokeInterface* functions;
+
+#if defined(__cplusplus)
+    jint DestroyJavaVM()
+    { return functions->DestroyJavaVM(this); }
+    jint AttachCurrentThread(JNIEnv** p_env, void* thr_args)
+    { return functions->AttachCurrentThread(this, p_env, thr_args); }
+    jint DetachCurrentThread()
+    { return functions->DetachCurrentThread(this); }
+    jint GetEnv(void** env, jint version)
+    { return functions->GetEnv(this, env, version); }
+    jint AttachCurrentThreadAsDaemon(JNIEnv** p_env, void* thr_args)
+    { return functions->AttachCurrentThreadAsDaemon(this, p_env, thr_args); }
+#endif /*__cplusplus*/
+};
+
+struct JavaVMAttachArgs {
+    jint        version;    /* must be >= JNI_VERSION_1_2 */
+    const char* name;       /* NULL or name of thread as modified UTF-8 str */
+    jobject     group;      /* global ref of a ThreadGroup object, or NULL */
+};
+typedef struct JavaVMAttachArgs JavaVMAttachArgs;
+
+/*
+ * JNI 1.2+ initialization.  (As of 1.6, the pre-1.2 structures are no
+ * longer supported.)
+ */
+typedef struct JavaVMOption {
+    const char* optionString;
+    void*       extraInfo;
+} JavaVMOption;
+
+typedef struct JavaVMInitArgs {
+    jint        version;    /* use JNI_VERSION_1_2 or later */
+
+    jint        nOptions;
+    JavaVMOption* options;
+    jboolean    ignoreUnrecognized;
+} JavaVMInitArgs;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * VM initialization functions.
+ *
+ * Note these are the only symbols exported for JNI by the VM.
+ */
+jint JNI_GetDefaultJavaVMInitArgs(void*);
+jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);
+jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*);
+
+/*
+ * Prototypes for functions exported by loadable shared libs.  These are
+ * called by JNI, not provided by JNI.
+ */
+jint JNI_OnLoad(JavaVM* vm, void* reserved);
+void JNI_OnUnload(JavaVM* vm, void* reserved);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/*
+ * Manifest constants.
+ */
+#define JNI_FALSE   0
+#define JNI_TRUE    1
+
+#define JNI_VERSION_1_1 0x00010001
+#define JNI_VERSION_1_2 0x00010002
+#define JNI_VERSION_1_4 0x00010004
+#define JNI_VERSION_1_6 0x00010006
+
+#define JNI_OK          (0)         /* no error */
+#define JNI_ERR         (-1)        /* generic error */
+#define JNI_EDETACHED   (-2)        /* thread detached from the VM */
+#define JNI_EVERSION    (-3)        /* JNI version error */
+
+#define JNI_COMMIT      1           /* copy content, do not free buffer */
+#define JNI_ABORT       2           /* free buffer w/o copying back */
+
+/* need these for Windows-aware headers */
+#define JNIIMPORT
+#define JNIEXPORT
+#define JNICALL
+
+#endif /*_JNI_H*/
diff --git a/ndk/build/platforms/android-1.5/common/include/lastlog.h b/ndk/build/platforms/android-1.5/common/include/lastlog.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/lastlog.h
diff --git a/ndk/build/platforms/android-1.5/common/include/libgen.h b/ndk/build/platforms/android-1.5/common/include/libgen.h
new file mode 100644
index 0000000..c5fc76a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/libgen.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _LIBGEN_H
+#define _LIBGEN_H
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+/* our version of dirname/basename don't modify the input path */
+extern char*  dirname (const char*  path);
+extern char*  basename(const char*  path);
+
+/* special thread-safe Bionic versions
+ *
+ * if 'buffer' is NULL, 'bufflen' is ignored and the length of the result is returned
+ * otherwise, place result in 'buffer'
+ *
+ * at most bufflen-1 characters written, plus a terminating zero
+ *
+ * return length of result, or -1 in case of error, with errno set to:
+ *
+ *    ERANGE:        buffer is too short
+ *    ENAMETOOLONG:  the result is too long for a valid path
+ */
+extern int    dirname_r(const char*  path, char*  buffer, size_t  bufflen);
+extern int    basename_r(const char*  path, char*  buffer, size_t  bufflen);
+
+__END_DECLS
+
+#endif /* _LIBGEN_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/limits.h b/ndk/build/platforms/android-1.5/common/include/limits.h
new file mode 100644
index 0000000..c204e4d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/limits.h
@@ -0,0 +1,96 @@
+/*	$OpenBSD: limits.h,v 1.13 2005/12/31 19:29:38 millert Exp $	*/
+/*	$NetBSD: limits.h,v 1.7 1994/10/26 00:56:00 cgd Exp $	*/
+
+/*
+ * Copyright (c) 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)limits.h	5.9 (Berkeley) 4/3/91
+ */
+
+#ifndef _LIMITS_H_
+#define	_LIMITS_H_
+
+#include <sys/cdefs.h>
+
+#if __POSIX_VISIBLE
+#define	_POSIX_ARG_MAX		4096
+#define	_POSIX_CHILD_MAX	25
+#define	_POSIX_LINK_MAX		8
+#define	_POSIX_MAX_CANON	255
+#define	_POSIX_MAX_INPUT	255
+#define	_POSIX_NAME_MAX		14
+#define	_POSIX_NGROUPS_MAX	0
+#define	_POSIX_OPEN_MAX		16
+#define	_POSIX_PATH_MAX		256
+#define _POSIX_PIPE_BUF		512
+#define	_POSIX_RE_DUP_MAX	255
+#define _POSIX_SSIZE_MAX	32767
+#define _POSIX_STREAM_MAX	8
+#define _POSIX_SYMLINK_MAX	255
+#define _POSIX_SYMLOOP_MAX	8
+#define _POSIX_TZNAME_MAX	3
+
+#define	_POSIX2_BC_BASE_MAX	99
+#define	_POSIX2_BC_DIM_MAX	2048
+#define	_POSIX2_BC_SCALE_MAX	99
+#define	_POSIX2_BC_STRING_MAX	1000
+#define	_POSIX2_COLL_WEIGHTS_MAX	2
+#define	_POSIX2_EXPR_NEST_MAX	32
+#define	_POSIX2_LINE_MAX	2048
+#define	_POSIX2_RE_DUP_MAX	_POSIX_RE_DUP_MAX
+
+#if __POSIX_VISIBLE >= 200112
+#define _POSIX_TTY_NAME_MAX	9	/* includes trailing NUL */
+#define _POSIX_LOGIN_NAME_MAX	9	/* includes trailing NUL */
+#endif /* __POSIX_VISIBLE >= 200112 */
+#endif /* __POSIX_VISIBLE */
+
+#if __XPG_VISIBLE
+#define PASS_MAX		128	/* _PASSWORD_LEN from <pwd.h> */
+
+#define NL_ARGMAX		9
+#define NL_LANGMAX		14
+#define NL_MSGMAX		32767
+#define NL_NMAX			1
+#define NL_SETMAX		255
+#define NL_TEXTMAX		255
+
+#define TMP_MAX                 308915776
+#endif /* __XPG_VISIBLE */
+
+#include <sys/limits.h>
+
+#if __POSIX_VISIBLE
+#include <arch/syslimits.h>
+#endif
+
+#ifndef PAGESIZE
+#define  PAGESIZE  PAGE_SIZE
+#endif
+
+#endif /* !_LIMITS_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/a.out.h b/ndk/build/platforms/android-1.5/common/include/linux/a.out.h
new file mode 100644
index 0000000..7325304
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/a.out.h
@@ -0,0 +1,220 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __A_OUT_GNU_H__
+#define __A_OUT_GNU_H__
+
+#define __GNU_EXEC_MACROS__
+
+#ifndef __STRUCT_EXEC_OVERRIDE__
+
+#include <asm/a.out.h>
+
+#endif
+
+enum machine_type {
+#ifdef M_OLDSUN2
+ M__OLDSUN2 = M_OLDSUN2,
+#else
+ M_OLDSUN2 = 0,
+#endif
+#ifdef M_68010
+ M__68010 = M_68010,
+#else
+ M_68010 = 1,
+#endif
+#ifdef M_68020
+ M__68020 = M_68020,
+#else
+ M_68020 = 2,
+#endif
+#ifdef M_SPARC
+ M__SPARC = M_SPARC,
+#else
+ M_SPARC = 3,
+#endif
+
+ M_386 = 100,
+ M_MIPS1 = 151,
+ M_MIPS2 = 152
+};
+
+#ifndef N_MAGIC
+#define N_MAGIC(exec) ((exec).a_info & 0xffff)
+#endif
+#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
+#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
+#define N_SET_INFO(exec, magic, type, flags)   ((exec).a_info = ((magic) & 0xffff)   | (((int)(type) & 0xff) << 16)   | (((flags) & 0xff) << 24))
+#define N_SET_MAGIC(exec, magic)   ((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
+
+#define N_SET_MACHTYPE(exec, machtype)   ((exec).a_info =   ((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
+
+#define N_SET_FLAGS(exec, flags)   ((exec).a_info =   ((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
+
+#define OMAGIC 0407
+
+#define NMAGIC 0410
+
+#define ZMAGIC 0413
+
+#define QMAGIC 0314
+
+#define CMAGIC 0421
+
+#ifndef N_BADMAG
+#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC   && N_MAGIC(x) != NMAGIC   && N_MAGIC(x) != ZMAGIC   && N_MAGIC(x) != QMAGIC)
+#endif
+
+#define _N_HDROFF(x) (1024 - sizeof (struct exec))
+
+#ifndef N_TXTOFF
+#define N_TXTOFF(x)   (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) :   (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
+#endif
+
+#ifndef N_DATOFF
+#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
+#endif
+
+#ifndef N_TRELOFF
+#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
+#endif
+
+#ifndef N_DRELOFF
+#define N_DRELOFF(x) (N_TRELOFF(x) + N_TRSIZE(x))
+#endif
+
+#ifndef N_SYMOFF
+#define N_SYMOFF(x) (N_DRELOFF(x) + N_DRSIZE(x))
+#endif
+
+#ifndef N_STROFF
+#define N_STROFF(x) (N_SYMOFF(x) + N_SYMSIZE(x))
+#endif
+
+#ifndef N_TXTADDR
+#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? PAGE_SIZE : 0)
+#endif
+
+#if defined(vax) || defined(hp300) || defined(pyr)
+#define SEGMENT_SIZE page_size
+#endif
+#ifdef sony
+#define SEGMENT_SIZE 0x2000
+#endif
+#ifdef is68k
+#define SEGMENT_SIZE 0x20000
+#endif
+#if defined(m68k) && defined(PORTAR)
+#define PAGE_SIZE 0x400
+#define SEGMENT_SIZE PAGE_SIZE
+#endif
+
+#ifdef linux
+#include <asm/page.h>
+#if defined(__i386__) || defined(__mc68000__)
+#define SEGMENT_SIZE 1024
+#else
+#ifndef SEGMENT_SIZE
+#define SEGMENT_SIZE PAGE_SIZE
+#endif
+#endif
+#endif
+
+#define _N_SEGMENT_ROUND(x) ALIGN(x, SEGMENT_SIZE)
+
+#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
+
+#ifndef N_DATADDR
+#define N_DATADDR(x)   (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x))   : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
+#endif
+
+#ifndef N_BSSADDR
+#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
+#endif
+
+#ifndef N_NLIST_DECLARED
+struct nlist {
+ union {
+ char *n_name;
+ struct nlist *n_next;
+ long n_strx;
+ } n_un;
+ unsigned char n_type;
+ char n_other;
+ short n_desc;
+ unsigned long n_value;
+};
+#endif
+
+#ifndef N_UNDF
+#define N_UNDF 0
+#endif
+#ifndef N_ABS
+#define N_ABS 2
+#endif
+#ifndef N_TEXT
+#define N_TEXT 4
+#endif
+#ifndef N_DATA
+#define N_DATA 6
+#endif
+#ifndef N_BSS
+#define N_BSS 8
+#endif
+#ifndef N_FN
+#define N_FN 15
+#endif
+
+#ifndef N_EXT
+#define N_EXT 1
+#endif
+#ifndef N_TYPE
+#define N_TYPE 036
+#endif
+#ifndef N_STAB
+#define N_STAB 0340
+#endif
+
+#define N_INDR 0xa
+
+#define N_SETA 0x14  
+#define N_SETT 0x16  
+#define N_SETD 0x18  
+#define N_SETB 0x1A  
+
+#define N_SETV 0x1C  
+
+#ifndef N_RELOCATION_INFO_DECLARED
+
+struct relocation_info
+{
+
+ int r_address;
+
+ unsigned int r_symbolnum:24;
+
+ unsigned int r_pcrel:1;
+
+ unsigned int r_length:2;
+
+ unsigned int r_extern:1;
+
+#ifdef NS32K
+ unsigned r_bsr:1;
+ unsigned r_disp:1;
+ unsigned r_pad:2;
+#else
+ unsigned int r_pad:4;
+#endif
+};
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/aio_abi.h b/ndk/build/platforms/android-1.5/common/include/linux/aio_abi.h
new file mode 100644
index 0000000..c92bc8f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/aio_abi.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX__AIO_ABI_H
+#define __LINUX__AIO_ABI_H
+
+#include <asm/byteorder.h>
+
+typedef unsigned long aio_context_t;
+
+enum {
+ IOCB_CMD_PREAD = 0,
+ IOCB_CMD_PWRITE = 1,
+ IOCB_CMD_FSYNC = 2,
+ IOCB_CMD_FDSYNC = 3,
+
+ IOCB_CMD_NOOP = 6,
+};
+
+struct io_event {
+ __u64 data;
+ __u64 obj;
+ __s64 res;
+ __s64 res2;
+};
+
+#ifdef __LITTLE_ENDIAN
+#define PADDED(x,y) x, y
+#elif defined(__BIG_ENDIAN)
+#define PADDED(x,y) y, x
+#else
+#error edit for your odd byteorder.
+#endif
+
+struct iocb {
+
+ __u64 aio_data;
+ __u32 PADDED(aio_key, aio_reserved1);
+
+ __u16 aio_lio_opcode;
+ __s16 aio_reqprio;
+ __u32 aio_fildes;
+
+ __u64 aio_buf;
+ __u64 aio_nbytes;
+ __s64 aio_offset;
+
+ __u64 aio_reserved2;
+ __u64 aio_reserved3;
+};
+
+#undef IFBIG
+#undef IFLITTLE
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/akm8976.h b/ndk/build/platforms/android-1.5/common/include/linux/akm8976.h
new file mode 100644
index 0000000..a5aa68e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/akm8976.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef AKM8976_H
+#define AKM8976_H
+
+#include <linux/ioctl.h>
+
+#define AKECS_MODE_MEASURE 0x00  
+
+#define AKECS_MODE_PFFD 0x01  
+#define AKECS_MODE_E2P_READ 0x02  
+#define AKECS_MODE_POWERDOWN 0x03  
+
+#define AKECS_MODE_MEASURE_SNG 0x10  
+#define AKECS_MODE_MEASURE_SEQ 0x11  
+
+#define CSPEC_AINT 0x01  
+#define CSPEC_SNG_NUM 0x01  
+#define CSPEC_SEQ_NUM 0x02  
+#define CSPEC_SFRQ_32 0x00  
+#define CSPEC_SFRQ_64 0x01  
+#define CSPEC_MCS 0x07  
+#define CSPEC_MKS 0x01  
+#define CSPEC_INTEN 0x01  
+
+#define RBUFF_SIZE 31  
+#define MAX_CALI_SIZE 0x1000U  
+
+#define AKECS_REG_ST 0xC0
+#define AKECS_REG_TMPS 0xC1
+#define AKECS_REG_MS1 0xE0
+#define AKECS_REG_MS2 0xE1
+#define AKECS_REG_MS3 0xE2
+
+#define AKMIO 0xA1
+
+#define ECS_IOCTL_INIT _IO(AKMIO, 0x01)
+#define ECS_IOCTL_WRITE _IOW(AKMIO, 0x02, char[5])
+#define ECS_IOCTL_READ _IOWR(AKMIO, 0x03, char[5])
+#define ECS_IOCTL_RESET _IO(AKMIO, 0x04)
+#define ECS_IOCTL_INT_STATUS _IO(AKMIO, 0x05)
+#define ECS_IOCTL_FFD_STATUS _IO(AKMIO, 0x06)
+#define ECS_IOCTL_SET_MODE _IOW(AKMIO, 0x07, short)
+#define ECS_IOCTL_GETDATA _IOR(AKMIO, 0x08, char[RBUFF_SIZE+1])
+#define ECS_IOCTL_GET_NUMFRQ _IOR(AKMIO, 0x09, char[2])
+#define ECS_IOCTL_SET_PERST _IO(AKMIO, 0x0A)
+#define ECS_IOCTL_SET_G0RST _IO(AKMIO, 0x0B)
+#define ECS_IOCTL_SET_YPR _IOW(AKMIO, 0x0C, short[12])
+#define ECS_IOCTL_GET_OPEN_STATUS _IOR(AKMIO, 0x0D, int)
+#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(AKMIO, 0x0E, int)
+#define ECS_IOCTL_GET_CALI_DATA _IOR(AKMIO, 0x0F, char[MAX_CALI_SIZE])
+#define ECS_IOCTL_GET_DELAY _IOR(AKMIO, 0x30, short)
+
+#define ECS_IOCTL_APP_SET_MODE _IOW(AKMIO, 0x10, short)
+#define ECS_IOCTL_APP_SET_MFLAG _IOW(AKMIO, 0x11, short)
+#define ECS_IOCTL_APP_GET_MFLAG _IOW(AKMIO, 0x12, short)
+#define ECS_IOCTL_APP_SET_AFLAG _IOW(AKMIO, 0x13, short)
+#define ECS_IOCTL_APP_GET_AFLAG _IOR(AKMIO, 0x14, short)
+#define ECS_IOCTL_APP_SET_TFLAG _IOR(AKMIO, 0x15, short)
+#define ECS_IOCTL_APP_GET_TFLAG _IOR(AKMIO, 0x16, short)
+#define ECS_IOCTL_APP_RESET_PEDOMETER _IO(AKMIO, 0x17)
+#define ECS_IOCTL_APP_SET_DELAY _IOW(AKMIO, 0x18, short)
+#define ECS_IOCTL_APP_GET_DELAY ECS_IOCTL_GET_DELAY
+#define ECS_IOCTL_APP_SET_MVFLAG _IOW(AKMIO, 0x19, short)  
+#define ECS_IOCTL_APP_GET_MVFLAG _IOR(AKMIO, 0x1A, short)  
+
+#define ECS_IOCTL_SET_STEP_CNT _IOW(AKMIO, 0x20, short)
+
+#define ECS_RST 146  
+#define ECS_CLK_ON 155  
+#define ECS_INTR 161  
+
+struct akm8976_platform_data {
+ int reset;
+ int clk_on;
+ int intr;
+};
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/android_alarm.h b/ndk/build/platforms/android-1.5/common/include/linux/android_alarm.h
new file mode 100644
index 0000000..80828ea
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/android_alarm.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ANDROID_ALARM_H
+#define _LINUX_ANDROID_ALARM_H
+
+#include <asm/ioctl.h>
+#include <linux/time.h>
+
+typedef enum {
+
+ ANDROID_ALARM_RTC_WAKEUP,
+ ANDROID_ALARM_RTC,
+ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
+ ANDROID_ALARM_ELAPSED_REALTIME,
+ ANDROID_ALARM_SYSTEMTIME,
+
+ ANDROID_ALARM_TYPE_COUNT,
+
+} android_alarm_type_t;
+
+typedef enum {
+ ANDROID_ALARM_RTC_WAKEUP_MASK = 1U << ANDROID_ALARM_RTC_WAKEUP,
+ ANDROID_ALARM_RTC_MASK = 1U << ANDROID_ALARM_RTC,
+ ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP_MASK = 1U << ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
+ ANDROID_ALARM_ELAPSED_REALTIME_MASK = 1U << ANDROID_ALARM_ELAPSED_REALTIME,
+ ANDROID_ALARM_SYSTEMTIME_MASK = 1U << ANDROID_ALARM_SYSTEMTIME,
+ ANDROID_ALARM_TIME_CHANGE_MASK = 1U << 16
+} android_alarm_return_flags_t;
+
+#define ANDROID_ALARM_CLEAR(type) _IO('a', 0 | ((type) << 4)) 
+#define ANDROID_ALARM_WAIT _IO('a', 1) 
+#define ANDROID_ALARM_SET(type) _IOW('a', 2 | ((type) << 4), struct timespec) 
+#define ANDROID_ALARM_SET_AND_WAIT(type) _IOW('a', 3 | ((type) << 4), struct timespec)
+#define ANDROID_ALARM_GET_TIME(type) _IOW('a', 4 | ((type) << 4), struct timespec)
+#define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec)
+#define ANDROID_ALARM_SET_TIMEZONE _IOW('a', 6, struct timezone)
+
+#define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0)))
+#define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/android_pmem.h b/ndk/build/platforms/android-1.5/common/include/linux/android_pmem.h
new file mode 100644
index 0000000..858857e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/android_pmem.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ANDROID_PMEM_H_
+#define _ANDROID_PMEM_H_
+
+#include <stdint.h>
+
+#ifndef __user
+#define __user
+#endif
+
+struct pmem_region {
+ unsigned long offset;
+ unsigned long len;
+};
+
+#define PMEM_IOCTL_MAGIC 'p'
+#define PMEM_GET_PHYS _IOW(PMEM_IOCTL_MAGIC, 1, struct pmem_region *)
+#define PMEM_MAP _IOW(PMEM_IOCTL_MAGIC, 2, struct pmem_region *)
+#define PMEM_GET_SIZE _IOW(PMEM_IOCTL_MAGIC, 3, struct pmem_region *)
+#define PMEM_UNMAP _IOW(PMEM_IOCTL_MAGIC, 4, struct pmem_region *)
+
+#define PMEM_ALLOCATE _IOW(PMEM_IOCTL_MAGIC, 5, unsigned int)
+
+#define PMEM_CONNECT _IOW(PMEM_IOCTL_MAGIC, 6, unsigned int)
+
+#define PMEM_GET_TOTAL_SIZE _IOW(PMEM_IOCTL_MAGIC, 7, struct pmem_region *)
+
+#define HW3D_REVOKE_GPU _IOW(PMEM_IOCTL_MAGIC, 8, unsigned int)
+#define HW3D_GRANT_GPU _IOW(PMEM_IOCTL_MAGIC, 9, unsigned int)
+#define HW3D_WAIT_IRQ _IOW(PMEM_IOCTL_MAGIC,10, unsigned int)
+
+struct android_pmem_platform_data;
+struct pmem_file_operations {
+ int (*mmap) (struct file *, struct vm_area_struct *);
+ int (*open) (struct inode *, struct file *);
+ ssize_t (*read) (struct file *, char __user *, size_t, long long *);
+ int (*release) (struct inode *, struct file *);
+ long (*ioctl) (struct file *, unsigned int, unsigned long);
+};
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/android_power.h b/ndk/build/platforms/android-1.5/common/include/linux/android_power.h
new file mode 100644
index 0000000..2e90321
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/android_power.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ANDROID_POWER_H
+#define _LINUX_ANDROID_POWER_H
+
+#include <linux/list.h>
+
+typedef struct
+{
+ struct list_head link;
+ int lock_count;
+ int flags;
+ const char *name;
+ int expires;
+} android_suspend_lock_t;
+
+#define ANDROID_SUSPEND_LOCK_FLAG_COUNTED (1U << 0)
+#define ANDROID_SUSPEND_LOCK_FLAG_USER_READABLE (1U << 1)
+#define ANDROID_SUSPEND_LOCK_FLAG_USER_SET (1U << 2)
+#define ANDROID_SUSPEND_LOCK_FLAG_USER_CLEAR (1U << 3)
+#define ANDROID_SUSPEND_LOCK_FLAG_USER_INC (1U << 4)
+#define ANDROID_SUSPEND_LOCK_FLAG_USER_DEC (1U << 5)
+#define ANDROID_SUSPEND_LOCK_FLAG_USER_VISIBLE_MASK (0x1fU << 1)
+#define ANDROID_SUSPEND_LOCK_AUTO_EXPIRE (1U << 6)
+
+typedef struct android_early_suspend android_early_suspend_t;
+struct android_early_suspend
+{
+ struct list_head link;
+ int level;
+ void (*suspend)(android_early_suspend_t *h);
+ void (*resume)(android_early_suspend_t *h);
+};
+
+typedef enum {
+ ANDROID_CHARGING_STATE_UNKNOWN,
+ ANDROID_CHARGING_STATE_DISCHARGE,
+ ANDROID_CHARGING_STATE_MAINTAIN,
+ ANDROID_CHARGING_STATE_SLOW,
+ ANDROID_CHARGING_STATE_NORMAL,
+ ANDROID_CHARGING_STATE_FAST,
+ ANDROID_CHARGING_STATE_OVERHEAT
+} android_charging_state_t;
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/apm_bios.h b/ndk/build/platforms/android-1.5/common/include/linux/apm_bios.h
new file mode 100644
index 0000000..d32b4aa
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/apm_bios.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_APM_H
+#define _LINUX_APM_H
+
+typedef unsigned short apm_event_t;
+typedef unsigned short apm_eventinfo_t;
+
+#define APM_STATE_READY 0x0000
+#define APM_STATE_STANDBY 0x0001
+#define APM_STATE_SUSPEND 0x0002
+#define APM_STATE_OFF 0x0003
+#define APM_STATE_BUSY 0x0004
+#define APM_STATE_REJECT 0x0005
+#define APM_STATE_OEM_SYS 0x0020
+#define APM_STATE_OEM_DEV 0x0040
+
+#define APM_STATE_DISABLE 0x0000
+#define APM_STATE_ENABLE 0x0001
+
+#define APM_STATE_DISENGAGE 0x0000
+#define APM_STATE_ENGAGE 0x0001
+
+#define APM_SYS_STANDBY 0x0001
+#define APM_SYS_SUSPEND 0x0002
+#define APM_NORMAL_RESUME 0x0003
+#define APM_CRITICAL_RESUME 0x0004
+#define APM_LOW_BATTERY 0x0005
+#define APM_POWER_STATUS_CHANGE 0x0006
+#define APM_UPDATE_TIME 0x0007
+#define APM_CRITICAL_SUSPEND 0x0008
+#define APM_USER_STANDBY 0x0009
+#define APM_USER_SUSPEND 0x000a
+#define APM_STANDBY_RESUME 0x000b
+#define APM_CAPABILITY_CHANGE 0x000c
+
+#define APM_SUCCESS 0x00
+#define APM_DISABLED 0x01
+#define APM_CONNECTED 0x02
+#define APM_NOT_CONNECTED 0x03
+#define APM_16_CONNECTED 0x05
+#define APM_16_UNSUPPORTED 0x06
+#define APM_32_CONNECTED 0x07
+#define APM_32_UNSUPPORTED 0x08
+#define APM_BAD_DEVICE 0x09
+#define APM_BAD_PARAM 0x0a
+#define APM_NOT_ENGAGED 0x0b
+#define APM_BAD_FUNCTION 0x0c
+#define APM_RESUME_DISABLED 0x0d
+#define APM_NO_ERROR 0x53
+#define APM_BAD_STATE 0x60
+#define APM_NO_EVENTS 0x80
+#define APM_NOT_PRESENT 0x86
+
+#define APM_DEVICE_BIOS 0x0000
+#define APM_DEVICE_ALL 0x0001
+#define APM_DEVICE_DISPLAY 0x0100
+#define APM_DEVICE_STORAGE 0x0200
+#define APM_DEVICE_PARALLEL 0x0300
+#define APM_DEVICE_SERIAL 0x0400
+#define APM_DEVICE_NETWORK 0x0500
+#define APM_DEVICE_PCMCIA 0x0600
+#define APM_DEVICE_BATTERY 0x8000
+#define APM_DEVICE_OEM 0xe000
+#define APM_DEVICE_OLD_ALL 0xffff
+#define APM_DEVICE_CLASS 0x00ff
+#define APM_DEVICE_MASK 0xff00
+
+#define APM_MAX_BATTERIES 2
+
+#define APM_CAP_GLOBAL_STANDBY 0x0001
+#define APM_CAP_GLOBAL_SUSPEND 0x0002
+#define APM_CAP_RESUME_STANDBY_TIMER 0x0004  
+#define APM_CAP_RESUME_SUSPEND_TIMER 0x0008  
+#define APM_CAP_RESUME_STANDBY_RING 0x0010  
+#define APM_CAP_RESUME_SUSPEND_RING 0x0020  
+#define APM_CAP_RESUME_STANDBY_PCMCIA 0x0040  
+#define APM_CAP_RESUME_SUSPEND_PCMCIA 0x0080  
+
+#include <linux/ioctl.h>
+
+#define APM_IOC_STANDBY _IO('A', 1)
+#define APM_IOC_SUSPEND _IO('A', 2)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ashmem.h b/ndk/build/platforms/android-1.5/common/include/linux/ashmem.h
new file mode 100644
index 0000000..a57d1de
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ashmem.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ASHMEM_H
+#define _LINUX_ASHMEM_H
+
+#include <linux/limits.h>
+#include <linux/ioctl.h>
+
+#define ASHMEM_NAME_LEN 256
+
+#define ASHMEM_NAME_DEF "dev/ashmem"
+
+#define ASHMEM_NOT_PURGED 0
+#define ASHMEM_WAS_PURGED 1
+
+#define ASHMEM_IS_UNPINNED 0
+#define ASHMEM_IS_PINNED 1
+
+struct ashmem_pin {
+ __u32 offset;
+ __u32 len;
+};
+
+#define __ASHMEMIOC 0x77
+
+#define ASHMEM_SET_NAME _IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN])
+#define ASHMEM_GET_NAME _IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN])
+#define ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, size_t)
+#define ASHMEM_GET_SIZE _IO(__ASHMEMIOC, 4)
+#define ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned long)
+#define ASHMEM_GET_PROT_MASK _IO(__ASHMEMIOC, 6)
+#define ASHMEM_PIN _IOW(__ASHMEMIOC, 7, struct ashmem_pin)
+#define ASHMEM_UNPIN _IOW(__ASHMEMIOC, 8, struct ashmem_pin)
+#define ASHMEM_GET_PIN_STATUS _IO(__ASHMEMIOC, 9)
+#define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ata.h b/ndk/build/platforms/android-1.5/common/include/linux/ata.h
new file mode 100644
index 0000000..76af576
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ata.h
@@ -0,0 +1,265 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_ATA_H__
+#define __LINUX_ATA_H__
+
+#include <linux/types.h>
+
+#define ATA_DMA_BOUNDARY 0xffffUL
+#define ATA_DMA_MASK 0xffffffffULL
+
+enum {
+
+ ATA_MAX_DEVICES = 2,
+ ATA_MAX_PRD = 256,
+ ATA_SECT_SIZE = 512,
+
+ ATA_ID_WORDS = 256,
+ ATA_ID_SERNO_OFS = 10,
+ ATA_ID_FW_REV_OFS = 23,
+ ATA_ID_PROD_OFS = 27,
+ ATA_ID_OLD_PIO_MODES = 51,
+ ATA_ID_FIELD_VALID = 53,
+ ATA_ID_MWDMA_MODES = 63,
+ ATA_ID_PIO_MODES = 64,
+ ATA_ID_EIDE_DMA_MIN = 65,
+ ATA_ID_EIDE_PIO = 67,
+ ATA_ID_EIDE_PIO_IORDY = 68,
+ ATA_ID_UDMA_MODES = 88,
+ ATA_ID_MAJOR_VER = 80,
+ ATA_ID_PIO4 = (1 << 1),
+
+ ATA_PCI_CTL_OFS = 2,
+ ATA_SERNO_LEN = 20,
+ ATA_UDMA0 = (1 << 0),
+ ATA_UDMA1 = ATA_UDMA0 | (1 << 1),
+ ATA_UDMA2 = ATA_UDMA1 | (1 << 2),
+ ATA_UDMA3 = ATA_UDMA2 | (1 << 3),
+ ATA_UDMA4 = ATA_UDMA3 | (1 << 4),
+ ATA_UDMA5 = ATA_UDMA4 | (1 << 5),
+ ATA_UDMA6 = ATA_UDMA5 | (1 << 6),
+ ATA_UDMA7 = ATA_UDMA6 | (1 << 7),
+
+ ATA_UDMA_MASK_40C = ATA_UDMA2,
+
+ ATA_PRD_SZ = 8,
+ ATA_PRD_TBL_SZ = (ATA_MAX_PRD * ATA_PRD_SZ),
+ ATA_PRD_EOT = (1 << 31),
+
+ ATA_DMA_TABLE_OFS = 4,
+ ATA_DMA_STATUS = 2,
+ ATA_DMA_CMD = 0,
+ ATA_DMA_WR = (1 << 3),
+ ATA_DMA_START = (1 << 0),
+ ATA_DMA_INTR = (1 << 2),
+ ATA_DMA_ERR = (1 << 1),
+ ATA_DMA_ACTIVE = (1 << 0),
+
+ ATA_HOB = (1 << 7),
+ ATA_NIEN = (1 << 1),
+ ATA_LBA = (1 << 6),
+ ATA_DEV1 = (1 << 4),
+ ATA_DEVICE_OBS = (1 << 7) | (1 << 5),
+ ATA_DEVCTL_OBS = (1 << 3),
+ ATA_BUSY = (1 << 7),
+ ATA_DRDY = (1 << 6),
+ ATA_DF = (1 << 5),
+ ATA_DRQ = (1 << 3),
+ ATA_ERR = (1 << 0),
+ ATA_SRST = (1 << 2),
+ ATA_ICRC = (1 << 7),
+ ATA_UNC = (1 << 6),
+ ATA_IDNF = (1 << 4),
+ ATA_ABORTED = (1 << 2),
+
+ ATA_REG_DATA = 0x00,
+ ATA_REG_ERR = 0x01,
+ ATA_REG_NSECT = 0x02,
+ ATA_REG_LBAL = 0x03,
+ ATA_REG_LBAM = 0x04,
+ ATA_REG_LBAH = 0x05,
+ ATA_REG_DEVICE = 0x06,
+ ATA_REG_STATUS = 0x07,
+
+ ATA_REG_FEATURE = ATA_REG_ERR,
+ ATA_REG_CMD = ATA_REG_STATUS,
+ ATA_REG_BYTEL = ATA_REG_LBAM,
+ ATA_REG_BYTEH = ATA_REG_LBAH,
+ ATA_REG_DEVSEL = ATA_REG_DEVICE,
+ ATA_REG_IRQ = ATA_REG_NSECT,
+
+ ATA_CMD_CHK_POWER = 0xE5,
+ ATA_CMD_STANDBY = 0xE2,
+ ATA_CMD_IDLE = 0xE3,
+ ATA_CMD_EDD = 0x90,
+ ATA_CMD_FLUSH = 0xE7,
+ ATA_CMD_FLUSH_EXT = 0xEA,
+ ATA_CMD_ID_ATA = 0xEC,
+ ATA_CMD_ID_ATAPI = 0xA1,
+ ATA_CMD_READ = 0xC8,
+ ATA_CMD_READ_EXT = 0x25,
+ ATA_CMD_WRITE = 0xCA,
+ ATA_CMD_WRITE_EXT = 0x35,
+ ATA_CMD_WRITE_FUA_EXT = 0x3D,
+ ATA_CMD_FPDMA_READ = 0x60,
+ ATA_CMD_FPDMA_WRITE = 0x61,
+ ATA_CMD_PIO_READ = 0x20,
+ ATA_CMD_PIO_READ_EXT = 0x24,
+ ATA_CMD_PIO_WRITE = 0x30,
+ ATA_CMD_PIO_WRITE_EXT = 0x34,
+ ATA_CMD_READ_MULTI = 0xC4,
+ ATA_CMD_READ_MULTI_EXT = 0x29,
+ ATA_CMD_WRITE_MULTI = 0xC5,
+ ATA_CMD_WRITE_MULTI_EXT = 0x39,
+ ATA_CMD_WRITE_MULTI_FUA_EXT = 0xCE,
+ ATA_CMD_SET_FEATURES = 0xEF,
+ ATA_CMD_PACKET = 0xA0,
+ ATA_CMD_VERIFY = 0x40,
+ ATA_CMD_VERIFY_EXT = 0x42,
+ ATA_CMD_STANDBYNOW1 = 0xE0,
+ ATA_CMD_IDLEIMMEDIATE = 0xE1,
+ ATA_CMD_INIT_DEV_PARAMS = 0x91,
+ ATA_CMD_READ_NATIVE_MAX = 0xF8,
+ ATA_CMD_READ_NATIVE_MAX_EXT = 0x27,
+ ATA_CMD_READ_LOG_EXT = 0x2f,
+
+ ATA_LOG_SATA_NCQ = 0x10,
+
+ SETFEATURES_XFER = 0x03,
+ XFER_UDMA_7 = 0x47,
+ XFER_UDMA_6 = 0x46,
+ XFER_UDMA_5 = 0x45,
+ XFER_UDMA_4 = 0x44,
+ XFER_UDMA_3 = 0x43,
+ XFER_UDMA_2 = 0x42,
+ XFER_UDMA_1 = 0x41,
+ XFER_UDMA_0 = 0x40,
+ XFER_MW_DMA_2 = 0x22,
+ XFER_MW_DMA_1 = 0x21,
+ XFER_MW_DMA_0 = 0x20,
+ XFER_SW_DMA_2 = 0x12,
+ XFER_SW_DMA_1 = 0x11,
+ XFER_SW_DMA_0 = 0x10,
+ XFER_PIO_4 = 0x0C,
+ XFER_PIO_3 = 0x0B,
+ XFER_PIO_2 = 0x0A,
+ XFER_PIO_1 = 0x09,
+ XFER_PIO_0 = 0x08,
+ XFER_PIO_SLOW = 0x00,
+
+ SETFEATURES_WC_ON = 0x02,
+ SETFEATURES_WC_OFF = 0x82,
+
+ ATAPI_PKT_DMA = (1 << 0),
+ ATAPI_DMADIR = (1 << 2),
+ ATAPI_CDB_LEN = 16,
+
+ ATA_CBL_NONE = 0,
+ ATA_CBL_PATA40 = 1,
+ ATA_CBL_PATA80 = 2,
+ ATA_CBL_PATA_UNK = 3,
+ ATA_CBL_SATA = 4,
+
+ SCR_STATUS = 0,
+ SCR_ERROR = 1,
+ SCR_CONTROL = 2,
+ SCR_ACTIVE = 3,
+ SCR_NOTIFICATION = 4,
+
+ SERR_DATA_RECOVERED = (1 << 0),
+ SERR_COMM_RECOVERED = (1 << 1),
+ SERR_DATA = (1 << 8),
+ SERR_PERSISTENT = (1 << 9),
+ SERR_PROTOCOL = (1 << 10),
+ SERR_INTERNAL = (1 << 11),
+ SERR_PHYRDY_CHG = (1 << 16),
+ SERR_DEV_XCHG = (1 << 26),
+
+ ATA_TFLAG_LBA48 = (1 << 0),
+ ATA_TFLAG_ISADDR = (1 << 1),
+ ATA_TFLAG_DEVICE = (1 << 2),
+ ATA_TFLAG_WRITE = (1 << 3),
+ ATA_TFLAG_LBA = (1 << 4),
+ ATA_TFLAG_FUA = (1 << 5),
+ ATA_TFLAG_POLLING = (1 << 6),
+};
+
+enum ata_tf_protocols {
+
+ ATA_PROT_UNKNOWN,
+ ATA_PROT_NODATA,
+ ATA_PROT_PIO,
+ ATA_PROT_DMA,
+ ATA_PROT_NCQ,
+ ATA_PROT_ATAPI,
+ ATA_PROT_ATAPI_NODATA,
+ ATA_PROT_ATAPI_DMA,
+};
+
+enum ata_ioctls {
+ ATA_IOC_GET_IO32 = 0x309,
+ ATA_IOC_SET_IO32 = 0x324,
+};
+
+struct ata_prd {
+ u32 addr;
+ u32 flags_len;
+};
+
+struct ata_taskfile {
+ unsigned long flags;
+ u8 protocol;
+
+ u8 ctl;
+
+ u8 hob_feature;
+ u8 hob_nsect;
+ u8 hob_lbal;
+ u8 hob_lbam;
+ u8 hob_lbah;
+
+ u8 feature;
+ u8 nsect;
+ u8 lbal;
+ u8 lbam;
+ u8 lbah;
+
+ u8 device;
+
+ u8 command;
+};
+
+#define ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0)
+#define ata_id_is_cfa(id) ((id)[0] == 0x848A)
+#define ata_id_is_sata(id) ((id)[93] == 0)
+#define ata_id_rahead_enabled(id) ((id)[85] & (1 << 6))
+#define ata_id_wcache_enabled(id) ((id)[85] & (1 << 5))
+#define ata_id_hpa_enabled(id) ((id)[85] & (1 << 10))
+#define ata_id_has_fua(id) ((id)[84] & (1 << 6))
+#define ata_id_has_flush(id) ((id)[83] & (1 << 12))
+#define ata_id_has_flush_ext(id) ((id)[83] & (1 << 13))
+#define ata_id_has_lba48(id) ((id)[83] & (1 << 10))
+#define ata_id_has_hpa(id) ((id)[82] & (1 << 10))
+#define ata_id_has_wcache(id) ((id)[82] & (1 << 5))
+#define ata_id_has_pm(id) ((id)[82] & (1 << 3))
+#define ata_id_has_lba(id) ((id)[49] & (1 << 9))
+#define ata_id_has_dma(id) ((id)[49] & (1 << 8))
+#define ata_id_has_ncq(id) ((id)[76] & (1 << 8))
+#define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1)
+#define ata_id_removeable(id) ((id)[0] & (1 << 7))
+#define ata_id_has_dword_io(id) ((id)[50] & (1 << 0))
+#define ata_id_u32(id,n)   (((u32) (id)[(n) + 1] << 16) | ((u32) (id)[(n)]))
+#define ata_id_u64(id,n)   ( ((u64) (id)[(n) + 3] << 48) |   ((u64) (id)[(n) + 2] << 32) |   ((u64) (id)[(n) + 1] << 16) |   ((u64) (id)[(n) + 0]) )
+
+#define ata_id_cdb_intr(id) (((id)[0] & 0x60) == 0x20)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/atm.h b/ndk/build/platforms/android-1.5/common/include/linux/atm.h
new file mode 100644
index 0000000..c9bcd70
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/atm.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ATM_H
+#define _LINUX_ATM_H
+
+#include <linux/compiler.h>
+#include <linux/atmapi.h>
+#include <linux/atmsap.h>
+#include <linux/atmioc.h>
+
+#define ATM_CELL_SIZE 53  
+#define ATM_CELL_PAYLOAD 48  
+#define ATM_AAL0_SDU 52  
+#define ATM_MAX_AAL34_PDU 65535  
+#define ATM_AAL5_TRAILER 8  
+#define ATM_MAX_AAL5_PDU 65535  
+#define ATM_MAX_CDV 9999  
+#define ATM_NOT_RSV_VCI 32  
+
+#define ATM_MAX_VPI 255  
+#define ATM_MAX_VPI_NNI 4096  
+#define ATM_MAX_VCI 65535  
+
+#define ATM_NO_AAL 0  
+#define ATM_AAL0 13  
+#define ATM_AAL1 1  
+#define ATM_AAL2 2  
+#define ATM_AAL34 3  
+#define ATM_AAL5 5  
+
+#define __SO_ENCODE(l,n,t) ((((l) & 0x1FF) << 22) | ((n) << 16) |   sizeof(t))
+#define __SO_LEVEL_MATCH(c,m) (((c) >> 22) == ((m) & 0x1FF))
+#define __SO_NUMBER(c) (((c) >> 16) & 0x3f)
+#define __SO_SIZE(c) ((c) & 0x3fff)
+
+#define SO_SETCLP __SO_ENCODE(SOL_ATM,0,int)
+
+#define SO_CIRANGE __SO_ENCODE(SOL_ATM,1,struct atm_cirange)
+
+#define SO_ATMQOS __SO_ENCODE(SOL_ATM,2,struct atm_qos)
+
+#define SO_ATMSAP __SO_ENCODE(SOL_ATM,3,struct atm_sap)
+
+#define SO_ATMPVC __SO_ENCODE(SOL_ATM,4,struct sockaddr_atmpvc)
+
+#define SO_MULTIPOINT __SO_ENCODE(SOL_ATM, 5, int)
+
+#define ATM_HDR_GFC_MASK 0xf0000000
+#define ATM_HDR_GFC_SHIFT 28
+#define ATM_HDR_VPI_MASK 0x0ff00000
+#define ATM_HDR_VPI_SHIFT 20
+#define ATM_HDR_VCI_MASK 0x000ffff0
+#define ATM_HDR_VCI_SHIFT 4
+#define ATM_HDR_PTI_MASK 0x0000000e
+#define ATM_HDR_PTI_SHIFT 1
+#define ATM_HDR_CLP 0x00000001
+
+#define ATM_PTI_US0 0  
+#define ATM_PTI_US1 1  
+#define ATM_PTI_UCES0 2  
+#define ATM_PTI_UCES1 3  
+#define ATM_PTI_SEGF5 4  
+#define ATM_PTI_E2EF5 5  
+#define ATM_PTI_RSV_RM 6  
+#define ATM_PTI_RSV 7  
+
+#define ATM_NONE 0  
+#define ATM_UBR 1
+#define ATM_CBR 2
+#define ATM_VBR 3
+#define ATM_ABR 4
+#define ATM_ANYCLASS 5  
+
+#define ATM_MAX_PCR -1  
+
+struct atm_trafprm {
+ unsigned char traffic_class;
+ int max_pcr;
+ int pcr;
+ int min_pcr;
+ int max_cdv;
+ int max_sdu;
+
+ unsigned int icr;
+ unsigned int tbe;
+ unsigned int frtt : 24;
+ unsigned int rif : 4;
+ unsigned int rdf : 4;
+ unsigned int nrm_pres :1;
+ unsigned int trm_pres :1;
+ unsigned int adtf_pres :1;
+ unsigned int cdf_pres :1;
+ unsigned int nrm :3;
+ unsigned int trm :3;
+ unsigned int adtf :10;
+ unsigned int cdf :3;
+ unsigned int spare :9;
+};
+
+struct atm_qos {
+ struct atm_trafprm txtp;
+ struct atm_trafprm rxtp __ATM_API_ALIGN;
+
+ unsigned char aal __ATM_API_ALIGN;
+};
+
+#define ATM_ITF_ANY -1  
+#define ATM_VPI_ANY -1
+#define ATM_VCI_ANY -1
+#define ATM_VPI_UNSPEC -2
+#define ATM_VCI_UNSPEC -2
+
+struct sockaddr_atmpvc {
+ unsigned short sap_family;
+ struct {
+ short itf;
+ short vpi;
+ int vci;
+ } sap_addr __ATM_API_ALIGN;
+};
+
+#define ATM_ESA_LEN 20  
+#define ATM_E164_LEN 12  
+
+#define ATM_AFI_DCC 0x39  
+#define ATM_AFI_ICD 0x47  
+#define ATM_AFI_E164 0x45  
+#define ATM_AFI_LOCAL 0x49   
+
+#define ATM_AFI_DCC_GROUP 0xBD  
+#define ATM_AFI_ICD_GROUP 0xC5  
+#define ATM_AFI_E164_GROUP 0xC3  
+#define ATM_AFI_LOCAL_GROUP 0xC7  
+
+#define ATM_LIJ_NONE 0  
+#define ATM_LIJ 1  
+#define ATM_LIJ_RPJ 2  
+#define ATM_LIJ_NJ 3  
+
+struct sockaddr_atmsvc {
+ unsigned short sas_family;
+ struct {
+ unsigned char prv[ATM_ESA_LEN];
+ char pub[ATM_E164_LEN+1];
+
+ char lij_type;
+ uint32_t lij_id;
+ } sas_addr __ATM_API_ALIGN;
+};
+
+typedef unsigned short atm_backend_t;
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/atmapi.h b/ndk/build/platforms/android-1.5/common/include/linux/atmapi.h
new file mode 100644
index 0000000..bee5cae
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/atmapi.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ATMAPI_H
+#define _LINUX_ATMAPI_H
+
+#if defined(__sparc__) || defined(__ia64__)
+
+#define __ATM_API_ALIGN __attribute__((aligned(8)))
+#else
+#define __ATM_API_ALIGN
+#endif
+
+typedef struct { unsigned char _[8]; } __ATM_API_ALIGN atm_kptr_t;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/atmdev.h b/ndk/build/platforms/android-1.5/common/include/linux/atmdev.h
new file mode 100644
index 0000000..27baeb0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/atmdev.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_ATMDEV_H
+#define LINUX_ATMDEV_H
+
+#include <linux/atmapi.h>
+#include <linux/atm.h>
+#include <linux/atmioc.h>
+
+#define ESI_LEN 6
+
+#define ATM_OC3_PCR (155520000/270*260/8/53)
+
+#define ATM_25_PCR ((25600000/8-8000)/54)
+
+#define ATM_OC12_PCR (622080000/1080*1040/8/53)
+
+#define ATM_DS3_PCR (8000*12)
+
+#define __AAL_STAT_ITEMS   __HANDLE_ITEM(tx);     __HANDLE_ITEM(tx_err);     __HANDLE_ITEM(rx);     __HANDLE_ITEM(rx_err);     __HANDLE_ITEM(rx_drop);  
+
+struct atm_aal_stats {
+#define __HANDLE_ITEM(i) int i
+ __AAL_STAT_ITEMS
+#undef __HANDLE_ITEM
+};
+
+struct atm_dev_stats {
+ struct atm_aal_stats aal0;
+ struct atm_aal_stats aal34;
+ struct atm_aal_stats aal5;
+} __ATM_API_ALIGN;
+
+#define ATM_GETLINKRATE _IOW('a',ATMIOC_ITF+1,struct atmif_sioc)
+
+#define ATM_GETNAMES _IOW('a',ATMIOC_ITF+3,struct atm_iobuf)
+
+#define ATM_GETTYPE _IOW('a',ATMIOC_ITF+4,struct atmif_sioc)
+
+#define ATM_GETESI _IOW('a',ATMIOC_ITF+5,struct atmif_sioc)
+
+#define ATM_GETADDR _IOW('a',ATMIOC_ITF+6,struct atmif_sioc)
+
+#define ATM_RSTADDR _IOW('a',ATMIOC_ITF+7,struct atmif_sioc)
+
+#define ATM_ADDADDR _IOW('a',ATMIOC_ITF+8,struct atmif_sioc)
+
+#define ATM_DELADDR _IOW('a',ATMIOC_ITF+9,struct atmif_sioc)
+
+#define ATM_GETCIRANGE _IOW('a',ATMIOC_ITF+10,struct atmif_sioc)
+
+#define ATM_SETCIRANGE _IOW('a',ATMIOC_ITF+11,struct atmif_sioc)
+
+#define ATM_SETESI _IOW('a',ATMIOC_ITF+12,struct atmif_sioc)
+
+#define ATM_SETESIF _IOW('a',ATMIOC_ITF+13,struct atmif_sioc)
+
+#define ATM_ADDLECSADDR _IOW('a', ATMIOC_ITF+14, struct atmif_sioc)
+
+#define ATM_DELLECSADDR _IOW('a', ATMIOC_ITF+15, struct atmif_sioc)
+
+#define ATM_GETLECSADDR _IOW('a', ATMIOC_ITF+16, struct atmif_sioc)
+
+#define ATM_GETSTAT _IOW('a',ATMIOC_SARCOM+0,struct atmif_sioc)
+
+#define ATM_GETSTATZ _IOW('a',ATMIOC_SARCOM+1,struct atmif_sioc)
+
+#define ATM_GETLOOP _IOW('a',ATMIOC_SARCOM+2,struct atmif_sioc)
+
+#define ATM_SETLOOP _IOW('a',ATMIOC_SARCOM+3,struct atmif_sioc)
+
+#define ATM_QUERYLOOP _IOW('a',ATMIOC_SARCOM+4,struct atmif_sioc)
+
+#define ATM_SETSC _IOW('a',ATMIOC_SPECIAL+1,int)
+
+#define ATM_SETBACKEND _IOW('a',ATMIOC_SPECIAL+2,atm_backend_t)
+
+#define ATM_NEWBACKENDIF _IOW('a',ATMIOC_SPECIAL+3,atm_backend_t)
+
+#define ATM_ADDPARTY _IOW('a', ATMIOC_SPECIAL+4,struct atm_iobuf)
+
+#define ATM_DROPPARTY _IOW('a', ATMIOC_SPECIAL+5,int)
+
+#define ATM_BACKEND_RAW 0 
+#define ATM_BACKEND_PPP 1  
+#define ATM_BACKEND_BR2684 2  
+
+#define ATM_ITFTYP_LEN 8  
+
+#define __ATM_LM_NONE 0  
+#define __ATM_LM_AAL 1  
+#define __ATM_LM_ATM 2  
+
+#define __ATM_LM_PHY 8  
+#define __ATM_LM_ANALOG 16  
+
+#define __ATM_LM_MKLOC(n) ((n))  
+#define __ATM_LM_MKRMT(n) ((n) << 8)  
+
+#define __ATM_LM_XTLOC(n) ((n) & 0xff)
+#define __ATM_LM_XTRMT(n) (((n) >> 8) & 0xff)
+
+#define ATM_LM_NONE 0  
+
+#define ATM_LM_LOC_AAL __ATM_LM_MKLOC(__ATM_LM_AAL)
+#define ATM_LM_LOC_ATM __ATM_LM_MKLOC(__ATM_LM_ATM)
+#define ATM_LM_LOC_PHY __ATM_LM_MKLOC(__ATM_LM_PHY)
+#define ATM_LM_LOC_ANALOG __ATM_LM_MKLOC(__ATM_LM_ANALOG)
+
+#define ATM_LM_RMT_AAL __ATM_LM_MKRMT(__ATM_LM_AAL)
+#define ATM_LM_RMT_ATM __ATM_LM_MKRMT(__ATM_LM_ATM)
+#define ATM_LM_RMT_PHY __ATM_LM_MKRMT(__ATM_LM_PHY)
+#define ATM_LM_RMT_ANALOG __ATM_LM_MKRMT(__ATM_LM_ANALOG)
+
+struct atm_iobuf {
+ int length;
+ void __user *buffer;
+};
+
+#define ATM_CI_MAX -1  
+
+struct atm_cirange {
+ signed char vpi_bits;
+ signed char vci_bits;
+};
+
+#define ATM_SC_RX 1024  
+#define ATM_SC_TX 2048  
+
+#define ATM_BACKLOG_DEFAULT 32  
+
+#define ATM_MF_IMMED 1  
+#define ATM_MF_INC_RSV 2  
+#define ATM_MF_INC_SHP 4  
+#define ATM_MF_DEC_RSV 8  
+#define ATM_MF_DEC_SHP 16  
+#define ATM_MF_BWD 32  
+
+#define ATM_MF_SET (ATM_MF_INC_RSV | ATM_MF_INC_SHP | ATM_MF_DEC_RSV |   ATM_MF_DEC_SHP | ATM_MF_BWD)
+
+#define ATM_VS_IDLE 0  
+#define ATM_VS_CONNECTED 1  
+#define ATM_VS_CLOSING 2  
+#define ATM_VS_LISTEN 3  
+#define ATM_VS_INUSE 4  
+#define ATM_VS_BOUND 5  
+
+#define ATM_VS2TXT_MAP   "IDLE", "CONNECTED", "CLOSING", "LISTEN", "INUSE", "BOUND"
+
+#define ATM_VF2TXT_MAP   "ADDR", "READY", "PARTIAL", "REGIS",   "RELEASED", "HASQOS", "LISTEN", "META",   "256", "512", "1024", "2048",   "SESSION", "HASSAP", "BOUND", "CLOSE"
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/atmioc.h b/ndk/build/platforms/android-1.5/common/include/linux/atmioc.h
new file mode 100644
index 0000000..d004339
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/atmioc.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ATMIOC_H
+#define _LINUX_ATMIOC_H
+
+#include <asm/ioctl.h>
+
+#define ATMIOC_PHYCOM 0x00  
+#define ATMIOC_PHYCOM_END 0x0f
+#define ATMIOC_PHYTYP 0x10  
+#define ATMIOC_PHYTYP_END 0x2f
+#define ATMIOC_PHYPRV 0x30  
+#define ATMIOC_PHYPRV_END 0x4f
+#define ATMIOC_SARCOM 0x50  
+#define ATMIOC_SARCOM_END 0x50
+#define ATMIOC_SARPRV 0x60  
+#define ATMIOC_SARPRV_END 0x7f
+#define ATMIOC_ITF 0x80  
+#define ATMIOC_ITF_END 0x8f
+#define ATMIOC_BACKEND 0x90  
+#define ATMIOC_BACKEND_END 0xaf
+
+#define ATMIOC_AREQUIPA 0xc0  
+#define ATMIOC_LANE 0xd0  
+#define ATMIOC_MPOA 0xd8  
+#define ATMIOC_CLIP 0xe0  
+#define ATMIOC_CLIP_END 0xef
+#define ATMIOC_SPECIAL 0xf0  
+#define ATMIOC_SPECIAL_END 0xff
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/atmppp.h b/ndk/build/platforms/android-1.5/common/include/linux/atmppp.h
new file mode 100644
index 0000000..3330c32
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/atmppp.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ATMPPP_H
+#define _LINUX_ATMPPP_H
+
+#include <linux/atm.h>
+
+#define PPPOATM_ENCAPS_AUTODETECT (0)
+#define PPPOATM_ENCAPS_VC (1)
+#define PPPOATM_ENCAPS_LLC (2)
+
+struct atm_backend_ppp {
+ atm_backend_t backend_num;
+ int encaps;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/atmsap.h b/ndk/build/platforms/android-1.5/common/include/linux/atmsap.h
new file mode 100644
index 0000000..456f75f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/atmsap.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ATMSAP_H
+#define _LINUX_ATMSAP_H
+
+#include <linux/atmapi.h>
+
+#define ATM_L2_NONE 0  
+#define ATM_L2_ISO1745 0x01  
+#define ATM_L2_Q291 0x02  
+#define ATM_L2_X25_LL 0x06  
+#define ATM_L2_X25_ML 0x07  
+#define ATM_L2_LAPB 0x08  
+#define ATM_L2_HDLC_ARM 0x09  
+#define ATM_L2_HDLC_NRM 0x0a  
+#define ATM_L2_HDLC_ABM 0x0b  
+#define ATM_L2_ISO8802 0x0c  
+#define ATM_L2_X75 0x0d  
+#define ATM_L2_Q922 0x0e  
+#define ATM_L2_USER 0x10  
+#define ATM_L2_ISO7776 0x11  
+
+#define ATM_L3_NONE 0  
+#define ATM_L3_X25 0x06  
+#define ATM_L3_ISO8208 0x07  
+#define ATM_L3_X223 0x08  
+#define ATM_L3_ISO8473 0x09  
+#define ATM_L3_T70 0x0a  
+#define ATM_L3_TR9577 0x0b  
+#define ATM_L3_H310 0x0c  
+#define ATM_L3_H321 0x0d  
+#define ATM_L3_USER 0x10  
+
+#define ATM_HL_NONE 0  
+#define ATM_HL_ISO 0x01  
+#define ATM_HL_USER 0x02  
+#define ATM_HL_HLP 0x03  
+#define ATM_HL_VENDOR 0x04  
+
+#define ATM_IMD_NONE 0  
+#define ATM_IMD_NORMAL 1  
+#define ATM_IMD_EXTENDED 2  
+
+#define ATM_TT_NONE 0  
+#define ATM_TT_RX 1  
+#define ATM_TT_TX 2  
+#define ATM_TT_RXTX 3  
+
+#define ATM_MC_NONE 0  
+#define ATM_MC_TS 1  
+#define ATM_MC_TS_FEC 2  
+#define ATM_MC_PS 3  
+#define ATM_MC_PS_FEC 4  
+#define ATM_MC_H221 5  
+
+#define ATM_MAX_HLI 8  
+
+struct atm_blli {
+ unsigned char l2_proto;
+ union {
+ struct {
+ unsigned char mode;
+
+ unsigned char window;
+ } itu;
+ unsigned char user;
+ } l2;
+ unsigned char l3_proto;
+ union {
+ struct {
+ unsigned char mode;
+
+ unsigned char def_size;
+
+ unsigned char window;
+ } itu;
+ unsigned char user;
+ struct {
+ unsigned char term_type;
+ unsigned char fw_mpx_cap;
+
+ unsigned char bw_mpx_cap;
+
+ } h310;
+ struct {
+ unsigned char ipi;
+ unsigned char snap[5];
+
+ } tr9577;
+ } l3;
+} __ATM_API_ALIGN;
+
+struct atm_bhli {
+ unsigned char hl_type;
+ unsigned char hl_length;
+
+ unsigned char hl_info[ATM_MAX_HLI];
+};
+
+#define ATM_MAX_BLLI 3  
+
+struct atm_sap {
+ struct atm_bhli bhli;
+ struct atm_blli blli[ATM_MAX_BLLI] __ATM_API_ALIGN;
+
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/attribute_container.h b/ndk/build/platforms/android-1.5/common/include/linux/attribute_container.h
new file mode 100644
index 0000000..1a9bfb0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/attribute_container.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ATTRIBUTE_CONTAINER_H_
+#define _ATTRIBUTE_CONTAINER_H_
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/klist.h>
+#include <linux/spinlock.h>
+
+struct attribute_container {
+ struct list_head node;
+ struct klist containers;
+ struct class *class;
+ struct class_device_attribute **attrs;
+ int (*match)(struct attribute_container *, struct device *);
+#define ATTRIBUTE_CONTAINER_NO_CLASSDEVS 0x01
+ unsigned long flags;
+};
+
+struct attribute_container *attribute_container_classdev_to_container(struct class_device *);
+struct class_device *attribute_container_find_class_device(struct attribute_container *, struct device *);
+struct class_device_attribute **attribute_container_classdev_to_attrs(const struct class_device *classdev);
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/auto_fs.h b/ndk/build/platforms/android-1.5/common/include/linux/auto_fs.h
new file mode 100644
index 0000000..3711cc4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/auto_fs.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_AUTO_FS_H
+#define _LINUX_AUTO_FS_H
+
+#include <linux/ioctl.h>
+
+#define AUTOFS_PROTO_VERSION 3
+
+#define AUTOFS_MAX_PROTO_VERSION AUTOFS_PROTO_VERSION
+#define AUTOFS_MIN_PROTO_VERSION AUTOFS_PROTO_VERSION
+
+#if defined(__sparc__) || defined(__mips__) || defined(__x86_64__) || defined(__powerpc__) || defined(__s390__)
+typedef unsigned int autofs_wqt_t;
+#else
+typedef unsigned long autofs_wqt_t;
+#endif
+
+#define autofs_ptype_missing 0  
+#define autofs_ptype_expire 1  
+
+struct autofs_packet_hdr {
+ int proto_version;
+ int type;
+};
+
+struct autofs_packet_missing {
+ struct autofs_packet_hdr hdr;
+ autofs_wqt_t wait_queue_token;
+ int len;
+ char name[NAME_MAX+1];
+};
+
+struct autofs_packet_expire {
+ struct autofs_packet_hdr hdr;
+ int len;
+ char name[NAME_MAX+1];
+};
+
+#define AUTOFS_IOC_READY _IO(0x93,0x60)
+#define AUTOFS_IOC_FAIL _IO(0x93,0x61)
+#define AUTOFS_IOC_CATATONIC _IO(0x93,0x62)
+#define AUTOFS_IOC_PROTOVER _IOR(0x93,0x63,int)
+#define AUTOFS_IOC_SETTIMEOUT _IOWR(0x93,0x64,unsigned long)
+#define AUTOFS_IOC_EXPIRE _IOR(0x93,0x65,struct autofs_packet_expire)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/autoconf.h b/ndk/build/platforms/android-1.5/common/include/linux/autoconf.h
new file mode 100644
index 0000000..306bf12
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/autoconf.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_AUTOCONF_CRAP_GOES_HERE
+#define LINUX_AUTOCONF_CRAP_GOES_HERE
+
+#define AUTOCONF_INCLUDED
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/auxvec.h b/ndk/build/platforms/android-1.5/common/include/linux/auxvec.h
new file mode 100644
index 0000000..f8a0701
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/auxvec.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_AUXVEC_H
+#define _LINUX_AUXVEC_H
+
+#include <asm/auxvec.h>
+
+#define AT_NULL 0  
+#define AT_IGNORE 1  
+#define AT_EXECFD 2  
+#define AT_PHDR 3  
+#define AT_PHENT 4  
+#define AT_PHNUM 5  
+#define AT_PAGESZ 6  
+#define AT_BASE 7  
+#define AT_FLAGS 8  
+#define AT_ENTRY 9  
+#define AT_NOTELF 10  
+#define AT_UID 11  
+#define AT_EUID 12  
+#define AT_GID 13  
+#define AT_EGID 14  
+#define AT_PLATFORM 15  
+#define AT_HWCAP 16  
+#define AT_CLKTCK 17  
+
+#define AT_SECURE 23  
+
+#define AT_VECTOR_SIZE 44  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/backing-dev.h b/ndk/build/platforms/android-1.5/common/include/linux/backing-dev.h
new file mode 100644
index 0000000..4996d2c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/backing-dev.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_BACKING_DEV_H
+#define _LINUX_BACKING_DEV_H
+
+#include <asm/atomic.h>
+
+enum bdi_state {
+ BDI_pdflush,
+ BDI_write_congested,
+ BDI_read_congested,
+ BDI_unused,
+};
+
+typedef int (congested_fn)(void *, int);
+
+struct backing_dev_info {
+ unsigned long ra_pages;
+ unsigned long state;
+ unsigned int capabilities;
+ congested_fn *congested_fn;
+ void *congested_data;
+ void (*unplug_io_fn)(struct backing_dev_info *, struct page *);
+ void *unplug_io_data;
+};
+
+#define BDI_CAP_NO_ACCT_DIRTY 0x00000001  
+#define BDI_CAP_NO_WRITEBACK 0x00000002  
+#define BDI_CAP_MAP_COPY 0x00000004  
+#define BDI_CAP_MAP_DIRECT 0x00000008  
+#define BDI_CAP_READ_MAP 0x00000010  
+#define BDI_CAP_WRITE_MAP 0x00000020  
+#define BDI_CAP_EXEC_MAP 0x00000040  
+#define BDI_CAP_VMFLAGS   (BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP)
+
+#if defined(VM_MAYREAD) && BDI_CAP_READ_MAP != (VM_MAYREAD || BDI_CAP_WRITE_MAP != (VM_MAYWRITE || BDI_CAP_EXEC_MAP != VM_MAYEXEC))
+#error please change backing_dev_info::capabilities flags
+#endif
+
+#define bdi_cap_writeback_dirty(bdi)   (!((bdi)->capabilities & BDI_CAP_NO_WRITEBACK))
+#define bdi_cap_account_dirty(bdi)   (!((bdi)->capabilities & BDI_CAP_NO_ACCT_DIRTY))
+#define mapping_cap_writeback_dirty(mapping)   bdi_cap_writeback_dirty((mapping)->backing_dev_info)
+#define mapping_cap_account_dirty(mapping)   bdi_cap_account_dirty((mapping)->backing_dev_info)
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/binder.h b/ndk/build/platforms/android-1.5/common/include/linux/binder.h
new file mode 100644
index 0000000..b97eafb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/binder.h
@@ -0,0 +1,186 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_BINDER_H
+#define _LINUX_BINDER_H
+
+#include <linux/ioctl.h>
+
+#define B_PACK_CHARS(c1, c2, c3, c4)   ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4))
+#define B_TYPE_LARGE 0x85
+
+enum {
+ BINDER_TYPE_BINDER = B_PACK_CHARS('s', 'b', '*', B_TYPE_LARGE),
+ BINDER_TYPE_WEAK_BINDER = B_PACK_CHARS('w', 'b', '*', B_TYPE_LARGE),
+ BINDER_TYPE_HANDLE = B_PACK_CHARS('s', 'h', '*', B_TYPE_LARGE),
+ BINDER_TYPE_WEAK_HANDLE = B_PACK_CHARS('w', 'h', '*', B_TYPE_LARGE),
+ BINDER_TYPE_FD = B_PACK_CHARS('f', 'd', '*', B_TYPE_LARGE),
+};
+
+enum {
+ FLAT_BINDER_FLAG_PRIORITY_MASK = 0xff,
+ FLAT_BINDER_FLAG_ACCEPTS_FDS = 0x100,
+};
+
+struct flat_binder_object {
+
+ unsigned long type;
+ unsigned long flags;
+
+ union {
+ void *binder;
+ signed long handle;
+ };
+
+ void *cookie;
+};
+
+struct binder_write_read {
+ signed long write_size;
+ signed long write_consumed;
+ unsigned long write_buffer;
+ signed long read_size;
+ signed long read_consumed;
+ unsigned long read_buffer;
+};
+
+struct binder_version {
+
+ signed long protocol_version;
+};
+
+#define BINDER_CURRENT_PROTOCOL_VERSION 7
+
+#define BINDER_WRITE_READ _IOWR('b', 1, struct binder_write_read)
+#define BINDER_SET_IDLE_TIMEOUT _IOW('b', 3, int64_t)
+#define BINDER_SET_MAX_THREADS _IOW('b', 5, size_t)
+#define BINDER_SET_IDLE_PRIORITY _IOW('b', 6, int)
+#define BINDER_SET_CONTEXT_MGR _IOW('b', 7, int)
+#define BINDER_THREAD_EXIT _IOW('b', 8, int)
+#define BINDER_VERSION _IOWR('b', 9, struct binder_version)
+
+enum transaction_flags {
+ TF_ONE_WAY = 0x01,
+ TF_ROOT_OBJECT = 0x04,
+ TF_STATUS_CODE = 0x08,
+ TF_ACCEPT_FDS = 0x10,
+};
+
+struct binder_transaction_data {
+
+ union {
+ size_t handle;
+ void *ptr;
+ } target;
+ void *cookie;
+ unsigned int code;
+
+ unsigned int flags;
+ pid_t sender_pid;
+ uid_t sender_euid;
+ size_t data_size;
+ size_t offsets_size;
+
+ union {
+ struct {
+
+ const void *buffer;
+
+ const void *offsets;
+ } ptr;
+ uint8_t buf[8];
+ } data;
+};
+
+struct binder_ptr_cookie {
+ void *ptr;
+ void *cookie;
+};
+
+struct binder_pri_desc {
+ int priority;
+ int desc;
+};
+
+struct binder_pri_ptr_cookie {
+ int priority;
+ void *ptr;
+ void *cookie;
+};
+
+enum BinderDriverReturnProtocol {
+ BR_ERROR = _IOR_BAD('r', 0, int),
+
+ BR_OK = _IO('r', 1),
+
+ BR_TRANSACTION = _IOR_BAD('r', 2, struct binder_transaction_data),
+ BR_REPLY = _IOR_BAD('r', 3, struct binder_transaction_data),
+
+ BR_ACQUIRE_RESULT = _IOR_BAD('r', 4, int),
+
+ BR_DEAD_REPLY = _IO('r', 5),
+
+ BR_TRANSACTION_COMPLETE = _IO('r', 6),
+
+ BR_INCREFS = _IOR_BAD('r', 7, struct binder_ptr_cookie),
+ BR_ACQUIRE = _IOR_BAD('r', 8, struct binder_ptr_cookie),
+ BR_RELEASE = _IOR_BAD('r', 9, struct binder_ptr_cookie),
+ BR_DECREFS = _IOR_BAD('r', 10, struct binder_ptr_cookie),
+
+ BR_ATTEMPT_ACQUIRE = _IOR_BAD('r', 11, struct binder_pri_ptr_cookie),
+
+ BR_NOOP = _IO('r', 12),
+
+ BR_SPAWN_LOOPER = _IO('r', 13),
+
+ BR_FINISHED = _IO('r', 14),
+
+ BR_DEAD_BINDER = _IOR_BAD('r', 15, void *),
+
+ BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR_BAD('r', 16, void *),
+
+ BR_FAILED_REPLY = _IO('r', 17),
+
+};
+
+enum BinderDriverCommandProtocol {
+ BC_TRANSACTION = _IOW_BAD('c', 0, struct binder_transaction_data),
+ BC_REPLY = _IOW_BAD('c', 1, struct binder_transaction_data),
+
+ BC_ACQUIRE_RESULT = _IOW_BAD('c', 2, int),
+
+ BC_FREE_BUFFER = _IOW_BAD('c', 3, int),
+
+ BC_INCREFS = _IOW_BAD('c', 4, int),
+ BC_ACQUIRE = _IOW_BAD('c', 5, int),
+ BC_RELEASE = _IOW_BAD('c', 6, int),
+ BC_DECREFS = _IOW_BAD('c', 7, int),
+
+ BC_INCREFS_DONE = _IOW_BAD('c', 8, struct binder_ptr_cookie),
+ BC_ACQUIRE_DONE = _IOW_BAD('c', 9, struct binder_ptr_cookie),
+
+ BC_ATTEMPT_ACQUIRE = _IOW_BAD('c', 10, struct binder_pri_desc),
+
+ BC_REGISTER_LOOPER = _IO('c', 11),
+
+ BC_ENTER_LOOPER = _IO('c', 12),
+ BC_EXIT_LOOPER = _IO('c', 13),
+
+ BC_REQUEST_DEATH_NOTIFICATION = _IOW_BAD('c', 14, struct binder_ptr_cookie),
+
+ BC_CLEAR_DEATH_NOTIFICATION = _IOW_BAD('c', 15, struct binder_ptr_cookie),
+
+ BC_DEAD_BINDER_DONE = _IOW_BAD('c', 16, void *),
+
+};
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/binfmts.h b/ndk/build/platforms/android-1.5/common/include/linux/binfmts.h
new file mode 100644
index 0000000..3335985
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/binfmts.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_BINFMTS_H
+#define _LINUX_BINFMTS_H
+
+#include <linux/capability.h>
+
+struct pt_regs;
+
+#define MAX_ARG_PAGES 32
+
+#define BINPRM_BUF_SIZE 128
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/bio.h b/ndk/build/platforms/android-1.5/common/include/linux/bio.h
new file mode 100644
index 0000000..4e91314
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/bio.h
@@ -0,0 +1,171 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_BIO_H
+#define __LINUX_BIO_H
+
+#include <linux/highmem.h>
+#include <linux/mempool.h>
+#include <linux/ioprio.h>
+
+#include <asm/io.h>
+
+#if defined(BIO_VMERGE_MAX_SIZE) && defined(BIO_VMERGE_BOUNDARY)
+#define BIOVEC_VIRT_START_SIZE(x) (bvec_to_phys(x) & (BIO_VMERGE_BOUNDARY - 1))
+#define BIOVEC_VIRT_OVERSIZE(x) ((x) > BIO_VMERGE_MAX_SIZE)
+#else
+#define BIOVEC_VIRT_START_SIZE(x) 0
+#define BIOVEC_VIRT_OVERSIZE(x) 0
+#endif
+
+#ifndef BIO_VMERGE_BOUNDARY
+#define BIO_VMERGE_BOUNDARY 0
+#endif
+
+#define BIO_DEBUG
+
+#ifdef BIO_DEBUG
+#define BIO_BUG_ON BUG_ON
+#else
+#define BIO_BUG_ON
+#endif
+
+#define BIO_MAX_PAGES 256
+#define BIO_MAX_SIZE (BIO_MAX_PAGES << PAGE_CACHE_SHIFT)
+#define BIO_MAX_SECTORS (BIO_MAX_SIZE >> 9)
+
+struct bio_vec {
+ struct page *bv_page;
+ unsigned int bv_len;
+ unsigned int bv_offset;
+};
+
+struct bio_set;
+struct bio;
+typedef int (bio_end_io_t) (struct bio *, unsigned int, int);
+typedef void (bio_destructor_t) (struct bio *);
+
+struct bio {
+ sector_t bi_sector;
+ struct bio *bi_next;
+ struct block_device *bi_bdev;
+ unsigned long bi_flags;
+ unsigned long bi_rw;
+
+ unsigned short bi_vcnt;
+ unsigned short bi_idx;
+
+ unsigned short bi_phys_segments;
+
+ unsigned short bi_hw_segments;
+
+ unsigned int bi_size;
+
+ unsigned int bi_hw_front_size;
+ unsigned int bi_hw_back_size;
+
+ unsigned int bi_max_vecs;
+
+ struct bio_vec *bi_io_vec;
+
+ bio_end_io_t *bi_end_io;
+ atomic_t bi_cnt;
+
+ void *bi_private;
+
+ bio_destructor_t *bi_destructor;
+};
+
+#define BIO_UPTODATE 0  
+#define BIO_RW_BLOCK 1  
+#define BIO_EOF 2  
+#define BIO_SEG_VALID 3  
+#define BIO_CLONED 4  
+#define BIO_BOUNCED 5  
+#define BIO_USER_MAPPED 6  
+#define BIO_EOPNOTSUPP 7  
+#define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag)))
+
+#define BIO_POOL_BITS (4)
+#define BIO_POOL_OFFSET (BITS_PER_LONG - BIO_POOL_BITS)
+#define BIO_POOL_MASK (1UL << BIO_POOL_OFFSET)
+#define BIO_POOL_IDX(bio) ((bio)->bi_flags >> BIO_POOL_OFFSET) 
+
+#define BIO_RW 0
+#define BIO_RW_AHEAD 1
+#define BIO_RW_BARRIER 2
+#define BIO_RW_FAILFAST 3
+#define BIO_RW_SYNC 4
+
+#define BIO_PRIO_SHIFT (8 * sizeof(unsigned long) - IOPRIO_BITS)
+#define bio_prio(bio) ((bio)->bi_rw >> BIO_PRIO_SHIFT)
+#define bio_prio_valid(bio) ioprio_valid(bio_prio(bio))
+
+#define bio_set_prio(bio, prio) do {   WARN_ON(prio >= (1 << IOPRIO_BITS));   (bio)->bi_rw &= ((1UL << BIO_PRIO_SHIFT) - 1);   (bio)->bi_rw |= ((unsigned long) (prio) << BIO_PRIO_SHIFT);  } while (0)
+
+#define bio_iovec_idx(bio, idx) (&((bio)->bi_io_vec[(idx)]))
+#define bio_iovec(bio) bio_iovec_idx((bio), (bio)->bi_idx)
+#define bio_page(bio) bio_iovec((bio))->bv_page
+#define bio_offset(bio) bio_iovec((bio))->bv_offset
+#define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx)
+#define bio_sectors(bio) ((bio)->bi_size >> 9)
+#define bio_cur_sectors(bio) (bio_iovec(bio)->bv_len >> 9)
+#define bio_data(bio) (page_address(bio_page((bio))) + bio_offset((bio)))
+#define bio_barrier(bio) ((bio)->bi_rw & (1 << BIO_RW_BARRIER))
+#define bio_sync(bio) ((bio)->bi_rw & (1 << BIO_RW_SYNC))
+#define bio_failfast(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST))
+#define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD))
+
+#define bio_to_phys(bio) (page_to_phys(bio_page((bio))) + (unsigned long) bio_offset((bio)))
+#define bvec_to_phys(bv) (page_to_phys((bv)->bv_page) + (unsigned long) (bv)->bv_offset)
+
+#define __bio_kmap_atomic(bio, idx, kmtype)   (kmap_atomic(bio_iovec_idx((bio), (idx))->bv_page, kmtype) +   bio_iovec_idx((bio), (idx))->bv_offset)
+
+#define __bio_kunmap_atomic(addr, kmtype) kunmap_atomic(addr, kmtype)
+
+#define __BVEC_END(bio) bio_iovec_idx((bio), (bio)->bi_vcnt - 1)
+#define __BVEC_START(bio) bio_iovec_idx((bio), (bio)->bi_idx)
+
+#ifndef BIOVEC_PHYS_MERGEABLE
+#define BIOVEC_PHYS_MERGEABLE(vec1, vec2)   ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2)))
+#endif
+
+#define BIOVEC_VIRT_MERGEABLE(vec1, vec2)   ((((bvec_to_phys((vec1)) + (vec1)->bv_len) | bvec_to_phys((vec2))) & (BIO_VMERGE_BOUNDARY - 1)) == 0)
+#define __BIO_SEG_BOUNDARY(addr1, addr2, mask)   (((addr1) | (mask)) == (((addr2) - 1) | (mask)))
+#define BIOVEC_SEG_BOUNDARY(q, b1, b2)   __BIO_SEG_BOUNDARY(bvec_to_phys((b1)), bvec_to_phys((b2)) + (b2)->bv_len, (q)->seg_boundary_mask)
+#define BIO_SEG_BOUNDARY(q, b1, b2)   BIOVEC_SEG_BOUNDARY((q), __BVEC_END((b1)), __BVEC_START((b2)))
+
+#define bio_io_error(bio, bytes) bio_endio((bio), (bytes), -EIO)
+
+#define __bio_for_each_segment(bvl, bio, i, start_idx)   for (bvl = bio_iovec_idx((bio), (start_idx)), i = (start_idx);   i < (bio)->bi_vcnt;   bvl++, i++)
+
+#define bio_for_each_segment(bvl, bio, i)   __bio_for_each_segment(bvl, bio, i, (bio)->bi_idx)
+
+#define bio_get(bio) atomic_inc(&(bio)->bi_cnt)
+
+struct bio_pair {
+ struct bio bio1, bio2;
+ struct bio_vec bv1, bv2;
+ atomic_t cnt;
+ int error;
+};
+
+struct request_queue;
+
+struct sg_iovec;
+
+#define bvec_kmap_irq(bvec, flags) (page_address((bvec)->bv_page) + (bvec)->bv_offset)
+#define bvec_kunmap_irq(buf, flags) do { *(flags) = 0; } while (0)
+
+#define __bio_kunmap_irq(buf, flags) bvec_kunmap_irq(buf, flags)
+#define bio_kmap_irq(bio, flags)   __bio_kmap_irq((bio), (bio)->bi_idx, (flags))
+#define bio_kunmap_irq(buf,flags) __bio_kunmap_irq(buf, flags)
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/bitmap.h b/ndk/build/platforms/android-1.5/common/include/linux/bitmap.h
new file mode 100644
index 0000000..246d158
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/bitmap.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_BITMAP_H
+#define __LINUX_BITMAP_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/string.h>
+
+#define BITMAP_LAST_WORD_MASK(nbits)  (   ((nbits) % BITS_PER_LONG) ?   (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL  )
+
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/bitops.h b/ndk/build/platforms/android-1.5/common/include/linux/bitops.h
new file mode 100644
index 0000000..f8df614
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/bitops.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_BITOPS_H
+#define _LINUX_BITOPS_H
+#include <asm/types.h>
+
+#include <asm/bitops.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/blkdev.h b/ndk/build/platforms/android-1.5/common/include/linux/blkdev.h
new file mode 100644
index 0000000..3004524
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/blkdev.h
@@ -0,0 +1,461 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_BLKDEV_H
+#define _LINUX_BLKDEV_H
+
+#include <linux/major.h>
+#include <linux/genhd.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <linux/pagemap.h>
+#include <linux/backing-dev.h>
+#include <linux/wait.h>
+#include <linux/mempool.h>
+#include <linux/bio.h>
+#include <linux/module.h>
+#include <linux/stringify.h>
+
+#include <asm/scatterlist.h>
+
+struct scsi_ioctl_command;
+
+struct request_queue;
+typedef struct request_queue request_queue_t;
+struct elevator_queue;
+typedef struct elevator_queue elevator_t;
+struct request_pm_state;
+struct blk_trace;
+
+#define BLKDEV_MIN_RQ 4
+#define BLKDEV_MAX_RQ 128  
+
+struct as_io_context {
+ spinlock_t lock;
+
+ void (*dtor)(struct as_io_context *aic);
+ void (*exit)(struct as_io_context *aic);
+
+ unsigned long state;
+ atomic_t nr_queued;
+ atomic_t nr_dispatched;
+
+ unsigned long last_end_request;
+ unsigned long ttime_total;
+ unsigned long ttime_samples;
+ unsigned long ttime_mean;
+
+ unsigned int seek_samples;
+ sector_t last_request_pos;
+ u64 seek_total;
+ sector_t seek_mean;
+};
+
+struct cfq_queue;
+struct cfq_io_context {
+ struct rb_node rb_node;
+ void *key;
+
+ struct cfq_queue *cfqq[2];
+
+ struct io_context *ioc;
+
+ unsigned long last_end_request;
+ sector_t last_request_pos;
+ unsigned long last_queue;
+
+ unsigned long ttime_total;
+ unsigned long ttime_samples;
+ unsigned long ttime_mean;
+
+ unsigned int seek_samples;
+ u64 seek_total;
+ sector_t seek_mean;
+
+ struct list_head queue_list;
+
+ void (*dtor)(struct io_context *);
+ void (*exit)(struct io_context *);
+};
+
+struct io_context {
+ atomic_t refcount;
+ struct task_struct *task;
+
+ int (*set_ioprio)(struct io_context *, unsigned int);
+
+ unsigned long last_waited;
+ int nr_batch_requests;
+
+ struct as_io_context *aic;
+ struct rb_root cic_root;
+};
+
+struct io_context *current_io_context(gfp_t gfp_flags);
+struct io_context *get_io_context(gfp_t gfp_flags);
+
+struct request;
+typedef void (rq_end_io_fn)(struct request *, int);
+
+struct request_list {
+ int count[2];
+ int starved[2];
+ int elvpriv;
+ mempool_t *rq_pool;
+ wait_queue_head_t wait[2];
+};
+
+#define BLK_MAX_CDB 16
+
+struct request {
+ struct list_head queuelist;
+ struct list_head donelist;
+
+ unsigned long flags;
+
+ sector_t sector;
+ unsigned long nr_sectors;
+
+ unsigned int current_nr_sectors;
+
+ sector_t hard_sector;
+ unsigned long hard_nr_sectors;
+
+ unsigned int hard_cur_sectors;
+
+ struct bio *bio;
+ struct bio *biotail;
+
+ void *elevator_private;
+ void *completion_data;
+
+ int rq_status;
+ int errors;
+ struct gendisk *rq_disk;
+ unsigned long start_time;
+
+ unsigned short nr_phys_segments;
+
+ unsigned short nr_hw_segments;
+
+ unsigned short ioprio;
+
+ int tag;
+
+ int ref_count;
+ request_queue_t *q;
+ struct request_list *rl;
+
+ struct completion *waiting;
+ void *special;
+ char *buffer;
+
+ unsigned int cmd_len;
+ unsigned char cmd[BLK_MAX_CDB];
+
+ unsigned int data_len;
+ unsigned int sense_len;
+ void *data;
+ void *sense;
+
+ unsigned int timeout;
+ int retries;
+
+ rq_end_io_fn *end_io;
+ void *end_io_data;
+};
+
+enum rq_flag_bits {
+ __REQ_RW,
+ __REQ_FAILFAST,
+ __REQ_SORTED,
+ __REQ_SOFTBARRIER,
+ __REQ_HARDBARRIER,
+ __REQ_FUA,
+ __REQ_CMD,
+ __REQ_NOMERGE,
+ __REQ_STARTED,
+ __REQ_DONTPREP,
+ __REQ_QUEUED,
+ __REQ_ELVPRIV,
+
+ __REQ_PC,
+ __REQ_BLOCK_PC,
+ __REQ_SENSE,
+
+ __REQ_FAILED,
+ __REQ_QUIET,
+ __REQ_SPECIAL,
+ __REQ_DRIVE_CMD,
+ __REQ_DRIVE_TASK,
+ __REQ_DRIVE_TASKFILE,
+ __REQ_PREEMPT,
+ __REQ_PM_SUSPEND,
+ __REQ_PM_RESUME,
+ __REQ_PM_SHUTDOWN,
+ __REQ_ORDERED_COLOR,
+ __REQ_RW_SYNC,
+ __REQ_NR_BITS,
+};
+
+#define REQ_RW (1 << __REQ_RW)
+#define REQ_FAILFAST (1 << __REQ_FAILFAST)
+#define REQ_SORTED (1 << __REQ_SORTED)
+#define REQ_SOFTBARRIER (1 << __REQ_SOFTBARRIER)
+#define REQ_HARDBARRIER (1 << __REQ_HARDBARRIER)
+#define REQ_FUA (1 << __REQ_FUA)
+#define REQ_CMD (1 << __REQ_CMD)
+#define REQ_NOMERGE (1 << __REQ_NOMERGE)
+#define REQ_STARTED (1 << __REQ_STARTED)
+#define REQ_DONTPREP (1 << __REQ_DONTPREP)
+#define REQ_QUEUED (1 << __REQ_QUEUED)
+#define REQ_ELVPRIV (1 << __REQ_ELVPRIV)
+#define REQ_PC (1 << __REQ_PC)
+#define REQ_BLOCK_PC (1 << __REQ_BLOCK_PC)
+#define REQ_SENSE (1 << __REQ_SENSE)
+#define REQ_FAILED (1 << __REQ_FAILED)
+#define REQ_QUIET (1 << __REQ_QUIET)
+#define REQ_SPECIAL (1 << __REQ_SPECIAL)
+#define REQ_DRIVE_CMD (1 << __REQ_DRIVE_CMD)
+#define REQ_DRIVE_TASK (1 << __REQ_DRIVE_TASK)
+#define REQ_DRIVE_TASKFILE (1 << __REQ_DRIVE_TASKFILE)
+#define REQ_PREEMPT (1 << __REQ_PREEMPT)
+#define REQ_PM_SUSPEND (1 << __REQ_PM_SUSPEND)
+#define REQ_PM_RESUME (1 << __REQ_PM_RESUME)
+#define REQ_PM_SHUTDOWN (1 << __REQ_PM_SHUTDOWN)
+#define REQ_ORDERED_COLOR (1 << __REQ_ORDERED_COLOR)
+#define REQ_RW_SYNC (1 << __REQ_RW_SYNC)
+
+struct request_pm_state
+{
+
+ int pm_step;
+
+ u32 pm_state;
+ void* data;
+};
+
+#include <linux/elevator.h>
+
+typedef int (merge_request_fn) (request_queue_t *, struct request *,
+ struct bio *);
+typedef int (merge_requests_fn) (request_queue_t *, struct request *,
+ struct request *);
+typedef void (request_fn_proc) (request_queue_t *q);
+typedef int (make_request_fn) (request_queue_t *q, struct bio *bio);
+typedef int (prep_rq_fn) (request_queue_t *, struct request *);
+typedef void (unplug_fn) (request_queue_t *);
+
+struct bio_vec;
+typedef int (merge_bvec_fn) (request_queue_t *, struct bio *, struct bio_vec *);
+typedef void (activity_fn) (void *data, int rw);
+typedef int (issue_flush_fn) (request_queue_t *, struct gendisk *, sector_t *);
+typedef void (prepare_flush_fn) (request_queue_t *, struct request *);
+typedef void (softirq_done_fn)(struct request *);
+
+enum blk_queue_state {
+ Queue_down,
+ Queue_up,
+};
+
+struct blk_queue_tag {
+ struct request **tag_index;
+ unsigned long *tag_map;
+ struct list_head busy_list;
+ int busy;
+ int max_depth;
+ int real_max_depth;
+ atomic_t refcnt;
+};
+
+struct request_queue
+{
+
+ struct list_head queue_head;
+ struct request *last_merge;
+ elevator_t *elevator;
+
+ struct request_list rq;
+
+ request_fn_proc *request_fn;
+ merge_request_fn *back_merge_fn;
+ merge_request_fn *front_merge_fn;
+ merge_requests_fn *merge_requests_fn;
+ make_request_fn *make_request_fn;
+ prep_rq_fn *prep_rq_fn;
+ unplug_fn *unplug_fn;
+ merge_bvec_fn *merge_bvec_fn;
+ activity_fn *activity_fn;
+ issue_flush_fn *issue_flush_fn;
+ prepare_flush_fn *prepare_flush_fn;
+ softirq_done_fn *softirq_done_fn;
+
+ sector_t end_sector;
+ struct request *boundary_rq;
+
+ struct timer_list unplug_timer;
+ int unplug_thresh;
+ unsigned long unplug_delay;
+ struct work_struct unplug_work;
+
+ struct backing_dev_info backing_dev_info;
+
+ void *queuedata;
+
+ void *activity_data;
+
+ unsigned long bounce_pfn;
+ gfp_t bounce_gfp;
+
+ unsigned long queue_flags;
+
+ spinlock_t __queue_lock;
+ spinlock_t *queue_lock;
+
+ struct kobject kobj;
+
+ unsigned long nr_requests;
+ unsigned int nr_congestion_on;
+ unsigned int nr_congestion_off;
+ unsigned int nr_batching;
+
+ unsigned int max_sectors;
+ unsigned int max_hw_sectors;
+ unsigned short max_phys_segments;
+ unsigned short max_hw_segments;
+ unsigned short hardsect_size;
+ unsigned int max_segment_size;
+
+ unsigned long seg_boundary_mask;
+ unsigned int dma_alignment;
+
+ struct blk_queue_tag *queue_tags;
+
+ unsigned int nr_sorted;
+ unsigned int in_flight;
+
+ unsigned int sg_timeout;
+ unsigned int sg_reserved_size;
+ int node;
+
+ struct blk_trace *blk_trace;
+
+ unsigned int ordered, next_ordered, ordseq;
+ int orderr, ordcolor;
+ struct request pre_flush_rq, bar_rq, post_flush_rq;
+ struct request *orig_bar_rq;
+ unsigned int bi_size;
+
+ struct mutex sysfs_lock;
+};
+
+#define RQ_INACTIVE (-1)
+#define RQ_ACTIVE 1
+
+#define QUEUE_FLAG_CLUSTER 0  
+#define QUEUE_FLAG_QUEUED 1  
+#define QUEUE_FLAG_STOPPED 2  
+#define QUEUE_FLAG_READFULL 3  
+#define QUEUE_FLAG_WRITEFULL 4  
+#define QUEUE_FLAG_DEAD 5  
+#define QUEUE_FLAG_REENTER 6  
+#define QUEUE_FLAG_PLUGGED 7  
+#define QUEUE_FLAG_ELVSWITCH 8  
+
+enum {
+
+ QUEUE_ORDERED_NONE = 0x00,
+ QUEUE_ORDERED_DRAIN = 0x01,
+ QUEUE_ORDERED_TAG = 0x02,
+
+ QUEUE_ORDERED_PREFLUSH = 0x10,
+ QUEUE_ORDERED_POSTFLUSH = 0x20,
+ QUEUE_ORDERED_FUA = 0x40,
+
+ QUEUE_ORDERED_DRAIN_FLUSH = QUEUE_ORDERED_DRAIN |
+ QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_POSTFLUSH,
+ QUEUE_ORDERED_DRAIN_FUA = QUEUE_ORDERED_DRAIN |
+ QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_FUA,
+ QUEUE_ORDERED_TAG_FLUSH = QUEUE_ORDERED_TAG |
+ QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_POSTFLUSH,
+ QUEUE_ORDERED_TAG_FUA = QUEUE_ORDERED_TAG |
+ QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_FUA,
+
+ QUEUE_ORDSEQ_STARTED = 0x01,
+ QUEUE_ORDSEQ_DRAIN = 0x02,
+ QUEUE_ORDSEQ_PREFLUSH = 0x04,
+ QUEUE_ORDSEQ_BAR = 0x08,
+ QUEUE_ORDSEQ_POSTFLUSH = 0x10,
+ QUEUE_ORDSEQ_DONE = 0x20,
+};
+
+#define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
+#define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
+#define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
+#define blk_queue_flushing(q) ((q)->ordseq)
+
+#define blk_fs_request(rq) ((rq)->flags & REQ_CMD)
+#define blk_pc_request(rq) ((rq)->flags & REQ_BLOCK_PC)
+#define blk_noretry_request(rq) ((rq)->flags & REQ_FAILFAST)
+#define blk_rq_started(rq) ((rq)->flags & REQ_STARTED)
+
+#define blk_account_rq(rq) (blk_rq_started(rq) && blk_fs_request(rq))
+
+#define blk_pm_suspend_request(rq) ((rq)->flags & REQ_PM_SUSPEND)
+#define blk_pm_resume_request(rq) ((rq)->flags & REQ_PM_RESUME)
+#define blk_pm_request(rq)   ((rq)->flags & (REQ_PM_SUSPEND | REQ_PM_RESUME))
+
+#define blk_sorted_rq(rq) ((rq)->flags & REQ_SORTED)
+#define blk_barrier_rq(rq) ((rq)->flags & REQ_HARDBARRIER)
+#define blk_fua_rq(rq) ((rq)->flags & REQ_FUA)
+
+#define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist)
+
+#define rq_data_dir(rq) ((rq)->flags & 1)
+
+#define RQ_NOMERGE_FLAGS   (REQ_NOMERGE | REQ_STARTED | REQ_HARDBARRIER | REQ_SOFTBARRIER)
+#define rq_mergeable(rq)   (!((rq)->flags & RQ_NOMERGE_FLAGS) && blk_fs_request((rq)))
+#define blk_queue_headactive(q, head_active)
+#define BLKPREP_OK 0  
+#define BLKPREP_KILL 1  
+#define BLKPREP_DEFER 2  
+
+#define BLK_BOUNCE_HIGH ((u64)blk_max_low_pfn << PAGE_SHIFT)
+#define BLK_BOUNCE_ANY ((u64)blk_max_pfn << PAGE_SHIFT)
+#define BLK_BOUNCE_ISA (ISA_DMA_THRESHOLD)
+
+#define rq_for_each_bio(_bio, rq)   if ((rq->bio))   for (_bio = (rq)->bio; _bio; _bio = _bio->bi_next)
+
+#define end_io_error(uptodate) (unlikely((uptodate) <= 0))
+
+#define blk_queue_tag_depth(q) ((q)->queue_tags->busy)
+#define blk_queue_tag_queue(q) ((q)->queue_tags->busy < (q)->queue_tags->max_depth)
+#define blk_rq_tagged(rq) ((rq)->flags & REQ_QUEUED)
+
+#define MAX_PHYS_SEGMENTS 128
+#define MAX_HW_SEGMENTS 128
+#define SAFE_MAX_SECTORS 255
+#define BLK_DEF_MAX_SECTORS 1024
+
+#define MAX_SEGMENT_SIZE 65536
+
+#define blkdev_entry_to_request(entry) list_entry((entry), struct request, queuelist)
+
+#define blk_finished_io(nsects) do { } while (0)
+#define blk_started_io(nsects) do { } while (0)
+
+#define sector_div(n, b)(  {   int _res;   _res = (n) % (b);   (n) /= (b);   _res;  }  )
+
+#define MODULE_ALIAS_BLOCKDEV(major,minor)   MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor))
+#define MODULE_ALIAS_BLOCKDEV_MAJOR(major)   MODULE_ALIAS("block-major-" __stringify(major) "-*")
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/blkpg.h b/ndk/build/platforms/android-1.5/common/include/linux/blkpg.h
new file mode 100644
index 0000000..45a4a47
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/blkpg.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_BLKPG_H
+#define _LINUX_BLKPG_H
+
+#include <linux/compiler.h>
+#include <linux/ioctl.h>
+
+#define BLKPG _IO(0x12,105)
+
+struct blkpg_ioctl_arg {
+ int op;
+ int flags;
+ int datalen;
+ void __user *data;
+};
+
+#define BLKPG_ADD_PARTITION 1
+#define BLKPG_DEL_PARTITION 2
+
+#define BLKPG_DEVNAMELTH 64
+#define BLKPG_VOLNAMELTH 64
+
+struct blkpg_partition {
+ long long start;
+ long long length;
+ int pno;
+ char devname[BLKPG_DEVNAMELTH];
+ char volname[BLKPG_VOLNAMELTH];
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/blockgroup_lock.h b/ndk/build/platforms/android-1.5/common/include/linux/blockgroup_lock.h
new file mode 100644
index 0000000..c814020
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/blockgroup_lock.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_BLOCKGROUP_LOCK_H
+#define _LINUX_BLOCKGROUP_LOCK_H
+
+#include <linux/spinlock.h>
+#include <linux/cache.h>
+
+#define NR_BG_LOCKS 1
+
+struct bgl_lock {
+ spinlock_t lock;
+} ____cacheline_aligned_in_smp;
+
+struct blockgroup_lock {
+ struct bgl_lock locks[NR_BG_LOCKS];
+};
+
+#define sb_bgl_lock(sb, block_group)   (&(sb)->s_blockgroup_lock.locks[(block_group) & (NR_BG_LOCKS-1)].lock)
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/byteorder/big_endian.h b/ndk/build/platforms/android-1.5/common/include/linux/byteorder/big_endian.h
new file mode 100644
index 0000000..ee0d880
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/byteorder/big_endian.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_BYTEORDER_BIG_ENDIAN_H
+#define _LINUX_BYTEORDER_BIG_ENDIAN_H
+
+#ifndef __BIG_ENDIAN
+#define __BIG_ENDIAN 4321
+#endif
+#ifndef __BIG_ENDIAN_BITFIELD
+#define __BIG_ENDIAN_BITFIELD
+#endif
+
+#include <linux/types.h>
+#include <linux/byteorder/swab.h>
+
+#define __constant_htonl(x) ((__force __be32)(__u32)(x))
+#define __constant_ntohl(x) ((__force __u32)(__be32)(x))
+#define __constant_htons(x) ((__force __be16)(__u16)(x))
+#define __constant_ntohs(x) ((__force __u16)(__be16)(x))
+#define __constant_cpu_to_le64(x) ((__force __le64)___constant_swab64((x)))
+#define __constant_le64_to_cpu(x) ___constant_swab64((__force __u64)(__le64)(x))
+#define __constant_cpu_to_le32(x) ((__force __le32)___constant_swab32((x)))
+#define __constant_le32_to_cpu(x) ___constant_swab32((__force __u32)(__le32)(x))
+#define __constant_cpu_to_le16(x) ((__force __le16)___constant_swab16((x)))
+#define __constant_le16_to_cpu(x) ___constant_swab16((__force __u16)(__le16)(x))
+#define __constant_cpu_to_be64(x) ((__force __be64)(__u64)(x))
+#define __constant_be64_to_cpu(x) ((__force __u64)(__be64)(x))
+#define __constant_cpu_to_be32(x) ((__force __be32)(__u32)(x))
+#define __constant_be32_to_cpu(x) ((__force __u32)(__be32)(x))
+#define __constant_cpu_to_be16(x) ((__force __be16)(__u16)(x))
+#define __constant_be16_to_cpu(x) ((__force __u16)(__be16)(x))
+#define __cpu_to_le64(x) ((__force __le64)__swab64((x)))
+#define __le64_to_cpu(x) __swab64((__force __u64)(__le64)(x))
+#define __cpu_to_le32(x) ((__force __le32)__swab32((x)))
+#define __le32_to_cpu(x) __swab32((__force __u32)(__le32)(x))
+#define __cpu_to_le16(x) ((__force __le16)__swab16((x)))
+#define __le16_to_cpu(x) __swab16((__force __u16)(__le16)(x))
+#define __cpu_to_be64(x) ((__force __be64)(__u64)(x))
+#define __be64_to_cpu(x) ((__force __u64)(__be64)(x))
+#define __cpu_to_be32(x) ((__force __be32)(__u32)(x))
+#define __be32_to_cpu(x) ((__force __u32)(__be32)(x))
+#define __cpu_to_be16(x) ((__force __be16)(__u16)(x))
+#define __be16_to_cpu(x) ((__force __u16)(__be16)(x))
+
+#define __cpu_to_le64s(x) __swab64s((x))
+#define __le64_to_cpus(x) __swab64s((x))
+#define __cpu_to_le32s(x) __swab32s((x))
+#define __le32_to_cpus(x) __swab32s((x))
+#define __cpu_to_le16s(x) __swab16s((x))
+#define __le16_to_cpus(x) __swab16s((x))
+#define __cpu_to_be64s(x) do {} while (0)
+#define __be64_to_cpus(x) do {} while (0)
+#define __cpu_to_be32s(x) do {} while (0)
+#define __be32_to_cpus(x) do {} while (0)
+#define __cpu_to_be16s(x) do {} while (0)
+#define __be16_to_cpus(x) do {} while (0)
+#include <linux/byteorder/generic.h>
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/byteorder/generic.h b/ndk/build/platforms/android-1.5/common/include/linux/byteorder/generic.h
new file mode 100644
index 0000000..ac469ff
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/byteorder/generic.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_BYTEORDER_GENERIC_H
+#define _LINUX_BYTEORDER_GENERIC_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/byteorder/little_endian.h b/ndk/build/platforms/android-1.5/common/include/linux/byteorder/little_endian.h
new file mode 100644
index 0000000..2c26e9c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/byteorder/little_endian.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_BYTEORDER_LITTLE_ENDIAN_H
+#define _LINUX_BYTEORDER_LITTLE_ENDIAN_H
+
+#ifndef __LITTLE_ENDIAN
+#define __LITTLE_ENDIAN 1234
+#endif
+#ifndef __LITTLE_ENDIAN_BITFIELD
+#define __LITTLE_ENDIAN_BITFIELD
+#endif
+
+#include <linux/types.h>
+#include <linux/byteorder/swab.h>
+
+#define __constant_htonl(x) ((__force __be32)___constant_swab32((x)))
+#define __constant_ntohl(x) ___constant_swab32((__force __be32)(x))
+#define __constant_htons(x) ((__force __be16)___constant_swab16((x)))
+#define __constant_ntohs(x) ___constant_swab16((__force __be16)(x))
+#define __constant_cpu_to_le64(x) ((__force __le64)(__u64)(x))
+#define __constant_le64_to_cpu(x) ((__force __u64)(__le64)(x))
+#define __constant_cpu_to_le32(x) ((__force __le32)(__u32)(x))
+#define __constant_le32_to_cpu(x) ((__force __u32)(__le32)(x))
+#define __constant_cpu_to_le16(x) ((__force __le16)(__u16)(x))
+#define __constant_le16_to_cpu(x) ((__force __u16)(__le16)(x))
+#define __constant_cpu_to_be64(x) ((__force __be64)___constant_swab64((x)))
+#define __constant_be64_to_cpu(x) ___constant_swab64((__force __u64)(__be64)(x))
+#define __constant_cpu_to_be32(x) ((__force __be32)___constant_swab32((x)))
+#define __constant_be32_to_cpu(x) ___constant_swab32((__force __u32)(__be32)(x))
+#define __constant_cpu_to_be16(x) ((__force __be16)___constant_swab16((x)))
+#define __constant_be16_to_cpu(x) ___constant_swab16((__force __u16)(__be16)(x))
+#define __cpu_to_le64(x) ((__force __le64)(__u64)(x))
+#define __le64_to_cpu(x) ((__force __u64)(__le64)(x))
+#define __cpu_to_le32(x) ((__force __le32)(__u32)(x))
+#define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
+#define __cpu_to_le16(x) ((__force __le16)(__u16)(x))
+#define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
+#define __cpu_to_be64(x) ((__force __be64)__swab64((x)))
+#define __be64_to_cpu(x) __swab64((__force __u64)(__be64)(x))
+#define __cpu_to_be32(x) ((__force __be32)__swab32((x)))
+#define __be32_to_cpu(x) __swab32((__force __u32)(__be32)(x))
+#define __cpu_to_be16(x) ((__force __be16)__swab16((x)))
+#define __be16_to_cpu(x) __swab16((__force __u16)(__be16)(x))
+
+#define __cpu_to_le64s(x) do {} while (0)
+#define __le64_to_cpus(x) do {} while (0)
+#define __cpu_to_le32s(x) do {} while (0)
+#define __le32_to_cpus(x) do {} while (0)
+#define __cpu_to_le16s(x) do {} while (0)
+#define __le16_to_cpus(x) do {} while (0)
+#define __cpu_to_be64s(x) __swab64s((x))
+#define __be64_to_cpus(x) __swab64s((x))
+#define __cpu_to_be32s(x) __swab32s((x))
+#define __be32_to_cpus(x) __swab32s((x))
+#define __cpu_to_be16s(x) __swab16s((x))
+#define __be16_to_cpus(x) __swab16s((x))
+#include <linux/byteorder/generic.h>
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/byteorder/swab.h b/ndk/build/platforms/android-1.5/common/include/linux/byteorder/swab.h
new file mode 100644
index 0000000..37336b5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/byteorder/swab.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_BYTEORDER_SWAB_H
+#define _LINUX_BYTEORDER_SWAB_H
+
+#include <linux/compiler.h>
+
+#define ___swab16(x)  ({   __u16 __x = (x);   ((__u16)(   (((__u16)(__x) & (__u16)0x00ffU) << 8) |   (((__u16)(__x) & (__u16)0xff00U) >> 8) ));  })
+
+#define ___swab32(x)  ({   __u32 __x = (x);   ((__u32)(   (((__u32)(__x) & (__u32)0x000000ffUL) << 24) |   (((__u32)(__x) & (__u32)0x0000ff00UL) << 8) |   (((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) |   (((__u32)(__x) & (__u32)0xff000000UL) >> 24) ));  })
+
+#define ___swab64(x)  ({   __u64 __x = (x);   ((__u64)(   (__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) |   (__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) |   (__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) |   (__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) |   (__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) |   (__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) |   (__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) |   (__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) ));  })
+
+#define ___constant_swab16(x)   ((__u16)(   (((__u16)(x) & (__u16)0x00ffU) << 8) |   (((__u16)(x) & (__u16)0xff00U) >> 8) ))
+#define ___constant_swab32(x)   ((__u32)(   (((__u32)(x) & (__u32)0x000000ffUL) << 24) |   (((__u32)(x) & (__u32)0x0000ff00UL) << 8) |   (((__u32)(x) & (__u32)0x00ff0000UL) >> 8) |   (((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
+#define ___constant_swab64(x)   ((__u64)(   (__u64)(((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) |   (__u64)(((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) |   (__u64)(((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) |   (__u64)(((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) |   (__u64)(((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) |   (__u64)(((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) |   (__u64)(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) |   (__u64)(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56) ))
+
+#ifndef __arch__swab16
+#define __arch__swab16(x) ({ __u16 __tmp = (x) ; ___swab16(__tmp); })
+#endif
+#ifndef __arch__swab32
+#define __arch__swab32(x) ({ __u32 __tmp = (x) ; ___swab32(__tmp); })
+#endif
+#ifndef __arch__swab64
+#define __arch__swab64(x) ({ __u64 __tmp = (x) ; ___swab64(__tmp); })
+#endif
+
+#ifndef __arch__swab16p
+#define __arch__swab16p(x) __arch__swab16(*(x))
+#endif
+#ifndef __arch__swab32p
+#define __arch__swab32p(x) __arch__swab32(*(x))
+#endif
+#ifndef __arch__swab64p
+#define __arch__swab64p(x) __arch__swab64(*(x))
+#endif
+
+#ifndef __arch__swab16s
+#define __arch__swab16s(x) do { *(x) = __arch__swab16p((x)); } while (0)
+#endif
+#ifndef __arch__swab32s
+#define __arch__swab32s(x) do { *(x) = __arch__swab32p((x)); } while (0)
+#endif
+#ifndef __arch__swab64s
+#define __arch__swab64s(x) do { *(x) = __arch__swab64p((x)); } while (0)
+#endif
+
+#if defined(__GNUC__) && defined(__OPTIMIZE__)
+#define __swab16(x)  (__builtin_constant_p((__u16)(x)) ?   ___swab16((x)) :   __fswab16((x)))
+#define __swab32(x)  (__builtin_constant_p((__u32)(x)) ?   ___swab32((x)) :   __fswab32((x)))
+#define __swab64(x)  (__builtin_constant_p((__u64)(x)) ?   ___swab64((x)) :   __fswab64((x)))
+#else
+#define __swab16(x) __fswab16(x)
+#define __swab32(x) __fswab32(x)
+#define __swab64(x) __fswab64(x)
+#endif
+
+#ifdef __BYTEORDER_HAS_U64__
+#ifdef __SWAB_64_THRU_32__
+#else
+#endif
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/byteorder/swabb.h b/ndk/build/platforms/android-1.5/common/include/linux/byteorder/swabb.h
new file mode 100644
index 0000000..c5b6a3e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/byteorder/swabb.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_BYTEORDER_SWABB_H
+#define _LINUX_BYTEORDER_SWABB_H
+
+#define ___swahw32(x)  ({   __u32 __x = (x);   ((__u32)(   (((__u32)(__x) & (__u32)0x0000ffffUL) << 16) |   (((__u32)(__x) & (__u32)0xffff0000UL) >> 16) ));  })
+#define ___swahb32(x)  ({   __u32 __x = (x);   ((__u32)(   (((__u32)(__x) & (__u32)0x00ff00ffUL) << 8) |   (((__u32)(__x) & (__u32)0xff00ff00UL) >> 8) ));  })
+
+#define ___constant_swahw32(x)   ((__u32)(   (((__u32)(x) & (__u32)0x0000ffffUL) << 16) |   (((__u32)(x) & (__u32)0xffff0000UL) >> 16) ))
+#define ___constant_swahb32(x)   ((__u32)(   (((__u32)(x) & (__u32)0x00ff00ffUL) << 8) |   (((__u32)(x) & (__u32)0xff00ff00UL) >> 8) ))
+
+#ifndef __arch__swahw32
+#define __arch__swahw32(x) ___swahw32(x)
+#endif
+#ifndef __arch__swahb32
+#define __arch__swahb32(x) ___swahb32(x)
+#endif
+
+#ifndef __arch__swahw32p
+#define __arch__swahw32p(x) __swahw32(*(x))
+#endif
+#ifndef __arch__swahb32p
+#define __arch__swahb32p(x) __swahb32(*(x))
+#endif
+
+#ifndef __arch__swahw32s
+#define __arch__swahw32s(x) do { *(x) = __swahw32p((x)); } while (0)
+#endif
+#ifndef __arch__swahb32s
+#define __arch__swahb32s(x) do { *(x) = __swahb32p((x)); } while (0)
+#endif
+
+#if defined(__GNUC__) && defined(__OPTIMIZE__)
+#define __swahw32(x)  (__builtin_constant_p((__u32)(x)) ?   ___swahw32((x)) :   __fswahw32((x)))
+#define __swahb32(x)  (__builtin_constant_p((__u32)(x)) ?   ___swahb32((x)) :   __fswahb32((x)))
+#else
+#define __swahw32(x) __fswahw32(x)
+#define __swahb32(x) __fswahb32(x)
+#endif
+
+#ifdef __BYTEORDER_HAS_U64__
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/cache.h b/ndk/build/platforms/android-1.5/common/include/linux/cache.h
new file mode 100644
index 0000000..d281855
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/cache.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_CACHE_H
+#define __LINUX_CACHE_H
+
+#include <linux/kernel.h>
+#include <asm/cache.h>
+
+#ifndef L1_CACHE_ALIGN
+#define L1_CACHE_ALIGN(x) ALIGN(x, L1_CACHE_BYTES)
+#endif
+
+#ifndef SMP_CACHE_BYTES
+#define SMP_CACHE_BYTES L1_CACHE_BYTES
+#endif
+
+#ifndef __read_mostly
+#define __read_mostly
+#endif
+
+#ifndef ____cacheline_aligned
+#define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
+#endif
+
+#ifndef ____cacheline_aligned_in_smp
+#define ____cacheline_aligned_in_smp
+#endif
+
+#ifndef __cacheline_aligned
+#define __cacheline_aligned   __attribute__((__aligned__(SMP_CACHE_BYTES),   __section__(".data.cacheline_aligned")))
+#endif
+
+#ifndef __cacheline_aligned_in_smp
+#define __cacheline_aligned_in_smp
+#endif
+
+#ifndef INTERNODE_CACHE_SHIFT
+#define INTERNODE_CACHE_SHIFT L1_CACHE_SHIFT
+#endif
+
+#ifndef ____cacheline_internodealigned_in_smp
+#define ____cacheline_internodealigned_in_smp
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/calc64.h b/ndk/build/platforms/android-1.5/common/include/linux/calc64.h
new file mode 100644
index 0000000..9f726aa
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/calc64.h
@@ -0,0 +1,22 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_CALC64_H
+#define _LINUX_CALC64_H
+
+#include <linux/types.h>
+#include <asm/div64.h>
+
+#ifndef div_long_long_rem
+#define div_long_long_rem(dividend, divisor, remainder)   do_div_llr((dividend), divisor, remainder)
+
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/capability.h b/ndk/build/platforms/android-1.5/common/include/linux/capability.h
new file mode 100644
index 0000000..605bc27
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/capability.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_CAPABILITY_H
+#define _LINUX_CAPABILITY_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+#define _LINUX_CAPABILITY_VERSION 0x19980330
+
+typedef struct __user_cap_header_struct {
+ __u32 version;
+ int pid;
+} __user *cap_user_header_t;
+
+typedef struct __user_cap_data_struct {
+ __u32 effective;
+ __u32 permitted;
+ __u32 inheritable;
+} __user *cap_user_data_t;
+
+#define CAP_CHOWN 0
+
+#define CAP_DAC_OVERRIDE 1
+
+#define CAP_DAC_READ_SEARCH 2
+
+#define CAP_FOWNER 3
+
+#define CAP_FSETID 4
+
+#define CAP_FS_MASK 0x1f
+
+#define CAP_KILL 5
+
+#define CAP_SETGID 6
+
+#define CAP_SETUID 7
+
+#define CAP_SETPCAP 8
+
+#define CAP_LINUX_IMMUTABLE 9
+
+#define CAP_NET_BIND_SERVICE 10
+
+#define CAP_NET_BROADCAST 11
+
+#define CAP_NET_ADMIN 12
+
+#define CAP_NET_RAW 13
+
+#define CAP_IPC_LOCK 14
+
+#define CAP_IPC_OWNER 15
+
+#define CAP_SYS_MODULE 16
+
+#define CAP_SYS_RAWIO 17
+
+#define CAP_SYS_CHROOT 18
+
+#define CAP_SYS_PTRACE 19
+
+#define CAP_SYS_PACCT 20
+
+#define CAP_SYS_ADMIN 21
+
+#define CAP_SYS_BOOT 22
+
+#define CAP_SYS_NICE 23
+
+#define CAP_SYS_RESOURCE 24
+
+#define CAP_SYS_TIME 25
+
+#define CAP_SYS_TTY_CONFIG 26
+
+#define CAP_MKNOD 27
+
+#define CAP_LEASE 28
+
+#define CAP_AUDIT_WRITE 29
+
+#define CAP_AUDIT_CONTROL 30
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/capi.h b/ndk/build/platforms/android-1.5/common/include/linux/capi.h
new file mode 100644
index 0000000..5591cf6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/capi.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_CAPI_H__
+#define __LINUX_CAPI_H__
+
+#include <asm/types.h>
+#include <linux/ioctl.h>
+#include <linux/kernelcapi.h>
+
+typedef struct capi_register_params {
+ __u32 level3cnt;
+ __u32 datablkcnt;
+ __u32 datablklen;
+} capi_register_params;
+
+#define CAPI_REGISTER _IOW('C',0x01,struct capi_register_params)
+
+#define CAPI_MANUFACTURER_LEN 64
+
+#define CAPI_GET_MANUFACTURER _IOWR('C',0x06,int)  
+
+typedef struct capi_version {
+ __u32 majorversion;
+ __u32 minorversion;
+ __u32 majormanuversion;
+ __u32 minormanuversion;
+} capi_version;
+
+#define CAPI_GET_VERSION _IOWR('C',0x07,struct capi_version)
+
+#define CAPI_SERIAL_LEN 8
+#define CAPI_GET_SERIAL _IOWR('C',0x08,int)  
+
+typedef struct capi_profile {
+ __u16 ncontroller;
+ __u16 nbchannel;
+ __u32 goptions;
+ __u32 support1;
+ __u32 support2;
+ __u32 support3;
+ __u32 reserved[6];
+ __u32 manu[5];
+} capi_profile;
+
+#define CAPI_GET_PROFILE _IOWR('C',0x09,struct capi_profile)
+
+typedef struct capi_manufacturer_cmd {
+ unsigned long cmd;
+ void __user *data;
+} capi_manufacturer_cmd;
+
+#define CAPI_MANUFACTURER_CMD _IOWR('C',0x20, struct capi_manufacturer_cmd)
+
+#define CAPI_GET_ERRCODE _IOR('C',0x21, __u16)
+
+#define CAPI_INSTALLED _IOR('C',0x22, __u16)
+
+typedef union capi_ioctl_struct {
+ __u32 contr;
+ capi_register_params rparams;
+ __u8 manufacturer[CAPI_MANUFACTURER_LEN];
+ capi_version version;
+ __u8 serial[CAPI_SERIAL_LEN];
+ capi_profile profile;
+ capi_manufacturer_cmd cmd;
+ __u16 errcode;
+} capi_ioctl_struct;
+
+#define CAPIFLAG_HIGHJACKING 0x0001
+
+#define CAPI_GET_FLAGS _IOR('C',0x23, unsigned)
+#define CAPI_SET_FLAGS _IOR('C',0x24, unsigned)
+#define CAPI_CLR_FLAGS _IOR('C',0x25, unsigned)
+
+#define CAPI_NCCI_OPENCOUNT _IOR('C',0x26, unsigned)
+
+#define CAPI_NCCI_GETUNIT _IOR('C',0x27, unsigned)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/cdev.h b/ndk/build/platforms/android-1.5/common/include/linux/cdev.h
new file mode 100644
index 0000000..7a71c7e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/cdev.h
@@ -0,0 +1,14 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_CDEV_H
+#define _LINUX_CDEV_H
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/cdrom.h b/ndk/build/platforms/android-1.5/common/include/linux/cdrom.h
new file mode 100644
index 0000000..cc70c9f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/cdrom.h
@@ -0,0 +1,718 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_CDROM_H
+#define _LINUX_CDROM_H
+
+#include <asm/byteorder.h>
+
+#define EDRIVE_CANT_DO_THIS EOPNOTSUPP
+
+#define CDROMPAUSE 0x5301   
+#define CDROMRESUME 0x5302  
+#define CDROMPLAYMSF 0x5303  
+#define CDROMPLAYTRKIND 0x5304  
+#define CDROMREADTOCHDR 0x5305  
+#define CDROMREADTOCENTRY 0x5306  
+#define CDROMSTOP 0x5307  
+#define CDROMSTART 0x5308  
+#define CDROMEJECT 0x5309  
+#define CDROMVOLCTRL 0x530a  
+#define CDROMSUBCHNL 0x530b  
+#define CDROMREADMODE2 0x530c  
+#define CDROMREADMODE1 0x530d  
+#define CDROMREADAUDIO 0x530e  
+#define CDROMEJECT_SW 0x530f  
+#define CDROMMULTISESSION 0x5310  
+#define CDROM_GET_MCN 0x5311  
+#define CDROM_GET_UPC CDROM_GET_MCN  
+#define CDROMRESET 0x5312  
+#define CDROMVOLREAD 0x5313  
+#define CDROMREADRAW 0x5314  
+
+#define CDROMREADCOOKED 0x5315  
+#define CDROMSEEK 0x5316  
+
+#define CDROMPLAYBLK 0x5317  
+
+#define CDROMREADALL 0x5318  
+
+#define CDROMGETSPINDOWN 0x531d
+#define CDROMSETSPINDOWN 0x531e
+
+#define CDROMCLOSETRAY 0x5319  
+#define CDROM_SET_OPTIONS 0x5320  
+#define CDROM_CLEAR_OPTIONS 0x5321  
+#define CDROM_SELECT_SPEED 0x5322  
+#define CDROM_SELECT_DISC 0x5323  
+#define CDROM_MEDIA_CHANGED 0x5325  
+#define CDROM_DRIVE_STATUS 0x5326  
+#define CDROM_DISC_STATUS 0x5327  
+#define CDROM_CHANGER_NSLOTS 0x5328  
+#define CDROM_LOCKDOOR 0x5329  
+#define CDROM_DEBUG 0x5330  
+#define CDROM_GET_CAPABILITY 0x5331  
+
+#define CDROMAUDIOBUFSIZ 0x5382  
+
+#define DVD_READ_STRUCT 0x5390  
+#define DVD_WRITE_STRUCT 0x5391  
+#define DVD_AUTH 0x5392  
+
+#define CDROM_SEND_PACKET 0x5393  
+#define CDROM_NEXT_WRITABLE 0x5394  
+#define CDROM_LAST_WRITTEN 0x5395  
+
+struct cdrom_msf0
+{
+ __u8 minute;
+ __u8 second;
+ __u8 frame;
+};
+
+union cdrom_addr
+{
+ struct cdrom_msf0 msf;
+ int lba;
+};
+
+struct cdrom_msf
+{
+ __u8 cdmsf_min0;
+ __u8 cdmsf_sec0;
+ __u8 cdmsf_frame0;
+ __u8 cdmsf_min1;
+ __u8 cdmsf_sec1;
+ __u8 cdmsf_frame1;
+};
+
+struct cdrom_ti
+{
+ __u8 cdti_trk0;
+ __u8 cdti_ind0;
+ __u8 cdti_trk1;
+ __u8 cdti_ind1;
+};
+
+struct cdrom_tochdr
+{
+ __u8 cdth_trk0;
+ __u8 cdth_trk1;
+};
+
+struct cdrom_volctrl
+{
+ __u8 channel0;
+ __u8 channel1;
+ __u8 channel2;
+ __u8 channel3;
+};
+
+struct cdrom_subchnl
+{
+ __u8 cdsc_format;
+ __u8 cdsc_audiostatus;
+ __u8 cdsc_adr: 4;
+ __u8 cdsc_ctrl: 4;
+ __u8 cdsc_trk;
+ __u8 cdsc_ind;
+ union cdrom_addr cdsc_absaddr;
+ union cdrom_addr cdsc_reladdr;
+};
+
+struct cdrom_tocentry
+{
+ __u8 cdte_track;
+ __u8 cdte_adr :4;
+ __u8 cdte_ctrl :4;
+ __u8 cdte_format;
+ union cdrom_addr cdte_addr;
+ __u8 cdte_datamode;
+};
+
+struct cdrom_read
+{
+ int cdread_lba;
+ char *cdread_bufaddr;
+ int cdread_buflen;
+};
+
+struct cdrom_read_audio
+{
+ union cdrom_addr addr;
+ __u8 addr_format;
+ int nframes;
+ __u8 __user *buf;
+};
+
+struct cdrom_multisession
+{
+ union cdrom_addr addr;
+ __u8 xa_flag;
+ __u8 addr_format;
+};
+
+struct cdrom_mcn
+{
+ __u8 medium_catalog_number[14];
+};
+
+struct cdrom_blk
+{
+ unsigned from;
+ unsigned short len;
+};
+
+#define CDROM_PACKET_SIZE 12
+
+#define CGC_DATA_UNKNOWN 0
+#define CGC_DATA_WRITE 1
+#define CGC_DATA_READ 2
+#define CGC_DATA_NONE 3
+
+struct cdrom_generic_command
+{
+ unsigned char cmd[CDROM_PACKET_SIZE];
+ unsigned char __user *buffer;
+ unsigned int buflen;
+ int stat;
+ struct request_sense __user *sense;
+ unsigned char data_direction;
+ int quiet;
+ int timeout;
+ void __user *reserved[1];
+};
+
+#define CD_MINS 74  
+#define CD_SECS 60  
+#define CD_FRAMES 75  
+#define CD_SYNC_SIZE 12  
+#define CD_MSF_OFFSET 150  
+#define CD_CHUNK_SIZE 24  
+#define CD_NUM_OF_CHUNKS 98  
+#define CD_FRAMESIZE_SUB 96  
+#define CD_HEAD_SIZE 4  
+#define CD_SUBHEAD_SIZE 8  
+#define CD_EDC_SIZE 4  
+#define CD_ZERO_SIZE 8  
+#define CD_ECC_SIZE 276  
+#define CD_FRAMESIZE 2048  
+#define CD_FRAMESIZE_RAW 2352  
+#define CD_FRAMESIZE_RAWER 2646   
+
+#define CD_FRAMESIZE_RAW1 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE)  
+#define CD_FRAMESIZE_RAW0 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE)  
+
+#define CD_XA_HEAD (CD_HEAD_SIZE+CD_SUBHEAD_SIZE)  
+#define CD_XA_TAIL (CD_EDC_SIZE+CD_ECC_SIZE)  
+#define CD_XA_SYNC_HEAD (CD_SYNC_SIZE+CD_XA_HEAD)  
+
+#define CDROM_LBA 0x01  
+#define CDROM_MSF 0x02  
+
+#define CDROM_DATA_TRACK 0x04
+
+#define CDROM_LEADOUT 0xAA
+
+#define CDROM_AUDIO_INVALID 0x00  
+#define CDROM_AUDIO_PLAY 0x11  
+#define CDROM_AUDIO_PAUSED 0x12  
+#define CDROM_AUDIO_COMPLETED 0x13  
+#define CDROM_AUDIO_ERROR 0x14  
+#define CDROM_AUDIO_NO_STATUS 0x15  
+
+#define CDC_CLOSE_TRAY 0x1  
+#define CDC_OPEN_TRAY 0x2  
+#define CDC_LOCK 0x4  
+#define CDC_SELECT_SPEED 0x8  
+#define CDC_SELECT_DISC 0x10  
+#define CDC_MULTI_SESSION 0x20  
+#define CDC_MCN 0x40  
+#define CDC_MEDIA_CHANGED 0x80  
+#define CDC_PLAY_AUDIO 0x100  
+#define CDC_RESET 0x200  
+#define CDC_DRIVE_STATUS 0x800  
+#define CDC_GENERIC_PACKET 0x1000  
+#define CDC_CD_R 0x2000  
+#define CDC_CD_RW 0x4000  
+#define CDC_DVD 0x8000  
+#define CDC_DVD_R 0x10000  
+#define CDC_DVD_RAM 0x20000  
+#define CDC_MO_DRIVE 0x40000  
+#define CDC_MRW 0x80000  
+#define CDC_MRW_W 0x100000  
+#define CDC_RAM 0x200000  
+
+#define CDS_NO_INFO 0  
+#define CDS_NO_DISC 1
+#define CDS_TRAY_OPEN 2
+#define CDS_DRIVE_NOT_READY 3
+#define CDS_DISC_OK 4
+
+#define CDS_AUDIO 100
+#define CDS_DATA_1 101
+#define CDS_DATA_2 102
+#define CDS_XA_2_1 103
+#define CDS_XA_2_2 104
+#define CDS_MIXED 105
+
+#define CDO_AUTO_CLOSE 0x1  
+#define CDO_AUTO_EJECT 0x2  
+#define CDO_USE_FFLAGS 0x4  
+#define CDO_LOCK 0x8  
+#define CDO_CHECK_TYPE 0x10  
+
+#define CDSL_NONE ((int) (~0U>>1)-1)
+#define CDSL_CURRENT ((int) (~0U>>1))
+
+#define CD_PART_MAX 64
+#define CD_PART_MASK (CD_PART_MAX - 1)
+
+#define GPCMD_BLANK 0xa1
+#define GPCMD_CLOSE_TRACK 0x5b
+#define GPCMD_FLUSH_CACHE 0x35
+#define GPCMD_FORMAT_UNIT 0x04
+#define GPCMD_GET_CONFIGURATION 0x46
+#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a
+#define GPCMD_GET_PERFORMANCE 0xac
+#define GPCMD_INQUIRY 0x12
+#define GPCMD_LOAD_UNLOAD 0xa6
+#define GPCMD_MECHANISM_STATUS 0xbd
+#define GPCMD_MODE_SELECT_10 0x55
+#define GPCMD_MODE_SENSE_10 0x5a
+#define GPCMD_PAUSE_RESUME 0x4b
+#define GPCMD_PLAY_AUDIO_10 0x45
+#define GPCMD_PLAY_AUDIO_MSF 0x47
+#define GPCMD_PLAY_AUDIO_TI 0x48
+#define GPCMD_PLAY_CD 0xbc
+#define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
+#define GPCMD_READ_10 0x28
+#define GPCMD_READ_12 0xa8
+#define GPCMD_READ_BUFFER_CAPACITY 0x5c
+#define GPCMD_READ_CDVD_CAPACITY 0x25
+#define GPCMD_READ_CD 0xbe
+#define GPCMD_READ_CD_MSF 0xb9
+#define GPCMD_READ_DISC_INFO 0x51
+#define GPCMD_READ_DVD_STRUCTURE 0xad
+#define GPCMD_READ_FORMAT_CAPACITIES 0x23
+#define GPCMD_READ_HEADER 0x44
+#define GPCMD_READ_TRACK_RZONE_INFO 0x52
+#define GPCMD_READ_SUBCHANNEL 0x42
+#define GPCMD_READ_TOC_PMA_ATIP 0x43
+#define GPCMD_REPAIR_RZONE_TRACK 0x58
+#define GPCMD_REPORT_KEY 0xa4
+#define GPCMD_REQUEST_SENSE 0x03
+#define GPCMD_RESERVE_RZONE_TRACK 0x53
+#define GPCMD_SEND_CUE_SHEET 0x5d
+#define GPCMD_SCAN 0xba
+#define GPCMD_SEEK 0x2b
+#define GPCMD_SEND_DVD_STRUCTURE 0xbf
+#define GPCMD_SEND_EVENT 0xa2
+#define GPCMD_SEND_KEY 0xa3
+#define GPCMD_SEND_OPC 0x54
+#define GPCMD_SET_READ_AHEAD 0xa7
+#define GPCMD_SET_STREAMING 0xb6
+#define GPCMD_START_STOP_UNIT 0x1b
+#define GPCMD_STOP_PLAY_SCAN 0x4e
+#define GPCMD_TEST_UNIT_READY 0x00
+#define GPCMD_VERIFY_10 0x2f
+#define GPCMD_WRITE_10 0x2a
+#define GPCMD_WRITE_AND_VERIFY_10 0x2e
+
+#define GPCMD_SET_SPEED 0xbb
+
+#define GPCMD_PLAYAUDIO_TI 0x48
+
+#define GPCMD_GET_MEDIA_STATUS 0xda
+
+#define GPMODE_VENDOR_PAGE 0x00
+#define GPMODE_R_W_ERROR_PAGE 0x01
+#define GPMODE_WRITE_PARMS_PAGE 0x05
+#define GPMODE_WCACHING_PAGE 0x08
+#define GPMODE_AUDIO_CTL_PAGE 0x0e
+#define GPMODE_POWER_PAGE 0x1a
+#define GPMODE_FAULT_FAIL_PAGE 0x1c
+#define GPMODE_TO_PROTECT_PAGE 0x1d
+#define GPMODE_CAPABILITIES_PAGE 0x2a
+#define GPMODE_ALL_PAGES 0x3f
+
+#define GPMODE_CDROM_PAGE 0x0d
+
+#define DVD_STRUCT_PHYSICAL 0x00
+#define DVD_STRUCT_COPYRIGHT 0x01
+#define DVD_STRUCT_DISCKEY 0x02
+#define DVD_STRUCT_BCA 0x03
+#define DVD_STRUCT_MANUFACT 0x04
+
+struct dvd_layer {
+ __u8 book_version : 4;
+ __u8 book_type : 4;
+ __u8 min_rate : 4;
+ __u8 disc_size : 4;
+ __u8 layer_type : 4;
+ __u8 track_path : 1;
+ __u8 nlayers : 2;
+ __u8 track_density : 4;
+ __u8 linear_density : 4;
+ __u8 bca : 1;
+ __u32 start_sector;
+ __u32 end_sector;
+ __u32 end_sector_l0;
+};
+
+#define DVD_LAYERS 4
+
+struct dvd_physical {
+ __u8 type;
+ __u8 layer_num;
+ struct dvd_layer layer[DVD_LAYERS];
+};
+
+struct dvd_copyright {
+ __u8 type;
+
+ __u8 layer_num;
+ __u8 cpst;
+ __u8 rmi;
+};
+
+struct dvd_disckey {
+ __u8 type;
+
+ unsigned agid : 2;
+ __u8 value[2048];
+};
+
+struct dvd_bca {
+ __u8 type;
+
+ int len;
+ __u8 value[188];
+};
+
+struct dvd_manufact {
+ __u8 type;
+
+ __u8 layer_num;
+ int len;
+ __u8 value[2048];
+};
+
+typedef union {
+ __u8 type;
+
+ struct dvd_physical physical;
+ struct dvd_copyright copyright;
+ struct dvd_disckey disckey;
+ struct dvd_bca bca;
+ struct dvd_manufact manufact;
+} dvd_struct;
+
+#define DVD_LU_SEND_AGID 0
+#define DVD_HOST_SEND_CHALLENGE 1
+#define DVD_LU_SEND_KEY1 2
+#define DVD_LU_SEND_CHALLENGE 3
+#define DVD_HOST_SEND_KEY2 4
+
+#define DVD_AUTH_ESTABLISHED 5
+#define DVD_AUTH_FAILURE 6
+
+#define DVD_LU_SEND_TITLE_KEY 7
+#define DVD_LU_SEND_ASF 8
+#define DVD_INVALIDATE_AGID 9
+#define DVD_LU_SEND_RPC_STATE 10
+#define DVD_HOST_SEND_RPC_STATE 11
+
+typedef __u8 dvd_key[5];
+typedef __u8 dvd_challenge[10];
+
+struct dvd_lu_send_agid {
+ __u8 type;
+ unsigned agid : 2;
+};
+
+struct dvd_host_send_challenge {
+ __u8 type;
+ unsigned agid : 2;
+
+ dvd_challenge chal;
+};
+
+struct dvd_send_key {
+ __u8 type;
+ unsigned agid : 2;
+
+ dvd_key key;
+};
+
+struct dvd_lu_send_challenge {
+ __u8 type;
+ unsigned agid : 2;
+
+ dvd_challenge chal;
+};
+
+#define DVD_CPM_NO_COPYRIGHT 0
+#define DVD_CPM_COPYRIGHTED 1
+
+#define DVD_CP_SEC_NONE 0
+#define DVD_CP_SEC_EXIST 1
+
+#define DVD_CGMS_UNRESTRICTED 0
+#define DVD_CGMS_SINGLE 2
+#define DVD_CGMS_RESTRICTED 3
+
+struct dvd_lu_send_title_key {
+ __u8 type;
+ unsigned agid : 2;
+
+ dvd_key title_key;
+ int lba;
+ unsigned cpm : 1;
+ unsigned cp_sec : 1;
+ unsigned cgms : 2;
+};
+
+struct dvd_lu_send_asf {
+ __u8 type;
+ unsigned agid : 2;
+
+ unsigned asf : 1;
+};
+
+struct dvd_host_send_rpcstate {
+ __u8 type;
+ __u8 pdrc;
+};
+
+struct dvd_lu_send_rpcstate {
+ __u8 type : 2;
+ __u8 vra : 3;
+ __u8 ucca : 3;
+ __u8 region_mask;
+ __u8 rpc_scheme;
+};
+
+typedef union {
+ __u8 type;
+
+ struct dvd_lu_send_agid lsa;
+ struct dvd_host_send_challenge hsc;
+ struct dvd_send_key lsk;
+ struct dvd_lu_send_challenge lsc;
+ struct dvd_send_key hsk;
+ struct dvd_lu_send_title_key lstk;
+ struct dvd_lu_send_asf lsasf;
+ struct dvd_host_send_rpcstate hrpcs;
+ struct dvd_lu_send_rpcstate lrpcs;
+} dvd_authinfo;
+
+struct request_sense {
+#ifdef __BIG_ENDIAN_BITFIELD
+ __u8 valid : 1;
+ __u8 error_code : 7;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 error_code : 7;
+ __u8 valid : 1;
+#endif
+ __u8 segment_number;
+#ifdef __BIG_ENDIAN_BITFIELD
+ __u8 reserved1 : 2;
+ __u8 ili : 1;
+ __u8 reserved2 : 1;
+ __u8 sense_key : 4;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 sense_key : 4;
+ __u8 reserved2 : 1;
+ __u8 ili : 1;
+ __u8 reserved1 : 2;
+#endif
+ __u8 information[4];
+ __u8 add_sense_len;
+ __u8 command_info[4];
+ __u8 asc;
+ __u8 ascq;
+ __u8 fruc;
+ __u8 sks[3];
+ __u8 asb[46];
+};
+
+#define CDF_RWRT 0x0020  
+#define CDF_HWDM 0x0024  
+#define CDF_MRW 0x0028
+
+#define CDM_MRW_NOTMRW 0
+#define CDM_MRW_BGFORMAT_INACTIVE 1
+#define CDM_MRW_BGFORMAT_ACTIVE 2
+#define CDM_MRW_BGFORMAT_COMPLETE 3
+
+#define MRW_LBA_DMA 0
+#define MRW_LBA_GAA 1
+
+#define MRW_MODE_PC_PRE1 0x2c
+#define MRW_MODE_PC 0x03
+
+struct mrw_feature_desc {
+ __u16 feature_code;
+#ifdef __BIG_ENDIAN_BITFIELD
+ __u8 reserved1 : 2;
+ __u8 feature_version : 4;
+ __u8 persistent : 1;
+ __u8 curr : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 curr : 1;
+ __u8 persistent : 1;
+ __u8 feature_version : 4;
+ __u8 reserved1 : 2;
+#endif
+ __u8 add_len;
+#ifdef __BIG_ENDIAN_BITFIELD
+ __u8 reserved2 : 7;
+ __u8 write : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 write : 1;
+ __u8 reserved2 : 7;
+#endif
+ __u8 reserved3;
+ __u8 reserved4;
+ __u8 reserved5;
+};
+
+struct rwrt_feature_desc {
+ __u16 feature_code;
+#ifdef __BIG_ENDIAN_BITFIELD
+ __u8 reserved1 : 2;
+ __u8 feature_version : 4;
+ __u8 persistent : 1;
+ __u8 curr : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 curr : 1;
+ __u8 persistent : 1;
+ __u8 feature_version : 4;
+ __u8 reserved1 : 2;
+#endif
+ __u8 add_len;
+ __u32 last_lba;
+ __u32 block_size;
+ __u16 blocking;
+#ifdef __BIG_ENDIAN_BITFIELD
+ __u8 reserved2 : 7;
+ __u8 page_present : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 page_present : 1;
+ __u8 reserved2 : 7;
+#endif
+ __u8 reserved3;
+};
+
+typedef struct {
+ __u16 disc_information_length;
+#ifdef __BIG_ENDIAN_BITFIELD
+ __u8 reserved1 : 3;
+ __u8 erasable : 1;
+ __u8 border_status : 2;
+ __u8 disc_status : 2;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 disc_status : 2;
+ __u8 border_status : 2;
+ __u8 erasable : 1;
+ __u8 reserved1 : 3;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ __u8 n_first_track;
+ __u8 n_sessions_lsb;
+ __u8 first_track_lsb;
+ __u8 last_track_lsb;
+#ifdef __BIG_ENDIAN_BITFIELD
+ __u8 did_v : 1;
+ __u8 dbc_v : 1;
+ __u8 uru : 1;
+ __u8 reserved2 : 2;
+ __u8 dbit : 1;
+ __u8 mrw_status : 2;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 mrw_status : 2;
+ __u8 dbit : 1;
+ __u8 reserved2 : 2;
+ __u8 uru : 1;
+ __u8 dbc_v : 1;
+ __u8 did_v : 1;
+#endif
+ __u8 disc_type;
+ __u8 n_sessions_msb;
+ __u8 first_track_msb;
+ __u8 last_track_msb;
+ __u32 disc_id;
+ __u32 lead_in;
+ __u32 lead_out;
+ __u8 disc_bar_code[8];
+ __u8 reserved3;
+ __u8 n_opc;
+} disc_information;
+
+typedef struct {
+ __u16 track_information_length;
+ __u8 track_lsb;
+ __u8 session_lsb;
+ __u8 reserved1;
+#ifdef __BIG_ENDIAN_BITFIELD
+ __u8 reserved2 : 2;
+ __u8 damage : 1;
+ __u8 copy : 1;
+ __u8 track_mode : 4;
+ __u8 rt : 1;
+ __u8 blank : 1;
+ __u8 packet : 1;
+ __u8 fp : 1;
+ __u8 data_mode : 4;
+ __u8 reserved3 : 6;
+ __u8 lra_v : 1;
+ __u8 nwa_v : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 track_mode : 4;
+ __u8 copy : 1;
+ __u8 damage : 1;
+ __u8 reserved2 : 2;
+ __u8 data_mode : 4;
+ __u8 fp : 1;
+ __u8 packet : 1;
+ __u8 blank : 1;
+ __u8 rt : 1;
+ __u8 nwa_v : 1;
+ __u8 lra_v : 1;
+ __u8 reserved3 : 6;
+#endif
+ __u32 track_start;
+ __u32 next_writable;
+ __u32 free_blocks;
+ __u32 fixed_packet_size;
+ __u32 track_size;
+ __u32 last_rec_address;
+} track_information;
+
+struct feature_header {
+ __u32 data_len;
+ __u8 reserved1;
+ __u8 reserved2;
+ __u16 curr_profile;
+};
+
+struct mode_page_header {
+ __u16 mode_data_length;
+ __u8 medium_type;
+ __u8 reserved1;
+ __u8 reserved2;
+ __u8 reserved3;
+ __u16 desc_length;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/circ_buf.h b/ndk/build/platforms/android-1.5/common/include/linux/circ_buf.h
new file mode 100644
index 0000000..438250c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/circ_buf.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_CIRC_BUF_H
+#define _LINUX_CIRC_BUF_H 1
+
+struct circ_buf {
+ char *buf;
+ int head;
+ int tail;
+};
+
+#define CIRC_CNT(head,tail,size) (((head) - (tail)) & ((size)-1))
+
+#define CIRC_SPACE(head,tail,size) CIRC_CNT((tail),((head)+1),(size))
+
+#define CIRC_CNT_TO_END(head,tail,size)   ({int end = (size) - (tail);   int n = ((head) + end) & ((size)-1);   n < end ? n : end;})
+
+#define CIRC_SPACE_TO_END(head,tail,size)   ({int end = (size) - 1 - (head);   int n = (end + (tail)) & ((size)-1);   n <= end ? n : end+1;})
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/clk.h b/ndk/build/platforms/android-1.5/common/include/linux/clk.h
new file mode 100644
index 0000000..2b8f436
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/clk.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_CLK_H
+#define __LINUX_CLK_H
+
+struct device;
+
+struct clk;
+
+struct clk *clk_get(struct device *dev, const char *id);
+
+struct clk *clk_get_parent(struct clk *clk);
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/coda.h b/ndk/build/platforms/android-1.5/common/include/linux/coda.h
new file mode 100644
index 0000000..e7e89f9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/coda.h
@@ -0,0 +1,594 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _CODA_HEADER_
+#define _CODA_HEADER_
+
+#if defined(__NetBSD__) || (defined(DJGPP) || defined(__CYGWIN32__)) && !defined(KERNEL)
+#include <sys/types.h>
+#endif
+
+#ifndef CODA_MAXSYMLINKS
+#define CODA_MAXSYMLINKS 10
+#endif
+
+#if defined(DJGPP) || defined(__CYGWIN32__)
+#ifdef KERNEL
+typedef unsigned long u_long;
+typedef unsigned int u_int;
+typedef unsigned short u_short;
+typedef u_long ino_t;
+typedef u_long dev_t;
+typedef void * caddr_t;
+#ifdef DOS
+typedef unsigned __int64 u_quad_t;
+#else
+typedef unsigned long long u_quad_t;
+#endif
+
+#define inline
+
+struct timespec {
+ long ts_sec;
+ long ts_nsec;
+};
+#else
+#include <sys/time.h>
+typedef unsigned long long u_quad_t;
+#endif
+#endif
+
+#ifdef __linux__
+#include <linux/time.h>
+#define cdev_t u_quad_t
+#if !defined(_UQUAD_T_) && (!defined(__GLIBC__) || __GLIBC__ < 2)
+#define _UQUAD_T_ 1
+typedef unsigned long long u_quad_t;
+#endif
+#else
+#define cdev_t dev_t
+#endif
+
+#ifdef __CYGWIN32__
+struct timespec {
+ time_t tv_sec;
+ long tv_nsec;
+};
+#endif
+
+#ifndef __BIT_TYPES_DEFINED__
+#define __BIT_TYPES_DEFINED__
+typedef signed char int8_t;
+typedef unsigned char u_int8_t;
+typedef short int16_t;
+typedef unsigned short u_int16_t;
+typedef int int32_t;
+typedef unsigned int u_int32_t;
+#endif
+
+#define CODA_MAXNAMLEN 255
+#define CODA_MAXPATHLEN 1024
+#define CODA_MAXSYMLINK 10
+
+#define C_O_READ 0x001
+#define C_O_WRITE 0x002
+#define C_O_TRUNC 0x010
+#define C_O_EXCL 0x100
+#define C_O_CREAT 0x200
+
+#define C_M_READ 00400
+#define C_M_WRITE 00200
+
+#define C_A_C_OK 8  
+#define C_A_R_OK 4  
+#define C_A_W_OK 2  
+#define C_A_X_OK 1  
+#define C_A_F_OK 0  
+
+#ifndef _VENUS_DIRENT_T_
+#define _VENUS_DIRENT_T_ 1
+struct venus_dirent {
+ u_int32_t d_fileno;
+ u_int16_t d_reclen;
+ u_int8_t d_type;
+ u_int8_t d_namlen;
+ char d_name[CODA_MAXNAMLEN + 1];
+};
+#undef DIRSIZ
+#define DIRSIZ(dp) ((sizeof (struct venus_dirent) - (CODA_MAXNAMLEN+1)) +   (((dp)->d_namlen+1 + 3) &~ 3))
+
+#define CDT_UNKNOWN 0
+#define CDT_FIFO 1
+#define CDT_CHR 2
+#define CDT_DIR 4
+#define CDT_BLK 6
+#define CDT_REG 8
+#define CDT_LNK 10
+#define CDT_SOCK 12
+#define CDT_WHT 14
+
+#define IFTOCDT(mode) (((mode) & 0170000) >> 12)
+#define CDTTOIF(dirtype) ((dirtype) << 12)
+
+#endif
+
+#ifndef _VUID_T_
+#define _VUID_T_
+typedef u_int32_t vuid_t;
+typedef u_int32_t vgid_t;
+#endif
+
+struct CodaFid {
+ u_int32_t opaque[4];
+};
+
+#define coda_f2i(fid)  (fid ? (fid->opaque[3] ^ (fid->opaque[2]<<10) ^ (fid->opaque[1]<<20) ^ fid->opaque[0]) : 0)
+
+#ifndef _VENUS_VATTR_T_
+#define _VENUS_VATTR_T_
+
+enum coda_vtype { C_VNON, C_VREG, C_VDIR, C_VBLK, C_VCHR, C_VLNK, C_VSOCK, C_VFIFO, C_VBAD };
+
+struct coda_vattr {
+ long va_type;
+ u_short va_mode;
+ short va_nlink;
+ vuid_t va_uid;
+ vgid_t va_gid;
+ long va_fileid;
+ u_quad_t va_size;
+ long va_blocksize;
+ struct timespec va_atime;
+ struct timespec va_mtime;
+ struct timespec va_ctime;
+ u_long va_gen;
+ u_long va_flags;
+ cdev_t va_rdev;
+ u_quad_t va_bytes;
+ u_quad_t va_filerev;
+};
+
+#endif
+
+struct coda_statfs {
+ int32_t f_blocks;
+ int32_t f_bfree;
+ int32_t f_bavail;
+ int32_t f_files;
+ int32_t f_ffree;
+};
+
+#define CODA_ROOT 2
+#define CODA_OPEN_BY_FD 3
+#define CODA_OPEN 4
+#define CODA_CLOSE 5
+#define CODA_IOCTL 6
+#define CODA_GETATTR 7
+#define CODA_SETATTR 8
+#define CODA_ACCESS 9
+#define CODA_LOOKUP 10
+#define CODA_CREATE 11
+#define CODA_REMOVE 12
+#define CODA_LINK 13
+#define CODA_RENAME 14
+#define CODA_MKDIR 15
+#define CODA_RMDIR 16
+#define CODA_SYMLINK 18
+#define CODA_READLINK 19
+#define CODA_FSYNC 20
+#define CODA_VGET 22
+#define CODA_SIGNAL 23
+#define CODA_REPLACE 24  
+#define CODA_FLUSH 25  
+#define CODA_PURGEUSER 26  
+#define CODA_ZAPFILE 27  
+#define CODA_ZAPDIR 28  
+#define CODA_PURGEFID 30  
+#define CODA_OPEN_BY_PATH 31
+#define CODA_RESOLVE 32
+#define CODA_REINTEGRATE 33
+#define CODA_STATFS 34
+#define CODA_STORE 35
+#define CODA_RELEASE 36
+#define CODA_NCALLS 37
+
+#define DOWNCALL(opcode) (opcode >= CODA_REPLACE && opcode <= CODA_PURGEFID)
+
+#define VC_MAXDATASIZE 8192
+#define VC_MAXMSGSIZE sizeof(union inputArgs)+sizeof(union outputArgs) +  VC_MAXDATASIZE 
+
+#define CIOC_KERNEL_VERSION _IOWR('c', 10, size_t)
+
+#define CODA_KERNEL_VERSION 3  
+
+struct coda_in_hdr {
+ u_int32_t opcode;
+ u_int32_t unique;
+ pid_t pid;
+ pid_t pgid;
+ vuid_t uid;
+};
+
+struct coda_out_hdr {
+ u_int32_t opcode;
+ u_int32_t unique;
+ u_int32_t result;
+};
+
+struct coda_root_out {
+ struct coda_out_hdr oh;
+ struct CodaFid VFid;
+};
+
+struct coda_root_in {
+ struct coda_in_hdr in;
+};
+
+struct coda_open_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int flags;
+};
+
+struct coda_open_out {
+ struct coda_out_hdr oh;
+ cdev_t dev;
+ ino_t inode;
+};
+
+struct coda_store_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int flags;
+};
+
+struct coda_store_out {
+ struct coda_out_hdr out;
+};
+
+struct coda_release_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int flags;
+};
+
+struct coda_release_out {
+ struct coda_out_hdr out;
+};
+
+struct coda_close_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int flags;
+};
+
+struct coda_close_out {
+ struct coda_out_hdr out;
+};
+
+struct coda_ioctl_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int cmd;
+ int len;
+ int rwflag;
+ char *data;
+};
+
+struct coda_ioctl_out {
+ struct coda_out_hdr oh;
+ int len;
+ caddr_t data;
+};
+
+struct coda_getattr_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+};
+
+struct coda_getattr_out {
+ struct coda_out_hdr oh;
+ struct coda_vattr attr;
+};
+
+struct coda_setattr_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ struct coda_vattr attr;
+};
+
+struct coda_setattr_out {
+ struct coda_out_hdr out;
+};
+
+struct coda_access_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int flags;
+};
+
+struct coda_access_out {
+ struct coda_out_hdr out;
+};
+
+#define CLU_CASE_SENSITIVE 0x01
+#define CLU_CASE_INSENSITIVE 0x02
+
+struct coda_lookup_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int name;
+ int flags;
+};
+
+struct coda_lookup_out {
+ struct coda_out_hdr oh;
+ struct CodaFid VFid;
+ int vtype;
+};
+
+struct coda_create_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ struct coda_vattr attr;
+ int excl;
+ int mode;
+ int name;
+};
+
+struct coda_create_out {
+ struct coda_out_hdr oh;
+ struct CodaFid VFid;
+ struct coda_vattr attr;
+};
+
+struct coda_remove_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int name;
+};
+
+struct coda_remove_out {
+ struct coda_out_hdr out;
+};
+
+struct coda_link_in {
+ struct coda_in_hdr ih;
+ struct CodaFid sourceFid;
+ struct CodaFid destFid;
+ int tname;
+};
+
+struct coda_link_out {
+ struct coda_out_hdr out;
+};
+
+struct coda_rename_in {
+ struct coda_in_hdr ih;
+ struct CodaFid sourceFid;
+ int srcname;
+ struct CodaFid destFid;
+ int destname;
+};
+
+struct coda_rename_out {
+ struct coda_out_hdr out;
+};
+
+struct coda_mkdir_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ struct coda_vattr attr;
+ int name;
+};
+
+struct coda_mkdir_out {
+ struct coda_out_hdr oh;
+ struct CodaFid VFid;
+ struct coda_vattr attr;
+};
+
+struct coda_rmdir_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int name;
+};
+
+struct coda_rmdir_out {
+ struct coda_out_hdr out;
+};
+
+struct coda_symlink_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int srcname;
+ struct coda_vattr attr;
+ int tname;
+};
+
+struct coda_symlink_out {
+ struct coda_out_hdr out;
+};
+
+struct coda_readlink_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+};
+
+struct coda_readlink_out {
+ struct coda_out_hdr oh;
+ int count;
+ caddr_t data;
+};
+
+struct coda_fsync_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+};
+
+struct coda_fsync_out {
+ struct coda_out_hdr out;
+};
+
+struct coda_vget_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+};
+
+struct coda_vget_out {
+ struct coda_out_hdr oh;
+ struct CodaFid VFid;
+ int vtype;
+};
+
+struct coda_purgeuser_out {
+ struct coda_out_hdr oh;
+ vuid_t uid;
+};
+
+struct coda_zapfile_out {
+ struct coda_out_hdr oh;
+ struct CodaFid CodaFid;
+};
+
+struct coda_zapdir_out {
+ struct coda_out_hdr oh;
+ struct CodaFid CodaFid;
+};
+
+struct coda_purgefid_out {
+ struct coda_out_hdr oh;
+ struct CodaFid CodaFid;
+};
+
+struct coda_replace_out {
+ struct coda_out_hdr oh;
+ struct CodaFid NewFid;
+ struct CodaFid OldFid;
+};
+
+struct coda_open_by_fd_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int flags;
+};
+
+struct coda_open_by_fd_out {
+ struct coda_out_hdr oh;
+ int fd;
+
+};
+
+struct coda_open_by_path_in {
+ struct coda_in_hdr ih;
+ struct CodaFid VFid;
+ int flags;
+};
+
+struct coda_open_by_path_out {
+ struct coda_out_hdr oh;
+ int path;
+};
+
+struct coda_statfs_in {
+ struct coda_in_hdr in;
+};
+
+struct coda_statfs_out {
+ struct coda_out_hdr oh;
+ struct coda_statfs stat;
+};
+
+#define CODA_NOCACHE 0x80000000
+
+union inputArgs {
+ struct coda_in_hdr ih;
+ struct coda_open_in coda_open;
+ struct coda_store_in coda_store;
+ struct coda_release_in coda_release;
+ struct coda_close_in coda_close;
+ struct coda_ioctl_in coda_ioctl;
+ struct coda_getattr_in coda_getattr;
+ struct coda_setattr_in coda_setattr;
+ struct coda_access_in coda_access;
+ struct coda_lookup_in coda_lookup;
+ struct coda_create_in coda_create;
+ struct coda_remove_in coda_remove;
+ struct coda_link_in coda_link;
+ struct coda_rename_in coda_rename;
+ struct coda_mkdir_in coda_mkdir;
+ struct coda_rmdir_in coda_rmdir;
+ struct coda_symlink_in coda_symlink;
+ struct coda_readlink_in coda_readlink;
+ struct coda_fsync_in coda_fsync;
+ struct coda_vget_in coda_vget;
+ struct coda_open_by_fd_in coda_open_by_fd;
+ struct coda_open_by_path_in coda_open_by_path;
+ struct coda_statfs_in coda_statfs;
+};
+
+union outputArgs {
+ struct coda_out_hdr oh;
+ struct coda_root_out coda_root;
+ struct coda_open_out coda_open;
+ struct coda_ioctl_out coda_ioctl;
+ struct coda_getattr_out coda_getattr;
+ struct coda_lookup_out coda_lookup;
+ struct coda_create_out coda_create;
+ struct coda_mkdir_out coda_mkdir;
+ struct coda_readlink_out coda_readlink;
+ struct coda_vget_out coda_vget;
+ struct coda_purgeuser_out coda_purgeuser;
+ struct coda_zapfile_out coda_zapfile;
+ struct coda_zapdir_out coda_zapdir;
+ struct coda_purgefid_out coda_purgefid;
+ struct coda_replace_out coda_replace;
+ struct coda_open_by_fd_out coda_open_by_fd;
+ struct coda_open_by_path_out coda_open_by_path;
+ struct coda_statfs_out coda_statfs;
+};
+
+union coda_downcalls {
+
+ struct coda_purgeuser_out purgeuser;
+ struct coda_zapfile_out zapfile;
+ struct coda_zapdir_out zapdir;
+ struct coda_purgefid_out purgefid;
+ struct coda_replace_out replace;
+};
+
+#define PIOCPARM_MASK 0x0000ffff
+struct ViceIoctl {
+ void __user *in;
+ void __user *out;
+ u_short in_size;
+ u_short out_size;
+};
+
+struct PioctlData {
+ const char __user *path;
+ int follow;
+ struct ViceIoctl vi;
+};
+
+#define CODA_CONTROL ".CONTROL"
+#define CODA_CONTROLLEN 8
+#define CTL_INO -1
+
+#define CODA_MOUNT_VERSION 1
+
+struct coda_mount_data {
+ int version;
+ int fd;
+};
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/coda_fs_i.h b/ndk/build/platforms/android-1.5/common/include/linux/coda_fs_i.h
new file mode 100644
index 0000000..28b0e59
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/coda_fs_i.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_CODA_FS_I
+#define _LINUX_CODA_FS_I
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/compat.h b/ndk/build/platforms/android-1.5/common/include/linux/compat.h
new file mode 100644
index 0000000..d30b550
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/compat.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_COMPAT_H
+#define _LINUX_COMPAT_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/compiler-gcc.h b/ndk/build/platforms/android-1.5/common/include/linux/compiler-gcc.h
new file mode 100644
index 0000000..0dd4a62
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/compiler-gcc.h
@@ -0,0 +1,22 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#define barrier() __asm__ __volatile__("": : :"memory")
+
+#define RELOC_HIDE(ptr, off)   ({ unsigned long __ptr;   __asm__ ("" : "=r"(__ptr) : "0"(ptr));   (typeof(ptr)) (__ptr + (off)); })
+
+#define inline inline __attribute__((always_inline))
+#define __inline__ __inline__ __attribute__((always_inline))
+#define __inline __inline __attribute__((always_inline))
+#define __deprecated __attribute__((deprecated))
+#define noinline __attribute__((noinline))
+#define __attribute_pure__ __attribute__((pure))
+#define __attribute_const__ __attribute__((__const__))
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/compiler.h b/ndk/build/platforms/android-1.5/common/include/linux/compiler.h
new file mode 100644
index 0000000..4055e33
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/compiler.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_COMPILER_H
+#define __LINUX_COMPILER_H
+
+#ifndef __ASSEMBLY__
+
+#define __user
+#define __kernel
+#define __safe
+#define __force
+#define __nocast
+#define __iomem
+#define __chk_user_ptr(x) (void)0
+#define __chk_io_ptr(x) (void)0
+#define __builtin_warning(x, y...) (1)
+#define __acquires(x)
+#define __releases(x)
+#define __acquire(x) (void)0
+#define __release(x) (void)0
+#define __cond_lock(x) (x)
+
+#endif
+
+#ifndef __attribute_const__
+#define __attribute_const__  
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/completion.h b/ndk/build/platforms/android-1.5/common/include/linux/completion.h
new file mode 100644
index 0000000..ee18211
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/completion.h
@@ -0,0 +1,32 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_COMPLETION_H
+#define __LINUX_COMPLETION_H
+
+#include <linux/wait.h>
+
+struct completion {
+ unsigned int done;
+ wait_queue_head_t wait;
+};
+
+#define COMPLETION_INITIALIZER(work)   { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) }
+
+#define COMPLETION_INITIALIZER_ONSTACK(work)   ({ init_completion(&work); work; })
+
+#define DECLARE_COMPLETION(work)   struct completion work = COMPLETION_INITIALIZER(work)
+
+#define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work)
+
+#define INIT_COMPLETION(x) ((x).done = 0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/config.h b/ndk/build/platforms/android-1.5/common/include/linux/config.h
new file mode 100644
index 0000000..7aa1056
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/config.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_CONFIG_H
+#define _LINUX_CONFIG_H
+
+#include <linux/autoconf.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/console_struct.h b/ndk/build/platforms/android-1.5/common/include/linux/console_struct.h
new file mode 100644
index 0000000..50e4cbe
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/console_struct.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <linux/wait.h>
+#include <linux/vt.h>
+
+struct vt_struct;
+
+#define NPAR 16
+
+struct vc_data {
+ unsigned short vc_num;
+ unsigned int vc_cols;
+ unsigned int vc_rows;
+ unsigned int vc_size_row;
+ unsigned int vc_scan_lines;
+ unsigned long vc_origin;
+ unsigned long vc_scr_end;
+ unsigned long vc_visible_origin;
+ unsigned int vc_top, vc_bottom;
+ const struct consw *vc_sw;
+ unsigned short *vc_screenbuf;
+ unsigned int vc_screenbuf_size;
+ unsigned char vc_mode;
+
+ unsigned char vc_attr;
+ unsigned char vc_def_color;
+ unsigned char vc_color;
+ unsigned char vc_s_color;
+ unsigned char vc_ulcolor;
+ unsigned char vc_halfcolor;
+
+ unsigned int vc_cursor_type;
+ unsigned short vc_complement_mask;
+ unsigned short vc_s_complement_mask;
+ unsigned int vc_x, vc_y;
+ unsigned int vc_saved_x, vc_saved_y;
+ unsigned long vc_pos;
+
+ unsigned short vc_hi_font_mask;
+ struct console_font vc_font;
+ unsigned short vc_video_erase_char;
+
+ unsigned int vc_state;
+ unsigned int vc_npar,vc_par[NPAR];
+ struct tty_struct *vc_tty;
+
+ struct vt_mode vt_mode;
+ int vt_pid;
+ int vt_newvt;
+ wait_queue_head_t paste_wait;
+
+ unsigned int vc_charset : 1;
+ unsigned int vc_s_charset : 1;
+ unsigned int vc_disp_ctrl : 1;
+ unsigned int vc_toggle_meta : 1;
+ unsigned int vc_decscnm : 1;
+ unsigned int vc_decom : 1;
+ unsigned int vc_decawm : 1;
+ unsigned int vc_deccm : 1;
+ unsigned int vc_decim : 1;
+ unsigned int vc_deccolm : 1;
+
+ unsigned int vc_intensity : 2;
+ unsigned int vc_underline : 1;
+ unsigned int vc_blink : 1;
+ unsigned int vc_reverse : 1;
+ unsigned int vc_s_intensity : 2;
+ unsigned int vc_s_underline : 1;
+ unsigned int vc_s_blink : 1;
+ unsigned int vc_s_reverse : 1;
+
+ unsigned int vc_ques : 1;
+ unsigned int vc_need_wrap : 1;
+ unsigned int vc_can_do_color : 1;
+ unsigned int vc_report_mouse : 2;
+ unsigned int vc_kmalloced : 1;
+ unsigned char vc_utf : 1;
+ unsigned char vc_utf_count;
+ int vc_utf_char;
+ unsigned int vc_tab_stop[8];
+ unsigned char vc_palette[16*3];
+ unsigned short * vc_translate;
+ unsigned char vc_G0_charset;
+ unsigned char vc_G1_charset;
+ unsigned char vc_saved_G0;
+ unsigned char vc_saved_G1;
+ unsigned int vc_bell_pitch;
+ unsigned int vc_bell_duration;
+ struct vc_data **vc_display_fg;
+ unsigned long vc_uni_pagedir;
+ unsigned long *vc_uni_pagedir_loc;
+
+};
+
+struct vc {
+ struct vc_data *d;
+
+};
+
+#define CUR_DEF 0
+#define CUR_NONE 1
+#define CUR_UNDERLINE 2
+#define CUR_LOWER_THIRD 3
+#define CUR_LOWER_HALF 4
+#define CUR_TWO_THIRDS 5
+#define CUR_BLOCK 6
+#define CUR_HWMASK 0x0f
+#define CUR_SWMASK 0xfff0
+
+#define CUR_DEFAULT CUR_UNDERLINE
+
+#define CON_IS_VISIBLE(conp) (*conp->vc_display_fg == conp)
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/cpu.h b/ndk/build/platforms/android-1.5/common/include/linux/cpu.h
new file mode 100644
index 0000000..f7e3889
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/cpu.h
@@ -0,0 +1,36 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_CPU_H_
+#define _LINUX_CPU_H_
+
+#include <linux/sysdev.h>
+#include <linux/node.h>
+#include <linux/compiler.h>
+#include <linux/cpumask.h>
+#include <asm/semaphore.h>
+
+struct cpu {
+ int node_id;
+ int no_control;
+ struct sys_device sysdev;
+};
+
+struct notifier_block;
+
+#define lock_cpu_hotplug() do { } while (0)
+#define unlock_cpu_hotplug() do { } while (0)
+#define lock_cpu_hotplug_interruptible() 0
+#define hotcpu_notifier(fn, pri) do { } while (0)
+#define register_hotcpu_notifier(nb) do { } while (0)
+#define unregister_hotcpu_notifier(nb) do { } while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/cpumask.h b/ndk/build/platforms/android-1.5/common/include/linux/cpumask.h
new file mode 100644
index 0000000..541940a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/cpumask.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_CPUMASK_H
+#define __LINUX_CPUMASK_H
+
+#include <linux/kernel.h>
+#include <linux/threads.h>
+#include <linux/bitmap.h>
+
+typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
+
+#define cpu_set(cpu, dst) __cpu_set((cpu), &(dst))
+#define cpu_clear(cpu, dst) __cpu_clear((cpu), &(dst))
+#define cpus_setall(dst) __cpus_setall(&(dst), NR_CPUS)
+#define cpus_clear(dst) __cpus_clear(&(dst), NR_CPUS)
+#define cpu_isset(cpu, cpumask) test_bit((cpu), (cpumask).bits)
+#define cpu_test_and_set(cpu, cpumask) __cpu_test_and_set((cpu), &(cpumask))
+#define cpus_and(dst, src1, src2) __cpus_and(&(dst), &(src1), &(src2), NR_CPUS)
+#define cpus_or(dst, src1, src2) __cpus_or(&(dst), &(src1), &(src2), NR_CPUS)
+#define cpus_xor(dst, src1, src2) __cpus_xor(&(dst), &(src1), &(src2), NR_CPUS)
+#define cpus_andnot(dst, src1, src2)   __cpus_andnot(&(dst), &(src1), &(src2), NR_CPUS)
+#define cpus_complement(dst, src) __cpus_complement(&(dst), &(src), NR_CPUS)
+#define cpus_equal(src1, src2) __cpus_equal(&(src1), &(src2), NR_CPUS)
+#define cpus_intersects(src1, src2) __cpus_intersects(&(src1), &(src2), NR_CPUS)
+#define cpus_subset(src1, src2) __cpus_subset(&(src1), &(src2), NR_CPUS)
+#define cpus_empty(src) __cpus_empty(&(src), NR_CPUS)
+#define cpus_full(cpumask) __cpus_full(&(cpumask), NR_CPUS)
+#define cpus_weight(cpumask) __cpus_weight(&(cpumask), NR_CPUS)
+#define cpus_shift_right(dst, src, n)   __cpus_shift_right(&(dst), &(src), (n), NR_CPUS)
+#define cpus_shift_left(dst, src, n)   __cpus_shift_left(&(dst), &(src), (n), NR_CPUS)
+#define first_cpu(src) 0
+#define next_cpu(n, src) 1
+#define cpumask_of_cpu(cpu)  ({   typeof(_unused_cpumask_arg_) m;   if (sizeof(m) == sizeof(unsigned long)) {   m.bits[0] = 1UL<<(cpu);   } else {   cpus_clear(m);   cpu_set((cpu), m);   }   m;  })
+#define CPU_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(NR_CPUS)
+#if NR_CPUS <= BITS_PER_LONG
+#define CPU_MASK_ALL  (cpumask_t) { {   [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD  } }
+#else
+#define CPU_MASK_ALL  (cpumask_t) { {   [0 ... BITS_TO_LONGS(NR_CPUS)-2] = ~0UL,   [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD  } }
+#endif
+#define CPU_MASK_NONE  (cpumask_t) { {   [0 ... BITS_TO_LONGS(NR_CPUS)-1] = 0UL  } }
+#define CPU_MASK_CPU0  (cpumask_t) { {   [0] = 1UL  } }
+#define cpus_addr(src) ((src).bits)
+#define cpumask_scnprintf(buf, len, src)   __cpumask_scnprintf((buf), (len), &(src), NR_CPUS)
+#define cpumask_parse(ubuf, ulen, dst)   __cpumask_parse((ubuf), (ulen), &(dst), NR_CPUS)
+#define cpulist_scnprintf(buf, len, src)   __cpulist_scnprintf((buf), (len), &(src), NR_CPUS)
+#define cpulist_parse(buf, dst) __cpulist_parse((buf), &(dst), NR_CPUS)
+#define cpu_remap(oldbit, old, new)   __cpu_remap((oldbit), &(old), &(new), NR_CPUS)
+#define cpus_remap(dst, src, old, new)   __cpus_remap(&(dst), &(src), &(old), &(new), NR_CPUS)
+#if NR_CPUS > 1
+#define for_each_cpu_mask(cpu, mask)   for ((cpu) = first_cpu(mask);   (cpu) < NR_CPUS;   (cpu) = next_cpu((cpu), (mask)))
+#else
+#define for_each_cpu_mask(cpu, mask)   for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask)
+#endif
+
+#if NR_CPUS > 1
+#define num_online_cpus() cpus_weight(cpu_online_map)
+#define num_possible_cpus() cpus_weight(cpu_possible_map)
+#define num_present_cpus() cpus_weight(cpu_present_map)
+#define cpu_online(cpu) cpu_isset((cpu), cpu_online_map)
+#define cpu_possible(cpu) cpu_isset((cpu), cpu_possible_map)
+#define cpu_present(cpu) cpu_isset((cpu), cpu_present_map)
+#else
+#define num_online_cpus() 1
+#define num_possible_cpus() 1
+#define num_present_cpus() 1
+#define cpu_online(cpu) ((cpu) == 0)
+#define cpu_possible(cpu) ((cpu) == 0)
+#define cpu_present(cpu) ((cpu) == 0)
+#endif
+
+#define highest_possible_processor_id() 0
+#define any_online_cpu(mask) 0
+
+#define for_each_possible_cpu(cpu) for_each_cpu_mask((cpu), cpu_possible_map)
+#define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map)
+#define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ctype.h b/ndk/build/platforms/android-1.5/common/include/linux/ctype.h
new file mode 100644
index 0000000..4644d12
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ctype.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_CTYPE_H
+#define _LINUX_CTYPE_H
+
+#define _U 0x01  
+#define _L 0x02  
+#define _D 0x04  
+#define _C 0x08  
+#define _P 0x10  
+#define _S 0x20  
+#define _X 0x40  
+#define _SP 0x80  
+
+#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
+
+#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
+#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0)
+#define iscntrl(c) ((__ismask(c)&(_C)) != 0)
+#define isdigit(c) ((__ismask(c)&(_D)) != 0)
+#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0)
+#define islower(c) ((__ismask(c)&(_L)) != 0)
+#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
+#define ispunct(c) ((__ismask(c)&(_P)) != 0)
+#define isspace(c) ((__ismask(c)&(_S)) != 0)
+#define isupper(c) ((__ismask(c)&(_U)) != 0)
+#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
+
+#define isascii(c) (((unsigned char)(c))<=0x7f)
+#define toascii(c) (((unsigned char)(c))&0x7f)
+
+#define tolower(c) __tolower(c)
+#define toupper(c) __toupper(c)
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/dccp.h b/ndk/build/platforms/android-1.5/common/include/linux/dccp.h
new file mode 100644
index 0000000..5e33777
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/dccp.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_DCCP_H
+#define _LINUX_DCCP_H
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+struct dccp_hdr {
+ __be16 dccph_sport,
+ dccph_dport;
+ __u8 dccph_doff;
+#ifdef __LITTLE_ENDIAN_BITFIELD
+ __u8 dccph_cscov:4,
+ dccph_ccval:4;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u8 dccph_ccval:4,
+ dccph_cscov:4;
+#else
+#error "Adjust your <asm/byteorder.h> defines"
+#endif
+ __u16 dccph_checksum;
+#ifdef __LITTLE_ENDIAN_BITFIELD
+ __u8 dccph_x:1,
+ dccph_type:4,
+ dccph_reserved:3;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u8 dccph_reserved:3,
+ dccph_type:4,
+ dccph_x:1;
+#else
+#error "Adjust your <asm/byteorder.h> defines"
+#endif
+ __u8 dccph_seq2;
+ __be16 dccph_seq;
+};
+
+struct dccp_hdr_ext {
+ __be32 dccph_seq_low;
+};
+
+struct dccp_hdr_request {
+ __be32 dccph_req_service;
+};
+
+struct dccp_hdr_ack_bits {
+ __be16 dccph_reserved1;
+ __be16 dccph_ack_nr_high;
+ __be32 dccph_ack_nr_low;
+};
+
+struct dccp_hdr_response {
+ struct dccp_hdr_ack_bits dccph_resp_ack;
+ __be32 dccph_resp_service;
+};
+
+struct dccp_hdr_reset {
+ struct dccp_hdr_ack_bits dccph_reset_ack;
+ __u8 dccph_reset_code,
+ dccph_reset_data[3];
+};
+
+enum dccp_pkt_type {
+ DCCP_PKT_REQUEST = 0,
+ DCCP_PKT_RESPONSE,
+ DCCP_PKT_DATA,
+ DCCP_PKT_ACK,
+ DCCP_PKT_DATAACK,
+ DCCP_PKT_CLOSEREQ,
+ DCCP_PKT_CLOSE,
+ DCCP_PKT_RESET,
+ DCCP_PKT_SYNC,
+ DCCP_PKT_SYNCACK,
+ DCCP_PKT_INVALID,
+};
+
+#define DCCP_NR_PKT_TYPES DCCP_PKT_INVALID
+
+enum {
+ DCCPO_PADDING = 0,
+ DCCPO_MANDATORY = 1,
+ DCCPO_MIN_RESERVED = 3,
+ DCCPO_MAX_RESERVED = 31,
+ DCCPO_CHANGE_L = 32,
+ DCCPO_CONFIRM_L = 33,
+ DCCPO_CHANGE_R = 34,
+ DCCPO_CONFIRM_R = 35,
+ DCCPO_NDP_COUNT = 37,
+ DCCPO_ACK_VECTOR_0 = 38,
+ DCCPO_ACK_VECTOR_1 = 39,
+ DCCPO_TIMESTAMP = 41,
+ DCCPO_TIMESTAMP_ECHO = 42,
+ DCCPO_ELAPSED_TIME = 43,
+ DCCPO_MAX = 45,
+ DCCPO_MIN_CCID_SPECIFIC = 128,
+ DCCPO_MAX_CCID_SPECIFIC = 255,
+};
+
+enum {
+ DCCPF_RESERVED = 0,
+ DCCPF_CCID = 1,
+ DCCPF_SEQUENCE_WINDOW = 3,
+ DCCPF_ACK_RATIO = 5,
+ DCCPF_SEND_ACK_VECTOR = 6,
+ DCCPF_SEND_NDP_COUNT = 7,
+
+ DCCPF_MIN_CCID_SPECIFIC = 128,
+ DCCPF_MAX_CCID_SPECIFIC = 255,
+};
+
+struct dccp_so_feat {
+ __u8 dccpsf_feat;
+ __u8 *dccpsf_val;
+ __u8 dccpsf_len;
+};
+
+#define DCCP_SOCKOPT_PACKET_SIZE 1
+#define DCCP_SOCKOPT_SERVICE 2
+#define DCCP_SOCKOPT_CHANGE_L 3
+#define DCCP_SOCKOPT_CHANGE_R 4
+#define DCCP_SOCKOPT_CCID_RX_INFO 128
+#define DCCP_SOCKOPT_CCID_TX_INFO 192
+
+#define DCCP_SERVICE_LIST_MAX_LEN 32
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/debug_locks.h b/ndk/build/platforms/android-1.5/common/include/linux/debug_locks.h
new file mode 100644
index 0000000..2d55fcd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/debug_locks.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_DEBUG_LOCKING_H
+#define __LINUX_DEBUG_LOCKING_H
+
+struct task_struct;
+
+#define _RET_IP_ (unsigned long)__builtin_return_address(0)
+#define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; })
+
+#define DEBUG_LOCKS_WARN_ON(c)  ({   int __ret = 0;     if (unlikely(c)) {   if (debug_locks_off())   WARN_ON(1);   __ret = 1;   }   __ret;  })
+
+#define SMP_DEBUG_LOCKS_WARN_ON(c) do { } while (0)
+
+#define locking_selftest() do { } while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/delay.h b/ndk/build/platforms/android-1.5/common/include/linux/delay.h
new file mode 100644
index 0000000..e032b6f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/delay.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_DELAY_H
+#define _LINUX_DELAY_H
+
+#include <asm/delay.h>
+
+#ifndef MAX_UDELAY_MS
+#define MAX_UDELAY_MS 5
+#endif
+
+#ifndef mdelay
+#define mdelay(n) (  (__builtin_constant_p(n) && (n)<=MAX_UDELAY_MS) ? udelay((n)*1000) :   ({unsigned long __ms=(n); while (__ms--) udelay(1000);}))
+#endif
+
+#ifndef ndelay
+#define ndelay(x) udelay(((x)+999)/1000)
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/device.h b/ndk/build/platforms/android-1.5/common/include/linux/device.h
new file mode 100644
index 0000000..6419322
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/device.h
@@ -0,0 +1,222 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _DEVICE_H_
+#define _DEVICE_H_
+
+#include <linux/ioport.h>
+#include <linux/kobject.h>
+#include <linux/klist.h>
+#include <linux/list.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/pm.h>
+#include <asm/semaphore.h>
+#include <asm/atomic.h>
+
+#define DEVICE_NAME_SIZE 50
+#define DEVICE_NAME_HALF __stringify(20)  
+#define DEVICE_ID_SIZE 32
+#define BUS_ID_SIZE KOBJ_NAME_LEN
+
+struct device;
+struct device_driver;
+struct class;
+struct class_device;
+
+struct bus_type {
+ const char * name;
+
+ struct subsystem subsys;
+ struct kset drivers;
+ struct kset devices;
+ struct klist klist_devices;
+ struct klist klist_drivers;
+
+ struct bus_attribute * bus_attrs;
+ struct device_attribute * dev_attrs;
+ struct driver_attribute * drv_attrs;
+
+ int (*match)(struct device * dev, struct device_driver * drv);
+ int (*uevent)(struct device *dev, char **envp,
+ int num_envp, char *buffer, int buffer_size);
+ int (*probe)(struct device * dev);
+ int (*remove)(struct device * dev);
+ void (*shutdown)(struct device * dev);
+ int (*suspend)(struct device * dev, pm_message_t state);
+ int (*resume)(struct device * dev);
+};
+
+struct device * bus_find_device(struct bus_type *bus, struct device *start,
+ void *data, int (*match)(struct device *, void *));
+
+struct bus_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct bus_type *, char * buf);
+ ssize_t (*store)(struct bus_type *, const char * buf, size_t count);
+};
+
+#define BUS_ATTR(_name,_mode,_show,_store)  struct bus_attribute bus_attr_##_name = __ATTR(_name,_mode,_show,_store)
+
+struct device_driver {
+ const char * name;
+ struct bus_type * bus;
+
+ struct completion unloaded;
+ struct kobject kobj;
+ struct klist klist_devices;
+ struct klist_node knode_bus;
+
+ struct module * owner;
+
+ int (*probe) (struct device * dev);
+ int (*remove) (struct device * dev);
+ void (*shutdown) (struct device * dev);
+ int (*suspend) (struct device * dev, pm_message_t state);
+ int (*resume) (struct device * dev);
+};
+
+struct driver_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct device_driver *, char * buf);
+ ssize_t (*store)(struct device_driver *, const char * buf, size_t count);
+};
+
+#define DRIVER_ATTR(_name,_mode,_show,_store)  struct driver_attribute driver_attr_##_name = __ATTR(_name,_mode,_show,_store)
+
+struct device * driver_find_device(struct device_driver *drv,
+ struct device *start, void *data,
+ int (*match)(struct device *, void *));
+
+struct class {
+ const char * name;
+ struct module * owner;
+
+ struct subsystem subsys;
+ struct list_head children;
+ struct list_head devices;
+ struct list_head interfaces;
+ struct semaphore sem;
+
+ struct class_attribute * class_attrs;
+ struct class_device_attribute * class_dev_attrs;
+
+ int (*uevent)(struct class_device *dev, char **envp,
+ int num_envp, char *buffer, int buffer_size);
+
+ void (*release)(struct class_device *dev);
+ void (*class_release)(struct class *class);
+};
+
+struct class_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct class *, char * buf);
+ ssize_t (*store)(struct class *, const char * buf, size_t count);
+};
+
+#define CLASS_ATTR(_name,_mode,_show,_store)  struct class_attribute class_attr_##_name = __ATTR(_name,_mode,_show,_store) 
+
+struct class_device_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct class_device *, char * buf);
+ ssize_t (*store)(struct class_device *, const char * buf, size_t count);
+};
+
+#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store)  struct class_device_attribute class_device_attr_##_name =   __ATTR(_name,_mode,_show,_store)
+
+struct class_device {
+ struct list_head node;
+
+ struct kobject kobj;
+ struct class * class;
+ dev_t devt;
+ struct class_device_attribute *devt_attr;
+ struct class_device_attribute uevent_attr;
+ struct device * dev;
+ void * class_data;
+ struct class_device *parent;
+ struct attribute_group ** groups;
+
+ void (*release)(struct class_device *dev);
+ int (*uevent)(struct class_device *dev, char **envp,
+ int num_envp, char *buffer, int buffer_size);
+ char class_id[BUS_ID_SIZE];
+};
+
+struct class_interface {
+ struct list_head node;
+ struct class *class;
+
+ int (*add) (struct class_device *, struct class_interface *);
+ void (*remove) (struct class_device *, struct class_interface *);
+};
+
+struct device_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct device *dev, struct device_attribute *attr,
+ char *buf);
+ ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count);
+};
+
+#define DEVICE_ATTR(_name,_mode,_show,_store)  struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store)
+
+struct device {
+ struct klist klist_children;
+ struct klist_node knode_parent;
+ struct klist_node knode_driver;
+ struct klist_node knode_bus;
+ struct device * parent;
+
+ struct kobject kobj;
+ char bus_id[BUS_ID_SIZE];
+ struct device_attribute uevent_attr;
+ struct device_attribute *devt_attr;
+
+ struct semaphore sem;
+
+ struct bus_type * bus;
+ struct device_driver *driver;
+ void *driver_data;
+ void *platform_data;
+ void *firmware_data;
+ struct dev_pm_info power;
+
+ u64 *dma_mask;
+ u64 coherent_dma_mask;
+
+ struct list_head dma_pools;
+
+ struct dma_coherent_mem *dma_mem;
+
+ struct list_head node;
+ struct class *class;
+ dev_t devt;
+
+ void (*release)(struct device * dev);
+};
+
+#define dev_printk(level, dev, format, arg...)   printk(level "%s %s: " format , dev_driver_string(dev) , (dev)->bus_id , ## arg)
+
+#ifdef DEBUG
+#define dev_dbg(dev, format, arg...)   dev_printk(KERN_DEBUG , dev , format , ## arg)
+#else
+#define dev_dbg(dev, format, arg...) do { (void)(dev); } while (0)
+#endif
+
+#define dev_err(dev, format, arg...)   dev_printk(KERN_ERR , dev , format , ## arg)
+#define dev_info(dev, format, arg...)   dev_printk(KERN_INFO , dev , format , ## arg)
+#define dev_warn(dev, format, arg...)   dev_printk(KERN_WARNING , dev , format , ## arg)
+#define dev_notice(dev, format, arg...)   dev_printk(KERN_NOTICE , dev , format , ## arg)
+
+#define MODULE_ALIAS_CHARDEV(major,minor)   MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
+#define MODULE_ALIAS_CHARDEV_MAJOR(major)   MODULE_ALIAS("char-major-" __stringify(major) "-*")
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/dirent.h b/ndk/build/platforms/android-1.5/common/include/linux/dirent.h
new file mode 100644
index 0000000..2dace18
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/dirent.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_DIRENT_H
+#define _LINUX_DIRENT_H
+
+struct dirent {
+ long d_ino;
+ __kernel_off_t d_off;
+ unsigned short d_reclen;
+ char d_name[256];
+};
+
+struct dirent64 {
+ __u64 d_ino;
+ __s64 d_off;
+ unsigned short d_reclen;
+ unsigned char d_type;
+ char d_name[256];
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/dm-ioctl.h b/ndk/build/platforms/android-1.5/common/include/linux/dm-ioctl.h
new file mode 100644
index 0000000..ead7744
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/dm-ioctl.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_DM_IOCTL_V4_H
+#define _LINUX_DM_IOCTL_V4_H
+
+#include <linux/types.h>
+
+#define DM_DIR "mapper"  
+#define DM_MAX_TYPE_NAME 16
+#define DM_NAME_LEN 128
+#define DM_UUID_LEN 129
+
+struct dm_ioctl {
+
+ uint32_t version[3];
+ uint32_t data_size;
+
+ uint32_t data_start;
+
+ uint32_t target_count;
+ int32_t open_count;
+ uint32_t flags;
+ uint32_t event_nr;
+ uint32_t padding;
+
+ uint64_t dev;
+
+ char name[DM_NAME_LEN];
+ char uuid[DM_UUID_LEN];
+ char data[7];
+};
+
+struct dm_target_spec {
+ uint64_t sector_start;
+ uint64_t length;
+ int32_t status;
+
+ uint32_t next;
+
+ char target_type[DM_MAX_TYPE_NAME];
+
+};
+
+struct dm_target_deps {
+ uint32_t count;
+ uint32_t padding;
+ uint64_t dev[0];
+};
+
+struct dm_name_list {
+ uint64_t dev;
+ uint32_t next;
+ char name[0];
+};
+
+struct dm_target_versions {
+ uint32_t next;
+ uint32_t version[3];
+
+ char name[0];
+};
+
+struct dm_target_msg {
+ uint64_t sector;
+
+ char message[0];
+};
+
+enum {
+
+ DM_VERSION_CMD = 0,
+ DM_REMOVE_ALL_CMD,
+ DM_LIST_DEVICES_CMD,
+
+ DM_DEV_CREATE_CMD,
+ DM_DEV_REMOVE_CMD,
+ DM_DEV_RENAME_CMD,
+ DM_DEV_SUSPEND_CMD,
+ DM_DEV_STATUS_CMD,
+ DM_DEV_WAIT_CMD,
+
+ DM_TABLE_LOAD_CMD,
+ DM_TABLE_CLEAR_CMD,
+ DM_TABLE_DEPS_CMD,
+ DM_TABLE_STATUS_CMD,
+
+ DM_LIST_VERSIONS_CMD,
+ DM_TARGET_MSG_CMD,
+ DM_DEV_SET_GEOMETRY_CMD
+};
+
+#define DM_IOCTL 0xfd
+
+#define DM_VERSION _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl)
+#define DM_REMOVE_ALL _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, struct dm_ioctl)
+#define DM_LIST_DEVICES _IOWR(DM_IOCTL, DM_LIST_DEVICES_CMD, struct dm_ioctl)
+
+#define DM_DEV_CREATE _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, struct dm_ioctl)
+#define DM_DEV_REMOVE _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, struct dm_ioctl)
+#define DM_DEV_RENAME _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, struct dm_ioctl)
+#define DM_DEV_SUSPEND _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, struct dm_ioctl)
+#define DM_DEV_STATUS _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl)
+#define DM_DEV_WAIT _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, struct dm_ioctl)
+
+#define DM_TABLE_LOAD _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, struct dm_ioctl)
+#define DM_TABLE_CLEAR _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, struct dm_ioctl)
+#define DM_TABLE_DEPS _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, struct dm_ioctl)
+#define DM_TABLE_STATUS _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, struct dm_ioctl)
+
+#define DM_LIST_VERSIONS _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, struct dm_ioctl)
+
+#define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl)
+#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
+
+#define DM_VERSION_MAJOR 4
+#define DM_VERSION_MINOR 14
+#define DM_VERSION_PATCHLEVEL 0
+#define DM_VERSION_EXTRA "-ioctl (2008-04-23)"
+
+#define DM_READONLY_FLAG (1 << 0)  
+#define DM_SUSPEND_FLAG (1 << 1)  
+#define DM_PERSISTENT_DEV_FLAG (1 << 3)  
+
+#define DM_STATUS_TABLE_FLAG (1 << 4)  
+
+#define DM_ACTIVE_PRESENT_FLAG (1 << 5)  
+#define DM_INACTIVE_PRESENT_FLAG (1 << 6)  
+
+#define DM_BUFFER_FULL_FLAG (1 << 8)  
+
+#define DM_SKIP_BDGET_FLAG (1 << 9)  
+
+#define DM_SKIP_LOCKFS_FLAG (1 << 10)  
+
+#define DM_NOFLUSH_FLAG (1 << 11)  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/dma-mapping.h b/ndk/build/platforms/android-1.5/common/include/linux/dma-mapping.h
new file mode 100644
index 0000000..6432259
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/dma-mapping.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ASM_LINUX_DMA_MAPPING_H
+#define _ASM_LINUX_DMA_MAPPING_H
+
+#include <linux/device.h>
+#include <linux/err.h>
+
+enum dma_data_direction {
+ DMA_BIDIRECTIONAL = 0,
+ DMA_TO_DEVICE = 1,
+ DMA_FROM_DEVICE = 2,
+ DMA_NONE = 3,
+};
+
+#define DMA_64BIT_MASK 0xffffffffffffffffULL
+#define DMA_48BIT_MASK 0x0000ffffffffffffULL
+#define DMA_40BIT_MASK 0x000000ffffffffffULL
+#define DMA_39BIT_MASK 0x0000007fffffffffULL
+#define DMA_32BIT_MASK 0x00000000ffffffffULL
+#define DMA_31BIT_MASK 0x000000007fffffffULL
+#define DMA_30BIT_MASK 0x000000003fffffffULL
+#define DMA_29BIT_MASK 0x000000001fffffffULL
+#define DMA_28BIT_MASK 0x000000000fffffffULL
+#define DMA_24BIT_MASK 0x0000000000ffffffULL
+
+#include <asm/dma-mapping.h>
+
+#define dma_sync_single dma_sync_single_for_cpu
+#define dma_sync_sg dma_sync_sg_for_cpu
+
+#define DMA_MEMORY_MAP 0x01
+#define DMA_MEMORY_IO 0x02
+#define DMA_MEMORY_INCLUDES_CHILDREN 0x04
+#define DMA_MEMORY_EXCLUSIVE 0x08
+
+#ifndef ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/dmaengine.h b/ndk/build/platforms/android-1.5/common/include/linux/dmaengine.h
new file mode 100644
index 0000000..549fea9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/dmaengine.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef DMAENGINE_H
+#define DMAENGINE_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/efs_dir.h b/ndk/build/platforms/android-1.5/common/include/linux/efs_dir.h
new file mode 100644
index 0000000..5be2762
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/efs_dir.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __EFS_DIR_H__
+#define __EFS_DIR_H__
+
+#define EFS_DIRBSIZE_BITS EFS_BLOCKSIZE_BITS
+#define EFS_DIRBSIZE (1 << EFS_DIRBSIZE_BITS)
+
+struct efs_dentry {
+ __be32 inode;
+ unsigned char namelen;
+ char name[3];
+};
+
+#define EFS_DENTSIZE (sizeof(struct efs_dentry) - 3 + 1)
+#define EFS_MAXNAMELEN ((1 << (sizeof(char) * 8)) - 1)
+
+#define EFS_DIRBLK_HEADERSIZE 4
+#define EFS_DIRBLK_MAGIC 0xbeef  
+
+struct efs_dir {
+ __be16 magic;
+ unsigned char firstused;
+ unsigned char slots;
+
+ unsigned char space[EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE];
+};
+
+#define EFS_MAXENTS   ((EFS_DIRBSIZE - EFS_DIRBLK_HEADERSIZE) /   (EFS_DENTSIZE + sizeof(char)))
+
+#define EFS_SLOTAT(dir, slot) EFS_REALOFF((dir)->space[slot])
+
+#define EFS_REALOFF(offset) ((offset << 1))
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/efs_fs_i.h b/ndk/build/platforms/android-1.5/common/include/linux/efs_fs_i.h
new file mode 100644
index 0000000..6d88d28
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/efs_fs_i.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __EFS_FS_I_H__
+#define __EFS_FS_I_H__
+
+typedef int32_t efs_block_t;
+typedef uint32_t efs_ino_t;
+
+#define EFS_DIRECTEXTENTS 12
+
+typedef union extent_u {
+ unsigned char raw[8];
+ struct extent_s {
+ unsigned int ex_magic:8;
+ unsigned int ex_bn:24;
+ unsigned int ex_length:8;
+ unsigned int ex_offset:24;
+ } cooked;
+} efs_extent;
+
+typedef struct edevs {
+ __be16 odev;
+ __be32 ndev;
+} efs_devs;
+
+struct efs_dinode {
+ __be16 di_mode;
+ __be16 di_nlink;
+ __be16 di_uid;
+ __be16 di_gid;
+ __be32 di_size;
+ __be32 di_atime;
+ __be32 di_mtime;
+ __be32 di_ctime;
+ __be32 di_gen;
+ __be16 di_numextents;
+ u_char di_version;
+ u_char di_spare;
+ union di_addr {
+ efs_extent di_extents[EFS_DIRECTEXTENTS];
+ efs_devs di_dev;
+ } di_u;
+};
+
+struct efs_inode_info {
+ int numextents;
+ int lastextent;
+
+ efs_extent extents[EFS_DIRECTEXTENTS];
+ struct inode vfs_inode;
+};
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/efs_fs_sb.h b/ndk/build/platforms/android-1.5/common/include/linux/efs_fs_sb.h
new file mode 100644
index 0000000..f7960c0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/efs_fs_sb.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __EFS_FS_SB_H__
+#define __EFS_FS_SB_H__
+
+#define EFS_SUPER_MAGIC 0x414A53
+
+#define EFS_MAGIC 0x072959
+#define EFS_NEWMAGIC 0x07295a
+
+#define IS_EFS_MAGIC(x) ((x == EFS_MAGIC) || (x == EFS_NEWMAGIC))
+
+#define EFS_SUPER 1
+#define EFS_ROOTINODE 2
+
+struct efs_super {
+ __be32 fs_size;
+ __be32 fs_firstcg;
+ __be32 fs_cgfsize;
+ __be16 fs_cgisize;
+ __be16 fs_sectors;
+ __be16 fs_heads;
+ __be16 fs_ncg;
+ __be16 fs_dirty;
+ __be32 fs_time;
+ __be32 fs_magic;
+ char fs_fname[6];
+ char fs_fpack[6];
+ __be32 fs_bmsize;
+ __be32 fs_tfree;
+ __be32 fs_tinode;
+ __be32 fs_bmblock;
+ __be32 fs_replsb;
+ __be32 fs_lastialloc;
+ char fs_spare[20];
+ __be32 fs_checksum;
+};
+
+struct efs_sb_info {
+ __u32 fs_magic;
+ __u32 fs_start;
+ __u32 first_block;
+ __u32 total_blocks;
+ __u32 group_size;
+ __u32 data_free;
+ __u32 inode_free;
+ __u16 inode_blocks;
+ __u16 total_groups;
+};
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/elevator.h b/ndk/build/platforms/android-1.5/common/include/linux/elevator.h
new file mode 100644
index 0000000..2e79ce9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/elevator.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ELEVATOR_H
+#define _LINUX_ELEVATOR_H
+
+typedef int (elevator_merge_fn) (request_queue_t *, struct request **,
+ struct bio *);
+
+typedef void (elevator_merge_req_fn) (request_queue_t *, struct request *, struct request *);
+
+typedef void (elevator_merged_fn) (request_queue_t *, struct request *);
+
+typedef int (elevator_dispatch_fn) (request_queue_t *, int);
+
+typedef void (elevator_add_req_fn) (request_queue_t *, struct request *);
+typedef int (elevator_queue_empty_fn) (request_queue_t *);
+typedef struct request *(elevator_request_list_fn) (request_queue_t *, struct request *);
+typedef void (elevator_completed_req_fn) (request_queue_t *, struct request *);
+typedef int (elevator_may_queue_fn) (request_queue_t *, int, struct bio *);
+
+typedef int (elevator_set_req_fn) (request_queue_t *, struct request *, struct bio *, gfp_t);
+typedef void (elevator_put_req_fn) (request_queue_t *, struct request *);
+typedef void (elevator_activate_req_fn) (request_queue_t *, struct request *);
+typedef void (elevator_deactivate_req_fn) (request_queue_t *, struct request *);
+
+typedef void *(elevator_init_fn) (request_queue_t *, elevator_t *);
+typedef void (elevator_exit_fn) (elevator_t *);
+
+struct elevator_ops
+{
+ elevator_merge_fn *elevator_merge_fn;
+ elevator_merged_fn *elevator_merged_fn;
+ elevator_merge_req_fn *elevator_merge_req_fn;
+
+ elevator_dispatch_fn *elevator_dispatch_fn;
+ elevator_add_req_fn *elevator_add_req_fn;
+ elevator_activate_req_fn *elevator_activate_req_fn;
+ elevator_deactivate_req_fn *elevator_deactivate_req_fn;
+
+ elevator_queue_empty_fn *elevator_queue_empty_fn;
+ elevator_completed_req_fn *elevator_completed_req_fn;
+
+ elevator_request_list_fn *elevator_former_req_fn;
+ elevator_request_list_fn *elevator_latter_req_fn;
+
+ elevator_set_req_fn *elevator_set_req_fn;
+ elevator_put_req_fn *elevator_put_req_fn;
+
+ elevator_may_queue_fn *elevator_may_queue_fn;
+
+ elevator_init_fn *elevator_init_fn;
+ elevator_exit_fn *elevator_exit_fn;
+ void (*trim)(struct io_context *);
+};
+
+#define ELV_NAME_MAX (16)
+
+struct elv_fs_entry {
+ struct attribute attr;
+ ssize_t (*show)(elevator_t *, char *);
+ ssize_t (*store)(elevator_t *, const char *, size_t);
+};
+
+struct elevator_type
+{
+ struct list_head list;
+ struct elevator_ops ops;
+ struct elevator_type *elevator_type;
+ struct elv_fs_entry *elevator_attrs;
+ char elevator_name[ELV_NAME_MAX];
+ struct module *elevator_owner;
+};
+
+struct elevator_queue
+{
+ struct elevator_ops *ops;
+ void *elevator_data;
+ struct kobject kobj;
+ struct elevator_type *elevator_type;
+ struct mutex sysfs_lock;
+};
+
+#define ELEVATOR_NO_MERGE 0
+#define ELEVATOR_FRONT_MERGE 1
+#define ELEVATOR_BACK_MERGE 2
+
+#define ELEVATOR_INSERT_FRONT 1
+#define ELEVATOR_INSERT_BACK 2
+#define ELEVATOR_INSERT_SORT 3
+#define ELEVATOR_INSERT_REQUEUE 4
+
+enum {
+ ELV_MQUEUE_MAY,
+ ELV_MQUEUE_NO,
+ ELV_MQUEUE_MUST,
+};
+
+#define rq_end_sector(rq) ((rq)->sector + (rq)->nr_sectors)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/elf-em.h b/ndk/build/platforms/android-1.5/common/include/linux/elf-em.h
new file mode 100644
index 0000000..e151fdf
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/elf-em.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ELF_EM_H
+#define _LINUX_ELF_EM_H
+
+#define EM_NONE 0
+#define EM_M32 1
+#define EM_SPARC 2
+#define EM_386 3
+#define EM_68K 4
+#define EM_88K 5
+#define EM_486 6  
+#define EM_860 7
+#define EM_MIPS 8  
+
+#define EM_MIPS_RS3_LE 10  
+#define EM_MIPS_RS4_BE 10  
+
+#define EM_PARISC 15  
+#define EM_SPARC32PLUS 18  
+#define EM_PPC 20  
+#define EM_PPC64 21  
+#define EM_SH 42  
+#define EM_SPARCV9 43  
+#define EM_IA_64 50  
+#define EM_X86_64 62  
+#define EM_S390 22  
+#define EM_CRIS 76  
+#define EM_V850 87  
+#define EM_M32R 88  
+#define EM_H8_300 46  
+#define EM_FRV 0x5441  
+
+#define EM_ALPHA 0x9026
+
+#define EM_CYGNUS_V850 0x9080
+
+#define EM_CYGNUS_M32R 0x9041
+
+#define EM_S390_OLD 0xA390
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/elf.h b/ndk/build/platforms/android-1.5/common/include/linux/elf.h
new file mode 100644
index 0000000..f16b439
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/elf.h
@@ -0,0 +1,361 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ELF_H
+#define _LINUX_ELF_H
+
+#include <linux/types.h>
+#include <linux/auxvec.h>
+#include <linux/elf-em.h>
+#include <asm/elf.h>
+
+#ifndef elf_read_implies_exec
+
+#define elf_read_implies_exec(ex, have_pt_gnu_stack) 0
+#endif
+
+typedef __u32 Elf32_Addr;
+typedef __u16 Elf32_Half;
+typedef __u32 Elf32_Off;
+typedef __s32 Elf32_Sword;
+typedef __u32 Elf32_Word;
+
+typedef __u64 Elf64_Addr;
+typedef __u16 Elf64_Half;
+typedef __s16 Elf64_SHalf;
+typedef __u64 Elf64_Off;
+typedef __s32 Elf64_Sword;
+typedef __u32 Elf64_Word;
+typedef __u64 Elf64_Xword;
+typedef __s64 Elf64_Sxword;
+
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_TLS 7  
+#define PT_LOOS 0x60000000  
+#define PT_HIOS 0x6fffffff  
+#define PT_LOPROC 0x70000000
+#define PT_HIPROC 0x7fffffff
+#define PT_GNU_EH_FRAME 0x6474e550
+
+#define PT_GNU_STACK (PT_LOOS + 0x474e551)
+
+#define ET_NONE 0
+#define ET_REL 1
+#define ET_EXEC 2
+#define ET_DYN 3
+#define ET_CORE 4
+#define ET_LOPROC 0xff00
+#define ET_HIPROC 0xffff
+
+#define DT_NULL 0
+#define DT_NEEDED 1
+#define DT_PLTRELSZ 2
+#define DT_PLTGOT 3
+#define DT_HASH 4
+#define DT_STRTAB 5
+#define DT_SYMTAB 6
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+#define DT_STRSZ 10
+#define DT_SYMENT 11
+#define DT_INIT 12
+#define DT_FINI 13
+#define DT_SONAME 14
+#define DT_RPATH 15
+#define DT_SYMBOLIC 16
+#define DT_REL 17
+#define DT_RELSZ 18
+#define DT_RELENT 19
+#define DT_PLTREL 20
+#define DT_DEBUG 21
+#define DT_TEXTREL 22
+#define DT_JMPREL 23
+#define DT_LOPROC 0x70000000
+#define DT_HIPROC 0x7fffffff
+
+#define STB_LOCAL 0
+#define STB_GLOBAL 1
+#define STB_WEAK 2
+
+#define STT_NOTYPE 0
+#define STT_OBJECT 1
+#define STT_FUNC 2
+#define STT_SECTION 3
+#define STT_FILE 4
+#define STT_COMMON 5
+#define STT_TLS 6
+
+#define ELF_ST_BIND(x) ((x) >> 4)
+#define ELF_ST_TYPE(x) (((unsigned int) x) & 0xf)
+#define ELF32_ST_BIND(x) ELF_ST_BIND(x)
+#define ELF32_ST_TYPE(x) ELF_ST_TYPE(x)
+#define ELF64_ST_BIND(x) ELF_ST_BIND(x)
+#define ELF64_ST_TYPE(x) ELF_ST_TYPE(x)
+
+typedef struct dynamic{
+ Elf32_Sword d_tag;
+ union{
+ Elf32_Sword d_val;
+ Elf32_Addr d_ptr;
+ } d_un;
+} Elf32_Dyn;
+
+typedef struct {
+ Elf64_Sxword d_tag;
+ union {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } d_un;
+} Elf64_Dyn;
+
+#define ELF32_R_SYM(x) ((x) >> 8)
+#define ELF32_R_TYPE(x) ((x) & 0xff)
+
+#define ELF64_R_SYM(i) ((i) >> 32)
+#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
+
+typedef struct elf32_rel {
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+} Elf32_Rel;
+
+typedef struct elf64_rel {
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+} Elf64_Rel;
+
+typedef struct elf32_rela{
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+ Elf32_Sword r_addend;
+} Elf32_Rela;
+
+typedef struct elf64_rela {
+ Elf64_Addr r_offset;
+ Elf64_Xword r_info;
+ Elf64_Sxword r_addend;
+} Elf64_Rela;
+
+typedef struct elf32_sym{
+ Elf32_Word st_name;
+ Elf32_Addr st_value;
+ Elf32_Word st_size;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf32_Half st_shndx;
+} Elf32_Sym;
+
+typedef struct elf64_sym {
+ Elf64_Word st_name;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf64_Half st_shndx;
+ Elf64_Addr st_value;
+ Elf64_Xword st_size;
+} Elf64_Sym;
+
+#define EI_NIDENT 16
+
+typedef struct elf32_hdr{
+ unsigned char e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry;
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct elf64_hdr {
+ unsigned char e_ident[16];
+ Elf64_Half e_type;
+ Elf64_Half e_machine;
+ Elf64_Word e_version;
+ Elf64_Addr e_entry;
+ Elf64_Off e_phoff;
+ Elf64_Off e_shoff;
+ Elf64_Word e_flags;
+ Elf64_Half e_ehsize;
+ Elf64_Half e_phentsize;
+ Elf64_Half e_phnum;
+ Elf64_Half e_shentsize;
+ Elf64_Half e_shnum;
+ Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+#define PF_R 0x4
+#define PF_W 0x2
+#define PF_X 0x1
+
+typedef struct elf32_phdr{
+ Elf32_Word p_type;
+ Elf32_Off p_offset;
+ Elf32_Addr p_vaddr;
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz;
+ Elf32_Word p_memsz;
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
+} Elf32_Phdr;
+
+typedef struct elf64_phdr {
+ Elf64_Word p_type;
+ Elf64_Word p_flags;
+ Elf64_Off p_offset;
+ Elf64_Addr p_vaddr;
+ Elf64_Addr p_paddr;
+ Elf64_Xword p_filesz;
+ Elf64_Xword p_memsz;
+ Elf64_Xword p_align;
+} Elf64_Phdr;
+
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+#define SHT_RELA 4
+#define SHT_HASH 5
+#define SHT_DYNAMIC 6
+#define SHT_NOTE 7
+#define SHT_NOBITS 8
+#define SHT_REL 9
+#define SHT_SHLIB 10
+#define SHT_DYNSYM 11
+#define SHT_NUM 12
+#define SHT_LOPROC 0x70000000
+#define SHT_HIPROC 0x7fffffff
+#define SHT_LOUSER 0x80000000
+#define SHT_HIUSER 0xffffffff
+
+#define SHF_WRITE 0x1
+#define SHF_ALLOC 0x2
+#define SHF_EXECINSTR 0x4
+#define SHF_MASKPROC 0xf0000000
+
+#define SHN_UNDEF 0
+#define SHN_LORESERVE 0xff00
+#define SHN_LOPROC 0xff00
+#define SHN_HIPROC 0xff1f
+#define SHN_ABS 0xfff1
+#define SHN_COMMON 0xfff2
+#define SHN_HIRESERVE 0xffff
+
+typedef struct {
+ Elf32_Word sh_name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_flags;
+ Elf32_Addr sh_addr;
+ Elf32_Off sh_offset;
+ Elf32_Word sh_size;
+ Elf32_Word sh_link;
+ Elf32_Word sh_info;
+ Elf32_Word sh_addralign;
+ Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+typedef struct elf64_shdr {
+ Elf64_Word sh_name;
+ Elf64_Word sh_type;
+ Elf64_Xword sh_flags;
+ Elf64_Addr sh_addr;
+ Elf64_Off sh_offset;
+ Elf64_Xword sh_size;
+ Elf64_Word sh_link;
+ Elf64_Word sh_info;
+ Elf64_Xword sh_addralign;
+ Elf64_Xword sh_entsize;
+} Elf64_Shdr;
+
+#define EI_MAG0 0  
+#define EI_MAG1 1
+#define EI_MAG2 2
+#define EI_MAG3 3
+#define EI_CLASS 4
+#define EI_DATA 5
+#define EI_VERSION 6
+#define EI_OSABI 7
+#define EI_PAD 8
+
+#define ELFMAG0 0x7f  
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define ELFCLASSNONE 0  
+#define ELFCLASS32 1
+#define ELFCLASS64 2
+#define ELFCLASSNUM 3
+
+#define ELFDATANONE 0  
+#define ELFDATA2LSB 1
+#define ELFDATA2MSB 2
+
+#define EV_NONE 0  
+#define EV_CURRENT 1
+#define EV_NUM 2
+
+#define ELFOSABI_NONE 0
+#define ELFOSABI_LINUX 3
+
+#ifndef ELF_OSABI
+#define ELF_OSABI ELFOSABI_NONE
+#endif
+
+#define NT_PRSTATUS 1
+#define NT_PRFPREG 2
+#define NT_PRPSINFO 3
+#define NT_TASKSTRUCT 4
+#define NT_AUXV 6
+#define NT_PRXFPREG 0x46e62b7f  
+
+typedef struct elf32_note {
+ Elf32_Word n_namesz;
+ Elf32_Word n_descsz;
+ Elf32_Word n_type;
+} Elf32_Nhdr;
+
+typedef struct elf64_note {
+ Elf64_Word n_namesz;
+ Elf64_Word n_descsz;
+ Elf64_Word n_type;
+} Elf64_Nhdr;
+
+#if ELF_CLASS == ELFCLASS32
+
+#define elfhdr elf32_hdr
+#define elf_phdr elf32_phdr
+#define elf_note elf32_note
+
+#else
+
+#define elfhdr elf64_hdr
+#define elf_phdr elf64_phdr
+#define elf_note elf64_note
+
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/err.h b/ndk/build/platforms/android-1.5/common/include/linux/err.h
new file mode 100644
index 0000000..1aa4f9b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/err.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ERR_H
+#define _LINUX_ERR_H
+
+#include <linux/compiler.h>
+
+#include <asm/errno.h>
+
+#define MAX_ERRNO 4095
+
+#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/errno.h b/ndk/build/platforms/android-1.5/common/include/linux/errno.h
new file mode 100644
index 0000000..72ee642
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/errno.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ERRNO_H
+#define _LINUX_ERRNO_H
+
+#include <asm/errno.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/errqueue.h b/ndk/build/platforms/android-1.5/common/include/linux/errqueue.h
new file mode 100644
index 0000000..03b2e42
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/errqueue.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ERRQUEUE_H
+#define _LINUX_ERRQUEUE_H 1
+
+struct sock_extended_err
+{
+ __u32 ee_errno;
+ __u8 ee_origin;
+ __u8 ee_type;
+ __u8 ee_code;
+ __u8 ee_pad;
+ __u32 ee_info;
+ __u32 ee_data;
+};
+
+#define SO_EE_ORIGIN_NONE 0
+#define SO_EE_ORIGIN_LOCAL 1
+#define SO_EE_ORIGIN_ICMP 2
+#define SO_EE_ORIGIN_ICMP6 3
+
+#define SO_EE_OFFENDER(ee) ((struct sockaddr*)((ee)+1))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/etherdevice.h b/ndk/build/platforms/android-1.5/common/include/linux/etherdevice.h
new file mode 100644
index 0000000..d087e8f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/etherdevice.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ETHERDEVICE_H
+#define _LINUX_ETHERDEVICE_H
+
+#include <linux/if_ether.h>
+#include <linux/netdevice.h>
+#include <linux/random.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ext2_fs.h b/ndk/build/platforms/android-1.5/common/include/linux/ext2_fs.h
new file mode 100644
index 0000000..c21b09a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ext2_fs.h
@@ -0,0 +1,378 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_EXT2_FS_H
+#define _LINUX_EXT2_FS_H
+
+#include <linux/types.h>
+
+#undef EXT2FS_DEBUG
+
+#define EXT2_PREALLOCATE
+#define EXT2_DEFAULT_PREALLOC_BLOCKS 8
+
+#define EXT2FS_DATE "95/08/09"
+#define EXT2FS_VERSION "0.5b"
+
+#ifdef EXT2FS_DEBUG
+#define ext2_debug(f, a...) {   printk ("EXT2-fs DEBUG (%s, %d): %s:",   __FILE__, __LINE__, __FUNCTION__);   printk (f, ## a);   }
+#else
+#define ext2_debug(f, a...)  
+#endif
+
+#define EXT2_BAD_INO 1  
+#define EXT2_ROOT_INO 2  
+#define EXT2_BOOT_LOADER_INO 5  
+#define EXT2_UNDEL_DIR_INO 6  
+
+#define EXT2_GOOD_OLD_FIRST_INO 11
+
+#define EXT2_SUPER_MAGIC 0xEF53
+
+#define EXT2_SB(sb) (sb)
+
+#define EXT2_LINK_MAX 32000
+
+#define EXT2_MIN_BLOCK_SIZE 1024
+#define EXT2_MAX_BLOCK_SIZE 4096
+#define EXT2_MIN_BLOCK_LOG_SIZE 10
+#define EXT2_BLOCK_SIZE(s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
+#define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10)
+#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ?   EXT2_GOOD_OLD_INODE_SIZE :   (s)->s_inode_size)
+#define EXT2_FIRST_INO(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ?   EXT2_GOOD_OLD_FIRST_INO :   (s)->s_first_ino)
+
+#define EXT2_MIN_FRAG_SIZE 1024
+#define EXT2_MAX_FRAG_SIZE 4096
+#define EXT2_MIN_FRAG_LOG_SIZE 10
+#define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
+#define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
+
+struct ext2_group_desc
+{
+ __le32 bg_block_bitmap;
+ __le32 bg_inode_bitmap;
+ __le32 bg_inode_table;
+ __le16 bg_free_blocks_count;
+ __le16 bg_free_inodes_count;
+ __le16 bg_used_dirs_count;
+ __le16 bg_pad;
+ __le32 bg_reserved[3];
+};
+
+#define EXT2_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group)
+#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
+#define EXT2_INODES_PER_GROUP(s) ((s)->s_inodes_per_group)
+
+#define EXT2_NDIR_BLOCKS 12
+#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
+#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
+#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
+#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
+
+#define EXT2_SECRM_FL 0x00000001  
+#define EXT2_UNRM_FL 0x00000002  
+#define EXT2_COMPR_FL 0x00000004  
+#define EXT2_SYNC_FL 0x00000008  
+#define EXT2_IMMUTABLE_FL 0x00000010  
+#define EXT2_APPEND_FL 0x00000020  
+#define EXT2_NODUMP_FL 0x00000040  
+#define EXT2_NOATIME_FL 0x00000080  
+
+#define EXT2_DIRTY_FL 0x00000100
+#define EXT2_COMPRBLK_FL 0x00000200  
+#define EXT2_NOCOMP_FL 0x00000400  
+#define EXT2_ECOMPR_FL 0x00000800  
+
+#define EXT2_BTREE_FL 0x00001000  
+#define EXT2_INDEX_FL 0x00001000  
+#define EXT2_IMAGIC_FL 0x00002000  
+#define EXT2_JOURNAL_DATA_FL 0x00004000  
+#define EXT2_NOTAIL_FL 0x00008000  
+#define EXT2_DIRSYNC_FL 0x00010000  
+#define EXT2_TOPDIR_FL 0x00020000  
+#define EXT2_RESERVED_FL 0x80000000  
+
+#define EXT2_FL_USER_VISIBLE 0x0003DFFF  
+#define EXT2_FL_USER_MODIFIABLE 0x000380FF  
+
+#define EXT2_IOC_GETFLAGS _IOR('f', 1, long)
+#define EXT2_IOC_SETFLAGS _IOW('f', 2, long)
+#define EXT2_IOC_GETVERSION _IOR('v', 1, long)
+#define EXT2_IOC_SETVERSION _IOW('v', 2, long)
+
+struct ext2_inode {
+ __le16 i_mode;
+ __le16 i_uid;
+ __le32 i_size;
+ __le32 i_atime;
+ __le32 i_ctime;
+ __le32 i_mtime;
+ __le32 i_dtime;
+ __le16 i_gid;
+ __le16 i_links_count;
+ __le32 i_blocks;
+ __le32 i_flags;
+ union {
+ struct {
+ __le32 l_i_reserved1;
+ } linux1;
+ struct {
+ __le32 h_i_translator;
+ } hurd1;
+ struct {
+ __le32 m_i_reserved1;
+ } masix1;
+ } osd1;
+ __le32 i_block[EXT2_N_BLOCKS];
+ __le32 i_generation;
+ __le32 i_file_acl;
+ __le32 i_dir_acl;
+ __le32 i_faddr;
+ union {
+ struct {
+ __u8 l_i_frag;
+ __u8 l_i_fsize;
+ __u16 i_pad1;
+ __le16 l_i_uid_high;
+ __le16 l_i_gid_high;
+ __u32 l_i_reserved2;
+ } linux2;
+ struct {
+ __u8 h_i_frag;
+ __u8 h_i_fsize;
+ __le16 h_i_mode_high;
+ __le16 h_i_uid_high;
+ __le16 h_i_gid_high;
+ __le32 h_i_author;
+ } hurd2;
+ struct {
+ __u8 m_i_frag;
+ __u8 m_i_fsize;
+ __u16 m_pad1;
+ __u32 m_i_reserved2[2];
+ } masix2;
+ } osd2;
+};
+
+#define i_size_high i_dir_acl
+
+#ifdef __linux__
+#define i_reserved1 osd1.linux1.l_i_reserved1
+#define i_frag osd2.linux2.l_i_frag
+#define i_fsize osd2.linux2.l_i_fsize
+#define i_uid_low i_uid
+#define i_gid_low i_gid
+#define i_uid_high osd2.linux2.l_i_uid_high
+#define i_gid_high osd2.linux2.l_i_gid_high
+#define i_reserved2 osd2.linux2.l_i_reserved2
+#endif
+
+#ifdef __hurd__
+#define i_translator osd1.hurd1.h_i_translator
+#define i_frag osd2.hurd2.h_i_frag;
+#define i_fsize osd2.hurd2.h_i_fsize;
+#define i_uid_high osd2.hurd2.h_i_uid_high
+#define i_gid_high osd2.hurd2.h_i_gid_high
+#define i_author osd2.hurd2.h_i_author
+#endif
+
+#ifdef __masix__
+#define i_reserved1 osd1.masix1.m_i_reserved1
+#define i_frag osd2.masix2.m_i_frag
+#define i_fsize osd2.masix2.m_i_fsize
+#define i_reserved2 osd2.masix2.m_i_reserved2
+#endif
+
+#define EXT2_VALID_FS 0x0001  
+#define EXT2_ERROR_FS 0x0002  
+
+#define EXT2_MOUNT_CHECK 0x000001  
+#define EXT2_MOUNT_OLDALLOC 0x000002  
+#define EXT2_MOUNT_GRPID 0x000004  
+#define EXT2_MOUNT_DEBUG 0x000008  
+#define EXT2_MOUNT_ERRORS_CONT 0x000010  
+#define EXT2_MOUNT_ERRORS_RO 0x000020  
+#define EXT2_MOUNT_ERRORS_PANIC 0x000040  
+#define EXT2_MOUNT_MINIX_DF 0x000080  
+#define EXT2_MOUNT_NOBH 0x000100  
+#define EXT2_MOUNT_NO_UID32 0x000200  
+#define EXT2_MOUNT_XATTR_USER 0x004000  
+#define EXT2_MOUNT_POSIX_ACL 0x008000  
+#define EXT2_MOUNT_XIP 0x010000  
+#define EXT2_MOUNT_USRQUOTA 0x020000  
+#define EXT2_MOUNT_GRPQUOTA 0x040000  
+
+#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
+#define set_opt(o, opt) o |= EXT2_MOUNT_##opt
+#define test_opt(sb, opt) (EXT2_SB(sb)->s_mount_opt &   EXT2_MOUNT_##opt)
+
+#define EXT2_DFL_MAX_MNT_COUNT 20  
+#define EXT2_DFL_CHECKINTERVAL 0  
+
+#define EXT2_ERRORS_CONTINUE 1  
+#define EXT2_ERRORS_RO 2  
+#define EXT2_ERRORS_PANIC 3  
+#define EXT2_ERRORS_DEFAULT EXT2_ERRORS_CONTINUE
+
+struct ext2_super_block {
+ __le32 s_inodes_count;
+ __le32 s_blocks_count;
+ __le32 s_r_blocks_count;
+ __le32 s_free_blocks_count;
+ __le32 s_free_inodes_count;
+ __le32 s_first_data_block;
+ __le32 s_log_block_size;
+ __le32 s_log_frag_size;
+ __le32 s_blocks_per_group;
+ __le32 s_frags_per_group;
+ __le32 s_inodes_per_group;
+ __le32 s_mtime;
+ __le32 s_wtime;
+ __le16 s_mnt_count;
+ __le16 s_max_mnt_count;
+ __le16 s_magic;
+ __le16 s_state;
+ __le16 s_errors;
+ __le16 s_minor_rev_level;
+ __le32 s_lastcheck;
+ __le32 s_checkinterval;
+ __le32 s_creator_os;
+ __le32 s_rev_level;
+ __le16 s_def_resuid;
+ __le16 s_def_resgid;
+
+ __le32 s_first_ino;
+ __le16 s_inode_size;
+ __le16 s_block_group_nr;
+ __le32 s_feature_compat;
+ __le32 s_feature_incompat;
+ __le32 s_feature_ro_compat;
+ __u8 s_uuid[16];
+ char s_volume_name[16];
+ char s_last_mounted[64];
+ __le32 s_algorithm_usage_bitmap;
+
+ __u8 s_prealloc_blocks;
+ __u8 s_prealloc_dir_blocks;
+ __u16 s_padding1;
+
+ __u8 s_journal_uuid[16];
+ __u32 s_journal_inum;
+ __u32 s_journal_dev;
+ __u32 s_last_orphan;
+ __u32 s_hash_seed[4];
+ __u8 s_def_hash_version;
+ __u8 s_reserved_char_pad;
+ __u16 s_reserved_word_pad;
+ __le32 s_default_mount_opts;
+ __le32 s_first_meta_bg;
+ __u32 s_reserved[190];
+};
+
+#define EXT2_OS_LINUX 0
+#define EXT2_OS_HURD 1
+#define EXT2_OS_MASIX 2
+#define EXT2_OS_FREEBSD 3
+#define EXT2_OS_LITES 4
+
+#define EXT2_GOOD_OLD_REV 0  
+#define EXT2_DYNAMIC_REV 1  
+
+#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
+#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV
+
+#define EXT2_GOOD_OLD_INODE_SIZE 128
+
+#define EXT2_HAS_COMPAT_FEATURE(sb,mask)   ( EXT2_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) )
+#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask)   ( EXT2_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) )
+#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask)   ( EXT2_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) )
+#define EXT2_SET_COMPAT_FEATURE(sb,mask)   EXT2_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask)
+#define EXT2_SET_RO_COMPAT_FEATURE(sb,mask)   EXT2_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask)
+#define EXT2_SET_INCOMPAT_FEATURE(sb,mask)   EXT2_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask)
+#define EXT2_CLEAR_COMPAT_FEATURE(sb,mask)   EXT2_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask)
+#define EXT2_CLEAR_RO_COMPAT_FEATURE(sb,mask)   EXT2_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask)
+#define EXT2_CLEAR_INCOMPAT_FEATURE(sb,mask)   EXT2_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask)
+
+#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001
+#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002
+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
+#define EXT2_FEATURE_COMPAT_EXT_ATTR 0x0008
+#define EXT2_FEATURE_COMPAT_RESIZE_INO 0x0010
+#define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020
+#define EXT2_FEATURE_COMPAT_ANY 0xffffffff
+
+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
+#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
+#define EXT2_FEATURE_RO_COMPAT_ANY 0xffffffff
+
+#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001
+#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
+#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004
+#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008
+#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010
+#define EXT2_FEATURE_INCOMPAT_ANY 0xffffffff
+
+#define EXT2_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR
+#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|   EXT2_FEATURE_INCOMPAT_META_BG)
+#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|   EXT2_FEATURE_RO_COMPAT_LARGE_FILE|   EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
+#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT2_FEATURE_RO_COMPAT_SUPP
+#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED ~EXT2_FEATURE_INCOMPAT_SUPP
+
+#define EXT2_DEF_RESUID 0
+#define EXT2_DEF_RESGID 0
+
+#define EXT2_DEFM_DEBUG 0x0001
+#define EXT2_DEFM_BSDGROUPS 0x0002
+#define EXT2_DEFM_XATTR_USER 0x0004
+#define EXT2_DEFM_ACL 0x0008
+#define EXT2_DEFM_UID16 0x0010
+
+#define EXT3_DEFM_JMODE 0x0060 
+#define EXT3_DEFM_JMODE_DATA 0x0020
+#define EXT3_DEFM_JMODE_ORDERED 0x0040
+#define EXT3_DEFM_JMODE_WBACK 0x0060
+
+#define EXT2_NAME_LEN 255
+
+struct ext2_dir_entry {
+ __le32 inode;
+ __le16 rec_len;
+ __le16 name_len;
+ char name[EXT2_NAME_LEN];
+};
+
+struct ext2_dir_entry_2 {
+ __le32 inode;
+ __le16 rec_len;
+ __u8 name_len;
+ __u8 file_type;
+ char name[EXT2_NAME_LEN];
+};
+
+enum {
+ EXT2_FT_UNKNOWN,
+ EXT2_FT_REG_FILE,
+ EXT2_FT_DIR,
+ EXT2_FT_CHRDEV,
+ EXT2_FT_BLKDEV,
+ EXT2_FT_FIFO,
+ EXT2_FT_SOCK,
+ EXT2_FT_SYMLINK,
+ EXT2_FT_MAX
+};
+
+#define EXT2_DIR_PAD 4
+#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1)
+#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) &   ~EXT2_DIR_ROUND)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ext3_fs.h b/ndk/build/platforms/android-1.5/common/include/linux/ext3_fs.h
new file mode 100644
index 0000000..8016fd1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ext3_fs.h
@@ -0,0 +1,448 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_EXT3_FS_H
+#define _LINUX_EXT3_FS_H
+
+#include <linux/types.h>
+
+#undef EXT3FS_DEBUG
+
+#define EXT3_DEFAULT_RESERVE_BLOCKS 8
+
+#define EXT3_MAX_RESERVE_BLOCKS 1027
+#define EXT3_RESERVE_WINDOW_NOT_ALLOCATED 0
+
+#define CONFIG_EXT3_INDEX
+
+#ifdef EXT3FS_DEBUG
+#define ext3_debug(f, a...)   do {   printk (KERN_DEBUG "EXT3-fs DEBUG (%s, %d): %s:",   __FILE__, __LINE__, __FUNCTION__);   printk (KERN_DEBUG f, ## a);   } while (0)
+#else
+#define ext3_debug(f, a...) do {} while (0)
+#endif
+
+#define EXT3_BAD_INO 1  
+#define EXT3_ROOT_INO 2  
+#define EXT3_BOOT_LOADER_INO 5  
+#define EXT3_UNDEL_DIR_INO 6  
+#define EXT3_RESIZE_INO 7  
+#define EXT3_JOURNAL_INO 8  
+
+#define EXT3_GOOD_OLD_FIRST_INO 11
+
+#define EXT3_SUPER_MAGIC 0xEF53
+
+#define EXT3_LINK_MAX 32000
+
+#define EXT3_MIN_BLOCK_SIZE 1024
+#define EXT3_MAX_BLOCK_SIZE 4096
+#define EXT3_MIN_BLOCK_LOG_SIZE 10
+#define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size)
+#define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32))
+#define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10)
+#define EXT3_INODE_SIZE(s) (((s)->s_rev_level == EXT3_GOOD_OLD_REV) ?   EXT3_GOOD_OLD_INODE_SIZE :   (s)->s_inode_size)
+#define EXT3_FIRST_INO(s) (((s)->s_rev_level == EXT3_GOOD_OLD_REV) ?   EXT3_GOOD_OLD_FIRST_INO :   (s)->s_first_ino)
+
+#define EXT3_MIN_FRAG_SIZE 1024
+#define EXT3_MAX_FRAG_SIZE 4096
+#define EXT3_MIN_FRAG_LOG_SIZE 10
+#define EXT3_FRAG_SIZE(s) (EXT3_MIN_FRAG_SIZE << (s)->s_log_frag_size)
+#define EXT3_FRAGS_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / EXT3_FRAG_SIZE(s))
+
+struct ext3_group_desc
+{
+ __le32 bg_block_bitmap;
+ __le32 bg_inode_bitmap;
+ __le32 bg_inode_table;
+ __le16 bg_free_blocks_count;
+ __le16 bg_free_inodes_count;
+ __le16 bg_used_dirs_count;
+ __u16 bg_pad;
+ __le32 bg_reserved[3];
+};
+
+#define EXT3_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group)
+#define EXT3_DESC_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_group_desc))
+#define EXT3_INODES_PER_GROUP(s) ((s)->s_inodes_per_group)
+
+#define EXT3_NDIR_BLOCKS 12
+#define EXT3_IND_BLOCK EXT3_NDIR_BLOCKS
+#define EXT3_DIND_BLOCK (EXT3_IND_BLOCK + 1)
+#define EXT3_TIND_BLOCK (EXT3_DIND_BLOCK + 1)
+#define EXT3_N_BLOCKS (EXT3_TIND_BLOCK + 1)
+
+#define EXT3_SECRM_FL 0x00000001  
+#define EXT3_UNRM_FL 0x00000002  
+#define EXT3_COMPR_FL 0x00000004  
+#define EXT3_SYNC_FL 0x00000008  
+#define EXT3_IMMUTABLE_FL 0x00000010  
+#define EXT3_APPEND_FL 0x00000020  
+#define EXT3_NODUMP_FL 0x00000040  
+#define EXT3_NOATIME_FL 0x00000080  
+
+#define EXT3_DIRTY_FL 0x00000100
+#define EXT3_COMPRBLK_FL 0x00000200  
+#define EXT3_NOCOMPR_FL 0x00000400  
+#define EXT3_ECOMPR_FL 0x00000800  
+
+#define EXT3_INDEX_FL 0x00001000  
+#define EXT3_IMAGIC_FL 0x00002000  
+#define EXT3_JOURNAL_DATA_FL 0x00004000  
+#define EXT3_NOTAIL_FL 0x00008000  
+#define EXT3_DIRSYNC_FL 0x00010000  
+#define EXT3_TOPDIR_FL 0x00020000  
+#define EXT3_RESERVED_FL 0x80000000  
+
+#define EXT3_FL_USER_VISIBLE 0x0003DFFF  
+#define EXT3_FL_USER_MODIFIABLE 0x000380FF  
+
+#define EXT3_STATE_JDATA 0x00000001  
+#define EXT3_STATE_NEW 0x00000002  
+#define EXT3_STATE_XATTR 0x00000004  
+
+struct ext3_new_group_input {
+ __u32 group;
+ __u32 block_bitmap;
+ __u32 inode_bitmap;
+ __u32 inode_table;
+ __u32 blocks_count;
+ __u16 reserved_blocks;
+ __u16 unused;
+};
+
+struct ext3_new_group_data {
+ __u32 group;
+ __u32 block_bitmap;
+ __u32 inode_bitmap;
+ __u32 inode_table;
+ __u32 blocks_count;
+ __u16 reserved_blocks;
+ __u16 unused;
+ __u32 free_blocks_count;
+};
+
+#define EXT3_IOC_GETFLAGS _IOR('f', 1, long)
+#define EXT3_IOC_SETFLAGS _IOW('f', 2, long)
+#define EXT3_IOC_GETVERSION _IOR('f', 3, long)
+#define EXT3_IOC_SETVERSION _IOW('f', 4, long)
+#define EXT3_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
+#define EXT3_IOC_GROUP_ADD _IOW('f', 8,struct ext3_new_group_input)
+#define EXT3_IOC_GETVERSION_OLD _IOR('v', 1, long)
+#define EXT3_IOC_SETVERSION_OLD _IOW('v', 2, long)
+#define EXT3_IOC_GETRSVSZ _IOR('f', 5, long)
+#define EXT3_IOC_SETRSVSZ _IOW('f', 6, long)
+
+struct ext3_mount_options {
+ unsigned long s_mount_opt;
+ uid_t s_resuid;
+ gid_t s_resgid;
+ unsigned long s_commit_interval;
+};
+
+struct ext3_inode {
+ __le16 i_mode;
+ __le16 i_uid;
+ __le32 i_size;
+ __le32 i_atime;
+ __le32 i_ctime;
+ __le32 i_mtime;
+ __le32 i_dtime;
+ __le16 i_gid;
+ __le16 i_links_count;
+ __le32 i_blocks;
+ __le32 i_flags;
+ union {
+ struct {
+ __u32 l_i_reserved1;
+ } linux1;
+ struct {
+ __u32 h_i_translator;
+ } hurd1;
+ struct {
+ __u32 m_i_reserved1;
+ } masix1;
+ } osd1;
+ __le32 i_block[EXT3_N_BLOCKS];
+ __le32 i_generation;
+ __le32 i_file_acl;
+ __le32 i_dir_acl;
+ __le32 i_faddr;
+ union {
+ struct {
+ __u8 l_i_frag;
+ __u8 l_i_fsize;
+ __u16 i_pad1;
+ __le16 l_i_uid_high;
+ __le16 l_i_gid_high;
+ __u32 l_i_reserved2;
+ } linux2;
+ struct {
+ __u8 h_i_frag;
+ __u8 h_i_fsize;
+ __u16 h_i_mode_high;
+ __u16 h_i_uid_high;
+ __u16 h_i_gid_high;
+ __u32 h_i_author;
+ } hurd2;
+ struct {
+ __u8 m_i_frag;
+ __u8 m_i_fsize;
+ __u16 m_pad1;
+ __u32 m_i_reserved2[2];
+ } masix2;
+ } osd2;
+ __le16 i_extra_isize;
+ __le16 i_pad1;
+};
+
+#define i_size_high i_dir_acl
+
+#ifdef __linux__
+#define i_reserved1 osd1.linux1.l_i_reserved1
+#define i_frag osd2.linux2.l_i_frag
+#define i_fsize osd2.linux2.l_i_fsize
+#define i_uid_low i_uid
+#define i_gid_low i_gid
+#define i_uid_high osd2.linux2.l_i_uid_high
+#define i_gid_high osd2.linux2.l_i_gid_high
+#define i_reserved2 osd2.linux2.l_i_reserved2
+
+#elif defined(__GNU__)
+
+#define i_translator osd1.hurd1.h_i_translator
+#define i_frag osd2.hurd2.h_i_frag;
+#define i_fsize osd2.hurd2.h_i_fsize;
+#define i_uid_high osd2.hurd2.h_i_uid_high
+#define i_gid_high osd2.hurd2.h_i_gid_high
+#define i_author osd2.hurd2.h_i_author
+
+#elif defined(__masix__)
+
+#define i_reserved1 osd1.masix1.m_i_reserved1
+#define i_frag osd2.masix2.m_i_frag
+#define i_fsize osd2.masix2.m_i_fsize
+#define i_reserved2 osd2.masix2.m_i_reserved2
+
+#endif
+
+#define EXT3_VALID_FS 0x0001  
+#define EXT3_ERROR_FS 0x0002  
+#define EXT3_ORPHAN_FS 0x0004  
+
+#define EXT3_MOUNT_CHECK 0x00001  
+#define EXT3_MOUNT_OLDALLOC 0x00002  
+#define EXT3_MOUNT_GRPID 0x00004  
+#define EXT3_MOUNT_DEBUG 0x00008  
+#define EXT3_MOUNT_ERRORS_CONT 0x00010  
+#define EXT3_MOUNT_ERRORS_RO 0x00020  
+#define EXT3_MOUNT_ERRORS_PANIC 0x00040  
+#define EXT3_MOUNT_MINIX_DF 0x00080  
+#define EXT3_MOUNT_NOLOAD 0x00100  
+#define EXT3_MOUNT_ABORT 0x00200  
+#define EXT3_MOUNT_DATA_FLAGS 0x00C00  
+#define EXT3_MOUNT_JOURNAL_DATA 0x00400  
+#define EXT3_MOUNT_ORDERED_DATA 0x00800  
+#define EXT3_MOUNT_WRITEBACK_DATA 0x00C00  
+#define EXT3_MOUNT_UPDATE_JOURNAL 0x01000  
+#define EXT3_MOUNT_NO_UID32 0x02000  
+#define EXT3_MOUNT_XATTR_USER 0x04000  
+#define EXT3_MOUNT_POSIX_ACL 0x08000  
+#define EXT3_MOUNT_RESERVATION 0x10000  
+#define EXT3_MOUNT_BARRIER 0x20000  
+#define EXT3_MOUNT_NOBH 0x40000  
+#define EXT3_MOUNT_QUOTA 0x80000  
+#define EXT3_MOUNT_USRQUOTA 0x100000  
+#define EXT3_MOUNT_GRPQUOTA 0x200000  
+
+#ifndef _LINUX_EXT2_FS_H
+#define clear_opt(o, opt) o &= ~EXT3_MOUNT_##opt
+#define set_opt(o, opt) o |= EXT3_MOUNT_##opt
+#define test_opt(sb, opt) (EXT3_SB(sb)->s_mount_opt &   EXT3_MOUNT_##opt)
+#else
+#define EXT2_MOUNT_NOLOAD EXT3_MOUNT_NOLOAD
+#define EXT2_MOUNT_ABORT EXT3_MOUNT_ABORT
+#define EXT2_MOUNT_DATA_FLAGS EXT3_MOUNT_DATA_FLAGS
+#endif
+
+#define ext3_set_bit ext2_set_bit
+#define ext3_set_bit_atomic ext2_set_bit_atomic
+#define ext3_clear_bit ext2_clear_bit
+#define ext3_clear_bit_atomic ext2_clear_bit_atomic
+#define ext3_test_bit ext2_test_bit
+#define ext3_find_first_zero_bit ext2_find_first_zero_bit
+#define ext3_find_next_zero_bit ext2_find_next_zero_bit
+
+#define EXT3_DFL_MAX_MNT_COUNT 20  
+#define EXT3_DFL_CHECKINTERVAL 0  
+
+#define EXT3_ERRORS_CONTINUE 1  
+#define EXT3_ERRORS_RO 2  
+#define EXT3_ERRORS_PANIC 3  
+#define EXT3_ERRORS_DEFAULT EXT3_ERRORS_CONTINUE
+
+struct ext3_super_block {
+  __le32 s_inodes_count;
+ __le32 s_blocks_count;
+ __le32 s_r_blocks_count;
+ __le32 s_free_blocks_count;
+  __le32 s_free_inodes_count;
+ __le32 s_first_data_block;
+ __le32 s_log_block_size;
+ __le32 s_log_frag_size;
+  __le32 s_blocks_per_group;
+ __le32 s_frags_per_group;
+ __le32 s_inodes_per_group;
+ __le32 s_mtime;
+  __le32 s_wtime;
+ __le16 s_mnt_count;
+ __le16 s_max_mnt_count;
+ __le16 s_magic;
+ __le16 s_state;
+ __le16 s_errors;
+ __le16 s_minor_rev_level;
+  __le32 s_lastcheck;
+ __le32 s_checkinterval;
+ __le32 s_creator_os;
+ __le32 s_rev_level;
+  __le16 s_def_resuid;
+ __le16 s_def_resgid;
+
+ __le32 s_first_ino;
+ __le16 s_inode_size;
+ __le16 s_block_group_nr;
+ __le32 s_feature_compat;
+  __le32 s_feature_incompat;
+ __le32 s_feature_ro_compat;
+  __u8 s_uuid[16];
+  char s_volume_name[16];
+  char s_last_mounted[64];
+  __le32 s_algorithm_usage_bitmap;
+
+ __u8 s_prealloc_blocks;
+ __u8 s_prealloc_dir_blocks;
+ __u16 s_reserved_gdt_blocks;
+
+  __u8 s_journal_uuid[16];
+  __le32 s_journal_inum;
+ __le32 s_journal_dev;
+ __le32 s_last_orphan;
+ __le32 s_hash_seed[4];
+ __u8 s_def_hash_version;
+ __u8 s_reserved_char_pad;
+ __u16 s_reserved_word_pad;
+ __le32 s_default_mount_opts;
+ __le32 s_first_meta_bg;
+ __u32 s_reserved[190];
+};
+
+#define EXT3_SB(sb) (sb)
+
+#define NEXT_ORPHAN(inode) EXT3_I(inode)->i_dtime
+
+#define EXT3_OS_LINUX 0
+#define EXT3_OS_HURD 1
+#define EXT3_OS_MASIX 2
+#define EXT3_OS_FREEBSD 3
+#define EXT3_OS_LITES 4
+
+#define EXT3_GOOD_OLD_REV 0  
+#define EXT3_DYNAMIC_REV 1  
+
+#define EXT3_CURRENT_REV EXT3_GOOD_OLD_REV
+#define EXT3_MAX_SUPP_REV EXT3_DYNAMIC_REV
+
+#define EXT3_GOOD_OLD_INODE_SIZE 128
+
+#define EXT3_HAS_COMPAT_FEATURE(sb,mask)   ( EXT3_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) )
+#define EXT3_HAS_RO_COMPAT_FEATURE(sb,mask)   ( EXT3_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) )
+#define EXT3_HAS_INCOMPAT_FEATURE(sb,mask)   ( EXT3_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) )
+#define EXT3_SET_COMPAT_FEATURE(sb,mask)   EXT3_SB(sb)->s_es->s_feature_compat |= cpu_to_le32(mask)
+#define EXT3_SET_RO_COMPAT_FEATURE(sb,mask)   EXT3_SB(sb)->s_es->s_feature_ro_compat |= cpu_to_le32(mask)
+#define EXT3_SET_INCOMPAT_FEATURE(sb,mask)   EXT3_SB(sb)->s_es->s_feature_incompat |= cpu_to_le32(mask)
+#define EXT3_CLEAR_COMPAT_FEATURE(sb,mask)   EXT3_SB(sb)->s_es->s_feature_compat &= ~cpu_to_le32(mask)
+#define EXT3_CLEAR_RO_COMPAT_FEATURE(sb,mask)   EXT3_SB(sb)->s_es->s_feature_ro_compat &= ~cpu_to_le32(mask)
+#define EXT3_CLEAR_INCOMPAT_FEATURE(sb,mask)   EXT3_SB(sb)->s_es->s_feature_incompat &= ~cpu_to_le32(mask)
+
+#define EXT3_FEATURE_COMPAT_DIR_PREALLOC 0x0001
+#define EXT3_FEATURE_COMPAT_IMAGIC_INODES 0x0002
+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
+#define EXT3_FEATURE_COMPAT_EXT_ATTR 0x0008
+#define EXT3_FEATURE_COMPAT_RESIZE_INODE 0x0010
+#define EXT3_FEATURE_COMPAT_DIR_INDEX 0x0020
+
+#define EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
+#define EXT3_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
+#define EXT3_FEATURE_RO_COMPAT_BTREE_DIR 0x0004
+
+#define EXT3_FEATURE_INCOMPAT_COMPRESSION 0x0001
+#define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002
+#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004  
+#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008  
+#define EXT3_FEATURE_INCOMPAT_META_BG 0x0010
+
+#define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR
+#define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE|   EXT3_FEATURE_INCOMPAT_RECOVER|   EXT3_FEATURE_INCOMPAT_META_BG)
+#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER|   EXT3_FEATURE_RO_COMPAT_LARGE_FILE|   EXT3_FEATURE_RO_COMPAT_BTREE_DIR)
+
+#define EXT3_DEF_RESUID 0
+#define EXT3_DEF_RESGID 0
+
+#define EXT3_DEFM_DEBUG 0x0001
+#define EXT3_DEFM_BSDGROUPS 0x0002
+#define EXT3_DEFM_XATTR_USER 0x0004
+#define EXT3_DEFM_ACL 0x0008
+#define EXT3_DEFM_UID16 0x0010
+#define EXT3_DEFM_JMODE 0x0060
+#define EXT3_DEFM_JMODE_DATA 0x0020
+#define EXT3_DEFM_JMODE_ORDERED 0x0040
+#define EXT3_DEFM_JMODE_WBACK 0x0060
+
+#define EXT3_NAME_LEN 255
+
+struct ext3_dir_entry {
+ __le32 inode;
+ __le16 rec_len;
+ __le16 name_len;
+ char name[EXT3_NAME_LEN];
+};
+
+struct ext3_dir_entry_2 {
+ __le32 inode;
+ __le16 rec_len;
+ __u8 name_len;
+ __u8 file_type;
+ char name[EXT3_NAME_LEN];
+};
+
+#define EXT3_FT_UNKNOWN 0
+#define EXT3_FT_REG_FILE 1
+#define EXT3_FT_DIR 2
+#define EXT3_FT_CHRDEV 3
+#define EXT3_FT_BLKDEV 4
+#define EXT3_FT_FIFO 5
+#define EXT3_FT_SOCK 6
+#define EXT3_FT_SYMLINK 7
+
+#define EXT3_FT_MAX 8
+
+#define EXT3_DIR_PAD 4
+#define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1)
+#define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) &   ~EXT3_DIR_ROUND)
+
+#define is_dx(dir) 0
+#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX)
+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2)
+
+#define DX_HASH_LEGACY 0
+#define DX_HASH_HALF_MD4 1
+#define DX_HASH_TEA 2
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/fadvise.h b/ndk/build/platforms/android-1.5/common/include/linux/fadvise.h
new file mode 100644
index 0000000..25a0a4c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/fadvise.h
@@ -0,0 +1,28 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef FADVISE_H_INCLUDED
+#define FADVISE_H_INCLUDED
+
+#define POSIX_FADV_NORMAL 0  
+#define POSIX_FADV_RANDOM 1  
+#define POSIX_FADV_SEQUENTIAL 2  
+#define POSIX_FADV_WILLNEED 3  
+
+#ifdef __s390x__
+#define POSIX_FADV_DONTNEED 6  
+#define POSIX_FADV_NOREUSE 7  
+#else
+#define POSIX_FADV_DONTNEED 4  
+#define POSIX_FADV_NOREUSE 5  
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/fb.h b/ndk/build/platforms/android-1.5/common/include/linux/fb.h
new file mode 100644
index 0000000..336c439
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/fb.h
@@ -0,0 +1,347 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_FB_H
+#define _LINUX_FB_H
+
+#include <asm/types.h>
+
+#define FB_MAJOR 29
+#define FB_MAX 32  
+
+#define FBIOGET_VSCREENINFO 0x4600
+#define FBIOPUT_VSCREENINFO 0x4601
+#define FBIOGET_FSCREENINFO 0x4602
+#define FBIOGETCMAP 0x4604
+#define FBIOPUTCMAP 0x4605
+#define FBIOPAN_DISPLAY 0x4606
+#define FBIO_CURSOR _IOWR('F', 0x08, struct fb_cursor)
+
+#define FBIOGET_CON2FBMAP 0x460F
+#define FBIOPUT_CON2FBMAP 0x4610
+#define FBIOBLANK 0x4611  
+#define FBIOGET_VBLANK _IOR('F', 0x12, struct fb_vblank)
+#define FBIO_ALLOC 0x4613
+#define FBIO_FREE 0x4614
+#define FBIOGET_GLYPH 0x4615
+#define FBIOGET_HWCINFO 0x4616
+#define FBIOPUT_MODEINFO 0x4617
+#define FBIOGET_DISPINFO 0x4618
+
+#define FB_TYPE_PACKED_PIXELS 0  
+#define FB_TYPE_PLANES 1  
+#define FB_TYPE_INTERLEAVED_PLANES 2  
+#define FB_TYPE_TEXT 3  
+#define FB_TYPE_VGA_PLANES 4  
+
+#define FB_AUX_TEXT_MDA 0  
+#define FB_AUX_TEXT_CGA 1  
+#define FB_AUX_TEXT_S3_MMIO 2  
+#define FB_AUX_TEXT_MGA_STEP16 3  
+#define FB_AUX_TEXT_MGA_STEP8 4  
+
+#define FB_AUX_VGA_PLANES_VGA4 0  
+#define FB_AUX_VGA_PLANES_CFB4 1  
+#define FB_AUX_VGA_PLANES_CFB8 2  
+
+#define FB_VISUAL_MONO01 0  
+#define FB_VISUAL_MONO10 1  
+#define FB_VISUAL_TRUECOLOR 2  
+#define FB_VISUAL_PSEUDOCOLOR 3  
+#define FB_VISUAL_DIRECTCOLOR 4  
+#define FB_VISUAL_STATIC_PSEUDOCOLOR 5  
+
+#define FB_ACCEL_NONE 0  
+#define FB_ACCEL_ATARIBLITT 1  
+#define FB_ACCEL_AMIGABLITT 2  
+#define FB_ACCEL_S3_TRIO64 3  
+#define FB_ACCEL_NCR_77C32BLT 4  
+#define FB_ACCEL_S3_VIRGE 5  
+#define FB_ACCEL_ATI_MACH64GX 6  
+#define FB_ACCEL_DEC_TGA 7  
+#define FB_ACCEL_ATI_MACH64CT 8  
+#define FB_ACCEL_ATI_MACH64VT 9  
+#define FB_ACCEL_ATI_MACH64GT 10  
+#define FB_ACCEL_SUN_CREATOR 11  
+#define FB_ACCEL_SUN_CGSIX 12  
+#define FB_ACCEL_SUN_LEO 13  
+#define FB_ACCEL_IMS_TWINTURBO 14  
+#define FB_ACCEL_3DLABS_PERMEDIA2 15  
+#define FB_ACCEL_MATROX_MGA2064W 16  
+#define FB_ACCEL_MATROX_MGA1064SG 17  
+#define FB_ACCEL_MATROX_MGA2164W 18  
+#define FB_ACCEL_MATROX_MGA2164W_AGP 19  
+#define FB_ACCEL_MATROX_MGAG100 20  
+#define FB_ACCEL_MATROX_MGAG200 21  
+#define FB_ACCEL_SUN_CG14 22  
+#define FB_ACCEL_SUN_BWTWO 23  
+#define FB_ACCEL_SUN_CGTHREE 24  
+#define FB_ACCEL_SUN_TCX 25  
+#define FB_ACCEL_MATROX_MGAG400 26  
+#define FB_ACCEL_NV3 27  
+#define FB_ACCEL_NV4 28  
+#define FB_ACCEL_NV5 29  
+#define FB_ACCEL_CT_6555x 30  
+#define FB_ACCEL_3DFX_BANSHEE 31  
+#define FB_ACCEL_ATI_RAGE128 32  
+#define FB_ACCEL_IGS_CYBER2000 33  
+#define FB_ACCEL_IGS_CYBER2010 34  
+#define FB_ACCEL_IGS_CYBER5000 35  
+#define FB_ACCEL_SIS_GLAMOUR 36  
+#define FB_ACCEL_3DLABS_PERMEDIA3 37  
+#define FB_ACCEL_ATI_RADEON 38  
+#define FB_ACCEL_I810 39  
+#define FB_ACCEL_SIS_GLAMOUR_2 40  
+#define FB_ACCEL_SIS_XABRE 41  
+#define FB_ACCEL_I830 42  
+#define FB_ACCEL_NV_10 43  
+#define FB_ACCEL_NV_20 44  
+#define FB_ACCEL_NV_30 45  
+#define FB_ACCEL_NV_40 46  
+#define FB_ACCEL_XGI_VOLARI_V 47  
+#define FB_ACCEL_XGI_VOLARI_Z 48  
+#define FB_ACCEL_OMAP1610 49  
+#define FB_ACCEL_NEOMAGIC_NM2070 90  
+#define FB_ACCEL_NEOMAGIC_NM2090 91  
+#define FB_ACCEL_NEOMAGIC_NM2093 92  
+#define FB_ACCEL_NEOMAGIC_NM2097 93  
+#define FB_ACCEL_NEOMAGIC_NM2160 94  
+#define FB_ACCEL_NEOMAGIC_NM2200 95  
+#define FB_ACCEL_NEOMAGIC_NM2230 96  
+#define FB_ACCEL_NEOMAGIC_NM2360 97  
+#define FB_ACCEL_NEOMAGIC_NM2380 98  
+
+#define FB_ACCEL_SAVAGE4 0x80  
+#define FB_ACCEL_SAVAGE3D 0x81  
+#define FB_ACCEL_SAVAGE3D_MV 0x82  
+#define FB_ACCEL_SAVAGE2000 0x83  
+#define FB_ACCEL_SAVAGE_MX_MV 0x84  
+#define FB_ACCEL_SAVAGE_MX 0x85  
+#define FB_ACCEL_SAVAGE_IX_MV 0x86  
+#define FB_ACCEL_SAVAGE_IX 0x87  
+#define FB_ACCEL_PROSAVAGE_PM 0x88  
+#define FB_ACCEL_PROSAVAGE_KM 0x89  
+#define FB_ACCEL_S3TWISTER_P 0x8a  
+#define FB_ACCEL_S3TWISTER_K 0x8b  
+#define FB_ACCEL_SUPERSAVAGE 0x8c  
+#define FB_ACCEL_PROSAVAGE_DDR 0x8d  
+#define FB_ACCEL_PROSAVAGE_DDRK 0x8e  
+
+struct fb_fix_screeninfo {
+ char id[16];
+ unsigned long smem_start;
+
+ __u32 smem_len;
+ __u32 type;
+ __u32 type_aux;
+ __u32 visual;
+ __u16 xpanstep;
+ __u16 ypanstep;
+ __u16 ywrapstep;
+ __u32 line_length;
+ unsigned long mmio_start;
+
+ __u32 mmio_len;
+ __u32 accel;
+
+ __u16 reserved[3];
+};
+
+struct fb_bitfield {
+ __u32 offset;
+ __u32 length;
+ __u32 msb_right;
+
+};
+
+#define FB_NONSTD_HAM 1  
+
+#define FB_ACTIVATE_NOW 0  
+#define FB_ACTIVATE_NXTOPEN 1  
+#define FB_ACTIVATE_TEST 2  
+#define FB_ACTIVATE_MASK 15
+
+#define FB_ACTIVATE_VBL 16  
+#define FB_CHANGE_CMAP_VBL 32  
+#define FB_ACTIVATE_ALL 64  
+#define FB_ACTIVATE_FORCE 128  
+#define FB_ACTIVATE_INV_MODE 256  
+
+#define FB_ACCELF_TEXT 1  
+
+#define FB_SYNC_HOR_HIGH_ACT 1  
+#define FB_SYNC_VERT_HIGH_ACT 2  
+#define FB_SYNC_EXT 4  
+#define FB_SYNC_COMP_HIGH_ACT 8  
+#define FB_SYNC_BROADCAST 16  
+
+#define FB_SYNC_ON_GREEN 32  
+
+#define FB_VMODE_NONINTERLACED 0  
+#define FB_VMODE_INTERLACED 1  
+#define FB_VMODE_DOUBLE 2  
+#define FB_VMODE_MASK 255
+
+#define FB_VMODE_YWRAP 256  
+#define FB_VMODE_SMOOTH_XPAN 512  
+#define FB_VMODE_CONUPDATE 512  
+
+#define FB_ROTATE_UR 0
+#define FB_ROTATE_CW 1
+#define FB_ROTATE_UD 2
+#define FB_ROTATE_CCW 3
+
+#define PICOS2KHZ(a) (1000000000UL/(a))
+#define KHZ2PICOS(a) (1000000000UL/(a))
+
+struct fb_var_screeninfo {
+ __u32 xres;
+ __u32 yres;
+ __u32 xres_virtual;
+ __u32 yres_virtual;
+ __u32 xoffset;
+ __u32 yoffset;
+
+ __u32 bits_per_pixel;
+ __u32 grayscale;
+
+ struct fb_bitfield red;
+ struct fb_bitfield green;
+ struct fb_bitfield blue;
+ struct fb_bitfield transp;
+
+ __u32 nonstd;
+
+ __u32 activate;
+
+ __u32 height;
+ __u32 width;
+
+ __u32 accel_flags;
+
+ __u32 pixclock;
+ __u32 left_margin;
+ __u32 right_margin;
+ __u32 upper_margin;
+ __u32 lower_margin;
+ __u32 hsync_len;
+ __u32 vsync_len;
+ __u32 sync;
+ __u32 vmode;
+ __u32 rotate;
+ __u32 reserved[5];
+};
+
+struct fb_cmap {
+ __u32 start;
+ __u32 len;
+ __u16 *red;
+ __u16 *green;
+ __u16 *blue;
+ __u16 *transp;
+};
+
+struct fb_con2fbmap {
+ __u32 console;
+ __u32 framebuffer;
+};
+
+#define VESA_NO_BLANKING 0
+#define VESA_VSYNC_SUSPEND 1
+#define VESA_HSYNC_SUSPEND 2
+#define VESA_POWERDOWN 3
+
+enum {
+
+ FB_BLANK_UNBLANK = VESA_NO_BLANKING,
+
+ FB_BLANK_NORMAL = VESA_NO_BLANKING + 1,
+
+ FB_BLANK_VSYNC_SUSPEND = VESA_VSYNC_SUSPEND + 1,
+
+ FB_BLANK_HSYNC_SUSPEND = VESA_HSYNC_SUSPEND + 1,
+
+ FB_BLANK_POWERDOWN = VESA_POWERDOWN + 1
+};
+
+#define FB_VBLANK_VBLANKING 0x001  
+#define FB_VBLANK_HBLANKING 0x002  
+#define FB_VBLANK_HAVE_VBLANK 0x004  
+#define FB_VBLANK_HAVE_HBLANK 0x008  
+#define FB_VBLANK_HAVE_COUNT 0x010  
+#define FB_VBLANK_HAVE_VCOUNT 0x020  
+#define FB_VBLANK_HAVE_HCOUNT 0x040  
+#define FB_VBLANK_VSYNCING 0x080  
+#define FB_VBLANK_HAVE_VSYNC 0x100  
+
+struct fb_vblank {
+ __u32 flags;
+ __u32 count;
+ __u32 vcount;
+ __u32 hcount;
+ __u32 reserved[4];
+};
+
+#define ROP_COPY 0
+#define ROP_XOR 1
+
+struct fb_copyarea {
+ __u32 dx;
+ __u32 dy;
+ __u32 width;
+ __u32 height;
+ __u32 sx;
+ __u32 sy;
+};
+
+struct fb_fillrect {
+ __u32 dx;
+ __u32 dy;
+ __u32 width;
+ __u32 height;
+ __u32 color;
+ __u32 rop;
+};
+
+struct fb_image {
+ __u32 dx;
+ __u32 dy;
+ __u32 width;
+ __u32 height;
+ __u32 fg_color;
+ __u32 bg_color;
+ __u8 depth;
+ const char *data;
+ struct fb_cmap cmap;
+};
+
+#define FB_CUR_SETIMAGE 0x01
+#define FB_CUR_SETPOS 0x02
+#define FB_CUR_SETHOT 0x04
+#define FB_CUR_SETCMAP 0x08
+#define FB_CUR_SETSHAPE 0x10
+#define FB_CUR_SETSIZE 0x20
+#define FB_CUR_SETALL 0xFF
+
+struct fbcurpos {
+ __u16 x, y;
+};
+
+struct fb_cursor {
+ __u16 set;
+ __u16 enable;
+ __u16 rop;
+ const char *mask;
+ struct fbcurpos hot;
+ struct fb_image image;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/fcntl.h b/ndk/build/platforms/android-1.5/common/include/linux/fcntl.h
new file mode 100644
index 0000000..323e87a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/fcntl.h
@@ -0,0 +1,35 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_FCNTL_H
+#define _LINUX_FCNTL_H
+
+#include <asm/fcntl.h>
+
+#define F_SETLEASE (F_LINUX_SPECIFIC_BASE+0)
+#define F_GETLEASE (F_LINUX_SPECIFIC_BASE+1)
+
+#define F_NOTIFY (F_LINUX_SPECIFIC_BASE+2)
+
+#define DN_ACCESS 0x00000001  
+#define DN_MODIFY 0x00000002  
+#define DN_CREATE 0x00000004  
+#define DN_DELETE 0x00000008  
+#define DN_RENAME 0x00000010  
+#define DN_ATTRIB 0x00000020  
+#define DN_MULTISHOT 0x80000000  
+
+#define AT_FDCWD -100  
+#define AT_SYMLINK_NOFOLLOW 0x100  
+#define AT_REMOVEDIR 0x200  
+#define AT_SYMLINK_FOLLOW 0x400  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/fd.h b/ndk/build/platforms/android-1.5/common/include/linux/fd.h
new file mode 100644
index 0000000..f3bedd1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/fd.h
@@ -0,0 +1,258 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_FD_H
+#define _LINUX_FD_H
+
+#include <linux/ioctl.h>
+#include <linux/compiler.h>
+
+struct floppy_struct {
+ unsigned int size,
+ sect,
+ head,
+ track,
+ stretch;
+#define FD_STRETCH 1
+#define FD_SWAPSIDES 2
+#define FD_ZEROBASED 4
+
+ unsigned char gap,
+
+ rate,
+#define FD_2M 0x4
+#define FD_SIZECODEMASK 0x38
+#define FD_SIZECODE(floppy) (((((floppy)->rate&FD_SIZECODEMASK)>> 3)+ 2) %8)
+#define FD_SECTSIZE(floppy) ( (floppy)->rate & FD_2M ?   512 : 128 << FD_SIZECODE(floppy) )
+#define FD_PERP 0x40
+
+ spec1,
+ fmt_gap;
+ const char * name;
+};
+
+#define FDCLRPRM _IO(2, 0x41)
+
+#define FDSETPRM _IOW(2, 0x42, struct floppy_struct) 
+#define FDSETMEDIAPRM FDSETPRM
+
+#define FDDEFPRM _IOW(2, 0x43, struct floppy_struct) 
+#define FDGETPRM _IOR(2, 0x04, struct floppy_struct)
+#define FDDEFMEDIAPRM FDDEFPRM
+#define FDGETMEDIAPRM FDGETPRM
+
+#define FDMSGON _IO(2,0x45)
+#define FDMSGOFF _IO(2,0x46)
+
+#define FD_FILL_BYTE 0xF6  
+
+struct format_descr {
+ unsigned int device,head,track;
+};
+
+#define FDFMTBEG _IO(2,0x47)
+
+#define FDFMTTRK _IOW(2,0x48, struct format_descr)
+
+#define FDFMTEND _IO(2,0x49)
+
+struct floppy_max_errors {
+ unsigned int
+ abort,
+ read_track,
+ reset,
+ recal,
+
+ reporting;
+
+};
+
+#define FDSETEMSGTRESH _IO(2,0x4a)
+
+#define FDFLUSH _IO(2,0x4b)
+
+#define FDSETMAXERRS _IOW(2, 0x4c, struct floppy_max_errors)
+#define FDGETMAXERRS _IOR(2, 0x0e, struct floppy_max_errors)
+
+typedef char floppy_drive_name[16];
+#define FDGETDRVTYP _IOR(2, 0x0f, floppy_drive_name)
+
+struct floppy_drive_params {
+ signed char cmos;
+
+ unsigned long max_dtr;
+ unsigned long hlt;
+ unsigned long hut;
+ unsigned long srt;
+
+ unsigned long spinup;
+ unsigned long spindown;
+ unsigned char spindown_offset;
+ unsigned char select_delay;
+ unsigned char rps;
+ unsigned char tracks;
+ unsigned long timeout;
+
+ unsigned char interleave_sect;
+
+ struct floppy_max_errors max_errors;
+
+ char flags;
+
+#define FTD_MSG 0x10
+#define FD_BROKEN_DCL 0x20
+#define FD_DEBUG 0x02
+#define FD_SILENT_DCL_CLEAR 0x4
+#define FD_INVERTED_DCL 0x80  
+
+ char read_track;
+
+ short autodetect[8];
+
+ int checkfreq;
+ int native_format;
+};
+
+enum {
+ FD_NEED_TWADDLE_BIT,
+ FD_VERIFY_BIT,
+ FD_DISK_NEWCHANGE_BIT,
+ FD_UNUSED_BIT,
+ FD_DISK_CHANGED_BIT,
+ FD_DISK_WRITABLE_BIT
+};
+
+#define FDSETDRVPRM _IOW(2, 0x90, struct floppy_drive_params)
+#define FDGETDRVPRM _IOR(2, 0x11, struct floppy_drive_params)
+
+struct floppy_drive_struct {
+ unsigned long flags;
+
+#define FD_NEED_TWADDLE (1 << FD_NEED_TWADDLE_BIT)
+#define FD_VERIFY (1 << FD_VERIFY_BIT)
+#define FD_DISK_NEWCHANGE (1 << FD_DISK_NEWCHANGE_BIT)
+#define FD_DISK_CHANGED (1 << FD_DISK_CHANGED_BIT)
+#define FD_DISK_WRITABLE (1 << FD_DISK_WRITABLE_BIT)
+
+ unsigned long spinup_date;
+ unsigned long select_date;
+ unsigned long first_read_date;
+ short probed_format;
+ short track;
+ short maxblock;
+ short maxtrack;
+ int generation;
+
+ int keep_data;
+
+ int fd_ref;
+ int fd_device;
+ unsigned long last_checked;
+
+ char *dmabuf;
+ int bufblocks;
+};
+
+#define FDGETDRVSTAT _IOR(2, 0x12, struct floppy_drive_struct)
+#define FDPOLLDRVSTAT _IOR(2, 0x13, struct floppy_drive_struct)
+
+enum reset_mode {
+ FD_RESET_IF_NEEDED,
+ FD_RESET_IF_RAWCMD,
+ FD_RESET_ALWAYS
+};
+#define FDRESET _IO(2, 0x54)
+
+struct floppy_fdc_state {
+ int spec1;
+ int spec2;
+ int dtr;
+ unsigned char version;
+ unsigned char dor;
+ unsigned long address;
+ unsigned int rawcmd:2;
+ unsigned int reset:1;
+ unsigned int need_configure:1;
+ unsigned int perp_mode:2;
+ unsigned int has_fifo:1;
+ unsigned int driver_version;
+#define FD_DRIVER_VERSION 0x100
+
+ unsigned char track[4];
+
+};
+
+#define FDGETFDCSTAT _IOR(2, 0x15, struct floppy_fdc_state)
+
+struct floppy_write_errors {
+
+ unsigned int write_errors;
+
+ unsigned long first_error_sector;
+ int first_error_generation;
+ unsigned long last_error_sector;
+ int last_error_generation;
+
+ unsigned int badness;
+};
+
+#define FDWERRORCLR _IO(2, 0x56)
+
+#define FDWERRORGET _IOR(2, 0x17, struct floppy_write_errors)
+
+#define FDHAVEBATCHEDRAWCMD
+
+struct floppy_raw_cmd {
+ unsigned int flags;
+#define FD_RAW_READ 1
+#define FD_RAW_WRITE 2
+#define FD_RAW_NO_MOTOR 4
+#define FD_RAW_DISK_CHANGE 4  
+#define FD_RAW_INTR 8  
+#define FD_RAW_SPIN 0x10  
+#define FD_RAW_NO_MOTOR_AFTER 0x20  
+#define FD_RAW_NEED_DISK 0x40  
+#define FD_RAW_NEED_SEEK 0x80  
+
+#define FD_RAW_MORE 0x100  
+#define FD_RAW_STOP_IF_FAILURE 0x200  
+#define FD_RAW_STOP_IF_SUCCESS 0x400  
+#define FD_RAW_SOFTFAILURE 0x800  
+
+#define FD_RAW_FAILURE 0x10000  
+#define FD_RAW_HARDFAILURE 0x20000  
+
+ void __user *data;
+ char *kernel_data;
+ struct floppy_raw_cmd *next;
+ long length;
+ long phys_length;
+ int buffer_length;
+
+ unsigned char rate;
+ unsigned char cmd_count;
+ unsigned char cmd[16];
+ unsigned char reply_count;
+ unsigned char reply[16];
+ int track;
+ int resultcode;
+
+ int reserved1;
+ int reserved2;
+};
+
+#define FDRAWCMD _IO(2, 0x58)
+
+#define FDTWADDLE _IO(2, 0x59)
+
+#define FDEJECT _IO(2, 0x5a)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/file.h b/ndk/build/platforms/android-1.5/common/include/linux/file.h
new file mode 100644
index 0000000..87e570b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/file.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_FILE_H
+#define __LINUX_FILE_H
+
+#include <asm/atomic.h>
+#include <linux/posix_types.h>
+#include <linux/compiler.h>
+#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
+#include <linux/types.h>
+
+#define NR_OPEN_DEFAULT BITS_PER_LONG
+
+struct embedded_fd_set {
+ unsigned long fds_bits[1];
+};
+
+#define EMBEDDED_FD_SET_SIZE (BITS_PER_BYTE * sizeof(struct embedded_fd_set))
+
+struct fdtable {
+ unsigned int max_fds;
+ int max_fdset;
+ struct file ** fd;
+ fd_set *close_on_exec;
+ fd_set *open_fds;
+ struct rcu_head rcu;
+ struct files_struct *free_files;
+ struct fdtable *next;
+};
+
+struct files_struct {
+
+ atomic_t count;
+ struct fdtable *fdt;
+ struct fdtable fdtab;
+
+ spinlock_t file_lock ____cacheline_aligned_in_smp;
+ int next_fd;
+ struct embedded_fd_set close_on_exec_init;
+ struct embedded_fd_set open_fds_init;
+ struct file * fd_array[NR_OPEN_DEFAULT];
+};
+
+#define files_fdtable(files) (rcu_dereference((files)->fdt))
+
+struct kmem_cache;
+
+#define fcheck(fd) fcheck_files(current->files, fd)
+
+struct task_struct;
+
+struct files_struct *get_files_struct(struct task_struct *);
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/filter.h b/ndk/build/platforms/android-1.5/common/include/linux/filter.h
new file mode 100644
index 0000000..e858a0f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/filter.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_FILTER_H__
+#define __LINUX_FILTER_H__
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+#define BPF_MAJOR_VERSION 1
+#define BPF_MINOR_VERSION 1
+
+struct sock_filter
+{
+ __u16 code;
+ __u8 jt;
+ __u8 jf;
+ __u32 k;
+};
+
+struct sock_fprog
+{
+ unsigned short len;
+ struct sock_filter __user *filter;
+};
+
+#define BPF_CLASS(code) ((code) & 0x07)
+#define BPF_LD 0x00
+#define BPF_LDX 0x01
+#define BPF_ST 0x02
+#define BPF_STX 0x03
+#define BPF_ALU 0x04
+#define BPF_JMP 0x05
+#define BPF_RET 0x06
+#define BPF_MISC 0x07
+
+#define BPF_SIZE(code) ((code) & 0x18)
+#define BPF_W 0x00
+#define BPF_H 0x08
+#define BPF_B 0x10
+#define BPF_MODE(code) ((code) & 0xe0)
+#define BPF_IMM 0x00
+#define BPF_ABS 0x20
+#define BPF_IND 0x40
+#define BPF_MEM 0x60
+#define BPF_LEN 0x80
+#define BPF_MSH 0xa0
+
+#define BPF_OP(code) ((code) & 0xf0)
+#define BPF_ADD 0x00
+#define BPF_SUB 0x10
+#define BPF_MUL 0x20
+#define BPF_DIV 0x30
+#define BPF_OR 0x40
+#define BPF_AND 0x50
+#define BPF_LSH 0x60
+#define BPF_RSH 0x70
+#define BPF_NEG 0x80
+#define BPF_JA 0x00
+#define BPF_JEQ 0x10
+#define BPF_JGT 0x20
+#define BPF_JGE 0x30
+#define BPF_JSET 0x40
+#define BPF_SRC(code) ((code) & 0x08)
+#define BPF_K 0x00
+#define BPF_X 0x08
+
+#define BPF_RVAL(code) ((code) & 0x18)
+#define BPF_A 0x10
+
+#define BPF_MISCOP(code) ((code) & 0xf8)
+#define BPF_TAX 0x00
+#define BPF_TXA 0x80
+
+#ifndef BPF_MAXINSNS
+#define BPF_MAXINSNS 4096
+#endif
+
+#ifndef BPF_STMT
+#define BPF_STMT(code, k) { (unsigned short)(code), 0, 0, k }
+#endif
+#ifndef BPF_JUMP
+#define BPF_JUMP(code, k, jt, jf) { (unsigned short)(code), jt, jf, k }
+#endif
+
+#define BPF_MEMWORDS 16
+
+#define SKF_AD_OFF (-0x1000)
+#define SKF_AD_PROTOCOL 0
+#define SKF_AD_PKTTYPE 4
+#define SKF_AD_IFINDEX 8
+#define SKF_AD_MAX 12
+#define SKF_NET_OFF (-0x100000)
+#define SKF_LL_OFF (-0x200000)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/fs.h b/ndk/build/platforms/android-1.5/common/include/linux/fs.h
new file mode 100644
index 0000000..8d375b5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/fs.h
@@ -0,0 +1,162 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_FS_H
+#define _LINUX_FS_H
+
+#include <linux/limits.h>
+#include <linux/ioctl.h>
+
+#undef NR_OPEN
+#define NR_OPEN (1024*1024)  
+#define INR_OPEN 1024  
+
+#define BLOCK_SIZE_BITS 10
+#define BLOCK_SIZE (1<<BLOCK_SIZE_BITS)
+
+#define SEEK_SET 0  
+#define SEEK_CUR 1  
+#define SEEK_END 2  
+
+struct files_stat_struct {
+ int nr_files;
+ int nr_free_files;
+ int max_files;
+};
+
+struct inodes_stat_t {
+ int nr_inodes;
+ int nr_unused;
+ int dummy[5];
+};
+
+#define NR_FILE 8192  
+
+#define MAY_EXEC 1
+#define MAY_WRITE 2
+#define MAY_READ 4
+#define MAY_APPEND 8
+
+#define FMODE_READ 1
+#define FMODE_WRITE 2
+
+#define FMODE_LSEEK 4
+#define FMODE_PREAD 8
+#define FMODE_PWRITE FMODE_PREAD  
+
+#define FMODE_EXEC 16
+
+#define RW_MASK 1
+#define RWA_MASK 2
+#define READ 0
+#define WRITE 1
+#define READA 2  
+#define SWRITE 3  
+#define SPECIAL 4  
+#define READ_SYNC (READ | (1 << BIO_RW_SYNC))
+#define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNC))
+#define WRITE_BARRIER ((1 << BIO_RW) | (1 << BIO_RW_BARRIER))
+
+#define SEL_IN 1
+#define SEL_OUT 2
+#define SEL_EX 4
+
+#define FS_REQUIRES_DEV 1 
+#define FS_BINARY_MOUNTDATA 2
+#define FS_REVAL_DOT 16384  
+#define FS_ODD_RENAME 32768  
+
+#define MS_RDONLY 1  
+#define MS_NOSUID 2  
+#define MS_NODEV 4  
+#define MS_NOEXEC 8  
+#define MS_SYNCHRONOUS 16  
+#define MS_REMOUNT 32  
+#define MS_MANDLOCK 64  
+#define MS_DIRSYNC 128  
+#define MS_NOATIME 1024  
+#define MS_NODIRATIME 2048  
+#define MS_BIND 4096
+#define MS_MOVE 8192
+#define MS_REC 16384
+#define MS_VERBOSE 32768  
+#define MS_SILENT 32768
+#define MS_POSIXACL (1<<16)  
+#define MS_UNBINDABLE (1<<17)  
+#define MS_PRIVATE (1<<18)  
+#define MS_SLAVE (1<<19)  
+#define MS_SHARED (1<<20)  
+#define MS_ACTIVE (1<<30)
+#define MS_NOUSER (1<<31)
+
+#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK)
+
+#define MS_MGC_VAL 0xC0ED0000
+#define MS_MGC_MSK 0xffff0000
+
+#define S_SYNC 1  
+#define S_NOATIME 2  
+#define S_APPEND 4  
+#define S_IMMUTABLE 8  
+#define S_DEAD 16  
+#define S_NOQUOTA 32  
+#define S_DIRSYNC 64  
+#define S_NOCMTIME 128  
+#define S_SWAPFILE 256  
+#define S_PRIVATE 512  
+
+#define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg))
+
+#define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY)
+#define IS_SYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS) ||   ((inode)->i_flags & S_SYNC))
+#define IS_DIRSYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) ||   ((inode)->i_flags & (S_SYNC|S_DIRSYNC)))
+#define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK)
+
+#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
+#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
+#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
+#define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
+
+#define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
+#define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME)
+#define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE)
+#define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE)
+
+#define BLKROSET _IO(0x12,93)  
+#define BLKROGET _IO(0x12,94)  
+#define BLKRRPART _IO(0x12,95)  
+#define BLKGETSIZE _IO(0x12,96)  
+#define BLKFLSBUF _IO(0x12,97)  
+#define BLKRASET _IO(0x12,98)  
+#define BLKRAGET _IO(0x12,99)  
+#define BLKFRASET _IO(0x12,100) 
+#define BLKFRAGET _IO(0x12,101) 
+#define BLKSECTSET _IO(0x12,102) 
+#define BLKSECTGET _IO(0x12,103) 
+#define BLKSSZGET _IO(0x12,104) 
+
+#define BLKBSZGET _IOR(0x12,112,size_t)
+#define BLKBSZSET _IOW(0x12,113,size_t)
+#define BLKGETSIZE64 _IOR(0x12,114,size_t)  
+#define BLKTRACESETUP _IOWR(0x12,115,struct blk_user_trace_setup)
+#define BLKTRACESTART _IO(0x12,116)
+#define BLKTRACESTOP _IO(0x12,117)
+#define BLKTRACETEARDOWN _IO(0x12,118)
+
+#define BMAP_IOCTL 1  
+#define FIBMAP _IO(0x00,1)  
+#define FIGETBSZ _IO(0x00,2)  
+
+#define SYNC_FILE_RANGE_WAIT_BEFORE 1
+#define SYNC_FILE_RANGE_WRITE 2
+#define SYNC_FILE_RANGE_WAIT_AFTER 4
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ftape.h b/ndk/build/platforms/android-1.5/common/include/linux/ftape.h
new file mode 100644
index 0000000..bb1527c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ftape.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _FTAPE_H
+#define _FTAPE_H
+
+#define FTAPE_VERSION "ftape v3.04d 25/11/97"
+
+#include <linux/types.h>
+#include <linux/mtio.h>
+
+#define FT_SECTOR(x) (x+1)  
+#define FT_SECTOR_SIZE 1024
+#define FT_SECTORS_PER_SEGMENT 32
+#define FT_ECC_SECTORS 3
+#define FT_SEGMENT_SIZE ((FT_SECTORS_PER_SEGMENT - FT_ECC_SECTORS) * FT_SECTOR_SIZE)
+#define FT_BUFF_SIZE (FT_SECTORS_PER_SEGMENT * FT_SECTOR_SIZE)
+
+#define FTAPE_SEL_A 0
+#define FTAPE_SEL_B 1
+#define FTAPE_SEL_C 2
+#define FTAPE_SEL_D 3
+#define FTAPE_SEL_MASK 3
+#define FTAPE_SEL(unit) ((unit) & FTAPE_SEL_MASK)
+#define FTAPE_NO_REWIND 4  
+
+typedef union {
+ struct {
+ __u8 error;
+ __u8 command;
+ } error;
+ long space;
+} ft_drive_error;
+typedef union {
+ struct {
+ __u8 drive_status;
+ __u8 drive_config;
+ __u8 tape_status;
+ } status;
+ long space;
+} ft_drive_status;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/futex.h b/ndk/build/platforms/android-1.5/common/include/linux/futex.h
new file mode 100644
index 0000000..30f9e59
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/futex.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_FUTEX_H
+#define _LINUX_FUTEX_H
+
+#include <linux/sched.h>
+
+#define FUTEX_WAIT 0
+#define FUTEX_WAKE 1
+#define FUTEX_FD 2
+#define FUTEX_REQUEUE 3
+#define FUTEX_CMP_REQUEUE 4
+#define FUTEX_WAKE_OP 5
+#define FUTEX_LOCK_PI 6
+#define FUTEX_UNLOCK_PI 7
+#define FUTEX_TRYLOCK_PI 8
+
+struct robust_list {
+ struct robust_list __user *next;
+};
+
+struct robust_list_head {
+
+ struct robust_list list;
+
+ long futex_offset;
+
+ struct robust_list __user *list_op_pending;
+};
+
+#define FUTEX_WAITERS 0x80000000
+
+#define FUTEX_OWNER_DIED 0x40000000
+
+#define FUTEX_TID_MASK 0x3fffffff
+
+#define ROBUST_LIST_LIMIT 2048
+
+#define FUTEX_OP_SET 0  
+#define FUTEX_OP_ADD 1  
+#define FUTEX_OP_OR 2  
+#define FUTEX_OP_ANDN 3  
+#define FUTEX_OP_XOR 4  
+#define FUTEX_OP_OPARG_SHIFT 8  
+#define FUTEX_OP_CMP_EQ 0  
+#define FUTEX_OP_CMP_NE 1  
+#define FUTEX_OP_CMP_LT 2  
+#define FUTEX_OP_CMP_LE 3  
+#define FUTEX_OP_CMP_GT 4  
+#define FUTEX_OP_CMP_GE 5  
+#define FUTEX_OP(op, oparg, cmp, cmparg)   (((op & 0xf) << 28) | ((cmp & 0xf) << 24)   | ((oparg & 0xfff) << 12) | (cmparg & 0xfff))
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/genhd.h b/ndk/build/platforms/android-1.5/common/include/linux/genhd.h
new file mode 100644
index 0000000..a3a3924
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/genhd.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_GENHD_H
+#define _LINUX_GENHD_H
+
+#include <linux/types.h>
+
+enum {
+
+ DOS_EXTENDED_PARTITION = 5,
+ LINUX_EXTENDED_PARTITION = 0x85,
+ WIN98_EXTENDED_PARTITION = 0x0f,
+
+ LINUX_SWAP_PARTITION = 0x82,
+ LINUX_RAID_PARTITION = 0xfd,
+
+ SOLARIS_X86_PARTITION = LINUX_SWAP_PARTITION,
+ NEW_SOLARIS_X86_PARTITION = 0xbf,
+
+ DM6_AUX1PARTITION = 0x51,
+ DM6_AUX3PARTITION = 0x53,
+ DM6_PARTITION = 0x54,
+ EZD_PARTITION = 0x55,
+
+ FREEBSD_PARTITION = 0xa5,
+ OPENBSD_PARTITION = 0xa6,
+ NETBSD_PARTITION = 0xa9,
+ BSDI_PARTITION = 0xb7,
+ MINIX_PARTITION = 0x81,
+ UNIXWARE_PARTITION = 0x63,
+};
+
+struct partition {
+ unsigned char boot_ind;
+ unsigned char head;
+ unsigned char sector;
+ unsigned char cyl;
+ unsigned char sys_ind;
+ unsigned char end_head;
+ unsigned char end_sector;
+ unsigned char end_cyl;
+ unsigned int start_sect;
+ unsigned int nr_sects;
+} __attribute__((packed));
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/gfp.h b/ndk/build/platforms/android-1.5/common/include/linux/gfp.h
new file mode 100644
index 0000000..0a59fe9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/gfp.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_GFP_H
+#define __LINUX_GFP_H
+
+#include <linux/mmzone.h>
+#include <linux/stddef.h>
+#include <linux/linkage.h>
+
+struct vm_area_struct;
+
+#define __GFP_DMA ((__force gfp_t)0x01u)
+#define __GFP_HIGHMEM ((__force gfp_t)0x02u)
+#if BITS_PER_LONG < 64
+#define __GFP_DMA32 ((__force gfp_t)0x00)  
+#else
+#define __GFP_DMA32 ((__force gfp_t)0x04)  
+#endif
+
+#define __GFP_WAIT ((__force gfp_t)0x10u)  
+#define __GFP_HIGH ((__force gfp_t)0x20u)  
+#define __GFP_IO ((__force gfp_t)0x40u)  
+#define __GFP_FS ((__force gfp_t)0x80u)  
+#define __GFP_COLD ((__force gfp_t)0x100u)  
+#define __GFP_NOWARN ((__force gfp_t)0x200u)  
+#define __GFP_REPEAT ((__force gfp_t)0x400u)  
+#define __GFP_NOFAIL ((__force gfp_t)0x800u)  
+#define __GFP_NORETRY ((__force gfp_t)0x1000u) 
+#define __GFP_NO_GROW ((__force gfp_t)0x2000u) 
+#define __GFP_COMP ((__force gfp_t)0x4000u) 
+#define __GFP_ZERO ((__force gfp_t)0x8000u) 
+#define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u)  
+#define __GFP_HARDWALL ((__force gfp_t)0x20000u)  
+
+#define __GFP_BITS_SHIFT 20  
+#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
+
+#define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|   __GFP_COLD|__GFP_NOWARN|__GFP_REPEAT|   __GFP_NOFAIL|__GFP_NORETRY|__GFP_NO_GROW|__GFP_COMP|   __GFP_NOMEMALLOC|__GFP_HARDWALL)
+
+#define GFP_NOWAIT (GFP_ATOMIC & ~__GFP_HIGH)
+
+#define GFP_ATOMIC (__GFP_HIGH)
+#define GFP_NOIO (__GFP_WAIT)
+#define GFP_NOFS (__GFP_WAIT | __GFP_IO)
+#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS)
+#define GFP_USER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL)
+#define GFP_HIGHUSER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL |   __GFP_HIGHMEM)
+
+#define GFP_DMA __GFP_DMA
+
+#define GFP_DMA32 __GFP_DMA32
+
+#ifndef HAVE_ARCH_FREE_PAGE
+#endif
+
+#define alloc_pages(gfp_mask, order)   alloc_pages_node(numa_node_id(), gfp_mask, order)
+#define alloc_page_vma(gfp_mask, vma, addr) alloc_pages(gfp_mask, 0)
+#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
+
+#define __get_free_page(gfp_mask)   __get_free_pages((gfp_mask),0)
+
+#define __get_dma_pages(gfp_mask, order)   __get_free_pages((gfp_mask) | GFP_DMA,(order))
+
+#define __free_page(page) __free_pages((page), 0)
+#define free_page(addr) free_pages((addr),0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/hardirq.h b/ndk/build/platforms/android-1.5/common/include/linux/hardirq.h
new file mode 100644
index 0000000..c0566b0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/hardirq.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_HARDIRQ_H
+#define LINUX_HARDIRQ_H
+
+#include <linux/preempt.h>
+#include <linux/smp_lock.h>
+#include <linux/lockdep.h>
+#include <asm/hardirq.h>
+#include <asm/system.h>
+
+#define PREEMPT_BITS 8
+#define SOFTIRQ_BITS 8
+
+#ifndef HARDIRQ_BITS
+#define HARDIRQ_BITS 12
+
+#if 1 << HARDIRQ_BITS < NR_IRQS
+#error HARDIRQ_BITS is too low!
+#endif
+#endif
+
+#define PREEMPT_SHIFT 0
+#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS)
+#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS)
+
+#define __IRQ_MASK(x) ((1UL << (x))-1)
+
+#define PREEMPT_MASK (__IRQ_MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
+#define SOFTIRQ_MASK (__IRQ_MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
+#define HARDIRQ_MASK (__IRQ_MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
+
+#define PREEMPT_OFFSET (1UL << PREEMPT_SHIFT)
+#define SOFTIRQ_OFFSET (1UL << SOFTIRQ_SHIFT)
+#define HARDIRQ_OFFSET (1UL << HARDIRQ_SHIFT)
+
+#if PREEMPT_ACTIVE < 1 << HARDIRQ_SHIFT + HARDIRQ_BITS
+#error PREEMPT_ACTIVE is too low!
+#endif
+
+#define hardirq_count() (preempt_count() & HARDIRQ_MASK)
+#define softirq_count() (preempt_count() & SOFTIRQ_MASK)
+#define irq_count() (preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))
+
+#define in_irq() (hardirq_count())
+#define in_softirq() (softirq_count())
+#define in_interrupt() (irq_count())
+
+#define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != 0)
+
+#define preemptible() 0
+#define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
+
+#define synchronize_irq(irq) barrier()
+
+struct task_struct;
+
+#define irq_enter()   do {   account_system_vtime(current);   add_preempt_count(HARDIRQ_OFFSET);   trace_hardirq_enter();   } while (0)
+#define __irq_exit()   do {   trace_hardirq_exit();   account_system_vtime(current);   sub_preempt_count(HARDIRQ_OFFSET);   } while (0)
+
+#define nmi_enter() do { lockdep_off(); irq_enter(); } while (0)
+#define nmi_exit() do { __irq_exit(); lockdep_on(); } while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/hdlc/ioctl.h b/ndk/build/platforms/android-1.5/common/include/linux/hdlc/ioctl.h
new file mode 100644
index 0000000..c15a67f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/hdlc/ioctl.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __HDLC_IOCTL_H__
+#define __HDLC_IOCTL_H__
+
+typedef struct {
+ unsigned int clock_rate;
+ unsigned int clock_type;
+ unsigned short loopback;
+} sync_serial_settings;
+
+typedef struct {
+ unsigned int clock_rate;
+ unsigned int clock_type;
+ unsigned short loopback;
+ unsigned int slot_map;
+} te1_settings;
+
+typedef struct {
+ unsigned short encoding;
+ unsigned short parity;
+} raw_hdlc_proto;
+
+typedef struct {
+ unsigned int t391;
+ unsigned int t392;
+ unsigned int n391;
+ unsigned int n392;
+ unsigned int n393;
+ unsigned short lmi;
+ unsigned short dce;
+} fr_proto;
+
+typedef struct {
+ unsigned int dlci;
+} fr_proto_pvc;
+
+typedef struct {
+ unsigned int dlci;
+ char master[IFNAMSIZ];
+}fr_proto_pvc_info;
+
+typedef struct {
+ unsigned int interval;
+ unsigned int timeout;
+} cisco_proto;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/hdreg.h b/ndk/build/platforms/android-1.5/common/include/linux/hdreg.h
new file mode 100644
index 0000000..a684ee9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/hdreg.h
@@ -0,0 +1,432 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_HDREG_H
+#define _LINUX_HDREG_H
+
+#define HDIO_DRIVE_CMD_HDR_SIZE (4 * sizeof(u8))
+#define HDIO_DRIVE_HOB_HDR_SIZE (8 * sizeof(u8))
+#define HDIO_DRIVE_TASK_HDR_SIZE (8 * sizeof(u8))
+
+#define IDE_DRIVE_TASK_INVALID -1
+#define IDE_DRIVE_TASK_NO_DATA 0
+#define IDE_DRIVE_TASK_SET_XFER 1
+
+#define IDE_DRIVE_TASK_IN 2
+
+#define IDE_DRIVE_TASK_OUT 3
+#define IDE_DRIVE_TASK_RAW_WRITE 4
+
+#define IDE_TASKFILE_STD_IN_FLAGS 0xFE
+#define IDE_HOB_STD_IN_FLAGS 0x3C
+#define IDE_TASKFILE_STD_OUT_FLAGS 0xFE
+#define IDE_HOB_STD_OUT_FLAGS 0x3C
+
+typedef unsigned char task_ioreg_t;
+typedef unsigned long sata_ioreg_t;
+
+typedef union ide_reg_valid_s {
+ unsigned all : 16;
+ struct {
+ unsigned data : 1;
+ unsigned error_feature : 1;
+ unsigned sector : 1;
+ unsigned nsector : 1;
+ unsigned lcyl : 1;
+ unsigned hcyl : 1;
+ unsigned select : 1;
+ unsigned status_command : 1;
+
+ unsigned data_hob : 1;
+ unsigned error_feature_hob : 1;
+ unsigned sector_hob : 1;
+ unsigned nsector_hob : 1;
+ unsigned lcyl_hob : 1;
+ unsigned hcyl_hob : 1;
+ unsigned select_hob : 1;
+ unsigned control_hob : 1;
+ } b;
+} ide_reg_valid_t;
+
+typedef struct ide_task_request_s {
+ task_ioreg_t io_ports[8];
+ task_ioreg_t hob_ports[8];
+ ide_reg_valid_t out_flags;
+ ide_reg_valid_t in_flags;
+ int data_phase;
+ int req_cmd;
+ unsigned long out_size;
+ unsigned long in_size;
+} ide_task_request_t;
+
+typedef struct ide_ioctl_request_s {
+ ide_task_request_t *task_request;
+ unsigned char *out_buffer;
+ unsigned char *in_buffer;
+} ide_ioctl_request_t;
+
+struct hd_drive_cmd_hdr {
+ task_ioreg_t command;
+ task_ioreg_t sector_number;
+ task_ioreg_t feature;
+ task_ioreg_t sector_count;
+};
+
+typedef struct hd_drive_task_hdr {
+ task_ioreg_t data;
+ task_ioreg_t feature;
+ task_ioreg_t sector_count;
+ task_ioreg_t sector_number;
+ task_ioreg_t low_cylinder;
+ task_ioreg_t high_cylinder;
+ task_ioreg_t device_head;
+ task_ioreg_t command;
+} task_struct_t;
+
+typedef struct hd_drive_hob_hdr {
+ task_ioreg_t data;
+ task_ioreg_t feature;
+ task_ioreg_t sector_count;
+ task_ioreg_t sector_number;
+ task_ioreg_t low_cylinder;
+ task_ioreg_t high_cylinder;
+ task_ioreg_t device_head;
+ task_ioreg_t control;
+} hob_struct_t;
+
+#define TASKFILE_INVALID 0x7fff
+#define TASKFILE_48 0x8000
+
+#define TASKFILE_NO_DATA 0x0000
+
+#define TASKFILE_IN 0x0001
+#define TASKFILE_MULTI_IN 0x0002
+
+#define TASKFILE_OUT 0x0004
+#define TASKFILE_MULTI_OUT 0x0008
+#define TASKFILE_IN_OUT 0x0010
+
+#define TASKFILE_IN_DMA 0x0020
+#define TASKFILE_OUT_DMA 0x0040
+#define TASKFILE_IN_DMAQ 0x0080
+#define TASKFILE_OUT_DMAQ 0x0100
+
+#define TASKFILE_P_IN 0x0200
+#define TASKFILE_P_OUT 0x0400
+#define TASKFILE_P_IN_DMA 0x0800
+#define TASKFILE_P_OUT_DMA 0x1000
+#define TASKFILE_P_IN_DMAQ 0x2000
+#define TASKFILE_P_OUT_DMAQ 0x4000
+
+#define WIN_NOP 0x00
+
+#define CFA_REQ_EXT_ERROR_CODE 0x03  
+
+#define WIN_SRST 0x08  
+#define WIN_DEVICE_RESET 0x08
+
+#define WIN_RECAL 0x10
+#define WIN_RESTORE WIN_RECAL
+
+#define WIN_READ 0x20  
+#define WIN_READ_ONCE 0x21  
+#define WIN_READ_LONG 0x22  
+#define WIN_READ_LONG_ONCE 0x23  
+#define WIN_READ_EXT 0x24  
+#define WIN_READDMA_EXT 0x25  
+#define WIN_READDMA_QUEUED_EXT 0x26  
+#define WIN_READ_NATIVE_MAX_EXT 0x27  
+
+#define WIN_MULTREAD_EXT 0x29  
+
+#define WIN_WRITE 0x30  
+#define WIN_WRITE_ONCE 0x31  
+#define WIN_WRITE_LONG 0x32  
+#define WIN_WRITE_LONG_ONCE 0x33  
+#define WIN_WRITE_EXT 0x34  
+#define WIN_WRITEDMA_EXT 0x35  
+#define WIN_WRITEDMA_QUEUED_EXT 0x36  
+#define WIN_SET_MAX_EXT 0x37  
+#define CFA_WRITE_SECT_WO_ERASE 0x38  
+#define WIN_MULTWRITE_EXT 0x39  
+
+#define WIN_WRITE_VERIFY 0x3C  
+
+#define WIN_VERIFY 0x40  
+#define WIN_VERIFY_ONCE 0x41  
+#define WIN_VERIFY_EXT 0x42  
+
+#define WIN_FORMAT 0x50
+
+#define WIN_INIT 0x60
+
+#define WIN_SEEK 0x70  
+
+#define CFA_TRANSLATE_SECTOR 0x87  
+#define WIN_DIAGNOSE 0x90
+#define WIN_SPECIFY 0x91  
+#define WIN_DOWNLOAD_MICROCODE 0x92
+#define WIN_STANDBYNOW2 0x94
+#define WIN_STANDBY2 0x96
+#define WIN_SETIDLE2 0x97
+#define WIN_CHECKPOWERMODE2 0x98
+#define WIN_SLEEPNOW2 0x99
+
+#define WIN_PACKETCMD 0xA0  
+#define WIN_PIDENTIFY 0xA1  
+#define WIN_QUEUED_SERVICE 0xA2
+#define WIN_SMART 0xB0  
+#define CFA_ERASE_SECTORS 0xC0
+#define WIN_MULTREAD 0xC4  
+#define WIN_MULTWRITE 0xC5  
+#define WIN_SETMULT 0xC6  
+#define WIN_READDMA_QUEUED 0xC7  
+#define WIN_READDMA 0xC8  
+#define WIN_READDMA_ONCE 0xC9  
+#define WIN_WRITEDMA 0xCA  
+#define WIN_WRITEDMA_ONCE 0xCB  
+#define WIN_WRITEDMA_QUEUED 0xCC  
+#define CFA_WRITE_MULTI_WO_ERASE 0xCD  
+#define WIN_GETMEDIASTATUS 0xDA
+#define WIN_ACKMEDIACHANGE 0xDB  
+#define WIN_POSTBOOT 0xDC
+#define WIN_PREBOOT 0xDD
+#define WIN_DOORLOCK 0xDE  
+#define WIN_DOORUNLOCK 0xDF  
+#define WIN_STANDBYNOW1 0xE0
+#define WIN_IDLEIMMEDIATE 0xE1  
+#define WIN_STANDBY 0xE2  
+#define WIN_SETIDLE1 0xE3
+#define WIN_READ_BUFFER 0xE4  
+#define WIN_CHECKPOWERMODE1 0xE5
+#define WIN_SLEEPNOW1 0xE6
+#define WIN_FLUSH_CACHE 0xE7
+#define WIN_WRITE_BUFFER 0xE8  
+#define WIN_WRITE_SAME 0xE9  
+
+#define WIN_FLUSH_CACHE_EXT 0xEA  
+#define WIN_IDENTIFY 0xEC  
+#define WIN_MEDIAEJECT 0xED
+#define WIN_IDENTIFY_DMA 0xEE  
+#define WIN_SETFEATURES 0xEF  
+#define EXABYTE_ENABLE_NEST 0xF0
+#define WIN_SECURITY_SET_PASS 0xF1
+#define WIN_SECURITY_UNLOCK 0xF2
+#define WIN_SECURITY_ERASE_PREPARE 0xF3
+#define WIN_SECURITY_ERASE_UNIT 0xF4
+#define WIN_SECURITY_FREEZE_LOCK 0xF5
+#define WIN_SECURITY_DISABLE 0xF6
+#define WIN_READ_NATIVE_MAX 0xF8  
+#define WIN_SET_MAX 0xF9
+#define DISABLE_SEAGATE 0xFB
+
+#define SMART_READ_VALUES 0xD0
+#define SMART_READ_THRESHOLDS 0xD1
+#define SMART_AUTOSAVE 0xD2
+#define SMART_SAVE 0xD3
+#define SMART_IMMEDIATE_OFFLINE 0xD4
+#define SMART_READ_LOG_SECTOR 0xD5
+#define SMART_WRITE_LOG_SECTOR 0xD6
+#define SMART_WRITE_THRESHOLDS 0xD7
+#define SMART_ENABLE 0xD8
+#define SMART_DISABLE 0xD9
+#define SMART_STATUS 0xDA
+#define SMART_AUTO_OFFLINE 0xDB
+
+#define SMART_LCYL_PASS 0x4F
+#define SMART_HCYL_PASS 0xC2
+
+#define SETFEATURES_EN_8BIT 0x01  
+#define SETFEATURES_EN_WCACHE 0x02  
+#define SETFEATURES_DIS_DEFECT 0x04  
+#define SETFEATURES_EN_APM 0x05  
+#define SETFEATURES_EN_SAME_R 0x22  
+#define SETFEATURES_DIS_MSN 0x31  
+#define SETFEATURES_DIS_RETRY 0x33  
+#define SETFEATURES_EN_AAM 0x42  
+#define SETFEATURES_RW_LONG 0x44  
+#define SETFEATURES_SET_CACHE 0x54  
+#define SETFEATURES_DIS_RLA 0x55  
+#define SETFEATURES_EN_RI 0x5D  
+#define SETFEATURES_EN_SI 0x5E  
+#define SETFEATURES_DIS_RPOD 0x66  
+#define SETFEATURES_DIS_ECC 0x77  
+#define SETFEATURES_DIS_8BIT 0x81  
+#define SETFEATURES_DIS_WCACHE 0x82  
+#define SETFEATURES_EN_DEFECT 0x84  
+#define SETFEATURES_DIS_APM 0x85  
+#define SETFEATURES_EN_ECC 0x88  
+#define SETFEATURES_EN_MSN 0x95  
+#define SETFEATURES_EN_RETRY 0x99  
+#define SETFEATURES_EN_RLA 0xAA  
+#define SETFEATURES_PREFETCH 0xAB  
+#define SETFEATURES_EN_REST 0xAC  
+#define SETFEATURES_4B_RW_LONG 0xBB  
+#define SETFEATURES_DIS_AAM 0xC2  
+#define SETFEATURES_EN_RPOD 0xCC  
+#define SETFEATURES_DIS_RI 0xDD  
+#define SETFEATURES_EN_SAME_M 0xDD  
+#define SETFEATURES_DIS_SI 0xDE  
+
+#define SECURITY_SET_PASSWORD 0xBA
+#define SECURITY_UNLOCK 0xBB
+#define SECURITY_ERASE_PREPARE 0xBC
+#define SECURITY_ERASE_UNIT 0xBD
+#define SECURITY_FREEZE_LOCK 0xBE
+#define SECURITY_DISABLE_PASSWORD 0xBF
+
+struct hd_geometry {
+ unsigned char heads;
+ unsigned char sectors;
+ unsigned short cylinders;
+ unsigned long start;
+};
+
+#define HDIO_GETGEO 0x0301  
+#define HDIO_GET_UNMASKINTR 0x0302  
+#define HDIO_GET_MULTCOUNT 0x0304  
+#define HDIO_GET_QDMA 0x0305  
+
+#define HDIO_SET_XFER 0x0306  
+
+#define HDIO_OBSOLETE_IDENTITY 0x0307  
+#define HDIO_GET_KEEPSETTINGS 0x0308  
+#define HDIO_GET_32BIT 0x0309  
+#define HDIO_GET_NOWERR 0x030a  
+#define HDIO_GET_DMA 0x030b  
+#define HDIO_GET_NICE 0x030c  
+#define HDIO_GET_IDENTITY 0x030d  
+#define HDIO_GET_WCACHE 0x030e  
+#define HDIO_GET_ACOUSTIC 0x030f  
+#define HDIO_GET_ADDRESS 0x0310  
+
+#define HDIO_GET_BUSSTATE 0x031a  
+#define HDIO_TRISTATE_HWIF 0x031b  
+#define HDIO_DRIVE_RESET 0x031c  
+#define HDIO_DRIVE_TASKFILE 0x031d  
+#define HDIO_DRIVE_TASK 0x031e  
+#define HDIO_DRIVE_CMD 0x031f  
+#define HDIO_DRIVE_CMD_AEB HDIO_DRIVE_TASK
+
+#define HDIO_SET_MULTCOUNT 0x0321  
+#define HDIO_SET_UNMASKINTR 0x0322  
+#define HDIO_SET_KEEPSETTINGS 0x0323  
+#define HDIO_SET_32BIT 0x0324  
+#define HDIO_SET_NOWERR 0x0325  
+#define HDIO_SET_DMA 0x0326  
+#define HDIO_SET_PIO_MODE 0x0327  
+#define HDIO_SCAN_HWIF 0x0328  
+#define HDIO_SET_NICE 0x0329  
+#define HDIO_UNREGISTER_HWIF 0x032a  
+#define HDIO_SET_WCACHE 0x032b  
+#define HDIO_SET_ACOUSTIC 0x032c  
+#define HDIO_SET_BUSSTATE 0x032d  
+#define HDIO_SET_QDMA 0x032e  
+#define HDIO_SET_ADDRESS 0x032f  
+
+enum {
+ BUSSTATE_OFF = 0,
+ BUSSTATE_ON,
+ BUSSTATE_TRISTATE
+};
+
+#define __NEW_HD_DRIVE_ID
+
+struct hd_driveid {
+ unsigned short config;
+ unsigned short cyls;
+ unsigned short reserved2;
+ unsigned short heads;
+ unsigned short track_bytes;
+ unsigned short sector_bytes;
+ unsigned short sectors;
+ unsigned short vendor0;
+ unsigned short vendor1;
+ unsigned short vendor2;
+ unsigned char serial_no[20];
+ unsigned short buf_type;
+ unsigned short buf_size;
+ unsigned short ecc_bytes;
+ unsigned char fw_rev[8];
+ unsigned char model[40];
+ unsigned char max_multsect;
+ unsigned char vendor3;
+ unsigned short dword_io;
+ unsigned char vendor4;
+ unsigned char capability;
+ unsigned short reserved50;
+ unsigned char vendor5;
+ unsigned char tPIO;
+ unsigned char vendor6;
+ unsigned char tDMA;
+ unsigned short field_valid;
+ unsigned short cur_cyls;
+ unsigned short cur_heads;
+ unsigned short cur_sectors;
+ unsigned short cur_capacity0;
+ unsigned short cur_capacity1;
+ unsigned char multsect;
+ unsigned char multsect_valid;
+ unsigned int lba_capacity;
+ unsigned short dma_1word;
+ unsigned short dma_mword;
+ unsigned short eide_pio_modes;
+ unsigned short eide_dma_min;
+ unsigned short eide_dma_time;
+ unsigned short eide_pio;
+ unsigned short eide_pio_iordy;
+ unsigned short words69_70[2];
+
+ unsigned short words71_74[4];
+ unsigned short queue_depth;
+ unsigned short words76_79[4];
+ unsigned short major_rev_num;
+ unsigned short minor_rev_num;
+ unsigned short command_set_1;
+ unsigned short command_set_2;
+ unsigned short cfsse;
+ unsigned short cfs_enable_1;
+ unsigned short cfs_enable_2;
+ unsigned short csf_default;
+ unsigned short dma_ultra;
+ unsigned short trseuc;
+ unsigned short trsEuc;
+ unsigned short CurAPMvalues;
+ unsigned short mprc;
+ unsigned short hw_config;
+ unsigned short acoustic;
+ unsigned short msrqs;
+ unsigned short sxfert;
+ unsigned short sal;
+ unsigned int spg;
+ unsigned long long lba_capacity_2;
+ unsigned short words104_125[22];
+ unsigned short last_lun;
+ unsigned short word127;
+ unsigned short dlf;
+ unsigned short csfo;
+ unsigned short words130_155[26];
+ unsigned short word156;
+ unsigned short words157_159[3];
+ unsigned short cfa_power;
+ unsigned short words161_175[15];
+ unsigned short words176_205[30];
+ unsigned short words206_254[49];
+ unsigned short integrity_word;
+};
+
+#define IDE_NICE_DSC_OVERLAP (0)  
+#define IDE_NICE_ATAPI_OVERLAP (1)  
+#define IDE_NICE_0 (2)  
+#define IDE_NICE_1 (3)  
+#define IDE_NICE_2 (4)  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/hdsmart.h b/ndk/build/platforms/android-1.5/common/include/linux/hdsmart.h
new file mode 100644
index 0000000..6cbc653
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/hdsmart.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_HDSMART_H
+#define _LINUX_HDSMART_H
+
+#define OFFLINE_FULL_SCAN 0
+#define SHORT_SELF_TEST 1
+#define EXTEND_SELF_TEST 2
+#define SHORT_CAPTIVE_SELF_TEST 129
+#define EXTEND_CAPTIVE_SELF_TEST 130
+
+typedef struct ata_smart_attribute_s {
+ unsigned char id;
+ unsigned short status_flag;
+ unsigned char normalized;
+ unsigned char worse_normal;
+ unsigned char raw[6];
+ unsigned char reserv;
+} __attribute__ ((packed)) ata_smart_attribute_t;
+
+typedef struct ata_smart_values_s {
+ unsigned short revnumber;
+ ata_smart_attribute_t vendor_attributes [30];
+ unsigned char offline_data_collection_status;
+ unsigned char self_test_exec_status;
+ unsigned short total_time_to_complete_off_line;
+ unsigned char vendor_specific_366;
+ unsigned char offline_data_collection_capability;
+ unsigned short smart_capability;
+ unsigned char errorlog_capability;
+ unsigned char vendor_specific_371;
+ unsigned char short_test_completion_time;
+ unsigned char extend_test_completion_time;
+ unsigned char reserved_374_385 [12];
+ unsigned char vendor_specific_386_509 [125];
+ unsigned char chksum;
+} __attribute__ ((packed)) ata_smart_values_t;
+
+typedef struct ata_smart_threshold_entry_s {
+ unsigned char id;
+ unsigned char normalized_threshold;
+ unsigned char reserved[10];
+} __attribute__ ((packed)) ata_smart_threshold_entry_t;
+
+typedef struct ata_smart_thresholds_s {
+ unsigned short revnumber;
+ ata_smart_threshold_entry_t thres_entries[30];
+ unsigned char reserved[149];
+ unsigned char chksum;
+} __attribute__ ((packed)) ata_smart_thresholds_t;
+
+typedef struct ata_smart_errorlog_command_struct_s {
+ unsigned char devicecontrolreg;
+ unsigned char featuresreg;
+ unsigned char sector_count;
+ unsigned char sector_number;
+ unsigned char cylinder_low;
+ unsigned char cylinder_high;
+ unsigned char drive_head;
+ unsigned char commandreg;
+ unsigned int timestamp;
+} __attribute__ ((packed)) ata_smart_errorlog_command_struct_t;
+
+typedef struct ata_smart_errorlog_error_struct_s {
+ unsigned char error_condition;
+ unsigned char extended_error[14];
+ unsigned char state;
+ unsigned short timestamp;
+} __attribute__ ((packed)) ata_smart_errorlog_error_struct_t;
+
+typedef struct ata_smart_errorlog_struct_s {
+ ata_smart_errorlog_command_struct_t commands[6];
+ ata_smart_errorlog_error_struct_t error_struct;
+} __attribute__ ((packed)) ata_smart_errorlog_struct_t;
+
+typedef struct ata_smart_errorlog_s {
+ unsigned char revnumber;
+ unsigned char error_log_pointer;
+ ata_smart_errorlog_struct_t errorlog_struct[5];
+ unsigned short ata_error_count;
+ unsigned short non_fatal_count;
+ unsigned short drive_timeout_count;
+ unsigned char reserved[53];
+ unsigned char chksum;
+} __attribute__ ((packed)) ata_smart_errorlog_t;
+
+typedef struct ata_smart_selftestlog_struct_s {
+ unsigned char selftestnumber;
+ unsigned char selfteststatus;
+ unsigned short timestamp;
+ unsigned char selftestfailurecheckpoint;
+ unsigned int lbafirstfailure;
+ unsigned char vendorspecific[15];
+} __attribute__ ((packed)) ata_smart_selftestlog_struct_t;
+
+typedef struct ata_smart_selftestlog_s {
+ unsigned short revnumber;
+ ata_smart_selftestlog_struct_t selftest_struct[21];
+ unsigned char vendorspecific[2];
+ unsigned char mostrecenttest;
+ unsigned char resevered[2];
+ unsigned char chksum;
+} __attribute__ ((packed)) ata_smart_selftestlog_t;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/highmem.h b/ndk/build/platforms/android-1.5/common/include/linux/highmem.h
new file mode 100644
index 0000000..d4a34ca
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/highmem.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_HIGHMEM_H
+#define _LINUX_HIGHMEM_H
+
+#include <linux/fs.h>
+#include <linux/mm.h>
+
+#include <asm/cacheflush.h>
+
+#ifndef ARCH_HAS_FLUSH_ANON_PAGE
+#endif
+#ifndef ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
+#endif
+#define kunmap(page) do { (void) (page); } while (0)
+#define kmap_atomic(page, idx) page_address(page)
+#define kunmap_atomic(addr, idx) do { } while (0)
+#define kmap_atomic_pfn(pfn, idx) page_address(pfn_to_page(pfn))
+#define kmap_atomic_to_page(ptr) virt_to_page(ptr)
+#ifndef __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/hil.h b/ndk/build/platforms/android-1.5/common/include/linux/hil.h
new file mode 100644
index 0000000..a0b3b97
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/hil.h
@@ -0,0 +1,256 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _HIL_H_
+#define _HIL_H_
+
+#include <asm/types.h>
+
+#define HIL_CLOCK 8MHZ
+#define HIL_EK1_CLOCK 30HZ
+#define HIL_EK2_CLOCK 60HZ
+
+#define HIL_TIMEOUT_DEV 5  
+#define HIL_TIMEOUT_DEVS 10  
+#define HIL_TIMEOUT_NORESP 10  
+#define HIL_TIMEOUT_DEVS_DATA 16  
+#define HIL_TIMEOUT_SELFTEST 200  
+
+#define HIL_WIRE_PACKET_LEN 15
+enum hil_wire_bitpos {
+ HIL_WIRE_START = 0,
+ HIL_WIRE_ADDR2,
+ HIL_WIRE_ADDR1,
+ HIL_WIRE_ADDR0,
+ HIL_WIRE_COMMAND,
+ HIL_WIRE_DATA7,
+ HIL_WIRE_DATA6,
+ HIL_WIRE_DATA5,
+ HIL_WIRE_DATA4,
+ HIL_WIRE_DATA3,
+ HIL_WIRE_DATA2,
+ HIL_WIRE_DATA1,
+ HIL_WIRE_DATA0,
+ HIL_WIRE_PARITY,
+ HIL_WIRE_STOP
+};
+
+enum hil_pkt_bitpos {
+ HIL_PKT_CMD = 0x00000800,
+ HIL_PKT_ADDR2 = 0x00000400,
+ HIL_PKT_ADDR1 = 0x00000200,
+ HIL_PKT_ADDR0 = 0x00000100,
+ HIL_PKT_ADDR_MASK = 0x00000700,
+ HIL_PKT_ADDR_SHIFT = 8,
+ HIL_PKT_DATA7 = 0x00000080,
+ HIL_PKT_DATA6 = 0x00000040,
+ HIL_PKT_DATA5 = 0x00000020,
+ HIL_PKT_DATA4 = 0x00000010,
+ HIL_PKT_DATA3 = 0x00000008,
+ HIL_PKT_DATA2 = 0x00000004,
+ HIL_PKT_DATA1 = 0x00000002,
+ HIL_PKT_DATA0 = 0x00000001,
+ HIL_PKT_DATA_MASK = 0x000000FF,
+ HIL_PKT_DATA_SHIFT = 0
+};
+
+enum hil_error_bitpos {
+ HIL_ERR_OB = 0x00000800,
+ HIL_ERR_INT = 0x00010000,
+ HIL_ERR_NMI = 0x00020000,
+ HIL_ERR_LERR = 0x00040000,
+ HIL_ERR_PERR = 0x01000000,
+ HIL_ERR_FERR = 0x02000000,
+ HIL_ERR_FOF = 0x04000000
+};
+
+enum hil_control_bitpos {
+ HIL_CTRL_TEST = 0x00010000,
+ HIL_CTRL_IPF = 0x00040000,
+ HIL_CTRL_APE = 0x02000000
+};
+
+#define HIL_DO_ALTER_CTRL 0x40000000  
+#define HIL_CTRL_ONLY 0xc0000000  
+
+typedef u32 hil_packet;
+
+enum hil_command {
+ HIL_CMD_IFC = 0x00,
+ HIL_CMD_EPT = 0x01,
+ HIL_CMD_ELB = 0x02,
+ HIL_CMD_IDD = 0x03,
+ HIL_CMD_DSR = 0x04,
+ HIL_CMD_PST = 0x05,
+ HIL_CMD_RRG = 0x06,
+ HIL_CMD_WRG = 0x07,
+ HIL_CMD_ACF = 0x08,
+ HIL_CMDID_ACF = 0x07,
+ HIL_CMD_POL = 0x10,
+ HIL_CMDCT_POL = 0x0f,
+ HIL_CMD_RPL = 0x20,
+ HIL_CMDCT_RPL = 0x0f,
+ HIL_CMD_RNM = 0x30,
+ HIL_CMD_RST = 0x31,
+ HIL_CMD_EXD = 0x32,
+ HIL_CMD_RSC = 0x33,
+
+ HIL_CMD_DKA = 0x3d,
+ HIL_CMD_EK1 = 0x3e,
+ HIL_CMD_EK2 = 0x3f,
+ HIL_CMD_PR1 = 0x40,
+ HIL_CMD_PR2 = 0x41,
+ HIL_CMD_PR3 = 0x42,
+ HIL_CMD_PR4 = 0x43,
+ HIL_CMD_PR5 = 0x44,
+ HIL_CMD_PR6 = 0x45,
+ HIL_CMD_PR7 = 0x46,
+ HIL_CMD_PRM = 0x47,
+ HIL_CMD_AK1 = 0x48,
+ HIL_CMD_AK2 = 0x49,
+ HIL_CMD_AK3 = 0x4a,
+ HIL_CMD_AK4 = 0x4b,
+ HIL_CMD_AK5 = 0x4c,
+ HIL_CMD_AK6 = 0x4d,
+ HIL_CMD_AK7 = 0x4e,
+ HIL_CMD_ACK = 0x4f,
+
+ HIL_CMD_RIO = 0xfa,
+ HIL_CMD_SHR = 0xfb,
+ HIL_CMD_TER = 0xfc,
+ HIL_CMD_CAE = 0xfd,
+ HIL_CMD_DHR = 0xfe,
+
+};
+
+#define HIL_IDD_DID_TYPE_MASK 0xe0  
+#define HIL_IDD_DID_TYPE_KB_INTEGRAL 0xa0  
+#define HIL_IDD_DID_TYPE_KB_ITF 0xc0  
+#define HIL_IDD_DID_TYPE_KB_RSVD 0xe0  
+#define HIL_IDD_DID_TYPE_KB_LANG_MASK 0x1f  
+#define HIL_IDD_DID_KBLANG_USE_ESD 0x00  
+#define HIL_IDD_DID_TYPE_ABS 0x80  
+#define HIL_IDD_DID_ABS_RSVD1_MASK 0xf8  
+#define HIL_IDD_DID_ABS_RSVD1 0x98
+#define HIL_IDD_DID_ABS_TABLET_MASK 0xf8  
+#define HIL_IDD_DID_ABS_TABLET 0x90
+#define HIL_IDD_DID_ABS_TSCREEN_MASK 0xfc  
+#define HIL_IDD_DID_ABS_TSCREEN 0x8c
+#define HIL_IDD_DID_ABS_RSVD2_MASK 0xfc  
+#define HIL_IDD_DID_ABS_RSVD2 0x88
+#define HIL_IDD_DID_ABS_RSVD3_MASK 0xfc  
+#define HIL_IDD_DID_ABS_RSVD3 0x80
+#define HIL_IDD_DID_TYPE_REL 0x60  
+#define HIL_IDD_DID_REL_RSVD1_MASK 0xf0  
+#define HIL_IDD_DID_REL_RSVD1 0x70
+#define HIL_IDD_DID_REL_RSVD2_MASK 0xfc  
+#define HIL_IDD_DID_REL_RSVD2 0x6c
+#define HIL_IDD_DID_REL_MOUSE_MASK 0xfc  
+#define HIL_IDD_DID_REL_MOUSE 0x68
+#define HIL_IDD_DID_REL_QUAD_MASK 0xf8  
+#define HIL_IDD_DID_REL_QUAD 0x60
+#define HIL_IDD_DID_TYPE_CHAR 0x40  
+#define HIL_IDD_DID_CHAR_BARCODE_MASK 0xfc  
+#define HIL_IDD_DID_CHAR_BARCODE 0x5c
+#define HIL_IDD_DID_CHAR_RSVD1_MASK 0xfc  
+#define HIL_IDD_DID_CHAR_RSVD1 0x58
+#define HIL_IDD_DID_CHAR_RSVD2_MASK 0xf8  
+#define HIL_IDD_DID_CHAR_RSVD2 0x50
+#define HIL_IDD_DID_CHAR_RSVD3_MASK 0xf0  
+#define HIL_IDD_DID_CHAR_RSVD3 0x40
+#define HIL_IDD_DID_TYPE_OTHER 0x20  
+#define HIL_IDD_DID_OTHER_RSVD1_MASK 0xf0  
+#define HIL_IDD_DID_OTHER_RSVD1 0x30
+#define HIL_IDD_DID_OTHER_BARCODE_MASK 0xfc  
+#define HIL_IDD_DID_OTHER_BARCODE 0x2c
+#define HIL_IDD_DID_OTHER_RSVD2_MASK 0xfc  
+#define HIL_IDD_DID_OTHER_RSVD2 0x28
+#define HIL_IDD_DID_OTHER_RSVD3_MASK 0xf8  
+#define HIL_IDD_DID_OTHER_RSVD3 0x20
+#define HIL_IDD_DID_TYPE_KEYPAD 0x00  
+
+#define HIL_IDD_HEADER_AXSET_MASK 0x03  
+#define HIL_IDD_HEADER_RSC 0x04  
+#define HIL_IDD_HEADER_EXD 0x08  
+#define HIL_IDD_HEADER_IOD 0x10  
+#define HIL_IDD_HEADER_16BIT 0x20  
+#define HIL_IDD_HEADER_ABS 0x40  
+#define HIL_IDD_HEADER_2X_AXIS 0x80  
+
+#define HIL_IDD_IOD_NBUTTON_MASK 0x07  
+#define HIL_IDD_IOD_PROXIMITY 0x08  
+#define HIL_IDD_IOD_PROMPT_MASK 0x70  
+#define HIL_IDD_IOD_PROMPT_SHIFT 4
+#define HIL_IDD_IOD_PROMPT 0x80  
+
+#define HIL_IDD_NUM_AXES_PER_SET(header_packet)  ((header_packet) & HIL_IDD_HEADER_AXSET_MASK)
+
+#define HIL_IDD_NUM_AXSETS(header_packet)  (2 - !((header_packet) & HIL_IDD_HEADER_2X_AXIS))
+
+#define HIL_IDD_LEN(header_packet)  ((4 - !(header_packet & HIL_IDD_HEADER_IOD) -   2 * !(HIL_IDD_NUM_AXES_PER_SET(header_packet))) +   2 * HIL_IDD_NUM_AXES_PER_SET(header_packet) *   !!((header_packet) & HIL_IDD_HEADER_ABS))
+
+#define HIL_IDD_AXIS_COUNTS_PER_M(header_ptr)  (!(HIL_IDD_NUM_AXSETS(*(header_ptr))) ? -1 :  (((*(header_ptr + 1) & HIL_PKT_DATA_MASK) +   ((*(header_ptr + 2) & HIL_PKT_DATA_MASK)) << 8)  * ((*(header_ptr) & HIL_IDD_HEADER_16BIT) ? 100 : 1)))
+
+#define HIL_IDD_AXIS_MAX(header_ptr, __axnum)  ((!(*(header_ptr) & HIL_IDD_HEADER_ABS) ||   (HIL_IDD_NUM_AXES_PER_SET(*(header_ptr)) <= __axnum)) ? 0 :   ((HIL_PKT_DATA_MASK & *((header_ptr) + 3 + 2 * __axnum)) +   ((HIL_PKT_DATA_MASK & *((header_ptr) + 4 + 2 * __axnum)) << 8)))
+
+#define HIL_IDD_IOD(header_ptr)  (*(header_ptr + HIL_IDD_LEN((*header_ptr)) - 1))
+
+#define HIL_IDD_HAS_GEN_PROMPT(header_ptr)  ((*header_ptr & HIL_IDD_HEADER_IOD) &&   (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_PROMPT))
+
+#define HIL_IDD_HAS_GEN_PROXIMITY(header_ptr)  ((*header_ptr & HIL_IDD_HEADER_IOD) &&   (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_PROXIMITY))
+
+#define HIL_IDD_NUM_BUTTONS(header_ptr)  ((*header_ptr & HIL_IDD_HEADER_IOD) ?   (HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_NBUTTON_MASK) : 0)
+
+#define HIL_IDD_NUM_PROMPTS(header_ptr)  ((*header_ptr & HIL_IDD_HEADER_IOD) ?   ((HIL_IDD_IOD(header_ptr) & HIL_IDD_IOD_NPROMPT_MASK)   >> HIL_IDD_IOD_PROMPT_SHIFT) : 0)
+
+#define HIL_EXD_HEADER_WRG 0x03  
+#define HIL_EXD_HEADER_WRG_TYPE1 0x01  
+#define HIL_EXD_HEADER_WRG_TYPE2 0x02  
+#define HIL_EXD_HEADER_RRG 0x04  
+#define HIL_EXD_HEADER_RNM 0x10  
+#define HIL_EXD_HEADER_RST 0x20  
+#define HIL_EXD_HEADER_LOCALE 0x40  
+
+#define HIL_EXD_NUM_RRG(header_ptr)  ((*header_ptr & HIL_EXD_HEADER_RRG) ?   (*(header_ptr + 1) & HIL_PKT_DATA_MASK) : 0)
+
+#define HIL_EXD_NUM_WWG(header_ptr)  ((*header_ptr & HIL_EXD_HEADER_WRG) ?   (*(header_ptr + 2 - !(*header_ptr & HIL_EXD_HEADER_RRG)) &   HIL_PKT_DATA_MASK) : 0)
+
+#define HIL_EXD_LEN(header_ptr)  (!!(*header_ptr & HIL_EXD_HEADER_RRG) +   !!(*header_ptr & HIL_EXD_HEADER_WRG) +   !!(*header_ptr & HIL_EXD_HEADER_LOCALE) +   2 * !!(*header_ptr & HIL_EXD_HEADER_WRG_TYPE2) + 1)
+
+#define HIL_EXD_LOCALE(header_ptr)  (!(*header_ptr & HIL_EXD_HEADER_LOCALE) ? -1 :   (*(header_ptr + HIL_EXD_LEN(header_ptr) - 1) & HIL_PKT_DATA_MASK))
+
+#define HIL_EXD_WRG_TYPE2_LEN(header_ptr)  (!(*header_ptr & HIL_EXD_HEADER_WRG_TYPE2) ? -1 :   (*(header_ptr + HIL_EXD_LEN(header_ptr) - 2 -   !!(*header_ptr & HIL_EXD_HEADER_LOCALE)) & HIL_PKT_DATA_MASK) +   ((*(header_ptr + HIL_EXD_LEN(header_ptr) - 1 -   !!(*header_ptr & HIL_EXD_HEADER_LOCALE)) & HIL_PKT_DATA_MASK) << 8))
+
+#define HIL_LOCALE_MAX 0x1f
+
+#define HIL_LOCALE_MAP  "",    "",    "",    "swiss.french",    "portuguese",    "arabic",    "hebrew",    "english.canadian",    "turkish",    "greek",    "thai",    "italian",    "korean",    "dutch",    "swedish",    "german",    "chinese",    "chinese",    "swiss.french",    "spanish",    "swiss.german",    "flemish",    "finnish",    "english.uk",    "french.canadian",    "swiss.german",    "norwegian",    "french",    "danish",    "japanese",    "spanish",   "english.us"    
+
+#define HIL_KEYCODES_SET1_TBLSIZE 128
+#define HIL_KEYCODES_SET1   KEY_5, KEY_RESERVED, KEY_RIGHTALT, KEY_LEFTALT,   KEY_RIGHTSHIFT, KEY_LEFTSHIFT, KEY_LEFTCTRL, KEY_SYSRQ,   KEY_KP4, KEY_KP8, KEY_KP5, KEY_KP9,   KEY_KP6, KEY_KP7, KEY_KPCOMMA, KEY_KPENTER,   KEY_KP1, KEY_KPSLASH, KEY_KP2, KEY_KPPLUS,   KEY_KP3, KEY_KPASTERISK, KEY_KP0, KEY_KPMINUS,   KEY_B, KEY_V, KEY_C, KEY_X,   KEY_Z, KEY_RESERVED, KEY_RESERVED, KEY_ESC,   KEY_6, KEY_F10, KEY_3, KEY_F11,   KEY_KPDOT, KEY_F9, KEY_TAB  , KEY_F12,   KEY_H, KEY_G, KEY_F, KEY_D,   KEY_S, KEY_A, KEY_RESERVED, KEY_CAPSLOCK,   KEY_U, KEY_Y, KEY_T, KEY_R,   KEY_E, KEY_W, KEY_Q, KEY_TAB,   KEY_7, KEY_6, KEY_5, KEY_4,   KEY_3, KEY_2, KEY_1, KEY_GRAVE,   KEY_F13, KEY_F14, KEY_F15, KEY_F16,   KEY_F17, KEY_F18, KEY_F19, KEY_F20,   KEY_MENU, KEY_F4, KEY_F3, KEY_F2,   KEY_F1, KEY_VOLUMEUP, KEY_STOP, KEY_SENDFILE,   KEY_SYSRQ, KEY_F5, KEY_F6, KEY_F7,   KEY_F8, KEY_VOLUMEDOWN, KEY_DEL_EOL, KEY_DEL_EOS,   KEY_8, KEY_9, KEY_0, KEY_MINUS,   KEY_EQUAL, KEY_BACKSPACE, KEY_INS_LINE, KEY_DEL_LINE,   KEY_I, KEY_O, KEY_P, KEY_LEFTBRACE,   KEY_RIGHTBRACE, KEY_BACKSLASH, KEY_INSERT, KEY_DELETE,   KEY_J, KEY_K, KEY_L, KEY_SEMICOLON,   KEY_APOSTROPHE, KEY_ENTER, KEY_HOME, KEY_PAGEUP,   KEY_M, KEY_COMMA, KEY_DOT, KEY_SLASH,   KEY_BACKSLASH, KEY_SELECT, KEY_102ND, KEY_PAGEDOWN,   KEY_N, KEY_SPACE, KEY_NEXT, KEY_RESERVED,   KEY_LEFT, KEY_DOWN, KEY_UP, KEY_RIGHT
+
+#define HIL_KEYCODES_SET3_TBLSIZE 128
+#define HIL_KEYCODES_SET3   KEY_RESERVED, KEY_ESC, KEY_1, KEY_2,   KEY_3, KEY_4, KEY_5, KEY_6,   KEY_7, KEY_8, KEY_9, KEY_0,   KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_TAB,   KEY_Q, KEY_W, KEY_E, KEY_R,   KEY_T, KEY_Y, KEY_U, KEY_I,   KEY_O, KEY_P, KEY_LEFTBRACE, KEY_RIGHTBRACE,   KEY_ENTER, KEY_LEFTCTRL, KEY_A, KEY_S,   KEY_D, KEY_F, KEY_G, KEY_H,   KEY_J, KEY_K, KEY_L, KEY_SEMICOLON,   KEY_APOSTROPHE,KEY_GRAVE, KEY_LEFTSHIFT, KEY_BACKSLASH,   KEY_Z, KEY_X, KEY_C, KEY_V,   KEY_B, KEY_N, KEY_M, KEY_COMMA,   KEY_DOT, KEY_SLASH, KEY_RIGHTSHIFT, KEY_KPASTERISK,   KEY_LEFTALT, KEY_SPACE, KEY_CAPSLOCK, KEY_F1,   KEY_F2, KEY_F3, KEY_F4, KEY_F5,   KEY_F6, KEY_F7, KEY_F8, KEY_F9,   KEY_F10, KEY_NUMLOCK, KEY_SCROLLLOCK, KEY_KP7,   KEY_KP8, KEY_KP9, KEY_KPMINUS, KEY_KP4,   KEY_KP5, KEY_KP6, KEY_KPPLUS, KEY_KP1,   KEY_KP2, KEY_KP3, KEY_KP0, KEY_KPDOT,   KEY_SYSRQ, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,   KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,   KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,   KEY_UP, KEY_LEFT, KEY_DOWN, KEY_RIGHT,   KEY_HOME, KEY_PAGEUP, KEY_END, KEY_PAGEDOWN,   KEY_INSERT, KEY_DELETE, KEY_102ND, KEY_RESERVED,   KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,   KEY_F1, KEY_F2, KEY_F3, KEY_F4,   KEY_F5, KEY_F6, KEY_F7, KEY_F8,   KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED,   KEY_RESERVED, KEY_RESERVED, KEY_RESERVED, KEY_RESERVED
+
+#define HIL_POL_NUM_AXES_MASK 0x03  
+#define HIL_POL_CTS 0x04  
+#define HIL_POL_STATUS_PENDING 0x08  
+#define HIL_POL_CHARTYPE_MASK 0x70  
+#define HIL_POL_CHARTYPE_NONE 0x00  
+#define HIL_POL_CHARTYPE_RSVD1 0x10  
+#define HIL_POL_CHARTYPE_ASCII 0x20  
+#define HIL_POL_CHARTYPE_BINARY 0x30  
+#define HIL_POL_CHARTYPE_SET1 0x40  
+#define HIL_POL_CHARTYPE_RSVD2 0x50  
+#define HIL_POL_CHARTYPE_SET2 0x60  
+#define HIL_POL_CHARTYPE_SET3 0x70  
+#define HIL_POL_AXIS_ALT 0x80  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/i2c.h b/ndk/build/platforms/android-1.5/common/include/linux/i2c.h
new file mode 100644
index 0000000..9513fc6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/i2c.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_I2C_H
+#define _LINUX_I2C_H
+
+#include <linux/types.h>
+
+struct i2c_msg {
+ __u16 addr;
+ __u16 flags;
+#define I2C_M_TEN 0x10  
+#define I2C_M_RD 0x01
+#define I2C_M_NOSTART 0x4000
+#define I2C_M_REV_DIR_ADDR 0x2000
+#define I2C_M_IGNORE_NAK 0x1000
+#define I2C_M_NO_RD_ACK 0x0800
+ __u16 len;
+ __u8 *buf;
+};
+
+#define I2C_FUNC_I2C 0x00000001
+#define I2C_FUNC_10BIT_ADDR 0x00000002
+#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004  
+#define I2C_FUNC_SMBUS_HWPEC_CALC 0x00000008  
+#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000  
+#define I2C_FUNC_SMBUS_QUICK 0x00010000 
+#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 
+#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 
+#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000 
+#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 
+#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000 
+#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 
+#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000 
+#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 
+#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 
+#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000  
+#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000  
+#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000  
+#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000  
+
+#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE |   I2C_FUNC_SMBUS_WRITE_BYTE)
+#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA |   I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
+#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA |   I2C_FUNC_SMBUS_WRITE_WORD_DATA)
+#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA |   I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
+#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK |   I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
+#define I2C_FUNC_SMBUS_I2C_BLOCK_2 (I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 |   I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2)
+
+#define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK |   I2C_FUNC_SMBUS_BYTE |   I2C_FUNC_SMBUS_BYTE_DATA |   I2C_FUNC_SMBUS_WORD_DATA |   I2C_FUNC_SMBUS_PROC_CALL |   I2C_FUNC_SMBUS_WRITE_BLOCK_DATA |   I2C_FUNC_SMBUS_I2C_BLOCK)
+
+#define I2C_SMBUS_BLOCK_MAX 32   
+union i2c_smbus_data {
+ __u8 byte;
+ __u16 word;
+ __u8 block[I2C_SMBUS_BLOCK_MAX + 2];
+
+};
+
+#define I2C_SMBUS_READ 1
+#define I2C_SMBUS_WRITE 0
+
+#define I2C_SMBUS_QUICK 0
+#define I2C_SMBUS_BYTE 1
+#define I2C_SMBUS_BYTE_DATA 2 
+#define I2C_SMBUS_WORD_DATA 3
+#define I2C_SMBUS_PROC_CALL 4
+#define I2C_SMBUS_BLOCK_DATA 5
+#define I2C_SMBUS_I2C_BLOCK_DATA 6
+#define I2C_SMBUS_BLOCK_PROC_CALL 7  
+
+#define I2C_RETRIES 0x0701  
+
+#define I2C_TIMEOUT 0x0702  
+
+#define I2C_SLAVE 0x0703  
+
+#define I2C_SLAVE_FORCE 0x0706  
+
+#define I2C_TENBIT 0x0704  
+
+#define I2C_FUNCS 0x0705  
+#define I2C_RDWR 0x0707  
+#define I2C_PEC 0x0708  
+
+#define I2C_SMBUS 0x0720  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/icmp.h b/ndk/build/platforms/android-1.5/common/include/linux/icmp.h
new file mode 100644
index 0000000..c5b58bb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/icmp.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ICMP_H
+#define _LINUX_ICMP_H
+
+#include <linux/types.h>
+
+#define ICMP_ECHOREPLY 0  
+#define ICMP_DEST_UNREACH 3  
+#define ICMP_SOURCE_QUENCH 4  
+#define ICMP_REDIRECT 5  
+#define ICMP_ECHO 8  
+#define ICMP_TIME_EXCEEDED 11  
+#define ICMP_PARAMETERPROB 12  
+#define ICMP_TIMESTAMP 13  
+#define ICMP_TIMESTAMPREPLY 14  
+#define ICMP_INFO_REQUEST 15  
+#define ICMP_INFO_REPLY 16  
+#define ICMP_ADDRESS 17  
+#define ICMP_ADDRESSREPLY 18  
+#define NR_ICMP_TYPES 18
+
+#define ICMP_NET_UNREACH 0  
+#define ICMP_HOST_UNREACH 1  
+#define ICMP_PROT_UNREACH 2  
+#define ICMP_PORT_UNREACH 3  
+#define ICMP_FRAG_NEEDED 4  
+#define ICMP_SR_FAILED 5  
+#define ICMP_NET_UNKNOWN 6
+#define ICMP_HOST_UNKNOWN 7
+#define ICMP_HOST_ISOLATED 8
+#define ICMP_NET_ANO 9
+#define ICMP_HOST_ANO 10
+#define ICMP_NET_UNR_TOS 11
+#define ICMP_HOST_UNR_TOS 12
+#define ICMP_PKT_FILTERED 13  
+#define ICMP_PREC_VIOLATION 14  
+#define ICMP_PREC_CUTOFF 15  
+#define NR_ICMP_UNREACH 15  
+
+#define ICMP_REDIR_NET 0  
+#define ICMP_REDIR_HOST 1  
+#define ICMP_REDIR_NETTOS 2  
+#define ICMP_REDIR_HOSTTOS 3  
+
+#define ICMP_EXC_TTL 0  
+#define ICMP_EXC_FRAGTIME 1  
+
+struct icmphdr {
+ __u8 type;
+ __u8 code;
+ __u16 checksum;
+ union {
+ struct {
+ __u16 id;
+ __u16 sequence;
+ } echo;
+ __u32 gateway;
+ struct {
+ __u16 __unused_field;
+ __u16 mtu;
+ } frag;
+ } un;
+};
+
+#define ICMP_FILTER 1
+
+struct icmp_filter {
+ __u32 data;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/if.h b/ndk/build/platforms/android-1.5/common/include/linux/if.h
new file mode 100644
index 0000000..47c29d9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/if.h
@@ -0,0 +1,176 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IF_H
+#define _LINUX_IF_H
+
+#include <linux/types.h>  
+#include <linux/socket.h>  
+#include <linux/compiler.h>  
+
+#define IFNAMSIZ 16
+#include <linux/hdlc/ioctl.h>
+
+#define IFF_UP 0x1  
+#define IFF_BROADCAST 0x2  
+#define IFF_DEBUG 0x4  
+#define IFF_LOOPBACK 0x8  
+#define IFF_POINTOPOINT 0x10  
+#define IFF_NOTRAILERS 0x20  
+#define IFF_RUNNING 0x40  
+#define IFF_NOARP 0x80  
+#define IFF_PROMISC 0x100  
+#define IFF_ALLMULTI 0x200  
+
+#define IFF_MASTER 0x400  
+#define IFF_SLAVE 0x800  
+
+#define IFF_MULTICAST 0x1000  
+
+#define IFF_PORTSEL 0x2000  
+#define IFF_AUTOMEDIA 0x4000  
+#define IFF_DYNAMIC 0x8000  
+
+#define IFF_LOWER_UP 0x10000  
+#define IFF_DORMANT 0x20000  
+
+#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|  IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
+
+#define IFF_802_1Q_VLAN 0x1  
+#define IFF_EBRIDGE 0x2  
+#define IFF_SLAVE_INACTIVE 0x4  
+#define IFF_MASTER_8023AD 0x8  
+#define IFF_MASTER_ALB 0x10  
+
+#define IF_GET_IFACE 0x0001  
+#define IF_GET_PROTO 0x0002
+
+#define IF_IFACE_V35 0x1000  
+#define IF_IFACE_V24 0x1001  
+#define IF_IFACE_X21 0x1002  
+#define IF_IFACE_T1 0x1003  
+#define IF_IFACE_E1 0x1004  
+#define IF_IFACE_SYNC_SERIAL 0x1005  
+#define IF_IFACE_X21D 0x1006  
+
+#define IF_PROTO_HDLC 0x2000  
+#define IF_PROTO_PPP 0x2001  
+#define IF_PROTO_CISCO 0x2002  
+#define IF_PROTO_FR 0x2003  
+#define IF_PROTO_FR_ADD_PVC 0x2004  
+#define IF_PROTO_FR_DEL_PVC 0x2005  
+#define IF_PROTO_X25 0x2006  
+#define IF_PROTO_HDLC_ETH 0x2007  
+#define IF_PROTO_FR_ADD_ETH_PVC 0x2008  
+#define IF_PROTO_FR_DEL_ETH_PVC 0x2009  
+#define IF_PROTO_FR_PVC 0x200A  
+#define IF_PROTO_FR_ETH_PVC 0x200B
+#define IF_PROTO_RAW 0x200C  
+
+enum {
+ IF_OPER_UNKNOWN,
+ IF_OPER_NOTPRESENT,
+ IF_OPER_DOWN,
+ IF_OPER_LOWERLAYERDOWN,
+ IF_OPER_TESTING,
+ IF_OPER_DORMANT,
+ IF_OPER_UP,
+};
+
+enum {
+ IF_LINK_MODE_DEFAULT,
+ IF_LINK_MODE_DORMANT,
+};
+
+struct ifmap
+{
+ unsigned long mem_start;
+ unsigned long mem_end;
+ unsigned short base_addr;
+ unsigned char irq;
+ unsigned char dma;
+ unsigned char port;
+
+};
+
+struct if_settings
+{
+ unsigned int type;
+ unsigned int size;
+ union {
+
+ raw_hdlc_proto __user *raw_hdlc;
+ cisco_proto __user *cisco;
+ fr_proto __user *fr;
+ fr_proto_pvc __user *fr_pvc;
+ fr_proto_pvc_info __user *fr_pvc_info;
+
+ sync_serial_settings __user *sync;
+ te1_settings __user *te1;
+ } ifs_ifsu;
+};
+
+struct ifreq
+{
+#define IFHWADDRLEN 6
+ union
+ {
+ char ifrn_name[IFNAMSIZ];
+ } ifr_ifrn;
+
+ union {
+ struct sockaddr ifru_addr;
+ struct sockaddr ifru_dstaddr;
+ struct sockaddr ifru_broadaddr;
+ struct sockaddr ifru_netmask;
+ struct sockaddr ifru_hwaddr;
+ short ifru_flags;
+ int ifru_ivalue;
+ int ifru_mtu;
+ struct ifmap ifru_map;
+ char ifru_slave[IFNAMSIZ];
+ char ifru_newname[IFNAMSIZ];
+ void __user * ifru_data;
+ struct if_settings ifru_settings;
+ } ifr_ifru;
+};
+
+#define ifr_name ifr_ifrn.ifrn_name  
+#define ifr_hwaddr ifr_ifru.ifru_hwaddr  
+#define ifr_addr ifr_ifru.ifru_addr  
+#define ifr_dstaddr ifr_ifru.ifru_dstaddr  
+#define ifr_broadaddr ifr_ifru.ifru_broadaddr  
+#define ifr_netmask ifr_ifru.ifru_netmask  
+#define ifr_flags ifr_ifru.ifru_flags  
+#define ifr_metric ifr_ifru.ifru_ivalue  
+#define ifr_mtu ifr_ifru.ifru_mtu  
+#define ifr_map ifr_ifru.ifru_map  
+#define ifr_slave ifr_ifru.ifru_slave  
+#define ifr_data ifr_ifru.ifru_data  
+#define ifr_ifindex ifr_ifru.ifru_ivalue  
+#define ifr_bandwidth ifr_ifru.ifru_ivalue  
+#define ifr_qlen ifr_ifru.ifru_ivalue  
+#define ifr_newname ifr_ifru.ifru_newname  
+#define ifr_settings ifr_ifru.ifru_settings  
+
+struct ifconf
+{
+ int ifc_len;
+ union
+ {
+ char __user *ifcu_buf;
+ struct ifreq __user *ifcu_req;
+ } ifc_ifcu;
+};
+#define ifc_buf ifc_ifcu.ifcu_buf  
+#define ifc_req ifc_ifcu.ifcu_req  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/if_arcnet.h b/ndk/build/platforms/android-1.5/common/include/linux/if_arcnet.h
new file mode 100644
index 0000000..a1ad877
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/if_arcnet.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IF_ARCNET_H
+#define _LINUX_IF_ARCNET_H
+
+#include <linux/if_ether.h>
+
+#define ARC_P_IP 212  
+#define ARC_P_IPV6 196  
+#define ARC_P_ARP 213  
+#define ARC_P_RARP 214  
+#define ARC_P_IPX 250  
+#define ARC_P_NOVELL_EC 236  
+
+#define ARC_P_IP_RFC1051 240  
+#define ARC_P_ARP_RFC1051 241  
+
+#define ARC_P_ETHER 232  
+
+#define ARC_P_DATAPOINT_BOOT 0  
+#define ARC_P_DATAPOINT_MOUNT 1
+#define ARC_P_POWERLAN_BEACON 8  
+#define ARC_P_POWERLAN_BEACON2 243  
+#define ARC_P_LANSOFT 251  
+#define ARC_P_ATALK 0xDD
+
+#define ARCNET_ALEN 1
+
+struct arc_rfc1201
+{
+ uint8_t proto;
+ uint8_t split_flag;
+ uint16_t sequence;
+ uint8_t payload[0];
+};
+#define RFC1201_HDR_SIZE 4
+
+struct arc_rfc1051
+{
+ uint8_t proto;
+ uint8_t payload[0];
+};
+#define RFC1051_HDR_SIZE 1
+
+struct arc_eth_encap
+{
+ uint8_t proto;
+ struct ethhdr eth;
+ uint8_t payload[0];
+};
+#define ETH_ENCAP_HDR_SIZE 14
+
+struct arc_cap
+{
+ uint8_t proto;
+ uint8_t cookie[sizeof(int)];
+ union {
+ uint8_t ack;
+ uint8_t raw[0];
+ } mes;
+};
+
+struct arc_hardware
+{
+ uint8_t source,
+ dest,
+ offset[2];
+};
+#define ARC_HDR_SIZE 4
+
+struct archdr
+{
+
+ struct arc_hardware hard;
+
+ union {
+ struct arc_rfc1201 rfc1201;
+ struct arc_rfc1051 rfc1051;
+ struct arc_eth_encap eth_encap;
+ struct arc_cap cap;
+ uint8_t raw[0];
+ } soft;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/if_arp.h b/ndk/build/platforms/android-1.5/common/include/linux/if_arp.h
new file mode 100644
index 0000000..1da50f5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/if_arp.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IF_ARP_H
+#define _LINUX_IF_ARP_H
+
+#include <linux/netdevice.h>
+
+#define ARPHRD_NETROM 0  
+#define ARPHRD_ETHER 1  
+#define ARPHRD_EETHER 2  
+#define ARPHRD_AX25 3  
+#define ARPHRD_PRONET 4  
+#define ARPHRD_CHAOS 5  
+#define ARPHRD_IEEE802 6  
+#define ARPHRD_ARCNET 7  
+#define ARPHRD_APPLETLK 8  
+#define ARPHRD_DLCI 15  
+#define ARPHRD_ATM 19  
+#define ARPHRD_METRICOM 23  
+#define ARPHRD_IEEE1394 24  
+#define ARPHRD_EUI64 27  
+#define ARPHRD_INFINIBAND 32  
+
+#define ARPHRD_SLIP 256
+#define ARPHRD_CSLIP 257
+#define ARPHRD_SLIP6 258
+#define ARPHRD_CSLIP6 259
+#define ARPHRD_RSRVD 260  
+#define ARPHRD_ADAPT 264
+#define ARPHRD_ROSE 270
+#define ARPHRD_X25 271  
+#define ARPHRD_HWX25 272  
+#define ARPHRD_PPP 512
+#define ARPHRD_CISCO 513  
+#define ARPHRD_HDLC ARPHRD_CISCO
+#define ARPHRD_LAPB 516  
+#define ARPHRD_DDCMP 517  
+#define ARPHRD_RAWHDLC 518  
+
+#define ARPHRD_TUNNEL 768  
+#define ARPHRD_TUNNEL6 769  
+#define ARPHRD_FRAD 770  
+#define ARPHRD_SKIP 771  
+#define ARPHRD_LOOPBACK 772  
+#define ARPHRD_LOCALTLK 773  
+#define ARPHRD_FDDI 774  
+#define ARPHRD_BIF 775  
+#define ARPHRD_SIT 776  
+#define ARPHRD_IPDDP 777  
+#define ARPHRD_IPGRE 778  
+#define ARPHRD_PIMREG 779  
+#define ARPHRD_HIPPI 780  
+#define ARPHRD_ASH 781  
+#define ARPHRD_ECONET 782  
+#define ARPHRD_IRDA 783  
+
+#define ARPHRD_FCPP 784  
+#define ARPHRD_FCAL 785  
+#define ARPHRD_FCPL 786  
+#define ARPHRD_FCFABRIC 787  
+
+#define ARPHRD_IEEE802_TR 800  
+#define ARPHRD_IEEE80211 801  
+#define ARPHRD_IEEE80211_PRISM 802  
+#define ARPHRD_IEEE80211_RADIOTAP 803  
+
+#define ARPHRD_VOID 0xFFFF  
+#define ARPHRD_NONE 0xFFFE  
+
+#define ARPOP_REQUEST 1  
+#define ARPOP_REPLY 2  
+#define ARPOP_RREQUEST 3  
+#define ARPOP_RREPLY 4  
+#define ARPOP_InREQUEST 8  
+#define ARPOP_InREPLY 9  
+#define ARPOP_NAK 10  
+
+struct arpreq {
+ struct sockaddr arp_pa;
+ struct sockaddr arp_ha;
+ int arp_flags;
+ struct sockaddr arp_netmask;
+ char arp_dev[16];
+};
+
+struct arpreq_old {
+ struct sockaddr arp_pa;
+ struct sockaddr arp_ha;
+ int arp_flags;
+ struct sockaddr arp_netmask;
+};
+
+#define ATF_COM 0x02  
+#define ATF_PERM 0x04  
+#define ATF_PUBL 0x08  
+#define ATF_USETRAILERS 0x10  
+#define ATF_NETMASK 0x20  
+#define ATF_DONTPUB 0x40  
+
+struct arphdr
+{
+ unsigned short ar_hrd;
+ unsigned short ar_pro;
+ unsigned char ar_hln;
+ unsigned char ar_pln;
+ unsigned short ar_op;
+
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/if_bridge.h b/ndk/build/platforms/android-1.5/common/include/linux/if_bridge.h
new file mode 100644
index 0000000..93f9494
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/if_bridge.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IF_BRIDGE_H
+#define _LINUX_IF_BRIDGE_H
+
+#include <linux/types.h>
+
+#define SYSFS_BRIDGE_ATTR "bridge"
+#define SYSFS_BRIDGE_FDB "brforward"
+#define SYSFS_BRIDGE_PORT_SUBDIR "brif"
+#define SYSFS_BRIDGE_PORT_ATTR "brport"
+#define SYSFS_BRIDGE_PORT_LINK "bridge"
+
+#define BRCTL_VERSION 1
+
+#define BRCTL_GET_VERSION 0
+#define BRCTL_GET_BRIDGES 1
+#define BRCTL_ADD_BRIDGE 2
+#define BRCTL_DEL_BRIDGE 3
+#define BRCTL_ADD_IF 4
+#define BRCTL_DEL_IF 5
+#define BRCTL_GET_BRIDGE_INFO 6
+#define BRCTL_GET_PORT_LIST 7
+#define BRCTL_SET_BRIDGE_FORWARD_DELAY 8
+#define BRCTL_SET_BRIDGE_HELLO_TIME 9
+#define BRCTL_SET_BRIDGE_MAX_AGE 10
+#define BRCTL_SET_AGEING_TIME 11
+#define BRCTL_SET_GC_INTERVAL 12
+#define BRCTL_GET_PORT_INFO 13
+#define BRCTL_SET_BRIDGE_STP_STATE 14
+#define BRCTL_SET_BRIDGE_PRIORITY 15
+#define BRCTL_SET_PORT_PRIORITY 16
+#define BRCTL_SET_PATH_COST 17
+#define BRCTL_GET_FDB_ENTRIES 18
+
+#define BR_STATE_DISABLED 0
+#define BR_STATE_LISTENING 1
+#define BR_STATE_LEARNING 2
+#define BR_STATE_FORWARDING 3
+#define BR_STATE_BLOCKING 4
+
+struct __bridge_info
+{
+ __u64 designated_root;
+ __u64 bridge_id;
+ __u32 root_path_cost;
+ __u32 max_age;
+ __u32 hello_time;
+ __u32 forward_delay;
+ __u32 bridge_max_age;
+ __u32 bridge_hello_time;
+ __u32 bridge_forward_delay;
+ __u8 topology_change;
+ __u8 topology_change_detected;
+ __u8 root_port;
+ __u8 stp_enabled;
+ __u32 ageing_time;
+ __u32 gc_interval;
+ __u32 hello_timer_value;
+ __u32 tcn_timer_value;
+ __u32 topology_change_timer_value;
+ __u32 gc_timer_value;
+};
+
+struct __port_info
+{
+ __u64 designated_root;
+ __u64 designated_bridge;
+ __u16 port_id;
+ __u16 designated_port;
+ __u32 path_cost;
+ __u32 designated_cost;
+ __u8 state;
+ __u8 top_change_ack;
+ __u8 config_pending;
+ __u8 unused0;
+ __u32 message_age_timer_value;
+ __u32 forward_delay_timer_value;
+ __u32 hold_timer_value;
+};
+
+struct __fdb_entry
+{
+ __u8 mac_addr[6];
+ __u8 port_no;
+ __u8 is_local;
+ __u32 ageing_timer_value;
+ __u32 unused;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/if_ether.h b/ndk/build/platforms/android-1.5/common/include/linux/if_ether.h
new file mode 100644
index 0000000..ff89c3d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/if_ether.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IF_ETHER_H
+#define _LINUX_IF_ETHER_H
+
+#include <linux/types.h>
+
+#define ETH_ALEN 6  
+#define ETH_HLEN 14  
+#define ETH_ZLEN 60  
+#define ETH_DATA_LEN 1500  
+#define ETH_FRAME_LEN 1514  
+
+#define ETH_P_LOOP 0x0060  
+#define ETH_P_PUP 0x0200  
+#define ETH_P_PUPAT 0x0201  
+#define ETH_P_IP 0x0800  
+#define ETH_P_X25 0x0805  
+#define ETH_P_ARP 0x0806  
+#define ETH_P_BPQ 0x08FF  
+#define ETH_P_IEEEPUP 0x0a00  
+#define ETH_P_IEEEPUPAT 0x0a01  
+#define ETH_P_DEC 0x6000  
+#define ETH_P_DNA_DL 0x6001  
+#define ETH_P_DNA_RC 0x6002  
+#define ETH_P_DNA_RT 0x6003  
+#define ETH_P_LAT 0x6004  
+#define ETH_P_DIAG 0x6005  
+#define ETH_P_CUST 0x6006  
+#define ETH_P_SCA 0x6007  
+#define ETH_P_RARP 0x8035  
+#define ETH_P_ATALK 0x809B  
+#define ETH_P_AARP 0x80F3  
+#define ETH_P_8021Q 0x8100  
+#define ETH_P_IPX 0x8137  
+#define ETH_P_IPV6 0x86DD  
+#define ETH_P_SLOW 0x8809  
+#define ETH_P_WCCP 0x883E  
+#define ETH_P_PPP_DISC 0x8863  
+#define ETH_P_PPP_SES 0x8864  
+#define ETH_P_MPLS_UC 0x8847  
+#define ETH_P_MPLS_MC 0x8848  
+#define ETH_P_ATMMPOA 0x884c  
+#define ETH_P_ATMFATE 0x8884  
+#define ETH_P_AOE 0x88A2  
+#define ETH_P_TIPC 0x88CA  
+
+#define ETH_P_802_3 0x0001  
+#define ETH_P_AX25 0x0002  
+#define ETH_P_ALL 0x0003  
+#define ETH_P_802_2 0x0004  
+#define ETH_P_SNAP 0x0005  
+#define ETH_P_DDCMP 0x0006  
+#define ETH_P_WAN_PPP 0x0007  
+#define ETH_P_PPP_MP 0x0008  
+#define ETH_P_LOCALTALK 0x0009  
+#define ETH_P_PPPTALK 0x0010  
+#define ETH_P_TR_802_2 0x0011  
+#define ETH_P_MOBITEX 0x0015  
+#define ETH_P_CONTROL 0x0016  
+#define ETH_P_IRDA 0x0017  
+#define ETH_P_ECONET 0x0018  
+#define ETH_P_HDLC 0x0019  
+#define ETH_P_ARCNET 0x001A  
+
+struct ethhdr {
+ unsigned char h_dest[ETH_ALEN];
+ unsigned char h_source[ETH_ALEN];
+ __be16 h_proto;
+} __attribute__((packed));
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/if_fc.h b/ndk/build/platforms/android-1.5/common/include/linux/if_fc.h
new file mode 100644
index 0000000..a6a47b4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/if_fc.h
@@ -0,0 +1,35 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IF_FC_H
+#define _LINUX_IF_FC_H
+
+#define FC_ALEN 6  
+#define FC_HLEN (sizeof(struct fch_hdr)+sizeof(struct fcllc))
+#define FC_ID_LEN 3  
+
+#define EXTENDED_SAP 0xAA
+#define UI_CMD 0x03
+
+struct fch_hdr {
+ __u8 daddr[FC_ALEN];
+ __u8 saddr[FC_ALEN];
+};
+
+struct fcllc {
+ __u8 dsap;
+ __u8 ssap;
+ __u8 llc;
+ __u8 protid[3];
+ __be16 ethertype;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/if_fddi.h b/ndk/build/platforms/android-1.5/common/include/linux/if_fddi.h
new file mode 100644
index 0000000..f59492f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/if_fddi.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IF_FDDI_H
+#define _LINUX_IF_FDDI_H
+
+#define FDDI_K_ALEN 6  
+#define FDDI_K_8022_HLEN 16  
+#define FDDI_K_SNAP_HLEN 21  
+#define FDDI_K_8022_ZLEN 16  
+#define FDDI_K_SNAP_ZLEN 21  
+#define FDDI_K_8022_DLEN 4475  
+#define FDDI_K_SNAP_DLEN 4470  
+#define FDDI_K_LLC_ZLEN 13  
+#define FDDI_K_LLC_LEN 4491  
+
+#define FDDI_FC_K_VOID 0x00 
+#define FDDI_FC_K_NON_RESTRICTED_TOKEN 0x80 
+#define FDDI_FC_K_RESTRICTED_TOKEN 0xC0 
+#define FDDI_FC_K_SMT_MIN 0x41
+#define FDDI_FC_K_SMT_MAX 0x4F
+#define FDDI_FC_K_MAC_MIN 0xC1
+#define FDDI_FC_K_MAC_MAX 0xCF 
+#define FDDI_FC_K_ASYNC_LLC_MIN 0x50
+#define FDDI_FC_K_ASYNC_LLC_DEF 0x54
+#define FDDI_FC_K_ASYNC_LLC_MAX 0x5F
+#define FDDI_FC_K_SYNC_LLC_MIN 0xD0
+#define FDDI_FC_K_SYNC_LLC_MAX 0xD7
+#define FDDI_FC_K_IMPLEMENTOR_MIN 0x60
+#define FDDI_FC_K_IMPLEMENTOR_MAX 0x6F
+#define FDDI_FC_K_RESERVED_MIN 0x70
+#define FDDI_FC_K_RESERVED_MAX 0x7F
+
+#define FDDI_EXTENDED_SAP 0xAA
+#define FDDI_UI_CMD 0x03
+
+struct fddi_8022_1_hdr
+ {
+ __u8 dsap;
+ __u8 ssap;
+ __u8 ctrl;
+ } __attribute__ ((packed));
+
+struct fddi_8022_2_hdr
+ {
+ __u8 dsap;
+ __u8 ssap;
+ __u8 ctrl_1;
+ __u8 ctrl_2;
+ } __attribute__ ((packed));
+
+#define FDDI_K_OUI_LEN 3
+struct fddi_snap_hdr
+ {
+ __u8 dsap;
+ __u8 ssap;
+ __u8 ctrl;
+ __u8 oui[FDDI_K_OUI_LEN];
+ __be16 ethertype;
+ } __attribute__ ((packed));
+
+struct fddihdr
+ {
+ __u8 fc;
+ __u8 daddr[FDDI_K_ALEN];
+ __u8 saddr[FDDI_K_ALEN];
+ union
+ {
+ struct fddi_8022_1_hdr llc_8022_1;
+ struct fddi_8022_2_hdr llc_8022_2;
+ struct fddi_snap_hdr llc_snap;
+ } hdr;
+ } __attribute__ ((packed));
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/if_hippi.h b/ndk/build/platforms/android-1.5/common/include/linux/if_hippi.h
new file mode 100644
index 0000000..52d36f6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/if_hippi.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IF_HIPPI_H
+#define _LINUX_IF_HIPPI_H
+
+#include <asm/byteorder.h>
+
+#define HIPPI_ALEN 6  
+#define HIPPI_HLEN sizeof(struct hippi_hdr)
+#define HIPPI_ZLEN 0  
+#define HIPPI_DATA_LEN 65280  
+#define HIPPI_FRAME_LEN (HIPPI_DATA_LEN + HIPPI_HLEN)
+
+#define HIPPI_EXTENDED_SAP 0xAA
+#define HIPPI_UI_CMD 0x03
+
+struct hipnet_statistics
+{
+ int rx_packets;
+ int tx_packets;
+ int rx_errors;
+ int tx_errors;
+ int rx_dropped;
+ int tx_dropped;
+
+ int rx_length_errors;
+ int rx_over_errors;
+ int rx_crc_errors;
+ int rx_frame_errors;
+ int rx_fifo_errors;
+ int rx_missed_errors;
+
+ int tx_aborted_errors;
+ int tx_carrier_errors;
+ int tx_fifo_errors;
+ int tx_heartbeat_errors;
+ int tx_window_errors;
+};
+
+struct hippi_fp_hdr
+{
+ __be32 fixed;
+ __be32 d2_size;
+} __attribute__ ((packed));
+
+struct hippi_le_hdr
+{
+#ifdef __BIG_ENDIAN_BITFIELD
+ __u8 fc:3;
+ __u8 double_wide:1;
+ __u8 message_type:4;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 message_type:4;
+ __u8 double_wide:1;
+ __u8 fc:3;
+#endif
+ __u8 dest_switch_addr[3];
+#ifdef __BIG_ENDIAN_BITFIELD
+ __u8 dest_addr_type:4,
+ src_addr_type:4;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 src_addr_type:4,
+ dest_addr_type:4;
+#endif
+ __u8 src_switch_addr[3];
+ __u16 reserved;
+ __u8 daddr[HIPPI_ALEN];
+ __u16 locally_administered;
+ __u8 saddr[HIPPI_ALEN];
+} __attribute__ ((packed));
+
+#define HIPPI_OUI_LEN 3
+
+struct hippi_snap_hdr
+{
+ __u8 dsap;
+ __u8 ssap;
+ __u8 ctrl;
+ __u8 oui[HIPPI_OUI_LEN];
+ __be16 ethertype;
+} __attribute__ ((packed));
+
+struct hippi_hdr
+{
+ struct hippi_fp_hdr fp;
+ struct hippi_le_hdr le;
+ struct hippi_snap_hdr snap;
+} __attribute__ ((packed));
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/if_packet.h b/ndk/build/platforms/android-1.5/common/include/linux/if_packet.h
new file mode 100644
index 0000000..1aa3bea
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/if_packet.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_IF_PACKET_H
+#define __LINUX_IF_PACKET_H
+
+struct sockaddr_pkt
+{
+ unsigned short spkt_family;
+ unsigned char spkt_device[14];
+ unsigned short spkt_protocol;
+};
+
+struct sockaddr_ll
+{
+ unsigned short sll_family;
+ unsigned short sll_protocol;
+ int sll_ifindex;
+ unsigned short sll_hatype;
+ unsigned char sll_pkttype;
+ unsigned char sll_halen;
+ unsigned char sll_addr[8];
+};
+
+#define PACKET_HOST 0  
+#define PACKET_BROADCAST 1  
+#define PACKET_MULTICAST 2  
+#define PACKET_OTHERHOST 3  
+#define PACKET_OUTGOING 4  
+
+#define PACKET_LOOPBACK 5  
+#define PACKET_FASTROUTE 6  
+
+#define PACKET_ADD_MEMBERSHIP 1
+#define PACKET_DROP_MEMBERSHIP 2
+#define PACKET_RECV_OUTPUT 3
+
+#define PACKET_RX_RING 5
+#define PACKET_STATISTICS 6
+#define PACKET_COPY_THRESH 7
+
+struct tpacket_stats
+{
+ unsigned int tp_packets;
+ unsigned int tp_drops;
+};
+
+struct tpacket_hdr
+{
+ unsigned long tp_status;
+#define TP_STATUS_KERNEL 0
+#define TP_STATUS_USER 1
+#define TP_STATUS_COPY 2
+#define TP_STATUS_LOSING 4
+#define TP_STATUS_CSUMNOTREADY 8
+ unsigned int tp_len;
+ unsigned int tp_snaplen;
+ unsigned short tp_mac;
+ unsigned short tp_net;
+ unsigned int tp_sec;
+ unsigned int tp_usec;
+};
+
+#define TPACKET_ALIGNMENT 16
+#define TPACKET_ALIGN(x) (((x)+TPACKET_ALIGNMENT-1)&~(TPACKET_ALIGNMENT-1))
+#define TPACKET_HDRLEN (TPACKET_ALIGN(sizeof(struct tpacket_hdr)) + sizeof(struct sockaddr_ll))
+
+struct tpacket_req
+{
+ unsigned int tp_block_size;
+ unsigned int tp_block_nr;
+ unsigned int tp_frame_size;
+ unsigned int tp_frame_nr;
+};
+
+struct packet_mreq
+{
+ int mr_ifindex;
+ unsigned short mr_type;
+ unsigned short mr_alen;
+ unsigned char mr_address[8];
+};
+
+#define PACKET_MR_MULTICAST 0
+#define PACKET_MR_PROMISC 1
+#define PACKET_MR_ALLMULTI 2
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/if_ppp.h b/ndk/build/platforms/android-1.5/common/include/linux/if_ppp.h
new file mode 100644
index 0000000..9f35c97
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/if_ppp.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IF_PPP_H_
+#define _IF_PPP_H_
+
+#include <linux/compiler.h>
+
+#define PPP_MTU 1500  
+#define PPP_MAXMRU 65000  
+#define PROTO_IPX 0x002b  
+#define PROTO_DNA_RT 0x0027  
+
+#define SC_COMP_PROT 0x00000001  
+#define SC_COMP_AC 0x00000002  
+#define SC_COMP_TCP 0x00000004  
+#define SC_NO_TCP_CCID 0x00000008  
+#define SC_REJ_COMP_AC 0x00000010  
+#define SC_REJ_COMP_TCP 0x00000020  
+#define SC_CCP_OPEN 0x00000040  
+#define SC_CCP_UP 0x00000080  
+#define SC_ENABLE_IP 0x00000100  
+#define SC_LOOP_TRAFFIC 0x00000200  
+#define SC_MULTILINK 0x00000400  
+#define SC_MP_SHORTSEQ 0x00000800  
+#define SC_COMP_RUN 0x00001000  
+#define SC_DECOMP_RUN 0x00002000  
+#define SC_MP_XSHORTSEQ 0x00004000  
+#define SC_DEBUG 0x00010000  
+#define SC_LOG_INPKT 0x00020000  
+#define SC_LOG_OUTPKT 0x00040000  
+#define SC_LOG_RAWIN 0x00080000  
+#define SC_LOG_FLUSH 0x00100000  
+#define SC_SYNC 0x00200000  
+#define SC_MUST_COMP 0x00400000  
+#define SC_MASK 0x0f600fff  
+
+#define SC_XMIT_BUSY 0x10000000  
+#define SC_RCV_ODDP 0x08000000  
+#define SC_RCV_EVNP 0x04000000  
+#define SC_RCV_B7_1 0x02000000  
+#define SC_RCV_B7_0 0x01000000  
+#define SC_DC_FERROR 0x00800000  
+#define SC_DC_ERROR 0x00400000  
+
+struct npioctl {
+ int protocol;
+ enum NPmode mode;
+};
+
+struct ppp_option_data {
+ __u8 __user *ptr;
+ __u32 length;
+ int transmit;
+};
+
+struct ifpppstatsreq {
+ struct ifreq b;
+ struct ppp_stats stats;
+};
+
+struct ifpppcstatsreq {
+ struct ifreq b;
+ struct ppp_comp_stats stats;
+};
+
+#define ifr__name b.ifr_ifrn.ifrn_name
+#define stats_ptr b.ifr_ifru.ifru_data
+
+#define PPPIOCGFLAGS _IOR('t', 90, int)  
+#define PPPIOCSFLAGS _IOW('t', 89, int)  
+#define PPPIOCGASYNCMAP _IOR('t', 88, int)  
+#define PPPIOCSASYNCMAP _IOW('t', 87, int)  
+#define PPPIOCGUNIT _IOR('t', 86, int)  
+#define PPPIOCGRASYNCMAP _IOR('t', 85, int)  
+#define PPPIOCSRASYNCMAP _IOW('t', 84, int)  
+#define PPPIOCGMRU _IOR('t', 83, int)  
+#define PPPIOCSMRU _IOW('t', 82, int)  
+#define PPPIOCSMAXCID _IOW('t', 81, int)  
+#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm)  
+#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm)  
+#define PPPIOCXFERUNIT _IO('t', 78)  
+#define PPPIOCSCOMPRESS _IOW('t', 77, struct ppp_option_data)
+#define PPPIOCGNPMODE _IOWR('t', 76, struct npioctl)  
+#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl)  
+#define PPPIOCSPASS _IOW('t', 71, struct sock_fprog)  
+#define PPPIOCSACTIVE _IOW('t', 70, struct sock_fprog)  
+#define PPPIOCGDEBUG _IOR('t', 65, int)  
+#define PPPIOCSDEBUG _IOW('t', 64, int)  
+#define PPPIOCGIDLE _IOR('t', 63, struct ppp_idle)  
+#define PPPIOCNEWUNIT _IOWR('t', 62, int)  
+#define PPPIOCATTACH _IOW('t', 61, int)  
+#define PPPIOCDETACH _IOW('t', 60, int)  
+#define PPPIOCSMRRU _IOW('t', 59, int)  
+#define PPPIOCCONNECT _IOW('t', 58, int)  
+#define PPPIOCDISCONN _IO('t', 57)  
+#define PPPIOCATTCHAN _IOW('t', 56, int)  
+#define PPPIOCGCHAN _IOR('t', 55, int)  
+
+#define SIOCGPPPSTATS (SIOCDEVPRIVATE + 0)
+#define SIOCGPPPVER (SIOCDEVPRIVATE + 1)  
+#define SIOCGPPPCSTATS (SIOCDEVPRIVATE + 2)
+
+#ifndef ifr_mtu
+#define ifr_mtu ifr_ifru.ifru_metric
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/if_tr.h b/ndk/build/platforms/android-1.5/common/include/linux/if_tr.h
new file mode 100644
index 0000000..7d6319a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/if_tr.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IF_TR_H
+#define _LINUX_IF_TR_H
+
+#include <asm/byteorder.h>  
+
+#define TR_ALEN 6  
+#define TR_HLEN (sizeof(struct trh_hdr)+sizeof(struct trllc))
+#define AC 0x10
+#define LLC_FRAME 0x40
+
+#define EXTENDED_SAP 0xAA
+#define UI_CMD 0x03
+
+struct trh_hdr {
+ __u8 ac;
+ __u8 fc;
+ __u8 daddr[TR_ALEN];
+ __u8 saddr[TR_ALEN];
+ __be16 rcf;
+ __be16 rseg[8];
+};
+
+struct trllc {
+ __u8 dsap;
+ __u8 ssap;
+ __u8 llc;
+ __u8 protid[3];
+ __be16 ethertype;
+};
+
+struct tr_statistics {
+ unsigned long rx_packets;
+ unsigned long tx_packets;
+ unsigned long rx_bytes;
+ unsigned long tx_bytes;
+ unsigned long rx_errors;
+ unsigned long tx_errors;
+ unsigned long rx_dropped;
+ unsigned long tx_dropped;
+ unsigned long multicast;
+ unsigned long transmit_collision;
+
+ unsigned long line_errors;
+ unsigned long internal_errors;
+ unsigned long burst_errors;
+ unsigned long A_C_errors;
+ unsigned long abort_delimiters;
+ unsigned long lost_frames;
+ unsigned long recv_congest_count;
+ unsigned long frame_copied_errors;
+ unsigned long frequency_errors;
+ unsigned long token_errors;
+ unsigned long dummy1;
+};
+
+#define TR_RII 0x80
+#define TR_RCF_DIR_BIT 0x80
+#define TR_RCF_LEN_MASK 0x1f00
+#define TR_RCF_BROADCAST 0x8000  
+#define TR_RCF_LIMITED_BROADCAST 0xC000  
+#define TR_RCF_FRAME2K 0x20
+#define TR_RCF_BROADCAST_MASK 0xC000
+#define TR_MAXRIFLEN 18
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/if_tun.h b/ndk/build/platforms/android-1.5/common/include/linux/if_tun.h
new file mode 100644
index 0000000..c5db4e0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/if_tun.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __IF_TUN_H
+#define __IF_TUN_H
+
+#define TUN_READQ_SIZE 500
+
+#define TUN_TUN_DEV 0x0001 
+#define TUN_TAP_DEV 0x0002
+#define TUN_TYPE_MASK 0x000f
+
+#define TUN_FASYNC 0x0010
+#define TUN_NOCHECKSUM 0x0020
+#define TUN_NO_PI 0x0040
+#define TUN_ONE_QUEUE 0x0080
+#define TUN_PERSIST 0x0100 
+
+#define TUNSETNOCSUM _IOW('T', 200, int) 
+#define TUNSETDEBUG _IOW('T', 201, int) 
+#define TUNSETIFF _IOW('T', 202, int) 
+#define TUNSETPERSIST _IOW('T', 203, int) 
+#define TUNSETOWNER _IOW('T', 204, int)
+#define TUNSETLINK _IOW('T', 205, int)
+
+#define IFF_TUN 0x0001
+#define IFF_TAP 0x0002
+#define IFF_NO_PI 0x1000
+#define IFF_ONE_QUEUE 0x2000
+
+struct tun_pi {
+ unsigned short flags;
+ unsigned short proto;
+};
+#define TUN_PKT_STRIP 0x0001
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/if_vlan.h b/ndk/build/platforms/android-1.5/common/include/linux/if_vlan.h
new file mode 100644
index 0000000..d3d2df2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/if_vlan.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IF_VLAN_H_
+#define _LINUX_IF_VLAN_H_
+
+enum vlan_ioctl_cmds {
+ ADD_VLAN_CMD,
+ DEL_VLAN_CMD,
+ SET_VLAN_INGRESS_PRIORITY_CMD,
+ SET_VLAN_EGRESS_PRIORITY_CMD,
+ GET_VLAN_INGRESS_PRIORITY_CMD,
+ GET_VLAN_EGRESS_PRIORITY_CMD,
+ SET_VLAN_NAME_TYPE_CMD,
+ SET_VLAN_FLAG_CMD,
+ GET_VLAN_REALDEV_NAME_CMD,
+ GET_VLAN_VID_CMD
+};
+
+enum vlan_name_types {
+ VLAN_NAME_TYPE_PLUS_VID,
+ VLAN_NAME_TYPE_RAW_PLUS_VID,
+ VLAN_NAME_TYPE_PLUS_VID_NO_PAD,
+ VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD,
+ VLAN_NAME_TYPE_HIGHEST
+};
+
+struct vlan_ioctl_args {
+ int cmd;
+ char device1[24];
+
+ union {
+ char device2[24];
+ int VID;
+ unsigned int skb_priority;
+ unsigned int name_type;
+ unsigned int bind_type;
+ unsigned int flag;
+ } u;
+
+ short vlan_qos;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/in.h b/ndk/build/platforms/android-1.5/common/include/linux/in.h
new file mode 100644
index 0000000..894e2da
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/in.h
@@ -0,0 +1,211 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IN_H
+#define _LINUX_IN_H
+
+#include <linux/types.h>
+#include <linux/socket.h>
+
+enum {
+ IPPROTO_IP = 0,
+ IPPROTO_ICMP = 1,
+ IPPROTO_IGMP = 2,
+ IPPROTO_IPIP = 4,
+ IPPROTO_TCP = 6,
+ IPPROTO_EGP = 8,
+ IPPROTO_PUP = 12,
+ IPPROTO_UDP = 17,
+ IPPROTO_IDP = 22,
+ IPPROTO_DCCP = 33,
+ IPPROTO_RSVP = 46,
+ IPPROTO_GRE = 47,
+
+ IPPROTO_IPV6 = 41,
+
+ IPPROTO_ESP = 50,
+ IPPROTO_AH = 51,
+ IPPROTO_PIM = 103,
+
+ IPPROTO_COMP = 108,
+ IPPROTO_SCTP = 132,
+
+ IPPROTO_RAW = 255,
+ IPPROTO_MAX
+};
+
+struct in_addr {
+ __u32 s_addr;
+};
+
+#define IP_TOS 1
+#define IP_TTL 2
+#define IP_HDRINCL 3
+#define IP_OPTIONS 4
+#define IP_ROUTER_ALERT 5
+#define IP_RECVOPTS 6
+#define IP_RETOPTS 7
+#define IP_PKTINFO 8
+#define IP_PKTOPTIONS 9
+#define IP_MTU_DISCOVER 10
+#define IP_RECVERR 11
+#define IP_RECVTTL 12
+#define IP_RECVTOS 13
+#define IP_MTU 14
+#define IP_FREEBIND 15
+#define IP_IPSEC_POLICY 16
+#define IP_XFRM_POLICY 17
+#define IP_PASSSEC 18
+
+#define IP_RECVRETOPTS IP_RETOPTS
+
+#define IP_PMTUDISC_DONT 0  
+#define IP_PMTUDISC_WANT 1  
+#define IP_PMTUDISC_DO 2  
+
+#define IP_MULTICAST_IF 32
+#define IP_MULTICAST_TTL 33
+#define IP_MULTICAST_LOOP 34
+#define IP_ADD_MEMBERSHIP 35
+#define IP_DROP_MEMBERSHIP 36
+#define IP_UNBLOCK_SOURCE 37
+#define IP_BLOCK_SOURCE 38
+#define IP_ADD_SOURCE_MEMBERSHIP 39
+#define IP_DROP_SOURCE_MEMBERSHIP 40
+#define IP_MSFILTER 41
+#define MCAST_JOIN_GROUP 42
+#define MCAST_BLOCK_SOURCE 43
+#define MCAST_UNBLOCK_SOURCE 44
+#define MCAST_LEAVE_GROUP 45
+#define MCAST_JOIN_SOURCE_GROUP 46
+#define MCAST_LEAVE_SOURCE_GROUP 47
+#define MCAST_MSFILTER 48
+
+#define MCAST_EXCLUDE 0
+#define MCAST_INCLUDE 1
+
+#define IP_DEFAULT_MULTICAST_TTL 1
+#define IP_DEFAULT_MULTICAST_LOOP 1
+
+struct ip_mreq
+{
+ struct in_addr imr_multiaddr;
+ struct in_addr imr_interface;
+};
+
+struct ip_mreqn
+{
+ struct in_addr imr_multiaddr;
+ struct in_addr imr_address;
+ int imr_ifindex;
+};
+
+struct ip_mreq_source {
+ __u32 imr_multiaddr;
+ __u32 imr_interface;
+ __u32 imr_sourceaddr;
+};
+
+struct ip_msfilter {
+ __u32 imsf_multiaddr;
+ __u32 imsf_interface;
+ __u32 imsf_fmode;
+ __u32 imsf_numsrc;
+ __u32 imsf_slist[1];
+};
+
+#define IP_MSFILTER_SIZE(numsrc)   (sizeof(struct ip_msfilter) - sizeof(__u32)   + (numsrc) * sizeof(__u32))
+
+struct group_req
+{
+ __u32 gr_interface;
+ struct __kernel_sockaddr_storage gr_group;
+};
+
+struct group_source_req
+{
+ __u32 gsr_interface;
+ struct __kernel_sockaddr_storage gsr_group;
+ struct __kernel_sockaddr_storage gsr_source;
+};
+
+struct group_filter
+{
+ __u32 gf_interface;
+ struct __kernel_sockaddr_storage gf_group;
+ __u32 gf_fmode;
+ __u32 gf_numsrc;
+ struct __kernel_sockaddr_storage gf_slist[1];
+};
+
+#define GROUP_FILTER_SIZE(numsrc)   (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage)   + (numsrc) * sizeof(struct __kernel_sockaddr_storage))
+
+struct in_pktinfo
+{
+ int ipi_ifindex;
+ struct in_addr ipi_spec_dst;
+ struct in_addr ipi_addr;
+};
+
+#define __SOCK_SIZE__ 16  
+struct sockaddr_in {
+ sa_family_t sin_family;
+ unsigned short int sin_port;
+ struct in_addr sin_addr;
+
+ unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
+ sizeof(unsigned short int) - sizeof(struct in_addr)];
+};
+#define sin_zero __pad  
+
+#define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0)
+#define IN_CLASSA_NET 0xff000000
+#define IN_CLASSA_NSHIFT 24
+#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET)
+#define IN_CLASSA_MAX 128
+
+#define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000)
+#define IN_CLASSB_NET 0xffff0000
+#define IN_CLASSB_NSHIFT 16
+#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET)
+#define IN_CLASSB_MAX 65536
+
+#define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000)
+#define IN_CLASSC_NET 0xffffff00
+#define IN_CLASSC_NSHIFT 8
+#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET)
+
+#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
+#define IN_MULTICAST(a) IN_CLASSD(a)
+#define IN_MULTICAST_NET 0xF0000000
+
+#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
+#define IN_BADCLASS(a) IN_EXPERIMENTAL((a))
+
+#define INADDR_ANY ((unsigned long int) 0x00000000)
+
+#define INADDR_BROADCAST ((unsigned long int) 0xffffffff)
+
+#define INADDR_NONE ((unsigned long int) 0xffffffff)
+
+#define IN_LOOPBACKNET 127
+
+#define INADDR_LOOPBACK 0x7f000001  
+#define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000)
+
+#define INADDR_UNSPEC_GROUP 0xe0000000U  
+#define INADDR_ALLHOSTS_GROUP 0xe0000001U  
+#define INADDR_ALLRTRS_GROUP 0xe0000002U  
+#define INADDR_MAX_LOCAL_GROUP 0xe00000ffU  
+
+#include <asm/byteorder.h> 
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/in6.h b/ndk/build/platforms/android-1.5/common/include/linux/in6.h
new file mode 100644
index 0000000..ceaeb7d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/in6.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IN6_H
+#define _LINUX_IN6_H
+
+#include <linux/types.h>
+
+struct in6_addr
+{
+ union
+ {
+ __u8 u6_addr8[16];
+ __u16 u6_addr16[8];
+ __u32 u6_addr32[4];
+ } in6_u;
+#define s6_addr in6_u.u6_addr8
+#define s6_addr16 in6_u.u6_addr16
+#define s6_addr32 in6_u.u6_addr32
+};
+
+#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
+
+struct sockaddr_in6 {
+ unsigned short int sin6_family;
+ __u16 sin6_port;
+ __u32 sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ __u32 sin6_scope_id;
+};
+
+struct ipv6_mreq {
+
+ struct in6_addr ipv6mr_multiaddr;
+
+ int ipv6mr_ifindex;
+};
+
+#define ipv6mr_acaddr ipv6mr_multiaddr
+
+struct in6_flowlabel_req
+{
+ struct in6_addr flr_dst;
+ __u32 flr_label;
+ __u8 flr_action;
+ __u8 flr_share;
+ __u16 flr_flags;
+ __u16 flr_expires;
+ __u16 flr_linger;
+ __u32 __flr_pad;
+
+};
+
+#define IPV6_FL_A_GET 0
+#define IPV6_FL_A_PUT 1
+#define IPV6_FL_A_RENEW 2
+
+#define IPV6_FL_F_CREATE 1
+#define IPV6_FL_F_EXCL 2
+
+#define IPV6_FL_S_NONE 0
+#define IPV6_FL_S_EXCL 1
+#define IPV6_FL_S_PROCESS 2
+#define IPV6_FL_S_USER 3
+#define IPV6_FL_S_ANY 255
+
+#define IPV6_FLOWINFO_FLOWLABEL 0x000fffff
+#define IPV6_FLOWINFO_PRIORITY 0x0ff00000
+
+#define IPV6_PRIORITY_UNCHARACTERIZED 0x0000
+#define IPV6_PRIORITY_FILLER 0x0100
+#define IPV6_PRIORITY_UNATTENDED 0x0200
+#define IPV6_PRIORITY_RESERVED1 0x0300
+#define IPV6_PRIORITY_BULK 0x0400
+#define IPV6_PRIORITY_RESERVED2 0x0500
+#define IPV6_PRIORITY_INTERACTIVE 0x0600
+#define IPV6_PRIORITY_CONTROL 0x0700
+#define IPV6_PRIORITY_8 0x0800
+#define IPV6_PRIORITY_9 0x0900
+#define IPV6_PRIORITY_10 0x0a00
+#define IPV6_PRIORITY_11 0x0b00
+#define IPV6_PRIORITY_12 0x0c00
+#define IPV6_PRIORITY_13 0x0d00
+#define IPV6_PRIORITY_14 0x0e00
+#define IPV6_PRIORITY_15 0x0f00
+
+#define IPPROTO_HOPOPTS 0  
+#define IPPROTO_ROUTING 43  
+#define IPPROTO_FRAGMENT 44  
+#define IPPROTO_ICMPV6 58  
+#define IPPROTO_NONE 59  
+#define IPPROTO_DSTOPTS 60  
+
+#define IPV6_TLV_PAD0 0
+#define IPV6_TLV_PADN 1
+#define IPV6_TLV_ROUTERALERT 5
+#define IPV6_TLV_JUMBO 194
+
+#define IPV6_ADDRFORM 1
+#define IPV6_2292PKTINFO 2
+#define IPV6_2292HOPOPTS 3
+#define IPV6_2292DSTOPTS 4
+#define IPV6_2292RTHDR 5
+#define IPV6_2292PKTOPTIONS 6
+#define IPV6_CHECKSUM 7
+#define IPV6_2292HOPLIMIT 8
+#define IPV6_NEXTHOP 9
+#define IPV6_AUTHHDR 10  
+#define IPV6_FLOWINFO 11
+
+#define IPV6_UNICAST_HOPS 16
+#define IPV6_MULTICAST_IF 17
+#define IPV6_MULTICAST_HOPS 18
+#define IPV6_MULTICAST_LOOP 19
+#define IPV6_ADD_MEMBERSHIP 20
+#define IPV6_DROP_MEMBERSHIP 21
+#define IPV6_ROUTER_ALERT 22
+#define IPV6_MTU_DISCOVER 23
+#define IPV6_MTU 24
+#define IPV6_RECVERR 25
+#define IPV6_V6ONLY 26
+#define IPV6_JOIN_ANYCAST 27
+#define IPV6_LEAVE_ANYCAST 28
+
+#define IPV6_PMTUDISC_DONT 0
+#define IPV6_PMTUDISC_WANT 1
+#define IPV6_PMTUDISC_DO 2
+
+#define IPV6_FLOWLABEL_MGR 32
+#define IPV6_FLOWINFO_SEND 33
+
+#define IPV6_IPSEC_POLICY 34
+#define IPV6_XFRM_POLICY 35
+
+#define IPV6_RECVPKTINFO 49
+#define IPV6_PKTINFO 50
+#define IPV6_RECVHOPLIMIT 51
+#define IPV6_HOPLIMIT 52
+#define IPV6_RECVHOPOPTS 53
+#define IPV6_HOPOPTS 54
+#define IPV6_RTHDRDSTOPTS 55
+#define IPV6_RECVRTHDR 56
+#define IPV6_RTHDR 57
+#define IPV6_RECVDSTOPTS 58
+#define IPV6_DSTOPTS 59
+
+#define IPV6_RECVTCLASS 66
+#define IPV6_TCLASS 67
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/init.h b/ndk/build/platforms/android-1.5/common/include/linux/init.h
new file mode 100644
index 0000000..846c4eb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/init.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_INIT_H
+#define _LINUX_INIT_H
+
+#include <linux/compiler.h>
+
+#define __init __attribute__ ((__section__ (".init.text")))
+#define __initdata __attribute__ ((__section__ (".init.data")))
+#define __exitdata __attribute__ ((__section__(".exit.data")))
+#define __exit_call __attribute_used__ __attribute__ ((__section__ (".exitcall.exit")))
+
+#ifdef MODULE
+#define __exit __attribute__ ((__section__(".exit.text")))
+#else
+#define __exit __attribute_used__ __attribute__ ((__section__(".exit.text")))
+#endif
+
+#define __INIT .section ".init.text","ax"
+#define __FINIT .previous
+#define __INITDATA .section ".init.data","aw"
+
+#ifndef __ASSEMBLY__
+
+typedef int (*initcall_t)(void);
+typedef void (*exitcall_t)(void);
+
+#endif
+
+#ifndef MODULE
+
+#ifndef __ASSEMBLY__
+
+#define __define_initcall(level,fn)   static initcall_t __initcall_##fn __attribute_used__   __attribute__((__section__(".initcall" level ".init"))) = fn
+
+#define core_initcall(fn) __define_initcall("1",fn)
+#define postcore_initcall(fn) __define_initcall("2",fn)
+#define arch_initcall(fn) __define_initcall("3",fn)
+#define subsys_initcall(fn) __define_initcall("4",fn)
+#define fs_initcall(fn) __define_initcall("5",fn)
+#define device_initcall(fn) __define_initcall("6",fn)
+#define late_initcall(fn) __define_initcall("7",fn)
+
+#define __initcall(fn) device_initcall(fn)
+
+#define __exitcall(fn)   static exitcall_t __exitcall_##fn __exit_call = fn
+
+#define console_initcall(fn)   static initcall_t __initcall_##fn   __attribute_used__ __attribute__((__section__(".con_initcall.init")))=fn
+
+#define security_initcall(fn)   static initcall_t __initcall_##fn   __attribute_used__ __attribute__((__section__(".security_initcall.init"))) = fn
+
+struct obs_kernel_param {
+ const char *str;
+ int (*setup_func)(char *);
+ int early;
+};
+
+#define __setup_param(str, unique_id, fn, early)   static char __setup_str_##unique_id[] __initdata = str;   static struct obs_kernel_param __setup_##unique_id   __attribute_used__   __attribute__((__section__(".init.setup")))   __attribute__((aligned((sizeof(long)))))   = { __setup_str_##unique_id, fn, early }
+
+#define __setup_null_param(str, unique_id)   __setup_param(str, unique_id, NULL, 0)
+
+#define __setup(str, fn)   __setup_param(str, fn, fn, 0)
+
+#define __obsolete_setup(str)   __setup_null_param(str, __LINE__)
+
+#define early_param(str, fn)   __setup_param(str, fn, fn, 1)
+
+#endif
+
+#define module_init(x) __initcall(x);
+
+#define module_exit(x) __exitcall(x);
+
+#else
+
+#define core_initcall(fn) module_init(fn)
+#define postcore_initcall(fn) module_init(fn)
+#define arch_initcall(fn) module_init(fn)
+#define subsys_initcall(fn) module_init(fn)
+#define fs_initcall(fn) module_init(fn)
+#define device_initcall(fn) module_init(fn)
+#define late_initcall(fn) module_init(fn)
+
+#define security_initcall(fn) module_init(fn)
+
+#define module_init(initfn)   static inline initcall_t __inittest(void)   { return initfn; }   int init_module(void) __attribute__((alias(#initfn)));
+
+#define module_exit(exitfn)   static inline exitcall_t __exittest(void)   { return exitfn; }   void cleanup_module(void) __attribute__((alias(#exitfn)));
+
+#define __setup_param(str, unique_id, fn)  
+#define __setup_null_param(str, unique_id)  
+#define __setup(str, func)  
+#define __obsolete_setup(str)  
+#endif
+
+#define __nosavedata __attribute__ ((__section__ (".data.nosave")))
+
+#define __init_or_module __init
+#define __initdata_or_module __initdata
+
+#define __devinit __init
+#define __devinitdata __initdata
+#define __devexit __exit
+#define __devexitdata __exitdata
+
+#define __cpuinit __init
+#define __cpuinitdata __initdata
+#define __cpuexit __exit
+#define __cpuexitdata __exitdata
+
+#define __meminit __init
+#define __meminitdata __initdata
+#define __memexit __exit
+#define __memexitdata __exitdata
+
+#ifdef MODULE
+#define __devexit_p(x) x
+#else
+#define __devexit_p(x) NULL
+#endif
+
+#ifdef MODULE
+#define __exit_p(x) x
+#else
+#define __exit_p(x) NULL
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/inotify.h b/ndk/build/platforms/android-1.5/common/include/linux/inotify.h
new file mode 100644
index 0000000..db53417
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/inotify.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_INOTIFY_H
+#define _LINUX_INOTIFY_H
+
+#include <linux/types.h>
+
+struct inotify_event {
+ __s32 wd;
+ __u32 mask;
+ __u32 cookie;
+ __u32 len;
+ char name[0];
+};
+
+#define IN_ACCESS 0x00000001  
+#define IN_MODIFY 0x00000002  
+#define IN_ATTRIB 0x00000004  
+#define IN_CLOSE_WRITE 0x00000008  
+#define IN_CLOSE_NOWRITE 0x00000010  
+#define IN_OPEN 0x00000020  
+#define IN_MOVED_FROM 0x00000040  
+#define IN_MOVED_TO 0x00000080  
+#define IN_CREATE 0x00000100  
+#define IN_DELETE 0x00000200  
+#define IN_DELETE_SELF 0x00000400  
+#define IN_MOVE_SELF 0x00000800  
+
+#define IN_UNMOUNT 0x00002000  
+#define IN_Q_OVERFLOW 0x00004000  
+#define IN_IGNORED 0x00008000  
+
+#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)  
+#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO)  
+
+#define IN_ONLYDIR 0x01000000  
+#define IN_DONT_FOLLOW 0x02000000  
+#define IN_MASK_ADD 0x20000000  
+#define IN_ISDIR 0x40000000  
+#define IN_ONESHOT 0x80000000  
+
+#define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE |   IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM |   IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF |   IN_MOVE_SELF)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/input.h b/ndk/build/platforms/android-1.5/common/include/linux/input.h
new file mode 100644
index 0000000..96dae14
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/input.h
@@ -0,0 +1,715 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _INPUT_H
+#define _INPUT_H
+
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <asm/types.h>
+
+struct input_event {
+ struct timeval time;
+ __u16 type;
+ __u16 code;
+ __s32 value;
+};
+
+#define EV_VERSION 0x010000
+
+struct input_id {
+ __u16 bustype;
+ __u16 vendor;
+ __u16 product;
+ __u16 version;
+};
+
+struct input_absinfo {
+ __s32 value;
+ __s32 minimum;
+ __s32 maximum;
+ __s32 fuzz;
+ __s32 flat;
+};
+
+#define EVIOCGVERSION _IOR('E', 0x01, int)  
+#define EVIOCGID _IOR('E', 0x02, struct input_id)  
+#define EVIOCGREP _IOR('E', 0x03, int[2])  
+#define EVIOCSREP _IOW('E', 0x03, int[2])  
+#define EVIOCGKEYCODE _IOR('E', 0x04, int[2])  
+#define EVIOCSKEYCODE _IOW('E', 0x04, int[2])  
+
+#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len)  
+#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len)  
+#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len)  
+
+#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len)  
+#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len)  
+#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len)  
+#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len)  
+
+#define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + ev, len)  
+#define EVIOCGABS(abs) _IOR('E', 0x40 + abs, struct input_absinfo)  
+#define EVIOCSABS(abs) _IOW('E', 0xc0 + abs, struct input_absinfo)  
+
+#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect))  
+#define EVIOCRMFF _IOW('E', 0x81, int)  
+#define EVIOCGEFFECTS _IOR('E', 0x84, int)  
+
+#define EVIOCGRAB _IOW('E', 0x90, int)  
+
+#define EV_SYN 0x00
+#define EV_KEY 0x01
+#define EV_REL 0x02
+#define EV_ABS 0x03
+#define EV_MSC 0x04
+#define EV_SW 0x05
+#define EV_LED 0x11
+#define EV_SND 0x12
+#define EV_REP 0x14
+#define EV_FF 0x15
+#define EV_PWR 0x16
+#define EV_FF_STATUS 0x17
+#define EV_MAX 0x1f
+
+#define SYN_REPORT 0
+#define SYN_CONFIG 1
+
+#define KEY_RESERVED 0
+#define KEY_ESC 1
+#define KEY_1 2
+#define KEY_2 3
+#define KEY_3 4
+#define KEY_4 5
+#define KEY_5 6
+#define KEY_6 7
+#define KEY_7 8
+#define KEY_8 9
+#define KEY_9 10
+#define KEY_0 11
+#define KEY_MINUS 12
+#define KEY_EQUAL 13
+#define KEY_BACKSPACE 14
+#define KEY_TAB 15
+#define KEY_Q 16
+#define KEY_W 17
+#define KEY_E 18
+#define KEY_R 19
+#define KEY_T 20
+#define KEY_Y 21
+#define KEY_U 22
+#define KEY_I 23
+#define KEY_O 24
+#define KEY_P 25
+#define KEY_LEFTBRACE 26
+#define KEY_RIGHTBRACE 27
+#define KEY_ENTER 28
+#define KEY_LEFTCTRL 29
+#define KEY_A 30
+#define KEY_S 31
+#define KEY_D 32
+#define KEY_F 33
+#define KEY_G 34
+#define KEY_H 35
+#define KEY_J 36
+#define KEY_K 37
+#define KEY_L 38
+#define KEY_SEMICOLON 39
+#define KEY_APOSTROPHE 40
+#define KEY_GRAVE 41
+#define KEY_LEFTSHIFT 42
+#define KEY_BACKSLASH 43
+#define KEY_Z 44
+#define KEY_X 45
+#define KEY_C 46
+#define KEY_V 47
+#define KEY_B 48
+#define KEY_N 49
+#define KEY_M 50
+#define KEY_COMMA 51
+#define KEY_DOT 52
+#define KEY_SLASH 53
+#define KEY_RIGHTSHIFT 54
+#define KEY_KPASTERISK 55
+#define KEY_LEFTALT 56
+#define KEY_SPACE 57
+#define KEY_CAPSLOCK 58
+#define KEY_F1 59
+#define KEY_F2 60
+#define KEY_F3 61
+#define KEY_F4 62
+#define KEY_F5 63
+#define KEY_F6 64
+#define KEY_F7 65
+#define KEY_F8 66
+#define KEY_F9 67
+#define KEY_F10 68
+#define KEY_NUMLOCK 69
+#define KEY_SCROLLLOCK 70
+#define KEY_KP7 71
+#define KEY_KP8 72
+#define KEY_KP9 73
+#define KEY_KPMINUS 74
+#define KEY_KP4 75
+#define KEY_KP5 76
+#define KEY_KP6 77
+#define KEY_KPPLUS 78
+#define KEY_KP1 79
+#define KEY_KP2 80
+#define KEY_KP3 81
+#define KEY_KP0 82
+#define KEY_KPDOT 83
+
+#define KEY_ZENKAKUHANKAKU 85
+#define KEY_102ND 86
+#define KEY_F11 87
+#define KEY_F12 88
+#define KEY_RO 89
+#define KEY_KATAKANA 90
+#define KEY_HIRAGANA 91
+#define KEY_HENKAN 92
+#define KEY_KATAKANAHIRAGANA 93
+#define KEY_MUHENKAN 94
+#define KEY_KPJPCOMMA 95
+#define KEY_KPENTER 96
+#define KEY_RIGHTCTRL 97
+#define KEY_KPSLASH 98
+#define KEY_SYSRQ 99
+#define KEY_RIGHTALT 100
+#define KEY_LINEFEED 101
+#define KEY_HOME 102
+#define KEY_UP 103
+#define KEY_PAGEUP 104
+#define KEY_LEFT 105
+#define KEY_RIGHT 106
+#define KEY_END 107
+#define KEY_DOWN 108
+#define KEY_PAGEDOWN 109
+#define KEY_INSERT 110
+#define KEY_DELETE 111
+#define KEY_MACRO 112
+#define KEY_MUTE 113
+#define KEY_VOLUMEDOWN 114
+#define KEY_VOLUMEUP 115
+#define KEY_POWER 116
+#define KEY_KPEQUAL 117
+#define KEY_KPPLUSMINUS 118
+#define KEY_PAUSE 119
+
+#define KEY_KPCOMMA 121
+#define KEY_HANGEUL 122
+#define KEY_HANGUEL KEY_HANGEUL
+#define KEY_HANJA 123
+#define KEY_YEN 124
+#define KEY_LEFTMETA 125
+#define KEY_RIGHTMETA 126
+#define KEY_COMPOSE 127
+
+#define KEY_STOP 128
+#define KEY_AGAIN 129
+#define KEY_PROPS 130
+#define KEY_UNDO 131
+#define KEY_FRONT 132
+#define KEY_COPY 133
+#define KEY_OPEN 134
+#define KEY_PASTE 135
+#define KEY_FIND 136
+#define KEY_CUT 137
+#define KEY_HELP 138
+#define KEY_MENU 139
+#define KEY_CALC 140
+#define KEY_SETUP 141
+#define KEY_SLEEP 142
+#define KEY_WAKEUP 143
+#define KEY_FILE 144
+#define KEY_SENDFILE 145
+#define KEY_DELETEFILE 146
+#define KEY_XFER 147
+#define KEY_PROG1 148
+#define KEY_PROG2 149
+#define KEY_WWW 150
+#define KEY_MSDOS 151
+#define KEY_COFFEE 152
+#define KEY_DIRECTION 153
+#define KEY_CYCLEWINDOWS 154
+#define KEY_MAIL 155
+#define KEY_BOOKMARKS 156
+#define KEY_COMPUTER 157
+#define KEY_BACK 158
+#define KEY_FORWARD 159
+#define KEY_CLOSECD 160
+#define KEY_EJECTCD 161
+#define KEY_EJECTCLOSECD 162
+#define KEY_NEXTSONG 163
+#define KEY_PLAYPAUSE 164
+#define KEY_PREVIOUSSONG 165
+#define KEY_STOPCD 166
+#define KEY_RECORD 167
+#define KEY_REWIND 168
+#define KEY_PHONE 169
+#define KEY_ISO 170
+#define KEY_CONFIG 171
+#define KEY_HOMEPAGE 172
+#define KEY_REFRESH 173
+#define KEY_EXIT 174
+#define KEY_MOVE 175
+#define KEY_EDIT 176
+#define KEY_SCROLLUP 177
+#define KEY_SCROLLDOWN 178
+#define KEY_KPLEFTPAREN 179
+#define KEY_KPRIGHTPAREN 180
+#define KEY_NEW 181
+#define KEY_REDO 182
+
+#define KEY_F13 183
+#define KEY_F14 184
+#define KEY_F15 185
+#define KEY_F16 186
+#define KEY_F17 187
+#define KEY_F18 188
+#define KEY_F19 189
+#define KEY_F20 190
+#define KEY_F21 191
+#define KEY_F22 192
+#define KEY_F23 193
+#define KEY_F24 194
+
+#define KEY_PLAYCD 200
+#define KEY_PAUSECD 201
+#define KEY_PROG3 202
+#define KEY_PROG4 203
+#define KEY_SUSPEND 205
+#define KEY_CLOSE 206
+#define KEY_PLAY 207
+#define KEY_FASTFORWARD 208
+#define KEY_BASSBOOST 209
+#define KEY_PRINT 210
+#define KEY_HP 211
+#define KEY_CAMERA 212
+#define KEY_SOUND 213
+#define KEY_QUESTION 214
+#define KEY_EMAIL 215
+#define KEY_CHAT 216
+#define KEY_SEARCH 217
+#define KEY_CONNECT 218
+#define KEY_FINANCE 219
+#define KEY_SPORT 220
+#define KEY_SHOP 221
+#define KEY_ALTERASE 222
+#define KEY_CANCEL 223
+#define KEY_BRIGHTNESSDOWN 224
+#define KEY_BRIGHTNESSUP 225
+#define KEY_MEDIA 226
+
+#define KEY_STAR 227
+#define KEY_SHARP 228
+#define KEY_SOFT1 229
+#define KEY_SOFT2 230
+#define KEY_SEND 231
+#define KEY_CENTER 232
+#define KEY_HEADSETHOOK 233
+#define KEY_0_5 234
+#define KEY_2_5 235
+
+#define KEY_SWITCHVIDEOMODE 236
+#define KEY_KBDILLUMTOGGLE 237
+#define KEY_KBDILLUMDOWN 238
+#define KEY_KBDILLUMUP 239
+
+#define KEY_SEND 231
+#define KEY_REPLY 232
+#define KEY_FORWARDMAIL 233
+#define KEY_SAVE 234
+#define KEY_DOCUMENTS 235
+
+#define KEY_BATTERY 236
+
+#define KEY_UNKNOWN 240
+
+#define BTN_MISC 0x100
+#define BTN_0 0x100
+#define BTN_1 0x101
+#define BTN_2 0x102
+#define BTN_3 0x103
+#define BTN_4 0x104
+#define BTN_5 0x105
+#define BTN_6 0x106
+#define BTN_7 0x107
+#define BTN_8 0x108
+#define BTN_9 0x109
+
+#define BTN_MOUSE 0x110
+#define BTN_LEFT 0x110
+#define BTN_RIGHT 0x111
+#define BTN_MIDDLE 0x112
+#define BTN_SIDE 0x113
+#define BTN_EXTRA 0x114
+#define BTN_FORWARD 0x115
+#define BTN_BACK 0x116
+#define BTN_TASK 0x117
+
+#define BTN_JOYSTICK 0x120
+#define BTN_TRIGGER 0x120
+#define BTN_THUMB 0x121
+#define BTN_THUMB2 0x122
+#define BTN_TOP 0x123
+#define BTN_TOP2 0x124
+#define BTN_PINKIE 0x125
+#define BTN_BASE 0x126
+#define BTN_BASE2 0x127
+#define BTN_BASE3 0x128
+#define BTN_BASE4 0x129
+#define BTN_BASE5 0x12a
+#define BTN_BASE6 0x12b
+#define BTN_DEAD 0x12f
+
+#define BTN_GAMEPAD 0x130
+#define BTN_A 0x130
+#define BTN_B 0x131
+#define BTN_C 0x132
+#define BTN_X 0x133
+#define BTN_Y 0x134
+#define BTN_Z 0x135
+#define BTN_TL 0x136
+#define BTN_TR 0x137
+#define BTN_TL2 0x138
+#define BTN_TR2 0x139
+#define BTN_SELECT 0x13a
+#define BTN_START 0x13b
+#define BTN_MODE 0x13c
+#define BTN_THUMBL 0x13d
+#define BTN_THUMBR 0x13e
+
+#define BTN_DIGI 0x140
+#define BTN_TOOL_PEN 0x140
+#define BTN_TOOL_RUBBER 0x141
+#define BTN_TOOL_BRUSH 0x142
+#define BTN_TOOL_PENCIL 0x143
+#define BTN_TOOL_AIRBRUSH 0x144
+#define BTN_TOOL_FINGER 0x145
+#define BTN_TOOL_MOUSE 0x146
+#define BTN_TOOL_LENS 0x147
+#define BTN_TOUCH 0x14a
+#define BTN_STYLUS 0x14b
+#define BTN_STYLUS2 0x14c
+#define BTN_TOOL_DOUBLETAP 0x14d
+#define BTN_TOOL_TRIPLETAP 0x14e
+
+#define BTN_WHEEL 0x150
+#define BTN_GEAR_DOWN 0x150
+#define BTN_GEAR_UP 0x151
+
+#define KEY_OK 0x160
+#define KEY_SELECT 0x161
+#define KEY_GOTO 0x162
+#define KEY_CLEAR 0x163
+#define KEY_POWER2 0x164
+#define KEY_OPTION 0x165
+#define KEY_INFO 0x166
+#define KEY_TIME 0x167
+#define KEY_VENDOR 0x168
+#define KEY_ARCHIVE 0x169
+#define KEY_PROGRAM 0x16a
+#define KEY_CHANNEL 0x16b
+#define KEY_FAVORITES 0x16c
+#define KEY_EPG 0x16d
+#define KEY_PVR 0x16e
+#define KEY_MHP 0x16f
+#define KEY_LANGUAGE 0x170
+#define KEY_TITLE 0x171
+#define KEY_SUBTITLE 0x172
+#define KEY_ANGLE 0x173
+#define KEY_ZOOM 0x174
+#define KEY_MODE 0x175
+#define KEY_KEYBOARD 0x176
+#define KEY_SCREEN 0x177
+#define KEY_PC 0x178
+#define KEY_TV 0x179
+#define KEY_TV2 0x17a
+#define KEY_VCR 0x17b
+#define KEY_VCR2 0x17c
+#define KEY_SAT 0x17d
+#define KEY_SAT2 0x17e
+#define KEY_CD 0x17f
+#define KEY_TAPE 0x180
+#define KEY_RADIO 0x181
+#define KEY_TUNER 0x182
+#define KEY_PLAYER 0x183
+#define KEY_TEXT 0x184
+#define KEY_DVD 0x185
+#define KEY_AUX 0x186
+#define KEY_MP3 0x187
+#define KEY_AUDIO 0x188
+#define KEY_VIDEO 0x189
+#define KEY_DIRECTORY 0x18a
+#define KEY_LIST 0x18b
+#define KEY_MEMO 0x18c
+#define KEY_CALENDAR 0x18d
+#define KEY_RED 0x18e
+#define KEY_GREEN 0x18f
+#define KEY_YELLOW 0x190
+#define KEY_BLUE 0x191
+#define KEY_CHANNELUP 0x192
+#define KEY_CHANNELDOWN 0x193
+#define KEY_FIRST 0x194
+#define KEY_LAST 0x195
+#define KEY_AB 0x196
+#define KEY_NEXT 0x197
+#define KEY_RESTART 0x198
+#define KEY_SLOW 0x199
+#define KEY_SHUFFLE 0x19a
+#define KEY_BREAK 0x19b
+#define KEY_PREVIOUS 0x19c
+#define KEY_DIGITS 0x19d
+#define KEY_TEEN 0x19e
+#define KEY_TWEN 0x19f
+
+#define KEY_DEL_EOL 0x1c0
+#define KEY_DEL_EOS 0x1c1
+#define KEY_INS_LINE 0x1c2
+#define KEY_DEL_LINE 0x1c3
+
+#define KEY_FN 0x1d0
+#define KEY_FN_ESC 0x1d1
+#define KEY_FN_F1 0x1d2
+#define KEY_FN_F2 0x1d3
+#define KEY_FN_F3 0x1d4
+#define KEY_FN_F4 0x1d5
+#define KEY_FN_F5 0x1d6
+#define KEY_FN_F6 0x1d7
+#define KEY_FN_F7 0x1d8
+#define KEY_FN_F8 0x1d9
+#define KEY_FN_F9 0x1da
+#define KEY_FN_F10 0x1db
+#define KEY_FN_F11 0x1dc
+#define KEY_FN_F12 0x1dd
+#define KEY_FN_1 0x1de
+#define KEY_FN_2 0x1df
+#define KEY_FN_D 0x1e0
+#define KEY_FN_E 0x1e1
+#define KEY_FN_F 0x1e2
+#define KEY_FN_S 0x1e3
+#define KEY_FN_B 0x1e4
+
+#define KEY_BRL_DOT1 0x1f1
+#define KEY_BRL_DOT2 0x1f2
+#define KEY_BRL_DOT3 0x1f3
+#define KEY_BRL_DOT4 0x1f4
+#define KEY_BRL_DOT5 0x1f5
+#define KEY_BRL_DOT6 0x1f6
+#define KEY_BRL_DOT7 0x1f7
+#define KEY_BRL_DOT8 0x1f8
+
+#define KEY_MIN_INTERESTING KEY_MUTE
+#define KEY_MAX 0x1ff
+
+#define REL_X 0x00
+#define REL_Y 0x01
+#define REL_Z 0x02
+#define REL_RX 0x03
+#define REL_RY 0x04
+#define REL_RZ 0x05
+#define REL_HWHEEL 0x06
+#define REL_DIAL 0x07
+#define REL_WHEEL 0x08
+#define REL_MISC 0x09
+#define REL_MAX 0x0f
+
+#define ABS_X 0x00
+#define ABS_Y 0x01
+#define ABS_Z 0x02
+#define ABS_RX 0x03
+#define ABS_RY 0x04
+#define ABS_RZ 0x05
+#define ABS_THROTTLE 0x06
+#define ABS_RUDDER 0x07
+#define ABS_WHEEL 0x08
+#define ABS_GAS 0x09
+#define ABS_BRAKE 0x0a
+#define ABS_HAT0X 0x10
+#define ABS_HAT0Y 0x11
+#define ABS_HAT1X 0x12
+#define ABS_HAT1Y 0x13
+#define ABS_HAT2X 0x14
+#define ABS_HAT2Y 0x15
+#define ABS_HAT3X 0x16
+#define ABS_HAT3Y 0x17
+#define ABS_PRESSURE 0x18
+#define ABS_DISTANCE 0x19
+#define ABS_TILT_X 0x1a
+#define ABS_TILT_Y 0x1b
+#define ABS_TOOL_WIDTH 0x1c
+#define ABS_VOLUME 0x20
+#define ABS_MISC 0x28
+#define ABS_MAX 0x3f
+
+#define SW_LID 0x00  
+#define SW_TABLET_MODE 0x01  
+#define SW_HEADPHONE_INSERT 0x02  
+#define SW_MAX 0x0f
+
+#define MSC_SERIAL 0x00
+#define MSC_PULSELED 0x01
+#define MSC_GESTURE 0x02
+#define MSC_RAW 0x03
+#define MSC_SCAN 0x04
+#define MSC_MAX 0x07
+
+#define LED_NUML 0x00
+#define LED_CAPSL 0x01
+#define LED_SCROLLL 0x02
+#define LED_COMPOSE 0x03
+#define LED_KANA 0x04
+#define LED_SLEEP 0x05
+#define LED_SUSPEND 0x06
+#define LED_MUTE 0x07
+#define LED_MISC 0x08
+#define LED_MAIL 0x09
+#define LED_CHARGING 0x0a
+#define LED_MAX 0x0f
+
+#define REP_DELAY 0x00
+#define REP_PERIOD 0x01
+#define REP_MAX 0x01
+
+#define SND_CLICK 0x00
+#define SND_BELL 0x01
+#define SND_TONE 0x02
+#define SND_MAX 0x07
+
+#define ID_BUS 0
+#define ID_VENDOR 1
+#define ID_PRODUCT 2
+#define ID_VERSION 3
+
+#define BUS_PCI 0x01
+#define BUS_ISAPNP 0x02
+#define BUS_USB 0x03
+#define BUS_HIL 0x04
+#define BUS_BLUETOOTH 0x05
+
+#define BUS_ISA 0x10
+#define BUS_I8042 0x11
+#define BUS_XTKBD 0x12
+#define BUS_RS232 0x13
+#define BUS_GAMEPORT 0x14
+#define BUS_PARPORT 0x15
+#define BUS_AMIGA 0x16
+#define BUS_ADB 0x17
+#define BUS_I2C 0x18
+#define BUS_HOST 0x19
+#define BUS_GSC 0x1A
+
+#define FF_STATUS_STOPPED 0x00
+#define FF_STATUS_PLAYING 0x01
+#define FF_STATUS_MAX 0x01
+
+struct ff_replay {
+ __u16 length;
+ __u16 delay;
+};
+
+struct ff_trigger {
+ __u16 button;
+ __u16 interval;
+};
+
+struct ff_envelope {
+ __u16 attack_length;
+ __u16 attack_level;
+ __u16 fade_length;
+ __u16 fade_level;
+};
+
+struct ff_constant_effect {
+ __s16 level;
+ struct ff_envelope envelope;
+};
+
+struct ff_ramp_effect {
+ __s16 start_level;
+ __s16 end_level;
+ struct ff_envelope envelope;
+};
+
+struct ff_condition_effect {
+ __u16 right_saturation;
+ __u16 left_saturation;
+
+ __s16 right_coeff;
+ __s16 left_coeff;
+
+ __u16 deadband;
+ __s16 center;
+
+};
+
+struct ff_periodic_effect {
+ __u16 waveform;
+ __u16 period;
+ __s16 magnitude;
+ __s16 offset;
+ __u16 phase;
+
+ struct ff_envelope envelope;
+
+ __u32 custom_len;
+ __s16 *custom_data;
+
+};
+
+struct ff_rumble_effect {
+ __u16 strong_magnitude;
+ __u16 weak_magnitude;
+};
+
+struct ff_effect {
+ __u16 type;
+
+ __s16 id;
+
+ __u16 direction;
+
+ struct ff_trigger trigger;
+ struct ff_replay replay;
+
+ union {
+ struct ff_constant_effect constant;
+ struct ff_ramp_effect ramp;
+ struct ff_periodic_effect periodic;
+ struct ff_condition_effect condition[2];
+ struct ff_rumble_effect rumble;
+ } u;
+};
+
+#define FF_RUMBLE 0x50
+#define FF_PERIODIC 0x51
+#define FF_CONSTANT 0x52
+#define FF_SPRING 0x53
+#define FF_FRICTION 0x54
+#define FF_DAMPER 0x55
+#define FF_INERTIA 0x56
+#define FF_RAMP 0x57
+
+#define FF_SQUARE 0x58
+#define FF_TRIANGLE 0x59
+#define FF_SINE 0x5a
+#define FF_SAW_UP 0x5b
+#define FF_SAW_DOWN 0x5c
+#define FF_CUSTOM 0x5d
+
+#define FF_GAIN 0x60
+#define FF_AUTOCENTER 0x61
+
+#define FF_MAX 0x7f
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/interrupt.h b/ndk/build/platforms/android-1.5/common/include/linux/interrupt.h
new file mode 100644
index 0000000..f48592f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/interrupt.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_INTERRUPT_H
+#define _LINUX_INTERRUPT_H
+
+#include <linux/kernel.h>
+#include <linux/linkage.h>
+#include <linux/bitops.h>
+#include <linux/preempt.h>
+#include <linux/cpumask.h>
+#include <linux/irqreturn.h>
+#include <linux/hardirq.h>
+#include <linux/sched.h>
+#include <linux/irqflags.h>
+#include <asm/atomic.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+
+#define IRQF_TRIGGER_NONE 0x00000000
+#define IRQF_TRIGGER_RISING 0x00000001
+#define IRQF_TRIGGER_FALLING 0x00000002
+#define IRQF_TRIGGER_HIGH 0x00000004
+#define IRQF_TRIGGER_LOW 0x00000008
+#define IRQF_TRIGGER_MASK (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW |   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)
+#define IRQF_TRIGGER_PROBE 0x00000010
+
+#define IRQF_DISABLED 0x00000020
+#define IRQF_SAMPLE_RANDOM 0x00000040
+#define IRQF_SHARED 0x00000080
+#define IRQF_PROBE_SHARED 0x00000100
+#define IRQF_TIMER 0x00000200
+#define IRQF_PERCPU 0x00000400
+
+#define SA_INTERRUPT IRQF_DISABLED
+#define SA_SAMPLE_RANDOM IRQF_SAMPLE_RANDOM
+#define SA_SHIRQ IRQF_SHARED
+#define SA_PROBEIRQ IRQF_PROBE_SHARED
+#define SA_PERCPU IRQF_PERCPU
+
+#define SA_TRIGGER_LOW IRQF_TRIGGER_LOW
+#define SA_TRIGGER_HIGH IRQF_TRIGGER_HIGH
+#define SA_TRIGGER_FALLING IRQF_TRIGGER_FALLING
+#define SA_TRIGGER_RISING IRQF_TRIGGER_RISING
+#define SA_TRIGGER_MASK IRQF_TRIGGER_MASK
+
+struct irqaction {
+ irqreturn_t (*handler)(int, void *, struct pt_regs *);
+ unsigned long flags;
+ cpumask_t mask;
+ const char *name;
+ void *dev_id;
+ struct irqaction *next;
+ int irq;
+ struct proc_dir_entry *dir;
+};
+
+#define local_irq_enable_in_hardirq() local_irq_enable()
+
+#define disable_irq_nosync_lockdep(irq) disable_irq_nosync(irq)
+#define disable_irq_lockdep(irq) disable_irq(irq)
+#define enable_irq_lockdep(irq) enable_irq(irq)
+
+#ifndef __ARCH_SET_SOFTIRQ_PENDING
+#define set_softirq_pending(x) (local_softirq_pending() = (x))
+#define or_softirq_pending(x) (local_softirq_pending() |= (x))
+#endif
+
+#define save_flags(x) save_flags(&x)
+#define save_and_cli(x) save_and_cli(&x)
+
+enum
+{
+ HI_SOFTIRQ=0,
+ TIMER_SOFTIRQ,
+ NET_TX_SOFTIRQ,
+ NET_RX_SOFTIRQ,
+ BLOCK_SOFTIRQ,
+ TASKLET_SOFTIRQ
+};
+
+struct softirq_action
+{
+ void (*action)(struct softirq_action *);
+ void *data;
+};
+
+#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0)
+
+struct tasklet_struct
+{
+ struct tasklet_struct *next;
+ unsigned long state;
+ atomic_t count;
+ void (*func)(unsigned long);
+ unsigned long data;
+};
+
+#define DECLARE_TASKLET(name, func, data)  struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(0), func, data }
+
+#define DECLARE_TASKLET_DISABLED(name, func, data)  struct tasklet_struct name = { NULL, 0, ATOMIC_INIT(1), func, data }
+
+enum
+{
+ TASKLET_STATE_SCHED,
+ TASKLET_STATE_RUN
+};
+
+#define tasklet_trylock(t) 1
+#define tasklet_unlock_wait(t) do { } while (0)
+#define tasklet_unlock(t) do { } while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ioctl.h b/ndk/build/platforms/android-1.5/common/include/linux/ioctl.h
new file mode 100644
index 0000000..9efbeab
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ioctl.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IOCTL_H
+#define _LINUX_IOCTL_H
+
+#include <asm/ioctl.h>
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ioport.h b/ndk/build/platforms/android-1.5/common/include/linux/ioport.h
new file mode 100644
index 0000000..b2081fc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ioport.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IOPORT_H
+#define _LINUX_IOPORT_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+struct resource {
+ resource_size_t start;
+ resource_size_t end;
+ const char *name;
+ unsigned long flags;
+ struct resource *parent, *sibling, *child;
+};
+
+struct resource_list {
+ struct resource_list *next;
+ struct resource *res;
+ struct pci_dev *dev;
+};
+
+#define IORESOURCE_BITS 0x000000ff  
+
+#define IORESOURCE_IO 0x00000100  
+#define IORESOURCE_MEM 0x00000200
+#define IORESOURCE_IRQ 0x00000400
+#define IORESOURCE_DMA 0x00000800
+
+#define IORESOURCE_PREFETCH 0x00001000  
+#define IORESOURCE_READONLY 0x00002000
+#define IORESOURCE_CACHEABLE 0x00004000
+#define IORESOURCE_RANGELENGTH 0x00008000
+#define IORESOURCE_SHADOWABLE 0x00010000
+#define IORESOURCE_BUS_HAS_VGA 0x00080000
+
+#define IORESOURCE_DISABLED 0x10000000
+#define IORESOURCE_UNSET 0x20000000
+#define IORESOURCE_AUTO 0x40000000
+#define IORESOURCE_BUSY 0x80000000  
+
+#define IORESOURCE_IRQ_HIGHEDGE (1<<0)
+#define IORESOURCE_IRQ_LOWEDGE (1<<1)
+#define IORESOURCE_IRQ_HIGHLEVEL (1<<2)
+#define IORESOURCE_IRQ_LOWLEVEL (1<<3)
+#define IORESOURCE_IRQ_SHAREABLE (1<<4)
+
+#define IORESOURCE_DMA_TYPE_MASK (3<<0)
+#define IORESOURCE_DMA_8BIT (0<<0)
+#define IORESOURCE_DMA_8AND16BIT (1<<0)
+#define IORESOURCE_DMA_16BIT (2<<0)
+
+#define IORESOURCE_DMA_MASTER (1<<2)
+#define IORESOURCE_DMA_BYTE (1<<3)
+#define IORESOURCE_DMA_WORD (1<<4)
+
+#define IORESOURCE_DMA_SPEED_MASK (3<<6)
+#define IORESOURCE_DMA_COMPATIBLE (0<<6)
+#define IORESOURCE_DMA_TYPEA (1<<6)
+#define IORESOURCE_DMA_TYPEB (2<<6)
+#define IORESOURCE_DMA_TYPEF (3<<6)
+
+#define IORESOURCE_MEM_WRITEABLE (1<<0)  
+#define IORESOURCE_MEM_CACHEABLE (1<<1)  
+#define IORESOURCE_MEM_RANGELENGTH (1<<2)  
+#define IORESOURCE_MEM_TYPE_MASK (3<<3)
+#define IORESOURCE_MEM_8BIT (0<<3)
+#define IORESOURCE_MEM_16BIT (1<<3)
+#define IORESOURCE_MEM_8AND16BIT (2<<3)
+#define IORESOURCE_MEM_32BIT (3<<3)
+#define IORESOURCE_MEM_SHADOWABLE (1<<5)  
+#define IORESOURCE_MEM_EXPANSIONROM (1<<6)
+
+#define IORESOURCE_ROM_ENABLE (1<<0)  
+#define IORESOURCE_ROM_SHADOW (1<<1)  
+#define IORESOURCE_ROM_COPY (1<<2)  
+
+#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name))
+#define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name))
+#define rename_region(region, newname) do { (region)->name = (newname); } while (0)
+
+#define release_region(start,n) __release_region(&ioport_resource, (start), (n))
+#define check_mem_region(start,n) __check_region(&iomem_resource, (start), (n))
+#define release_mem_region(start,n) __release_region(&iomem_resource, (start), (n))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ioprio.h b/ndk/build/platforms/android-1.5/common/include/linux/ioprio.h
new file mode 100644
index 0000000..a0a5d48
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ioprio.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef IOPRIO_H
+#define IOPRIO_H
+
+#include <linux/sched.h>
+
+#define IOPRIO_BITS (16)
+#define IOPRIO_CLASS_SHIFT (13)
+#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
+
+#define IOPRIO_PRIO_CLASS(mask) ((mask) >> IOPRIO_CLASS_SHIFT)
+#define IOPRIO_PRIO_DATA(mask) ((mask) & IOPRIO_PRIO_MASK)
+#define IOPRIO_PRIO_VALUE(class, data) (((class) << IOPRIO_CLASS_SHIFT) | data)
+
+#define ioprio_valid(mask) (IOPRIO_PRIO_CLASS((mask)) != IOPRIO_CLASS_NONE)
+
+enum {
+ IOPRIO_CLASS_NONE,
+ IOPRIO_CLASS_RT,
+ IOPRIO_CLASS_BE,
+ IOPRIO_CLASS_IDLE,
+};
+
+#define IOPRIO_BE_NR (8)
+
+enum {
+ IOPRIO_WHO_PROCESS = 1,
+ IOPRIO_WHO_PGRP,
+ IOPRIO_WHO_USER,
+};
+
+#define IOPRIO_NORM (4)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ip.h b/ndk/build/platforms/android-1.5/common/include/linux/ip.h
new file mode 100644
index 0000000..040789d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ip.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IP_H
+#define _LINUX_IP_H
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+#define IPTOS_TOS_MASK 0x1E
+#define IPTOS_TOS(tos) ((tos)&IPTOS_TOS_MASK)
+#define IPTOS_LOWDELAY 0x10
+#define IPTOS_THROUGHPUT 0x08
+#define IPTOS_RELIABILITY 0x04
+#define IPTOS_MINCOST 0x02
+
+#define IPTOS_PREC_MASK 0xE0
+#define IPTOS_PREC(tos) ((tos)&IPTOS_PREC_MASK)
+#define IPTOS_PREC_NETCONTROL 0xe0
+#define IPTOS_PREC_INTERNETCONTROL 0xc0
+#define IPTOS_PREC_CRITIC_ECP 0xa0
+#define IPTOS_PREC_FLASHOVERRIDE 0x80
+#define IPTOS_PREC_FLASH 0x60
+#define IPTOS_PREC_IMMEDIATE 0x40
+#define IPTOS_PREC_PRIORITY 0x20
+#define IPTOS_PREC_ROUTINE 0x00
+
+#define IPOPT_COPY 0x80
+#define IPOPT_CLASS_MASK 0x60
+#define IPOPT_NUMBER_MASK 0x1f
+
+#define IPOPT_COPIED(o) ((o)&IPOPT_COPY)
+#define IPOPT_CLASS(o) ((o)&IPOPT_CLASS_MASK)
+#define IPOPT_NUMBER(o) ((o)&IPOPT_NUMBER_MASK)
+
+#define IPOPT_CONTROL 0x00
+#define IPOPT_RESERVED1 0x20
+#define IPOPT_MEASUREMENT 0x40
+#define IPOPT_RESERVED2 0x60
+
+#define IPOPT_END (0 |IPOPT_CONTROL)
+#define IPOPT_NOOP (1 |IPOPT_CONTROL)
+#define IPOPT_SEC (2 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_LSRR (3 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_TIMESTAMP (4 |IPOPT_MEASUREMENT)
+#define IPOPT_RR (7 |IPOPT_CONTROL)
+#define IPOPT_SID (8 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_SSRR (9 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_RA (20|IPOPT_CONTROL|IPOPT_COPY)
+
+#define IPVERSION 4
+#define MAXTTL 255
+#define IPDEFTTL 64
+
+#define IPOPT_OPTVAL 0
+#define IPOPT_OLEN 1
+#define IPOPT_OFFSET 2
+#define IPOPT_MINOFF 4
+#define MAX_IPOPTLEN 40
+#define IPOPT_NOP IPOPT_NOOP
+#define IPOPT_EOL IPOPT_END
+#define IPOPT_TS IPOPT_TIMESTAMP
+
+#define IPOPT_TS_TSONLY 0  
+#define IPOPT_TS_TSANDADDR 1  
+#define IPOPT_TS_PRESPEC 3  
+
+struct iphdr {
+#ifdef __LITTLE_ENDIAN_BITFIELD
+ __u8 ihl:4,
+ version:4;
+#elif defined (__BIG_ENDIAN_BITFIELD)
+ __u8 version:4,
+ ihl:4;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ __u8 tos;
+ __be16 tot_len;
+ __be16 id;
+ __be16 frag_off;
+ __u8 ttl;
+ __u8 protocol;
+ __u16 check;
+ __be32 saddr;
+ __be32 daddr;
+
+};
+
+struct ip_auth_hdr {
+ __u8 nexthdr;
+ __u8 hdrlen;
+ __u16 reserved;
+ __u32 spi;
+ __u32 seq_no;
+ __u8 auth_data[0];
+};
+
+struct ip_esp_hdr {
+ __u32 spi;
+ __u32 seq_no;
+ __u8 enc_data[0];
+};
+
+struct ip_comp_hdr {
+ __u8 nexthdr;
+ __u8 flags;
+ __u16 cpi;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ipc.h b/ndk/build/platforms/android-1.5/common/include/linux/ipc.h
new file mode 100644
index 0000000..54766d5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ipc.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IPC_H
+#define _LINUX_IPC_H
+
+#include <linux/types.h>
+
+#define IPC_PRIVATE ((__kernel_key_t) 0) 
+
+struct ipc_perm
+{
+ __kernel_key_t key;
+ __kernel_uid_t uid;
+ __kernel_gid_t gid;
+ __kernel_uid_t cuid;
+ __kernel_gid_t cgid;
+ __kernel_mode_t mode;
+ unsigned short seq;
+};
+
+#include <asm/ipcbuf.h>
+
+#define IPC_CREAT 00001000  
+#define IPC_EXCL 00002000  
+#define IPC_NOWAIT 00004000  
+
+#define IPC_DIPC 00010000  
+#define IPC_OWN 00020000  
+
+#define IPC_RMID 0  
+#define IPC_SET 1  
+#define IPC_STAT 2  
+#define IPC_INFO 3  
+
+#define IPC_OLD 0  
+#define IPC_64 0x0100  
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ipmi_msgdefs.h b/ndk/build/platforms/android-1.5/common/include/linux/ipmi_msgdefs.h
new file mode 100644
index 0000000..247d563
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ipmi_msgdefs.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_IPMI_MSGDEFS_H
+#define __LINUX_IPMI_MSGDEFS_H
+
+#define IPMI_NETFN_SENSOR_EVENT_REQUEST 0x04
+#define IPMI_NETFN_SENSOR_EVENT_RESPONSE 0x05
+#define IPMI_GET_EVENT_RECEIVER_CMD 0x01
+
+#define IPMI_NETFN_APP_REQUEST 0x06
+#define IPMI_NETFN_APP_RESPONSE 0x07
+#define IPMI_GET_DEVICE_ID_CMD 0x01
+#define IPMI_CLEAR_MSG_FLAGS_CMD 0x30
+#define IPMI_GET_DEVICE_GUID_CMD 0x08
+#define IPMI_GET_MSG_FLAGS_CMD 0x31
+#define IPMI_SEND_MSG_CMD 0x34
+#define IPMI_GET_MSG_CMD 0x33
+#define IPMI_SET_BMC_GLOBAL_ENABLES_CMD 0x2e
+#define IPMI_GET_BMC_GLOBAL_ENABLES_CMD 0x2f
+#define IPMI_READ_EVENT_MSG_BUFFER_CMD 0x35
+#define IPMI_GET_CHANNEL_INFO_CMD 0x42
+
+#define IPMI_NETFN_STORAGE_REQUEST 0x0a
+#define IPMI_NETFN_STORAGE_RESPONSE 0x0b
+#define IPMI_ADD_SEL_ENTRY_CMD 0x44
+
+#define IPMI_BMC_SLAVE_ADDR 0x20
+
+#define IPMI_MAX_MSG_LENGTH 272  
+
+#define IPMI_CC_NO_ERROR 0x00
+#define IPMI_NODE_BUSY_ERR 0xc0
+#define IPMI_INVALID_COMMAND_ERR 0xc1
+#define IPMI_ERR_MSG_TRUNCATED 0xc6
+#define IPMI_LOST_ARBITRATION_ERR 0x81
+#define IPMI_ERR_UNSPECIFIED 0xff
+
+#define IPMI_CHANNEL_PROTOCOL_IPMB 1
+#define IPMI_CHANNEL_PROTOCOL_ICMB 2
+#define IPMI_CHANNEL_PROTOCOL_SMBUS 4
+#define IPMI_CHANNEL_PROTOCOL_KCS 5
+#define IPMI_CHANNEL_PROTOCOL_SMIC 6
+#define IPMI_CHANNEL_PROTOCOL_BT10 7
+#define IPMI_CHANNEL_PROTOCOL_BT15 8
+#define IPMI_CHANNEL_PROTOCOL_TMODE 9
+
+#define IPMI_CHANNEL_MEDIUM_IPMB 1
+#define IPMI_CHANNEL_MEDIUM_ICMB10 2
+#define IPMI_CHANNEL_MEDIUM_ICMB09 3
+#define IPMI_CHANNEL_MEDIUM_8023LAN 4
+#define IPMI_CHANNEL_MEDIUM_ASYNC 5
+#define IPMI_CHANNEL_MEDIUM_OTHER_LAN 6
+#define IPMI_CHANNEL_MEDIUM_PCI_SMBUS 7
+#define IPMI_CHANNEL_MEDIUM_SMBUS1 8
+#define IPMI_CHANNEL_MEDIUM_SMBUS2 9
+#define IPMI_CHANNEL_MEDIUM_USB1 10
+#define IPMI_CHANNEL_MEDIUM_USB2 11
+#define IPMI_CHANNEL_MEDIUM_SYSINTF 12
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ipmi_smi.h b/ndk/build/platforms/android-1.5/common/include/linux/ipmi_smi.h
new file mode 100644
index 0000000..56cc210
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ipmi_smi.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_IPMI_SMI_H
+#define __LINUX_IPMI_SMI_H
+
+#include <linux/ipmi_msgdefs.h>
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/ipmi_smi.h>
+
+typedef struct ipmi_smi *ipmi_smi_t;
+
+struct ipmi_smi_msg
+{
+ struct list_head link;
+
+ long msgid;
+ void *user_data;
+
+ int data_size;
+ unsigned char data[IPMI_MAX_MSG_LENGTH];
+
+ int rsp_size;
+ unsigned char rsp[IPMI_MAX_MSG_LENGTH];
+
+ void (*done)(struct ipmi_smi_msg *msg);
+};
+
+struct ipmi_smi_handlers
+{
+ struct module *owner;
+
+ int (*start_processing)(void *send_info,
+ ipmi_smi_t new_intf);
+
+ void (*sender)(void *send_info,
+ struct ipmi_smi_msg *msg,
+ int priority);
+
+ void (*request_events)(void *send_info);
+
+ void (*set_run_to_completion)(void *send_info, int run_to_completion);
+
+ void (*poll)(void *send_info);
+
+ int (*inc_usecount)(void *send_info);
+ void (*dec_usecount)(void *send_info);
+};
+
+struct ipmi_device_id {
+ unsigned char device_id;
+ unsigned char device_revision;
+ unsigned char firmware_revision_1;
+ unsigned char firmware_revision_2;
+ unsigned char ipmi_version;
+ unsigned char additional_device_support;
+ unsigned int manufacturer_id;
+ unsigned int product_id;
+ unsigned char aux_firmware_revision[4];
+ unsigned int aux_firmware_revision_set : 1;
+};
+
+#define ipmi_version_major(v) ((v)->ipmi_version & 0xf)
+#define ipmi_version_minor(v) ((v)->ipmi_version >> 4)
+
+struct ipmi_smi_msg *ipmi_alloc_smi_msg(void);
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ipx.h b/ndk/build/platforms/android-1.5/common/include/linux/ipx.h
new file mode 100644
index 0000000..ff675e9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ipx.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPX_H_
+#define _IPX_H_
+#include <linux/sockios.h>
+#include <linux/socket.h>
+#define IPX_NODE_LEN 6
+#define IPX_MTU 576
+
+struct sockaddr_ipx {
+ sa_family_t sipx_family;
+ __u16 sipx_port;
+ __u32 sipx_network;
+ unsigned char sipx_node[IPX_NODE_LEN];
+ __u8 sipx_type;
+ unsigned char sipx_zero;
+};
+
+#define sipx_special sipx_port
+#define sipx_action sipx_zero
+#define IPX_DLTITF 0
+#define IPX_CRTITF 1
+
+struct ipx_route_definition {
+ __u32 ipx_network;
+ __u32 ipx_router_network;
+ unsigned char ipx_router_node[IPX_NODE_LEN];
+};
+
+struct ipx_interface_definition {
+ __u32 ipx_network;
+ unsigned char ipx_device[16];
+ unsigned char ipx_dlink_type;
+#define IPX_FRAME_NONE 0
+#define IPX_FRAME_SNAP 1
+#define IPX_FRAME_8022 2
+#define IPX_FRAME_ETHERII 3
+#define IPX_FRAME_8023 4
+#define IPX_FRAME_TR_8022 5  
+ unsigned char ipx_special;
+#define IPX_SPECIAL_NONE 0
+#define IPX_PRIMARY 1
+#define IPX_INTERNAL 2
+ unsigned char ipx_node[IPX_NODE_LEN];
+};
+
+struct ipx_config_data {
+ unsigned char ipxcfg_auto_select_primary;
+ unsigned char ipxcfg_auto_create_interfaces;
+};
+
+struct ipx_route_def {
+ __u32 ipx_network;
+ __u32 ipx_router_network;
+#define IPX_ROUTE_NO_ROUTER 0
+ unsigned char ipx_router_node[IPX_NODE_LEN];
+ unsigned char ipx_device[16];
+ unsigned short ipx_flags;
+#define IPX_RT_SNAP 8
+#define IPX_RT_8022 4
+#define IPX_RT_BLUEBOOK 2
+#define IPX_RT_ROUTED 1
+};
+
+#define SIOCAIPXITFCRT (SIOCPROTOPRIVATE)
+#define SIOCAIPXPRISLT (SIOCPROTOPRIVATE + 1)
+#define SIOCIPXCFGDATA (SIOCPROTOPRIVATE + 2)
+#define SIOCIPXNCPCONN (SIOCPROTOPRIVATE + 3)
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/irq.h b/ndk/build/platforms/android-1.5/common/include/linux/irq.h
new file mode 100644
index 0000000..38f5db7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/irq.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IRQ_H
+#define _LINUX_IRQ_H
+
+#include <linux/smp.h>
+
+#include <linux/linkage.h>
+#include <linux/cache.h>
+#include <linux/spinlock.h>
+#include <linux/cpumask.h>
+#include <linux/irqreturn.h>
+
+#include <asm/irq.h>
+#include <asm/ptrace.h>
+
+#define IRQ_TYPE_NONE 0x00000000  
+#define IRQ_TYPE_EDGE_RISING 0x00000001  
+#define IRQ_TYPE_EDGE_FALLING 0x00000002  
+#define IRQ_TYPE_EDGE_BOTH (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)
+#define IRQ_TYPE_LEVEL_HIGH 0x00000004  
+#define IRQ_TYPE_LEVEL_LOW 0x00000008  
+#define IRQ_TYPE_SENSE_MASK 0x0000000f  
+#define IRQ_TYPE_PROBE 0x00000010  
+
+#define IRQ_INPROGRESS 0x00010000  
+#define IRQ_DISABLED 0x00020000  
+#define IRQ_PENDING 0x00040000  
+#define IRQ_REPLAY 0x00080000  
+#define IRQ_AUTODETECT 0x00100000  
+#define IRQ_WAITING 0x00200000  
+#define IRQ_LEVEL 0x00400000  
+#define IRQ_MASKED 0x00800000  
+#define IRQ_PER_CPU 0x01000000  
+#define CHECK_IRQ_PER_CPU(var) 0
+
+#define IRQ_NOPROBE 0x02000000  
+#define IRQ_NOREQUEST 0x04000000  
+#define IRQ_NOAUTOEN 0x08000000  
+#define IRQ_DELAYED_DISABLE 0x10000000  
+#define IRQ_WAKEUP 0x20000000  
+
+struct proc_dir_entry;
+
+struct irq_chip {
+ const char *name;
+ unsigned int (*startup)(unsigned int irq);
+ void (*shutdown)(unsigned int irq);
+ void (*enable)(unsigned int irq);
+ void (*disable)(unsigned int irq);
+
+ void (*ack)(unsigned int irq);
+ void (*mask)(unsigned int irq);
+ void (*mask_ack)(unsigned int irq);
+ void (*unmask)(unsigned int irq);
+ void (*eoi)(unsigned int irq);
+
+ void (*end)(unsigned int irq);
+ void (*set_affinity)(unsigned int irq, cpumask_t dest);
+ int (*retrigger)(unsigned int irq);
+ int (*set_type)(unsigned int irq, unsigned int flow_type);
+ int (*set_wake)(unsigned int irq, unsigned int on);
+
+ const char *typename;
+};
+
+struct irq_desc {
+ void fastcall (*handle_irq)(unsigned int irq,
+ struct irq_desc *desc,
+ struct pt_regs *regs);
+ struct irq_chip *chip;
+ void *handler_data;
+ void *chip_data;
+ struct irqaction *action;
+ unsigned int status;
+
+ unsigned int depth;
+ unsigned int wake_depth;
+ unsigned int irq_count;
+ unsigned int irqs_unhandled;
+ spinlock_t lock;
+} ____cacheline_aligned;
+
+#define hw_interrupt_type irq_chip
+typedef struct irq_chip hw_irq_controller;
+#define no_irq_type no_irq_chip
+typedef struct irq_desc irq_desc_t;
+
+#include <asm/hw_irq.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/irq_cpustat.h b/ndk/build/platforms/android-1.5/common/include/linux/irq_cpustat.h
new file mode 100644
index 0000000..3540a4a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/irq_cpustat.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __irq_cpustat_h
+#define __irq_cpustat_h
+
+#ifndef __ARCH_IRQ_STAT
+
+#define __IRQ_STAT(cpu, member) (irq_stat[cpu].member)
+#endif
+
+#define local_softirq_pending()   __IRQ_STAT(smp_processor_id(), __softirq_pending)
+
+#define nmi_count(cpu) __IRQ_STAT((cpu), __nmi_count)  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/irqflags.h b/ndk/build/platforms/android-1.5/common/include/linux/irqflags.h
new file mode 100644
index 0000000..1bf3f90
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/irqflags.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TRACE_IRQFLAGS_H
+#define _LINUX_TRACE_IRQFLAGS_H
+
+#define trace_hardirqs_on() do { } while (0)
+#define trace_hardirqs_off() do { } while (0)
+#define trace_softirqs_on(ip) do { } while (0)
+#define trace_softirqs_off(ip) do { } while (0)
+#define trace_hardirq_context(p) 0
+#define trace_softirq_context(p) 0
+#define trace_hardirqs_enabled(p) 0
+#define trace_softirqs_enabled(p) 0
+#define trace_hardirq_enter() do { } while (0)
+#define trace_hardirq_exit() do { } while (0)
+#define trace_softirq_enter() do { } while (0)
+#define trace_softirq_exit() do { } while (0)
+#define INIT_TRACE_IRQFLAGS
+
+#define raw_local_irq_disable() local_irq_disable()
+#define raw_local_irq_enable() local_irq_enable()
+#define raw_local_irq_save(flags) local_irq_save(flags)
+#define raw_local_irq_restore(flags) local_irq_restore(flags)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/irqreturn.h b/ndk/build/platforms/android-1.5/common/include/linux/irqreturn.h
new file mode 100644
index 0000000..e37f430
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/irqreturn.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_IRQRETURN_H
+#define _LINUX_IRQRETURN_H
+
+typedef int irqreturn_t;
+
+#define IRQ_NONE (0)
+#define IRQ_HANDLED (1)
+#define IRQ_RETVAL(x) ((x) != 0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/jbd.h b/ndk/build/platforms/android-1.5/common/include/linux/jbd.h
new file mode 100644
index 0000000..7ba766c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/jbd.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_JBD_H
+#define _LINUX_JBD_H
+
+#include "jfs_compat.h"
+#define JFS_DEBUG
+#define jfs_debug jbd_debug
+
+#define journal_oom_retry 1
+
+#undef JBD_PARANOID_IOFAIL
+
+#define JBD_DEFAULT_MAX_COMMIT_AGE 5
+
+#define jbd_debug(f, a...)  
+
+#define jbd_kmalloc(size, flags)   __jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry)
+#define jbd_rep_kmalloc(size, flags)   __jbd_kmalloc(__FUNCTION__, (size), (flags), 1)
+
+#define JFS_MIN_JOURNAL_BLOCKS 1024
+
+#define JFS_MAGIC_NUMBER 0xc03b3998U  
+
+#define JFS_DESCRIPTOR_BLOCK 1
+#define JFS_COMMIT_BLOCK 2
+#define JFS_SUPERBLOCK_V1 3
+#define JFS_SUPERBLOCK_V2 4
+#define JFS_REVOKE_BLOCK 5
+
+typedef struct journal_header_s
+{
+ __be32 h_magic;
+ __be32 h_blocktype;
+ __be32 h_sequence;
+} journal_header_t;
+
+typedef struct journal_block_tag_s
+{
+ __be32 t_blocknr;
+ __be32 t_flags;
+} journal_block_tag_t;
+
+typedef struct journal_revoke_header_s
+{
+ journal_header_t r_header;
+ __be32 r_count;
+} journal_revoke_header_t;
+
+#define JFS_FLAG_ESCAPE 1  
+#define JFS_FLAG_SAME_UUID 2  
+#define JFS_FLAG_DELETED 4  
+#define JFS_FLAG_LAST_TAG 8  
+
+typedef struct journal_superblock_s
+{
+
+ journal_header_t s_header;
+
+ __be32 s_blocksize;
+ __be32 s_maxlen;
+ __be32 s_first;
+
+ __be32 s_sequence;
+ __be32 s_start;
+
+ __be32 s_errno;
+
+ __be32 s_feature_compat;
+ __be32 s_feature_incompat;
+ __be32 s_feature_ro_compat;
+
+ __u8 s_uuid[16];
+
+ __be32 s_nr_users;
+
+ __be32 s_dynsuper;
+
+ __be32 s_max_transaction;
+ __be32 s_max_trans_data;
+
+ __u32 s_padding[44];
+
+ __u8 s_users[16*48];
+
+} journal_superblock_t;
+
+#define JFS_HAS_COMPAT_FEATURE(j,mask)   ((j)->j_format_version >= 2 &&   ((j)->j_superblock->s_feature_compat & cpu_to_be32((mask))))
+#define JFS_HAS_RO_COMPAT_FEATURE(j,mask)   ((j)->j_format_version >= 2 &&   ((j)->j_superblock->s_feature_ro_compat & cpu_to_be32((mask))))
+#define JFS_HAS_INCOMPAT_FEATURE(j,mask)   ((j)->j_format_version >= 2 &&   ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask))))
+
+#define JFS_FEATURE_INCOMPAT_REVOKE 0x00000001
+
+#define JFS_KNOWN_COMPAT_FEATURES 0
+#define JFS_KNOWN_ROCOMPAT_FEATURES 0
+#define JFS_KNOWN_INCOMPAT_FEATURES JFS_FEATURE_INCOMPAT_REVOKE
+
+#define BJ_None 0  
+#define BJ_SyncData 1  
+#define BJ_Metadata 2  
+#define BJ_Forget 3  
+#define BJ_IO 4  
+#define BJ_Shadow 5  
+#define BJ_LogCtl 6  
+#define BJ_Reserved 7  
+#define BJ_Locked 8  
+#define BJ_Types 9
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/jiffies.h b/ndk/build/platforms/android-1.5/common/include/linux/jiffies.h
new file mode 100644
index 0000000..86b705b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/jiffies.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_JIFFIES_H
+#define _LINUX_JIFFIES_H
+
+#include <linux/calc64.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <asm/param.h>  
+
+#if HZ >= (12 && HZ < 24)
+#define SHIFT_HZ 4
+#elif HZ >= 24 && HZ < 48
+#define SHIFT_HZ 5
+#elif HZ >= 48 && HZ < 96
+#define SHIFT_HZ 6
+#elif HZ >= 96 && HZ < 192
+#define SHIFT_HZ 7
+#elif HZ >= 192 && HZ < 384
+#define SHIFT_HZ 8
+#elif HZ >= 384 && HZ < 768
+#define SHIFT_HZ 9
+#elif HZ >= 768 && HZ < 1536
+#define SHIFT_HZ 10
+#else
+#error You lose.
+#endif
+
+#define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ)  
+
+#define LATCH_HPET ((HPET_TICK_RATE + HZ/2) / HZ)
+
+#define SH_DIV(NOM,DEN,LSH) ( (((NOM) / (DEN)) << (LSH))   + ((((NOM) % (DEN)) << (LSH)) + (DEN) / 2) / (DEN))
+
+#define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH, 8))
+
+#define ACTHZ_HPET (SH_DIV (HPET_TICK_RATE, LATCH_HPET, 8))
+
+#define TICK_NSEC (SH_DIV (1000000UL * 1000, ACTHZ, 8))
+
+#define TICK_NSEC_HPET (SH_DIV(1000000UL * 1000, ACTHZ_HPET, 8))
+
+#define TICK_USEC ((1000000UL + USER_HZ/2) / USER_HZ)
+
+#define TICK_USEC_TO_NSEC(TUSEC) (SH_DIV (TUSEC * USER_HZ * 1000, ACTHZ, 8))
+
+#define __jiffy_data __attribute__((section(".data")))
+
+#if BITS_PER_LONG < 64
+
+#else
+#endif
+#define time_after(a,b)   (typecheck(unsigned long, a) &&   typecheck(unsigned long, b) &&   ((long)(b) - (long)(a) < 0))
+#define time_before(a,b) time_after(b,a)
+#define time_after_eq(a,b)   (typecheck(unsigned long, a) &&   typecheck(unsigned long, b) &&   ((long)(a) - (long)(b) >= 0))
+#define time_before_eq(a,b) time_after_eq(b,a)
+#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
+#define MAX_JIFFY_OFFSET ((~0UL >> 1)-1)
+#define SEC_JIFFIE_SC (31 - SHIFT_HZ)
+#if !((NSEC_PER_SEC << 2) / TICK_NSEC << SEC_JIFFIE_SC - 2 & 0x80000000)
+#undef SEC_JIFFIE_SC
+#define SEC_JIFFIE_SC (32 - SHIFT_HZ)
+#endif
+#define NSEC_JIFFIE_SC (SEC_JIFFIE_SC + 29)
+#define USEC_JIFFIE_SC (SEC_JIFFIE_SC + 19)
+#define SEC_CONVERSION ((unsigned long)((((u64)NSEC_PER_SEC << SEC_JIFFIE_SC) +  TICK_NSEC -1) / (u64)TICK_NSEC))
+#define NSEC_CONVERSION ((unsigned long)((((u64)1 << NSEC_JIFFIE_SC) +  TICK_NSEC -1) / (u64)TICK_NSEC))
+#define USEC_CONVERSION   ((unsigned long)((((u64)NSEC_PER_USEC << USEC_JIFFIE_SC) +  TICK_NSEC -1) / (u64)TICK_NSEC))
+#define USEC_ROUND (u64)(((u64)1 << USEC_JIFFIE_SC) - 1)
+#if BITS_PER_LONG < 64
+#define MAX_SEC_IN_JIFFIES   (long)((u64)((u64)MAX_JIFFY_OFFSET * TICK_NSEC) / NSEC_PER_SEC)
+#else
+#define MAX_SEC_IN_JIFFIES   (SH_DIV((MAX_JIFFY_OFFSET >> SEC_JIFFIE_SC) * TICK_NSEC, NSEC_PER_SEC, 1) - 1)
+#endif
+#if HZ <= (MSEC_PER_SEC && !(MSEC_PER_SEC % HZ))
+#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
+#else
+#endif
+#if HZ <= (USEC_PER_SEC && !(USEC_PER_SEC % HZ))
+#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
+#else
+#endif
+#if HZ <= (MSEC_PER_SEC && !(MSEC_PER_SEC % HZ))
+#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC)
+#else
+#endif
+#if HZ <= (USEC_PER_SEC && !(USEC_PER_SEC % HZ))
+#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC)
+#else
+#endif
+#if TICK_NSEC % NSEC_PER_SEC / USER_HZ == 0
+#else
+#endif
+#if HZ % USER_HZ == 0
+#else
+#endif
+#if TICK_NSEC % NSEC_PER_SEC / USER_HZ == 0
+#else
+#endif
+#if NSEC_PER_SEC % USER_HZ == 0
+#elif (USER_HZ % 512) == 0
+#else
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/kd.h b/ndk/build/platforms/android-1.5/common/include/linux/kd.h
new file mode 100644
index 0000000..1541ddf
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/kd.h
@@ -0,0 +1,176 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_KD_H
+#define _LINUX_KD_H
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+#define GIO_FONT 0x4B60  
+#define PIO_FONT 0x4B61  
+
+#define GIO_FONTX 0x4B6B  
+#define PIO_FONTX 0x4B6C  
+struct consolefontdesc {
+ unsigned short charcount;
+ unsigned short charheight;
+ char __user *chardata;
+};
+
+#define PIO_FONTRESET 0x4B6D  
+
+#define GIO_CMAP 0x4B70  
+#define PIO_CMAP 0x4B71  
+
+#define KIOCSOUND 0x4B2F  
+#define KDMKTONE 0x4B30  
+
+#define KDGETLED 0x4B31  
+#define KDSETLED 0x4B32  
+#define LED_SCR 0x01  
+#define LED_NUM 0x02  
+#define LED_CAP 0x04  
+
+#define KDGKBTYPE 0x4B33  
+#define KB_84 0x01
+#define KB_101 0x02  
+#define KB_OTHER 0x03
+
+#define KDADDIO 0x4B34  
+#define KDDELIO 0x4B35  
+#define KDENABIO 0x4B36  
+#define KDDISABIO 0x4B37  
+
+#define KDSETMODE 0x4B3A  
+#define KD_TEXT 0x00
+#define KD_GRAPHICS 0x01
+#define KD_TEXT0 0x02  
+#define KD_TEXT1 0x03  
+#define KDGETMODE 0x4B3B  
+
+#define KDMAPDISP 0x4B3C  
+#define KDUNMAPDISP 0x4B3D  
+
+typedef char scrnmap_t;
+#define E_TABSZ 256
+#define GIO_SCRNMAP 0x4B40  
+#define PIO_SCRNMAP 0x4B41  
+#define GIO_UNISCRNMAP 0x4B69  
+#define PIO_UNISCRNMAP 0x4B6A  
+
+#define GIO_UNIMAP 0x4B66  
+struct unipair {
+ unsigned short unicode;
+ unsigned short fontpos;
+};
+struct unimapdesc {
+ unsigned short entry_ct;
+ struct unipair __user *entries;
+};
+#define PIO_UNIMAP 0x4B67  
+#define PIO_UNIMAPCLR 0x4B68  
+struct unimapinit {
+ unsigned short advised_hashsize;
+ unsigned short advised_hashstep;
+ unsigned short advised_hashlevel;
+};
+
+#define UNI_DIRECT_BASE 0xF000  
+#define UNI_DIRECT_MASK 0x01FF  
+
+#define K_RAW 0x00
+#define K_XLATE 0x01
+#define K_MEDIUMRAW 0x02
+#define K_UNICODE 0x03
+#define KDGKBMODE 0x4B44  
+#define KDSKBMODE 0x4B45  
+
+#define K_METABIT 0x03
+#define K_ESCPREFIX 0x04
+#define KDGKBMETA 0x4B62  
+#define KDSKBMETA 0x4B63  
+
+#define K_SCROLLLOCK 0x01
+#define K_NUMLOCK 0x02
+#define K_CAPSLOCK 0x04
+#define KDGKBLED 0x4B64  
+#define KDSKBLED 0x4B65  
+
+struct kbentry {
+ unsigned char kb_table;
+ unsigned char kb_index;
+ unsigned short kb_value;
+};
+#define K_NORMTAB 0x00
+#define K_SHIFTTAB 0x01
+#define K_ALTTAB 0x02
+#define K_ALTSHIFTTAB 0x03
+
+#define KDGKBENT 0x4B46  
+#define KDSKBENT 0x4B47  
+
+struct kbsentry {
+ unsigned char kb_func;
+ unsigned char kb_string[512];
+};
+#define KDGKBSENT 0x4B48  
+#define KDSKBSENT 0x4B49  
+
+struct kbdiacr {
+ unsigned char diacr, base, result;
+};
+struct kbdiacrs {
+ unsigned int kb_cnt;
+ struct kbdiacr kbdiacr[256];
+};
+#define KDGKBDIACR 0x4B4A  
+#define KDSKBDIACR 0x4B4B  
+
+struct kbkeycode {
+ unsigned int scancode, keycode;
+};
+#define KDGETKEYCODE 0x4B4C  
+#define KDSETKEYCODE 0x4B4D  
+
+#define KDSIGACCEPT 0x4B4E  
+
+struct kbd_repeat {
+ int delay;
+ int period;
+
+};
+
+#define KDKBDREP 0x4B52  
+
+#define KDFONTOP 0x4B72  
+
+struct console_font_op {
+ unsigned int op;
+ unsigned int flags;
+ unsigned int width, height;
+ unsigned int charcount;
+ unsigned char __user *data;
+};
+
+struct console_font {
+ unsigned int width, height;
+ unsigned int charcount;
+ unsigned char *data;
+};
+
+#define KD_FONT_OP_SET 0  
+#define KD_FONT_OP_GET 1  
+#define KD_FONT_OP_SET_DEFAULT 2  
+#define KD_FONT_OP_COPY 3  
+
+#define KD_FONT_FLAG_DONT_RECALC 1  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/kdev_t.h b/ndk/build/platforms/android-1.5/common/include/linux/kdev_t.h
new file mode 100644
index 0000000..517f9c3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/kdev_t.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_KDEV_T_H
+#define _LINUX_KDEV_T_H
+
+#define MAJOR(dev) ((dev)>>8)
+#define MINOR(dev) ((dev) & 0xff)
+#define MKDEV(ma,mi) ((ma)<<8 | (mi))
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/kernel.h b/ndk/build/platforms/android-1.5/common/include/linux/kernel.h
new file mode 100644
index 0000000..9682e47
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/kernel.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_KERNEL_H
+#define _LINUX_KERNEL_H
+
+#define SI_LOAD_SHIFT 16
+struct sysinfo {
+ long uptime;
+ unsigned long loads[3];
+ unsigned long totalram;
+ unsigned long freeram;
+ unsigned long sharedram;
+ unsigned long bufferram;
+ unsigned long totalswap;
+ unsigned long freeswap;
+ unsigned short procs;
+ unsigned short pad;
+ unsigned long totalhigh;
+ unsigned long freehigh;
+ unsigned int mem_unit;
+ char _f[20-2*sizeof(long)-sizeof(int)];
+};
+
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+
+#define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1)
+
+#define __FUNCTION__ (__func__)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/kernel_stat.h b/ndk/build/platforms/android-1.5/common/include/linux/kernel_stat.h
new file mode 100644
index 0000000..f333736
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/kernel_stat.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_KERNEL_STAT_H
+#define _LINUX_KERNEL_STAT_H
+
+#include <asm/irq.h>
+#include <linux/smp.h>
+#include <linux/threads.h>
+#include <linux/percpu.h>
+#include <linux/cpumask.h>
+#include <asm/cputime.h>
+
+struct cpu_usage_stat {
+ cputime64_t user;
+ cputime64_t nice;
+ cputime64_t system;
+ cputime64_t softirq;
+ cputime64_t irq;
+ cputime64_t idle;
+ cputime64_t iowait;
+ cputime64_t steal;
+};
+
+struct kernel_stat {
+ struct cpu_usage_stat cpustat;
+ unsigned int irqs[NR_IRQS];
+};
+
+#define kstat_cpu(cpu) per_cpu(kstat, cpu)
+
+#define kstat_this_cpu __get_cpu_var(kstat)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/kernelcapi.h b/ndk/build/platforms/android-1.5/common/include/linux/kernelcapi.h
new file mode 100644
index 0000000..4638b0a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/kernelcapi.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __KERNELCAPI_H__
+#define __KERNELCAPI_H__
+
+#define CAPI_MAXAPPL 240  
+#define CAPI_MAXCONTR 32  
+#define CAPI_MAXDATAWINDOW 8
+
+typedef struct kcapi_flagdef {
+ int contr;
+ int flag;
+} kcapi_flagdef;
+
+typedef struct kcapi_carddef {
+ char driver[32];
+ unsigned int port;
+ unsigned irq;
+ unsigned int membase;
+ int cardnr;
+} kcapi_carddef;
+
+#define KCAPI_CMD_TRACE 10
+#define KCAPI_CMD_ADDCARD 11  
+
+#define KCAPI_TRACE_OFF 0
+#define KCAPI_TRACE_SHORT_NO_DATA 1
+#define KCAPI_TRACE_FULL_NO_DATA 2
+#define KCAPI_TRACE_SHORT 3
+#define KCAPI_TRACE_FULL 4
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/kexec.h b/ndk/build/platforms/android-1.5/common/include/linux/kexec.h
new file mode 100644
index 0000000..4004646
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/kexec.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_KEXEC_H
+#define LINUX_KEXEC_H
+
+struct pt_regs;
+struct task_struct;
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/key.h b/ndk/build/platforms/android-1.5/common/include/linux/key.h
new file mode 100644
index 0000000..5c485d7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/key.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_KEY_H
+#define _LINUX_KEY_H
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/rbtree.h>
+#include <linux/rcupdate.h>
+#include <asm/atomic.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/keyboard.h b/ndk/build/platforms/android-1.5/common/include/linux/keyboard.h
new file mode 100644
index 0000000..25e0945
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/keyboard.h
@@ -0,0 +1,446 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_KEYBOARD_H
+#define __LINUX_KEYBOARD_H
+
+#include <linux/wait.h>
+
+#define KG_SHIFT 0
+#define KG_CTRL 2
+#define KG_ALT 3
+#define KG_ALTGR 1
+#define KG_SHIFTL 4
+#define KG_KANASHIFT 4
+#define KG_SHIFTR 5
+#define KG_CTRLL 6
+#define KG_CTRLR 7
+#define KG_CAPSSHIFT 8
+
+#define NR_SHIFT 9
+
+#define NR_KEYS 256
+#define MAX_NR_KEYMAPS 256
+
+#define MAX_NR_OF_USER_KEYMAPS 256  
+
+#define MAX_NR_FUNC 256  
+
+#define KT_LATIN 0  
+#define KT_LETTER 11  
+#define KT_FN 1
+#define KT_SPEC 2
+#define KT_PAD 3
+#define KT_DEAD 4
+#define KT_CONS 5
+#define KT_CUR 6
+#define KT_SHIFT 7
+#define KT_META 8
+#define KT_ASCII 9
+#define KT_LOCK 10
+#define KT_SLOCK 12
+#define KT_BRL 14
+
+#define K(t,v) (((t)<<8)|(v))
+#define KTYP(x) ((x) >> 8)
+#define KVAL(x) ((x) & 0xff)
+
+#define K_F1 K(KT_FN,0)
+#define K_F2 K(KT_FN,1)
+#define K_F3 K(KT_FN,2)
+#define K_F4 K(KT_FN,3)
+#define K_F5 K(KT_FN,4)
+#define K_F6 K(KT_FN,5)
+#define K_F7 K(KT_FN,6)
+#define K_F8 K(KT_FN,7)
+#define K_F9 K(KT_FN,8)
+#define K_F10 K(KT_FN,9)
+#define K_F11 K(KT_FN,10)
+#define K_F12 K(KT_FN,11)
+#define K_F13 K(KT_FN,12)
+#define K_F14 K(KT_FN,13)
+#define K_F15 K(KT_FN,14)
+#define K_F16 K(KT_FN,15)
+#define K_F17 K(KT_FN,16)
+#define K_F18 K(KT_FN,17)
+#define K_F19 K(KT_FN,18)
+#define K_F20 K(KT_FN,19)
+#define K_FIND K(KT_FN,20)
+#define K_INSERT K(KT_FN,21)
+#define K_REMOVE K(KT_FN,22)
+#define K_SELECT K(KT_FN,23)
+#define K_PGUP K(KT_FN,24)  
+#define K_PGDN K(KT_FN,25)  
+#define K_MACRO K(KT_FN,26)
+#define K_HELP K(KT_FN,27)
+#define K_DO K(KT_FN,28)
+#define K_PAUSE K(KT_FN,29)
+#define K_F21 K(KT_FN,30)
+#define K_F22 K(KT_FN,31)
+#define K_F23 K(KT_FN,32)
+#define K_F24 K(KT_FN,33)
+#define K_F25 K(KT_FN,34)
+#define K_F26 K(KT_FN,35)
+#define K_F27 K(KT_FN,36)
+#define K_F28 K(KT_FN,37)
+#define K_F29 K(KT_FN,38)
+#define K_F30 K(KT_FN,39)
+#define K_F31 K(KT_FN,40)
+#define K_F32 K(KT_FN,41)
+#define K_F33 K(KT_FN,42)
+#define K_F34 K(KT_FN,43)
+#define K_F35 K(KT_FN,44)
+#define K_F36 K(KT_FN,45)
+#define K_F37 K(KT_FN,46)
+#define K_F38 K(KT_FN,47)
+#define K_F39 K(KT_FN,48)
+#define K_F40 K(KT_FN,49)
+#define K_F41 K(KT_FN,50)
+#define K_F42 K(KT_FN,51)
+#define K_F43 K(KT_FN,52)
+#define K_F44 K(KT_FN,53)
+#define K_F45 K(KT_FN,54)
+#define K_F46 K(KT_FN,55)
+#define K_F47 K(KT_FN,56)
+#define K_F48 K(KT_FN,57)
+#define K_F49 K(KT_FN,58)
+#define K_F50 K(KT_FN,59)
+#define K_F51 K(KT_FN,60)
+#define K_F52 K(KT_FN,61)
+#define K_F53 K(KT_FN,62)
+#define K_F54 K(KT_FN,63)
+#define K_F55 K(KT_FN,64)
+#define K_F56 K(KT_FN,65)
+#define K_F57 K(KT_FN,66)
+#define K_F58 K(KT_FN,67)
+#define K_F59 K(KT_FN,68)
+#define K_F60 K(KT_FN,69)
+#define K_F61 K(KT_FN,70)
+#define K_F62 K(KT_FN,71)
+#define K_F63 K(KT_FN,72)
+#define K_F64 K(KT_FN,73)
+#define K_F65 K(KT_FN,74)
+#define K_F66 K(KT_FN,75)
+#define K_F67 K(KT_FN,76)
+#define K_F68 K(KT_FN,77)
+#define K_F69 K(KT_FN,78)
+#define K_F70 K(KT_FN,79)
+#define K_F71 K(KT_FN,80)
+#define K_F72 K(KT_FN,81)
+#define K_F73 K(KT_FN,82)
+#define K_F74 K(KT_FN,83)
+#define K_F75 K(KT_FN,84)
+#define K_F76 K(KT_FN,85)
+#define K_F77 K(KT_FN,86)
+#define K_F78 K(KT_FN,87)
+#define K_F79 K(KT_FN,88)
+#define K_F80 K(KT_FN,89)
+#define K_F81 K(KT_FN,90)
+#define K_F82 K(KT_FN,91)
+#define K_F83 K(KT_FN,92)
+#define K_F84 K(KT_FN,93)
+#define K_F85 K(KT_FN,94)
+#define K_F86 K(KT_FN,95)
+#define K_F87 K(KT_FN,96)
+#define K_F88 K(KT_FN,97)
+#define K_F89 K(KT_FN,98)
+#define K_F90 K(KT_FN,99)
+#define K_F91 K(KT_FN,100)
+#define K_F92 K(KT_FN,101)
+#define K_F93 K(KT_FN,102)
+#define K_F94 K(KT_FN,103)
+#define K_F95 K(KT_FN,104)
+#define K_F96 K(KT_FN,105)
+#define K_F97 K(KT_FN,106)
+#define K_F98 K(KT_FN,107)
+#define K_F99 K(KT_FN,108)
+#define K_F100 K(KT_FN,109)
+#define K_F101 K(KT_FN,110)
+#define K_F102 K(KT_FN,111)
+#define K_F103 K(KT_FN,112)
+#define K_F104 K(KT_FN,113)
+#define K_F105 K(KT_FN,114)
+#define K_F106 K(KT_FN,115)
+#define K_F107 K(KT_FN,116)
+#define K_F108 K(KT_FN,117)
+#define K_F109 K(KT_FN,118)
+#define K_F110 K(KT_FN,119)
+#define K_F111 K(KT_FN,120)
+#define K_F112 K(KT_FN,121)
+#define K_F113 K(KT_FN,122)
+#define K_F114 K(KT_FN,123)
+#define K_F115 K(KT_FN,124)
+#define K_F116 K(KT_FN,125)
+#define K_F117 K(KT_FN,126)
+#define K_F118 K(KT_FN,127)
+#define K_F119 K(KT_FN,128)
+#define K_F120 K(KT_FN,129)
+#define K_F121 K(KT_FN,130)
+#define K_F122 K(KT_FN,131)
+#define K_F123 K(KT_FN,132)
+#define K_F124 K(KT_FN,133)
+#define K_F125 K(KT_FN,134)
+#define K_F126 K(KT_FN,135)
+#define K_F127 K(KT_FN,136)
+#define K_F128 K(KT_FN,137)
+#define K_F129 K(KT_FN,138)
+#define K_F130 K(KT_FN,139)
+#define K_F131 K(KT_FN,140)
+#define K_F132 K(KT_FN,141)
+#define K_F133 K(KT_FN,142)
+#define K_F134 K(KT_FN,143)
+#define K_F135 K(KT_FN,144)
+#define K_F136 K(KT_FN,145)
+#define K_F137 K(KT_FN,146)
+#define K_F138 K(KT_FN,147)
+#define K_F139 K(KT_FN,148)
+#define K_F140 K(KT_FN,149)
+#define K_F141 K(KT_FN,150)
+#define K_F142 K(KT_FN,151)
+#define K_F143 K(KT_FN,152)
+#define K_F144 K(KT_FN,153)
+#define K_F145 K(KT_FN,154)
+#define K_F146 K(KT_FN,155)
+#define K_F147 K(KT_FN,156)
+#define K_F148 K(KT_FN,157)
+#define K_F149 K(KT_FN,158)
+#define K_F150 K(KT_FN,159)
+#define K_F151 K(KT_FN,160)
+#define K_F152 K(KT_FN,161)
+#define K_F153 K(KT_FN,162)
+#define K_F154 K(KT_FN,163)
+#define K_F155 K(KT_FN,164)
+#define K_F156 K(KT_FN,165)
+#define K_F157 K(KT_FN,166)
+#define K_F158 K(KT_FN,167)
+#define K_F159 K(KT_FN,168)
+#define K_F160 K(KT_FN,169)
+#define K_F161 K(KT_FN,170)
+#define K_F162 K(KT_FN,171)
+#define K_F163 K(KT_FN,172)
+#define K_F164 K(KT_FN,173)
+#define K_F165 K(KT_FN,174)
+#define K_F166 K(KT_FN,175)
+#define K_F167 K(KT_FN,176)
+#define K_F168 K(KT_FN,177)
+#define K_F169 K(KT_FN,178)
+#define K_F170 K(KT_FN,179)
+#define K_F171 K(KT_FN,180)
+#define K_F172 K(KT_FN,181)
+#define K_F173 K(KT_FN,182)
+#define K_F174 K(KT_FN,183)
+#define K_F175 K(KT_FN,184)
+#define K_F176 K(KT_FN,185)
+#define K_F177 K(KT_FN,186)
+#define K_F178 K(KT_FN,187)
+#define K_F179 K(KT_FN,188)
+#define K_F180 K(KT_FN,189)
+#define K_F181 K(KT_FN,190)
+#define K_F182 K(KT_FN,191)
+#define K_F183 K(KT_FN,192)
+#define K_F184 K(KT_FN,193)
+#define K_F185 K(KT_FN,194)
+#define K_F186 K(KT_FN,195)
+#define K_F187 K(KT_FN,196)
+#define K_F188 K(KT_FN,197)
+#define K_F189 K(KT_FN,198)
+#define K_F190 K(KT_FN,199)
+#define K_F191 K(KT_FN,200)
+#define K_F192 K(KT_FN,201)
+#define K_F193 K(KT_FN,202)
+#define K_F194 K(KT_FN,203)
+#define K_F195 K(KT_FN,204)
+#define K_F196 K(KT_FN,205)
+#define K_F197 K(KT_FN,206)
+#define K_F198 K(KT_FN,207)
+#define K_F199 K(KT_FN,208)
+#define K_F200 K(KT_FN,209)
+#define K_F201 K(KT_FN,210)
+#define K_F202 K(KT_FN,211)
+#define K_F203 K(KT_FN,212)
+#define K_F204 K(KT_FN,213)
+#define K_F205 K(KT_FN,214)
+#define K_F206 K(KT_FN,215)
+#define K_F207 K(KT_FN,216)
+#define K_F208 K(KT_FN,217)
+#define K_F209 K(KT_FN,218)
+#define K_F210 K(KT_FN,219)
+#define K_F211 K(KT_FN,220)
+#define K_F212 K(KT_FN,221)
+#define K_F213 K(KT_FN,222)
+#define K_F214 K(KT_FN,223)
+#define K_F215 K(KT_FN,224)
+#define K_F216 K(KT_FN,225)
+#define K_F217 K(KT_FN,226)
+#define K_F218 K(KT_FN,227)
+#define K_F219 K(KT_FN,228)
+#define K_F220 K(KT_FN,229)
+#define K_F221 K(KT_FN,230)
+#define K_F222 K(KT_FN,231)
+#define K_F223 K(KT_FN,232)
+#define K_F224 K(KT_FN,233)
+#define K_F225 K(KT_FN,234)
+#define K_F226 K(KT_FN,235)
+#define K_F227 K(KT_FN,236)
+#define K_F228 K(KT_FN,237)
+#define K_F229 K(KT_FN,238)
+#define K_F230 K(KT_FN,239)
+#define K_F231 K(KT_FN,240)
+#define K_F232 K(KT_FN,241)
+#define K_F233 K(KT_FN,242)
+#define K_F234 K(KT_FN,243)
+#define K_F235 K(KT_FN,244)
+#define K_F236 K(KT_FN,245)
+#define K_F237 K(KT_FN,246)
+#define K_F238 K(KT_FN,247)
+#define K_F239 K(KT_FN,248)
+#define K_F240 K(KT_FN,249)
+#define K_F241 K(KT_FN,250)
+#define K_F242 K(KT_FN,251)
+#define K_F243 K(KT_FN,252)
+#define K_F244 K(KT_FN,253)
+#define K_F245 K(KT_FN,254)
+#define K_UNDO K(KT_FN,255)
+
+#define K_HOLE K(KT_SPEC,0)
+#define K_ENTER K(KT_SPEC,1)
+#define K_SH_REGS K(KT_SPEC,2)
+#define K_SH_MEM K(KT_SPEC,3)
+#define K_SH_STAT K(KT_SPEC,4)
+#define K_BREAK K(KT_SPEC,5)
+#define K_CONS K(KT_SPEC,6)
+#define K_CAPS K(KT_SPEC,7)
+#define K_NUM K(KT_SPEC,8)
+#define K_HOLD K(KT_SPEC,9)
+#define K_SCROLLFORW K(KT_SPEC,10)
+#define K_SCROLLBACK K(KT_SPEC,11)
+#define K_BOOT K(KT_SPEC,12)
+#define K_CAPSON K(KT_SPEC,13)
+#define K_COMPOSE K(KT_SPEC,14)
+#define K_SAK K(KT_SPEC,15)
+#define K_DECRCONSOLE K(KT_SPEC,16)
+#define K_INCRCONSOLE K(KT_SPEC,17)
+#define K_SPAWNCONSOLE K(KT_SPEC,18)
+#define K_BARENUMLOCK K(KT_SPEC,19)
+
+#define K_ALLOCATED K(KT_SPEC,126)  
+#define K_NOSUCHMAP K(KT_SPEC,127)  
+
+#define K_P0 K(KT_PAD,0)
+#define K_P1 K(KT_PAD,1)
+#define K_P2 K(KT_PAD,2)
+#define K_P3 K(KT_PAD,3)
+#define K_P4 K(KT_PAD,4)
+#define K_P5 K(KT_PAD,5)
+#define K_P6 K(KT_PAD,6)
+#define K_P7 K(KT_PAD,7)
+#define K_P8 K(KT_PAD,8)
+#define K_P9 K(KT_PAD,9)
+#define K_PPLUS K(KT_PAD,10)  
+#define K_PMINUS K(KT_PAD,11)  
+#define K_PSTAR K(KT_PAD,12)  
+#define K_PSLASH K(KT_PAD,13)  
+#define K_PENTER K(KT_PAD,14)  
+#define K_PCOMMA K(KT_PAD,15)  
+#define K_PDOT K(KT_PAD,16)  
+#define K_PPLUSMINUS K(KT_PAD,17)  
+#define K_PPARENL K(KT_PAD,18)  
+#define K_PPARENR K(KT_PAD,19)  
+
+#define NR_PAD 20
+
+#define K_DGRAVE K(KT_DEAD,0)
+#define K_DACUTE K(KT_DEAD,1)
+#define K_DCIRCM K(KT_DEAD,2)
+#define K_DTILDE K(KT_DEAD,3)
+#define K_DDIERE K(KT_DEAD,4)
+#define K_DCEDIL K(KT_DEAD,5)
+
+#define NR_DEAD 6
+
+#define K_DOWN K(KT_CUR,0)
+#define K_LEFT K(KT_CUR,1)
+#define K_RIGHT K(KT_CUR,2)
+#define K_UP K(KT_CUR,3)
+
+#define K_SHIFT K(KT_SHIFT,KG_SHIFT)
+#define K_CTRL K(KT_SHIFT,KG_CTRL)
+#define K_ALT K(KT_SHIFT,KG_ALT)
+#define K_ALTGR K(KT_SHIFT,KG_ALTGR)
+#define K_SHIFTL K(KT_SHIFT,KG_SHIFTL)
+#define K_SHIFTR K(KT_SHIFT,KG_SHIFTR)
+#define K_CTRLL K(KT_SHIFT,KG_CTRLL)
+#define K_CTRLR K(KT_SHIFT,KG_CTRLR)
+#define K_CAPSSHIFT K(KT_SHIFT,KG_CAPSSHIFT)
+
+#define K_ASC0 K(KT_ASCII,0)
+#define K_ASC1 K(KT_ASCII,1)
+#define K_ASC2 K(KT_ASCII,2)
+#define K_ASC3 K(KT_ASCII,3)
+#define K_ASC4 K(KT_ASCII,4)
+#define K_ASC5 K(KT_ASCII,5)
+#define K_ASC6 K(KT_ASCII,6)
+#define K_ASC7 K(KT_ASCII,7)
+#define K_ASC8 K(KT_ASCII,8)
+#define K_ASC9 K(KT_ASCII,9)
+#define K_HEX0 K(KT_ASCII,10)
+#define K_HEX1 K(KT_ASCII,11)
+#define K_HEX2 K(KT_ASCII,12)
+#define K_HEX3 K(KT_ASCII,13)
+#define K_HEX4 K(KT_ASCII,14)
+#define K_HEX5 K(KT_ASCII,15)
+#define K_HEX6 K(KT_ASCII,16)
+#define K_HEX7 K(KT_ASCII,17)
+#define K_HEX8 K(KT_ASCII,18)
+#define K_HEX9 K(KT_ASCII,19)
+#define K_HEXa K(KT_ASCII,20)
+#define K_HEXb K(KT_ASCII,21)
+#define K_HEXc K(KT_ASCII,22)
+#define K_HEXd K(KT_ASCII,23)
+#define K_HEXe K(KT_ASCII,24)
+#define K_HEXf K(KT_ASCII,25)
+
+#define NR_ASCII 26
+
+#define K_SHIFTLOCK K(KT_LOCK,KG_SHIFT)
+#define K_CTRLLOCK K(KT_LOCK,KG_CTRL)
+#define K_ALTLOCK K(KT_LOCK,KG_ALT)
+#define K_ALTGRLOCK K(KT_LOCK,KG_ALTGR)
+#define K_SHIFTLLOCK K(KT_LOCK,KG_SHIFTL)
+#define K_SHIFTRLOCK K(KT_LOCK,KG_SHIFTR)
+#define K_CTRLLLOCK K(KT_LOCK,KG_CTRLL)
+#define K_CTRLRLOCK K(KT_LOCK,KG_CTRLR)
+
+#define K_SHIFT_SLOCK K(KT_SLOCK,KG_SHIFT)
+#define K_CTRL_SLOCK K(KT_SLOCK,KG_CTRL)
+#define K_ALT_SLOCK K(KT_SLOCK,KG_ALT)
+#define K_ALTGR_SLOCK K(KT_SLOCK,KG_ALTGR)
+#define K_SHIFTL_SLOCK K(KT_SLOCK,KG_SHIFTL)
+#define K_SHIFTR_SLOCK K(KT_SLOCK,KG_SHIFTR)
+#define K_CTRLL_SLOCK K(KT_SLOCK,KG_CTRLL)
+#define K_CTRLR_SLOCK K(KT_SLOCK,KG_CTRLR)
+
+#define NR_LOCK 8
+
+#define K_BRL_BLANK K(KT_BRL, 0)
+#define K_BRL_DOT1 K(KT_BRL, 1)
+#define K_BRL_DOT2 K(KT_BRL, 2)
+#define K_BRL_DOT3 K(KT_BRL, 3)
+#define K_BRL_DOT4 K(KT_BRL, 4)
+#define K_BRL_DOT5 K(KT_BRL, 5)
+#define K_BRL_DOT6 K(KT_BRL, 6)
+#define K_BRL_DOT7 K(KT_BRL, 7)
+#define K_BRL_DOT8 K(KT_BRL, 8)
+
+#define NR_BRL 9
+
+#define MAX_DIACR 256
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/keychord.h b/ndk/build/platforms/android-1.5/common/include/linux/keychord.h
new file mode 100644
index 0000000..9148431
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/keychord.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_KEYCHORD_H_
+#define __LINUX_KEYCHORD_H_
+
+#include <linux/input.h>
+
+#define KEYCHORD_VERSION 1
+
+struct input_keychord {
+
+ __u16 version;
+
+ __u16 id;
+
+ __u16 count;
+
+ __u16 keycodes[];
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/klist.h b/ndk/build/platforms/android-1.5/common/include/linux/klist.h
new file mode 100644
index 0000000..0df014f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/klist.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_KLIST_H
+#define _LINUX_KLIST_H
+
+#include <linux/spinlock.h>
+#include <linux/completion.h>
+#include <linux/kref.h>
+#include <linux/list.h>
+
+struct klist_node;
+struct klist {
+ spinlock_t k_lock;
+ struct list_head k_list;
+ void (*get)(struct klist_node *);
+ void (*put)(struct klist_node *);
+};
+
+struct klist_node {
+ struct klist * n_klist;
+ struct list_head n_node;
+ struct kref n_ref;
+ struct completion n_removed;
+};
+
+struct klist_iter {
+ struct klist * i_klist;
+ struct list_head * i_head;
+ struct klist_node * i_cur;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/kmod.h b/ndk/build/platforms/android-1.5/common/include/linux/kmod.h
new file mode 100644
index 0000000..d24456d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/kmod.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_KMOD_H__
+#define __LINUX_KMOD_H__
+
+#include <linux/stddef.h>
+#include <linux/errno.h>
+#include <linux/compiler.h>
+
+#define KMOD_PATH_LEN 256
+
+#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/kobject.h b/ndk/build/platforms/android-1.5/common/include/linux/kobject.h
new file mode 100644
index 0000000..c61a950
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/kobject.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _KOBJECT_H_
+#define _KOBJECT_H_
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/kref.h b/ndk/build/platforms/android-1.5/common/include/linux/kref.h
new file mode 100644
index 0000000..ee02b7f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/kref.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _KREF_H_
+#define _KREF_H_
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ktime.h b/ndk/build/platforms/android-1.5/common/include/linux/ktime.h
new file mode 100644
index 0000000..34f8f0f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ktime.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_KTIME_H
+#define _LINUX_KTIME_H
+
+#include <linux/time.h>
+#include <linux/jiffies.h>
+
+typedef union {
+ s64 tv64;
+#if BITS_PER_LONG != (64 && !defined(CONFIG_KTIME_SCALAR))
+ struct {
+#ifdef __BIG_ENDIAN
+ s32 sec, nsec;
+#else
+ s32 nsec, sec;
+#endif
+ } tv;
+#endif
+} ktime_t;
+
+#define KTIME_MAX ((s64)~((u64)1 << 63))
+#define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC)
+
+#if BITS_PER_LONG == 64
+
+#if BITS_PER_LONG == 64
+#endif
+#define ktime_sub(lhs, rhs)   ({ (ktime_t){ .tv64 = (lhs).tv64 - (rhs).tv64 }; })
+#define ktime_add(lhs, rhs)   ({ (ktime_t){ .tv64 = (lhs).tv64 + (rhs).tv64 }; })
+#define ktime_add_ns(kt, nsval)   ({ (ktime_t){ .tv64 = (kt).tv64 + (nsval) }; })
+#define ktime_to_timespec(kt) ns_to_timespec((kt).tv64)
+#define ktime_to_timeval(kt) ns_to_timeval((kt).tv64)
+#define ktime_to_ns(kt) ((kt).tv64)
+#else
+
+#endif
+#define KTIME_REALTIME_RES (ktime_t){ .tv64 = TICK_NSEC }
+#define KTIME_MONOTONIC_RES (ktime_t){ .tv64 = TICK_NSEC }
+
+#define ktime_get_real_ts(ts) getnstimeofday(ts)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/limits.h b/ndk/build/platforms/android-1.5/common/include/linux/limits.h
new file mode 100644
index 0000000..5565e30
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/limits.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_LIMITS_H
+#define _LINUX_LIMITS_H
+
+#define NR_OPEN 1024
+
+#define NGROUPS_MAX 65536  
+#define ARG_MAX 131072  
+#define CHILD_MAX 999  
+#define OPEN_MAX 256  
+#define LINK_MAX 127  
+#define MAX_CANON 255  
+#define MAX_INPUT 255  
+#define NAME_MAX 255  
+#define PATH_MAX 4096  
+#define PIPE_BUF 4096  
+#define XATTR_NAME_MAX 255  
+#define XATTR_SIZE_MAX 65536  
+#define XATTR_LIST_MAX 65536  
+
+#define RTSIG_MAX 32
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/linkage.h b/ndk/build/platforms/android-1.5/common/include/linux/linkage.h
new file mode 100644
index 0000000..e0194bc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/linkage.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_LINKAGE_H
+#define _LINUX_LINKAGE_H
+
+#include <asm/linkage.h>
+
+#ifdef __cplusplus
+#define CPP_ASMLINKAGE extern "C"
+#else
+#define CPP_ASMLINKAGE
+#endif
+
+#ifndef asmlinkage
+#define asmlinkage CPP_ASMLINKAGE
+#endif
+
+#ifndef prevent_tail_call
+#define prevent_tail_call(ret) do { } while (0)
+#endif
+
+#ifndef __ALIGN
+#define __ALIGN .align 4,0x90
+#define __ALIGN_STR ".align 4,0x90"
+#endif
+
+#ifdef __ASSEMBLY__
+
+#define ALIGN __ALIGN
+#define ALIGN_STR __ALIGN_STR
+
+#ifndef ENTRY
+#define ENTRY(name)   .globl name;   ALIGN;   name:
+#endif
+
+#define KPROBE_ENTRY(name)   .section .kprobes.text, "ax";   ENTRY(name)
+
+#ifndef END
+#define END(name)   .size name, .-name
+#endif
+
+#ifndef ENDPROC
+#define ENDPROC(name)   .type name, @function;   END(name)
+#endif
+
+#endif
+
+#define NORET_TYPE  
+#define ATTRIB_NORET __attribute__((noreturn))
+#define NORET_AND noreturn,
+
+#ifndef FASTCALL
+#define FASTCALL(x) x
+#define fastcall
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/list.h b/ndk/build/platforms/android-1.5/common/include/linux/list.h
new file mode 100644
index 0000000..d17871d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/list.h
@@ -0,0 +1,16 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_LIST_H
+#define _LINUX_LIST_H
+
+#warning "don't include kernel headers in userspace"
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/lockd/nlm.h b/ndk/build/platforms/android-1.5/common/include/linux/lockd/nlm.h
new file mode 100644
index 0000000..d5d44fe
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/lockd/nlm.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_LOCKD_NLM_H
+#define LINUX_LOCKD_NLM_H
+
+#define NLM_OFFSET_MAX ((s32) 0x7fffffff)
+#define NLM4_OFFSET_MAX ((s64) ((~(u64)0) >> 1))
+
+enum {
+ NLM_LCK_GRANTED = 0,
+ NLM_LCK_DENIED = 1,
+ NLM_LCK_DENIED_NOLOCKS = 2,
+ NLM_LCK_BLOCKED = 3,
+ NLM_LCK_DENIED_GRACE_PERIOD = 4,
+};
+
+#define NLM_PROGRAM 100021
+
+#define NLMPROC_NULL 0
+#define NLMPROC_TEST 1
+#define NLMPROC_LOCK 2
+#define NLMPROC_CANCEL 3
+#define NLMPROC_UNLOCK 4
+#define NLMPROC_GRANTED 5
+#define NLMPROC_TEST_MSG 6
+#define NLMPROC_LOCK_MSG 7
+#define NLMPROC_CANCEL_MSG 8
+#define NLMPROC_UNLOCK_MSG 9
+#define NLMPROC_GRANTED_MSG 10
+#define NLMPROC_TEST_RES 11
+#define NLMPROC_LOCK_RES 12
+#define NLMPROC_CANCEL_RES 13
+#define NLMPROC_UNLOCK_RES 14
+#define NLMPROC_GRANTED_RES 15
+#define NLMPROC_NSM_NOTIFY 16  
+#define NLMPROC_SHARE 20
+#define NLMPROC_UNSHARE 21
+#define NLMPROC_NM_LOCK 22
+#define NLMPROC_FREE_ALL 23
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/lockd/xdr.h b/ndk/build/platforms/android-1.5/common/include/linux/lockd/xdr.h
new file mode 100644
index 0000000..75d0308
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/lockd/xdr.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LOCKD_XDR_H
+#define LOCKD_XDR_H
+
+#include <linux/fs.h>
+#include <linux/nfs.h>
+#include <linux/sunrpc/xdr.h>
+
+#define NLM_MAXCOOKIELEN 32
+#define NLM_MAXSTRLEN 1024
+
+#define nlm_granted __constant_htonl(NLM_LCK_GRANTED)
+#define nlm_lck_denied __constant_htonl(NLM_LCK_DENIED)
+#define nlm_lck_denied_nolocks __constant_htonl(NLM_LCK_DENIED_NOLOCKS)
+#define nlm_lck_blocked __constant_htonl(NLM_LCK_BLOCKED)
+#define nlm_lck_denied_grace_period __constant_htonl(NLM_LCK_DENIED_GRACE_PERIOD)
+
+struct nlm_lock {
+ char * caller;
+ int len;
+ struct nfs_fh fh;
+ struct xdr_netobj oh;
+ u32 svid;
+ struct file_lock fl;
+};
+
+struct nlm_cookie
+{
+ unsigned char data[NLM_MAXCOOKIELEN];
+ unsigned int len;
+};
+
+struct nlm_args {
+ struct nlm_cookie cookie;
+ struct nlm_lock lock;
+ u32 block;
+ u32 reclaim;
+ u32 state;
+ u32 monitor;
+ u32 fsm_access;
+ u32 fsm_mode;
+};
+
+typedef struct nlm_args nlm_args;
+
+struct nlm_res {
+ struct nlm_cookie cookie;
+ u32 status;
+ struct nlm_lock lock;
+};
+
+struct nlm_reboot {
+ char * mon;
+ int len;
+ u32 state;
+ u32 addr;
+ u32 vers;
+ u32 proto;
+};
+
+#define NLMSVC_XDRSIZE sizeof(struct nlm_args)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/lockdep.h b/ndk/build/platforms/android-1.5/common/include/linux/lockdep.h
new file mode 100644
index 0000000..f5e8634
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/lockdep.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_LOCKDEP_H
+#define __LINUX_LOCKDEP_H
+
+#include <linux/linkage.h>
+#include <linux/list.h>
+#include <linux/debug_locks.h>
+#include <linux/stacktrace.h>
+
+#define lock_acquire(l, s, t, r, c, i) do { } while (0)
+#define lock_release(l, n, i) do { } while (0)
+#define lockdep_init() do { } while (0)
+#define lockdep_info() do { } while (0)
+#define lockdep_init_map(lock, name, key) do { (void)(key); } while (0)
+#define lockdep_set_class(lock, key) do { (void)(key); } while (0)
+#define lockdep_set_class_and_name(lock, key, name)   do { (void)(key); } while (0)
+#define INIT_LOCKDEP
+#define lockdep_reset() do { debug_locks = 1; } while (0)
+#define lockdep_free_key_range(start, size) do { } while (0)
+
+#define early_init_irq_lock_class() do { } while (0)
+
+#define early_boot_irqs_off() do { } while (0)
+#define early_boot_irqs_on() do { } while (0)
+
+#define SINGLE_DEPTH_NESTING 1
+
+#define spin_acquire(l, s, t, i) do { } while (0)
+#define spin_release(l, n, i) do { } while (0)
+
+#define rwlock_acquire(l, s, t, i) do { } while (0)
+#define rwlock_acquire_read(l, s, t, i) do { } while (0)
+#define rwlock_release(l, n, i) do { } while (0)
+
+#define mutex_acquire(l, s, t, i) do { } while (0)
+#define mutex_release(l, n, i) do { } while (0)
+
+#define rwsem_acquire(l, s, t, i) do { } while (0)
+#define rwsem_acquire_read(l, s, t, i) do { } while (0)
+#define rwsem_release(l, n, i) do { } while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/loop.h b/ndk/build/platforms/android-1.5/common/include/linux/loop.h
new file mode 100644
index 0000000..9cdfd38
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/loop.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_LOOP_H
+#define _LINUX_LOOP_H
+
+#define LO_NAME_SIZE 64
+#define LO_KEY_SIZE 32
+
+enum {
+ LO_FLAGS_READ_ONLY = 1,
+ LO_FLAGS_USE_AOPS = 2,
+};
+
+#include <asm/posix_types.h>  
+#include <asm/types.h>  
+
+struct loop_info {
+ int lo_number;
+ __kernel_old_dev_t lo_device;
+ unsigned long lo_inode;
+ __kernel_old_dev_t lo_rdevice;
+ int lo_offset;
+ int lo_encrypt_type;
+ int lo_encrypt_key_size;
+ int lo_flags;
+ char lo_name[LO_NAME_SIZE];
+ unsigned char lo_encrypt_key[LO_KEY_SIZE];
+ unsigned long lo_init[2];
+ char reserved[4];
+};
+
+struct loop_info64 {
+ __u64 lo_device;
+ __u64 lo_inode;
+ __u64 lo_rdevice;
+ __u64 lo_offset;
+ __u64 lo_sizelimit;
+ __u32 lo_number;
+ __u32 lo_encrypt_type;
+ __u32 lo_encrypt_key_size;
+ __u32 lo_flags;
+ __u8 lo_file_name[LO_NAME_SIZE];
+ __u8 lo_crypt_name[LO_NAME_SIZE];
+ __u8 lo_encrypt_key[LO_KEY_SIZE];
+ __u64 lo_init[2];
+};
+
+#define LO_CRYPT_NONE 0
+#define LO_CRYPT_XOR 1
+#define LO_CRYPT_DES 2
+#define LO_CRYPT_FISH2 3  
+#define LO_CRYPT_BLOW 4
+#define LO_CRYPT_CAST128 5
+#define LO_CRYPT_IDEA 6
+#define LO_CRYPT_DUMMY 9
+#define LO_CRYPT_SKIPJACK 10
+#define LO_CRYPT_CRYPTOAPI 18
+#define MAX_LO_CRYPT 20
+
+#define LOOP_SET_FD 0x4C00
+#define LOOP_CLR_FD 0x4C01
+#define LOOP_SET_STATUS 0x4C02
+#define LOOP_GET_STATUS 0x4C03
+#define LOOP_SET_STATUS64 0x4C04
+#define LOOP_GET_STATUS64 0x4C05
+#define LOOP_CHANGE_FD 0x4C06
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/magic.h b/ndk/build/platforms/android-1.5/common/include/linux/magic.h
new file mode 100644
index 0000000..c94f9ce
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/magic.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_MAGIC_H__
+#define __LINUX_MAGIC_H__
+
+#define ADFS_SUPER_MAGIC 0xadf5
+#define AFFS_SUPER_MAGIC 0xadff
+#define AFS_SUPER_MAGIC 0x5346414F
+#define AUTOFS_SUPER_MAGIC 0x0187
+#define CODA_SUPER_MAGIC 0x73757245
+#define EFS_SUPER_MAGIC 0x414A53
+#define EXT2_SUPER_MAGIC 0xEF53
+#define EXT3_SUPER_MAGIC 0xEF53
+#define EXT4_SUPER_MAGIC 0xEF53
+#define HPFS_SUPER_MAGIC 0xf995e849
+#define ISOFS_SUPER_MAGIC 0x9660
+#define JFFS2_SUPER_MAGIC 0x72b6
+#define ANON_INODE_FS_MAGIC 0x09041934
+
+#define MINIX_SUPER_MAGIC 0x137F  
+#define MINIX_SUPER_MAGIC2 0x138F  
+#define MINIX2_SUPER_MAGIC 0x2468  
+#define MINIX2_SUPER_MAGIC2 0x2478  
+#define MINIX3_SUPER_MAGIC 0x4d5a  
+
+#define MSDOS_SUPER_MAGIC 0x4d44  
+#define NCP_SUPER_MAGIC 0x564c  
+#define NFS_SUPER_MAGIC 0x6969
+#define OPENPROM_SUPER_MAGIC 0x9fa1
+#define PROC_SUPER_MAGIC 0x9fa0
+#define QNX4_SUPER_MAGIC 0x002f  
+
+#define REISERFS_SUPER_MAGIC 0x52654973  
+
+#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
+#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
+#define REISER2FS_JR_SUPER_MAGIC_STRING "ReIsEr3Fs"
+
+#define SMB_SUPER_MAGIC 0x517B
+#define USBDEVICE_SUPER_MAGIC 0x9fa2
+#define CGROUP_SUPER_MAGIC 0x27e0eb
+
+#define FUTEXFS_SUPER_MAGIC 0xBAD1DEA
+#define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/major.h b/ndk/build/platforms/android-1.5/common/include/linux/major.h
new file mode 100644
index 0000000..e42d698
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/major.h
@@ -0,0 +1,175 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_MAJOR_H
+#define _LINUX_MAJOR_H
+
+#define UNNAMED_MAJOR 0
+#define MEM_MAJOR 1
+#define RAMDISK_MAJOR 1
+#define FLOPPY_MAJOR 2
+#define PTY_MASTER_MAJOR 2
+#define IDE0_MAJOR 3
+#define HD_MAJOR IDE0_MAJOR
+#define PTY_SLAVE_MAJOR 3
+#define TTY_MAJOR 4
+#define TTYAUX_MAJOR 5
+#define LP_MAJOR 6
+#define VCS_MAJOR 7
+#define LOOP_MAJOR 7
+#define SCSI_DISK0_MAJOR 8
+#define SCSI_TAPE_MAJOR 9
+#define MD_MAJOR 9
+#define MISC_MAJOR 10
+#define SCSI_CDROM_MAJOR 11
+#define MUX_MAJOR 11  
+#define XT_DISK_MAJOR 13
+#define INPUT_MAJOR 13
+#define SOUND_MAJOR 14
+#define CDU31A_CDROM_MAJOR 15
+#define JOYSTICK_MAJOR 15
+#define GOLDSTAR_CDROM_MAJOR 16
+#define OPTICS_CDROM_MAJOR 17
+#define SANYO_CDROM_MAJOR 18
+#define CYCLADES_MAJOR 19
+#define CYCLADESAUX_MAJOR 20
+#define MITSUMI_X_CDROM_MAJOR 20
+#define MFM_ACORN_MAJOR 21  
+#define SCSI_GENERIC_MAJOR 21
+#define IDE1_MAJOR 22
+#define DIGICU_MAJOR 22
+#define DIGI_MAJOR 23
+#define MITSUMI_CDROM_MAJOR 23
+#define CDU535_CDROM_MAJOR 24
+#define STL_SERIALMAJOR 24
+#define MATSUSHITA_CDROM_MAJOR 25
+#define STL_CALLOUTMAJOR 25
+#define MATSUSHITA_CDROM2_MAJOR 26
+#define QIC117_TAPE_MAJOR 27
+#define MATSUSHITA_CDROM3_MAJOR 27
+#define MATSUSHITA_CDROM4_MAJOR 28
+#define STL_SIOMEMMAJOR 28
+#define ACSI_MAJOR 28
+#define AZTECH_CDROM_MAJOR 29
+#define GRAPHDEV_MAJOR 29  
+#define CM206_CDROM_MAJOR 32
+#define IDE2_MAJOR 33
+#define IDE3_MAJOR 34
+#define Z8530_MAJOR 34
+#define XPRAM_MAJOR 35  
+#define NETLINK_MAJOR 36
+#define PS2ESDI_MAJOR 36
+#define IDETAPE_MAJOR 37
+#define Z2RAM_MAJOR 37
+#define APBLOCK_MAJOR 38  
+#define DDV_MAJOR 39  
+#define NBD_MAJOR 43  
+#define RISCOM8_NORMAL_MAJOR 48
+#define DAC960_MAJOR 48  
+#define RISCOM8_CALLOUT_MAJOR 49
+#define MKISS_MAJOR 55
+#define DSP56K_MAJOR 55  
+
+#define IDE4_MAJOR 56
+#define IDE5_MAJOR 57
+
+#define SCSI_DISK1_MAJOR 65
+#define SCSI_DISK2_MAJOR 66
+#define SCSI_DISK3_MAJOR 67
+#define SCSI_DISK4_MAJOR 68
+#define SCSI_DISK5_MAJOR 69
+#define SCSI_DISK6_MAJOR 70
+#define SCSI_DISK7_MAJOR 71
+
+#define COMPAQ_SMART2_MAJOR 72
+#define COMPAQ_SMART2_MAJOR1 73
+#define COMPAQ_SMART2_MAJOR2 74
+#define COMPAQ_SMART2_MAJOR3 75
+#define COMPAQ_SMART2_MAJOR4 76
+#define COMPAQ_SMART2_MAJOR5 77
+#define COMPAQ_SMART2_MAJOR6 78
+#define COMPAQ_SMART2_MAJOR7 79
+
+#define SPECIALIX_NORMAL_MAJOR 75
+#define SPECIALIX_CALLOUT_MAJOR 76
+
+#define AURORA_MAJOR 79
+
+#define I2O_MAJOR 80  
+
+#define SHMIQ_MAJOR 85  
+#define SCSI_CHANGER_MAJOR 86
+
+#define IDE6_MAJOR 88
+#define IDE7_MAJOR 89
+#define IDE8_MAJOR 90
+#define IDE9_MAJOR 91
+
+#define DASD_MAJOR 94
+
+#define MDISK_MAJOR 95
+
+#define UBD_MAJOR 98
+
+#define PP_MAJOR 99
+#define JSFD_MAJOR 99
+
+#define PHONE_MAJOR 100
+
+#define COMPAQ_CISS_MAJOR 104
+#define COMPAQ_CISS_MAJOR1 105
+#define COMPAQ_CISS_MAJOR2 106
+#define COMPAQ_CISS_MAJOR3 107
+#define COMPAQ_CISS_MAJOR4 108
+#define COMPAQ_CISS_MAJOR5 109
+#define COMPAQ_CISS_MAJOR6 110
+#define COMPAQ_CISS_MAJOR7 111
+
+#define VIODASD_MAJOR 112
+#define VIOCD_MAJOR 113
+
+#define ATARAID_MAJOR 114
+
+#define SCSI_DISK8_MAJOR 128
+#define SCSI_DISK9_MAJOR 129
+#define SCSI_DISK10_MAJOR 130
+#define SCSI_DISK11_MAJOR 131
+#define SCSI_DISK12_MAJOR 132
+#define SCSI_DISK13_MAJOR 133
+#define SCSI_DISK14_MAJOR 134
+#define SCSI_DISK15_MAJOR 135
+
+#define UNIX98_PTY_MASTER_MAJOR 128
+#define UNIX98_PTY_MAJOR_COUNT 8
+#define UNIX98_PTY_SLAVE_MAJOR (UNIX98_PTY_MASTER_MAJOR+UNIX98_PTY_MAJOR_COUNT)
+
+#define RTF_MAJOR 150
+#define RAW_MAJOR 162
+
+#define USB_ACM_MAJOR 166
+#define USB_ACM_AUX_MAJOR 167
+#define USB_CHAR_MAJOR 180
+
+#define VXVM_MAJOR 199  
+#define VXSPEC_MAJOR 200  
+#define VXDMP_MAJOR 201  
+
+#define MSR_MAJOR 202
+#define CPUID_MAJOR 203
+
+#define OSST_MAJOR 206  
+
+#define IBM_TTY3270_MAJOR 227
+#define IBM_FS3270_MAJOR 228
+
+#define VIOTAPE_MAJOR 230
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mc146818rtc.h b/ndk/build/platforms/android-1.5/common/include/linux/mc146818rtc.h
new file mode 100644
index 0000000..74436ea
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mc146818rtc.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _MC146818RTC_H
+#define _MC146818RTC_H
+
+#include <asm/io.h>
+#include <linux/rtc.h>  
+#include <asm/mc146818rtc.h>  
+
+#define RTC_SECONDS 0
+#define RTC_SECONDS_ALARM 1
+#define RTC_MINUTES 2
+#define RTC_MINUTES_ALARM 3
+#define RTC_HOURS 4
+#define RTC_HOURS_ALARM 5
+
+#define RTC_ALARM_DONT_CARE 0xC0
+
+#define RTC_DAY_OF_WEEK 6
+#define RTC_DAY_OF_MONTH 7
+#define RTC_MONTH 8
+#define RTC_YEAR 9
+
+#define RTC_REG_A 10
+#define RTC_REG_B 11
+#define RTC_REG_C 12
+#define RTC_REG_D 13
+
+#define RTC_FREQ_SELECT RTC_REG_A
+
+#define RTC_UIP 0x80
+#define RTC_DIV_CTL 0x70
+
+#define RTC_REF_CLCK_4MHZ 0x00
+#define RTC_REF_CLCK_1MHZ 0x10
+#define RTC_REF_CLCK_32KHZ 0x20
+
+#define RTC_DIV_RESET1 0x60
+#define RTC_DIV_RESET2 0x70
+
+#define RTC_RATE_SELECT 0x0F
+
+#define RTC_CONTROL RTC_REG_B
+#define RTC_SET 0x80  
+#define RTC_PIE 0x40  
+#define RTC_AIE 0x20  
+#define RTC_UIE 0x10  
+#define RTC_SQWE 0x08  
+#define RTC_DM_BINARY 0x04  
+#define RTC_24H 0x02  
+#define RTC_DST_EN 0x01  
+
+#define RTC_INTR_FLAGS RTC_REG_C
+
+#define RTC_IRQF 0x80  
+#define RTC_PF 0x40
+#define RTC_AF 0x20
+#define RTC_UF 0x10
+
+#define RTC_VALID RTC_REG_D
+#define RTC_VRT 0x80  
+
+#ifndef ARCH_RTC_LOCATION
+
+#define RTC_IO_EXTENT 0x8
+#define RTC_IOMAPPED 1  
+
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mca.h b/ndk/build/platforms/android-1.5/common/include/linux/mca.h
new file mode 100644
index 0000000..dfbfc2a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mca.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_MCA_H
+#define _LINUX_MCA_H
+
+#include <linux/device.h>
+
+#define MCA_bus 0
+
+typedef int (*MCA_ProcFn)(char* buf, int slot, void* dev);
+
+enum MCA_AdapterStatus {
+ MCA_ADAPTER_NORMAL = 0,
+ MCA_ADAPTER_NONE = 1,
+ MCA_ADAPTER_DISABLED = 2,
+ MCA_ADAPTER_ERROR = 3
+};
+
+struct mca_device {
+ u64 dma_mask;
+ int pos_id;
+ int slot;
+
+ int index;
+
+ int driver_loaded;
+
+ unsigned char pos[8];
+
+ short pos_register;
+
+ enum MCA_AdapterStatus status;
+ struct device dev;
+ char name[32];
+};
+#define to_mca_device(mdev) container_of(mdev, struct mca_device, dev)
+
+struct mca_bus_accessor_functions {
+ unsigned char (*mca_read_pos)(struct mca_device *, int reg);
+ void (*mca_write_pos)(struct mca_device *, int reg,
+ unsigned char byte);
+ int (*mca_transform_irq)(struct mca_device *, int irq);
+ int (*mca_transform_ioport)(struct mca_device *,
+ int region);
+ void * (*mca_transform_memory)(struct mca_device *,
+ void *memory);
+};
+
+struct mca_bus {
+ u64 default_dma_mask;
+ int number;
+ struct mca_bus_accessor_functions f;
+ struct device dev;
+ char name[32];
+};
+#define to_mca_bus(mdev) container_of(mdev, struct mca_bus, dev)
+
+struct mca_driver {
+ const short *id_table;
+ void *driver_data;
+ struct device_driver driver;
+};
+#define to_mca_driver(mdriver) container_of(mdriver, struct mca_driver, driver)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mempolicy.h b/ndk/build/platforms/android-1.5/common/include/linux/mempolicy.h
new file mode 100644
index 0000000..6b7b2d4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mempolicy.h
@@ -0,0 +1,32 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_MEMPOLICY_H
+#define _LINUX_MEMPOLICY_H 1
+
+#include <linux/errno.h>
+
+#define MPOL_DEFAULT 0
+#define MPOL_PREFERRED 1
+#define MPOL_BIND 2
+#define MPOL_INTERLEAVE 3
+
+#define MPOL_MAX MPOL_INTERLEAVE
+
+#define MPOL_F_NODE (1<<0)  
+#define MPOL_F_ADDR (1<<1)  
+
+#define MPOL_MF_STRICT (1<<0)  
+#define MPOL_MF_MOVE (1<<1)  
+#define MPOL_MF_MOVE_ALL (1<<2)  
+#define MPOL_MF_INTERNAL (1<<3)  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mempool.h b/ndk/build/platforms/android-1.5/common/include/linux/mempool.h
new file mode 100644
index 0000000..fa2432b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mempool.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_MEMPOOL_H
+#define _LINUX_MEMPOOL_H
+
+#include <linux/wait.h>
+
+struct kmem_cache;
+
+typedef void * (mempool_alloc_t)(gfp_t gfp_mask, void *pool_data);
+typedef void (mempool_free_t)(void *element, void *pool_data);
+
+typedef struct mempool_s {
+ spinlock_t lock;
+ int min_nr;
+ int curr_nr;
+ void **elements;
+
+ void *pool_data;
+ mempool_alloc_t *alloc;
+ mempool_free_t *free;
+ wait_queue_head_t wait;
+} mempool_t;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/miscdevice.h b/ndk/build/platforms/android-1.5/common/include/linux/miscdevice.h
new file mode 100644
index 0000000..457960a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/miscdevice.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_MISCDEVICE_H
+#define _LINUX_MISCDEVICE_H
+#include <linux/module.h>
+#include <linux/major.h>
+
+#define PSMOUSE_MINOR 1
+#define MS_BUSMOUSE_MINOR 2
+#define ATIXL_BUSMOUSE_MINOR 3
+
+#define ATARIMOUSE_MINOR 5
+#define SUN_MOUSE_MINOR 6
+#define APOLLO_MOUSE_MINOR 7
+#define PC110PAD_MINOR 9
+
+#define WATCHDOG_MINOR 130  
+#define TEMP_MINOR 131  
+#define RTC_MINOR 135
+#define EFI_RTC_MINOR 136  
+#define SUN_OPENPROM_MINOR 139
+#define DMAPI_MINOR 140  
+#define NVRAM_MINOR 144
+#define SGI_MMTIMER 153
+#define STORE_QUEUE_MINOR 155
+#define I2O_MINOR 166
+#define MICROCODE_MINOR 184
+#define MWAVE_MINOR 219  
+#define MPT_MINOR 220
+#define MISC_DYNAMIC_MINOR 255
+
+#define TUN_MINOR 200
+#define HPET_MINOR 228
+
+struct device;
+struct class_device;
+
+struct miscdevice {
+ int minor;
+ const char *name;
+ const struct file_operations *fops;
+ struct list_head list;
+ struct device *dev;
+ struct class_device *class;
+};
+
+#define MODULE_ALIAS_MISCDEV(minor)   MODULE_ALIAS("char-major-" __stringify(MISC_MAJOR)   "-" __stringify(minor))
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mm.h b/ndk/build/platforms/android-1.5/common/include/linux/mm.h
new file mode 100644
index 0000000..fea293b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mm.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_MM_H
+#define _LINUX_MM_H
+
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/capability.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mmc/card.h b/ndk/build/platforms/android-1.5/common/include/linux/mmc/card.h
new file mode 100644
index 0000000..94afe21
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mmc/card.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_MMC_CARD_H
+#define LINUX_MMC_CARD_H
+
+#include <linux/mmc/mmc.h>
+
+struct mmc_cid {
+ unsigned int manfid;
+ char prod_name[8];
+ unsigned int serial;
+ unsigned short oemid;
+ unsigned short year;
+ unsigned char hwrev;
+ unsigned char fwrev;
+ unsigned char month;
+};
+
+struct mmc_csd {
+ unsigned char mmca_vsn;
+ unsigned short cmdclass;
+ unsigned short tacc_clks;
+ unsigned int tacc_ns;
+ unsigned int r2w_factor;
+ unsigned int max_dtr;
+ unsigned int read_blkbits;
+ unsigned int write_blkbits;
+ unsigned int capacity;
+ unsigned int read_partial:1,
+ read_misalign:1,
+ write_partial:1,
+ write_misalign:1;
+};
+
+struct sd_scr {
+ unsigned char sda_vsn;
+ unsigned char bus_widths;
+#define SD_SCR_BUS_WIDTH_1 (1<<0)
+#define SD_SCR_BUS_WIDTH_4 (1<<2)
+};
+
+struct mmc_host;
+
+struct mmc_card {
+ struct list_head node;
+ struct mmc_host *host;
+ struct device dev;
+ unsigned int rca;
+ unsigned int state;
+#define MMC_STATE_PRESENT (1<<0)  
+#define MMC_STATE_DEAD (1<<1)  
+#define MMC_STATE_BAD (1<<2)  
+#define MMC_STATE_SDCARD (1<<3)  
+#define MMC_STATE_READONLY (1<<4)  
+ u32 raw_cid[4];
+ u32 raw_csd[4];
+ u32 raw_scr[2];
+ struct mmc_cid cid;
+ struct mmc_csd csd;
+ struct sd_scr scr;
+};
+
+#define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT)
+#define mmc_card_dead(c) ((c)->state & MMC_STATE_DEAD)
+#define mmc_card_bad(c) ((c)->state & MMC_STATE_BAD)
+#define mmc_card_sd(c) ((c)->state & MMC_STATE_SDCARD)
+#define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY)
+
+#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
+#define mmc_card_set_dead(c) ((c)->state |= MMC_STATE_DEAD)
+#define mmc_card_set_bad(c) ((c)->state |= MMC_STATE_BAD)
+#define mmc_card_set_sd(c) ((c)->state |= MMC_STATE_SDCARD)
+#define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
+
+#define mmc_card_name(c) ((c)->cid.prod_name)
+#define mmc_card_id(c) ((c)->dev.bus_id)
+
+#define mmc_list_to_card(l) container_of(l, struct mmc_card, node)
+#define mmc_get_drvdata(c) dev_get_drvdata(&(c)->dev)
+#define mmc_set_drvdata(c,d) dev_set_drvdata(&(c)->dev, d)
+
+struct mmc_driver {
+ struct device_driver drv;
+ int (*probe)(struct mmc_card *);
+ void (*remove)(struct mmc_card *);
+ int (*suspend)(struct mmc_card *, pm_message_t);
+ int (*resume)(struct mmc_card *);
+};
+
+#define mmc_card_release_host(c) mmc_release_host((c)->host)
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mmc/host.h b/ndk/build/platforms/android-1.5/common/include/linux/mmc/host.h
new file mode 100644
index 0000000..9433626
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mmc/host.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_MMC_HOST_H
+#define LINUX_MMC_HOST_H
+
+#include <linux/mmc/mmc.h>
+
+struct mmc_ios {
+ unsigned int clock;
+ unsigned short vdd;
+
+#define MMC_VDD_150 0
+#define MMC_VDD_155 1
+#define MMC_VDD_160 2
+#define MMC_VDD_165 3
+#define MMC_VDD_170 4
+#define MMC_VDD_180 5
+#define MMC_VDD_190 6
+#define MMC_VDD_200 7
+#define MMC_VDD_210 8
+#define MMC_VDD_220 9
+#define MMC_VDD_230 10
+#define MMC_VDD_240 11
+#define MMC_VDD_250 12
+#define MMC_VDD_260 13
+#define MMC_VDD_270 14
+#define MMC_VDD_280 15
+#define MMC_VDD_290 16
+#define MMC_VDD_300 17
+#define MMC_VDD_310 18
+#define MMC_VDD_320 19
+#define MMC_VDD_330 20
+#define MMC_VDD_340 21
+#define MMC_VDD_350 22
+#define MMC_VDD_360 23
+
+ unsigned char bus_mode;
+
+#define MMC_BUSMODE_OPENDRAIN 1
+#define MMC_BUSMODE_PUSHPULL 2
+
+ unsigned char chip_select;
+
+#define MMC_CS_DONTCARE 0
+#define MMC_CS_HIGH 1
+#define MMC_CS_LOW 2
+
+ unsigned char power_mode;
+
+#define MMC_POWER_OFF 0
+#define MMC_POWER_UP 1
+#define MMC_POWER_ON 2
+
+ unsigned char bus_width;
+
+#define MMC_BUS_WIDTH_1 0
+#define MMC_BUS_WIDTH_4 2
+};
+
+struct mmc_host_ops {
+ void (*request)(struct mmc_host *host, struct mmc_request *req);
+ void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
+ int (*get_ro)(struct mmc_host *host);
+};
+
+struct mmc_card;
+struct device;
+
+struct mmc_host {
+ struct device *dev;
+ struct class_device class_dev;
+ int index;
+ const struct mmc_host_ops *ops;
+ unsigned int f_min;
+ unsigned int f_max;
+ u32 ocr_avail;
+
+ unsigned long caps;
+
+#define MMC_CAP_4_BIT_DATA (1 << 0)  
+
+ unsigned int max_seg_size;
+ unsigned short max_hw_segs;
+ unsigned short max_phys_segs;
+ unsigned short max_sectors;
+ unsigned short unused;
+
+ struct mmc_ios ios;
+ u32 ocr;
+
+ unsigned int mode;
+#define MMC_MODE_MMC 0
+#define MMC_MODE_SD 1
+
+ struct list_head cards;
+
+ wait_queue_head_t wq;
+ spinlock_t lock;
+ struct mmc_card *card_busy;
+ struct mmc_card *card_selected;
+
+ struct work_struct detect;
+
+ unsigned long private[0] ____cacheline_aligned;
+};
+
+#define mmc_dev(x) ((x)->dev)
+#define mmc_hostname(x) ((x)->class_dev.class_id)
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mmc/mmc.h b/ndk/build/platforms/android-1.5/common/include/linux/mmc/mmc.h
new file mode 100644
index 0000000..089714c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mmc/mmc.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef MMC_H
+#define MMC_H
+
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+
+struct request;
+struct mmc_data;
+struct mmc_request;
+
+struct mmc_command {
+ u32 opcode;
+ u32 arg;
+ u32 resp[4];
+ unsigned int flags;
+#define MMC_RSP_PRESENT (1 << 0)
+#define MMC_RSP_136 (1 << 1)  
+#define MMC_RSP_CRC (1 << 2)  
+#define MMC_RSP_BUSY (1 << 3)  
+#define MMC_RSP_OPCODE (1 << 4)  
+#define MMC_CMD_MASK (3 << 5)  
+#define MMC_CMD_AC (0 << 5)
+#define MMC_CMD_ADTC (1 << 5)
+#define MMC_CMD_BC (2 << 5)
+#define MMC_CMD_BCR (3 << 5)
+
+#define MMC_RSP_NONE (0)
+#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY)
+#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
+#define MMC_RSP_R3 (MMC_RSP_PRESENT)
+#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC)
+
+#define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE))
+
+#define mmc_cmd_type(cmd) ((cmd)->flags & MMC_CMD_MASK)
+
+ unsigned int retries;
+ unsigned int error;
+
+#define MMC_ERR_NONE 0
+#define MMC_ERR_TIMEOUT 1
+#define MMC_ERR_BADCRC 2
+#define MMC_ERR_FIFO 3
+#define MMC_ERR_FAILED 4
+#define MMC_ERR_INVALID 5
+
+ struct mmc_data *data;
+ struct mmc_request *mrq;
+};
+
+struct mmc_data {
+ unsigned int timeout_ns;
+ unsigned int timeout_clks;
+ unsigned int blksz_bits;
+ unsigned int blksz;
+ unsigned int blocks;
+ unsigned int error;
+ unsigned int flags;
+
+#define MMC_DATA_WRITE (1 << 8)
+#define MMC_DATA_READ (1 << 9)
+#define MMC_DATA_STREAM (1 << 10)
+#define MMC_DATA_MULTI (1 << 11)
+
+ unsigned int bytes_xfered;
+
+ struct mmc_command *stop;
+ struct mmc_request *mrq;
+
+ unsigned int sg_len;
+ struct scatterlist *sg;
+};
+
+struct mmc_request {
+ struct mmc_command *cmd;
+ struct mmc_data *data;
+ struct mmc_command *stop;
+
+ void *done_data;
+ void (*done)(struct mmc_request *);
+};
+
+struct mmc_host;
+struct mmc_card;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mmzone.h b/ndk/build/platforms/android-1.5/common/include/linux/mmzone.h
new file mode 100644
index 0000000..a81382e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mmzone.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_MMZONE_H
+#define _LINUX_MMZONE_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mod_devicetable.h b/ndk/build/platforms/android-1.5/common/include/linux/mod_devicetable.h
new file mode 100644
index 0000000..a3c1de8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mod_devicetable.h
@@ -0,0 +1,209 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_MOD_DEVICETABLE_H
+#define LINUX_MOD_DEVICETABLE_H
+
+#define PCI_ANY_ID (~0)
+
+struct pci_device_id {
+ __u32 vendor, device;
+ __u32 subvendor, subdevice;
+ __u32 class, class_mask;
+ kernel_ulong_t driver_data;
+};
+
+#define IEEE1394_MATCH_VENDOR_ID 0x0001
+#define IEEE1394_MATCH_MODEL_ID 0x0002
+#define IEEE1394_MATCH_SPECIFIER_ID 0x0004
+#define IEEE1394_MATCH_VERSION 0x0008
+
+struct ieee1394_device_id {
+ __u32 match_flags;
+ __u32 vendor_id;
+ __u32 model_id;
+ __u32 specifier_id;
+ __u32 version;
+ kernel_ulong_t driver_data
+ __attribute__((aligned(sizeof(kernel_ulong_t))));
+};
+
+struct usb_device_id {
+
+ __u16 match_flags;
+
+ __u16 idVendor;
+ __u16 idProduct;
+ __u16 bcdDevice_lo;
+ __u16 bcdDevice_hi;
+
+ __u8 bDeviceClass;
+ __u8 bDeviceSubClass;
+ __u8 bDeviceProtocol;
+
+ __u8 bInterfaceClass;
+ __u8 bInterfaceSubClass;
+ __u8 bInterfaceProtocol;
+
+ kernel_ulong_t driver_info;
+};
+
+#define USB_DEVICE_ID_MATCH_VENDOR 0x0001
+#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002
+#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004
+#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008
+#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010
+#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020
+#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040
+#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080
+#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100
+#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
+
+struct ccw_device_id {
+ __u16 match_flags;
+
+ __u16 cu_type;
+ __u16 dev_type;
+ __u8 cu_model;
+ __u8 dev_model;
+
+ kernel_ulong_t driver_info;
+};
+
+#define CCW_DEVICE_ID_MATCH_CU_TYPE 0x01
+#define CCW_DEVICE_ID_MATCH_CU_MODEL 0x02
+#define CCW_DEVICE_ID_MATCH_DEVICE_TYPE 0x04
+#define CCW_DEVICE_ID_MATCH_DEVICE_MODEL 0x08
+
+#define PNP_ID_LEN 8
+#define PNP_MAX_DEVICES 8
+
+struct pnp_device_id {
+ __u8 id[PNP_ID_LEN];
+ kernel_ulong_t driver_data;
+};
+
+struct pnp_card_device_id {
+ __u8 id[PNP_ID_LEN];
+ kernel_ulong_t driver_data;
+ struct {
+ __u8 id[PNP_ID_LEN];
+ } devs[PNP_MAX_DEVICES];
+};
+
+#define SERIO_ANY 0xff
+
+struct serio_device_id {
+ __u8 type;
+ __u8 extra;
+ __u8 id;
+ __u8 proto;
+};
+
+struct of_device_id
+{
+ char name[32];
+ char type[32];
+ char compatible[128];
+ kernel_ulong_t data;
+};
+
+struct vio_device_id {
+ char type[32];
+ char compat[32];
+};
+
+struct pcmcia_device_id {
+ __u16 match_flags;
+
+ __u16 manf_id;
+ __u16 card_id;
+
+ __u8 func_id;
+
+ __u8 function;
+
+ __u8 device_no;
+
+ __u32 prod_id_hash[4]
+ __attribute__((aligned(sizeof(__u32))));
+
+ kernel_ulong_t prod_id[4]
+ __attribute__((aligned(sizeof(kernel_ulong_t))));
+
+ kernel_ulong_t driver_info;
+ kernel_ulong_t cisfile;
+};
+
+#define PCMCIA_DEV_ID_MATCH_MANF_ID 0x0001
+#define PCMCIA_DEV_ID_MATCH_CARD_ID 0x0002
+#define PCMCIA_DEV_ID_MATCH_FUNC_ID 0x0004
+#define PCMCIA_DEV_ID_MATCH_FUNCTION 0x0008
+#define PCMCIA_DEV_ID_MATCH_PROD_ID1 0x0010
+#define PCMCIA_DEV_ID_MATCH_PROD_ID2 0x0020
+#define PCMCIA_DEV_ID_MATCH_PROD_ID3 0x0040
+#define PCMCIA_DEV_ID_MATCH_PROD_ID4 0x0080
+#define PCMCIA_DEV_ID_MATCH_DEVICE_NO 0x0100
+#define PCMCIA_DEV_ID_MATCH_FAKE_CIS 0x0200
+#define PCMCIA_DEV_ID_MATCH_ANONYMOUS 0x0400
+
+struct i2c_device_id {
+ __u16 id;
+};
+
+#define INPUT_DEVICE_ID_EV_MAX 0x1f
+#define INPUT_DEVICE_ID_KEY_MAX 0x1ff
+#define INPUT_DEVICE_ID_REL_MAX 0x0f
+#define INPUT_DEVICE_ID_ABS_MAX 0x3f
+#define INPUT_DEVICE_ID_MSC_MAX 0x07
+#define INPUT_DEVICE_ID_LED_MAX 0x0f
+#define INPUT_DEVICE_ID_SND_MAX 0x07
+#define INPUT_DEVICE_ID_FF_MAX 0x7f
+#define INPUT_DEVICE_ID_SW_MAX 0x0f
+
+#define INPUT_DEVICE_ID_MATCH_BUS 1
+#define INPUT_DEVICE_ID_MATCH_VENDOR 2
+#define INPUT_DEVICE_ID_MATCH_PRODUCT 4
+#define INPUT_DEVICE_ID_MATCH_VERSION 8
+
+#define INPUT_DEVICE_ID_MATCH_EVBIT 0x0010
+#define INPUT_DEVICE_ID_MATCH_KEYBIT 0x0020
+#define INPUT_DEVICE_ID_MATCH_RELBIT 0x0040
+#define INPUT_DEVICE_ID_MATCH_ABSBIT 0x0080
+#define INPUT_DEVICE_ID_MATCH_MSCIT 0x0100
+#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x0200
+#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x0400
+#define INPUT_DEVICE_ID_MATCH_FFBIT 0x0800
+#define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000
+
+struct input_device_id {
+
+ kernel_ulong_t flags;
+
+ __u16 bustype;
+ __u16 vendor;
+ __u16 product;
+ __u16 version;
+
+ kernel_ulong_t evbit[INPUT_DEVICE_ID_EV_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t keybit[INPUT_DEVICE_ID_KEY_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t relbit[INPUT_DEVICE_ID_REL_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t absbit[INPUT_DEVICE_ID_ABS_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t mscbit[INPUT_DEVICE_ID_MSC_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t ledbit[INPUT_DEVICE_ID_LED_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1];
+ kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1];
+
+ kernel_ulong_t driver_info;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/module.h b/ndk/build/platforms/android-1.5/common/include/linux/module.h
new file mode 100644
index 0000000..3c449c6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/module.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_MODULE_H
+#define _LINUX_MODULE_H
+
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/stat.h>
+#include <linux/compiler.h>
+#include <linux/cache.h>
+#include <linux/kmod.h>
+#include <linux/elf.h>
+#include <linux/stringify.h>
+#include <linux/kobject.h>
+#include <linux/moduleparam.h>
+#include <asm/local.h>
+
+#include <asm/module.h>
+
+#define MODULE_SUPPORTED_DEVICE(name)
+
+#ifndef MODULE_SYMBOL_PREFIX
+#define MODULE_SYMBOL_PREFIX ""
+#endif
+
+#define MODULE_NAME_LEN (64 - sizeof(unsigned long))
+
+struct kernel_symbol
+{
+ unsigned long value;
+ const char *name;
+};
+
+struct modversion_info
+{
+ unsigned long crc;
+ char name[MODULE_NAME_LEN];
+};
+
+struct module;
+
+struct module_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct module_attribute *, struct module *, char *);
+ ssize_t (*store)(struct module_attribute *, struct module *,
+ const char *, size_t count);
+ void (*setup)(struct module *, const char *);
+ int (*test)(struct module *);
+ void (*free)(struct module *);
+};
+
+struct module_kobject
+{
+ struct kobject kobj;
+ struct module *mod;
+};
+
+struct exception_table_entry;
+
+#ifdef MODULE
+#define MODULE_GENERIC_TABLE(gtype,name)  extern const struct gtype##_id __mod_##gtype##_table   __attribute__ ((unused, alias(__stringify(name))))
+
+#define THIS_MODULE (&__this_module)
+#else
+#define MODULE_GENERIC_TABLE(gtype,name)
+#define THIS_MODULE ((struct module *)0)
+#endif
+
+#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
+
+#define MODULE_ALIAS(_alias) MODULE_INFO(alias, _alias)
+
+#define MODULE_LICENSE(_license) MODULE_INFO(license, _license)
+
+#define MODULE_AUTHOR(_author) MODULE_INFO(author, _author)
+
+#define MODULE_DESCRIPTION(_description) MODULE_INFO(description, _description)
+
+#define MODULE_PARM_DESC(_parm, desc)   __MODULE_INFO(parm, _parm, #_parm ":" desc)
+
+#define MODULE_DEVICE_TABLE(type,name)   MODULE_GENERIC_TABLE(type##_device,name)
+
+#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
+
+struct notifier_block;
+
+#define EXPORT_SYMBOL(sym)
+#define EXPORT_SYMBOL_GPL(sym)
+#define EXPORT_SYMBOL_GPL_FUTURE(sym)
+#define EXPORT_UNUSED_SYMBOL(sym)
+#define EXPORT_UNUSED_SYMBOL_GPL(sym)
+
+#define symbol_get(x) ({ extern typeof(x) x __attribute__((weak)); &(x); })
+#define symbol_put(x) do { } while(0)
+#define symbol_put_addr(x) do { } while(0)
+#define module_name(mod) "kernel"
+#define __unsafe(mod)
+#define module_put_and_exit(code) do_exit(code)
+
+struct module;
+
+#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)
+#define __MODULE_STRING(x) __stringify(x)
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/moduleparam.h b/ndk/build/platforms/android-1.5/common/include/linux/moduleparam.h
new file mode 100644
index 0000000..b46ddd6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/moduleparam.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_MODULE_PARAMS_H
+#define _LINUX_MODULE_PARAMS_H
+
+#include <linux/init.h>
+#include <linux/stringify.h>
+#include <linux/kernel.h>
+
+#ifdef MODULE
+#define MODULE_PARAM_PREFIX  
+#else
+#define MODULE_PARAM_PREFIX KBUILD_MODNAME "."
+#endif
+
+#ifdef MODULE
+#define ___module_cat(a,b) __mod_ ## a ## b
+#define __module_cat(a,b) ___module_cat(a,b)
+#define __MODULE_INFO(tag, name, info)  static const char __module_cat(name,__LINE__)[]   __attribute_used__   __attribute__((section(".modinfo"),unused)) = __stringify(tag) "=" info
+#else
+#define __MODULE_INFO(tag, name, info)
+#endif
+#define __MODULE_PARM_TYPE(name, _type)   __MODULE_INFO(parmtype, name##type, #name ":" _type)
+
+struct kernel_param;
+
+typedef int (*param_set_fn)(const char *val, struct kernel_param *kp);
+
+typedef int (*param_get_fn)(char *buffer, struct kernel_param *kp);
+
+struct kernel_param {
+ const char *name;
+ unsigned int perm;
+ param_set_fn set;
+ param_get_fn get;
+ void *arg;
+};
+
+struct kparam_string {
+ unsigned int maxlen;
+ char *string;
+};
+
+struct kparam_array
+{
+ unsigned int max;
+ unsigned int *num;
+ param_set_fn set;
+ param_get_fn get;
+ unsigned int elemsize;
+ void *elem;
+};
+
+#define __module_param_call(prefix, name, set, get, arg, perm)   static char __param_str_##name[] = prefix #name;   static struct kernel_param const __param_##name   __attribute_used__   __attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *))))   = { __param_str_##name, perm, set, get, arg }
+
+#define module_param_call(name, set, get, arg, perm)   __module_param_call(MODULE_PARAM_PREFIX, name, set, get, arg, perm)
+
+#define module_param_named(name, value, type, perm)   param_check_##type(name, &(value));   module_param_call(name, param_set_##type, param_get_##type, &value, perm);   __MODULE_PARM_TYPE(name, #type)
+
+#define module_param(name, type, perm)   module_param_named(name, name, type, perm)
+
+#define module_param_string(name, string, len, perm)   static struct kparam_string __param_string_##name   = { len, string };   module_param_call(name, param_set_copystring, param_get_string,   &__param_string_##name, perm);   __MODULE_PARM_TYPE(name, "string")
+
+#define __param_check(name, p, type)   static inline type *__check_##name(void) { return(p); }
+
+#define param_check_byte(name, p) __param_check(name, p, unsigned char)
+
+#define param_check_short(name, p) __param_check(name, p, short)
+
+#define param_check_ushort(name, p) __param_check(name, p, unsigned short)
+
+#define param_check_int(name, p) __param_check(name, p, int)
+
+#define param_check_uint(name, p) __param_check(name, p, unsigned int)
+
+#define param_check_long(name, p) __param_check(name, p, long)
+
+#define param_check_ulong(name, p) __param_check(name, p, unsigned long)
+
+#define param_check_charp(name, p) __param_check(name, p, char *)
+
+#define param_check_bool(name, p) __param_check(name, p, int)
+
+#define param_check_invbool(name, p) __param_check(name, p, int)
+
+#define module_param_array_named(name, array, type, nump, perm)   static struct kparam_array __param_arr_##name   = { ARRAY_SIZE(array), nump, param_set_##type, param_get_##type,  sizeof(array[0]), array };   module_param_call(name, param_array_set, param_array_get,   &__param_arr_##name, perm);   __MODULE_PARM_TYPE(name, "array of " #type)
+
+#define module_param_array(name, type, nump, perm)   module_param_array_named(name, name, type, nump, perm)
+
+struct module;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mount.h b/ndk/build/platforms/android-1.5/common/include/linux/mount.h
new file mode 100644
index 0000000..ee476e0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mount.h
@@ -0,0 +1,14 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_MOUNT_H
+#define _LINUX_MOUNT_H
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/msdos_fs.h b/ndk/build/platforms/android-1.5/common/include/linux/msdos_fs.h
new file mode 100644
index 0000000..5a4eb0a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/msdos_fs.h
@@ -0,0 +1,180 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_MSDOS_FS_H
+#define _LINUX_MSDOS_FS_H
+
+#include <linux/magic.h>
+
+#include <asm/byteorder.h>
+
+#define SECTOR_SIZE 512  
+#define SECTOR_BITS 9  
+#define MSDOS_DPB (MSDOS_DPS)  
+#define MSDOS_DPB_BITS 4  
+#define MSDOS_DPS (SECTOR_SIZE / sizeof(struct msdos_dir_entry))
+#define MSDOS_DPS_BITS 4  
+#define CF_LE_W(v) le16_to_cpu(v)
+#define CF_LE_L(v) le32_to_cpu(v)
+#define CT_LE_W(v) cpu_to_le16(v)
+#define CT_LE_L(v) cpu_to_le32(v)
+
+#define MSDOS_ROOT_INO 1  
+#define MSDOS_DIR_BITS 5  
+
+#define FAT_MAX_DIR_ENTRIES (65536)
+#define FAT_MAX_DIR_SIZE (FAT_MAX_DIR_ENTRIES << MSDOS_DIR_BITS)
+
+#define ATTR_NONE 0  
+#define ATTR_RO 1  
+#define ATTR_HIDDEN 2  
+#define ATTR_SYS 4  
+#define ATTR_VOLUME 8  
+#define ATTR_DIR 16  
+#define ATTR_ARCH 32  
+
+#define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
+
+#define ATTR_EXT (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
+
+#define CASE_LOWER_BASE 8  
+#define CASE_LOWER_EXT 16  
+
+#define DELETED_FLAG 0xe5  
+#define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG)
+
+#define MSDOS_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)
+
+#define MSDOS_MKMODE(a, m) (m & (a & ATTR_RO ? S_IRUGO|S_IXUGO : S_IRWXUGO))
+
+#define MSDOS_NAME 11  
+#define MSDOS_LONGNAME 256  
+#define MSDOS_SLOTS 21  
+#define MSDOS_DOT ".          "  
+#define MSDOS_DOTDOT "..         "  
+
+#define FAT_VALID_MEDIA(x) ((0xF8 <= (x) && (x) <= 0xFF) || (x) == 0xF0)
+#define FAT_FIRST_ENT(s, x) ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 :   MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x))
+
+#define FAT_START_ENT 2
+
+#define MAX_FAT12 0xFF4
+#define MAX_FAT16 0xFFF4
+#define MAX_FAT32 0x0FFFFFF6
+#define MAX_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? MAX_FAT32 :   MSDOS_SB(s)->fat_bits == 16 ? MAX_FAT16 : MAX_FAT12)
+
+#define BAD_FAT12 0xFF7
+#define BAD_FAT16 0xFFF7
+#define BAD_FAT32 0x0FFFFFF7
+
+#define EOF_FAT12 0xFFF
+#define EOF_FAT16 0xFFFF
+#define EOF_FAT32 0x0FFFFFFF
+
+#define FAT_ENT_FREE (0)
+#define FAT_ENT_BAD (BAD_FAT32)
+#define FAT_ENT_EOF (EOF_FAT32)
+
+#define FAT_FSINFO_SIG1 0x41615252
+#define FAT_FSINFO_SIG2 0x61417272
+#define IS_FSINFO(x) (le32_to_cpu((x)->signature1) == FAT_FSINFO_SIG1   && le32_to_cpu((x)->signature2) == FAT_FSINFO_SIG2)
+
+#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
+#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
+
+#define FAT_IOCTL_GET_ATTRIBUTES _IOR('r', 0x10, __u32)
+#define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, __u32)
+#define VFAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x12, __u32)
+
+#define VFAT_SFN_DISPLAY_LOWER 0x0001  
+#define VFAT_SFN_DISPLAY_WIN95 0x0002  
+#define VFAT_SFN_DISPLAY_WINNT 0x0004  
+#define VFAT_SFN_CREATE_WIN95 0x0100  
+#define VFAT_SFN_CREATE_WINNT 0x0200  
+
+struct fat_boot_sector {
+ __u8 ignored[3];
+ __u8 system_id[8];
+ __u8 sector_size[2];
+ __u8 sec_per_clus;
+ __le16 reserved;
+ __u8 fats;
+ __u8 dir_entries[2];
+ __u8 sectors[2];
+ __u8 media;
+ __le16 fat_length;
+ __le16 secs_track;
+ __le16 heads;
+ __le32 hidden;
+ __le32 total_sect;
+
+ __le32 fat32_length;
+ __le16 flags;
+ __u8 version[2];
+ __le32 root_cluster;
+ __le16 info_sector;
+ __le16 backup_boot;
+ __le16 reserved2[6];
+};
+
+struct fat_boot_fsinfo {
+ __le32 signature1;
+ __le32 reserved1[120];
+ __le32 signature2;
+ __le32 free_clusters;
+ __le32 next_cluster;
+ __le32 reserved2[4];
+};
+
+struct fat_boot_bsx {
+ __u8 drive;
+ __u8 reserved1;
+ __u8 signature;
+ __u8 vol_id[4];
+ __u8 vol_label[11];
+ __u8 type[8];
+};
+#define FAT16_BSX_OFFSET 36  
+#define FAT32_BSX_OFFSET 64  
+
+struct msdos_dir_entry {
+ __u8 name[MSDOS_NAME];
+ __u8 attr;
+ __u8 lcase;
+ __u8 ctime_cs;
+ __le16 ctime;
+ __le16 cdate;
+ __le16 adate;
+ __le16 starthi;
+ __le16 time,date,start;
+ __le32 size;
+};
+
+struct msdos_dir_slot {
+ __u8 id;
+ __u8 name0_4[10];
+ __u8 attr;
+ __u8 reserved;
+ __u8 alias_checksum;
+ __u8 name5_10[12];
+ __le16 start;
+ __u8 name11_12[4];
+};
+
+struct fat_slot_info {
+ loff_t i_pos;
+ loff_t slot_off;
+ int nr_slots;
+ struct msdos_dir_entry *de;
+ struct buffer_head *bh;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/msg.h b/ndk/build/platforms/android-1.5/common/include/linux/msg.h
new file mode 100644
index 0000000..254f1e9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/msg.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_MSG_H
+#define _LINUX_MSG_H
+
+#include <linux/ipc.h>
+
+#define MSG_STAT 11
+#define MSG_INFO 12
+
+#define MSG_NOERROR 010000  
+#define MSG_EXCEPT 020000  
+
+struct msqid_ds {
+ struct ipc_perm msg_perm;
+ struct msg *msg_first;
+ struct msg *msg_last;
+ __kernel_time_t msg_stime;
+ __kernel_time_t msg_rtime;
+ __kernel_time_t msg_ctime;
+ unsigned long msg_lcbytes;
+ unsigned long msg_lqbytes;
+ unsigned short msg_cbytes;
+ unsigned short msg_qnum;
+ unsigned short msg_qbytes;
+ __kernel_ipc_pid_t msg_lspid;
+ __kernel_ipc_pid_t msg_lrpid;
+};
+
+#include <asm/msgbuf.h>
+
+struct msgbuf {
+ long mtype;
+ char mtext[1];
+};
+
+struct msginfo {
+ int msgpool;
+ int msgmap;
+ int msgmax;
+ int msgmnb;
+ int msgmni;
+ int msgssz;
+ int msgtql;
+ unsigned short msgseg;
+};
+
+#define MSGMNI 16    
+#define MSGMAX 8192    
+#define MSGMNB 16384    
+
+#define MSGPOOL (MSGMNI*MSGMNB/1024)  
+#define MSGTQL MSGMNB  
+#define MSGMAP MSGMNB  
+#define MSGSSZ 16  
+#define __MSGSEG ((MSGPOOL*1024)/ MSGSSZ)  
+#define MSGSEG (__MSGSEG <= 0xffff ? __MSGSEG : 0xffff)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/msm_adsp.h b/ndk/build/platforms/android-1.5/common/include/linux/msm_adsp.h
new file mode 100644
index 0000000..6f12707
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/msm_adsp.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_MSM_ADSP_H
+#define __LINUX_MSM_ADSP_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/sizes.h>
+
+#define ADSP_IOCTL_MAGIC 'q'
+
+struct adsp_command_t {
+ uint16_t queue;
+ uint32_t len;
+ uint8_t *data;
+};
+
+struct adsp_event_t {
+ uint16_t type;
+ uint32_t timeout_ms;
+ uint16_t msg_id;
+ uint16_t flags;
+ uint32_t len;
+ uint8_t *data;
+};
+
+struct adsp_pmem_info_t {
+ int fd;
+ void *vaddr;
+};
+
+#define ADSP_IOCTL_ENABLE   _IOR(ADSP_IOCTL_MAGIC, 1, unsigned)
+
+#define ADSP_IOCTL_DISABLE   _IOR(ADSP_IOCTL_MAGIC, 2, unsigned)
+
+#define ADSP_IOCTL_DISABLE_ACK   _IOR(ADSP_IOCTL_MAGIC, 3, unsigned)
+
+#define ADSP_IOCTL_WRITE_COMMAND   _IOR(ADSP_IOCTL_MAGIC, 4, struct adsp_command_t *)
+
+#define ADSP_IOCTL_GET_EVENT   _IOWR(ADSP_IOCTL_MAGIC, 5, struct adsp_event_data_t *)
+
+#define ADSP_IOCTL_DISABLE_EVENT_RSP   _IOR(ADSP_IOCTL_MAGIC, 10, unsigned)
+
+#define ADSP_IOCTL_REGISTER_PMEM   _IOW(ADSP_IOCTL_MAGIC, 13, struct adsp_pmem_info *)
+
+#define ADSP_IOCTL_ABORT_EVENT_READ   _IOW(ADSP_IOCTL_MAGIC, 15, unsigned)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/msm_audio.h b/ndk/build/platforms/android-1.5/common/include/linux/msm_audio.h
new file mode 100644
index 0000000..9ac58aa
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/msm_audio.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_MSM_AUDIO_H
+#define __LINUX_MSM_AUDIO_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/sizes.h>
+
+#define AUDIO_IOCTL_MAGIC 'a'
+
+#define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned)
+#define AUDIO_STOP _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned)
+#define AUDIO_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned)
+#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned)
+#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned)
+#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned)
+#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned)
+#define AUDIO_SET_ADRC _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned)
+#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned)
+#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned)
+#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned)
+#define AUDIO_ENABLE_AUDPRE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned)
+#define AUDIO_SET_AGC _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned)
+#define AUDIO_SET_NS _IOW(AUDIO_IOCTL_MAGIC, 13, unsigned)
+#define AUDIO_SET_TX_IIR _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned)
+
+struct msm_audio_config {
+ uint32_t buffer_size;
+ uint32_t buffer_count;
+ uint32_t channel_count;
+ uint32_t sample_rate;
+ uint32_t type;
+ uint32_t unused[3];
+};
+
+struct msm_audio_stats {
+ uint32_t byte_count;
+ uint32_t sample_count;
+ uint32_t unused[2];
+};
+
+#define SND_IOCTL_MAGIC 's'
+
+#define SND_MUTE_UNMUTED 0
+#define SND_MUTE_MUTED 1
+
+struct msm_snd_device_config {
+ uint32_t device;
+ uint32_t ear_mute;
+ uint32_t mic_mute;
+};
+
+#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *)
+
+#define SND_METHOD_VOICE 0
+
+struct msm_snd_volume_config {
+ uint32_t device;
+ uint32_t method;
+ uint32_t volume;
+};
+
+#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *)
+
+#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)
+
+struct msm_snd_endpoint {
+ int id;
+ char name[64];
+};
+
+#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_snd_endpoint *)
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/msm_mdp.h b/ndk/build/platforms/android-1.5/common/include/linux/msm_mdp.h
new file mode 100644
index 0000000..43fdac3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/msm_mdp.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _MSM_MDP_H_
+#define _MSM_MDP_H_
+
+#include <linux/types.h>
+
+#define MSMFB_IOCTL_MAGIC 'm'
+#define MSMFB_GRP_DISP _IOW(MSMFB_IOCTL_MAGIC, 1, unsigned int)
+#define MSMFB_BLIT _IOW(MSMFB_IOCTL_MAGIC, 2, unsigned int)
+
+enum {
+ MDP_RGB_565,
+ MDP_XRGB_8888,
+ MDP_Y_CBCR_H2V2,
+ MDP_ARGB_8888,
+ MDP_RGB_888,
+ MDP_Y_CRCB_H2V2,
+ MDP_YCRYCB_H2V1,
+ MDP_Y_CRCB_H2V1,
+ MDP_Y_CBCR_H2V1,
+ MDP_RGBA_8888,
+ MDP_BGRA_8888,
+ MDP_IMGTYPE_LIMIT
+};
+
+enum {
+ PMEM_IMG,
+ FB_IMG,
+};
+
+#define MDP_ROT_NOP 0
+#define MDP_FLIP_LR 0x1
+#define MDP_FLIP_UD 0x2
+#define MDP_ROT_90 0x4
+#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR)
+#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR)
+#define MDP_DITHER 0x8
+#define MDP_BLUR 0x10
+
+#define MDP_TRANSP_NOP 0xffffffff
+#define MDP_ALPHA_NOP 0xff
+
+struct mdp_rect {
+ uint32_t x;
+ uint32_t y;
+ uint32_t w;
+ uint32_t h;
+};
+
+struct mdp_img {
+ uint32_t width;
+ uint32_t height;
+ uint32_t format;
+ uint32_t offset;
+ int memory_id;
+};
+
+struct mdp_blit_req {
+ struct mdp_img src;
+ struct mdp_img dst;
+ struct mdp_rect src_rect;
+ struct mdp_rect dst_rect;
+ uint32_t alpha;
+ uint32_t transp_mask;
+ uint32_t flags;
+};
+
+struct mdp_blit_req_list {
+ uint32_t count;
+ struct mdp_blit_req req[];
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mt9t013.h b/ndk/build/platforms/android-1.5/common/include/linux/mt9t013.h
new file mode 100644
index 0000000..821ef21
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mt9t013.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef CAMERA_MT9T013_H
+#define CAMERA_MT9T013_H
+#include <linux/cdev.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/sizes.h>
+
+#define MT9T013_I2C_IOCTL_MAGIC 'm'
+
+#define MT9T013_I2C_IOCTL_W   _IOW(MT9T013_I2C_IOCTL_MAGIC, 0, unsigned)
+
+#define MT9T013_I2C_IOCTL_R   _IOR(MT9T013_I2C_IOCTL_MAGIC, 1, unsigned)
+
+#define MT9T013_I2C_IOCTL_AF_W   _IOW(MT9T013_I2C_IOCTL_MAGIC, 2, unsigned)
+
+#define MT9T013_I2C_IOCTL_CAMIF_PAD_REG_RESET   _IO(MT9T013_I2C_IOCTL_MAGIC, 3)
+
+#define MT9T013_I2C_IOCTL_CAMIF_PAD_REG_RESET_2   _IO(MT9T013_I2C_IOCTL_MAGIC, 4)
+
+#define CAMERA_CONFIGURE_GPIOS   _IO(MT9T013_I2C_IOCTL_MAGIC, 7)
+
+#define CAMERA_UNCONFIGURE_GPIOS   _IO(MT9T013_I2C_IOCTL_MAGIC, 8)
+
+#define CAMERA_LENS_POWER_ON   _IO(MT9T013_I2C_IOCTL_MAGIC, 9)
+
+#define CAMERA_LENS_POWER_OFF   _IO(MT9T013_I2C_IOCTL_MAGIC, 10)
+
+#define MT9T013_I2C_IOCTL_CAMIF_APPS_RESET   _IO(MT9T013_I2C_IOCTL_MAGIC, 11)
+
+#define CAMIO_VFE_MDC_CLK 1  
+#define CAMIO_MDC_CLK 2  
+#define CAMIO_VFE_CLK 3  
+
+#define MT9T013_I2C_IOCTL_CLK_ENABLE   _IOW(MT9T013_I2C_IOCTL_MAGIC, 12, unsigned)
+
+#define MT9T013_I2C_IOCTL_CLK_DISABLE   _IOW(MT9T013_I2C_IOCTL_MAGIC, 13, unsigned)
+
+#define MT9T013_I2C_IOCTL_CLK_SELECT   _IOW(MT9T013_I2C_IOCTL_MAGIC, 14, unsigned)
+
+#define MT9T013_I2C_IOCTL_CLK_FREQ_PROG   _IOW(MT9T013_I2C_IOCTL_MAGIC, 15, unsigned)
+
+#define CAMSENSOR_REG_INIT 0<<0
+#define CAMSENSOR_REG_UPDATE_PERIODIC 1<<0
+#define CAMSENSOR_TYPE_PREVIEW 0<<1
+#define CAMSENSOR_TYPE_SNAPSHOT 1<<1
+
+#define MT9T013_I2C_IOCTL_SENSOR_SETTING   _IOW(MT9T013_I2C_IOCTL_MAGIC, 16, uint32_t)
+
+struct mt9t013_reg_struct
+{
+ uint16_t vt_pix_clk_div;
+ uint16_t vt_sys_clk_div;
+ uint16_t pre_pll_clk_div;
+ uint16_t pll_multiplier;
+ uint16_t op_pix_clk_div;
+ uint16_t op_sys_clk_div;
+ uint16_t scale_m;
+ uint16_t row_speed;
+ uint16_t x_addr_start;
+ uint16_t x_addr_end;
+ uint16_t y_addr_start;
+ uint16_t y_addr_end;
+ uint16_t read_mode;
+ uint16_t x_output_size ;
+ uint16_t y_output_size;
+ uint16_t line_length_pck;
+ uint16_t frame_length_lines;
+ uint16_t coarse_integration_time;
+ uint16_t fine_integration_time;
+};
+
+struct mt9t013_reg_pat {
+ struct mt9t013_reg_struct reg[2];
+};
+
+#define MT9T013_I2C_IOCTL_GET_REGISTERS   _IOR(MT9T013_I2C_IOCTL_MAGIC, 17, struct mt9t013_reg_pat *)
+
+struct mt9t013_exposure_gain {
+ uint16_t gain;
+ uint16_t line;
+ uint32_t mode;
+};
+
+#define MT9T013_I2C_IOCTL_EXPOSURE_GAIN   _IOW(MT9T013_I2C_IOCTL_MAGIC, 18, struct exposure_gain *)
+
+#define MT9T013_I2C_IOCTL_MOVE_FOCUS   _IOW(MT9T013_I2C_IOCTL_MAGIC, 19, uint32_t)
+
+#define MT9T013_I2C_IOCTL_SET_DEFAULT_FOCUS   _IOW(MT9T013_I2C_IOCTL_MAGIC, 20, uint32_t)
+
+#define MT9T013_I2C_IOCTL_POWER_DOWN   _IO(MT9T013_I2C_IOCTL_MAGIC, 21)
+
+struct mt9t013_init {
+ int preview;
+ uint16_t chipid;
+};
+
+#define MT9T013_I2C_IOCTL_INIT   _IOWR(MT9T013_I2C_IOCTL_MAGIC, 22, struct mt9t013_init *)
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mtd/bbm.h b/ndk/build/platforms/android-1.5/common/include/linux/mtd/bbm.h
new file mode 100644
index 0000000..e311b23
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mtd/bbm.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_MTD_BBM_H
+#define __LINUX_MTD_BBM_H
+
+#define NAND_MAX_CHIPS 8
+
+struct nand_bbt_descr {
+ int options;
+ int pages[NAND_MAX_CHIPS];
+ int offs;
+ int veroffs;
+ uint8_t version[NAND_MAX_CHIPS];
+ int len;
+ int maxblocks;
+ int reserved_block_code;
+ uint8_t *pattern;
+};
+
+#define NAND_BBT_NRBITS_MSK 0x0000000F
+#define NAND_BBT_1BIT 0x00000001
+#define NAND_BBT_2BIT 0x00000002
+#define NAND_BBT_4BIT 0x00000004
+#define NAND_BBT_8BIT 0x00000008
+
+#define NAND_BBT_LASTBLOCK 0x00000010
+
+#define NAND_BBT_ABSPAGE 0x00000020
+
+#define NAND_BBT_SEARCH 0x00000040
+
+#define NAND_BBT_PERCHIP 0x00000080
+
+#define NAND_BBT_VERSION 0x00000100
+
+#define NAND_BBT_CREATE 0x00000200
+
+#define NAND_BBT_SCANALLPAGES 0x00000400
+
+#define NAND_BBT_SCANEMPTY 0x00000800
+
+#define NAND_BBT_WRITE 0x00001000
+
+#define NAND_BBT_SAVECONTENT 0x00002000
+
+#define NAND_BBT_SCAN2NDPAGE 0x00004000
+
+#define NAND_BBT_SCAN_MAXBLOCKS 4
+
+#define ONENAND_BADBLOCK_POS 0
+
+struct bbm_info {
+ int bbt_erase_shift;
+ int badblockpos;
+ int options;
+
+ uint8_t *bbt;
+
+ int (*isbad_bbt)(struct mtd_info *mtd, loff_t ofs, int allowbbt);
+
+ struct nand_bbt_descr *badblock_pattern;
+
+ void *priv;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mtd/blktrans.h b/ndk/build/platforms/android-1.5/common/include/linux/mtd/blktrans.h
new file mode 100644
index 0000000..7c40724
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mtd/blktrans.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __MTD_TRANS_H__
+#define __MTD_TRANS_H__
+
+#include <linux/mutex.h>
+
+struct hd_geometry;
+struct mtd_info;
+struct mtd_blktrans_ops;
+struct file;
+struct inode;
+
+struct mtd_blktrans_dev {
+ struct mtd_blktrans_ops *tr;
+ struct list_head list;
+ struct mtd_info *mtd;
+ struct mutex lock;
+ int devnum;
+ int blksize;
+ unsigned long size;
+ int readonly;
+ void *blkcore_priv;
+};
+
+struct blkcore_priv;
+
+struct mtd_blktrans_ops {
+ char *name;
+ int major;
+ int part_bits;
+
+ int (*readsect)(struct mtd_blktrans_dev *dev,
+ unsigned long block, char *buffer);
+ int (*writesect)(struct mtd_blktrans_dev *dev,
+ unsigned long block, char *buffer);
+
+ int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo);
+ int (*flush)(struct mtd_blktrans_dev *dev);
+
+ int (*open)(struct mtd_blktrans_dev *dev);
+ int (*release)(struct mtd_blktrans_dev *dev);
+
+ void (*add_mtd)(struct mtd_blktrans_ops *tr, struct mtd_info *mtd);
+ void (*remove_dev)(struct mtd_blktrans_dev *dev);
+
+ struct list_head devs;
+ struct list_head list;
+ struct module *owner;
+
+ struct mtd_blkcore_priv *blkcore_priv;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mtd/cfi.h b/ndk/build/platforms/android-1.5/common/include/linux/mtd/cfi.h
new file mode 100644
index 0000000..d7f1ba1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mtd/cfi.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __MTD_CFI_H__
+#define __MTD_CFI_H__
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/flashchip.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/cfi_endian.h>
+
+#define cfi_interleave_is_1(cfi) (0)
+
+#define cfi_interleave_is_2(cfi) (0)
+
+#define cfi_interleave_is_4(cfi) (0)
+
+#define cfi_interleave_is_8(cfi) (0)
+
+#define CFI_DEVICETYPE_X8 (8 / 8)
+#define CFI_DEVICETYPE_X16 (16 / 8)
+#define CFI_DEVICETYPE_X32 (32 / 8)
+#define CFI_DEVICETYPE_X64 (64 / 8)
+
+struct cfi_extquery {
+ uint8_t pri[3];
+ uint8_t MajorVersion;
+ uint8_t MinorVersion;
+} __attribute__((packed));
+
+struct cfi_pri_intelext {
+ uint8_t pri[3];
+ uint8_t MajorVersion;
+ uint8_t MinorVersion;
+ uint32_t FeatureSupport;
+ uint8_t SuspendCmdSupport;
+ uint16_t BlkStatusRegMask;
+ uint8_t VccOptimal;
+ uint8_t VppOptimal;
+ uint8_t NumProtectionFields;
+ uint16_t ProtRegAddr;
+ uint8_t FactProtRegSize;
+ uint8_t UserProtRegSize;
+ uint8_t extra[0];
+} __attribute__((packed));
+
+struct cfi_intelext_otpinfo {
+ uint32_t ProtRegAddr;
+ uint16_t FactGroups;
+ uint8_t FactProtRegSize;
+ uint16_t UserGroups;
+ uint8_t UserProtRegSize;
+} __attribute__((packed));
+
+struct cfi_intelext_blockinfo {
+ uint16_t NumIdentBlocks;
+ uint16_t BlockSize;
+ uint16_t MinBlockEraseCycles;
+ uint8_t BitsPerCell;
+ uint8_t BlockCap;
+} __attribute__((packed));
+
+struct cfi_intelext_regioninfo {
+ uint16_t NumIdentPartitions;
+ uint8_t NumOpAllowed;
+ uint8_t NumOpAllowedSimProgMode;
+ uint8_t NumOpAllowedSimEraMode;
+ uint8_t NumBlockTypes;
+ struct cfi_intelext_blockinfo BlockTypes[1];
+} __attribute__((packed));
+
+struct cfi_intelext_programming_regioninfo {
+ uint8_t ProgRegShift;
+ uint8_t Reserved1;
+ uint8_t ControlValid;
+ uint8_t Reserved2;
+ uint8_t ControlInvalid;
+ uint8_t Reserved3;
+} __attribute__((packed));
+
+struct cfi_pri_amdstd {
+ uint8_t pri[3];
+ uint8_t MajorVersion;
+ uint8_t MinorVersion;
+ uint8_t SiliconRevision;
+ uint8_t EraseSuspend;
+ uint8_t BlkProt;
+ uint8_t TmpBlkUnprotect;
+ uint8_t BlkProtUnprot;
+ uint8_t SimultaneousOps;
+ uint8_t BurstMode;
+ uint8_t PageMode;
+ uint8_t VppMin;
+ uint8_t VppMax;
+ uint8_t TopBottom;
+} __attribute__((packed));
+
+struct cfi_pri_atmel {
+ uint8_t pri[3];
+ uint8_t MajorVersion;
+ uint8_t MinorVersion;
+ uint8_t Features;
+ uint8_t BottomBoot;
+ uint8_t BurstMode;
+ uint8_t PageMode;
+} __attribute__((packed));
+
+struct cfi_pri_query {
+ uint8_t NumFields;
+ uint32_t ProtField[1];
+} __attribute__((packed));
+
+struct cfi_bri_query {
+ uint8_t PageModeReadCap;
+ uint8_t NumFields;
+ uint32_t ConfField[1];
+} __attribute__((packed));
+
+#define P_ID_NONE 0x0000
+#define P_ID_INTEL_EXT 0x0001
+#define P_ID_AMD_STD 0x0002
+#define P_ID_INTEL_STD 0x0003
+#define P_ID_AMD_EXT 0x0004
+#define P_ID_WINBOND 0x0006
+#define P_ID_ST_ADV 0x0020
+#define P_ID_MITSUBISHI_STD 0x0100
+#define P_ID_MITSUBISHI_EXT 0x0101
+#define P_ID_SST_PAGE 0x0102
+#define P_ID_INTEL_PERFORMANCE 0x0200
+#define P_ID_INTEL_DATA 0x0210
+#define P_ID_RESERVED 0xffff
+
+#define CFI_MODE_CFI 1
+#define CFI_MODE_JEDEC 0
+
+struct cfi_private {
+ uint16_t cmdset;
+ void *cmdset_priv;
+ int interleave;
+ int device_type;
+ int cfi_mode;
+ int addr_unlock1;
+ int addr_unlock2;
+ struct mtd_info *(*cmdset_setup)(struct map_info *);
+ struct cfi_ident *cfiq;
+ int mfr, id;
+ int numchips;
+ unsigned long chipshift;
+ const char *im_name;
+ struct flchip chips[0];
+};
+
+#if BITS_PER_LONG >= 64
+#endif
+#define CMD(x) cfi_build_cmd((x), map, cfi)
+#if BITS_PER_LONG >= 64
+#endif
+#define MERGESTATUS(x) cfi_merge_status((x), map, cfi)
+
+struct cfi_fixup {
+ uint16_t mfr;
+ uint16_t id;
+ void (*fixup)(struct mtd_info *mtd, void* param);
+ void* param;
+};
+
+#define CFI_MFR_ANY 0xffff
+#define CFI_ID_ANY 0xffff
+
+#define CFI_MFR_AMD 0x0001
+#define CFI_MFR_ATMEL 0x001F
+#define CFI_MFR_ST 0x0020  
+
+typedef int (*varsize_frob_t)(struct map_info *map, struct flchip *chip,
+ unsigned long adr, int len, void *thunk);
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mtd/cfi_endian.h b/ndk/build/platforms/android-1.5/common/include/linux/mtd/cfi_endian.h
new file mode 100644
index 0000000..452091e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mtd/cfi_endian.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm/byteorder.h>
+
+#define CFI_HOST_ENDIAN
+
+#ifdef CFI_LITTLE_ENDIAN
+#define cpu_to_cfi8(x) (x)
+#define cfi8_to_cpu(x) (x)
+#define cpu_to_cfi16(x) cpu_to_le16(x)
+#define cpu_to_cfi32(x) cpu_to_le32(x)
+#define cpu_to_cfi64(x) cpu_to_le64(x)
+#define cfi16_to_cpu(x) le16_to_cpu(x)
+#define cfi32_to_cpu(x) le32_to_cpu(x)
+#define cfi64_to_cpu(x) le64_to_cpu(x)
+#elif defined (CFI_BIG_ENDIAN)
+#define cpu_to_cfi8(x) (x)
+#define cfi8_to_cpu(x) (x)
+#define cpu_to_cfi16(x) cpu_to_be16(x)
+#define cpu_to_cfi32(x) cpu_to_be32(x)
+#define cpu_to_cfi64(x) cpu_to_be64(x)
+#define cfi16_to_cpu(x) be16_to_cpu(x)
+#define cfi32_to_cpu(x) be32_to_cpu(x)
+#define cfi64_to_cpu(x) be64_to_cpu(x)
+#elif defined (CFI_HOST_ENDIAN)
+#define cpu_to_cfi8(x) (x)
+#define cfi8_to_cpu(x) (x)
+#define cpu_to_cfi16(x) (x)
+#define cpu_to_cfi32(x) (x)
+#define cpu_to_cfi64(x) (x)
+#define cfi16_to_cpu(x) (x)
+#define cfi32_to_cpu(x) (x)
+#define cfi64_to_cpu(x) (x)
+#else
+#error No CFI endianness defined
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mtd/compatmac.h b/ndk/build/platforms/android-1.5/common/include/linux/mtd/compatmac.h
new file mode 100644
index 0000000..143f46a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mtd/compatmac.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_MTD_COMPATMAC_H__
+#define __LINUX_MTD_COMPATMAC_H__
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mtd/flashchip.h b/ndk/build/platforms/android-1.5/common/include/linux/mtd/flashchip.h
new file mode 100644
index 0000000..e441048
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mtd/flashchip.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __MTD_FLASHCHIP_H__
+#define __MTD_FLASHCHIP_H__
+
+#include <linux/sched.h>
+
+typedef enum {
+ FL_READY,
+ FL_STATUS,
+ FL_CFI_QUERY,
+ FL_JEDEC_QUERY,
+ FL_ERASING,
+ FL_ERASE_SUSPENDING,
+ FL_ERASE_SUSPENDED,
+ FL_WRITING,
+ FL_WRITING_TO_BUFFER,
+ FL_OTP_WRITE,
+ FL_WRITE_SUSPENDING,
+ FL_WRITE_SUSPENDED,
+ FL_PM_SUSPENDED,
+ FL_SYNCING,
+ FL_UNLOADING,
+ FL_LOCKING,
+ FL_UNLOCKING,
+ FL_POINT,
+ FL_XIP_WHILE_ERASING,
+ FL_XIP_WHILE_WRITING,
+ FL_UNKNOWN
+} flstate_t;
+
+struct flchip {
+ unsigned long start;
+
+ int ref_point_counter;
+ flstate_t state;
+ flstate_t oldstate;
+
+ unsigned int write_suspended:1;
+ unsigned int erase_suspended:1;
+ unsigned long in_progress_block_addr;
+
+ spinlock_t *mutex;
+ spinlock_t _spinlock;
+ wait_queue_head_t wq;
+ int word_write_time;
+ int buffer_write_time;
+ int erase_time;
+
+ void *priv;
+};
+
+struct flchip_shared {
+ spinlock_t lock;
+ struct flchip *writing;
+ struct flchip *erasing;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mtd/map.h b/ndk/build/platforms/android-1.5/common/include/linux/mtd/map.h
new file mode 100644
index 0000000..87124bc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mtd/map.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_MTD_MAP_H__
+#define __LINUX_MTD_MAP_H__
+
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/string.h>
+
+#include <linux/mtd/compatmac.h>
+
+#include <asm/unaligned.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+#define map_bankwidth_is_1(map) (0)
+
+#define map_bankwidth_is_2(map) (0)
+
+#define map_bankwidth_is_4(map) (0)
+
+#define map_calc_words(map) ((map_bankwidth(map) + (sizeof(unsigned long)-1))/ sizeof(unsigned long))
+
+#define map_bankwidth_is_8(map) (0)
+
+#define map_bankwidth_is_16(map) (0)
+
+#define map_bankwidth_is_32(map) (0)
+
+#ifndef map_bankwidth
+#error "No bus width supported. What's the point?"
+#endif
+
+#define MAX_MAP_LONGS ( ((MAX_MAP_BANKWIDTH*8) + BITS_PER_LONG - 1) / BITS_PER_LONG )
+
+struct map_info {
+ char *name;
+ unsigned long size;
+ unsigned long phys;
+#define NO_XIP (-1UL)
+
+ void __iomem *virt;
+ void *cached;
+
+ int bankwidth;
+
+ void (*inval_cache)(struct map_info *, unsigned long, ssize_t);
+
+ void (*set_vpp)(struct map_info *, int);
+
+ unsigned long map_priv_1;
+ unsigned long map_priv_2;
+ void *fldrv_priv;
+ struct mtd_chip_driver *fldrv;
+};
+
+struct mtd_chip_driver {
+ struct mtd_info *(*probe)(struct map_info *map);
+ void (*destroy)(struct mtd_info *);
+ struct module *module;
+ char *name;
+ struct list_head list;
+};
+
+struct mtd_info *do_map_probe(const char *name, struct map_info *map);
+
+#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
+#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)
+
+#define INVALIDATE_CACHED_RANGE(map, from, size)   do { if(map->inval_cache) map->inval_cache(map, from, size); } while(0)
+
+#define map_word_andequal(m, a, b, z) map_word_equal(m, z, map_word_and(m, a, b))
+#if BITS_PER_LONG >= 64
+#endif
+#ifdef __LITTLE_ENDIAN
+#else
+#endif
+#if BITS_PER_LONG < 64
+#define MAP_FF_LIMIT 4
+#else
+#define MAP_FF_LIMIT 8
+#endif
+#if BITS_PER_LONG >= 64
+#endif
+#if BITS_PER_LONG >= 64
+#endif
+#define map_read(map, ofs) inline_map_read(map, ofs)
+#define map_copy_from(map, to, from, len) inline_map_copy_from(map, to, from, len)
+#define map_write(map, datum, ofs) inline_map_write(map, datum, ofs)
+#define map_copy_to(map, to, from, len) inline_map_copy_to(map, to, from, len)
+#define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth))
+#define map_is_linear(map) ({ (void)(map); 1; })
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mtd/mtd.h b/ndk/build/platforms/android-1.5/common/include/linux/mtd/mtd.h
new file mode 100644
index 0000000..300813c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mtd/mtd.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __MTD_MTD_H__
+#define __MTD_MTD_H__
+
+#error This is a kernel header. Perhaps include mtd-user.h instead?
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/uio.h>
+#include <linux/notifier.h>
+
+#include <linux/mtd/compatmac.h>
+#include <mtd/mtd-abi.h>
+
+#define MTD_CHAR_MAJOR 90
+#define MTD_BLOCK_MAJOR 31
+#define MAX_MTD_DEVICES 16
+
+#define MTD_ERASE_PENDING 0x01
+#define MTD_ERASING 0x02
+#define MTD_ERASE_SUSPEND 0x04
+#define MTD_ERASE_DONE 0x08
+#define MTD_ERASE_FAILED 0x10
+
+struct erase_info {
+ struct mtd_info *mtd;
+ u_int32_t addr;
+ u_int32_t len;
+ u_int32_t fail_addr;
+ u_long time;
+ u_long retries;
+ u_int dev;
+ u_int cell;
+ void (*callback) (struct erase_info *self);
+ u_long priv;
+ u_char state;
+ struct erase_info *next;
+};
+
+struct mtd_erase_region_info {
+ u_int32_t offset;
+ u_int32_t erasesize;
+ u_int32_t numblocks;
+};
+
+typedef enum {
+ MTD_OOB_PLACE,
+ MTD_OOB_AUTO,
+ MTD_OOB_RAW,
+} mtd_oob_mode_t;
+
+struct mtd_oob_ops {
+ mtd_oob_mode_t mode;
+ size_t len;
+ size_t retlen;
+ size_t ooblen;
+ uint32_t ooboffs;
+ uint8_t *datbuf;
+ uint8_t *oobbuf;
+};
+
+struct mtd_info {
+ u_char type;
+ u_int32_t flags;
+ u_int32_t size;
+
+ u_int32_t erasesize;
+
+ u_int32_t writesize;
+
+ u_int32_t oobsize;
+ u_int32_t ecctype;
+ u_int32_t eccsize;
+
+#define MTD_PROGREGION_CTRLMODE_VALID(mtd) (mtd)->oobsize
+#define MTD_PROGREGION_CTRLMODE_INVALID(mtd) (mtd)->ecctype
+
+ char *name;
+ int index;
+
+ struct nand_ecclayout *ecclayout;
+
+ int numeraseregions;
+ struct mtd_erase_region_info *eraseregions;
+
+ u_int32_t bank_size;
+
+ int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
+
+ int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
+
+ void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len);
+
+ int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
+ int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
+
+ int (*read_oob) (struct mtd_info *mtd, loff_t from,
+ struct mtd_oob_ops *ops);
+ int (*write_oob) (struct mtd_info *mtd, loff_t to,
+ struct mtd_oob_ops *ops);
+
+ int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
+ int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
+ int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);
+ int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
+ int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
+ int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len);
+
+ int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
+
+ void (*sync) (struct mtd_info *mtd);
+
+ int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len);
+ int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len);
+
+ int (*suspend) (struct mtd_info *mtd);
+ void (*resume) (struct mtd_info *mtd);
+
+ int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);
+ int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
+
+ struct notifier_block reboot_notifier;
+
+ struct mtd_ecc_stats ecc_stats;
+
+ void *priv;
+
+ struct module *owner;
+ int usecount;
+};
+
+struct mtd_notifier {
+ void (*add)(struct mtd_info *mtd);
+ void (*remove)(struct mtd_info *mtd);
+ struct list_head list;
+};
+
+#define MTD_DEBUG_LEVEL0 (0)  
+#define MTD_DEBUG_LEVEL1 (1)  
+#define MTD_DEBUG_LEVEL2 (2)  
+#define MTD_DEBUG_LEVEL3 (3)  
+#define DEBUG(n, args...) do { } while(0)
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mtd/nand.h b/ndk/build/platforms/android-1.5/common/include/linux/mtd/nand.h
new file mode 100644
index 0000000..36e9fb4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mtd/nand.h
@@ -0,0 +1,319 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_MTD_NAND_H
+#define __LINUX_MTD_NAND_H
+
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/mtd/mtd.h>
+
+struct mtd_info;
+
+#define NAND_MAX_CHIPS 8
+
+#define NAND_MAX_OOBSIZE 64
+#define NAND_MAX_PAGESIZE 2048
+
+#define NAND_NCE 0x01
+
+#define NAND_CLE 0x02
+
+#define NAND_ALE 0x04
+
+#define NAND_CTRL_CLE (NAND_NCE | NAND_CLE)
+#define NAND_CTRL_ALE (NAND_NCE | NAND_ALE)
+#define NAND_CTRL_CHANGE 0x80
+
+#define NAND_CMD_READ0 0
+#define NAND_CMD_READ1 1
+#define NAND_CMD_RNDOUT 5
+#define NAND_CMD_PAGEPROG 0x10
+#define NAND_CMD_READOOB 0x50
+#define NAND_CMD_ERASE1 0x60
+#define NAND_CMD_STATUS 0x70
+#define NAND_CMD_STATUS_MULTI 0x71
+#define NAND_CMD_SEQIN 0x80
+#define NAND_CMD_RNDIN 0x85
+#define NAND_CMD_READID 0x90
+#define NAND_CMD_ERASE2 0xd0
+#define NAND_CMD_RESET 0xff
+
+#define NAND_CMD_READSTART 0x30
+#define NAND_CMD_RNDOUTSTART 0xE0
+#define NAND_CMD_CACHEDPROG 0x15
+
+#define NAND_CMD_DEPLETE1 0x100
+#define NAND_CMD_DEPLETE2 0x38
+#define NAND_CMD_STATUS_MULTI 0x71
+#define NAND_CMD_STATUS_ERROR 0x72
+
+#define NAND_CMD_STATUS_ERROR0 0x73
+#define NAND_CMD_STATUS_ERROR1 0x74
+#define NAND_CMD_STATUS_ERROR2 0x75
+#define NAND_CMD_STATUS_ERROR3 0x76
+#define NAND_CMD_STATUS_RESET 0x7f
+#define NAND_CMD_STATUS_CLEAR 0xff
+
+#define NAND_CMD_NONE -1
+
+#define NAND_STATUS_FAIL 0x01
+#define NAND_STATUS_FAIL_N1 0x02
+#define NAND_STATUS_TRUE_READY 0x20
+#define NAND_STATUS_READY 0x40
+#define NAND_STATUS_WP 0x80
+
+typedef enum {
+ NAND_ECC_NONE,
+ NAND_ECC_SOFT,
+ NAND_ECC_HW,
+ NAND_ECC_HW_SYNDROME,
+} nand_ecc_modes_t;
+
+#define NAND_ECC_READ 0
+
+#define NAND_ECC_WRITE 1
+
+#define NAND_ECC_READSYN 2
+
+#define NAND_GET_DEVICE 0x80
+
+#define NAND_NO_AUTOINCR 0x00000001
+
+#define NAND_BUSWIDTH_16 0x00000002
+
+#define NAND_NO_PADDING 0x00000004
+
+#define NAND_CACHEPRG 0x00000008
+
+#define NAND_COPYBACK 0x00000010
+
+#define NAND_IS_AND 0x00000020
+
+#define NAND_4PAGE_ARRAY 0x00000040
+
+#define BBT_AUTO_REFRESH 0x00000080
+
+#define NAND_NO_READRDY 0x00000100
+
+#define NAND_SAMSUNG_LP_OPTIONS   (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
+
+#define NAND_CANAUTOINCR(chip) (!(chip->options & NAND_NO_AUTOINCR))
+#define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING))
+#define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
+#define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK))
+
+#define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR)
+
+#define NAND_USE_FLASH_BBT 0x00010000
+
+#define NAND_SKIP_BBTSCAN 0x00020000
+
+#define NAND_CONTROLLER_ALLOC 0x80000000
+
+typedef enum {
+ FL_READY,
+ FL_READING,
+ FL_WRITING,
+ FL_ERASING,
+ FL_SYNCING,
+ FL_CACHEDPRG,
+ FL_PM_SUSPENDED,
+} nand_state_t;
+
+struct nand_chip;
+
+struct nand_hw_control {
+ spinlock_t lock;
+ struct nand_chip *active;
+ wait_queue_head_t wq;
+};
+
+struct nand_ecc_ctrl {
+ nand_ecc_modes_t mode;
+ int steps;
+ int size;
+ int bytes;
+ int total;
+ int prepad;
+ int postpad;
+ struct nand_ecclayout *layout;
+ void (*hwctl)(struct mtd_info *mtd, int mode);
+ int (*calculate)(struct mtd_info *mtd,
+ const uint8_t *dat,
+ uint8_t *ecc_code);
+ int (*correct)(struct mtd_info *mtd, uint8_t *dat,
+ uint8_t *read_ecc,
+ uint8_t *calc_ecc);
+ int (*read_page)(struct mtd_info *mtd,
+ struct nand_chip *chip,
+ uint8_t *buf);
+ void (*write_page)(struct mtd_info *mtd,
+ struct nand_chip *chip,
+ const uint8_t *buf);
+ int (*read_oob)(struct mtd_info *mtd,
+ struct nand_chip *chip,
+ int page,
+ int sndcmd);
+ int (*write_oob)(struct mtd_info *mtd,
+ struct nand_chip *chip,
+ int page);
+};
+
+struct nand_buffers {
+ uint8_t ecccalc[NAND_MAX_OOBSIZE];
+ uint8_t ecccode[NAND_MAX_OOBSIZE];
+ uint8_t oobwbuf[NAND_MAX_OOBSIZE];
+ uint8_t databuf[NAND_MAX_PAGESIZE];
+ uint8_t oobrbuf[NAND_MAX_OOBSIZE];
+};
+
+struct nand_chip {
+ void __iomem *IO_ADDR_R;
+ void __iomem *IO_ADDR_W;
+
+ uint8_t (*read_byte)(struct mtd_info *mtd);
+ u16 (*read_word)(struct mtd_info *mtd);
+ void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
+ void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
+ int (*verify_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
+ void (*select_chip)(struct mtd_info *mtd, int chip);
+ int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
+ int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
+ void (*cmd_ctrl)(struct mtd_info *mtd, int dat,
+ unsigned int ctrl);
+ int (*dev_ready)(struct mtd_info *mtd);
+ void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
+ int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
+ void (*erase_cmd)(struct mtd_info *mtd, int page);
+ int (*scan_bbt)(struct mtd_info *mtd);
+ int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
+
+ int chip_delay;
+ unsigned int options;
+
+ int page_shift;
+ int phys_erase_shift;
+ int bbt_erase_shift;
+ int chip_shift;
+ int numchips;
+ unsigned long chipsize;
+ int pagemask;
+ int pagebuf;
+ int badblockpos;
+
+ nand_state_t state;
+
+ uint8_t *oob_poi;
+ struct nand_hw_control *controller;
+ struct nand_ecclayout *ecclayout;
+
+ struct nand_ecc_ctrl ecc;
+ struct nand_buffers buffers;
+ struct nand_hw_control hwcontrol;
+
+ struct mtd_oob_ops ops;
+
+ uint8_t *bbt;
+ struct nand_bbt_descr *bbt_td;
+ struct nand_bbt_descr *bbt_md;
+
+ struct nand_bbt_descr *badblock_pattern;
+
+ void *priv;
+};
+
+#define NAND_MFR_TOSHIBA 0x98
+#define NAND_MFR_SAMSUNG 0xec
+#define NAND_MFR_FUJITSU 0x04
+#define NAND_MFR_NATIONAL 0x8f
+#define NAND_MFR_RENESAS 0x07
+#define NAND_MFR_STMICRO 0x20
+#define NAND_MFR_HYNIX 0xad
+
+struct nand_flash_dev {
+ char *name;
+ int id;
+ unsigned long pagesize;
+ unsigned long chipsize;
+ unsigned long erasesize;
+ unsigned long options;
+};
+
+struct nand_manufacturers {
+ int id;
+ char * name;
+};
+
+struct nand_bbt_descr {
+ int options;
+ int pages[NAND_MAX_CHIPS];
+ int offs;
+ int veroffs;
+ uint8_t version[NAND_MAX_CHIPS];
+ int len;
+ int maxblocks;
+ int reserved_block_code;
+ uint8_t *pattern;
+};
+
+#define NAND_BBT_NRBITS_MSK 0x0000000F
+#define NAND_BBT_1BIT 0x00000001
+#define NAND_BBT_2BIT 0x00000002
+#define NAND_BBT_4BIT 0x00000004
+#define NAND_BBT_8BIT 0x00000008
+
+#define NAND_BBT_LASTBLOCK 0x00000010
+
+#define NAND_BBT_ABSPAGE 0x00000020
+
+#define NAND_BBT_SEARCH 0x00000040
+
+#define NAND_BBT_PERCHIP 0x00000080
+
+#define NAND_BBT_VERSION 0x00000100
+
+#define NAND_BBT_CREATE 0x00000200
+
+#define NAND_BBT_SCANALLPAGES 0x00000400
+
+#define NAND_BBT_SCANEMPTY 0x00000800
+
+#define NAND_BBT_WRITE 0x00001000
+
+#define NAND_BBT_SAVECONTENT 0x00002000
+
+#define NAND_BBT_SCAN2NDPAGE 0x00004000
+
+#define NAND_BBT_SCAN_MAXBLOCKS 4
+
+#define NAND_SMALL_BADBLOCK_POS 5
+#define NAND_LARGE_BADBLOCK_POS 0
+
+struct platform_nand_chip {
+ int nr_chips;
+ int chip_offset;
+ int nr_partitions;
+ struct mtd_partition *partitions;
+ struct nand_ecclayout *ecclayout;
+ int chip_delay;
+ unsigned int options;
+ void *priv;
+};
+
+struct platform_nand_ctrl {
+ void (*hwcontrol)(struct mtd_info *mtd, int cmd);
+ int (*dev_ready)(struct mtd_info *mtd);
+ void (*select_chip)(struct mtd_info *mtd, int chip);
+ void *priv;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mtd/nand_ecc.h b/ndk/build/platforms/android-1.5/common/include/linux/mtd/nand_ecc.h
new file mode 100644
index 0000000..3e817f4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mtd/nand_ecc.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __MTD_NAND_ECC_H__
+#define __MTD_NAND_ECC_H__
+
+struct mtd_info;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mtd/nftl.h b/ndk/build/platforms/android-1.5/common/include/linux/mtd/nftl.h
new file mode 100644
index 0000000..da7320e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mtd/nftl.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __MTD_NFTL_H__
+#define __MTD_NFTL_H__
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/blktrans.h>
+
+#include <mtd/nftl-user.h>
+
+#define BLOCK_NIL 0xffff  
+#define BLOCK_FREE 0xfffe  
+#define BLOCK_NOTEXPLORED 0xfffd  
+#define BLOCK_RESERVED 0xfffc  
+
+struct NFTLrecord {
+ struct mtd_blktrans_dev mbd;
+ __u16 MediaUnit, SpareMediaUnit;
+ __u32 EraseSize;
+ struct NFTLMediaHeader MediaHdr;
+ int usecount;
+ unsigned char heads;
+ unsigned char sectors;
+ unsigned short cylinders;
+ __u16 numvunits;
+ __u16 lastEUN;
+ __u16 numfreeEUNs;
+ __u16 LastFreeEUN;
+ int head,sect,cyl;
+ __u16 *EUNtable;
+ __u16 *ReplUnitTable;
+ unsigned int nb_blocks;
+ unsigned int nb_boot_blocks;
+ struct erase_info instr;
+ struct nand_ecclayout oobinfo;
+};
+
+#ifndef NFTL_MAJOR
+#define NFTL_MAJOR 93
+#endif
+
+#define MAX_NFTLS 16
+#define MAX_SECTORS_PER_UNIT 64
+#define NFTL_PARTN_BITS 4
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mtd/onenand_regs.h b/ndk/build/platforms/android-1.5/common/include/linux/mtd/onenand_regs.h
new file mode 100644
index 0000000..a39c78f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mtd/onenand_regs.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __ONENAND_REG_H
+#define __ONENAND_REG_H
+
+#define ONENAND_MEMORY_MAP(x) ((x) << 1)
+
+#define ONENAND_BOOTRAM ONENAND_MEMORY_MAP(0x0000)
+#define ONENAND_DATARAM ONENAND_MEMORY_MAP(0x0200)
+#define ONENAND_SPARERAM ONENAND_MEMORY_MAP(0x8010)
+
+#define ONENAND_REG_MANUFACTURER_ID ONENAND_MEMORY_MAP(0xF000)
+#define ONENAND_REG_DEVICE_ID ONENAND_MEMORY_MAP(0xF001)
+#define ONENAND_REG_VERSION_ID ONENAND_MEMORY_MAP(0xF002)
+#define ONENAND_REG_DATA_BUFFER_SIZE ONENAND_MEMORY_MAP(0xF003)
+#define ONENAND_REG_BOOT_BUFFER_SIZE ONENAND_MEMORY_MAP(0xF004)
+#define ONENAND_REG_NUM_BUFFERS ONENAND_MEMORY_MAP(0xF005)
+#define ONENAND_REG_TECHNOLOGY ONENAND_MEMORY_MAP(0xF006)
+
+#define ONENAND_REG_START_ADDRESS1 ONENAND_MEMORY_MAP(0xF100)
+#define ONENAND_REG_START_ADDRESS2 ONENAND_MEMORY_MAP(0xF101)
+#define ONENAND_REG_START_ADDRESS3 ONENAND_MEMORY_MAP(0xF102)
+#define ONENAND_REG_START_ADDRESS4 ONENAND_MEMORY_MAP(0xF103)
+#define ONENAND_REG_START_ADDRESS5 ONENAND_MEMORY_MAP(0xF104)
+#define ONENAND_REG_START_ADDRESS6 ONENAND_MEMORY_MAP(0xF105)
+#define ONENAND_REG_START_ADDRESS7 ONENAND_MEMORY_MAP(0xF106)
+#define ONENAND_REG_START_ADDRESS8 ONENAND_MEMORY_MAP(0xF107)
+
+#define ONENAND_REG_START_BUFFER ONENAND_MEMORY_MAP(0xF200)
+#define ONENAND_REG_COMMAND ONENAND_MEMORY_MAP(0xF220)
+#define ONENAND_REG_SYS_CFG1 ONENAND_MEMORY_MAP(0xF221)
+#define ONENAND_REG_SYS_CFG2 ONENAND_MEMORY_MAP(0xF222)
+#define ONENAND_REG_CTRL_STATUS ONENAND_MEMORY_MAP(0xF240)
+#define ONENAND_REG_INTERRUPT ONENAND_MEMORY_MAP(0xF241)
+#define ONENAND_REG_START_BLOCK_ADDRESS ONENAND_MEMORY_MAP(0xF24C)
+#define ONENAND_REG_END_BLOCK_ADDRESS ONENAND_MEMORY_MAP(0xF24D)
+#define ONENAND_REG_WP_STATUS ONENAND_MEMORY_MAP(0xF24E)
+
+#define ONENAND_REG_ECC_STATUS ONENAND_MEMORY_MAP(0xFF00)
+#define ONENAND_REG_ECC_M0 ONENAND_MEMORY_MAP(0xFF01)
+#define ONENAND_REG_ECC_S0 ONENAND_MEMORY_MAP(0xFF02)
+#define ONENAND_REG_ECC_M1 ONENAND_MEMORY_MAP(0xFF03)
+#define ONENAND_REG_ECC_S1 ONENAND_MEMORY_MAP(0xFF04)
+#define ONENAND_REG_ECC_M2 ONENAND_MEMORY_MAP(0xFF05)
+#define ONENAND_REG_ECC_S2 ONENAND_MEMORY_MAP(0xFF06)
+#define ONENAND_REG_ECC_M3 ONENAND_MEMORY_MAP(0xFF07)
+#define ONENAND_REG_ECC_S3 ONENAND_MEMORY_MAP(0xFF08)
+
+#define ONENAND_DEVICE_DENSITY_SHIFT (4)
+#define ONENAND_DEVICE_IS_DDP (1 << 3)
+#define ONENAND_DEVICE_IS_DEMUX (1 << 2)
+#define ONENAND_DEVICE_VCC_MASK (0x3)
+
+#define ONENAND_DEVICE_DENSITY_512Mb (0x002)
+
+#define ONENAND_VERSION_PROCESS_SHIFT (8)
+
+#define ONENAND_DDP_SHIFT (15)
+
+#define ONENAND_FPA_MASK (0x3f)
+#define ONENAND_FPA_SHIFT (2)
+#define ONENAND_FSA_MASK (0x03)
+
+#define ONENAND_BSA_MASK (0x03)
+#define ONENAND_BSA_SHIFT (8)
+#define ONENAND_BSA_BOOTRAM (0 << 2)
+#define ONENAND_BSA_DATARAM0 (2 << 2)
+#define ONENAND_BSA_DATARAM1 (3 << 2)
+#define ONENAND_BSC_MASK (0x03)
+
+#define ONENAND_CMD_READ (0x00)
+#define ONENAND_CMD_READOOB (0x13)
+#define ONENAND_CMD_PROG (0x80)
+#define ONENAND_CMD_PROGOOB (0x1A)
+#define ONENAND_CMD_UNLOCK (0x23)
+#define ONENAND_CMD_LOCK (0x2A)
+#define ONENAND_CMD_LOCK_TIGHT (0x2C)
+#define ONENAND_CMD_ERASE (0x94)
+#define ONENAND_CMD_RESET (0xF0)
+#define ONENAND_CMD_OTP_ACCESS (0x65)
+#define ONENAND_CMD_READID (0x90)
+
+#define ONENAND_CMD_BUFFERRAM (0x1978)
+
+#define ONENAND_SYS_CFG1_SYNC_READ (1 << 15)
+#define ONENAND_SYS_CFG1_BRL_7 (7 << 12)
+#define ONENAND_SYS_CFG1_BRL_6 (6 << 12)
+#define ONENAND_SYS_CFG1_BRL_5 (5 << 12)
+#define ONENAND_SYS_CFG1_BRL_4 (4 << 12)
+#define ONENAND_SYS_CFG1_BRL_3 (3 << 12)
+#define ONENAND_SYS_CFG1_BRL_10 (2 << 12)
+#define ONENAND_SYS_CFG1_BRL_9 (1 << 12)
+#define ONENAND_SYS_CFG1_BRL_8 (0 << 12)
+#define ONENAND_SYS_CFG1_BRL_SHIFT (12)
+#define ONENAND_SYS_CFG1_BL_32 (4 << 9)
+#define ONENAND_SYS_CFG1_BL_16 (3 << 9)
+#define ONENAND_SYS_CFG1_BL_8 (2 << 9)
+#define ONENAND_SYS_CFG1_BL_4 (1 << 9)
+#define ONENAND_SYS_CFG1_BL_CONT (0 << 9)
+#define ONENAND_SYS_CFG1_BL_SHIFT (9)
+#define ONENAND_SYS_CFG1_NO_ECC (1 << 8)
+#define ONENAND_SYS_CFG1_RDY (1 << 7)
+#define ONENAND_SYS_CFG1_INT (1 << 6)
+#define ONENAND_SYS_CFG1_IOBE (1 << 5)
+#define ONENAND_SYS_CFG1_RDY_CONF (1 << 4)
+
+#define ONENAND_CTRL_ONGO (1 << 15)
+#define ONENAND_CTRL_LOCK (1 << 14)
+#define ONENAND_CTRL_LOAD (1 << 13)
+#define ONENAND_CTRL_PROGRAM (1 << 12)
+#define ONENAND_CTRL_ERASE (1 << 11)
+#define ONENAND_CTRL_ERROR (1 << 10)
+#define ONENAND_CTRL_RSTB (1 << 7)
+#define ONENAND_CTRL_OTP_L (1 << 6)
+#define ONENAND_CTRL_OTP_BL (1 << 5)
+
+#define ONENAND_INT_MASTER (1 << 15)
+#define ONENAND_INT_READ (1 << 7)
+#define ONENAND_INT_WRITE (1 << 6)
+#define ONENAND_INT_ERASE (1 << 5)
+#define ONENAND_INT_RESET (1 << 4)
+#define ONENAND_INT_CLEAR (0 << 0)
+
+#define ONENAND_WP_US (1 << 2)
+#define ONENAND_WP_LS (1 << 1)
+#define ONENAND_WP_LTS (1 << 0)
+
+#define ONENAND_ECC_1BIT (1 << 0)
+#define ONENAND_ECC_2BIT (1 << 1)
+#define ONENAND_ECC_2BIT_ALL (0xAAAA)
+
+#define ONENAND_OTP_LOCK_OFFSET (14)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mtd/partitions.h b/ndk/build/platforms/android-1.5/common/include/linux/mtd/partitions.h
new file mode 100644
index 0000000..aeb15e1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mtd/partitions.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef MTD_PARTITIONS_H
+#define MTD_PARTITIONS_H
+
+#include <linux/types.h>
+
+struct mtd_partition {
+ char *name;
+ u_int32_t size;
+ u_int32_t offset;
+ u_int32_t mask_flags;
+ struct nand_ecclayout *ecclayout;
+ struct mtd_info **mtdp;
+};
+
+#define MTDPART_OFS_NXTBLK (-2)
+#define MTDPART_OFS_APPEND (-1)
+#define MTDPART_SIZ_FULL (0)
+
+struct mtd_part_parser {
+ struct list_head list;
+ struct module *owner;
+ const char *name;
+ int (*parse_fn)(struct mtd_info *, struct mtd_partition **, unsigned long);
+};
+
+#define put_partition_parser(p) do { module_put((p)->owner); } while(0)
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mtio.h b/ndk/build/platforms/android-1.5/common/include/linux/mtio.h
new file mode 100644
index 0000000..47a6e2b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mtio.h
@@ -0,0 +1,259 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_MTIO_H
+#define _LINUX_MTIO_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <linux/qic117.h>
+
+struct mtop {
+ short mt_op;
+ int mt_count;
+};
+
+#define MTRESET 0  
+#define MTFSF 1  
+#define MTBSF 2  
+#define MTFSR 3  
+#define MTBSR 4  
+#define MTWEOF 5  
+#define MTREW 6  
+#define MTOFFL 7  
+#define MTNOP 8  
+#define MTRETEN 9  
+#define MTBSFM 10  
+#define MTFSFM 11  
+#define MTEOM 12  
+#define MTERASE 13  
+
+#define MTRAS1 14  
+#define MTRAS2 15  
+#define MTRAS3 16  
+
+#define MTSETBLK 20  
+#define MTSETDENSITY 21  
+#define MTSEEK 22  
+#define MTTELL 23  
+#define MTSETDRVBUFFER 24  
+
+#define MTFSS 25  
+#define MTBSS 26  
+#define MTWSM 27  
+
+#define MTLOCK 28  
+#define MTUNLOCK 29  
+#define MTLOAD 30  
+#define MTUNLOAD 31  
+#define MTCOMPRESSION 32 
+#define MTSETPART 33  
+#define MTMKPART 34  
+
+struct mtget {
+ long mt_type;
+ long mt_resid;
+
+ long mt_dsreg;
+ long mt_gstat;
+ long mt_erreg;
+
+ __kernel_daddr_t mt_fileno;
+ __kernel_daddr_t mt_blkno;
+};
+
+#define MT_ISUNKNOWN 0x01
+#define MT_ISQIC02 0x02  
+#define MT_ISWT5150 0x03  
+#define MT_ISARCHIVE_5945L2 0x04  
+#define MT_ISCMSJ500 0x05  
+#define MT_ISTDC3610 0x06  
+#define MT_ISARCHIVE_VP60I 0x07  
+#define MT_ISARCHIVE_2150L 0x08  
+#define MT_ISARCHIVE_2060L 0x09  
+#define MT_ISARCHIVESC499 0x0A  
+#define MT_ISQIC02_ALL_FEATURES 0x0F  
+#define MT_ISWT5099EEN24 0x11  
+#define MT_ISTEAC_MT2ST 0x12  
+#define MT_ISEVEREX_FT40A 0x32  
+#define MT_ISDDS1 0x51  
+#define MT_ISDDS2 0x52  
+#define MT_ISONSTREAM_SC 0x61  
+#define MT_ISSCSI1 0x71  
+#define MT_ISSCSI2 0x72  
+
+#define MT_ISFTAPE_UNKNOWN 0x800000  
+#define MT_ISFTAPE_FLAG 0x800000
+
+struct mt_tape_info {
+ long t_type;
+ char *t_name;
+};
+
+#define MT_TAPE_INFO {   {MT_ISUNKNOWN, "Unknown type of tape device"},   {MT_ISQIC02, "Generic QIC-02 tape streamer"},   {MT_ISWT5150, "Wangtek 5150, QIC-150"},   {MT_ISARCHIVE_5945L2, "Archive 5945L-2"},   {MT_ISCMSJ500, "CMS Jumbo 500"},   {MT_ISTDC3610, "Tandberg TDC 3610, QIC-24"},   {MT_ISARCHIVE_VP60I, "Archive VP60i, QIC-02"},   {MT_ISARCHIVE_2150L, "Archive Viper 2150L"},   {MT_ISARCHIVE_2060L, "Archive Viper 2060L"},   {MT_ISARCHIVESC499, "Archive SC-499 QIC-36 controller"},   {MT_ISQIC02_ALL_FEATURES, "Generic QIC-02 tape, all features"},   {MT_ISWT5099EEN24, "Wangtek 5099-een24, 60MB"},   {MT_ISTEAC_MT2ST, "Teac MT-2ST 155mb data cassette drive"},   {MT_ISEVEREX_FT40A, "Everex FT40A, QIC-40"},   {MT_ISONSTREAM_SC, "OnStream SC-, DI-, DP-, or USB tape drive"},   {MT_ISSCSI1, "Generic SCSI-1 tape"},   {MT_ISSCSI2, "Generic SCSI-2 tape"},   {0, NULL}  }
+
+struct mtpos {
+ long mt_blkno;
+};
+
+struct mtvolinfo {
+ unsigned int mt_volno;
+ unsigned int mt_blksz;
+ unsigned int mt_rawsize;
+ unsigned int mt_size;
+ unsigned int mt_cmpr:1;
+};
+
+#define MT_FT_RD_SINGLE 0
+#define MT_FT_RD_AHEAD 1
+#define MT_FT_WR_ASYNC 0  
+#define MT_FT_WR_MULTI 1  
+#define MT_FT_WR_SINGLE 2  
+#define MT_FT_WR_DELETE 3  
+
+struct mtftseg
+{
+ unsigned mt_segno;
+ unsigned mt_mode;
+ int mt_result;
+ void __user *mt_data;
+};
+
+struct mttapesize {
+ unsigned long mt_capacity;
+ unsigned long mt_used;
+};
+
+#define FTFMT_SET_PARMS 1  
+#define FTFMT_GET_PARMS 2  
+#define FTFMT_FORMAT_TRACK 3  
+#define FTFMT_STATUS 4  
+#define FTFMT_VERIFY 5  
+
+struct ftfmtparms {
+ unsigned char ft_qicstd;
+ unsigned char ft_fmtcode;
+ unsigned char ft_fhm;
+ unsigned char ft_ftm;
+ unsigned short ft_spt;
+ unsigned short ft_tpc;
+};
+
+struct ftfmttrack {
+ unsigned int ft_track;
+ unsigned char ft_gap3;
+};
+
+struct ftfmtstatus {
+ unsigned int ft_segment;
+};
+
+struct ftfmtverify {
+ unsigned int ft_segment;
+ unsigned long ft_bsm;
+};
+
+struct mtftformat {
+ unsigned int fmt_op;
+ union fmt_arg {
+ struct ftfmtparms fmt_parms;
+ struct ftfmttrack fmt_track;
+ struct ftfmtstatus fmt_status;
+ struct ftfmtverify fmt_verify;
+ } fmt_arg;
+};
+
+struct mtftcmd {
+ unsigned int ft_wait_before;
+ qic117_cmd_t ft_cmd;
+ unsigned char ft_parm_cnt;
+ unsigned char ft_parms[3];
+ unsigned int ft_result_bits;
+ unsigned int ft_result;
+ unsigned int ft_wait_after;
+ int ft_status;
+ int ft_error;
+};
+
+#define MTIOCTOP _IOW('m', 1, struct mtop)  
+#define MTIOCGET _IOR('m', 2, struct mtget)  
+#define MTIOCPOS _IOR('m', 3, struct mtpos)  
+
+#define MTIOCGETCONFIG _IOR('m', 4, struct mtconfiginfo)  
+#define MTIOCSETCONFIG _IOW('m', 5, struct mtconfiginfo)  
+
+#define MTIOCRDFTSEG _IOWR('m', 6, struct mtftseg)  
+#define MTIOCWRFTSEG _IOWR('m', 7, struct mtftseg)  
+#define MTIOCVOLINFO _IOR('m', 8, struct mtvolinfo)  
+#define MTIOCGETSIZE _IOR('m', 9, struct mttapesize) 
+#define MTIOCFTFORMAT _IOWR('m', 10, struct mtftformat)  
+#define MTIOCFTCMD _IOWR('m', 11, struct mtftcmd)  
+
+#define GMT_EOF(x) ((x) & 0x80000000)
+#define GMT_BOT(x) ((x) & 0x40000000)
+#define GMT_EOT(x) ((x) & 0x20000000)
+#define GMT_SM(x) ((x) & 0x10000000)  
+#define GMT_EOD(x) ((x) & 0x08000000)  
+#define GMT_WR_PROT(x) ((x) & 0x04000000)
+
+#define GMT_ONLINE(x) ((x) & 0x01000000)
+#define GMT_D_6250(x) ((x) & 0x00800000)
+#define GMT_D_1600(x) ((x) & 0x00400000)
+#define GMT_D_800(x) ((x) & 0x00200000)
+
+#define GMT_DR_OPEN(x) ((x) & 0x00040000)  
+
+#define GMT_IM_REP_EN(x) ((x) & 0x00010000)  
+#define GMT_CLN(x) ((x) & 0x00008000)  
+
+#define MT_ST_BLKSIZE_SHIFT 0
+#define MT_ST_BLKSIZE_MASK 0xffffff
+#define MT_ST_DENSITY_SHIFT 24
+#define MT_ST_DENSITY_MASK 0xff000000
+
+#define MT_ST_SOFTERR_SHIFT 0
+#define MT_ST_SOFTERR_MASK 0xffff
+
+#define MT_ST_OPTIONS 0xf0000000
+#define MT_ST_BOOLEANS 0x10000000
+#define MT_ST_SETBOOLEANS 0x30000000
+#define MT_ST_CLEARBOOLEANS 0x40000000
+#define MT_ST_WRITE_THRESHOLD 0x20000000
+#define MT_ST_DEF_BLKSIZE 0x50000000
+#define MT_ST_DEF_OPTIONS 0x60000000
+#define MT_ST_TIMEOUTS 0x70000000
+#define MT_ST_SET_TIMEOUT (MT_ST_TIMEOUTS | 0x000000)
+#define MT_ST_SET_LONG_TIMEOUT (MT_ST_TIMEOUTS | 0x100000)
+#define MT_ST_SET_CLN 0x80000000
+
+#define MT_ST_BUFFER_WRITES 0x1
+#define MT_ST_ASYNC_WRITES 0x2
+#define MT_ST_READ_AHEAD 0x4
+#define MT_ST_DEBUGGING 0x8
+#define MT_ST_TWO_FM 0x10
+#define MT_ST_FAST_MTEOM 0x20
+#define MT_ST_AUTO_LOCK 0x40
+#define MT_ST_DEF_WRITES 0x80
+#define MT_ST_CAN_BSR 0x100
+#define MT_ST_NO_BLKLIMS 0x200
+#define MT_ST_CAN_PARTITIONS 0x400
+#define MT_ST_SCSI2LOGICAL 0x800
+#define MT_ST_SYSV 0x1000
+#define MT_ST_NOWAIT 0x2000
+
+#define MT_ST_CLEAR_DEFAULT 0xfffff
+#define MT_ST_DEF_DENSITY (MT_ST_DEF_OPTIONS | 0x100000)
+#define MT_ST_DEF_COMPRESSION (MT_ST_DEF_OPTIONS | 0x200000)
+#define MT_ST_DEF_DRVBUFFER (MT_ST_DEF_OPTIONS | 0x300000)
+
+#define MT_ST_HPLOADER_OFFSET 10000
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mutex-debug.h b/ndk/build/platforms/android-1.5/common/include/linux/mutex-debug.h
new file mode 100644
index 0000000..7065610
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mutex-debug.h
@@ -0,0 +1,22 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_MUTEX_DEBUG_H
+#define __LINUX_MUTEX_DEBUG_H
+
+#include <linux/linkage.h>
+#include <linux/lockdep.h>
+
+#define __DEBUG_MUTEX_INITIALIZER(lockname)   , .magic = &lockname
+
+#define mutex_init(mutex)  do {   static struct lock_class_key __key;     __mutex_init((mutex), #mutex, &__key);  } while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/mutex.h b/ndk/build/platforms/android-1.5/common/include/linux/mutex.h
new file mode 100644
index 0000000..4b33a8a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/mutex.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_MUTEX_H
+#define __LINUX_MUTEX_H
+
+#include <linux/list.h>
+#include <linux/spinlock_types.h>
+#include <linux/linkage.h>
+#include <linux/lockdep.h>
+
+#include <asm/atomic.h>
+
+struct mutex {
+
+ atomic_t count;
+ spinlock_t wait_lock;
+ struct list_head wait_list;
+};
+
+struct mutex_waiter {
+ struct list_head list;
+ struct task_struct *task;
+};
+
+#define __DEBUG_MUTEX_INITIALIZER(lockname)
+#define mutex_init(mutex)  do {   static struct lock_class_key __key;     __mutex_init((mutex), #mutex, &__key);  } while (0)
+#define mutex_destroy(mutex) do { } while (0)
+
+#define __DEP_MAP_MUTEX_INITIALIZER(lockname)
+
+#define __MUTEX_INITIALIZER(lockname)   { .count = ATOMIC_INIT(1)   , .wait_lock = SPIN_LOCK_UNLOCKED   , .wait_list = LIST_HEAD_INIT(lockname.wait_list)   __DEBUG_MUTEX_INITIALIZER(lockname)   __DEP_MAP_MUTEX_INITIALIZER(lockname) }
+
+#define DEFINE_MUTEX(mutexname)   struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
+
+#define mutex_lock_nested(lock, subclass) mutex_lock(lock)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ncp.h b/ndk/build/platforms/android-1.5/common/include/linux/ncp.h
new file mode 100644
index 0000000..091220a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ncp.h
@@ -0,0 +1,193 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NCP_H
+#define _LINUX_NCP_H
+
+#include <linux/types.h>
+
+#define NCP_PTYPE (0x11)
+#define NCP_PORT (0x0451)
+
+#define NCP_ALLOC_SLOT_REQUEST (0x1111)
+#define NCP_REQUEST (0x2222)
+#define NCP_DEALLOC_SLOT_REQUEST (0x5555)
+
+struct ncp_request_header {
+ __u16 type;
+ __u8 sequence;
+ __u8 conn_low;
+ __u8 task;
+ __u8 conn_high;
+ __u8 function;
+ __u8 data[0];
+} __attribute__((packed));
+
+#define NCP_REPLY (0x3333)
+#define NCP_WATCHDOG (0x3E3E)
+#define NCP_POSITIVE_ACK (0x9999)
+
+struct ncp_reply_header {
+ __u16 type;
+ __u8 sequence;
+ __u8 conn_low;
+ __u8 task;
+ __u8 conn_high;
+ __u8 completion_code;
+ __u8 connection_state;
+ __u8 data[0];
+} __attribute__((packed));
+
+#define NCP_VOLNAME_LEN (16)
+#define NCP_NUMBER_OF_VOLUMES (256)
+struct ncp_volume_info {
+ __u32 total_blocks;
+ __u32 free_blocks;
+ __u32 purgeable_blocks;
+ __u32 not_yet_purgeable_blocks;
+ __u32 total_dir_entries;
+ __u32 available_dir_entries;
+ __u8 sectors_per_block;
+ char volume_name[NCP_VOLNAME_LEN + 1];
+};
+
+#define AR_READ (cpu_to_le16(1))
+#define AR_WRITE (cpu_to_le16(2))
+#define AR_EXCLUSIVE (cpu_to_le16(0x20))
+
+#define NCP_FILE_ID_LEN 6
+
+#define NW_NS_DOS 0
+#define NW_NS_MAC 1
+#define NW_NS_NFS 2
+#define NW_NS_FTAM 3
+#define NW_NS_OS2 4
+
+#define RIM_NAME (cpu_to_le32(1))
+#define RIM_SPACE_ALLOCATED (cpu_to_le32(2))
+#define RIM_ATTRIBUTES (cpu_to_le32(4))
+#define RIM_DATA_SIZE (cpu_to_le32(8))
+#define RIM_TOTAL_SIZE (cpu_to_le32(0x10))
+#define RIM_EXT_ATTR_INFO (cpu_to_le32(0x20))
+#define RIM_ARCHIVE (cpu_to_le32(0x40))
+#define RIM_MODIFY (cpu_to_le32(0x80))
+#define RIM_CREATION (cpu_to_le32(0x100))
+#define RIM_OWNING_NAMESPACE (cpu_to_le32(0x200))
+#define RIM_DIRECTORY (cpu_to_le32(0x400))
+#define RIM_RIGHTS (cpu_to_le32(0x800))
+#define RIM_ALL (cpu_to_le32(0xFFF))
+#define RIM_COMPRESSED_INFO (cpu_to_le32(0x80000000))
+
+#define NSIBM_NFS_NAME 0x0001
+#define NSIBM_NFS_MODE 0x0002
+#define NSIBM_NFS_GID 0x0004
+#define NSIBM_NFS_NLINKS 0x0008
+#define NSIBM_NFS_RDEV 0x0010
+#define NSIBM_NFS_LINK 0x0020
+#define NSIBM_NFS_CREATED 0x0040
+#define NSIBM_NFS_UID 0x0080
+#define NSIBM_NFS_ACSFLAG 0x0100
+#define NSIBM_NFS_MYFLAG 0x0200
+
+#define OC_MODE_OPEN 0x01
+#define OC_MODE_TRUNCATE 0x02
+#define OC_MODE_REPLACE 0x02
+#define OC_MODE_CREATE 0x08
+
+#define OC_ACTION_NONE 0x00
+#define OC_ACTION_OPEN 0x01
+#define OC_ACTION_CREATE 0x02
+#define OC_ACTION_TRUNCATE 0x04
+#define OC_ACTION_REPLACE 0x04
+
+#ifndef AR_READ_ONLY
+#define AR_READ_ONLY 0x0001
+#define AR_WRITE_ONLY 0x0002
+#define AR_DENY_READ 0x0004
+#define AR_DENY_WRITE 0x0008
+#define AR_COMPATIBILITY 0x0010
+#define AR_WRITE_THROUGH 0x0040
+#define AR_OPEN_COMPRESSED 0x0100
+#endif
+
+struct nw_nfs_info {
+ __u32 mode;
+ __u32 rdev;
+};
+
+struct nw_info_struct {
+ __u32 spaceAlloc;
+ __le32 attributes;
+ __u16 flags;
+ __le32 dataStreamSize;
+ __le32 totalStreamSize;
+ __u16 numberOfStreams;
+ __le16 creationTime;
+ __le16 creationDate;
+ __u32 creatorID;
+ __le16 modifyTime;
+ __le16 modifyDate;
+ __u32 modifierID;
+ __le16 lastAccessDate;
+ __u16 archiveTime;
+ __u16 archiveDate;
+ __u32 archiverID;
+ __u16 inheritedRightsMask;
+ __le32 dirEntNum;
+ __le32 DosDirNum;
+ __u32 volNumber;
+ __u32 EADataSize;
+ __u32 EAKeyCount;
+ __u32 EAKeySize;
+ __u32 NSCreator;
+ __u8 nameLen;
+ __u8 entryName[256];
+
+} __attribute__((packed));
+
+#define DM_ATTRIBUTES (cpu_to_le32(0x02))
+#define DM_CREATE_DATE (cpu_to_le32(0x04))
+#define DM_CREATE_TIME (cpu_to_le32(0x08))
+#define DM_CREATOR_ID (cpu_to_le32(0x10))
+#define DM_ARCHIVE_DATE (cpu_to_le32(0x20))
+#define DM_ARCHIVE_TIME (cpu_to_le32(0x40))
+#define DM_ARCHIVER_ID (cpu_to_le32(0x80))
+#define DM_MODIFY_DATE (cpu_to_le32(0x0100))
+#define DM_MODIFY_TIME (cpu_to_le32(0x0200))
+#define DM_MODIFIER_ID (cpu_to_le32(0x0400))
+#define DM_LAST_ACCESS_DATE (cpu_to_le32(0x0800))
+#define DM_INHERITED_RIGHTS_MASK (cpu_to_le32(0x1000))
+#define DM_MAXIMUM_SPACE (cpu_to_le32(0x2000))
+
+struct nw_modify_dos_info {
+ __le32 attributes;
+ __le16 creationDate;
+ __le16 creationTime;
+ __u32 creatorID;
+ __le16 modifyDate;
+ __le16 modifyTime;
+ __u32 modifierID;
+ __u16 archiveDate;
+ __u16 archiveTime;
+ __u32 archiverID;
+ __le16 lastAccessDate;
+ __u16 inheritanceGrantMask;
+ __u16 inheritanceRevokeMask;
+ __u32 maximumSpace;
+} __attribute__((packed));
+
+struct nw_search_sequence {
+ __u8 volNumber;
+ __u32 dirBase;
+ __u32 sequence;
+} __attribute__((packed));
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ncp_mount.h b/ndk/build/platforms/android-1.5/common/include/linux/ncp_mount.h
new file mode 100644
index 0000000..204869f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ncp_mount.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NCP_MOUNT_H
+#define _LINUX_NCP_MOUNT_H
+
+#include <linux/types.h>
+#include <linux/ncp.h>
+
+#define NCP_MOUNT_VERSION 3  
+
+#define NCP_MOUNT_SOFT 0x0001
+#define NCP_MOUNT_INTR 0x0002
+#define NCP_MOUNT_STRONG 0x0004  
+#define NCP_MOUNT_NO_OS2 0x0008  
+#define NCP_MOUNT_NO_NFS 0x0010  
+#define NCP_MOUNT_EXTRAS 0x0020
+#define NCP_MOUNT_SYMLINKS 0x0040  
+#define NCP_MOUNT_NFS_EXTRAS 0x0080  
+
+struct ncp_mount_data {
+ int version;
+ unsigned int ncp_fd;
+ __kernel_uid_t mounted_uid;
+ __kernel_pid_t wdog_pid;
+
+ unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];
+ unsigned int time_out;
+ unsigned int retry_count;
+ unsigned int flags;
+
+ __kernel_uid_t uid;
+ __kernel_gid_t gid;
+ __kernel_mode_t file_mode;
+ __kernel_mode_t dir_mode;
+};
+
+#define NCP_MOUNT_VERSION_V4 (4)  
+
+struct ncp_mount_data_v4 {
+ int version;
+ unsigned long flags;
+
+ unsigned long mounted_uid;
+
+ long wdog_pid;
+
+ unsigned int ncp_fd;
+ unsigned int time_out;
+ unsigned int retry_count;
+
+ unsigned long uid;
+ unsigned long gid;
+
+ unsigned long file_mode;
+ unsigned long dir_mode;
+};
+
+#define NCP_MOUNT_VERSION_V5 (5)  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ncp_no.h b/ndk/build/platforms/android-1.5/common/include/linux/ncp_no.h
new file mode 100644
index 0000000..9afed68
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ncp_no.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _NCP_NO
+#define _NCP_NO
+
+#define aRONLY (__constant_cpu_to_le32(1))
+#define aHIDDEN (__constant_cpu_to_le32(2))
+#define aSYSTEM (__constant_cpu_to_le32(4))
+#define aEXECUTE (__constant_cpu_to_le32(8))
+#define aDIR (__constant_cpu_to_le32(0x10))
+#define aARCH (__constant_cpu_to_le32(0x20))
+#define aSHARED (__constant_cpu_to_le32(0x80))
+#define aDONTSUBALLOCATE (__constant_cpu_to_le32(1L<<11))
+#define aTRANSACTIONAL (__constant_cpu_to_le32(1L<<12))
+#define aPURGE (__constant_cpu_to_le32(1L<<16))
+#define aRENAMEINHIBIT (__constant_cpu_to_le32(1L<<17))
+#define aDELETEINHIBIT (__constant_cpu_to_le32(1L<<18))
+#define aDONTCOMPRESS (__constant_cpu_to_le32(1L<<27))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/net.h b/ndk/build/platforms/android-1.5/common/include/linux/net.h
new file mode 100644
index 0000000..29fca2c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/net.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NET_H
+#define _LINUX_NET_H
+
+#include <linux/wait.h>
+#include <asm/socket.h>
+
+struct poll_table_struct;
+struct inode;
+
+#define NPROTO 32  
+
+#define SYS_SOCKET 1  
+#define SYS_BIND 2  
+#define SYS_CONNECT 3  
+#define SYS_LISTEN 4  
+#define SYS_ACCEPT 5  
+#define SYS_GETSOCKNAME 6  
+#define SYS_GETPEERNAME 7  
+#define SYS_SOCKETPAIR 8  
+#define SYS_SEND 9  
+#define SYS_RECV 10  
+#define SYS_SENDTO 11  
+#define SYS_RECVFROM 12  
+#define SYS_SHUTDOWN 13  
+#define SYS_SETSOCKOPT 14  
+#define SYS_GETSOCKOPT 15  
+#define SYS_SENDMSG 16  
+#define SYS_RECVMSG 17  
+
+typedef enum {
+ SS_FREE = 0,
+ SS_UNCONNECTED,
+ SS_CONNECTING,
+ SS_CONNECTED,
+ SS_DISCONNECTING
+} socket_state;
+
+#define __SO_ACCEPTCON (1 << 16)  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netdevice.h b/ndk/build/platforms/android-1.5/common/include/linux/netdevice.h
new file mode 100644
index 0000000..54b58f1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netdevice.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NETDEVICE_H
+#define _LINUX_NETDEVICE_H
+
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <linux/if_packet.h>
+
+#define MAX_ADDR_LEN 32  
+
+#define NETDEV_TX_OK 0  
+#define NETDEV_TX_BUSY 1  
+#define NETDEV_TX_LOCKED -1  
+
+#define LL_MAX_HEADER 32
+
+#define MAX_HEADER LL_MAX_HEADER
+
+struct net_device_stats
+{
+ unsigned long rx_packets;
+ unsigned long tx_packets;
+ unsigned long rx_bytes;
+ unsigned long tx_bytes;
+ unsigned long rx_errors;
+ unsigned long tx_errors;
+ unsigned long rx_dropped;
+ unsigned long tx_dropped;
+ unsigned long multicast;
+ unsigned long collisions;
+
+ unsigned long rx_length_errors;
+ unsigned long rx_over_errors;
+ unsigned long rx_crc_errors;
+ unsigned long rx_frame_errors;
+ unsigned long rx_fifo_errors;
+ unsigned long rx_missed_errors;
+
+ unsigned long tx_aborted_errors;
+ unsigned long tx_carrier_errors;
+ unsigned long tx_fifo_errors;
+ unsigned long tx_heartbeat_errors;
+ unsigned long tx_window_errors;
+
+ unsigned long rx_compressed;
+ unsigned long tx_compressed;
+};
+
+enum {
+ IF_PORT_UNKNOWN = 0,
+ IF_PORT_10BASE2,
+ IF_PORT_10BASET,
+ IF_PORT_AUI,
+ IF_PORT_100BASET,
+ IF_PORT_100BASETX,
+ IF_PORT_100BASEFX
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter.h
new file mode 100644
index 0000000..0488344
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter.h
@@ -0,0 +1,36 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_NETFILTER_H
+#define __LINUX_NETFILTER_H
+
+#include <linux/compiler.h>
+
+#define NF_DROP 0
+#define NF_ACCEPT 1
+#define NF_STOLEN 2
+#define NF_QUEUE 3
+#define NF_REPEAT 4
+#define NF_STOP 5
+#define NF_MAX_VERDICT NF_STOP
+
+#define NF_VERDICT_MASK 0x0000ffff
+#define NF_VERDICT_BITS 16
+
+#define NF_VERDICT_QMASK 0xffff0000
+#define NF_VERDICT_QBITS 16
+
+#define NF_QUEUE_NR(x) (((x << NF_VERDICT_QBITS) & NF_VERDICT_QMASK) | NF_QUEUE)
+
+#define NFC_UNKNOWN 0x4000
+#define NFC_ALTERED 0x8000
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_common.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_common.h
new file mode 100644
index 0000000..69177fc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_common.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _NF_CONNTRACK_COMMON_H
+#define _NF_CONNTRACK_COMMON_H
+
+enum ip_conntrack_info
+{
+
+ IP_CT_ESTABLISHED,
+
+ IP_CT_RELATED,
+
+ IP_CT_NEW,
+
+ IP_CT_IS_REPLY,
+
+ IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
+};
+
+enum ip_conntrack_status {
+
+ IPS_EXPECTED_BIT = 0,
+ IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
+
+ IPS_SEEN_REPLY_BIT = 1,
+ IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
+
+ IPS_ASSURED_BIT = 2,
+ IPS_ASSURED = (1 << IPS_ASSURED_BIT),
+
+ IPS_CONFIRMED_BIT = 3,
+ IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
+
+ IPS_SRC_NAT_BIT = 4,
+ IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
+
+ IPS_DST_NAT_BIT = 5,
+ IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
+
+ IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
+
+ IPS_SEQ_ADJUST_BIT = 6,
+ IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
+
+ IPS_SRC_NAT_DONE_BIT = 7,
+ IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
+
+ IPS_DST_NAT_DONE_BIT = 8,
+ IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
+
+ IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
+
+ IPS_DYING_BIT = 9,
+ IPS_DYING = (1 << IPS_DYING_BIT),
+
+ IPS_FIXED_TIMEOUT_BIT = 10,
+ IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
+};
+
+enum ip_conntrack_events
+{
+
+ IPCT_NEW_BIT = 0,
+ IPCT_NEW = (1 << IPCT_NEW_BIT),
+
+ IPCT_RELATED_BIT = 1,
+ IPCT_RELATED = (1 << IPCT_RELATED_BIT),
+
+ IPCT_DESTROY_BIT = 2,
+ IPCT_DESTROY = (1 << IPCT_DESTROY_BIT),
+
+ IPCT_REFRESH_BIT = 3,
+ IPCT_REFRESH = (1 << IPCT_REFRESH_BIT),
+
+ IPCT_STATUS_BIT = 4,
+ IPCT_STATUS = (1 << IPCT_STATUS_BIT),
+
+ IPCT_PROTOINFO_BIT = 5,
+ IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT),
+
+ IPCT_PROTOINFO_VOLATILE_BIT = 6,
+ IPCT_PROTOINFO_VOLATILE = (1 << IPCT_PROTOINFO_VOLATILE_BIT),
+
+ IPCT_HELPER_BIT = 7,
+ IPCT_HELPER = (1 << IPCT_HELPER_BIT),
+
+ IPCT_HELPINFO_BIT = 8,
+ IPCT_HELPINFO = (1 << IPCT_HELPINFO_BIT),
+
+ IPCT_HELPINFO_VOLATILE_BIT = 9,
+ IPCT_HELPINFO_VOLATILE = (1 << IPCT_HELPINFO_VOLATILE_BIT),
+
+ IPCT_NATINFO_BIT = 10,
+ IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
+
+ IPCT_COUNTER_FILLING_BIT = 11,
+ IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
+};
+
+enum ip_conntrack_expect_events {
+ IPEXP_NEW_BIT = 0,
+ IPEXP_NEW = (1 << IPEXP_NEW_BIT),
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_ftp.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_ftp.h
new file mode 100644
index 0000000..ff815a7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_ftp.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _NF_CONNTRACK_FTP_H
+#define _NF_CONNTRACK_FTP_H
+
+enum ip_ct_ftp_type
+{
+
+ IP_CT_FTP_PORT,
+
+ IP_CT_FTP_PASV,
+
+ IP_CT_FTP_EPRT,
+
+ IP_CT_FTP_EPSV,
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_sctp.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_sctp.h
new file mode 100644
index 0000000..15768b2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_sctp.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _NF_CONNTRACK_SCTP_H
+#define _NF_CONNTRACK_SCTP_H
+
+#include <linux/netfilter/nf_conntrack_tuple_common.h>
+
+enum sctp_conntrack {
+ SCTP_CONNTRACK_NONE,
+ SCTP_CONNTRACK_CLOSED,
+ SCTP_CONNTRACK_COOKIE_WAIT,
+ SCTP_CONNTRACK_COOKIE_ECHOED,
+ SCTP_CONNTRACK_ESTABLISHED,
+ SCTP_CONNTRACK_SHUTDOWN_SENT,
+ SCTP_CONNTRACK_SHUTDOWN_RECD,
+ SCTP_CONNTRACK_SHUTDOWN_ACK_SENT,
+ SCTP_CONNTRACK_MAX
+};
+
+struct ip_ct_sctp
+{
+ enum sctp_conntrack state;
+
+ u_int32_t vtag[IP_CT_DIR_MAX];
+ u_int32_t ttag[IP_CT_DIR_MAX];
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_tcp.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_tcp.h
new file mode 100644
index 0000000..227f902
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_tcp.h
@@ -0,0 +1,36 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _NF_CONNTRACK_TCP_H
+#define _NF_CONNTRACK_TCP_H
+
+enum tcp_conntrack {
+ TCP_CONNTRACK_NONE,
+ TCP_CONNTRACK_SYN_SENT,
+ TCP_CONNTRACK_SYN_RECV,
+ TCP_CONNTRACK_ESTABLISHED,
+ TCP_CONNTRACK_FIN_WAIT,
+ TCP_CONNTRACK_CLOSE_WAIT,
+ TCP_CONNTRACK_LAST_ACK,
+ TCP_CONNTRACK_TIME_WAIT,
+ TCP_CONNTRACK_CLOSE,
+ TCP_CONNTRACK_LISTEN,
+ TCP_CONNTRACK_MAX,
+ TCP_CONNTRACK_IGNORE
+};
+
+#define IP_CT_TCP_FLAG_WINDOW_SCALE 0x01
+
+#define IP_CT_TCP_FLAG_SACK_PERM 0x02
+
+#define IP_CT_TCP_FLAG_CLOSE_INIT 0x03
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_tuple_common.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_tuple_common.h
new file mode 100644
index 0000000..f282543
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nf_conntrack_tuple_common.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _NF_CONNTRACK_TUPLE_COMMON_H
+#define _NF_CONNTRACK_TUPLE_COMMON_H
+
+enum ip_conntrack_dir
+{
+ IP_CT_DIR_ORIGINAL,
+ IP_CT_DIR_REPLY,
+ IP_CT_DIR_MAX
+};
+
+#define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nfnetlink.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nfnetlink.h
new file mode 100644
index 0000000..4544cab
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nfnetlink.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _NFNETLINK_H
+#define _NFNETLINK_H
+#include <linux/types.h>
+
+#define NF_NETLINK_CONNTRACK_NEW 0x00000001
+#define NF_NETLINK_CONNTRACK_UPDATE 0x00000002
+#define NF_NETLINK_CONNTRACK_DESTROY 0x00000004
+#define NF_NETLINK_CONNTRACK_EXP_NEW 0x00000008
+#define NF_NETLINK_CONNTRACK_EXP_UPDATE 0x00000010
+#define NF_NETLINK_CONNTRACK_EXP_DESTROY 0x00000020
+
+enum nfnetlink_groups {
+ NFNLGRP_NONE,
+#define NFNLGRP_NONE NFNLGRP_NONE
+ NFNLGRP_CONNTRACK_NEW,
+#define NFNLGRP_CONNTRACK_NEW NFNLGRP_CONNTRACK_NEW
+ NFNLGRP_CONNTRACK_UPDATE,
+#define NFNLGRP_CONNTRACK_UPDATE NFNLGRP_CONNTRACK_UPDATE
+ NFNLGRP_CONNTRACK_DESTROY,
+#define NFNLGRP_CONNTRACK_DESTROY NFNLGRP_CONNTRACK_DESTROY
+ NFNLGRP_CONNTRACK_EXP_NEW,
+#define NFNLGRP_CONNTRACK_EXP_NEW NFNLGRP_CONNTRACK_EXP_NEW
+ NFNLGRP_CONNTRACK_EXP_UPDATE,
+#define NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_UPDATE
+ NFNLGRP_CONNTRACK_EXP_DESTROY,
+#define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY
+ __NFNLGRP_MAX,
+};
+#define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
+
+struct nfattr
+{
+ u_int16_t nfa_len;
+ u_int16_t nfa_type;
+} __attribute__ ((packed));
+
+#define NFNL_NFA_NEST 0x8000
+#define NFA_TYPE(attr) ((attr)->nfa_type & 0x7fff)
+
+#define NFA_ALIGNTO 4
+#define NFA_ALIGN(len) (((len) + NFA_ALIGNTO - 1) & ~(NFA_ALIGNTO - 1))
+#define NFA_OK(nfa,len) ((len) > 0 && (nfa)->nfa_len >= sizeof(struct nfattr)   && (nfa)->nfa_len <= (len))
+#define NFA_NEXT(nfa,attrlen) ((attrlen) -= NFA_ALIGN((nfa)->nfa_len),   (struct nfattr *)(((char *)(nfa)) + NFA_ALIGN((nfa)->nfa_len)))
+#define NFA_LENGTH(len) (NFA_ALIGN(sizeof(struct nfattr)) + (len))
+#define NFA_SPACE(len) NFA_ALIGN(NFA_LENGTH(len))
+#define NFA_DATA(nfa) ((void *)(((char *)(nfa)) + NFA_LENGTH(0)))
+#define NFA_PAYLOAD(nfa) ((int)((nfa)->nfa_len) - NFA_LENGTH(0))
+#define NFA_NEST(skb, type)  ({ struct nfattr *__start = (struct nfattr *) (skb)->tail;   NFA_PUT(skb, (NFNL_NFA_NEST | type), 0, NULL);   __start; })
+#define NFA_NEST_END(skb, start)  ({ (start)->nfa_len = ((skb)->tail - (unsigned char *) (start));   (skb)->len; })
+#define NFA_NEST_CANCEL(skb, start)  ({ if (start)   skb_trim(skb, (unsigned char *) (start) - (skb)->data);   -1; })
+
+struct nfgenmsg {
+ u_int8_t nfgen_family;
+ u_int8_t version;
+ u_int16_t res_id;
+} __attribute__ ((packed));
+
+#define NFNETLINK_V0 0
+
+#define NFM_NFA(n) ((struct nfattr *)(((char *)(n))   + NLMSG_ALIGN(sizeof(struct nfgenmsg))))
+#define NFM_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct nfgenmsg))
+
+#define NFNL_SUBSYS_ID(x) ((x & 0xff00) >> 8)
+#define NFNL_MSG_TYPE(x) (x & 0x00ff)
+
+#define NFNL_SUBSYS_NONE 0
+#define NFNL_SUBSYS_CTNETLINK 1
+#define NFNL_SUBSYS_CTNETLINK_EXP 2
+#define NFNL_SUBSYS_QUEUE 3
+#define NFNL_SUBSYS_ULOG 4
+#define NFNL_SUBSYS_COUNT 5
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nfnetlink_conntrack.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nfnetlink_conntrack.h
new file mode 100644
index 0000000..105dd09
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/nfnetlink_conntrack.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPCONNTRACK_NETLINK_H
+#define _IPCONNTRACK_NETLINK_H
+#include <linux/netfilter/nfnetlink.h>
+
+enum cntl_msg_types {
+ IPCTNL_MSG_CT_NEW,
+ IPCTNL_MSG_CT_GET,
+ IPCTNL_MSG_CT_DELETE,
+ IPCTNL_MSG_CT_GET_CTRZERO,
+
+ IPCTNL_MSG_MAX
+};
+
+enum ctnl_exp_msg_types {
+ IPCTNL_MSG_EXP_NEW,
+ IPCTNL_MSG_EXP_GET,
+ IPCTNL_MSG_EXP_DELETE,
+
+ IPCTNL_MSG_EXP_MAX
+};
+
+enum ctattr_type {
+ CTA_UNSPEC,
+ CTA_TUPLE_ORIG,
+ CTA_TUPLE_REPLY,
+ CTA_STATUS,
+ CTA_PROTOINFO,
+ CTA_HELP,
+ CTA_NAT_SRC,
+#define CTA_NAT CTA_NAT_SRC  
+ CTA_TIMEOUT,
+ CTA_MARK,
+ CTA_COUNTERS_ORIG,
+ CTA_COUNTERS_REPLY,
+ CTA_USE,
+ CTA_ID,
+ CTA_NAT_DST,
+ __CTA_MAX
+};
+#define CTA_MAX (__CTA_MAX - 1)
+
+enum ctattr_tuple {
+ CTA_TUPLE_UNSPEC,
+ CTA_TUPLE_IP,
+ CTA_TUPLE_PROTO,
+ __CTA_TUPLE_MAX
+};
+#define CTA_TUPLE_MAX (__CTA_TUPLE_MAX - 1)
+
+enum ctattr_ip {
+ CTA_IP_UNSPEC,
+ CTA_IP_V4_SRC,
+ CTA_IP_V4_DST,
+ CTA_IP_V6_SRC,
+ CTA_IP_V6_DST,
+ __CTA_IP_MAX
+};
+#define CTA_IP_MAX (__CTA_IP_MAX - 1)
+
+enum ctattr_l4proto {
+ CTA_PROTO_UNSPEC,
+ CTA_PROTO_NUM,
+ CTA_PROTO_SRC_PORT,
+ CTA_PROTO_DST_PORT,
+ CTA_PROTO_ICMP_ID,
+ CTA_PROTO_ICMP_TYPE,
+ CTA_PROTO_ICMP_CODE,
+ CTA_PROTO_ICMPV6_ID,
+ CTA_PROTO_ICMPV6_TYPE,
+ CTA_PROTO_ICMPV6_CODE,
+ __CTA_PROTO_MAX
+};
+#define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1)
+
+enum ctattr_protoinfo {
+ CTA_PROTOINFO_UNSPEC,
+ CTA_PROTOINFO_TCP,
+ __CTA_PROTOINFO_MAX
+};
+#define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1)
+
+enum ctattr_protoinfo_tcp {
+ CTA_PROTOINFO_TCP_UNSPEC,
+ CTA_PROTOINFO_TCP_STATE,
+ __CTA_PROTOINFO_TCP_MAX
+};
+#define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1)
+
+enum ctattr_counters {
+ CTA_COUNTERS_UNSPEC,
+ CTA_COUNTERS_PACKETS,
+ CTA_COUNTERS_BYTES,
+ CTA_COUNTERS32_PACKETS,
+ CTA_COUNTERS32_BYTES,
+ __CTA_COUNTERS_MAX
+};
+#define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
+
+enum ctattr_nat {
+ CTA_NAT_UNSPEC,
+ CTA_NAT_MINIP,
+ CTA_NAT_MAXIP,
+ CTA_NAT_PROTO,
+ __CTA_NAT_MAX
+};
+#define CTA_NAT_MAX (__CTA_NAT_MAX - 1)
+
+enum ctattr_protonat {
+ CTA_PROTONAT_UNSPEC,
+ CTA_PROTONAT_PORT_MIN,
+ CTA_PROTONAT_PORT_MAX,
+ __CTA_PROTONAT_MAX
+};
+#define CTA_PROTONAT_MAX (__CTA_PROTONAT_MAX - 1)
+
+enum ctattr_expect {
+ CTA_EXPECT_UNSPEC,
+ CTA_EXPECT_MASTER,
+ CTA_EXPECT_TUPLE,
+ CTA_EXPECT_MASK,
+ CTA_EXPECT_TIMEOUT,
+ CTA_EXPECT_ID,
+ CTA_EXPECT_HELP_NAME,
+ __CTA_EXPECT_MAX
+};
+#define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
+
+enum ctattr_help {
+ CTA_HELP_UNSPEC,
+ CTA_HELP_NAME,
+ __CTA_HELP_MAX
+};
+#define CTA_HELP_MAX (__CTA_HELP_MAX - 1)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/x_tables.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/x_tables.h
new file mode 100644
index 0000000..234181f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/x_tables.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _X_TABLES_H
+#define _X_TABLES_H
+
+#define XT_FUNCTION_MAXNAMELEN 30
+#define XT_TABLE_MAXNAMELEN 32
+
+struct xt_entry_match
+{
+ union {
+ struct {
+ u_int16_t match_size;
+
+ char name[XT_FUNCTION_MAXNAMELEN-1];
+
+ u_int8_t revision;
+ } user;
+ struct {
+ u_int16_t match_size;
+
+ struct xt_match *match;
+ } kernel;
+
+ u_int16_t match_size;
+ } u;
+
+ unsigned char data[0];
+};
+
+struct xt_entry_target
+{
+ union {
+ struct {
+ u_int16_t target_size;
+
+ char name[XT_FUNCTION_MAXNAMELEN-1];
+
+ u_int8_t revision;
+ } user;
+ struct {
+ u_int16_t target_size;
+
+ struct xt_target *target;
+ } kernel;
+
+ u_int16_t target_size;
+ } u;
+
+ unsigned char data[0];
+};
+
+struct xt_standard_target
+{
+ struct xt_entry_target target;
+ int verdict;
+};
+
+struct xt_get_revision
+{
+ char name[XT_FUNCTION_MAXNAMELEN-1];
+
+ u_int8_t revision;
+};
+
+#define XT_CONTINUE 0xFFFFFFFF
+
+#define XT_RETURN (-NF_REPEAT - 1)
+
+struct _xt_align
+{
+ u_int8_t u8;
+ u_int16_t u16;
+ u_int32_t u32;
+ u_int64_t u64;
+};
+
+#define XT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1))   & ~(__alignof__(struct _xt_align)-1))
+
+#define XT_STANDARD_TARGET ""
+
+#define XT_ERROR_TARGET "ERROR"
+
+#define XT_BASE_CTL 64  
+
+#define XT_SO_SET_REPLACE (XT_BASE_CTL)
+#define XT_SO_SET_ADD_COUNTERS (XT_BASE_CTL + 1)
+#define XT_SO_SET_MAX XT_SO_SET_ADD_COUNTERS
+
+#define XT_SO_GET_INFO (XT_BASE_CTL)
+#define XT_SO_GET_ENTRIES (XT_BASE_CTL + 1)
+#define XT_SO_GET_REVISION_MATCH (XT_BASE_CTL + 2)
+#define XT_SO_GET_REVISION_TARGET (XT_BASE_CTL + 3)
+#define XT_SO_GET_MAX XT_SO_GET_REVISION_TARGET
+
+#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
+#define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
+
+struct xt_counters
+{
+ u_int64_t pcnt, bcnt;
+};
+
+struct xt_counters_info
+{
+
+ char name[XT_TABLE_MAXNAMELEN];
+
+ unsigned int num_counters;
+
+ struct xt_counters counters[0];
+};
+
+#define XT_INV_PROTO 0x40  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_CLASSIFY.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_CLASSIFY.h
new file mode 100644
index 0000000..1e9f61e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_CLASSIFY.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_CLASSIFY_H
+#define _XT_CLASSIFY_H
+
+struct xt_classify_target_info {
+ u_int32_t priority;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_CONNMARK.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_CONNMARK.h
new file mode 100644
index 0000000..1b30eeb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_CONNMARK.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_CONNMARK_H_target
+#define _XT_CONNMARK_H_target
+
+enum {
+ XT_CONNMARK_SET = 0,
+ XT_CONNMARK_SAVE,
+ XT_CONNMARK_RESTORE
+};
+
+struct xt_connmark_target_info {
+ unsigned long mark;
+ unsigned long mask;
+ u_int8_t mode;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_CONNSECMARK.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_CONNSECMARK.h
new file mode 100644
index 0000000..5e16b2e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_CONNSECMARK.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_CONNSECMARK_H_target
+#define _XT_CONNSECMARK_H_target
+
+enum {
+ CONNSECMARK_SAVE = 1,
+ CONNSECMARK_RESTORE,
+};
+
+struct xt_connsecmark_target_info {
+ u_int8_t mode;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_MARK.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_MARK.h
new file mode 100644
index 0000000..f58c97c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_MARK.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_MARK_H_target
+#define _XT_MARK_H_target
+
+struct xt_mark_target_info {
+ unsigned long mark;
+};
+
+enum {
+ XT_MARK_SET=0,
+ XT_MARK_AND,
+ XT_MARK_OR,
+};
+
+struct xt_mark_target_info_v1 {
+ unsigned long mark;
+ u_int8_t mode;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_NFQUEUE.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_NFQUEUE.h
new file mode 100644
index 0000000..1f0cacb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_NFQUEUE.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_NFQ_TARGET_H
+#define _XT_NFQ_TARGET_H
+
+struct xt_NFQ_info {
+ u_int16_t queuenum;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_SECMARK.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_SECMARK.h
new file mode 100644
index 0000000..a91d32c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_SECMARK.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_SECMARK_H_target
+#define _XT_SECMARK_H_target
+
+#define SECMARK_MODE_SEL 0x01  
+#define SECMARK_SELCTX_MAX 256
+
+struct xt_secmark_target_selinux_info {
+ u_int32_t selsid;
+ char selctx[SECMARK_SELCTX_MAX];
+};
+
+struct xt_secmark_target_info {
+ u_int8_t mode;
+ union {
+ struct xt_secmark_target_selinux_info sel;
+ } u;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_comment.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_comment.h
new file mode 100644
index 0000000..6ea26fc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_comment.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_COMMENT_H
+#define _XT_COMMENT_H
+
+#define XT_MAX_COMMENT_LEN 256
+
+struct xt_comment_info {
+ unsigned char comment[XT_MAX_COMMENT_LEN];
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_connbytes.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_connbytes.h
new file mode 100644
index 0000000..8cc80e1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_connbytes.h
@@ -0,0 +1,36 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_CONNBYTES_H
+#define _XT_CONNBYTES_H
+
+enum xt_connbytes_what {
+ XT_CONNBYTES_PKTS,
+ XT_CONNBYTES_BYTES,
+ XT_CONNBYTES_AVGPKT,
+};
+
+enum xt_connbytes_direction {
+ XT_CONNBYTES_DIR_ORIGINAL,
+ XT_CONNBYTES_DIR_REPLY,
+ XT_CONNBYTES_DIR_BOTH,
+};
+
+struct xt_connbytes_info
+{
+ struct {
+ aligned_u64 from;
+ aligned_u64 to;
+ } count;
+ u_int8_t what;
+ u_int8_t direction;
+};
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_connmark.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_connmark.h
new file mode 100644
index 0000000..021e03a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_connmark.h
@@ -0,0 +1,20 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_CONNMARK_H
+#define _XT_CONNMARK_H
+
+struct xt_connmark_info {
+ unsigned long mark, mask;
+ u_int8_t invert;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_conntrack.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_conntrack.h
new file mode 100644
index 0000000..aa9bde2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_conntrack.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_CONNTRACK_H
+#define _XT_CONNTRACK_H
+
+#include <linux/netfilter/nf_conntrack_tuple_common.h>
+#include <linux/in.h>
+
+#define XT_CONNTRACK_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
+#define XT_CONNTRACK_STATE_INVALID (1 << 0)
+
+#define XT_CONNTRACK_STATE_SNAT (1 << (IP_CT_NUMBER + 1))
+#define XT_CONNTRACK_STATE_DNAT (1 << (IP_CT_NUMBER + 2))
+#define XT_CONNTRACK_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 3))
+
+#define XT_CONNTRACK_STATE 0x01
+#define XT_CONNTRACK_PROTO 0x02
+#define XT_CONNTRACK_ORIGSRC 0x04
+#define XT_CONNTRACK_ORIGDST 0x08
+#define XT_CONNTRACK_REPLSRC 0x10
+#define XT_CONNTRACK_REPLDST 0x20
+#define XT_CONNTRACK_STATUS 0x40
+#define XT_CONNTRACK_EXPIRES 0x80
+
+struct ip_conntrack_old_tuple
+{
+ struct {
+ __u32 ip;
+ union {
+ __u16 all;
+ } u;
+ } src;
+
+ struct {
+ __u32 ip;
+ union {
+ __u16 all;
+ } u;
+
+ __u16 protonum;
+ } dst;
+};
+
+struct xt_conntrack_info
+{
+ unsigned int statemask, statusmask;
+
+ struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX];
+ struct in_addr sipmsk[IP_CT_DIR_MAX], dipmsk[IP_CT_DIR_MAX];
+
+ unsigned long expires_min, expires_max;
+
+ u_int8_t flags;
+
+ u_int8_t invflags;
+};
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_dccp.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_dccp.h
new file mode 100644
index 0000000..8a10e67
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_dccp.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_DCCP_H_
+#define _XT_DCCP_H_
+
+#define XT_DCCP_SRC_PORTS 0x01
+#define XT_DCCP_DEST_PORTS 0x02
+#define XT_DCCP_TYPE 0x04
+#define XT_DCCP_OPTION 0x08
+
+#define XT_DCCP_VALID_FLAGS 0x0f
+
+struct xt_dccp_info {
+ u_int16_t dpts[2];
+ u_int16_t spts[2];
+
+ u_int16_t flags;
+ u_int16_t invflags;
+
+ u_int16_t typemask;
+ u_int8_t option;
+};
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_esp.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_esp.h
new file mode 100644
index 0000000..175c47e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_esp.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_ESP_H
+#define _XT_ESP_H
+
+struct xt_esp
+{
+ u_int32_t spis[2];
+ u_int8_t invflags;
+};
+
+#define XT_ESP_INV_SPI 0x01  
+#define XT_ESP_INV_MASK 0x01  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_helper.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_helper.h
new file mode 100644
index 0000000..6ffa451
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_helper.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_HELPER_H
+#define _XT_HELPER_H
+
+struct xt_helper_info {
+ int invert;
+ char name[30];
+};
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_length.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_length.h
new file mode 100644
index 0000000..12db6c7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_length.h
@@ -0,0 +1,20 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_LENGTH_H
+#define _XT_LENGTH_H
+
+struct xt_length_info {
+ u_int16_t min, max;
+ u_int8_t invert;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_limit.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_limit.h
new file mode 100644
index 0000000..f9fb37f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_limit.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_RATE_H
+#define _XT_RATE_H
+
+#define XT_LIMIT_SCALE 10000
+
+struct xt_rateinfo {
+ u_int32_t avg;
+ u_int32_t burst;
+
+ unsigned long prev;
+ u_int32_t credit;
+ u_int32_t credit_cap, cost;
+
+ struct xt_rateinfo *master;
+};
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_mac.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_mac.h
new file mode 100644
index 0000000..2473aab
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_mac.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_MAC_H
+#define _XT_MAC_H
+
+struct xt_mac_info {
+ unsigned char srcaddr[ETH_ALEN];
+ int invert;
+};
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_mark.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_mark.h
new file mode 100644
index 0000000..69699df
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_mark.h
@@ -0,0 +1,20 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_MARK_H
+#define _XT_MARK_H
+
+struct xt_mark_info {
+ unsigned long mark, mask;
+ u_int8_t invert;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_multiport.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_multiport.h
new file mode 100644
index 0000000..f17979a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_multiport.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_MULTIPORT_H
+#define _XT_MULTIPORT_H
+
+enum xt_multiport_flags
+{
+ XT_MULTIPORT_SOURCE,
+ XT_MULTIPORT_DESTINATION,
+ XT_MULTIPORT_EITHER
+};
+
+#define XT_MULTI_PORTS 15
+
+struct xt_multiport
+{
+ u_int8_t flags;
+ u_int8_t count;
+ u_int16_t ports[XT_MULTI_PORTS];
+};
+
+struct xt_multiport_v1
+{
+ u_int8_t flags;
+ u_int8_t count;
+ u_int16_t ports[XT_MULTI_PORTS];
+ u_int8_t pflags[XT_MULTI_PORTS];
+ u_int8_t invert;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_physdev.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_physdev.h
new file mode 100644
index 0000000..d0ca032
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_physdev.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_PHYSDEV_H
+#define _XT_PHYSDEV_H
+
+#define XT_PHYSDEV_OP_IN 0x01
+#define XT_PHYSDEV_OP_OUT 0x02
+#define XT_PHYSDEV_OP_BRIDGED 0x04
+#define XT_PHYSDEV_OP_ISIN 0x08
+#define XT_PHYSDEV_OP_ISOUT 0x10
+#define XT_PHYSDEV_OP_MASK (0x20 - 1)
+
+struct xt_physdev_info {
+ char physindev[IFNAMSIZ];
+ char in_mask[IFNAMSIZ];
+ char physoutdev[IFNAMSIZ];
+ char out_mask[IFNAMSIZ];
+ u_int8_t invert;
+ u_int8_t bitmask;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_pkttype.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_pkttype.h
new file mode 100644
index 0000000..32527b8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_pkttype.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_PKTTYPE_H
+#define _XT_PKTTYPE_H
+
+struct xt_pkttype_info {
+ int pkttype;
+ int invert;
+};
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_quota.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_quota.h
new file mode 100644
index 0000000..d34752d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_quota.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_QUOTA_H
+#define _XT_QUOTA_H
+
+enum xt_quota_flags {
+ XT_QUOTA_INVERT = 0x1,
+};
+#define XT_QUOTA_MASK 0x1
+
+struct xt_quota_info {
+ u_int32_t flags;
+ u_int32_t pad;
+ aligned_u64 quota;
+ struct xt_quota_info *master;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_realm.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_realm.h
new file mode 100644
index 0000000..1a2a3cf
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_realm.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_REALM_H
+#define _XT_REALM_H
+
+struct xt_realm_info {
+ u_int32_t id;
+ u_int32_t mask;
+ u_int8_t invert;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_sctp.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_sctp.h
new file mode 100644
index 0000000..f79c3b6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_sctp.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_SCTP_H_
+#define _XT_SCTP_H_
+
+#define XT_SCTP_SRC_PORTS 0x01
+#define XT_SCTP_DEST_PORTS 0x02
+#define XT_SCTP_CHUNK_TYPES 0x04
+
+#define XT_SCTP_VALID_FLAGS 0x07
+
+#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0]))
+
+struct xt_sctp_flag_info {
+ u_int8_t chunktype;
+ u_int8_t flag;
+ u_int8_t flag_mask;
+};
+
+#define XT_NUM_SCTP_FLAGS 4
+
+struct xt_sctp_info {
+ u_int16_t dpts[2];
+ u_int16_t spts[2];
+
+ u_int32_t chunkmap[256 / sizeof (u_int32_t)];
+
+#define SCTP_CHUNK_MATCH_ANY 0x01  
+#define SCTP_CHUNK_MATCH_ALL 0x02  
+#define SCTP_CHUNK_MATCH_ONLY 0x04  
+
+ u_int32_t chunk_match_type;
+ struct xt_sctp_flag_info flag_info[XT_NUM_SCTP_FLAGS];
+ int flag_count;
+
+ u_int32_t flags;
+ u_int32_t invflags;
+};
+
+#define bytes(type) (sizeof(type) * 8)
+
+#define SCTP_CHUNKMAP_SET(chunkmap, type)   do {   chunkmap[type / bytes(u_int32_t)] |=   1 << (type % bytes(u_int32_t));   } while (0)
+
+#define SCTP_CHUNKMAP_CLEAR(chunkmap, type)   do {   chunkmap[type / bytes(u_int32_t)] &=   ~(1 << (type % bytes(u_int32_t)));   } while (0)
+
+#define SCTP_CHUNKMAP_IS_SET(chunkmap, type)  ({   (chunkmap[type / bytes (u_int32_t)] &   (1 << (type % bytes (u_int32_t)))) ? 1: 0;  })
+
+#define SCTP_CHUNKMAP_RESET(chunkmap)   do {   int i;   for (i = 0; i < ELEMCOUNT(chunkmap); i++)   chunkmap[i] = 0;   } while (0)
+
+#define SCTP_CHUNKMAP_SET_ALL(chunkmap)   do {   int i;   for (i = 0; i < ELEMCOUNT(chunkmap); i++)   chunkmap[i] = ~0;   } while (0)
+
+#define SCTP_CHUNKMAP_COPY(destmap, srcmap)   do {   int i;   for (i = 0; i < ELEMCOUNT(chunkmap); i++)   destmap[i] = srcmap[i];   } while (0)
+
+#define SCTP_CHUNKMAP_IS_CLEAR(chunkmap)  ({   int i;   int flag = 1;   for (i = 0; i < ELEMCOUNT(chunkmap); i++) {   if (chunkmap[i]) {   flag = 0;   break;   }   }   flag;  })
+
+#define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap)  ({   int i;   int flag = 1;   for (i = 0; i < ELEMCOUNT(chunkmap); i++) {   if (chunkmap[i] != ~0) {   flag = 0;   break;   }   }   flag;  })
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_state.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_state.h
new file mode 100644
index 0000000..6754776
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_state.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_STATE_H
+#define _XT_STATE_H
+
+#define XT_STATE_BIT(ctinfo) (1 << ((ctinfo)%IP_CT_IS_REPLY+1))
+#define XT_STATE_INVALID (1 << 0)
+
+#define XT_STATE_UNTRACKED (1 << (IP_CT_NUMBER + 1))
+
+struct xt_state_info
+{
+ unsigned int statemask;
+};
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_statistic.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_statistic.h
new file mode 100644
index 0000000..999b0a1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_statistic.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_STATISTIC_H
+#define _XT_STATISTIC_H
+
+enum xt_statistic_mode {
+ XT_STATISTIC_MODE_RANDOM,
+ XT_STATISTIC_MODE_NTH,
+ __XT_STATISTIC_MODE_MAX
+};
+#define XT_STATISTIC_MODE_MAX (__XT_STATISTIC_MODE_MAX - 1)
+
+enum xt_statistic_flags {
+ XT_STATISTIC_INVERT = 0x1,
+};
+#define XT_STATISTIC_MASK 0x1
+
+struct xt_statistic_info {
+ u_int16_t mode;
+ u_int16_t flags;
+ union {
+ struct {
+ u_int32_t probability;
+ } random;
+ struct {
+ u_int32_t every;
+ u_int32_t packet;
+ u_int32_t count;
+ } nth;
+ } u;
+ struct xt_statistic_info *master __attribute__((aligned(8)));
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_string.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_string.h
new file mode 100644
index 0000000..a01018f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_string.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_STRING_H
+#define _XT_STRING_H
+
+#define XT_STRING_MAX_PATTERN_SIZE 128
+#define XT_STRING_MAX_ALGO_NAME_SIZE 16
+
+struct xt_string_info
+{
+ u_int16_t from_offset;
+ u_int16_t to_offset;
+ char algo[XT_STRING_MAX_ALGO_NAME_SIZE];
+ char pattern[XT_STRING_MAX_PATTERN_SIZE];
+ u_int8_t patlen;
+ u_int8_t invert;
+ struct ts_config __attribute__((aligned(8))) *config;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_tcpmss.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_tcpmss.h
new file mode 100644
index 0000000..33de0ee
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_tcpmss.h
@@ -0,0 +1,20 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_TCPMSS_MATCH_H
+#define _XT_TCPMSS_MATCH_H
+
+struct xt_tcpmss_match_info {
+ u_int16_t mss_min, mss_max;
+ u_int8_t invert;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_tcpudp.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_tcpudp.h
new file mode 100644
index 0000000..476fffb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter/xt_tcpudp.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XT_TCPUDP_H
+#define _XT_TCPUDP_H
+
+struct xt_tcp
+{
+ u_int16_t spts[2];
+ u_int16_t dpts[2];
+ u_int8_t option;
+ u_int8_t flg_mask;
+ u_int8_t flg_cmp;
+ u_int8_t invflags;
+};
+
+#define XT_TCP_INV_SRCPT 0x01  
+#define XT_TCP_INV_DSTPT 0x02  
+#define XT_TCP_INV_FLAGS 0x04  
+#define XT_TCP_INV_OPTION 0x08  
+#define XT_TCP_INV_MASK 0x0F  
+
+struct xt_udp
+{
+ u_int16_t spts[2];
+ u_int16_t dpts[2];
+ u_int8_t invflags;
+};
+
+#define XT_UDP_INV_SRCPT 0x01  
+#define XT_UDP_INV_DSTPT 0x02  
+#define XT_UDP_INV_MASK 0x03  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_arp.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_arp.h
new file mode 100644
index 0000000..08569db
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_arp.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_ARP_NETFILTER_H
+#define __LINUX_ARP_NETFILTER_H
+
+#include <linux/netfilter.h>
+
+#define NF_ARP 0
+
+#define NF_ARP_IN 0
+#define NF_ARP_OUT 1
+#define NF_ARP_FORWARD 2
+#define NF_ARP_NUMHOOKS 3
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_arp/arp_tables.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_arp/arp_tables.h
new file mode 100644
index 0000000..665a347
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_arp/arp_tables.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ARPTABLES_H
+#define _ARPTABLES_H
+
+#include <linux/compiler.h>
+#include <linux/netfilter_arp.h>
+
+#include <linux/netfilter/x_tables.h>
+
+#define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
+#define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
+#define arpt_target xt_target
+#define arpt_table xt_table
+
+#define ARPT_DEV_ADDR_LEN_MAX 16
+
+struct arpt_devaddr_info {
+ char addr[ARPT_DEV_ADDR_LEN_MAX];
+ char mask[ARPT_DEV_ADDR_LEN_MAX];
+};
+
+struct arpt_arp {
+
+ struct in_addr src, tgt;
+
+ struct in_addr smsk, tmsk;
+
+ u_int8_t arhln, arhln_mask;
+ struct arpt_devaddr_info src_devaddr;
+ struct arpt_devaddr_info tgt_devaddr;
+
+ u_int16_t arpop, arpop_mask;
+
+ u_int16_t arhrd, arhrd_mask;
+ u_int16_t arpro, arpro_mask;
+
+ char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
+ unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+
+ u_int8_t flags;
+
+ u_int16_t invflags;
+};
+
+#define arpt_entry_target xt_entry_target
+#define arpt_standard_target xt_standard_target
+
+#define ARPT_F_MASK 0x00  
+
+#define ARPT_INV_VIA_IN 0x0001  
+#define ARPT_INV_VIA_OUT 0x0002  
+#define ARPT_INV_SRCIP 0x0004  
+#define ARPT_INV_TGTIP 0x0008  
+#define ARPT_INV_SRCDEVADDR 0x0010  
+#define ARPT_INV_TGTDEVADDR 0x0020  
+#define ARPT_INV_ARPOP 0x0040  
+#define ARPT_INV_ARPHRD 0x0080  
+#define ARPT_INV_ARPPRO 0x0100  
+#define ARPT_INV_ARPHLN 0x0200  
+#define ARPT_INV_MASK 0x03FF  
+
+struct arpt_entry
+{
+ struct arpt_arp arp;
+
+ u_int16_t target_offset;
+
+ u_int16_t next_offset;
+
+ unsigned int comefrom;
+
+ struct xt_counters counters;
+
+ unsigned char elems[0];
+};
+
+#define ARPT_CTL_OFFSET 32
+#define ARPT_BASE_CTL (XT_BASE_CTL+ARPT_CTL_OFFSET)
+
+#define ARPT_SO_SET_REPLACE (XT_SO_SET_REPLACE+ARPT_CTL_OFFSET)
+#define ARPT_SO_SET_ADD_COUNTERS (XT_SO_SET_ADD_COUNTERS+ARPT_CTL_OFFSET)
+#define ARPT_SO_SET_MAX (XT_SO_SET_MAX+ARPT_CTL_OFFSET)
+
+#define ARPT_SO_GET_INFO (XT_SO_GET_INFO+ARPT_CTL_OFFSET)
+#define ARPT_SO_GET_ENTRIES (XT_SO_GET_ENTRIES+ARPT_CTL_OFFSET)
+
+#define ARPT_SO_GET_REVISION_TARGET (XT_SO_GET_REVISION_TARGET+ARPT_CTL_OFFSET)
+#define ARPT_SO_GET_MAX (XT_SO_GET_REVISION_TARGET+ARPT_CTL_OFFSET)
+
+#define ARPT_CONTINUE XT_CONTINUE
+
+#define ARPT_RETURN XT_RETURN
+
+struct arpt_getinfo
+{
+
+ char name[ARPT_TABLE_MAXNAMELEN];
+
+ unsigned int valid_hooks;
+
+ unsigned int hook_entry[NF_ARP_NUMHOOKS];
+
+ unsigned int underflow[NF_ARP_NUMHOOKS];
+
+ unsigned int num_entries;
+
+ unsigned int size;
+};
+
+struct arpt_replace
+{
+
+ char name[ARPT_TABLE_MAXNAMELEN];
+
+ unsigned int valid_hooks;
+
+ unsigned int num_entries;
+
+ unsigned int size;
+
+ unsigned int hook_entry[NF_ARP_NUMHOOKS];
+
+ unsigned int underflow[NF_ARP_NUMHOOKS];
+
+ unsigned int num_counters;
+
+ struct xt_counters __user *counters;
+
+ struct arpt_entry entries[0];
+};
+
+#define arpt_counters_info xt_counters_info
+
+struct arpt_get_entries
+{
+
+ char name[ARPT_TABLE_MAXNAMELEN];
+
+ unsigned int size;
+
+ struct arpt_entry entrytable[0];
+};
+
+#define ARPT_STANDARD_TARGET XT_STANDARD_TARGET
+
+#define ARPT_ERROR_TARGET XT_ERROR_TARGET
+
+#define ARPT_ENTRY_ITERATE(entries, size, fn, args...)  ({   unsigned int __i;   int __ret = 0;   struct arpt_entry *__entry;     for (__i = 0; __i < (size); __i += __entry->next_offset) {   __entry = (void *)(entries) + __i;     __ret = fn(__entry , ## args);   if (__ret != 0)   break;   }   __ret;  })
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_bridge.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_bridge.h
new file mode 100644
index 0000000..22cca55
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_bridge.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_BRIDGE_NETFILTER_H
+#define __LINUX_BRIDGE_NETFILTER_H
+
+#include <linux/netfilter.h>
+
+#define NF_BR_PRE_ROUTING 0
+
+#define NF_BR_LOCAL_IN 1
+
+#define NF_BR_FORWARD 2
+
+#define NF_BR_LOCAL_OUT 3
+
+#define NF_BR_POST_ROUTING 4
+
+#define NF_BR_BROUTING 5
+#define NF_BR_NUMHOOKS 6
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4.h
new file mode 100644
index 0000000..17fd451
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_IP_NETFILTER_H
+#define __LINUX_IP_NETFILTER_H
+
+#include <linux/netfilter.h>
+
+#define NFC_IP_SRC 0x0001
+
+#define NFC_IP_DST 0x0002
+
+#define NFC_IP_IF_IN 0x0004
+
+#define NFC_IP_IF_OUT 0x0008
+
+#define NFC_IP_TOS 0x0010
+
+#define NFC_IP_PROTO 0x0020
+
+#define NFC_IP_OPTIONS 0x0040
+
+#define NFC_IP_FRAG 0x0080
+
+#define NFC_IP_TCPFLAGS 0x0100
+
+#define NFC_IP_SRC_PT 0x0200
+
+#define NFC_IP_DST_PT 0x0400
+
+#define NFC_IP_PROTO_UNKNOWN 0x2000
+
+#define NF_IP_PRE_ROUTING 0
+
+#define NF_IP_LOCAL_IN 1
+
+#define NF_IP_FORWARD 2
+
+#define NF_IP_LOCAL_OUT 3
+
+#define NF_IP_POST_ROUTING 4
+#define NF_IP_NUMHOOKS 5
+
+enum nf_ip_hook_priorities {
+ NF_IP_PRI_FIRST = INT_MIN,
+ NF_IP_PRI_CONNTRACK_DEFRAG = -400,
+ NF_IP_PRI_RAW = -300,
+ NF_IP_PRI_SELINUX_FIRST = -225,
+ NF_IP_PRI_CONNTRACK = -200,
+ NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
+ NF_IP_PRI_MANGLE = -150,
+ NF_IP_PRI_NAT_DST = -100,
+ NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,
+ NF_IP_PRI_FILTER = 0,
+ NF_IP_PRI_NAT_SRC = 100,
+ NF_IP_PRI_SELINUX_LAST = 225,
+ NF_IP_PRI_CONNTRACK_HELPER = INT_MAX - 2,
+ NF_IP_PRI_NAT_SEQ_ADJUST = INT_MAX - 1,
+ NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
+ NF_IP_PRI_LAST = INT_MAX,
+};
+
+#define SO_ORIGINAL_DST 80
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_conntrack.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_conntrack.h
new file mode 100644
index 0000000..ef55a61
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP_CONNTRACK_H
+#define _IP_CONNTRACK_H
+
+#include <linux/netfilter/nf_conntrack_common.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_conntrack_tuple.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
new file mode 100644
index 0000000..0c96baf
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP_CONNTRACK_TUPLE_H
+#define _IP_CONNTRACK_TUPLE_H
+
+#include <linux/types.h>
+#include <linux/netfilter/nf_conntrack_tuple_common.h>
+
+union ip_conntrack_manip_proto
+{
+
+ u_int16_t all;
+
+ struct {
+ __be16 port;
+ } tcp;
+ struct {
+ u_int16_t port;
+ } udp;
+ struct {
+ u_int16_t id;
+ } icmp;
+ struct {
+ u_int16_t port;
+ } sctp;
+ struct {
+ __be16 key;
+ } gre;
+};
+
+struct ip_conntrack_manip
+{
+ u_int32_t ip;
+ union ip_conntrack_manip_proto u;
+};
+
+struct ip_conntrack_tuple
+{
+ struct ip_conntrack_manip src;
+
+ struct {
+ u_int32_t ip;
+ union {
+
+ u_int16_t all;
+
+ struct {
+ u_int16_t port;
+ } tcp;
+ struct {
+ u_int16_t port;
+ } udp;
+ struct {
+ u_int8_t type, code;
+ } icmp;
+ struct {
+ u_int16_t port;
+ } sctp;
+ struct {
+ __be16 key;
+ } gre;
+ } u;
+
+ u_int8_t protonum;
+
+ u_int8_t dir;
+ } dst;
+};
+
+#define IP_CT_TUPLE_U_BLANK(tuple)   do {   (tuple)->src.u.all = 0;   (tuple)->dst.u.all = 0;   } while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_nat.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_nat.h
new file mode 100644
index 0000000..7db9da3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_nat.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP_NAT_H
+#define _IP_NAT_H
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv4/ip_conntrack_tuple.h>
+
+#define IP_NAT_MAPPING_TYPE_MAX_NAMELEN 16
+
+enum ip_nat_manip_type
+{
+ IP_NAT_MANIP_SRC,
+ IP_NAT_MANIP_DST
+};
+
+#define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING && (hooknum) != NF_IP_LOCAL_IN)
+
+#define IP_NAT_RANGE_MAP_IPS 1
+#define IP_NAT_RANGE_PROTO_SPECIFIED 2
+
+struct ip_nat_seq {
+
+ u_int32_t correction_pos;
+
+ int16_t offset_before, offset_after;
+};
+
+struct ip_nat_range
+{
+
+ unsigned int flags;
+
+ u_int32_t min_ip, max_ip;
+
+ union ip_conntrack_manip_proto min, max;
+};
+
+struct ip_nat_multi_range_compat
+{
+ unsigned int rangesize;
+
+ struct ip_nat_range range[1];
+};
+
+#define ip_nat_multi_range ip_nat_multi_range_compat
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_nat_rule.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_nat_rule.h
new file mode 100644
index 0000000..b9db0b0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_nat_rule.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP_NAT_RULE_H
+#define _IP_NAT_RULE_H
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ip_nat.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_queue.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_queue.h
new file mode 100644
index 0000000..5d17a54
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_queue.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP_QUEUE_H
+#define _IP_QUEUE_H
+
+#include <net/if.h>
+
+typedef struct ipq_packet_msg {
+ unsigned long packet_id;
+ unsigned long mark;
+ long timestamp_sec;
+ long timestamp_usec;
+ unsigned int hook;
+ char indev_name[IFNAMSIZ];
+ char outdev_name[IFNAMSIZ];
+ unsigned short hw_protocol;
+ unsigned short hw_type;
+ unsigned char hw_addrlen;
+ unsigned char hw_addr[8];
+ size_t data_len;
+ unsigned char payload[0];
+} ipq_packet_msg_t;
+
+typedef struct ipq_mode_msg {
+ unsigned char value;
+ size_t range;
+} ipq_mode_msg_t;
+
+typedef struct ipq_verdict_msg {
+ unsigned int value;
+ unsigned long id;
+ size_t data_len;
+ unsigned char payload[0];
+} ipq_verdict_msg_t;
+
+typedef struct ipq_peer_msg {
+ union {
+ ipq_verdict_msg_t verdict;
+ ipq_mode_msg_t mode;
+ } msg;
+} ipq_peer_msg_t;
+
+enum {
+ IPQ_COPY_NONE,
+ IPQ_COPY_META,
+ IPQ_COPY_PACKET
+};
+#define IPQ_COPY_MAX IPQ_COPY_PACKET
+
+#define IPQM_BASE 0x10  
+#define IPQM_MODE (IPQM_BASE + 1)  
+#define IPQM_VERDICT (IPQM_BASE + 2)   
+#define IPQM_PACKET (IPQM_BASE + 3)  
+#define IPQM_MAX (IPQM_BASE + 4)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_tables.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_tables.h
new file mode 100644
index 0000000..aa48305
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ip_tables.h
@@ -0,0 +1,180 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPTABLES_H
+#define _IPTABLES_H
+
+#include <linux/compiler.h>
+#include <linux/netfilter_ipv4.h>
+
+#include <linux/netfilter/x_tables.h>
+
+#define IPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
+#define IPT_TABLE_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
+#define ipt_match xt_match
+#define ipt_target xt_target
+#define ipt_table xt_table
+#define ipt_get_revision xt_get_revision
+
+struct ipt_ip {
+
+ struct in_addr src, dst;
+
+ struct in_addr smsk, dmsk;
+ char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
+ unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+
+ u_int16_t proto;
+
+ u_int8_t flags;
+
+ u_int8_t invflags;
+};
+
+#define ipt_entry_match xt_entry_match
+#define ipt_entry_target xt_entry_target
+#define ipt_standard_target xt_standard_target
+
+#define ipt_counters xt_counters
+
+#define IPT_F_FRAG 0x01  
+#define IPT_F_GOTO 0x02  
+#define IPT_F_MASK 0x03  
+
+#define IPT_INV_VIA_IN 0x01  
+#define IPT_INV_VIA_OUT 0x02  
+#define IPT_INV_TOS 0x04  
+#define IPT_INV_SRCIP 0x08  
+#define IPT_INV_DSTIP 0x10  
+#define IPT_INV_FRAG 0x20  
+#define IPT_INV_PROTO XT_INV_PROTO
+#define IPT_INV_MASK 0x7F  
+
+struct ipt_entry
+{
+ struct ipt_ip ip;
+
+ unsigned int nfcache;
+
+ u_int16_t target_offset;
+
+ u_int16_t next_offset;
+
+ unsigned int comefrom;
+
+ struct xt_counters counters;
+
+ unsigned char elems[0];
+};
+
+#define IPT_BASE_CTL XT_BASE_CTL
+
+#define IPT_SO_SET_REPLACE XT_SO_SET_REPLACE
+#define IPT_SO_SET_ADD_COUNTERS XT_SO_SET_ADD_COUNTERS
+#define IPT_SO_SET_MAX XT_SO_SET_MAX
+
+#define IPT_SO_GET_INFO XT_SO_GET_INFO
+#define IPT_SO_GET_ENTRIES XT_SO_GET_ENTRIES
+#define IPT_SO_GET_REVISION_MATCH XT_SO_GET_REVISION_MATCH
+#define IPT_SO_GET_REVISION_TARGET XT_SO_GET_REVISION_TARGET
+#define IPT_SO_GET_MAX XT_SO_GET_REVISION_TARGET
+
+#define IPT_CONTINUE XT_CONTINUE
+#define IPT_RETURN XT_RETURN
+
+#include <linux/netfilter/xt_tcpudp.h>
+#define ipt_udp xt_udp
+#define ipt_tcp xt_tcp
+
+#define IPT_TCP_INV_SRCPT XT_TCP_INV_SRCPT
+#define IPT_TCP_INV_DSTPT XT_TCP_INV_DSTPT
+#define IPT_TCP_INV_FLAGS XT_TCP_INV_FLAGS
+#define IPT_TCP_INV_OPTION XT_TCP_INV_OPTION
+#define IPT_TCP_INV_MASK XT_TCP_INV_MASK
+
+#define IPT_UDP_INV_SRCPT XT_UDP_INV_SRCPT
+#define IPT_UDP_INV_DSTPT XT_UDP_INV_DSTPT
+#define IPT_UDP_INV_MASK XT_UDP_INV_MASK
+
+struct ipt_icmp
+{
+ u_int8_t type;
+ u_int8_t code[2];
+ u_int8_t invflags;
+};
+
+#define IPT_ICMP_INV 0x01  
+
+struct ipt_getinfo
+{
+
+ char name[IPT_TABLE_MAXNAMELEN];
+
+ unsigned int valid_hooks;
+
+ unsigned int hook_entry[NF_IP_NUMHOOKS];
+
+ unsigned int underflow[NF_IP_NUMHOOKS];
+
+ unsigned int num_entries;
+
+ unsigned int size;
+};
+
+struct ipt_replace
+{
+
+ char name[IPT_TABLE_MAXNAMELEN];
+
+ unsigned int valid_hooks;
+
+ unsigned int num_entries;
+
+ unsigned int size;
+
+ unsigned int hook_entry[NF_IP_NUMHOOKS];
+
+ unsigned int underflow[NF_IP_NUMHOOKS];
+
+ unsigned int num_counters;
+
+ struct xt_counters __user *counters;
+
+ struct ipt_entry entries[0];
+};
+
+#define ipt_counters_info xt_counters_info
+
+struct ipt_get_entries
+{
+
+ char name[IPT_TABLE_MAXNAMELEN];
+
+ unsigned int size;
+
+ struct ipt_entry entrytable[0];
+};
+
+#define IPT_STANDARD_TARGET XT_STANDARD_TARGET
+
+#define IPT_ERROR_TARGET XT_ERROR_TARGET
+
+static __inline__ struct ipt_entry_target *
+ipt_get_target(struct ipt_entry *e)
+{
+ return (void *)e + e->target_offset;
+}
+
+#define IPT_MATCH_ITERATE(e, fn, args...)  ({   unsigned int __i;   int __ret = 0;   struct ipt_entry_match *__match;     for (__i = sizeof(struct ipt_entry);   __i < (e)->target_offset;   __i += __match->u.match_size) {   __match = (void *)(e) + __i;     __ret = fn(__match , ## args);   if (__ret != 0)   break;   }   __ret;  })
+
+#define IPT_ENTRY_ITERATE(entries, size, fn, args...)  ({   unsigned int __i;   int __ret = 0;   struct ipt_entry *__entry;     for (__i = 0; __i < (size); __i += __entry->next_offset) {   __entry = (void *)(entries) + __i;     __ret = fn(__entry , ## args);   if (__ret != 0)   break;   }   __ret;  })
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_CLASSIFY.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_CLASSIFY.h
new file mode 100644
index 0000000..a738edd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_CLASSIFY.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_CLASSIFY_H
+#define _IPT_CLASSIFY_H
+
+#include <linux/netfilter/xt_CLASSIFY.h>
+#define ipt_classify_target_info xt_classify_target_info
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_DSCP.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_DSCP.h
new file mode 100644
index 0000000..0271fb2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_DSCP.h
@@ -0,0 +1,20 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_DSCP_TARGET_H
+#define _IPT_DSCP_TARGET_H
+#include <linux/netfilter_ipv4/ipt_dscp.h>
+
+struct ipt_DSCP_info {
+ u_int8_t dscp;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_ECN.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_ECN.h
new file mode 100644
index 0000000..67c16fe
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_ECN.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_ECN_TARGET_H
+#define _IPT_ECN_TARGET_H
+#include <linux/netfilter_ipv4/ipt_DSCP.h>
+
+#define IPT_ECN_IP_MASK (~IPT_DSCP_MASK)
+
+#define IPT_ECN_OP_SET_IP 0x01  
+#define IPT_ECN_OP_SET_ECE 0x10  
+#define IPT_ECN_OP_SET_CWR 0x20  
+
+#define IPT_ECN_OP_MASK 0xce
+
+struct ipt_ECN_info {
+ u_int8_t operation;
+ u_int8_t ip_ect;
+ union {
+ struct {
+ u_int8_t ece:1, cwr:1;
+ } tcp;
+ } proto;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_LOG.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_LOG.h
new file mode 100644
index 0000000..dd6fd1b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_LOG.h
@@ -0,0 +1,28 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_LOG_H
+#define _IPT_LOG_H
+
+#define IPT_LOG_TCPSEQ 0x01  
+#define IPT_LOG_TCPOPT 0x02  
+#define IPT_LOG_IPOPT 0x04  
+#define IPT_LOG_UID 0x08  
+#define IPT_LOG_NFLOG 0x10  
+#define IPT_LOG_MASK 0x1f
+
+struct ipt_log_info {
+ unsigned char level;
+ unsigned char logflags;
+ char prefix[30];
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_NFQUEUE.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_NFQUEUE.h
new file mode 100644
index 0000000..27ac4a5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_NFQUEUE.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_NFQ_TARGET_H
+#define _IPT_NFQ_TARGET_H
+
+#include <linux/netfilter/xt_NFQUEUE.h>
+
+#define ipt_NFQ_info xt_NFQ_info
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_REJECT.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_REJECT.h
new file mode 100644
index 0000000..d3c3965
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_REJECT.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_REJECT_H
+#define _IPT_REJECT_H
+
+enum ipt_reject_with {
+ IPT_ICMP_NET_UNREACHABLE,
+ IPT_ICMP_HOST_UNREACHABLE,
+ IPT_ICMP_PROT_UNREACHABLE,
+ IPT_ICMP_PORT_UNREACHABLE,
+ IPT_ICMP_ECHOREPLY,
+ IPT_ICMP_NET_PROHIBITED,
+ IPT_ICMP_HOST_PROHIBITED,
+ IPT_TCP_RESET,
+ IPT_ICMP_ADMIN_PROHIBITED
+};
+
+struct ipt_reject_info {
+ enum ipt_reject_with with;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_TCPMSS.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_TCPMSS.h
new file mode 100644
index 0000000..e924f37
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_TCPMSS.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_TCPMSS_H
+#define _IPT_TCPMSS_H
+
+struct ipt_tcpmss_info {
+ u_int16_t mss;
+};
+
+#define IPT_TCPMSS_CLAMP_PMTU 0xffff
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_TOS.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_TOS.h
new file mode 100644
index 0000000..1cc2116
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_TOS.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_TOS_H_target
+#define _IPT_TOS_H_target
+
+#ifndef IPTOS_NORMALSVC
+#define IPTOS_NORMALSVC 0
+#endif
+
+struct ipt_tos_target_info {
+ u_int8_t tos;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_TTL.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_TTL.h
new file mode 100644
index 0000000..f9e98af
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_TTL.h
@@ -0,0 +1,28 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_TTL_H
+#define _IPT_TTL_H
+
+enum {
+ IPT_TTL_SET = 0,
+ IPT_TTL_INC,
+ IPT_TTL_DEC
+};
+
+#define IPT_TTL_MAXMODE IPT_TTL_DEC
+
+struct ipt_TTL_info {
+ u_int8_t mode;
+ u_int8_t ttl;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_ULOG.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_ULOG.h
new file mode 100644
index 0000000..9511cb8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_ULOG.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_ULOG_H
+#define _IPT_ULOG_H
+
+#ifndef NETLINK_NFLOG
+#define NETLINK_NFLOG 5
+#endif
+
+#define ULOG_DEFAULT_NLGROUP 1
+#define ULOG_DEFAULT_QTHRESHOLD 1
+
+#define ULOG_MAC_LEN 80
+#define ULOG_PREFIX_LEN 32
+
+#define ULOG_MAX_QLEN 50
+
+struct ipt_ulog_info {
+ unsigned int nl_group;
+ size_t copy_range;
+ size_t qthreshold;
+ char prefix[ULOG_PREFIX_LEN];
+};
+
+typedef struct ulog_packet_msg {
+ unsigned long mark;
+ long timestamp_sec;
+ long timestamp_usec;
+ unsigned int hook;
+ char indev_name[IFNAMSIZ];
+ char outdev_name[IFNAMSIZ];
+ size_t data_len;
+ char prefix[ULOG_PREFIX_LEN];
+ unsigned char mac_len;
+ unsigned char mac[ULOG_MAC_LEN];
+ unsigned char payload[0];
+} ulog_packet_msg_t;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_addrtype.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_addrtype.h
new file mode 100644
index 0000000..5203b32
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_addrtype.h
@@ -0,0 +1,22 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_ADDRTYPE_H
+#define _IPT_ADDRTYPE_H
+
+struct ipt_addrtype_info {
+ u_int16_t source;
+ u_int16_t dest;
+ u_int32_t invert_source;
+ u_int32_t invert_dest;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_ah.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_ah.h
new file mode 100644
index 0000000..11983e2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_ah.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_AH_H
+#define _IPT_AH_H
+
+struct ipt_ah
+{
+ u_int32_t spis[2];
+ u_int8_t invflags;
+};
+
+#define IPT_AH_INV_SPI 0x01  
+#define IPT_AH_INV_MASK 0x01  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_comment.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_comment.h
new file mode 100644
index 0000000..dbd7507
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_comment.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_COMMENT_H
+#define _IPT_COMMENT_H
+
+#include <linux/netfilter/xt_comment.h>
+
+#define IPT_MAX_COMMENT_LEN XT_MAX_COMMENT_LEN
+
+#define ipt_comment_info xt_comment_info
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_connbytes.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_connbytes.h
new file mode 100644
index 0000000..8ae19c5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_connbytes.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_CONNBYTES_H
+#define _IPT_CONNBYTES_H
+
+#include <linux/netfilter/xt_connbytes.h>
+#define ipt_connbytes_what xt_connbytes_what
+
+#define IPT_CONNBYTES_PKTS XT_CONNBYTES_PKTS
+#define IPT_CONNBYTES_BYTES XT_CONNBYTES_BYTES
+#define IPT_CONNBYTES_AVGPKT XT_CONNBYTES_AVGPKT
+
+#define ipt_connbytes_direction xt_connbytes_direction
+#define IPT_CONNBYTES_DIR_ORIGINAL XT_CONNBYTES_DIR_ORIGINAL
+#define IPT_CONNBYTES_DIR_REPLY XT_CONNBYTES_DIR_REPLY
+#define IPT_CONNBYTES_DIR_BOTH XT_CONNBYTES_DIR_BOTH
+
+#define ipt_connbytes_info xt_connbytes_info
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_dccp.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_dccp.h
new file mode 100644
index 0000000..c1212c9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_dccp.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_DCCP_H_
+#define _IPT_DCCP_H_
+
+#include <linux/netfilter/xt_dccp.h>
+#define IPT_DCCP_SRC_PORTS XT_DCCP_SRC_PORTS
+#define IPT_DCCP_DEST_PORTS XT_DCCP_DEST_PORTS
+#define IPT_DCCP_TYPE XT_DCCP_TYPE
+#define IPT_DCCP_OPTION XT_DCCP_OPTION
+
+#define IPT_DCCP_VALID_FLAGS XT_DCCP_VALID_FLAGS
+
+#define ipt_dccp_info xt_dccp_info
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_dscp_.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_dscp_.h
new file mode 100644
index 0000000..aba8861
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_dscp_.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_DSCP_H
+#define _IPT_DSCP_H
+
+#define IPT_DSCP_MASK 0xfc  
+#define IPT_DSCP_SHIFT 2
+#define IPT_DSCP_MAX 0x3f  
+
+struct ipt_dscp_info {
+ u_int8_t dscp;
+ u_int8_t invert;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_esp.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_esp.h
new file mode 100644
index 0000000..4947e7e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_esp.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_ESP_H
+#define _IPT_ESP_H
+
+#include <linux/netfilter/xt_esp.h>
+
+#define ipt_esp xt_esp
+#define IPT_ESP_INV_SPI XT_ESP_INV_SPI
+#define IPT_ESP_INV_MASK XT_ESP_INV_MASK
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_hashlimit.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_hashlimit.h
new file mode 100644
index 0000000..adc1f41
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_hashlimit.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_HASHLIMIT_H
+#define _IPT_HASHLIMIT_H
+
+#define IPT_HASHLIMIT_SCALE 10000
+
+struct ipt_hashlimit_htable;
+
+#define IPT_HASHLIMIT_HASH_DIP 0x0001
+#define IPT_HASHLIMIT_HASH_DPT 0x0002
+#define IPT_HASHLIMIT_HASH_SIP 0x0004
+#define IPT_HASHLIMIT_HASH_SPT 0x0008
+
+struct hashlimit_cfg {
+ u_int32_t mode;
+ u_int32_t avg;
+ u_int32_t burst;
+
+ u_int32_t size;
+ u_int32_t max;
+ u_int32_t gc_interval;
+ u_int32_t expire;
+};
+
+struct ipt_hashlimit_info {
+ char name [IFNAMSIZ];
+ struct hashlimit_cfg cfg;
+ struct ipt_hashlimit_htable *hinfo;
+
+ union {
+ void *ptr;
+ struct ipt_hashlimit_info *master;
+ } u;
+};
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_helper.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_helper.h
new file mode 100644
index 0000000..576add9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_helper.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_HELPER_H
+#define _IPT_HELPER_H
+
+#include <linux/netfilter/xt_helper.h>
+#define ipt_helper_info xt_helper_info
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_iprange.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_iprange.h
new file mode 100644
index 0000000..b4dd603
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_iprange.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_IPRANGE_H
+#define _IPT_IPRANGE_H
+
+#define IPRANGE_SRC 0x01  
+#define IPRANGE_DST 0x02  
+#define IPRANGE_SRC_INV 0x10  
+#define IPRANGE_DST_INV 0x20  
+
+struct ipt_iprange {
+
+ u_int32_t min_ip, max_ip;
+};
+
+struct ipt_iprange_info
+{
+ struct ipt_iprange src;
+ struct ipt_iprange dst;
+
+ u_int8_t flags;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_length.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_length.h
new file mode 100644
index 0000000..9610859
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_length.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_LENGTH_H
+#define _IPT_LENGTH_H
+
+#include <linux/netfilter/xt_length.h>
+#define ipt_length_info xt_length_info
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_mac.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_mac.h
new file mode 100644
index 0000000..89378a3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_mac.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_MAC_H
+#define _IPT_MAC_H
+
+#include <linux/netfilter/xt_mac.h>
+#define ipt_mac_info xt_mac_info
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_owner.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_owner.h
new file mode 100644
index 0000000..8b742b1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_owner.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_OWNER_H
+#define _IPT_OWNER_H
+
+#define IPT_OWNER_UID 0x01
+#define IPT_OWNER_GID 0x02
+#define IPT_OWNER_PID 0x04
+#define IPT_OWNER_SID 0x08
+#define IPT_OWNER_COMM 0x10
+
+struct ipt_owner_info {
+ uid_t uid;
+ gid_t gid;
+ pid_t pid;
+ pid_t sid;
+ char comm[16];
+ u_int8_t match, invert;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_physdev.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_physdev.h
new file mode 100644
index 0000000..791cf02
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_physdev.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_PHYSDEV_H
+#define _IPT_PHYSDEV_H
+
+#include <linux/netfilter/xt_physdev.h>
+
+#define IPT_PHYSDEV_OP_IN XT_PHYSDEV_OP_IN
+#define IPT_PHYSDEV_OP_OUT XT_PHYSDEV_OP_OUT
+#define IPT_PHYSDEV_OP_BRIDGED XT_PHYSDEV_OP_BRIDGED
+#define IPT_PHYSDEV_OP_ISIN XT_PHYSDEV_OP_ISIN
+#define IPT_PHYSDEV_OP_ISOUT XT_PHYSDEV_OP_ISOUT
+#define IPT_PHYSDEV_OP_MASK XT_PHYSDEV_OP_MASK
+
+#define ipt_physdev_info xt_physdev_info
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_pkttype.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_pkttype.h
new file mode 100644
index 0000000..fbb20b1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_pkttype.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_PKTTYPE_H
+#define _IPT_PKTTYPE_H
+
+#include <linux/netfilter/xt_pkttype.h>
+#define ipt_pkttype_info xt_pkttype_info
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_realm.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_realm.h
new file mode 100644
index 0000000..9b80faa
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_realm.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_REALM_H
+#define _IPT_REALM_H
+
+#include <linux/netfilter/xt_realm.h>
+#define ipt_realm_info xt_realm_info
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_recent.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_recent.h
new file mode 100644
index 0000000..45172bd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_recent.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_RECENT_H
+#define _IPT_RECENT_H
+
+#define RECENT_NAME "ipt_recent"
+#define RECENT_VER "v0.3.1"
+
+#define IPT_RECENT_CHECK 1
+#define IPT_RECENT_SET 2
+#define IPT_RECENT_UPDATE 4
+#define IPT_RECENT_REMOVE 8
+#define IPT_RECENT_TTL 16
+
+#define IPT_RECENT_SOURCE 0
+#define IPT_RECENT_DEST 1
+
+#define IPT_RECENT_NAME_LEN 200
+
+struct ipt_recent_info {
+ u_int32_t seconds;
+ u_int32_t hit_count;
+ u_int8_t check_set;
+ u_int8_t invert;
+ char name[IPT_RECENT_NAME_LEN];
+ u_int8_t side;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_sctp.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_sctp.h
new file mode 100644
index 0000000..20f301f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_sctp.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_SCTP_H_
+#define _IPT_SCTP_H_
+
+#define IPT_SCTP_SRC_PORTS 0x01
+#define IPT_SCTP_DEST_PORTS 0x02
+#define IPT_SCTP_CHUNK_TYPES 0x04
+
+#define IPT_SCTP_VALID_FLAGS 0x07
+
+struct ipt_sctp_flag_info {
+ u_int8_t chunktype;
+ u_int8_t flag;
+ u_int8_t flag_mask;
+};
+
+#define IPT_NUM_SCTP_FLAGS 4
+
+struct ipt_sctp_info {
+ u_int16_t dpts[2];
+ u_int16_t spts[2];
+
+ u_int32_t chunkmap[256 / sizeof (u_int32_t)];
+
+#define SCTP_CHUNK_MATCH_ANY 0x01  
+#define SCTP_CHUNK_MATCH_ALL 0x02  
+#define SCTP_CHUNK_MATCH_ONLY 0x04  
+
+ u_int32_t chunk_match_type;
+ struct ipt_sctp_flag_info flag_info[IPT_NUM_SCTP_FLAGS];
+ int flag_count;
+
+ u_int32_t flags;
+ u_int32_t invflags;
+};
+
+#define bytes(type) (sizeof(type) * 8)
+
+#define SCTP_CHUNKMAP_SET(chunkmap, type)   do {   chunkmap[type / bytes(u_int32_t)] |=   1 << (type % bytes(u_int32_t));   } while (0)
+
+#define SCTP_CHUNKMAP_CLEAR(chunkmap, type)   do {   chunkmap[type / bytes(u_int32_t)] &=   ~(1 << (type % bytes(u_int32_t)));   } while (0)
+
+#define SCTP_CHUNKMAP_IS_SET(chunkmap, type)  ({   (chunkmap[type / bytes (u_int32_t)] &   (1 << (type % bytes (u_int32_t)))) ? 1: 0;  })
+
+#define SCTP_CHUNKMAP_RESET(chunkmap)   do {   int i;   for (i = 0; i < ARRAY_SIZE(chunkmap); i++)   chunkmap[i] = 0;   } while (0)
+
+#define SCTP_CHUNKMAP_SET_ALL(chunkmap)   do {   int i;   for (i = 0; i < ARRAY_SIZE(chunkmap); i++)   chunkmap[i] = ~0;   } while (0)
+
+#define SCTP_CHUNKMAP_COPY(destmap, srcmap)   do {   int i;   for (i = 0; i < ARRAY_SIZE(chunkmap); i++)   destmap[i] = srcmap[i];   } while (0)
+
+#define SCTP_CHUNKMAP_IS_CLEAR(chunkmap)  ({   int i;   int flag = 1;   for (i = 0; i < ARRAY_SIZE(chunkmap); i++) {   if (chunkmap[i]) {   flag = 0;   break;   }   }   flag;  })
+
+#define SCTP_CHUNKMAP_IS_ALL_SET(chunkmap)  ({   int i;   int flag = 1;   for (i = 0; i < ARRAY_SIZE(chunkmap); i++) {   if (chunkmap[i] != ~0) {   flag = 0;   break;   }   }   flag;  })
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_state.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_state.h
new file mode 100644
index 0000000..bd51990
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_state.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_STATE_H
+#define _IPT_STATE_H
+
+#include <linux/netfilter/xt_state.h>
+
+#define IPT_STATE_BIT XT_STATE_BIT
+#define IPT_STATE_INVALID XT_STATE_INVALID
+
+#define IPT_STATE_UNTRACKED XT_STATE_UNTRACKED
+
+#define ipt_state_info xt_state_info
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_string.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_string.h
new file mode 100644
index 0000000..60923dd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_string.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_STRING_H
+#define _IPT_STRING_H
+
+#include <linux/netfilter/xt_string.h>
+
+#define IPT_STRING_MAX_PATTERN_SIZE XT_STRING_MAX_PATTERN_SIZE
+#define IPT_STRING_MAX_ALGO_NAME_SIZE XT_STRING_MAX_ALGO_NAME_SIZE
+#define ipt_string_info xt_string_info
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_tos_.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_tos_.h
new file mode 100644
index 0000000..789ce22
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv4/ipt_tos_.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IPT_TOS_H
+#define _IPT_TOS_H
+
+struct ipt_tos_info {
+ u_int8_t tos;
+ u_int8_t invert;
+};
+
+#ifndef IPTOS_NORMALSVC
+#define IPTOS_NORMALSVC 0
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6.h
new file mode 100644
index 0000000..0d68cd9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_IP6_NETFILTER_H
+#define __LINUX_IP6_NETFILTER_H
+
+#include <linux/netfilter.h>
+
+#define NFC_IP6_SRC 0x0001
+
+#define NFC_IP6_DST 0x0002
+
+#define NFC_IP6_IF_IN 0x0004
+
+#define NFC_IP6_IF_OUT 0x0008
+
+#define NFC_IP6_TOS 0x0010
+
+#define NFC_IP6_PROTO 0x0020
+
+#define NFC_IP6_OPTIONS 0x0040
+
+#define NFC_IP6_FRAG 0x0080
+
+#define NFC_IP6_TCPFLAGS 0x0100
+
+#define NFC_IP6_SRC_PT 0x0200
+
+#define NFC_IP6_DST_PT 0x0400
+
+#define NFC_IP6_PROTO_UNKNOWN 0x2000
+
+#define NF_IP6_PRE_ROUTING 0
+
+#define NF_IP6_LOCAL_IN 1
+
+#define NF_IP6_FORWARD 2
+
+#define NF_IP6_LOCAL_OUT 3
+
+#define NF_IP6_POST_ROUTING 4
+#define NF_IP6_NUMHOOKS 5
+
+enum nf_ip6_hook_priorities {
+ NF_IP6_PRI_FIRST = INT_MIN,
+ NF_IP6_PRI_CONNTRACK_DEFRAG = -400,
+ NF_IP6_PRI_SELINUX_FIRST = -225,
+ NF_IP6_PRI_CONNTRACK = -200,
+ NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD = -175,
+ NF_IP6_PRI_MANGLE = -150,
+ NF_IP6_PRI_NAT_DST = -100,
+ NF_IP6_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50,
+ NF_IP6_PRI_FILTER = 0,
+ NF_IP6_PRI_NAT_SRC = 100,
+ NF_IP6_PRI_SELINUX_LAST = 225,
+ NF_IP6_PRI_LAST = INT_MAX,
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6_tables.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6_tables.h
new file mode 100644
index 0000000..1687e4f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6_tables.h
@@ -0,0 +1,178 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP6_TABLES_H
+#define _IP6_TABLES_H
+
+#include <linux/compiler.h>
+#include <linux/netfilter_ipv6.h>
+
+#include <linux/netfilter/x_tables.h>
+
+#define IP6T_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
+#define IP6T_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
+
+#define ip6t_match xt_match
+#define ip6t_target xt_target
+#define ip6t_table xt_table
+#define ip6t_get_revision xt_get_revision
+
+struct ip6t_ip6 {
+
+ struct in6_addr src, dst;
+
+ struct in6_addr smsk, dmsk;
+ char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
+ unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+
+ u_int16_t proto;
+
+ u_int8_t tos;
+
+ u_int8_t flags;
+
+ u_int8_t invflags;
+};
+
+#define ip6t_entry_match xt_entry_match
+#define ip6t_entry_target xt_entry_target
+#define ip6t_standard_target xt_standard_target
+
+#define ip6t_counters xt_counters
+
+#define IP6T_F_PROTO 0x01  
+#define IP6T_F_TOS 0x02  
+#define IP6T_F_GOTO 0x04  
+#define IP6T_F_MASK 0x07  
+
+#define IP6T_INV_VIA_IN 0x01  
+#define IP6T_INV_VIA_OUT 0x02  
+#define IP6T_INV_TOS 0x04  
+#define IP6T_INV_SRCIP 0x08  
+#define IP6T_INV_DSTIP 0x10  
+#define IP6T_INV_FRAG 0x20  
+#define IP6T_INV_PROTO XT_INV_PROTO
+#define IP6T_INV_MASK 0x7F  
+
+struct ip6t_entry
+{
+ struct ip6t_ip6 ipv6;
+
+ unsigned int nfcache;
+
+ u_int16_t target_offset;
+
+ u_int16_t next_offset;
+
+ unsigned int comefrom;
+
+ struct xt_counters counters;
+
+ unsigned char elems[0];
+};
+
+#define IP6T_BASE_CTL XT_BASE_CTL
+
+#define IP6T_SO_SET_REPLACE XT_SO_SET_REPLACE
+#define IP6T_SO_SET_ADD_COUNTERS XT_SO_SET_ADD_COUNTERS
+#define IP6T_SO_SET_MAX XT_SO_SET_MAX
+
+#define IP6T_SO_GET_INFO XT_SO_GET_INFO
+#define IP6T_SO_GET_ENTRIES XT_SO_GET_ENTRIES
+#define IP6T_SO_GET_REVISION_MATCH XT_SO_GET_REVISION_MATCH
+#define IP6T_SO_GET_REVISION_TARGET XT_SO_GET_REVISION_TARGET
+#define IP6T_SO_GET_MAX XT_SO_GET_REVISION_TARGET
+
+#define IP6T_CONTINUE XT_CONTINUE
+
+#define IP6T_RETURN XT_RETURN
+
+#include <linux/netfilter/xt_tcpudp.h>
+
+#define ip6t_tcp xt_tcp
+#define ip6t_udp xt_udp
+
+#define IP6T_TCP_INV_SRCPT XT_TCP_INV_SRCPT
+#define IP6T_TCP_INV_DSTPT XT_TCP_INV_DSTPT
+#define IP6T_TCP_INV_FLAGS XT_TCP_INV_FLAGS
+#define IP6T_TCP_INV_OPTION XT_TCP_INV_OPTION
+#define IP6T_TCP_INV_MASK XT_TCP_INV_MASK
+
+#define IP6T_UDP_INV_SRCPT XT_UDP_INV_SRCPT
+#define IP6T_UDP_INV_DSTPT XT_UDP_INV_DSTPT
+#define IP6T_UDP_INV_MASK XT_UDP_INV_MASK
+
+struct ip6t_icmp
+{
+ u_int8_t type;
+ u_int8_t code[2];
+ u_int8_t invflags;
+};
+
+#define IP6T_ICMP_INV 0x01  
+
+struct ip6t_getinfo
+{
+
+ char name[IP6T_TABLE_MAXNAMELEN];
+
+ unsigned int valid_hooks;
+
+ unsigned int hook_entry[NF_IP6_NUMHOOKS];
+
+ unsigned int underflow[NF_IP6_NUMHOOKS];
+
+ unsigned int num_entries;
+
+ unsigned int size;
+};
+
+struct ip6t_replace
+{
+
+ char name[IP6T_TABLE_MAXNAMELEN];
+
+ unsigned int valid_hooks;
+
+ unsigned int num_entries;
+
+ unsigned int size;
+
+ unsigned int hook_entry[NF_IP6_NUMHOOKS];
+
+ unsigned int underflow[NF_IP6_NUMHOOKS];
+
+ unsigned int num_counters;
+
+ struct xt_counters __user *counters;
+
+ struct ip6t_entry entries[0];
+};
+
+#define ip6t_counters_info xt_counters_info
+
+struct ip6t_get_entries
+{
+
+ char name[IP6T_TABLE_MAXNAMELEN];
+
+ unsigned int size;
+
+ struct ip6t_entry entrytable[0];
+};
+
+#define IP6T_STANDARD_TARGET XT_STANDARD_TARGET
+
+#define IP6T_ERROR_TARGET XT_ERROR_TARGET
+
+#define IP6T_MATCH_ITERATE(e, fn, args...)  ({   unsigned int __i;   int __ret = 0;   struct ip6t_entry_match *__m;     for (__i = sizeof(struct ip6t_entry);   __i < (e)->target_offset;   __i += __m->u.match_size) {   __m = (void *)(e) + __i;     __ret = fn(__m , ## args);   if (__ret != 0)   break;   }   __ret;  })
+#define IP6T_ENTRY_ITERATE(entries, size, fn, args...)  ({   unsigned int __i;   int __ret = 0;   struct ip6t_entry *__e;     for (__i = 0; __i < (size); __i += __e->next_offset) {   __e = (void *)(entries) + __i;     __ret = fn(__e , ## args);   if (__ret != 0)   break;   }   __ret;  })
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_HL.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_HL.h
new file mode 100644
index 0000000..1071ff9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_HL.h
@@ -0,0 +1,28 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP6T_HL_H
+#define _IP6T_HL_H
+
+enum {
+ IP6T_HL_SET = 0,
+ IP6T_HL_INC,
+ IP6T_HL_DEC
+};
+
+#define IP6T_HL_MAXMODE IP6T_HL_DEC
+
+struct ip6t_HL_info {
+ u_int8_t mode;
+ u_int8_t hop_limit;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_LOG.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_LOG.h
new file mode 100644
index 0000000..344c133
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_LOG.h
@@ -0,0 +1,28 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP6T_LOG_H
+#define _IP6T_LOG_H
+
+#define IP6T_LOG_TCPSEQ 0x01  
+#define IP6T_LOG_TCPOPT 0x02  
+#define IP6T_LOG_IPOPT 0x04  
+#define IP6T_LOG_UID 0x08  
+#define IP6T_LOG_NFLOG 0x10  
+#define IP6T_LOG_MASK 0x1f
+
+struct ip6t_log_info {
+ unsigned char level;
+ unsigned char logflags;
+ char prefix[30];
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_REJECT.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_REJECT.h
new file mode 100644
index 0000000..b101c85
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_REJECT.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP6T_REJECT_H
+#define _IP6T_REJECT_H
+
+enum ip6t_reject_with {
+ IP6T_ICMP6_NO_ROUTE,
+ IP6T_ICMP6_ADM_PROHIBITED,
+ IP6T_ICMP6_NOT_NEIGHBOUR,
+ IP6T_ICMP6_ADDR_UNREACH,
+ IP6T_ICMP6_PORT_UNREACH,
+ IP6T_ICMP6_ECHOREPLY,
+ IP6T_TCP_RESET
+};
+
+struct ip6t_reject_info {
+ u_int32_t with;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_ah.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_ah.h
new file mode 100644
index 0000000..7110df5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_ah.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP6T_AH_H
+#define _IP6T_AH_H
+
+struct ip6t_ah
+{
+ u_int32_t spis[2];
+ u_int32_t hdrlen;
+ u_int8_t hdrres;
+ u_int8_t invflags;
+};
+
+#define IP6T_AH_SPI 0x01
+#define IP6T_AH_LEN 0x02
+#define IP6T_AH_RES 0x04
+
+#define IP6T_AH_INV_SPI 0x01  
+#define IP6T_AH_INV_LEN 0x02  
+#define IP6T_AH_INV_MASK 0x03  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_esp.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_esp.h
new file mode 100644
index 0000000..0aa7556
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_esp.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP6T_ESP_H
+#define _IP6T_ESP_H
+
+#include <linux/netfilter/xt_esp.h>
+
+#define ip6t_esp xt_esp
+#define IP6T_ESP_INV_SPI XT_ESP_INV_SPI
+#define IP6T_ESP_INV_MASK XT_ESP_INV_MASK
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_frag.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_frag.h
new file mode 100644
index 0000000..134d6bb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_frag.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP6T_FRAG_H
+#define _IP6T_FRAG_H
+
+struct ip6t_frag
+{
+ u_int32_t ids[2];
+ u_int32_t hdrlen;
+ u_int8_t flags;
+ u_int8_t invflags;
+};
+
+#define IP6T_FRAG_IDS 0x01
+#define IP6T_FRAG_LEN 0x02
+#define IP6T_FRAG_RES 0x04
+#define IP6T_FRAG_FST 0x08
+#define IP6T_FRAG_MF 0x10
+#define IP6T_FRAG_NMF 0x20
+
+#define IP6T_FRAG_INV_IDS 0x01  
+#define IP6T_FRAG_INV_LEN 0x02  
+#define IP6T_FRAG_INV_MASK 0x03  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_hl.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_hl.h
new file mode 100644
index 0000000..e0144d2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_hl.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP6T_HL_H
+#define _IP6T_HL_H
+
+enum {
+ IP6T_HL_EQ = 0,
+ IP6T_HL_NE,
+ IP6T_HL_LT,
+ IP6T_HL_GT,
+};
+
+struct ip6t_hl_info {
+ u_int8_t mode;
+ u_int8_t hop_limit;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_ipv6header.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_ipv6header.h
new file mode 100644
index 0000000..7e83ebc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_ipv6header.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __IPV6HEADER_H
+#define __IPV6HEADER_H
+
+struct ip6t_ipv6header_info
+{
+ u_int8_t matchflags;
+ u_int8_t invflags;
+ u_int8_t modeflag;
+};
+
+#define MASK_HOPOPTS 128
+#define MASK_DSTOPTS 64
+#define MASK_ROUTING 32
+#define MASK_FRAGMENT 16
+#define MASK_AH 8
+#define MASK_ESP 4
+#define MASK_NONE 2
+#define MASK_PROTO 1
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_length.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_length.h
new file mode 100644
index 0000000..fdc4c5f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_length.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP6T_LENGTH_H
+#define _IP6T_LENGTH_H
+
+#include <linux/netfilter/xt_length.h>
+#define ip6t_length_info xt_length_info
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_mac.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_mac.h
new file mode 100644
index 0000000..58e6023
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_mac.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP6T_MAC_H
+#define _IP6T_MAC_H
+
+#include <linux/netfilter/xt_mac.h>
+#define ip6t_mac_info xt_mac_info
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_opts.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_opts.h
new file mode 100644
index 0000000..1d9db9c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_opts.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP6T_OPTS_H
+#define _IP6T_OPTS_H
+
+#define IP6T_OPTS_OPTSNR 16
+
+struct ip6t_opts
+{
+ u_int32_t hdrlen;
+ u_int8_t flags;
+ u_int8_t invflags;
+ u_int16_t opts[IP6T_OPTS_OPTSNR];
+ u_int8_t optsnr;
+};
+
+#define IP6T_OPTS_LEN 0x01
+#define IP6T_OPTS_OPTS 0x02
+#define IP6T_OPTS_NSTRICT 0x04
+
+#define IP6T_OPTS_INV_LEN 0x01  
+#define IP6T_OPTS_INV_MASK 0x01  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_owner.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_owner.h
new file mode 100644
index 0000000..a6126b4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_owner.h
@@ -0,0 +1,28 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP6T_OWNER_H
+#define _IP6T_OWNER_H
+
+#define IP6T_OWNER_UID 0x01
+#define IP6T_OWNER_GID 0x02
+#define IP6T_OWNER_PID 0x04
+#define IP6T_OWNER_SID 0x08
+
+struct ip6t_owner_info {
+ uid_t uid;
+ gid_t gid;
+ pid_t pid;
+ pid_t sid;
+ u_int8_t match, invert;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_physdev.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_physdev.h
new file mode 100644
index 0000000..657e2fb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_physdev.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP6T_PHYSDEV_H
+#define _IP6T_PHYSDEV_H
+
+#include <linux/netfilter/xt_physdev.h>
+
+#define IP6T_PHYSDEV_OP_IN XT_PHYSDEV_OP_IN
+#define IP6T_PHYSDEV_OP_OUT XT_PHYSDEV_OP_OUT
+#define IP6T_PHYSDEV_OP_BRIDGED XT_PHYSDEV_OP_BRIDGED
+#define IP6T_PHYSDEV_OP_ISIN XT_PHYSDEV_OP_ISIN
+#define IP6T_PHYSDEV_OP_ISOUT XT_PHYSDEV_OP_ISOUT
+#define IP6T_PHYSDEV_OP_MASK XT_PHYSDEV_OP_MASK
+
+#define ip6t_physdev_info xt_physdev_info
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_rt.h b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_rt.h
new file mode 100644
index 0000000..274a7ee
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netfilter_ipv6/ip6t_rt.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _IP6T_RT_H
+#define _IP6T_RT_H
+
+#define IP6T_RT_HOPS 16
+
+struct ip6t_rt
+{
+ u_int32_t rt_type;
+ u_int32_t segsleft[2];
+ u_int32_t hdrlen;
+ u_int8_t flags;
+ u_int8_t invflags;
+ struct in6_addr addrs[IP6T_RT_HOPS];
+ u_int8_t addrnr;
+};
+
+#define IP6T_RT_TYP 0x01
+#define IP6T_RT_SGS 0x02
+#define IP6T_RT_LEN 0x04
+#define IP6T_RT_RES 0x08
+#define IP6T_RT_FST_MASK 0x30
+#define IP6T_RT_FST 0x10
+#define IP6T_RT_FST_NSTRICT 0x20
+
+#define IP6T_RT_INV_TYP 0x01  
+#define IP6T_RT_INV_SGS 0x02  
+#define IP6T_RT_INV_LEN 0x04  
+#define IP6T_RT_INV_MASK 0x07  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/netlink.h b/ndk/build/platforms/android-1.5/common/include/linux/netlink.h
new file mode 100644
index 0000000..b6f1c06
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/netlink.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_NETLINK_H
+#define __LINUX_NETLINK_H
+
+#include <linux/socket.h>  
+#include <linux/types.h>
+
+#define NETLINK_ROUTE 0  
+#define NETLINK_UNUSED 1  
+#define NETLINK_USERSOCK 2  
+#define NETLINK_FIREWALL 3  
+#define NETLINK_INET_DIAG 4  
+#define NETLINK_NFLOG 5  
+#define NETLINK_XFRM 6  
+#define NETLINK_SELINUX 7  
+#define NETLINK_ISCSI 8  
+#define NETLINK_AUDIT 9  
+#define NETLINK_FIB_LOOKUP 10 
+#define NETLINK_CONNECTOR 11
+#define NETLINK_NETFILTER 12  
+#define NETLINK_IP6_FW 13
+#define NETLINK_DNRTMSG 14  
+#define NETLINK_KOBJECT_UEVENT 15  
+#define NETLINK_GENERIC 16
+
+#define MAX_LINKS 32 
+
+struct sockaddr_nl
+{
+ sa_family_t nl_family;
+ unsigned short nl_pad;
+ __u32 nl_pid;
+ __u32 nl_groups;
+};
+
+struct nlmsghdr
+{
+ __u32 nlmsg_len;
+ __u16 nlmsg_type;
+ __u16 nlmsg_flags;
+ __u32 nlmsg_seq;
+ __u32 nlmsg_pid;
+};
+
+#define NLM_F_REQUEST 1  
+#define NLM_F_MULTI 2  
+#define NLM_F_ACK 4  
+#define NLM_F_ECHO 8  
+
+#define NLM_F_ROOT 0x100  
+#define NLM_F_MATCH 0x200  
+#define NLM_F_ATOMIC 0x400  
+#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH)
+
+#define NLM_F_REPLACE 0x100  
+#define NLM_F_EXCL 0x200  
+#define NLM_F_CREATE 0x400  
+#define NLM_F_APPEND 0x800  
+
+#define NLMSG_ALIGNTO 4
+#define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) )
+#define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr)))
+#define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN))
+#define NLMSG_SPACE(len) NLMSG_ALIGN(NLMSG_LENGTH(len))
+#define NLMSG_DATA(nlh) ((void*)(((char*)nlh) + NLMSG_LENGTH(0)))
+#define NLMSG_NEXT(nlh,len) ((len) -= NLMSG_ALIGN((nlh)->nlmsg_len),   (struct nlmsghdr*)(((char*)(nlh)) + NLMSG_ALIGN((nlh)->nlmsg_len)))
+#define NLMSG_OK(nlh,len) ((len) >= (int)sizeof(struct nlmsghdr) &&   (nlh)->nlmsg_len >= sizeof(struct nlmsghdr) &&   (nlh)->nlmsg_len <= (len))
+#define NLMSG_PAYLOAD(nlh,len) ((nlh)->nlmsg_len - NLMSG_SPACE((len)))
+
+#define NLMSG_NOOP 0x1  
+#define NLMSG_ERROR 0x2  
+#define NLMSG_DONE 0x3  
+#define NLMSG_OVERRUN 0x4  
+
+#define NLMSG_MIN_TYPE 0x10  
+
+struct nlmsgerr
+{
+ int error;
+ struct nlmsghdr msg;
+};
+
+#define NETLINK_ADD_MEMBERSHIP 1
+#define NETLINK_DROP_MEMBERSHIP 2
+#define NETLINK_PKTINFO 3
+
+struct nl_pktinfo
+{
+ __u32 group;
+};
+
+#define NET_MAJOR 36  
+
+enum {
+ NETLINK_UNCONNECTED = 0,
+ NETLINK_CONNECTED,
+};
+
+struct nlattr
+{
+ __u16 nla_len;
+ __u16 nla_type;
+};
+
+#define NLA_ALIGNTO 4
+#define NLA_ALIGN(len) (((len) + NLA_ALIGNTO - 1) & ~(NLA_ALIGNTO - 1))
+#define NLA_HDRLEN ((int) NLA_ALIGN(sizeof(struct nlattr)))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nfs.h b/ndk/build/platforms/android-1.5/common/include/linux/nfs.h
new file mode 100644
index 0000000..d94dc9f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nfs.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NFS_H
+#define _LINUX_NFS_H
+
+#define NFS_PROGRAM 100003
+#define NFS_PORT 2049
+#define NFS_MAXDATA 8192
+#define NFS_MAXPATHLEN 1024
+#define NFS_MAXNAMLEN 255
+#define NFS_MAXGROUPS 16
+#define NFS_FHSIZE 32
+#define NFS_COOKIESIZE 4
+#define NFS_FIFO_DEV (-1)
+#define NFSMODE_FMT 0170000
+#define NFSMODE_DIR 0040000
+#define NFSMODE_CHR 0020000
+#define NFSMODE_BLK 0060000
+#define NFSMODE_REG 0100000
+#define NFSMODE_LNK 0120000
+#define NFSMODE_SOCK 0140000
+#define NFSMODE_FIFO 0010000
+
+#define NFS_MNT_PROGRAM 100005
+#define NFS_MNT_PORT 627
+
+ enum nfs_stat {
+ NFS_OK = 0,
+ NFSERR_PERM = 1,
+ NFSERR_NOENT = 2,
+ NFSERR_IO = 5,
+ NFSERR_NXIO = 6,
+ NFSERR_EAGAIN = 11,
+ NFSERR_ACCES = 13,
+ NFSERR_EXIST = 17,
+ NFSERR_XDEV = 18,
+ NFSERR_NODEV = 19,
+ NFSERR_NOTDIR = 20,
+ NFSERR_ISDIR = 21,
+ NFSERR_INVAL = 22,
+ NFSERR_FBIG = 27,
+ NFSERR_NOSPC = 28,
+ NFSERR_ROFS = 30,
+ NFSERR_MLINK = 31,
+ NFSERR_OPNOTSUPP = 45,
+ NFSERR_NAMETOOLONG = 63,
+ NFSERR_NOTEMPTY = 66,
+ NFSERR_DQUOT = 69,
+ NFSERR_STALE = 70,
+ NFSERR_REMOTE = 71,
+ NFSERR_WFLUSH = 99,
+ NFSERR_BADHANDLE = 10001,
+ NFSERR_NOT_SYNC = 10002,
+ NFSERR_BAD_COOKIE = 10003,
+ NFSERR_NOTSUPP = 10004,
+ NFSERR_TOOSMALL = 10005,
+ NFSERR_SERVERFAULT = 10006,
+ NFSERR_BADTYPE = 10007,
+ NFSERR_JUKEBOX = 10008,
+ NFSERR_SAME = 10009,
+ NFSERR_DENIED = 10010,
+ NFSERR_EXPIRED = 10011,
+ NFSERR_LOCKED = 10012,
+ NFSERR_GRACE = 10013,
+ NFSERR_FHEXPIRED = 10014,
+ NFSERR_SHARE_DENIED = 10015,
+ NFSERR_WRONGSEC = 10016,
+ NFSERR_CLID_INUSE = 10017,
+ NFSERR_RESOURCE = 10018,
+ NFSERR_MOVED = 10019,
+ NFSERR_NOFILEHANDLE = 10020,
+ NFSERR_MINOR_VERS_MISMATCH = 10021,
+ NFSERR_STALE_CLIENTID = 10022,
+ NFSERR_STALE_STATEID = 10023,
+ NFSERR_OLD_STATEID = 10024,
+ NFSERR_BAD_STATEID = 10025,
+ NFSERR_BAD_SEQID = 10026,
+ NFSERR_NOT_SAME = 10027,
+ NFSERR_LOCK_RANGE = 10028,
+ NFSERR_SYMLINK = 10029,
+ NFSERR_RESTOREFH = 10030,
+ NFSERR_LEASE_MOVED = 10031,
+ NFSERR_ATTRNOTSUPP = 10032,
+ NFSERR_NO_GRACE = 10033,
+ NFSERR_RECLAIM_BAD = 10034,
+ NFSERR_RECLAIM_CONFLICT = 10035,
+ NFSERR_BAD_XDR = 10036,
+ NFSERR_LOCKS_HELD = 10037,
+ NFSERR_OPENMODE = 10038,
+ NFSERR_BADOWNER = 10039,
+ NFSERR_BADCHAR = 10040,
+ NFSERR_BADNAME = 10041,
+ NFSERR_BAD_RANGE = 10042,
+ NFSERR_LOCK_NOTSUPP = 10043,
+ NFSERR_OP_ILLEGAL = 10044,
+ NFSERR_DEADLOCK = 10045,
+ NFSERR_FILE_OPEN = 10046,
+ NFSERR_ADMIN_REVOKED = 10047,
+ NFSERR_CB_PATH_DOWN = 10048,
+ NFSERR_REPLAY_ME = 10049
+};
+
+enum nfs_ftype {
+ NFNON = 0,
+ NFREG = 1,
+ NFDIR = 2,
+ NFBLK = 3,
+ NFCHR = 4,
+ NFLNK = 5,
+ NFSOCK = 6,
+ NFBAD = 7,
+ NFFIFO = 8
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nfs2.h b/ndk/build/platforms/android-1.5/common/include/linux/nfs2.h
new file mode 100644
index 0000000..1bb5df2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nfs2.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NFS2_H
+#define _LINUX_NFS2_H
+
+#define NFS2_PORT 2049
+#define NFS2_MAXDATA 8192
+#define NFS2_MAXPATHLEN 1024
+#define NFS2_MAXNAMLEN 255
+#define NFS2_MAXGROUPS 16
+#define NFS2_FHSIZE 32
+#define NFS2_COOKIESIZE 4
+#define NFS2_FIFO_DEV (-1)
+#define NFS2MODE_FMT 0170000
+#define NFS2MODE_DIR 0040000
+#define NFS2MODE_CHR 0020000
+#define NFS2MODE_BLK 0060000
+#define NFS2MODE_REG 0100000
+#define NFS2MODE_LNK 0120000
+#define NFS2MODE_SOCK 0140000
+#define NFS2MODE_FIFO 0010000
+
+enum nfs2_ftype {
+ NF2NON = 0,
+ NF2REG = 1,
+ NF2DIR = 2,
+ NF2BLK = 3,
+ NF2CHR = 4,
+ NF2LNK = 5,
+ NF2SOCK = 6,
+ NF2BAD = 7,
+ NF2FIFO = 8
+};
+
+struct nfs2_fh {
+ char data[NFS2_FHSIZE];
+};
+
+#define NFS2_VERSION 2
+#define NFSPROC_NULL 0
+#define NFSPROC_GETATTR 1
+#define NFSPROC_SETATTR 2
+#define NFSPROC_ROOT 3
+#define NFSPROC_LOOKUP 4
+#define NFSPROC_READLINK 5
+#define NFSPROC_READ 6
+#define NFSPROC_WRITECACHE 7
+#define NFSPROC_WRITE 8
+#define NFSPROC_CREATE 9
+#define NFSPROC_REMOVE 10
+#define NFSPROC_RENAME 11
+#define NFSPROC_LINK 12
+#define NFSPROC_SYMLINK 13
+#define NFSPROC_MKDIR 14
+#define NFSPROC_RMDIR 15
+#define NFSPROC_READDIR 16
+#define NFSPROC_STATFS 17
+
+#define NFS_MNT_PROGRAM 100005
+#define NFS_MNT_VERSION 1
+#define MNTPROC_NULL 0
+#define MNTPROC_MNT 1
+#define MNTPROC_UMNT 3
+#define MNTPROC_UMNTALL 4
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nfs3.h b/ndk/build/platforms/android-1.5/common/include/linux/nfs3.h
new file mode 100644
index 0000000..8303459
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nfs3.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NFS3_H
+#define _LINUX_NFS3_H
+
+#define NFS3_PORT 2049
+#define NFS3_MAXDATA 32768
+#define NFS3_MAXPATHLEN PATH_MAX
+#define NFS3_MAXNAMLEN NAME_MAX
+#define NFS3_MAXGROUPS 16
+#define NFS3_FHSIZE 64
+#define NFS3_COOKIESIZE 4
+#define NFS3_FIFO_DEV (-1)
+#define NFS3MODE_FMT 0170000
+#define NFS3MODE_DIR 0040000
+#define NFS3MODE_CHR 0020000
+#define NFS3MODE_BLK 0060000
+#define NFS3MODE_REG 0100000
+#define NFS3MODE_LNK 0120000
+#define NFS3MODE_SOCK 0140000
+#define NFS3MODE_FIFO 0010000
+
+#define NFS3_ACCESS_READ 0x0001
+#define NFS3_ACCESS_LOOKUP 0x0002
+#define NFS3_ACCESS_MODIFY 0x0004
+#define NFS3_ACCESS_EXTEND 0x0008
+#define NFS3_ACCESS_DELETE 0x0010
+#define NFS3_ACCESS_EXECUTE 0x0020
+#define NFS3_ACCESS_FULL 0x003f
+
+enum nfs3_createmode {
+ NFS3_CREATE_UNCHECKED = 0,
+ NFS3_CREATE_GUARDED = 1,
+ NFS3_CREATE_EXCLUSIVE = 2
+};
+
+#define NFS3_FSF_LINK 0x0001
+#define NFS3_FSF_SYMLINK 0x0002
+#define NFS3_FSF_HOMOGENEOUS 0x0008
+#define NFS3_FSF_CANSETTIME 0x0010
+
+#define NFS3_FSF_DEFAULT 0x001B
+#define NFS3_FSF_BILLYBOY 0x0018
+#define NFS3_FSF_READONLY 0x0008
+
+enum nfs3_ftype {
+ NF3NON = 0,
+ NF3REG = 1,
+ NF3DIR = 2,
+ NF3BLK = 3,
+ NF3CHR = 4,
+ NF3LNK = 5,
+ NF3SOCK = 6,
+ NF3FIFO = 7,
+ NF3BAD = 8
+};
+
+struct nfs3_fh {
+ unsigned short size;
+ unsigned char data[NFS3_FHSIZE];
+};
+
+#define NFS3_VERSION 3
+#define NFS3PROC_NULL 0
+#define NFS3PROC_GETATTR 1
+#define NFS3PROC_SETATTR 2
+#define NFS3PROC_LOOKUP 3
+#define NFS3PROC_ACCESS 4
+#define NFS3PROC_READLINK 5
+#define NFS3PROC_READ 6
+#define NFS3PROC_WRITE 7
+#define NFS3PROC_CREATE 8
+#define NFS3PROC_MKDIR 9
+#define NFS3PROC_SYMLINK 10
+#define NFS3PROC_MKNOD 11
+#define NFS3PROC_REMOVE 12
+#define NFS3PROC_RMDIR 13
+#define NFS3PROC_RENAME 14
+#define NFS3PROC_LINK 15
+#define NFS3PROC_READDIR 16
+#define NFS3PROC_READDIRPLUS 17
+#define NFS3PROC_FSSTAT 18
+#define NFS3PROC_FSINFO 19
+#define NFS3PROC_PATHCONF 20
+#define NFS3PROC_COMMIT 21
+
+#define NFS_MNT3_PROGRAM 100005
+#define NFS_MNT3_VERSION 3
+#define MOUNTPROC3_NULL 0
+#define MOUNTPROC3_MNT 1
+#define MOUNTPROC3_UMNT 3
+#define MOUNTPROC3_UMNTALL 4
+
+#ifdef NFS_NEED_KERNEL_TYPES
+
+#define NFS3_POST_OP_ATTR_WORDS 22
+
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nfs4.h b/ndk/build/platforms/android-1.5/common/include/linux/nfs4.h
new file mode 100644
index 0000000..2e95e45
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nfs4.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NFS4_H
+#define _LINUX_NFS4_H
+
+#include <linux/types.h>
+
+#define NFS4_VERIFIER_SIZE 8
+#define NFS4_FHSIZE 128
+#define NFS4_MAXPATHLEN PATH_MAX
+#define NFS4_MAXNAMLEN NAME_MAX
+
+#define NFS4_ACCESS_READ 0x0001
+#define NFS4_ACCESS_LOOKUP 0x0002
+#define NFS4_ACCESS_MODIFY 0x0004
+#define NFS4_ACCESS_EXTEND 0x0008
+#define NFS4_ACCESS_DELETE 0x0010
+#define NFS4_ACCESS_EXECUTE 0x0020
+
+#define NFS4_FH_PERSISTENT 0x0000
+#define NFS4_FH_NOEXPIRE_WITH_OPEN 0x0001
+#define NFS4_FH_VOLATILE_ANY 0x0002
+#define NFS4_FH_VOL_MIGRATION 0x0004
+#define NFS4_FH_VOL_RENAME 0x0008
+
+#define NFS4_OPEN_RESULT_CONFIRM 0x0002
+#define NFS4_OPEN_RESULT_LOCKTYPE_POSIX 0x0004
+
+#define NFS4_SHARE_ACCESS_READ 0x0001
+#define NFS4_SHARE_ACCESS_WRITE 0x0002
+#define NFS4_SHARE_ACCESS_BOTH 0x0003
+#define NFS4_SHARE_DENY_READ 0x0001
+#define NFS4_SHARE_DENY_WRITE 0x0002
+#define NFS4_SHARE_DENY_BOTH 0x0003
+
+#define NFS4_SET_TO_SERVER_TIME 0
+#define NFS4_SET_TO_CLIENT_TIME 1
+
+#define NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE 0
+#define NFS4_ACE_ACCESS_DENIED_ACE_TYPE 1
+#define NFS4_ACE_SYSTEM_AUDIT_ACE_TYPE 2
+#define NFS4_ACE_SYSTEM_ALARM_ACE_TYPE 3
+
+#define ACL4_SUPPORT_ALLOW_ACL 0x01
+#define ACL4_SUPPORT_DENY_ACL 0x02
+#define ACL4_SUPPORT_AUDIT_ACL 0x04
+#define ACL4_SUPPORT_ALARM_ACL 0x08
+
+#define NFS4_ACE_FILE_INHERIT_ACE 0x00000001
+#define NFS4_ACE_DIRECTORY_INHERIT_ACE 0x00000002
+#define NFS4_ACE_NO_PROPAGATE_INHERIT_ACE 0x00000004
+#define NFS4_ACE_INHERIT_ONLY_ACE 0x00000008
+#define NFS4_ACE_SUCCESSFUL_ACCESS_ACE_FLAG 0x00000010
+#define NFS4_ACE_FAILED_ACCESS_ACE_FLAG 0x00000020
+#define NFS4_ACE_IDENTIFIER_GROUP 0x00000040
+#define NFS4_ACE_OWNER 0x00000080
+#define NFS4_ACE_GROUP 0x00000100
+#define NFS4_ACE_EVERYONE 0x00000200
+
+#define NFS4_ACE_READ_DATA 0x00000001
+#define NFS4_ACE_LIST_DIRECTORY 0x00000001
+#define NFS4_ACE_WRITE_DATA 0x00000002
+#define NFS4_ACE_ADD_FILE 0x00000002
+#define NFS4_ACE_APPEND_DATA 0x00000004
+#define NFS4_ACE_ADD_SUBDIRECTORY 0x00000004
+#define NFS4_ACE_READ_NAMED_ATTRS 0x00000008
+#define NFS4_ACE_WRITE_NAMED_ATTRS 0x00000010
+#define NFS4_ACE_EXECUTE 0x00000020
+#define NFS4_ACE_DELETE_CHILD 0x00000040
+#define NFS4_ACE_READ_ATTRIBUTES 0x00000080
+#define NFS4_ACE_WRITE_ATTRIBUTES 0x00000100
+#define NFS4_ACE_DELETE 0x00010000
+#define NFS4_ACE_READ_ACL 0x00020000
+#define NFS4_ACE_WRITE_ACL 0x00040000
+#define NFS4_ACE_WRITE_OWNER 0x00080000
+#define NFS4_ACE_SYNCHRONIZE 0x00100000
+#define NFS4_ACE_GENERIC_READ 0x00120081
+#define NFS4_ACE_GENERIC_WRITE 0x00160106
+#define NFS4_ACE_GENERIC_EXECUTE 0x001200A0
+#define NFS4_ACE_MASK_ALL 0x001F01FF
+
+enum nfs4_acl_whotype {
+ NFS4_ACL_WHO_NAMED = 0,
+ NFS4_ACL_WHO_OWNER,
+ NFS4_ACL_WHO_GROUP,
+ NFS4_ACL_WHO_EVERYONE,
+};
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nfs_xdr.h b/ndk/build/platforms/android-1.5/common/include/linux/nfs_xdr.h
new file mode 100644
index 0000000..48fe262
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nfs_xdr.h
@@ -0,0 +1,556 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NFS_XDR_H
+#define _LINUX_NFS_XDR_H
+
+#include <linux/sunrpc/xprt.h>
+#include <linux/nfsacl.h>
+
+#define NFS_MAX_FILE_IO_SIZE (1048576U)
+#define NFS_DEF_FILE_IO_SIZE (4096U)
+#define NFS_MIN_FILE_IO_SIZE (1024U)
+
+struct nfs_fsid {
+ uint64_t major;
+ uint64_t minor;
+};
+
+#define NFS_ATTR_WCC 0x0001  
+#define NFS_ATTR_FATTR 0x0002  
+#define NFS_ATTR_FATTR_V3 0x0004  
+#define NFS_ATTR_FATTR_V4 0x0008  
+#define NFS_ATTR_FATTR_V4_REFERRAL 0x0010  
+
+struct nfs_fsinfo {
+ struct nfs_fattr *fattr;
+ __u32 rtmax;
+ __u32 rtpref;
+ __u32 rtmult;
+ __u32 wtmax;
+ __u32 wtpref;
+ __u32 wtmult;
+ __u32 dtpref;
+ __u64 maxfilesize;
+ __u32 lease_time;
+};
+
+struct nfs_fsstat {
+ struct nfs_fattr *fattr;
+ __u64 tbytes;
+ __u64 fbytes;
+ __u64 abytes;
+ __u64 tfiles;
+ __u64 ffiles;
+ __u64 afiles;
+};
+
+struct nfs2_fsstat {
+ __u32 tsize;
+ __u32 bsize;
+ __u32 blocks;
+ __u32 bfree;
+ __u32 bavail;
+};
+
+struct nfs_pathconf {
+ struct nfs_fattr *fattr;
+ __u32 max_link;
+ __u32 max_namelen;
+};
+
+struct nfs4_change_info {
+ u32 atomic;
+ u64 before;
+ u64 after;
+};
+
+struct nfs_seqid;
+
+struct nfs_openargs {
+ const struct nfs_fh * fh;
+ struct nfs_seqid * seqid;
+ int open_flags;
+ __u64 clientid;
+ __u32 id;
+ union {
+ struct iattr * attrs;
+ nfs4_verifier verifier;
+ nfs4_stateid delegation;
+ int delegation_type;
+ } u;
+ const struct qstr * name;
+ const struct nfs_server *server;
+ const u32 * bitmask;
+ __u32 claim;
+};
+
+struct nfs_openres {
+ nfs4_stateid stateid;
+ struct nfs_fh fh;
+ struct nfs4_change_info cinfo;
+ __u32 rflags;
+ struct nfs_fattr * f_attr;
+ struct nfs_fattr * dir_attr;
+ const struct nfs_server *server;
+ int delegation_type;
+ nfs4_stateid delegation;
+ __u32 do_recall;
+ __u64 maxsize;
+};
+
+struct nfs_open_confirmargs {
+ const struct nfs_fh * fh;
+ nfs4_stateid * stateid;
+ struct nfs_seqid * seqid;
+};
+
+struct nfs_open_confirmres {
+ nfs4_stateid stateid;
+};
+
+struct nfs_closeargs {
+ struct nfs_fh * fh;
+ nfs4_stateid * stateid;
+ struct nfs_seqid * seqid;
+ int open_flags;
+ const u32 * bitmask;
+};
+
+struct nfs_closeres {
+ nfs4_stateid stateid;
+ struct nfs_fattr * fattr;
+ const struct nfs_server *server;
+};
+
+struct nfs_lowner {
+ __u64 clientid;
+ u32 id;
+};
+
+struct nfs_lock_args {
+ struct nfs_fh * fh;
+ struct file_lock * fl;
+ struct nfs_seqid * lock_seqid;
+ nfs4_stateid * lock_stateid;
+ struct nfs_seqid * open_seqid;
+ nfs4_stateid * open_stateid;
+ struct nfs_lowner lock_owner;
+ unsigned char block : 1;
+ unsigned char reclaim : 1;
+ unsigned char new_lock_owner : 1;
+};
+
+struct nfs_lock_res {
+ nfs4_stateid stateid;
+};
+
+struct nfs_locku_args {
+ struct nfs_fh * fh;
+ struct file_lock * fl;
+ struct nfs_seqid * seqid;
+ nfs4_stateid * stateid;
+};
+
+struct nfs_locku_res {
+ nfs4_stateid stateid;
+};
+
+struct nfs_lockt_args {
+ struct nfs_fh * fh;
+ struct file_lock * fl;
+ struct nfs_lowner lock_owner;
+};
+
+struct nfs_lockt_res {
+ struct file_lock * denied;
+};
+
+struct nfs4_delegreturnargs {
+ const struct nfs_fh *fhandle;
+ const nfs4_stateid *stateid;
+ const u32 * bitmask;
+};
+
+struct nfs4_delegreturnres {
+ struct nfs_fattr * fattr;
+ const struct nfs_server *server;
+};
+
+struct nfs_readargs {
+ struct nfs_fh * fh;
+ struct nfs_open_context *context;
+ __u64 offset;
+ __u32 count;
+ unsigned int pgbase;
+ struct page ** pages;
+};
+
+struct nfs_readres {
+ struct nfs_fattr * fattr;
+ __u32 count;
+ int eof;
+};
+
+struct nfs_writeargs {
+ struct nfs_fh * fh;
+ struct nfs_open_context *context;
+ __u64 offset;
+ __u32 count;
+ enum nfs3_stable_how stable;
+ unsigned int pgbase;
+ struct page ** pages;
+ const u32 * bitmask;
+};
+
+struct nfs_writeverf {
+ enum nfs3_stable_how committed;
+ __u32 verifier[2];
+};
+
+struct nfs_writeres {
+ struct nfs_fattr * fattr;
+ struct nfs_writeverf * verf;
+ __u32 count;
+ const struct nfs_server *server;
+};
+
+struct nfs_entry {
+ __u64 ino;
+ __u64 cookie,
+ prev_cookie;
+ const char * name;
+ unsigned int len;
+ int eof;
+ struct nfs_fh * fh;
+ struct nfs_fattr * fattr;
+};
+
+struct nfs_sattrargs {
+ struct nfs_fh * fh;
+ struct iattr * sattr;
+};
+
+struct nfs_diropargs {
+ struct nfs_fh * fh;
+ const char * name;
+ unsigned int len;
+};
+
+struct nfs_createargs {
+ struct nfs_fh * fh;
+ const char * name;
+ unsigned int len;
+ struct iattr * sattr;
+};
+
+struct nfs_renameargs {
+ struct nfs_fh * fromfh;
+ const char * fromname;
+ unsigned int fromlen;
+ struct nfs_fh * tofh;
+ const char * toname;
+ unsigned int tolen;
+};
+
+struct nfs_setattrargs {
+ struct nfs_fh * fh;
+ nfs4_stateid stateid;
+ struct iattr * iap;
+ const struct nfs_server * server;
+ const u32 * bitmask;
+};
+
+struct nfs_setaclargs {
+ struct nfs_fh * fh;
+ size_t acl_len;
+ unsigned int acl_pgbase;
+ struct page ** acl_pages;
+};
+
+struct nfs_getaclargs {
+ struct nfs_fh * fh;
+ size_t acl_len;
+ unsigned int acl_pgbase;
+ struct page ** acl_pages;
+};
+
+struct nfs_setattrres {
+ struct nfs_fattr * fattr;
+ const struct nfs_server * server;
+};
+
+struct nfs_linkargs {
+ struct nfs_fh * fromfh;
+ struct nfs_fh * tofh;
+ const char * toname;
+ unsigned int tolen;
+};
+
+struct nfs_symlinkargs {
+ struct nfs_fh * fromfh;
+ const char * fromname;
+ unsigned int fromlen;
+ const char * topath;
+ unsigned int tolen;
+ struct iattr * sattr;
+};
+
+struct nfs_readdirargs {
+ struct nfs_fh * fh;
+ __u32 cookie;
+ unsigned int count;
+ struct page ** pages;
+};
+
+struct nfs3_getaclargs {
+ struct nfs_fh * fh;
+ int mask;
+ struct page ** pages;
+};
+
+struct nfs3_setaclargs {
+ struct inode * inode;
+ int mask;
+ struct posix_acl * acl_access;
+ struct posix_acl * acl_default;
+ struct page ** pages;
+};
+
+struct nfs_diropok {
+ struct nfs_fh * fh;
+ struct nfs_fattr * fattr;
+};
+
+struct nfs_readlinkargs {
+ struct nfs_fh * fh;
+ unsigned int pgbase;
+ unsigned int pglen;
+ struct page ** pages;
+};
+
+struct nfs3_sattrargs {
+ struct nfs_fh * fh;
+ struct iattr * sattr;
+ unsigned int guard;
+ struct timespec guardtime;
+};
+
+struct nfs3_diropargs {
+ struct nfs_fh * fh;
+ const char * name;
+ unsigned int len;
+};
+
+struct nfs3_accessargs {
+ struct nfs_fh * fh;
+ __u32 access;
+};
+
+struct nfs3_createargs {
+ struct nfs_fh * fh;
+ const char * name;
+ unsigned int len;
+ struct iattr * sattr;
+ enum nfs3_createmode createmode;
+ __u32 verifier[2];
+};
+
+struct nfs3_mkdirargs {
+ struct nfs_fh * fh;
+ const char * name;
+ unsigned int len;
+ struct iattr * sattr;
+};
+
+struct nfs3_symlinkargs {
+ struct nfs_fh * fromfh;
+ const char * fromname;
+ unsigned int fromlen;
+ const char * topath;
+ unsigned int tolen;
+ struct iattr * sattr;
+};
+
+struct nfs3_mknodargs {
+ struct nfs_fh * fh;
+ const char * name;
+ unsigned int len;
+ enum nfs3_ftype type;
+ struct iattr * sattr;
+ dev_t rdev;
+};
+
+struct nfs3_renameargs {
+ struct nfs_fh * fromfh;
+ const char * fromname;
+ unsigned int fromlen;
+ struct nfs_fh * tofh;
+ const char * toname;
+ unsigned int tolen;
+};
+
+struct nfs3_linkargs {
+ struct nfs_fh * fromfh;
+ struct nfs_fh * tofh;
+ const char * toname;
+ unsigned int tolen;
+};
+
+struct nfs3_readdirargs {
+ struct nfs_fh * fh;
+ __u64 cookie;
+ __u32 verf[2];
+ int plus;
+ unsigned int count;
+ struct page ** pages;
+};
+
+struct nfs3_diropres {
+ struct nfs_fattr * dir_attr;
+ struct nfs_fh * fh;
+ struct nfs_fattr * fattr;
+};
+
+struct nfs3_accessres {
+ struct nfs_fattr * fattr;
+ __u32 access;
+};
+
+struct nfs3_readlinkargs {
+ struct nfs_fh * fh;
+ unsigned int pgbase;
+ unsigned int pglen;
+ struct page ** pages;
+};
+
+struct nfs3_renameres {
+ struct nfs_fattr * fromattr;
+ struct nfs_fattr * toattr;
+};
+
+struct nfs3_linkres {
+ struct nfs_fattr * dir_attr;
+ struct nfs_fattr * fattr;
+};
+
+struct nfs3_readdirres {
+ struct nfs_fattr * dir_attr;
+ __u32 * verf;
+ int plus;
+};
+
+struct nfs3_getaclres {
+ struct nfs_fattr * fattr;
+ int mask;
+ unsigned int acl_access_count;
+ unsigned int acl_default_count;
+ struct posix_acl * acl_access;
+ struct posix_acl * acl_default;
+};
+
+struct nfs_page;
+
+#define NFS_PAGEVEC_SIZE (8U)
+
+struct nfs_read_data {
+ int flags;
+ struct rpc_task task;
+ struct inode *inode;
+ struct rpc_cred *cred;
+ struct nfs_fattr fattr;
+ struct list_head pages;
+ struct nfs_page *req;
+ struct page **pagevec;
+ unsigned int npages;
+ struct nfs_readargs args;
+ struct nfs_readres res;
+ struct page *page_array[NFS_PAGEVEC_SIZE];
+};
+
+struct nfs_write_data {
+ int flags;
+ struct rpc_task task;
+ struct inode *inode;
+ struct rpc_cred *cred;
+ struct nfs_fattr fattr;
+ struct nfs_writeverf verf;
+ struct list_head pages;
+ struct nfs_page *req;
+ struct page **pagevec;
+ unsigned int npages;
+ struct nfs_writeargs args;
+ struct nfs_writeres res;
+ struct page *page_array[NFS_PAGEVEC_SIZE];
+};
+
+struct nfs_access_entry;
+
+struct nfs_rpc_ops {
+ int version;
+ struct dentry_operations *dentry_ops;
+ struct inode_operations *dir_inode_ops;
+ struct inode_operations *file_inode_ops;
+
+ int (*getroot) (struct nfs_server *, struct nfs_fh *,
+ struct nfs_fsinfo *);
+ int (*getattr) (struct nfs_server *, struct nfs_fh *,
+ struct nfs_fattr *);
+ int (*setattr) (struct dentry *, struct nfs_fattr *,
+ struct iattr *);
+ int (*lookup) (struct inode *, struct qstr *,
+ struct nfs_fh *, struct nfs_fattr *);
+ int (*access) (struct inode *, struct nfs_access_entry *);
+ int (*readlink)(struct inode *, struct page *, unsigned int,
+ unsigned int);
+ int (*read) (struct nfs_read_data *);
+ int (*write) (struct nfs_write_data *);
+ int (*commit) (struct nfs_write_data *);
+ int (*create) (struct inode *, struct dentry *,
+ struct iattr *, int, struct nameidata *);
+ int (*remove) (struct inode *, struct qstr *);
+ int (*unlink_setup) (struct rpc_message *,
+ struct dentry *, struct qstr *);
+ int (*unlink_done) (struct dentry *, struct rpc_task *);
+ int (*rename) (struct inode *, struct qstr *,
+ struct inode *, struct qstr *);
+ int (*link) (struct inode *, struct inode *, struct qstr *);
+ int (*symlink) (struct inode *, struct qstr *, struct qstr *,
+ struct iattr *, struct nfs_fh *,
+ struct nfs_fattr *);
+ int (*mkdir) (struct inode *, struct dentry *, struct iattr *);
+ int (*rmdir) (struct inode *, struct qstr *);
+ int (*readdir) (struct dentry *, struct rpc_cred *,
+ u64, struct page *, unsigned int, int);
+ int (*mknod) (struct inode *, struct dentry *, struct iattr *,
+ dev_t);
+ int (*statfs) (struct nfs_server *, struct nfs_fh *,
+ struct nfs_fsstat *);
+ int (*fsinfo) (struct nfs_server *, struct nfs_fh *,
+ struct nfs_fsinfo *);
+ int (*pathconf) (struct nfs_server *, struct nfs_fh *,
+ struct nfs_pathconf *);
+ u32 * (*decode_dirent)(u32 *, struct nfs_entry *, int plus);
+ void (*read_setup) (struct nfs_read_data *);
+ int (*read_done) (struct rpc_task *, struct nfs_read_data *);
+ void (*write_setup) (struct nfs_write_data *, int how);
+ int (*write_done) (struct rpc_task *, struct nfs_write_data *);
+ void (*commit_setup) (struct nfs_write_data *, int how);
+ int (*commit_done) (struct rpc_task *, struct nfs_write_data *);
+ int (*file_open) (struct inode *, struct file *);
+ int (*file_release) (struct inode *, struct file *);
+ int (*lock)(struct file *, int, struct file_lock *);
+ void (*clear_acl_cache)(struct inode *);
+};
+
+#define NFS_CALL(op, inode, args) NFS_PROTO(inode)->op args
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nfsacl.h b/ndk/build/platforms/android-1.5/common/include/linux/nfsacl.h
new file mode 100644
index 0000000..7dd95ab
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nfsacl.h
@@ -0,0 +1,32 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_NFSACL_H
+#define __LINUX_NFSACL_H
+
+#define NFS_ACL_PROGRAM 100227
+
+#define ACLPROC2_GETACL 1
+#define ACLPROC2_SETACL 2
+#define ACLPROC2_GETATTR 3
+#define ACLPROC2_ACCESS 4
+
+#define ACLPROC3_GETACL 1
+#define ACLPROC3_SETACL 2
+
+#define NFS_ACL 0x0001
+#define NFS_ACLCNT 0x0002
+#define NFS_DFACL 0x0004
+#define NFS_DFACLCNT 0x0008
+
+#define NFS_ACL_DEFAULT 0x1000
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nfsd/auth.h b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/auth.h
new file mode 100644
index 0000000..f840f0e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/auth.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_NFSD_AUTH_H
+#define LINUX_NFSD_AUTH_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nfsd/const.h b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/const.h
new file mode 100644
index 0000000..c345508
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/const.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NFSD_CONST_H
+#define _LINUX_NFSD_CONST_H
+
+#include <linux/nfs.h>
+#include <linux/nfs2.h>
+#include <linux/nfs3.h>
+#include <linux/nfs4.h>
+
+#define NFSSVC_MAXVERS 3
+
+#define NFSSVC_MAXBLKSIZE (32*1024)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nfsd/debug.h b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/debug.h
new file mode 100644
index 0000000..9b90f05
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/debug.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_NFSD_DEBUG_H
+#define LINUX_NFSD_DEBUG_H
+
+#include <linux/sunrpc/debug.h>
+
+#ifdef RPC_DEBUG
+#define NFSD_DEBUG 1
+#endif
+
+#define NFSDDBG_SOCK 0x0001
+#define NFSDDBG_FH 0x0002
+#define NFSDDBG_EXPORT 0x0004
+#define NFSDDBG_SVC 0x0008
+#define NFSDDBG_PROC 0x0010
+#define NFSDDBG_FILEOP 0x0020
+#define NFSDDBG_AUTH 0x0040
+#define NFSDDBG_REPCACHE 0x0080
+#define NFSDDBG_XDR 0x0100
+#define NFSDDBG_LOCKD 0x0200
+#define NFSDDBG_ALL 0x7FFF
+#define NFSDDBG_NOCHANGE 0xFFFF
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nfsd/export.h b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/export.h
new file mode 100644
index 0000000..932274f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/export.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef NFSD_EXPORT_H
+#define NFSD_EXPORT_H
+
+#include <asm/types.h>
+
+#define NFSCLNT_IDMAX 1024
+#define NFSCLNT_ADDRMAX 16
+#define NFSCLNT_KEYMAX 32
+
+#define NFSEXP_READONLY 0x0001
+#define NFSEXP_INSECURE_PORT 0x0002
+#define NFSEXP_ROOTSQUASH 0x0004
+#define NFSEXP_ALLSQUASH 0x0008
+#define NFSEXP_ASYNC 0x0010
+#define NFSEXP_GATHERED_WRITES 0x0020
+
+#define NFSEXP_NOHIDE 0x0200
+#define NFSEXP_NOSUBTREECHECK 0x0400
+#define NFSEXP_NOAUTHNLM 0x0800  
+#define NFSEXP_MSNFS 0x1000  
+#define NFSEXP_FSID 0x2000
+#define NFSEXP_CROSSMOUNT 0x4000
+#define NFSEXP_NOACL 0x8000  
+#define NFSEXP_ALLFLAGS 0xFE3F
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nfsd/interface.h b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/interface.h
new file mode 100644
index 0000000..3c3946a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/interface.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_NFSD_INTERFACE_H
+#define LINUX_NFSD_INTERFACE_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nfsd/nfsfh.h b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/nfsfh.h
new file mode 100644
index 0000000..13450d2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/nfsfh.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NFSD_FH_H
+#define _LINUX_NFSD_FH_H
+
+#include <asm/types.h>
+#include <linux/nfsd/const.h>
+#include <linux/nfsd/debug.h>
+
+struct nfs_fhbase_old {
+ __u32 fb_dcookie;
+ __u32 fb_ino;
+ __u32 fb_dirino;
+ __u32 fb_dev;
+ __u32 fb_xdev;
+ __u32 fb_xino;
+ __u32 fb_generation;
+};
+
+struct nfs_fhbase_new {
+ __u8 fb_version;
+ __u8 fb_auth_type;
+ __u8 fb_fsid_type;
+ __u8 fb_fileid_type;
+ __u32 fb_auth[1];
+
+};
+
+struct knfsd_fh {
+ unsigned int fh_size;
+ union {
+ struct nfs_fhbase_old fh_old;
+ __u32 fh_pad[NFS4_FHSIZE/4];
+ struct nfs_fhbase_new fh_new;
+ } fh_base;
+};
+
+#define ofh_dcookie fh_base.fh_old.fb_dcookie
+#define ofh_ino fh_base.fh_old.fb_ino
+#define ofh_dirino fh_base.fh_old.fb_dirino
+#define ofh_dev fh_base.fh_old.fb_dev
+#define ofh_xdev fh_base.fh_old.fb_xdev
+#define ofh_xino fh_base.fh_old.fb_xino
+#define ofh_generation fh_base.fh_old.fb_generation
+
+#define fh_version fh_base.fh_new.fb_version
+#define fh_fsid_type fh_base.fh_new.fb_fsid_type
+#define fh_auth_type fh_base.fh_new.fb_auth_type
+#define fh_fileid_type fh_base.fh_new.fb_fileid_type
+#define fh_auth fh_base.fh_new.fb_auth
+#define fh_fsid fh_base.fh_new.fb_auth
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nfsd/stats.h b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/stats.h
new file mode 100644
index 0000000..647e65c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/stats.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_NFSD_STATS_H
+#define LINUX_NFSD_STATS_H
+
+#include <linux/nfs4.h>
+
+struct nfsd_stats {
+ unsigned int rchits;
+ unsigned int rcmisses;
+ unsigned int rcnocache;
+ unsigned int fh_stale;
+ unsigned int fh_lookup;
+ unsigned int fh_anon;
+ unsigned int fh_nocache_dir;
+ unsigned int fh_nocache_nondir;
+ unsigned int io_read;
+ unsigned int io_write;
+ unsigned int th_cnt;
+ unsigned int th_usage[10];
+ unsigned int th_fullcnt;
+ unsigned int ra_size;
+ unsigned int ra_depth[11];
+
+};
+
+#define NFSD_USAGE_WRAP (HZ*1000000)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nfsd/xdr.h b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/xdr.h
new file mode 100644
index 0000000..f94961d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nfsd/xdr.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_NFSD_H
+#define LINUX_NFSD_H
+
+#include <linux/fs.h>
+#include <linux/vfs.h>
+#include <linux/nfs.h>
+
+struct nfsd_fhandle {
+ struct svc_fh fh;
+};
+
+struct nfsd_sattrargs {
+ struct svc_fh fh;
+ struct iattr attrs;
+};
+
+struct nfsd_diropargs {
+ struct svc_fh fh;
+ char * name;
+ int len;
+};
+
+struct nfsd_readargs {
+ struct svc_fh fh;
+ __u32 offset;
+ __u32 count;
+ struct kvec vec[RPCSVC_MAXPAGES];
+ int vlen;
+};
+
+struct nfsd_writeargs {
+ svc_fh fh;
+ __u32 offset;
+ int len;
+ struct kvec vec[RPCSVC_MAXPAGES];
+ int vlen;
+};
+
+struct nfsd_createargs {
+ struct svc_fh fh;
+ char * name;
+ int len;
+ struct iattr attrs;
+};
+
+struct nfsd_renameargs {
+ struct svc_fh ffh;
+ char * fname;
+ int flen;
+ struct svc_fh tfh;
+ char * tname;
+ int tlen;
+};
+
+struct nfsd_readlinkargs {
+ struct svc_fh fh;
+ char * buffer;
+};
+
+struct nfsd_linkargs {
+ struct svc_fh ffh;
+ struct svc_fh tfh;
+ char * tname;
+ int tlen;
+};
+
+struct nfsd_symlinkargs {
+ struct svc_fh ffh;
+ char * fname;
+ int flen;
+ char * tname;
+ int tlen;
+ struct iattr attrs;
+};
+
+struct nfsd_readdirargs {
+ struct svc_fh fh;
+ __u32 cookie;
+ __u32 count;
+ u32 * buffer;
+};
+
+struct nfsd_attrstat {
+ struct svc_fh fh;
+ struct kstat stat;
+};
+
+struct nfsd_diropres {
+ struct svc_fh fh;
+ struct kstat stat;
+};
+
+struct nfsd_readlinkres {
+ int len;
+};
+
+struct nfsd_readres {
+ struct svc_fh fh;
+ unsigned long count;
+ struct kstat stat;
+};
+
+struct nfsd_readdirres {
+ int count;
+
+ struct readdir_cd common;
+ u32 * buffer;
+ int buflen;
+ u32 * offset;
+};
+
+struct nfsd_statfsres {
+ struct kstatfs stats;
+};
+
+union nfsd_xdrstore {
+ struct nfsd_sattrargs sattr;
+ struct nfsd_diropargs dirop;
+ struct nfsd_readargs read;
+ struct nfsd_writeargs write;
+ struct nfsd_createargs create;
+ struct nfsd_renameargs rename;
+ struct nfsd_linkargs link;
+ struct nfsd_symlinkargs symlink;
+ struct nfsd_readdirargs readdir;
+};
+
+#define NFS2_SVC_XDRSIZE sizeof(union nfsd_xdrstore)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/node.h b/ndk/build/platforms/android-1.5/common/include/linux/node.h
new file mode 100644
index 0000000..b33bffc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/node.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NODE_H_
+#define _LINUX_NODE_H_
+
+#include <linux/sysdev.h>
+#include <linux/cpumask.h>
+
+struct node {
+ struct sys_device sysdev;
+};
+
+#define to_node(sys_device) container_of(sys_device, struct node, sysdev)
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nodemask.h b/ndk/build/platforms/android-1.5/common/include/linux/nodemask.h
new file mode 100644
index 0000000..4ec8632
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nodemask.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_NODEMASK_H
+#define __LINUX_NODEMASK_H
+
+#include <linux/kernel.h>
+#include <linux/threads.h>
+#include <linux/bitmap.h>
+#include <linux/numa.h>
+
+typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t;
+
+#define node_set(node, dst) __node_set((node), &(dst))
+#define node_clear(node, dst) __node_clear((node), &(dst))
+#define nodes_setall(dst) __nodes_setall(&(dst), MAX_NUMNODES)
+#define nodes_clear(dst) __nodes_clear(&(dst), MAX_NUMNODES)
+#define node_isset(node, nodemask) test_bit((node), (nodemask).bits)
+#define node_test_and_set(node, nodemask)   __node_test_and_set((node), &(nodemask))
+#define nodes_and(dst, src1, src2)   __nodes_and(&(dst), &(src1), &(src2), MAX_NUMNODES)
+#define nodes_or(dst, src1, src2)   __nodes_or(&(dst), &(src1), &(src2), MAX_NUMNODES)
+#define nodes_xor(dst, src1, src2)   __nodes_xor(&(dst), &(src1), &(src2), MAX_NUMNODES)
+#define nodes_andnot(dst, src1, src2)   __nodes_andnot(&(dst), &(src1), &(src2), MAX_NUMNODES)
+#define nodes_complement(dst, src)   __nodes_complement(&(dst), &(src), MAX_NUMNODES)
+#define nodes_equal(src1, src2)   __nodes_equal(&(src1), &(src2), MAX_NUMNODES)
+#define nodes_intersects(src1, src2)   __nodes_intersects(&(src1), &(src2), MAX_NUMNODES)
+#define nodes_subset(src1, src2)   __nodes_subset(&(src1), &(src2), MAX_NUMNODES)
+#define nodes_empty(src) __nodes_empty(&(src), MAX_NUMNODES)
+#define nodes_full(nodemask) __nodes_full(&(nodemask), MAX_NUMNODES)
+#define nodes_weight(nodemask) __nodes_weight(&(nodemask), MAX_NUMNODES)
+#define nodes_shift_right(dst, src, n)   __nodes_shift_right(&(dst), &(src), (n), MAX_NUMNODES)
+#define nodes_shift_left(dst, src, n)   __nodes_shift_left(&(dst), &(src), (n), MAX_NUMNODES)
+#define first_node(src) __first_node(&(src))
+#define next_node(n, src) __next_node((n), &(src))
+#define nodemask_of_node(node)  ({   typeof(_unused_nodemask_arg_) m;   if (sizeof(m) == sizeof(unsigned long)) {   m.bits[0] = 1UL<<(node);   } else {   nodes_clear(m);   node_set((node), m);   }   m;  })
+#define first_unset_node(mask) __first_unset_node(&(mask))
+#define NODE_MASK_LAST_WORD BITMAP_LAST_WORD_MASK(MAX_NUMNODES)
+#if MAX_NUMNODES <= BITS_PER_LONG
+#define NODE_MASK_ALL  ((nodemask_t) { {   [BITS_TO_LONGS(MAX_NUMNODES)-1] = NODE_MASK_LAST_WORD  } })
+#else
+#define NODE_MASK_ALL  ((nodemask_t) { {   [0 ... BITS_TO_LONGS(MAX_NUMNODES)-2] = ~0UL,   [BITS_TO_LONGS(MAX_NUMNODES)-1] = NODE_MASK_LAST_WORD  } })
+#endif
+#define NODE_MASK_NONE  ((nodemask_t) { {   [0 ... BITS_TO_LONGS(MAX_NUMNODES)-1] = 0UL  } })
+#define nodes_addr(src) ((src).bits)
+#define nodemask_scnprintf(buf, len, src)   __nodemask_scnprintf((buf), (len), &(src), MAX_NUMNODES)
+#define nodemask_parse(ubuf, ulen, dst)   __nodemask_parse((ubuf), (ulen), &(dst), MAX_NUMNODES)
+#define nodelist_scnprintf(buf, len, src)   __nodelist_scnprintf((buf), (len), &(src), MAX_NUMNODES)
+#define nodelist_parse(buf, dst) __nodelist_parse((buf), &(dst), MAX_NUMNODES)
+#define node_remap(oldbit, old, new)   __node_remap((oldbit), &(old), &(new), MAX_NUMNODES)
+#define nodes_remap(dst, src, old, new)   __nodes_remap(&(dst), &(src), &(old), &(new), MAX_NUMNODES)
+#if MAX_NUMNODES > 1
+#define for_each_node_mask(node, mask)   for ((node) = first_node(mask);   (node) < MAX_NUMNODES;   (node) = next_node((node), (mask)))
+#else
+#define for_each_node_mask(node, mask)   if (!nodes_empty(mask))   for ((node) = 0; (node) < 1; (node)++)
+#endif
+
+#if MAX_NUMNODES > 1
+#define num_online_nodes() nodes_weight(node_online_map)
+#define num_possible_nodes() nodes_weight(node_possible_map)
+#define node_online(node) node_isset((node), node_online_map)
+#define node_possible(node) node_isset((node), node_possible_map)
+#define first_online_node first_node(node_online_map)
+#define next_online_node(nid) next_node((nid), node_online_map)
+#else
+#define num_online_nodes() 1
+#define num_possible_nodes() 1
+#define node_online(node) ((node) == 0)
+#define node_possible(node) ((node) == 0)
+#define first_online_node 0
+#define next_online_node(nid) (MAX_NUMNODES)
+#endif
+
+#define any_online_node(mask)  ({   int node;   for_each_node_mask(node, (mask))   if (node_online(node))   break;   node;  })
+
+#define node_set_online(node) set_bit((node), node_online_map.bits)
+#define node_set_offline(node) clear_bit((node), node_online_map.bits)
+
+#define for_each_node(node) for_each_node_mask((node), node_possible_map)
+#define for_each_online_node(node) for_each_node_mask((node), node_online_map)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/notifier.h b/ndk/build/platforms/android-1.5/common/include/linux/notifier.h
new file mode 100644
index 0000000..f1fc461
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/notifier.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NOTIFIER_H
+#define _LINUX_NOTIFIER_H
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/rwsem.h>
+
+struct notifier_block {
+ int (*notifier_call)(struct notifier_block *, unsigned long, void *);
+ struct notifier_block *next;
+ int priority;
+};
+
+struct atomic_notifier_head {
+ spinlock_t lock;
+ struct notifier_block *head;
+};
+
+struct blocking_notifier_head {
+ struct rw_semaphore rwsem;
+ struct notifier_block *head;
+};
+
+struct raw_notifier_head {
+ struct notifier_block *head;
+};
+
+#define ATOMIC_INIT_NOTIFIER_HEAD(name) do {   spin_lock_init(&(name)->lock);   (name)->head = NULL;   } while (0)
+#define BLOCKING_INIT_NOTIFIER_HEAD(name) do {   init_rwsem(&(name)->rwsem);   (name)->head = NULL;   } while (0)
+#define RAW_INIT_NOTIFIER_HEAD(name) do {   (name)->head = NULL;   } while (0)
+
+#define ATOMIC_NOTIFIER_INIT(name) {   .lock = __SPIN_LOCK_UNLOCKED(name.lock),   .head = NULL }
+#define BLOCKING_NOTIFIER_INIT(name) {   .rwsem = __RWSEM_INITIALIZER((name).rwsem),   .head = NULL }
+#define RAW_NOTIFIER_INIT(name) {   .head = NULL }
+
+#define ATOMIC_NOTIFIER_HEAD(name)   struct atomic_notifier_head name =   ATOMIC_NOTIFIER_INIT(name)
+#define BLOCKING_NOTIFIER_HEAD(name)   struct blocking_notifier_head name =   BLOCKING_NOTIFIER_INIT(name)
+#define RAW_NOTIFIER_HEAD(name)   struct raw_notifier_head name =   RAW_NOTIFIER_INIT(name)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/numa.h b/ndk/build/platforms/android-1.5/common/include/linux/numa.h
new file mode 100644
index 0000000..f5d66f5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/numa.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NUMA_H
+#define _LINUX_NUMA_H
+
+#define NODES_SHIFT 0
+
+#define MAX_NUMNODES (1 << NODES_SHIFT)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/nvram.h b/ndk/build/platforms/android-1.5/common/include/linux/nvram.h
new file mode 100644
index 0000000..b358bdb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/nvram.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_NVRAM_H
+#define _LINUX_NVRAM_H
+
+#include <linux/ioctl.h>
+
+#define NVRAM_INIT _IO('p', 0x40)  
+#define NVRAM_SETCKS _IO('p', 0x41)  
+
+#define NVRAM_FIRST_BYTE 14
+
+#define NVRAM_OFFSET(x) ((x)-NVRAM_FIRST_BYTE)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/omap_csmi.h b/ndk/build/platforms/android-1.5/common/include/linux/omap_csmi.h
new file mode 100644
index 0000000..6a28d3d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/omap_csmi.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _OMAP_CSMI_H_
+#define _OMAP_CSMI_H_
+
+#include <asm/ioctl.h>
+
+#define OMAP_CSMI_TTY_ENABLE_ACK _IO('c', 0)
+#define OMAP_CSMI_TTY_DISABLE_ACK _IO('c', 1)
+#define OMAP_CSMI_TTY_READ_UNACKED _IOR('c', 2, int)
+#define OMAP_CSMI_TTY_ACK _IOW('c', 3, int)
+#define OMAP_CSMI_TTY_WAKEUP_AND_ACK _IOW('c', 4, int)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/pagemap.h b/ndk/build/platforms/android-1.5/common/include/linux/pagemap.h
new file mode 100644
index 0000000..8dd397d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/pagemap.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_PAGEMAP_H
+#define _LINUX_PAGEMAP_H
+
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/highmem.h>
+#include <linux/compiler.h>
+#include <asm/uaccess.h>
+#include <linux/gfp.h>
+
+#define AS_EIO (__GFP_BITS_SHIFT + 0)  
+#define AS_ENOSPC (__GFP_BITS_SHIFT + 1)  
+
+#define PAGE_CACHE_SHIFT PAGE_SHIFT
+#define PAGE_CACHE_SIZE PAGE_SIZE
+#define PAGE_CACHE_MASK PAGE_MASK
+#define PAGE_CACHE_ALIGN(addr) (((addr)+PAGE_CACHE_SIZE-1)&PAGE_CACHE_MASK)
+#define page_cache_get(page) get_page(page)
+#define page_cache_release(page) put_page(page)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/param.h b/ndk/build/platforms/android-1.5/common/include/linux/param.h
new file mode 100644
index 0000000..456695d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/param.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_PARAM_H
+#define _LINUX_PARAM_H
+
+#include <asm/param.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/patchkey.h b/ndk/build/platforms/android-1.5/common/include/linux/patchkey.h
new file mode 100644
index 0000000..fdf86ce
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/patchkey.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_PATCHKEY_H_INDIRECT
+#error "patchkey.h included directly"
+#endif
+
+#ifndef _LINUX_PATCHKEY_H
+#define _LINUX_PATCHKEY_H
+
+#include <endian.h>
+
+#ifdef __BYTE_ORDER
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define _PATCHKEY(id) (0xfd00|id)
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#define _PATCHKEY(id) ((id<<8)|0x00fd)
+#else
+#error "could not determine byte order"
+#endif
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/pci.h b/ndk/build/platforms/android-1.5/common/include/linux/pci.h
new file mode 100644
index 0000000..165deb4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/pci.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_PCI_H
+#define LINUX_PCI_H
+
+#include <linux/pci_regs.h>
+
+#include <linux/pci_ids.h>
+
+#define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
+#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
+#define PCI_FUNC(devfn) ((devfn) & 0x07)
+
+#define PCIIOC_BASE ('P' << 24 | 'C' << 16 | 'I' << 8)
+#define PCIIOC_CONTROLLER (PCIIOC_BASE | 0x00)  
+#define PCIIOC_MMAP_IS_IO (PCIIOC_BASE | 0x01)  
+#define PCIIOC_MMAP_IS_MEM (PCIIOC_BASE | 0x02)  
+#define PCIIOC_WRITE_COMBINE (PCIIOC_BASE | 0x03)  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/pci_ids.h b/ndk/build/platforms/android-1.5/common/include/linux/pci_ids.h
new file mode 100644
index 0000000..ec5adfb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/pci_ids.h
@@ -0,0 +1,2270 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#define PCI_CLASS_NOT_DEFINED 0x0000
+#define PCI_CLASS_NOT_DEFINED_VGA 0x0001
+
+#define PCI_BASE_CLASS_STORAGE 0x01
+#define PCI_CLASS_STORAGE_SCSI 0x0100
+#define PCI_CLASS_STORAGE_IDE 0x0101
+#define PCI_CLASS_STORAGE_FLOPPY 0x0102
+#define PCI_CLASS_STORAGE_IPI 0x0103
+#define PCI_CLASS_STORAGE_RAID 0x0104
+#define PCI_CLASS_STORAGE_SAS 0x0107
+#define PCI_CLASS_STORAGE_OTHER 0x0180
+
+#define PCI_BASE_CLASS_NETWORK 0x02
+#define PCI_CLASS_NETWORK_ETHERNET 0x0200
+#define PCI_CLASS_NETWORK_TOKEN_RING 0x0201
+#define PCI_CLASS_NETWORK_FDDI 0x0202
+#define PCI_CLASS_NETWORK_ATM 0x0203
+#define PCI_CLASS_NETWORK_OTHER 0x0280
+
+#define PCI_BASE_CLASS_DISPLAY 0x03
+#define PCI_CLASS_DISPLAY_VGA 0x0300
+#define PCI_CLASS_DISPLAY_XGA 0x0301
+#define PCI_CLASS_DISPLAY_3D 0x0302
+#define PCI_CLASS_DISPLAY_OTHER 0x0380
+
+#define PCI_BASE_CLASS_MULTIMEDIA 0x04
+#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400
+#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401
+#define PCI_CLASS_MULTIMEDIA_PHONE 0x0402
+#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480
+
+#define PCI_BASE_CLASS_MEMORY 0x05
+#define PCI_CLASS_MEMORY_RAM 0x0500
+#define PCI_CLASS_MEMORY_FLASH 0x0501
+#define PCI_CLASS_MEMORY_OTHER 0x0580
+
+#define PCI_BASE_CLASS_BRIDGE 0x06
+#define PCI_CLASS_BRIDGE_HOST 0x0600
+#define PCI_CLASS_BRIDGE_ISA 0x0601
+#define PCI_CLASS_BRIDGE_EISA 0x0602
+#define PCI_CLASS_BRIDGE_MC 0x0603
+#define PCI_CLASS_BRIDGE_PCI 0x0604
+#define PCI_CLASS_BRIDGE_PCMCIA 0x0605
+#define PCI_CLASS_BRIDGE_NUBUS 0x0606
+#define PCI_CLASS_BRIDGE_CARDBUS 0x0607
+#define PCI_CLASS_BRIDGE_RACEWAY 0x0608
+#define PCI_CLASS_BRIDGE_OTHER 0x0680
+
+#define PCI_BASE_CLASS_COMMUNICATION 0x07
+#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700
+#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701
+#define PCI_CLASS_COMMUNICATION_MULTISERIAL 0x0702
+#define PCI_CLASS_COMMUNICATION_MODEM 0x0703
+#define PCI_CLASS_COMMUNICATION_OTHER 0x0780
+
+#define PCI_BASE_CLASS_SYSTEM 0x08
+#define PCI_CLASS_SYSTEM_PIC 0x0800
+#define PCI_CLASS_SYSTEM_PIC_IOAPIC 0x080010
+#define PCI_CLASS_SYSTEM_PIC_IOXAPIC 0x080020
+#define PCI_CLASS_SYSTEM_DMA 0x0801
+#define PCI_CLASS_SYSTEM_TIMER 0x0802
+#define PCI_CLASS_SYSTEM_RTC 0x0803
+#define PCI_CLASS_SYSTEM_PCI_HOTPLUG 0x0804
+#define PCI_CLASS_SYSTEM_SDHCI 0x0805
+#define PCI_CLASS_SYSTEM_OTHER 0x0880
+
+#define PCI_BASE_CLASS_INPUT 0x09
+#define PCI_CLASS_INPUT_KEYBOARD 0x0900
+#define PCI_CLASS_INPUT_PEN 0x0901
+#define PCI_CLASS_INPUT_MOUSE 0x0902
+#define PCI_CLASS_INPUT_SCANNER 0x0903
+#define PCI_CLASS_INPUT_GAMEPORT 0x0904
+#define PCI_CLASS_INPUT_OTHER 0x0980
+
+#define PCI_BASE_CLASS_DOCKING 0x0a
+#define PCI_CLASS_DOCKING_GENERIC 0x0a00
+#define PCI_CLASS_DOCKING_OTHER 0x0a80
+
+#define PCI_BASE_CLASS_PROCESSOR 0x0b
+#define PCI_CLASS_PROCESSOR_386 0x0b00
+#define PCI_CLASS_PROCESSOR_486 0x0b01
+#define PCI_CLASS_PROCESSOR_PENTIUM 0x0b02
+#define PCI_CLASS_PROCESSOR_ALPHA 0x0b10
+#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20
+#define PCI_CLASS_PROCESSOR_MIPS 0x0b30
+#define PCI_CLASS_PROCESSOR_CO 0x0b40
+
+#define PCI_BASE_CLASS_SERIAL 0x0c
+#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00
+#define PCI_CLASS_SERIAL_ACCESS 0x0c01
+#define PCI_CLASS_SERIAL_SSA 0x0c02
+#define PCI_CLASS_SERIAL_USB 0x0c03
+#define PCI_CLASS_SERIAL_USB_UHCI 0x0c0300
+#define PCI_CLASS_SERIAL_USB_OHCI 0x0c0310
+#define PCI_CLASS_SERIAL_USB_EHCI 0x0c0320
+#define PCI_CLASS_SERIAL_FIBER 0x0c04
+#define PCI_CLASS_SERIAL_SMBUS 0x0c05
+
+#define PCI_BASE_CLASS_INTELLIGENT 0x0e
+#define PCI_CLASS_INTELLIGENT_I2O 0x0e00
+
+#define PCI_BASE_CLASS_SATELLITE 0x0f
+#define PCI_CLASS_SATELLITE_TV 0x0f00
+#define PCI_CLASS_SATELLITE_AUDIO 0x0f01
+#define PCI_CLASS_SATELLITE_VOICE 0x0f03
+#define PCI_CLASS_SATELLITE_DATA 0x0f04
+
+#define PCI_BASE_CLASS_CRYPT 0x10
+#define PCI_CLASS_CRYPT_NETWORK 0x1000
+#define PCI_CLASS_CRYPT_ENTERTAINMENT 0x1001
+#define PCI_CLASS_CRYPT_OTHER 0x1080
+
+#define PCI_BASE_CLASS_SIGNAL_PROCESSING 0x11
+#define PCI_CLASS_SP_DPIO 0x1100
+#define PCI_CLASS_SP_OTHER 0x1180
+
+#define PCI_CLASS_OTHERS 0xff
+
+#define PCI_VENDOR_ID_DYNALINK 0x0675
+#define PCI_DEVICE_ID_DYNALINK_IS64PH 0x1702
+
+#define PCI_VENDOR_ID_BERKOM 0x0871
+#define PCI_DEVICE_ID_BERKOM_A1T 0xffa1
+#define PCI_DEVICE_ID_BERKOM_T_CONCEPT 0xffa2
+#define PCI_DEVICE_ID_BERKOM_A4T 0xffa4
+#define PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO 0xffa8
+
+#define PCI_VENDOR_ID_COMPAQ 0x0e11
+#define PCI_DEVICE_ID_COMPAQ_TOKENRING 0x0508
+#define PCI_DEVICE_ID_COMPAQ_TACHYON 0xa0fc
+#define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10
+#define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32
+#define PCI_DEVICE_ID_COMPAQ_NETEL10 0xae34
+#define PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE 0xae33
+#define PCI_DEVICE_ID_COMPAQ_NETFLEX3I 0xae35
+#define PCI_DEVICE_ID_COMPAQ_NETEL100D 0xae40
+#define PCI_DEVICE_ID_COMPAQ_NETEL100PI 0xae43
+#define PCI_DEVICE_ID_COMPAQ_NETEL100I 0xb011
+#define PCI_DEVICE_ID_COMPAQ_CISS 0xb060
+#define PCI_DEVICE_ID_COMPAQ_CISSB 0xb178
+#define PCI_DEVICE_ID_COMPAQ_CISSC 0x46
+#define PCI_DEVICE_ID_COMPAQ_THUNDER 0xf130
+#define PCI_DEVICE_ID_COMPAQ_NETFLEX3B 0xf150
+
+#define PCI_VENDOR_ID_NCR 0x1000
+#define PCI_VENDOR_ID_LSI_LOGIC 0x1000
+#define PCI_DEVICE_ID_NCR_53C810 0x0001
+#define PCI_DEVICE_ID_NCR_53C820 0x0002
+#define PCI_DEVICE_ID_NCR_53C825 0x0003
+#define PCI_DEVICE_ID_NCR_53C815 0x0004
+#define PCI_DEVICE_ID_LSI_53C810AP 0x0005
+#define PCI_DEVICE_ID_NCR_53C860 0x0006
+#define PCI_DEVICE_ID_LSI_53C1510 0x000a
+#define PCI_DEVICE_ID_NCR_53C896 0x000b
+#define PCI_DEVICE_ID_NCR_53C895 0x000c
+#define PCI_DEVICE_ID_NCR_53C885 0x000d
+#define PCI_DEVICE_ID_NCR_53C875 0x000f
+#define PCI_DEVICE_ID_NCR_53C1510 0x0010
+#define PCI_DEVICE_ID_LSI_53C895A 0x0012
+#define PCI_DEVICE_ID_LSI_53C875A 0x0013
+#define PCI_DEVICE_ID_LSI_53C1010_33 0x0020
+#define PCI_DEVICE_ID_LSI_53C1010_66 0x0021
+#define PCI_DEVICE_ID_LSI_53C1030 0x0030
+#define PCI_DEVICE_ID_LSI_1030_53C1035 0x0032
+#define PCI_DEVICE_ID_LSI_53C1035 0x0040
+#define PCI_DEVICE_ID_NCR_53C875J 0x008f
+#define PCI_DEVICE_ID_LSI_FC909 0x0621
+#define PCI_DEVICE_ID_LSI_FC929 0x0622
+#define PCI_DEVICE_ID_LSI_FC929_LAN 0x0623
+#define PCI_DEVICE_ID_LSI_FC919 0x0624
+#define PCI_DEVICE_ID_LSI_FC919_LAN 0x0625
+#define PCI_DEVICE_ID_LSI_FC929X 0x0626
+#define PCI_DEVICE_ID_LSI_FC939X 0x0642
+#define PCI_DEVICE_ID_LSI_FC949X 0x0640
+#define PCI_DEVICE_ID_LSI_FC949ES 0x0646
+#define PCI_DEVICE_ID_LSI_FC919X 0x0628
+#define PCI_DEVICE_ID_NCR_YELLOWFIN 0x0701
+#define PCI_DEVICE_ID_LSI_61C102 0x0901
+#define PCI_DEVICE_ID_LSI_63C815 0x1000
+#define PCI_DEVICE_ID_LSI_SAS1064 0x0050
+#define PCI_DEVICE_ID_LSI_SAS1064R 0x0411
+#define PCI_DEVICE_ID_LSI_SAS1066 0x005E
+#define PCI_DEVICE_ID_LSI_SAS1068 0x0054
+#define PCI_DEVICE_ID_LSI_SAS1064A 0x005C
+#define PCI_DEVICE_ID_LSI_SAS1064E 0x0056
+#define PCI_DEVICE_ID_LSI_SAS1066E 0x005A
+#define PCI_DEVICE_ID_LSI_SAS1068E 0x0058
+#define PCI_DEVICE_ID_LSI_SAS1078 0x0060
+
+#define PCI_VENDOR_ID_ATI 0x1002
+
+#define PCI_DEVICE_ID_ATI_68800 0x4158
+#define PCI_DEVICE_ID_ATI_215CT222 0x4354
+#define PCI_DEVICE_ID_ATI_210888CX 0x4358
+#define PCI_DEVICE_ID_ATI_215ET222 0x4554
+
+#define PCI_DEVICE_ID_ATI_215GB 0x4742
+#define PCI_DEVICE_ID_ATI_215GD 0x4744
+#define PCI_DEVICE_ID_ATI_215GI 0x4749
+#define PCI_DEVICE_ID_ATI_215GP 0x4750
+#define PCI_DEVICE_ID_ATI_215GQ 0x4751
+#define PCI_DEVICE_ID_ATI_215XL 0x4752
+#define PCI_DEVICE_ID_ATI_215GT 0x4754
+#define PCI_DEVICE_ID_ATI_215GTB 0x4755
+#define PCI_DEVICE_ID_ATI_215_IV 0x4756
+#define PCI_DEVICE_ID_ATI_215_IW 0x4757
+#define PCI_DEVICE_ID_ATI_215_IZ 0x475A
+#define PCI_DEVICE_ID_ATI_210888GX 0x4758
+#define PCI_DEVICE_ID_ATI_215_LB 0x4c42
+#define PCI_DEVICE_ID_ATI_215_LD 0x4c44
+#define PCI_DEVICE_ID_ATI_215_LG 0x4c47
+#define PCI_DEVICE_ID_ATI_215_LI 0x4c49
+#define PCI_DEVICE_ID_ATI_215_LM 0x4c4D
+#define PCI_DEVICE_ID_ATI_215_LN 0x4c4E
+#define PCI_DEVICE_ID_ATI_215_LR 0x4c52
+#define PCI_DEVICE_ID_ATI_215_LS 0x4c53
+#define PCI_DEVICE_ID_ATI_264_LT 0x4c54
+
+#define PCI_DEVICE_ID_ATI_264VT 0x5654
+#define PCI_DEVICE_ID_ATI_264VU 0x5655
+#define PCI_DEVICE_ID_ATI_264VV 0x5656
+
+#define PCI_DEVICE_ID_ATI_RAGE128_RE 0x5245
+#define PCI_DEVICE_ID_ATI_RAGE128_RF 0x5246
+#define PCI_DEVICE_ID_ATI_RAGE128_RG 0x5247
+
+#define PCI_DEVICE_ID_ATI_RAGE128_RK 0x524b
+#define PCI_DEVICE_ID_ATI_RAGE128_RL 0x524c
+#define PCI_DEVICE_ID_ATI_RAGE128_SE 0x5345
+#define PCI_DEVICE_ID_ATI_RAGE128_SF 0x5346
+#define PCI_DEVICE_ID_ATI_RAGE128_SG 0x5347
+#define PCI_DEVICE_ID_ATI_RAGE128_SH 0x5348
+#define PCI_DEVICE_ID_ATI_RAGE128_SK 0x534b
+#define PCI_DEVICE_ID_ATI_RAGE128_SL 0x534c
+#define PCI_DEVICE_ID_ATI_RAGE128_SM 0x534d
+#define PCI_DEVICE_ID_ATI_RAGE128_SN 0x534e
+
+#define PCI_DEVICE_ID_ATI_RAGE128_TF 0x5446
+#define PCI_DEVICE_ID_ATI_RAGE128_TL 0x544c
+#define PCI_DEVICE_ID_ATI_RAGE128_TR 0x5452
+#define PCI_DEVICE_ID_ATI_RAGE128_TS 0x5453
+#define PCI_DEVICE_ID_ATI_RAGE128_TT 0x5454
+#define PCI_DEVICE_ID_ATI_RAGE128_TU 0x5455
+
+#define PCI_DEVICE_ID_ATI_RAGE128_LE 0x4c45
+#define PCI_DEVICE_ID_ATI_RAGE128_LF 0x4c46
+
+#define PCI_DEVICE_ID_ATI_RAGE128_MF 0x4d46
+#define PCI_DEVICE_ID_ATI_RAGE128_ML 0x4d4c
+
+#define PCI_DEVICE_ID_ATI_RAGE128_PA 0x5041
+#define PCI_DEVICE_ID_ATI_RAGE128_PB 0x5042
+#define PCI_DEVICE_ID_ATI_RAGE128_PC 0x5043
+#define PCI_DEVICE_ID_ATI_RAGE128_PD 0x5044
+#define PCI_DEVICE_ID_ATI_RAGE128_PE 0x5045
+#define PCI_DEVICE_ID_ATI_RAGE128_PF 0x5046
+
+#define PCI_DEVICE_ID_ATI_RAGE128_PG 0x5047
+#define PCI_DEVICE_ID_ATI_RAGE128_PH 0x5048
+#define PCI_DEVICE_ID_ATI_RAGE128_PI 0x5049
+#define PCI_DEVICE_ID_ATI_RAGE128_PJ 0x504A
+#define PCI_DEVICE_ID_ATI_RAGE128_PK 0x504B
+#define PCI_DEVICE_ID_ATI_RAGE128_PL 0x504C
+#define PCI_DEVICE_ID_ATI_RAGE128_PM 0x504D
+#define PCI_DEVICE_ID_ATI_RAGE128_PN 0x504E
+#define PCI_DEVICE_ID_ATI_RAGE128_PO 0x504F
+#define PCI_DEVICE_ID_ATI_RAGE128_PP 0x5050
+#define PCI_DEVICE_ID_ATI_RAGE128_PQ 0x5051
+#define PCI_DEVICE_ID_ATI_RAGE128_PR 0x5052
+#define PCI_DEVICE_ID_ATI_RAGE128_PS 0x5053
+#define PCI_DEVICE_ID_ATI_RAGE128_PT 0x5054
+#define PCI_DEVICE_ID_ATI_RAGE128_PU 0x5055
+#define PCI_DEVICE_ID_ATI_RAGE128_PV 0x5056
+#define PCI_DEVICE_ID_ATI_RAGE128_PW 0x5057
+#define PCI_DEVICE_ID_ATI_RAGE128_PX 0x5058
+
+#define PCI_DEVICE_ID_ATI_RADEON_QD 0x5144
+#define PCI_DEVICE_ID_ATI_RADEON_QE 0x5145
+#define PCI_DEVICE_ID_ATI_RADEON_QF 0x5146
+#define PCI_DEVICE_ID_ATI_RADEON_QG 0x5147
+
+#define PCI_DEVICE_ID_ATI_RADEON_QY 0x5159
+#define PCI_DEVICE_ID_ATI_RADEON_QZ 0x515a
+
+#define PCI_DEVICE_ID_ATI_RADEON_QL 0x514c
+#define PCI_DEVICE_ID_ATI_RADEON_QN 0x514e
+#define PCI_DEVICE_ID_ATI_RADEON_QO 0x514f
+#define PCI_DEVICE_ID_ATI_RADEON_Ql 0x516c
+#define PCI_DEVICE_ID_ATI_RADEON_BB 0x4242
+
+#define PCI_DEVICE_ID_ATI_RADEON_QM 0x514d
+
+#define PCI_DEVICE_ID_ATI_RADEON_QW 0x5157
+#define PCI_DEVICE_ID_ATI_RADEON_QX 0x5158
+
+#define PCI_DEVICE_ID_ATI_RADEON_Id 0x4964
+#define PCI_DEVICE_ID_ATI_RADEON_Ie 0x4965
+#define PCI_DEVICE_ID_ATI_RADEON_If 0x4966
+#define PCI_DEVICE_ID_ATI_RADEON_Ig 0x4967
+
+#define PCI_DEVICE_ID_ATI_RADEON_Ya 0x5961
+#define PCI_DEVICE_ID_ATI_RADEON_Yd 0x5964
+
+#define PCI_DEVICE_ID_ATI_RADEON_ND 0x4e44
+#define PCI_DEVICE_ID_ATI_RADEON_NE 0x4e45
+#define PCI_DEVICE_ID_ATI_RADEON_NF 0x4e46
+#define PCI_DEVICE_ID_ATI_RADEON_NG 0x4e47
+
+#define PCI_DEVICE_ID_ATI_RADEON_LY 0x4c59
+#define PCI_DEVICE_ID_ATI_RADEON_LZ 0x4c5a
+
+#define PCI_DEVICE_ID_ATI_RADEON_LW 0x4c57
+#define PCI_DEVICE_ID_ATI_RADEON_LX 0x4c58
+
+#define PCI_DEVICE_ID_ATI_RADEON_Ld 0x4c64
+#define PCI_DEVICE_ID_ATI_RADEON_Le 0x4c65
+#define PCI_DEVICE_ID_ATI_RADEON_Lf 0x4c66
+#define PCI_DEVICE_ID_ATI_RADEON_Lg 0x4c67
+
+#define PCI_DEVICE_ID_ATI_RS100 0xcab0
+#define PCI_DEVICE_ID_ATI_RS200 0xcab2
+#define PCI_DEVICE_ID_ATI_RS200_B 0xcbb2
+#define PCI_DEVICE_ID_ATI_RS250 0xcab3
+#define PCI_DEVICE_ID_ATI_RS300_100 0x5830
+#define PCI_DEVICE_ID_ATI_RS300_133 0x5831
+#define PCI_DEVICE_ID_ATI_RS300_166 0x5832
+#define PCI_DEVICE_ID_ATI_RS300_200 0x5833
+#define PCI_DEVICE_ID_ATI_RS350_100 0x7830
+#define PCI_DEVICE_ID_ATI_RS350_133 0x7831
+#define PCI_DEVICE_ID_ATI_RS350_166 0x7832
+#define PCI_DEVICE_ID_ATI_RS350_200 0x7833
+#define PCI_DEVICE_ID_ATI_RS400_100 0x5a30
+#define PCI_DEVICE_ID_ATI_RS400_133 0x5a31
+#define PCI_DEVICE_ID_ATI_RS400_166 0x5a32
+#define PCI_DEVICE_ID_ATI_RS400_200 0x5a33
+#define PCI_DEVICE_ID_ATI_RS480 0x5950
+
+#define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349
+#define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353
+#define PCI_DEVICE_ID_ATI_IXP300_SMBUS 0x4363
+#define PCI_DEVICE_ID_ATI_IXP300_IDE 0x4369
+#define PCI_DEVICE_ID_ATI_IXP300_SATA 0x436e
+#define PCI_DEVICE_ID_ATI_IXP400_SMBUS 0x4372
+#define PCI_DEVICE_ID_ATI_IXP400_IDE 0x4376
+#define PCI_DEVICE_ID_ATI_IXP400_SATA 0x4379
+#define PCI_DEVICE_ID_ATI_IXP400_SATA2 0x437a
+#define PCI_DEVICE_ID_ATI_IXP600_SATA 0x4380
+#define PCI_DEVICE_ID_ATI_IXP600_SRAID 0x4381
+#define PCI_DEVICE_ID_ATI_IXP600_IDE 0x438c
+
+#define PCI_VENDOR_ID_VLSI 0x1004
+#define PCI_DEVICE_ID_VLSI_82C592 0x0005
+#define PCI_DEVICE_ID_VLSI_82C593 0x0006
+#define PCI_DEVICE_ID_VLSI_82C594 0x0007
+#define PCI_DEVICE_ID_VLSI_82C597 0x0009
+#define PCI_DEVICE_ID_VLSI_82C541 0x000c
+#define PCI_DEVICE_ID_VLSI_82C543 0x000d
+#define PCI_DEVICE_ID_VLSI_82C532 0x0101
+#define PCI_DEVICE_ID_VLSI_82C534 0x0102
+#define PCI_DEVICE_ID_VLSI_82C535 0x0104
+#define PCI_DEVICE_ID_VLSI_82C147 0x0105
+#define PCI_DEVICE_ID_VLSI_VAS96011 0x0702
+
+#define PCI_VENDOR_ID_ADL 0x1005
+#define PCI_DEVICE_ID_ADL_2301 0x2301
+
+#define PCI_VENDOR_ID_NS 0x100b
+#define PCI_DEVICE_ID_NS_87415 0x0002
+#define PCI_DEVICE_ID_NS_87560_LIO 0x000e
+#define PCI_DEVICE_ID_NS_87560_USB 0x0012
+#define PCI_DEVICE_ID_NS_83815 0x0020
+#define PCI_DEVICE_ID_NS_83820 0x0022
+#define PCI_DEVICE_ID_NS_CS5535_ISA 0x002b
+#define PCI_DEVICE_ID_NS_CS5535_IDE 0x002d
+#define PCI_DEVICE_ID_NS_CS5535_AUDIO 0x002e
+#define PCI_DEVICE_ID_NS_CS5535_USB 0x002f
+#define PCI_DEVICE_ID_NS_CS5535_VIDEO 0x0030
+#define PCI_DEVICE_ID_NS_SATURN 0x0035
+#define PCI_DEVICE_ID_NS_SCx200_BRIDGE 0x0500
+#define PCI_DEVICE_ID_NS_SCx200_SMI 0x0501
+#define PCI_DEVICE_ID_NS_SCx200_IDE 0x0502
+#define PCI_DEVICE_ID_NS_SCx200_AUDIO 0x0503
+#define PCI_DEVICE_ID_NS_SCx200_VIDEO 0x0504
+#define PCI_DEVICE_ID_NS_SCx200_XBUS 0x0505
+#define PCI_DEVICE_ID_NS_SC1100_BRIDGE 0x0510
+#define PCI_DEVICE_ID_NS_SC1100_SMI 0x0511
+#define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515
+#define PCI_DEVICE_ID_NS_87410 0xd001
+
+#define PCI_DEVICE_ID_NS_CS5535_HOST_BRIDGE 0x0028
+#define PCI_DEVICE_ID_NS_CS5535_ISA_BRIDGE 0x002b
+
+#define PCI_VENDOR_ID_TSENG 0x100c
+#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202
+#define PCI_DEVICE_ID_TSENG_W32P_b 0x3205
+#define PCI_DEVICE_ID_TSENG_W32P_c 0x3206
+#define PCI_DEVICE_ID_TSENG_W32P_d 0x3207
+#define PCI_DEVICE_ID_TSENG_ET6000 0x3208
+
+#define PCI_VENDOR_ID_WEITEK 0x100e
+#define PCI_DEVICE_ID_WEITEK_P9000 0x9001
+#define PCI_DEVICE_ID_WEITEK_P9100 0x9100
+
+#define PCI_VENDOR_ID_DEC 0x1011
+#define PCI_DEVICE_ID_DEC_BRD 0x0001
+#define PCI_DEVICE_ID_DEC_TULIP 0x0002
+#define PCI_DEVICE_ID_DEC_TGA 0x0004
+#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009
+#define PCI_DEVICE_ID_DEC_TGA2 0x000D
+#define PCI_DEVICE_ID_DEC_FDDI 0x000F
+#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014
+#define PCI_DEVICE_ID_DEC_21142 0x0019
+#define PCI_DEVICE_ID_DEC_21052 0x0021
+#define PCI_DEVICE_ID_DEC_21150 0x0022
+#define PCI_DEVICE_ID_DEC_21152 0x0024
+#define PCI_DEVICE_ID_DEC_21153 0x0025
+#define PCI_DEVICE_ID_DEC_21154 0x0026
+#define PCI_DEVICE_ID_DEC_21285 0x1065
+#define PCI_DEVICE_ID_COMPAQ_42XX 0x0046
+
+#define PCI_VENDOR_ID_CIRRUS 0x1013
+#define PCI_DEVICE_ID_CIRRUS_7548 0x0038
+#define PCI_DEVICE_ID_CIRRUS_5430 0x00a0
+#define PCI_DEVICE_ID_CIRRUS_5434_4 0x00a4
+#define PCI_DEVICE_ID_CIRRUS_5434_8 0x00a8
+#define PCI_DEVICE_ID_CIRRUS_5436 0x00ac
+#define PCI_DEVICE_ID_CIRRUS_5446 0x00b8
+#define PCI_DEVICE_ID_CIRRUS_5480 0x00bc
+#define PCI_DEVICE_ID_CIRRUS_5462 0x00d0
+#define PCI_DEVICE_ID_CIRRUS_5464 0x00d4
+#define PCI_DEVICE_ID_CIRRUS_5465 0x00d6
+#define PCI_DEVICE_ID_CIRRUS_6729 0x1100
+#define PCI_DEVICE_ID_CIRRUS_6832 0x1110
+#define PCI_DEVICE_ID_CIRRUS_7543 0x1202
+#define PCI_DEVICE_ID_CIRRUS_4610 0x6001
+#define PCI_DEVICE_ID_CIRRUS_4612 0x6003
+#define PCI_DEVICE_ID_CIRRUS_4615 0x6004
+
+#define PCI_VENDOR_ID_IBM 0x1014
+#define PCI_DEVICE_ID_IBM_TR 0x0018
+#define PCI_DEVICE_ID_IBM_TR_WAKE 0x003e
+#define PCI_DEVICE_ID_IBM_CPC710_PCI64 0x00fc
+#define PCI_DEVICE_ID_IBM_SNIPE 0x0180
+#define PCI_DEVICE_ID_IBM_CITRINE 0x028C
+#define PCI_DEVICE_ID_IBM_GEMSTONE 0xB166
+#define PCI_DEVICE_ID_IBM_OBSIDIAN 0x02BD
+#define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1 0x0031
+#define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2 0x0219
+#define PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX 0x021A
+#define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM 0x0251
+#define PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL 0x252
+
+#define PCI_VENDOR_ID_COMPEX2 0x101a  
+#define PCI_DEVICE_ID_COMPEX2_100VG 0x0005
+
+#define PCI_VENDOR_ID_WD 0x101c
+#define PCI_DEVICE_ID_WD_90C 0xc24a
+
+#define PCI_VENDOR_ID_AMI 0x101e
+#define PCI_DEVICE_ID_AMI_MEGARAID3 0x1960
+#define PCI_DEVICE_ID_AMI_MEGARAID 0x9010
+#define PCI_DEVICE_ID_AMI_MEGARAID2 0x9060
+
+#define PCI_VENDOR_ID_AMD 0x1022
+#define PCI_DEVICE_ID_AMD_K8_NB 0x1100
+#define PCI_DEVICE_ID_AMD_LANCE 0x2000
+#define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001
+#define PCI_DEVICE_ID_AMD_SCSI 0x2020
+#define PCI_DEVICE_ID_AMD_SERENADE 0x36c0
+#define PCI_DEVICE_ID_AMD_FE_GATE_7006 0x7006
+#define PCI_DEVICE_ID_AMD_FE_GATE_7007 0x7007
+#define PCI_DEVICE_ID_AMD_FE_GATE_700C 0x700C
+#define PCI_DEVICE_ID_AMD_FE_GATE_700E 0x700E
+#define PCI_DEVICE_ID_AMD_COBRA_7401 0x7401
+#define PCI_DEVICE_ID_AMD_VIPER_7409 0x7409
+#define PCI_DEVICE_ID_AMD_VIPER_740B 0x740B
+#define PCI_DEVICE_ID_AMD_VIPER_7410 0x7410
+#define PCI_DEVICE_ID_AMD_VIPER_7411 0x7411
+#define PCI_DEVICE_ID_AMD_VIPER_7413 0x7413
+#define PCI_DEVICE_ID_AMD_VIPER_7440 0x7440
+#define PCI_DEVICE_ID_AMD_OPUS_7441 0x7441
+#define PCI_DEVICE_ID_AMD_OPUS_7443 0x7443
+#define PCI_DEVICE_ID_AMD_VIPER_7443 0x7443
+#define PCI_DEVICE_ID_AMD_OPUS_7445 0x7445
+#define PCI_DEVICE_ID_AMD_8111_LPC 0x7468
+#define PCI_DEVICE_ID_AMD_8111_IDE 0x7469
+#define PCI_DEVICE_ID_AMD_8111_SMBUS2 0x746a
+#define PCI_DEVICE_ID_AMD_8111_SMBUS 0x746b
+#define PCI_DEVICE_ID_AMD_8111_AUDIO 0x746d
+#define PCI_DEVICE_ID_AMD_8151_0 0x7454
+#define PCI_DEVICE_ID_AMD_8131_BRIDGE 0x7450
+#define PCI_DEVICE_ID_AMD_8131_APIC 0x7451
+#define PCI_DEVICE_ID_AMD_CS5536_ISA 0x2090
+#define PCI_DEVICE_ID_AMD_CS5536_FLASH 0x2091
+#define PCI_DEVICE_ID_AMD_CS5536_AUDIO 0x2093
+#define PCI_DEVICE_ID_AMD_CS5536_OHC 0x2094
+#define PCI_DEVICE_ID_AMD_CS5536_EHC 0x2095
+#define PCI_DEVICE_ID_AMD_CS5536_UDC 0x2096
+#define PCI_DEVICE_ID_AMD_CS5536_UOC 0x2097
+#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A
+
+#define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081
+#define PCI_DEVICE_ID_AMD_LX_AES 0x2082
+
+#define PCI_VENDOR_ID_TRIDENT 0x1023
+#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
+#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001
+#define PCI_DEVICE_ID_TRIDENT_9320 0x9320
+#define PCI_DEVICE_ID_TRIDENT_9388 0x9388
+#define PCI_DEVICE_ID_TRIDENT_9397 0x9397
+#define PCI_DEVICE_ID_TRIDENT_939A 0x939A
+#define PCI_DEVICE_ID_TRIDENT_9520 0x9520
+#define PCI_DEVICE_ID_TRIDENT_9525 0x9525
+#define PCI_DEVICE_ID_TRIDENT_9420 0x9420
+#define PCI_DEVICE_ID_TRIDENT_9440 0x9440
+#define PCI_DEVICE_ID_TRIDENT_9660 0x9660
+#define PCI_DEVICE_ID_TRIDENT_9750 0x9750
+#define PCI_DEVICE_ID_TRIDENT_9850 0x9850
+#define PCI_DEVICE_ID_TRIDENT_9880 0x9880
+#define PCI_DEVICE_ID_TRIDENT_8400 0x8400
+#define PCI_DEVICE_ID_TRIDENT_8420 0x8420
+#define PCI_DEVICE_ID_TRIDENT_8500 0x8500
+
+#define PCI_VENDOR_ID_AI 0x1025
+#define PCI_DEVICE_ID_AI_M1435 0x1435
+
+#define PCI_VENDOR_ID_DELL 0x1028
+#define PCI_DEVICE_ID_DELL_RACIII 0x0008
+#define PCI_DEVICE_ID_DELL_RAC4 0x0012
+#define PCI_DEVICE_ID_DELL_PERC5 0x0015
+
+#define PCI_VENDOR_ID_MATROX 0x102B
+#define PCI_DEVICE_ID_MATROX_MGA_2 0x0518
+#define PCI_DEVICE_ID_MATROX_MIL 0x0519
+#define PCI_DEVICE_ID_MATROX_MYS 0x051A
+#define PCI_DEVICE_ID_MATROX_MIL_2 0x051b
+#define PCI_DEVICE_ID_MATROX_MYS_AGP 0x051e
+#define PCI_DEVICE_ID_MATROX_MIL_2_AGP 0x051f
+#define PCI_DEVICE_ID_MATROX_MGA_IMP 0x0d10
+#define PCI_DEVICE_ID_MATROX_G100_MM 0x1000
+#define PCI_DEVICE_ID_MATROX_G100_AGP 0x1001
+#define PCI_DEVICE_ID_MATROX_G200_PCI 0x0520
+#define PCI_DEVICE_ID_MATROX_G200_AGP 0x0521
+#define PCI_DEVICE_ID_MATROX_G400 0x0525
+#define PCI_DEVICE_ID_MATROX_G550 0x2527
+#define PCI_DEVICE_ID_MATROX_VIA 0x4536
+
+#define PCI_VENDOR_ID_CT 0x102c
+#define PCI_DEVICE_ID_CT_69000 0x00c0
+#define PCI_DEVICE_ID_CT_65545 0x00d8
+#define PCI_DEVICE_ID_CT_65548 0x00dc
+#define PCI_DEVICE_ID_CT_65550 0x00e0
+#define PCI_DEVICE_ID_CT_65554 0x00e4
+#define PCI_DEVICE_ID_CT_65555 0x00e5
+
+#define PCI_VENDOR_ID_MIRO 0x1031
+#define PCI_DEVICE_ID_MIRO_36050 0x5601
+#define PCI_DEVICE_ID_MIRO_DC10PLUS 0x7efe
+#define PCI_DEVICE_ID_MIRO_DC30PLUS 0xd801
+
+#define PCI_VENDOR_ID_NEC 0x1033
+#define PCI_DEVICE_ID_NEC_CBUS_1 0x0001  
+#define PCI_DEVICE_ID_NEC_LOCAL 0x0002  
+#define PCI_DEVICE_ID_NEC_ATM 0x0003  
+#define PCI_DEVICE_ID_NEC_R4000 0x0004  
+#define PCI_DEVICE_ID_NEC_486 0x0005  
+#define PCI_DEVICE_ID_NEC_ACCEL_1 0x0006  
+#define PCI_DEVICE_ID_NEC_UXBUS 0x0007  
+#define PCI_DEVICE_ID_NEC_ACCEL_2 0x0008  
+#define PCI_DEVICE_ID_NEC_GRAPH 0x0009  
+#define PCI_DEVICE_ID_NEC_VL 0x0016  
+#define PCI_DEVICE_ID_NEC_STARALPHA2 0x002c  
+#define PCI_DEVICE_ID_NEC_CBUS_2 0x002d  
+#define PCI_DEVICE_ID_NEC_USB 0x0035  
+#define PCI_DEVICE_ID_NEC_CBUS_3 0x003b
+#define PCI_DEVICE_ID_NEC_NAPCCARD 0x003e
+#define PCI_DEVICE_ID_NEC_PCX2 0x0046  
+#define PCI_DEVICE_ID_NEC_NILE4 0x005a
+#define PCI_DEVICE_ID_NEC_VRC5476 0x009b
+#define PCI_DEVICE_ID_NEC_VRC4173 0x00a5
+#define PCI_DEVICE_ID_NEC_VRC5477_AC97 0x00a6
+#define PCI_DEVICE_ID_NEC_PC9821CS01 0x800c  
+#define PCI_DEVICE_ID_NEC_PC9821NRB06 0x800d  
+
+#define PCI_VENDOR_ID_FD 0x1036
+#define PCI_DEVICE_ID_FD_36C70 0x0000
+
+#define PCI_VENDOR_ID_SI 0x1039
+#define PCI_DEVICE_ID_SI_5591_AGP 0x0001
+#define PCI_DEVICE_ID_SI_6202 0x0002
+#define PCI_DEVICE_ID_SI_503 0x0008
+#define PCI_DEVICE_ID_SI_ACPI 0x0009
+#define PCI_DEVICE_ID_SI_SMBUS 0x0016
+#define PCI_DEVICE_ID_SI_LPC 0x0018
+#define PCI_DEVICE_ID_SI_5597_VGA 0x0200
+#define PCI_DEVICE_ID_SI_6205 0x0205
+#define PCI_DEVICE_ID_SI_501 0x0406
+#define PCI_DEVICE_ID_SI_496 0x0496
+#define PCI_DEVICE_ID_SI_300 0x0300
+#define PCI_DEVICE_ID_SI_315H 0x0310
+#define PCI_DEVICE_ID_SI_315 0x0315
+#define PCI_DEVICE_ID_SI_315PRO 0x0325
+#define PCI_DEVICE_ID_SI_530 0x0530
+#define PCI_DEVICE_ID_SI_540 0x0540
+#define PCI_DEVICE_ID_SI_550 0x0550
+#define PCI_DEVICE_ID_SI_540_VGA 0x5300
+#define PCI_DEVICE_ID_SI_550_VGA 0x5315
+#define PCI_DEVICE_ID_SI_620 0x0620
+#define PCI_DEVICE_ID_SI_630 0x0630
+#define PCI_DEVICE_ID_SI_633 0x0633
+#define PCI_DEVICE_ID_SI_635 0x0635
+#define PCI_DEVICE_ID_SI_640 0x0640
+#define PCI_DEVICE_ID_SI_645 0x0645
+#define PCI_DEVICE_ID_SI_646 0x0646
+#define PCI_DEVICE_ID_SI_648 0x0648
+#define PCI_DEVICE_ID_SI_650 0x0650
+#define PCI_DEVICE_ID_SI_651 0x0651
+#define PCI_DEVICE_ID_SI_655 0x0655
+#define PCI_DEVICE_ID_SI_661 0x0661
+#define PCI_DEVICE_ID_SI_730 0x0730
+#define PCI_DEVICE_ID_SI_733 0x0733
+#define PCI_DEVICE_ID_SI_630_VGA 0x6300
+#define PCI_DEVICE_ID_SI_735 0x0735
+#define PCI_DEVICE_ID_SI_740 0x0740
+#define PCI_DEVICE_ID_SI_741 0x0741
+#define PCI_DEVICE_ID_SI_745 0x0745
+#define PCI_DEVICE_ID_SI_746 0x0746
+#define PCI_DEVICE_ID_SI_755 0x0755
+#define PCI_DEVICE_ID_SI_760 0x0760
+#define PCI_DEVICE_ID_SI_900 0x0900
+#define PCI_DEVICE_ID_SI_961 0x0961
+#define PCI_DEVICE_ID_SI_962 0x0962
+#define PCI_DEVICE_ID_SI_963 0x0963
+#define PCI_DEVICE_ID_SI_965 0x0965
+#define PCI_DEVICE_ID_SI_966 0x0966
+#define PCI_DEVICE_ID_SI_968 0x0968
+#define PCI_DEVICE_ID_SI_5511 0x5511
+#define PCI_DEVICE_ID_SI_5513 0x5513
+#define PCI_DEVICE_ID_SI_5517 0x5517
+#define PCI_DEVICE_ID_SI_5518 0x5518
+#define PCI_DEVICE_ID_SI_5571 0x5571
+#define PCI_DEVICE_ID_SI_5581 0x5581
+#define PCI_DEVICE_ID_SI_5582 0x5582
+#define PCI_DEVICE_ID_SI_5591 0x5591
+#define PCI_DEVICE_ID_SI_5596 0x5596
+#define PCI_DEVICE_ID_SI_5597 0x5597
+#define PCI_DEVICE_ID_SI_5598 0x5598
+#define PCI_DEVICE_ID_SI_5600 0x5600
+#define PCI_DEVICE_ID_SI_7012 0x7012
+#define PCI_DEVICE_ID_SI_7013 0x7013
+#define PCI_DEVICE_ID_SI_7016 0x7016
+#define PCI_DEVICE_ID_SI_7018 0x7018
+
+#define PCI_VENDOR_ID_HP 0x103c
+#define PCI_DEVICE_ID_HP_VISUALIZE_EG 0x1005
+#define PCI_DEVICE_ID_HP_VISUALIZE_FX6 0x1006
+#define PCI_DEVICE_ID_HP_VISUALIZE_FX4 0x1008
+#define PCI_DEVICE_ID_HP_VISUALIZE_FX2 0x100a
+#define PCI_DEVICE_ID_HP_TACHYON 0x1028
+#define PCI_DEVICE_ID_HP_TACHLITE 0x1029
+#define PCI_DEVICE_ID_HP_J2585A 0x1030
+#define PCI_DEVICE_ID_HP_J2585B 0x1031
+#define PCI_DEVICE_ID_HP_J2973A 0x1040
+#define PCI_DEVICE_ID_HP_J2970A 0x1042
+#define PCI_DEVICE_ID_HP_DIVA 0x1048
+#define PCI_DEVICE_ID_HP_DIVA_TOSCA1 0x1049
+#define PCI_DEVICE_ID_HP_DIVA_TOSCA2 0x104A
+#define PCI_DEVICE_ID_HP_DIVA_MAESTRO 0x104B
+#define PCI_DEVICE_ID_HP_REO_IOC 0x10f1
+#define PCI_DEVICE_ID_HP_VISUALIZE_FXE 0x108b
+#define PCI_DEVICE_ID_HP_DIVA_HALFDOME 0x1223
+#define PCI_DEVICE_ID_HP_DIVA_KEYSTONE 0x1226
+#define PCI_DEVICE_ID_HP_DIVA_POWERBAR 0x1227
+#define PCI_DEVICE_ID_HP_ZX1_IOC 0x122a
+#define PCI_DEVICE_ID_HP_PCIX_LBA 0x122e
+#define PCI_DEVICE_ID_HP_SX1000_IOC 0x127c
+#define PCI_DEVICE_ID_HP_DIVA_EVEREST 0x1282
+#define PCI_DEVICE_ID_HP_DIVA_AUX 0x1290
+#define PCI_DEVICE_ID_HP_DIVA_RMP3 0x1301
+#define PCI_DEVICE_ID_HP_DIVA_HURRICANE 0x132a
+#define PCI_DEVICE_ID_HP_CISSA 0x3220
+#define PCI_DEVICE_ID_HP_CISSC 0x3230
+#define PCI_DEVICE_ID_HP_CISSD 0x3238
+#define PCI_DEVICE_ID_HP_ZX2_IOC 0x4031
+
+#define PCI_VENDOR_ID_PCTECH 0x1042
+#define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000
+#define PCI_DEVICE_ID_PCTECH_RZ1001 0x1001
+#define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020
+
+#define PCI_VENDOR_ID_ASUSTEK 0x1043
+#define PCI_DEVICE_ID_ASUSTEK_0675 0x0675
+
+#define PCI_VENDOR_ID_DPT 0x1044
+#define PCI_DEVICE_ID_DPT 0xa400
+
+#define PCI_VENDOR_ID_OPTI 0x1045
+#define PCI_DEVICE_ID_OPTI_82C558 0xc558
+#define PCI_DEVICE_ID_OPTI_82C621 0xc621
+#define PCI_DEVICE_ID_OPTI_82C700 0xc700
+#define PCI_DEVICE_ID_OPTI_82C825 0xd568
+
+#define PCI_VENDOR_ID_ELSA 0x1048
+#define PCI_DEVICE_ID_ELSA_MICROLINK 0x1000
+#define PCI_DEVICE_ID_ELSA_QS3000 0x3000
+
+#define PCI_VENDOR_ID_BUSLOGIC 0x104B
+#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140
+#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040
+#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130
+
+#define PCI_VENDOR_ID_TI 0x104c
+#define PCI_DEVICE_ID_TI_TVP4020 0x3d07
+#define PCI_DEVICE_ID_TI_4450 0x8011
+#define PCI_DEVICE_ID_TI_XX21_XX11 0x8031
+#define PCI_DEVICE_ID_TI_XX21_XX11_SD 0x8034
+#define PCI_DEVICE_ID_TI_X515 0x8036
+#define PCI_DEVICE_ID_TI_XX12 0x8039
+#define PCI_DEVICE_ID_TI_1130 0xac12
+#define PCI_DEVICE_ID_TI_1031 0xac13
+#define PCI_DEVICE_ID_TI_1131 0xac15
+#define PCI_DEVICE_ID_TI_1250 0xac16
+#define PCI_DEVICE_ID_TI_1220 0xac17
+#define PCI_DEVICE_ID_TI_1221 0xac19
+#define PCI_DEVICE_ID_TI_1210 0xac1a
+#define PCI_DEVICE_ID_TI_1450 0xac1b
+#define PCI_DEVICE_ID_TI_1225 0xac1c
+#define PCI_DEVICE_ID_TI_1251A 0xac1d
+#define PCI_DEVICE_ID_TI_1211 0xac1e
+#define PCI_DEVICE_ID_TI_1251B 0xac1f
+#define PCI_DEVICE_ID_TI_4410 0xac41
+#define PCI_DEVICE_ID_TI_4451 0xac42
+#define PCI_DEVICE_ID_TI_4510 0xac44
+#define PCI_DEVICE_ID_TI_4520 0xac46
+#define PCI_DEVICE_ID_TI_7510 0xac47
+#define PCI_DEVICE_ID_TI_7610 0xac48
+#define PCI_DEVICE_ID_TI_7410 0xac49
+#define PCI_DEVICE_ID_TI_1410 0xac50
+#define PCI_DEVICE_ID_TI_1420 0xac51
+#define PCI_DEVICE_ID_TI_1451A 0xac52
+#define PCI_DEVICE_ID_TI_1620 0xac54
+#define PCI_DEVICE_ID_TI_1520 0xac55
+#define PCI_DEVICE_ID_TI_1510 0xac56
+#define PCI_DEVICE_ID_TI_X620 0xac8d
+#define PCI_DEVICE_ID_TI_X420 0xac8e
+
+#define PCI_VENDOR_ID_SONY 0x104d
+
+#define PCI_VENDOR_ID_WINBOND2 0x1050
+#define PCI_DEVICE_ID_WINBOND2_89C940F 0x5a5a
+#define PCI_DEVICE_ID_WINBOND2_6692 0x6692
+
+#define PCI_VENDOR_ID_ANIGMA 0x1051
+#define PCI_DEVICE_ID_ANIGMA_MC145575 0x0100
+
+#define PCI_VENDOR_ID_EFAR 0x1055
+#define PCI_DEVICE_ID_EFAR_SLC90E66_1 0x9130
+#define PCI_DEVICE_ID_EFAR_SLC90E66_3 0x9463
+
+#define PCI_VENDOR_ID_MOTOROLA 0x1057
+#define PCI_DEVICE_ID_MOTOROLA_MPC105 0x0001
+#define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002
+#define PCI_DEVICE_ID_MOTOROLA_MPC107 0x0004
+#define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801
+#define PCI_DEVICE_ID_MOTOROLA_FALCON 0x4802
+#define PCI_DEVICE_ID_MOTOROLA_HAWK 0x4803
+#define PCI_DEVICE_ID_MOTOROLA_HARRIER 0x480b
+#define PCI_DEVICE_ID_MOTOROLA_MPC5200 0x5803
+#define PCI_DEVICE_ID_MOTOROLA_MPC5200B 0x5809
+
+#define PCI_VENDOR_ID_PROMISE 0x105a
+#define PCI_DEVICE_ID_PROMISE_20265 0x0d30
+#define PCI_DEVICE_ID_PROMISE_20267 0x4d30
+#define PCI_DEVICE_ID_PROMISE_20246 0x4d33
+#define PCI_DEVICE_ID_PROMISE_20262 0x4d38
+#define PCI_DEVICE_ID_PROMISE_20263 0x0D38
+#define PCI_DEVICE_ID_PROMISE_20268 0x4d68
+#define PCI_DEVICE_ID_PROMISE_20269 0x4d69
+#define PCI_DEVICE_ID_PROMISE_20270 0x6268
+#define PCI_DEVICE_ID_PROMISE_20271 0x6269
+#define PCI_DEVICE_ID_PROMISE_20275 0x1275
+#define PCI_DEVICE_ID_PROMISE_20276 0x5275
+#define PCI_DEVICE_ID_PROMISE_20277 0x7275
+
+#define PCI_VENDOR_ID_UMC 0x1060
+#define PCI_DEVICE_ID_UMC_UM8673F 0x0101
+#define PCI_DEVICE_ID_UMC_UM8886BF 0x673a
+#define PCI_DEVICE_ID_UMC_UM8886A 0x886a
+
+#define PCI_VENDOR_ID_MYLEX 0x1069
+#define PCI_DEVICE_ID_MYLEX_DAC960_P 0x0001
+#define PCI_DEVICE_ID_MYLEX_DAC960_PD 0x0002
+#define PCI_DEVICE_ID_MYLEX_DAC960_PG 0x0010
+#define PCI_DEVICE_ID_MYLEX_DAC960_LA 0x0020
+#define PCI_DEVICE_ID_MYLEX_DAC960_LP 0x0050
+#define PCI_DEVICE_ID_MYLEX_DAC960_BA 0xBA56
+#define PCI_DEVICE_ID_MYLEX_DAC960_GEM 0xB166
+
+#define PCI_VENDOR_ID_APPLE 0x106b
+#define PCI_DEVICE_ID_APPLE_BANDIT 0x0001
+#define PCI_DEVICE_ID_APPLE_HYDRA 0x000e
+#define PCI_DEVICE_ID_APPLE_UNI_N_FW 0x0018
+#define PCI_DEVICE_ID_APPLE_UNI_N_AGP 0x0020
+#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC 0x0021
+#define PCI_DEVICE_ID_APPLE_UNI_N_GMACP 0x0024
+#define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P 0x0027
+#define PCI_DEVICE_ID_APPLE_UNI_N_AGP15 0x002d
+#define PCI_DEVICE_ID_APPLE_UNI_N_PCI15 0x002e
+#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032
+#define PCI_DEVICE_ID_APPLE_UNI_N_ATA 0x0033
+#define PCI_DEVICE_ID_APPLE_UNI_N_AGP2 0x0034
+#define PCI_DEVICE_ID_APPLE_IPID_ATA100 0x003b
+#define PCI_DEVICE_ID_APPLE_K2_ATA100 0x0043
+#define PCI_DEVICE_ID_APPLE_U3_AGP 0x004b
+#define PCI_DEVICE_ID_APPLE_K2_GMAC 0x004c
+#define PCI_DEVICE_ID_APPLE_SH_ATA 0x0050
+#define PCI_DEVICE_ID_APPLE_SH_SUNGEM 0x0051
+#define PCI_DEVICE_ID_APPLE_U3L_AGP 0x0058
+#define PCI_DEVICE_ID_APPLE_U3H_AGP 0x0059
+#define PCI_DEVICE_ID_APPLE_IPID2_AGP 0x0066
+#define PCI_DEVICE_ID_APPLE_IPID2_ATA 0x0069
+#define PCI_DEVICE_ID_APPLE_IPID2_FW 0x006a
+#define PCI_DEVICE_ID_APPLE_IPID2_GMAC 0x006b
+#define PCI_DEVICE_ID_APPLE_TIGON3 0x1645
+
+#define PCI_VENDOR_ID_YAMAHA 0x1073
+#define PCI_DEVICE_ID_YAMAHA_724 0x0004
+#define PCI_DEVICE_ID_YAMAHA_724F 0x000d
+#define PCI_DEVICE_ID_YAMAHA_740 0x000a
+#define PCI_DEVICE_ID_YAMAHA_740C 0x000c
+#define PCI_DEVICE_ID_YAMAHA_744 0x0010
+#define PCI_DEVICE_ID_YAMAHA_754 0x0012
+
+#define PCI_VENDOR_ID_QLOGIC 0x1077
+#define PCI_DEVICE_ID_QLOGIC_ISP10160 0x1016
+#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020
+#define PCI_DEVICE_ID_QLOGIC_ISP1080 0x1080
+#define PCI_DEVICE_ID_QLOGIC_ISP12160 0x1216
+#define PCI_DEVICE_ID_QLOGIC_ISP1240 0x1240
+#define PCI_DEVICE_ID_QLOGIC_ISP1280 0x1280
+#define PCI_DEVICE_ID_QLOGIC_ISP2100 0x2100
+#define PCI_DEVICE_ID_QLOGIC_ISP2200 0x2200
+#define PCI_DEVICE_ID_QLOGIC_ISP2300 0x2300
+#define PCI_DEVICE_ID_QLOGIC_ISP2312 0x2312
+#define PCI_DEVICE_ID_QLOGIC_ISP2322 0x2322
+#define PCI_DEVICE_ID_QLOGIC_ISP6312 0x6312
+#define PCI_DEVICE_ID_QLOGIC_ISP6322 0x6322
+#define PCI_DEVICE_ID_QLOGIC_ISP2422 0x2422
+#define PCI_DEVICE_ID_QLOGIC_ISP2432 0x2432
+#define PCI_DEVICE_ID_QLOGIC_ISP2512 0x2512
+#define PCI_DEVICE_ID_QLOGIC_ISP2522 0x2522
+#define PCI_DEVICE_ID_QLOGIC_ISP5422 0x5422
+#define PCI_DEVICE_ID_QLOGIC_ISP5432 0x5432
+
+#define PCI_VENDOR_ID_CYRIX 0x1078
+#define PCI_DEVICE_ID_CYRIX_5510 0x0000
+#define PCI_DEVICE_ID_CYRIX_PCI_MASTER 0x0001
+#define PCI_DEVICE_ID_CYRIX_5520 0x0002
+#define PCI_DEVICE_ID_CYRIX_5530_LEGACY 0x0100
+#define PCI_DEVICE_ID_CYRIX_5530_IDE 0x0102
+#define PCI_DEVICE_ID_CYRIX_5530_AUDIO 0x0103
+#define PCI_DEVICE_ID_CYRIX_5530_VIDEO 0x0104
+
+#define PCI_VENDOR_ID_CONTAQ 0x1080
+#define PCI_DEVICE_ID_CONTAQ_82C693 0xc693
+
+#define PCI_VENDOR_ID_OLICOM 0x108d
+#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012
+#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013
+#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014
+
+#define PCI_VENDOR_ID_SUN 0x108e
+#define PCI_DEVICE_ID_SUN_EBUS 0x1000
+#define PCI_DEVICE_ID_SUN_HAPPYMEAL 0x1001
+#define PCI_DEVICE_ID_SUN_RIO_EBUS 0x1100
+#define PCI_DEVICE_ID_SUN_RIO_GEM 0x1101
+#define PCI_DEVICE_ID_SUN_RIO_1394 0x1102
+#define PCI_DEVICE_ID_SUN_RIO_USB 0x1103
+#define PCI_DEVICE_ID_SUN_GEM 0x2bad
+#define PCI_DEVICE_ID_SUN_SIMBA 0x5000
+#define PCI_DEVICE_ID_SUN_PBM 0x8000
+#define PCI_DEVICE_ID_SUN_SCHIZO 0x8001
+#define PCI_DEVICE_ID_SUN_SABRE 0xa000
+#define PCI_DEVICE_ID_SUN_HUMMINGBIRD 0xa001
+#define PCI_DEVICE_ID_SUN_TOMATILLO 0xa801
+#define PCI_DEVICE_ID_SUN_CASSINI 0xabba
+
+#define PCI_VENDOR_ID_CMD 0x1095
+#define PCI_DEVICE_ID_CMD_643 0x0643
+#define PCI_DEVICE_ID_CMD_646 0x0646
+#define PCI_DEVICE_ID_CMD_648 0x0648
+#define PCI_DEVICE_ID_CMD_649 0x0649
+
+#define PCI_DEVICE_ID_SII_680 0x0680
+#define PCI_DEVICE_ID_SII_3112 0x3112
+#define PCI_DEVICE_ID_SII_1210SA 0x0240
+
+#define PCI_VENDOR_ID_BROOKTREE 0x109e
+#define PCI_DEVICE_ID_BROOKTREE_878 0x0878
+#define PCI_DEVICE_ID_BROOKTREE_879 0x0879
+
+#define PCI_VENDOR_ID_SGI 0x10a9
+#define PCI_DEVICE_ID_SGI_IOC3 0x0003
+#define PCI_DEVICE_ID_SGI_IOC4 0x100a
+#define PCI_VENDOR_ID_SGI_LITHIUM 0x1002
+
+#define PCI_VENDOR_ID_WINBOND 0x10ad
+#define PCI_DEVICE_ID_WINBOND_82C105 0x0105
+#define PCI_DEVICE_ID_WINBOND_83C553 0x0565
+
+#define PCI_VENDOR_ID_PLX 0x10b5
+#define PCI_DEVICE_ID_PLX_R685 0x1030
+#define PCI_DEVICE_ID_PLX_ROMULUS 0x106a
+#define PCI_DEVICE_ID_PLX_SPCOM800 0x1076
+#define PCI_DEVICE_ID_PLX_1077 0x1077
+#define PCI_DEVICE_ID_PLX_SPCOM200 0x1103
+#define PCI_DEVICE_ID_PLX_DJINN_ITOO 0x1151
+#define PCI_DEVICE_ID_PLX_R753 0x1152
+#define PCI_DEVICE_ID_PLX_OLITEC 0x1187
+#define PCI_DEVICE_ID_PLX_PCI200SYN 0x3196
+#define PCI_DEVICE_ID_PLX_9050 0x9050
+#define PCI_DEVICE_ID_PLX_9080 0x9080
+#define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001
+
+#define PCI_VENDOR_ID_MADGE 0x10b6
+#define PCI_DEVICE_ID_MADGE_MK2 0x0002
+
+#define PCI_VENDOR_ID_3COM 0x10b7
+#define PCI_DEVICE_ID_3COM_3C985 0x0001
+#define PCI_DEVICE_ID_3COM_3C940 0x1700
+#define PCI_DEVICE_ID_3COM_3C339 0x3390
+#define PCI_DEVICE_ID_3COM_3C359 0x3590
+#define PCI_DEVICE_ID_3COM_3C940B 0x80eb
+#define PCI_DEVICE_ID_3COM_3CR990 0x9900
+#define PCI_DEVICE_ID_3COM_3CR990_TX_95 0x9902
+#define PCI_DEVICE_ID_3COM_3CR990_TX_97 0x9903
+#define PCI_DEVICE_ID_3COM_3CR990B 0x9904
+#define PCI_DEVICE_ID_3COM_3CR990_FX 0x9905
+#define PCI_DEVICE_ID_3COM_3CR990SVR95 0x9908
+#define PCI_DEVICE_ID_3COM_3CR990SVR97 0x9909
+#define PCI_DEVICE_ID_3COM_3CR990SVR 0x990a
+
+#define PCI_VENDOR_ID_AL 0x10b9
+#define PCI_DEVICE_ID_AL_M1533 0x1533
+#define PCI_DEVICE_ID_AL_M1535 0x1535
+#define PCI_DEVICE_ID_AL_M1541 0x1541
+#define PCI_DEVICE_ID_AL_M1563 0x1563
+#define PCI_DEVICE_ID_AL_M1621 0x1621
+#define PCI_DEVICE_ID_AL_M1631 0x1631
+#define PCI_DEVICE_ID_AL_M1632 0x1632
+#define PCI_DEVICE_ID_AL_M1641 0x1641
+#define PCI_DEVICE_ID_AL_M1644 0x1644
+#define PCI_DEVICE_ID_AL_M1647 0x1647
+#define PCI_DEVICE_ID_AL_M1651 0x1651
+#define PCI_DEVICE_ID_AL_M1671 0x1671
+#define PCI_DEVICE_ID_AL_M1681 0x1681
+#define PCI_DEVICE_ID_AL_M1683 0x1683
+#define PCI_DEVICE_ID_AL_M1689 0x1689
+#define PCI_DEVICE_ID_AL_M5219 0x5219
+#define PCI_DEVICE_ID_AL_M5228 0x5228
+#define PCI_DEVICE_ID_AL_M5229 0x5229
+#define PCI_DEVICE_ID_AL_M5451 0x5451
+#define PCI_DEVICE_ID_AL_M7101 0x7101
+
+#define PCI_VENDOR_ID_NEOMAGIC 0x10c8
+#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005
+#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006
+#define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016
+
+#define PCI_VENDOR_ID_TCONRAD 0x10da
+#define PCI_DEVICE_ID_TCONRAD_TOKENRING 0x0508
+
+#define PCI_VENDOR_ID_NVIDIA 0x10de
+#define PCI_DEVICE_ID_NVIDIA_TNT 0x0020
+#define PCI_DEVICE_ID_NVIDIA_TNT2 0x0028
+#define PCI_DEVICE_ID_NVIDIA_UTNT2 0x0029
+#define PCI_DEVICE_ID_NVIDIA_TNT_UNKNOWN 0x002a
+#define PCI_DEVICE_ID_NVIDIA_VTNT2 0x002C
+#define PCI_DEVICE_ID_NVIDIA_UVTNT2 0x002D
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS 0x0034
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE 0x0035
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA 0x0036
+#define PCI_DEVICE_ID_NVIDIA_NVENET_10 0x0037
+#define PCI_DEVICE_ID_NVIDIA_NVENET_11 0x0038
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2 0x003e
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_ULTRA 0x0040
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800 0x0041
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_LE 0x0042
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_GT 0x0045
+#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_4000 0x004E
+#define PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS 0x0052
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE 0x0053
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA 0x0054
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2 0x0055
+#define PCI_DEVICE_ID_NVIDIA_NVENET_8 0x0056
+#define PCI_DEVICE_ID_NVIDIA_NVENET_9 0x0057
+#define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059
+#define PCI_DEVICE_ID_NVIDIA_CK804_PCIE 0x005d
+#define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS 0x0064
+#define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE 0x0065
+#define PCI_DEVICE_ID_NVIDIA_NVENET_2 0x0066
+#define PCI_DEVICE_ID_NVIDIA_MCP2_MODEM 0x0069
+#define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a
+#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS 0x0084
+#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE 0x0085
+#define PCI_DEVICE_ID_NVIDIA_NVENET_4 0x0086
+#define PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM 0x0089
+#define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO 0x008a
+#define PCI_DEVICE_ID_NVIDIA_NVENET_5 0x008c
+#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA 0x008e
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT 0x0090
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX 0x0091
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800 0x0098
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800_GTX 0x0099
+#define PCI_DEVICE_ID_NVIDIA_ITNT2 0x00A0
+#define PCI_DEVICE_ID_GEFORCE_6800A 0x00c1
+#define PCI_DEVICE_ID_GEFORCE_6800A_LE 0x00c2
+#define PCI_DEVICE_ID_GEFORCE_GO_6800 0x00c8
+#define PCI_DEVICE_ID_GEFORCE_GO_6800_ULTRA 0x00c9
+#define PCI_DEVICE_ID_QUADRO_FX_GO1400 0x00cc
+#define PCI_DEVICE_ID_QUADRO_FX_1400 0x00ce
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3 0x00d1
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS 0x00d4
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE 0x00d5
+#define PCI_DEVICE_ID_NVIDIA_NVENET_3 0x00d6
+#define PCI_DEVICE_ID_NVIDIA_MCP3_MODEM 0x00d9
+#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da
+#define PCI_DEVICE_ID_NVIDIA_NVENET_7 0x00df
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3S 0x00e1
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA 0x00e3
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS 0x00e4
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE 0x00e5
+#define PCI_DEVICE_ID_NVIDIA_NVENET_6 0x00e6
+#define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO 0x00ea
+#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2 0x00ee
+#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1 0x00f0
+#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT1 0x00f1
+#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT2 0x00f2
+#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6200_ALT1 0x00f3
+#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT 0x00f9
+#define PCIE_DEVICE_ID_NVIDIA_QUADRO_NVS280 0x00fd
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR 0x0100
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR 0x0101
+#define PCI_DEVICE_ID_NVIDIA_QUADRO 0x0103
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX 0x0110
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2 0x0111
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO 0x0112
+#define PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR 0x0113
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6600_GT 0x0140
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6600 0x0141
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6610_XL 0x0145
+#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_540 0x014E
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6200 0x014F
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS 0x0150
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2 0x0151
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA 0x0152
+#define PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO 0x0153
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6200_TURBOCACHE 0x0161
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200 0x0164
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250 0x0166
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200_1 0x0167
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250_1 0x0168
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460 0x0170
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440 0x0171
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420 0x0172
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_SE 0x0173
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO 0x0174
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO 0x0175
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32 0x0176
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_460_GO 0x0177
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL 0x0178
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64 0x0179
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_200 0x017A
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL 0x017B
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL 0x017C
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_410_GO_M16 0x017D
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_8X 0x0181
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440SE_8X 0x0182
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420_8X 0x0183
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_4000 0x0185
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_448_GO 0x0186
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_488_GO 0x0187
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_580_XGL 0x0188
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_MAC 0x0189
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_280_NVS 0x018A
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_380_XGL 0x018B
+#define PCI_DEVICE_ID_NVIDIA_IGEFORCE2 0x01a0
+#define PCI_DEVICE_ID_NVIDIA_NFORCE 0x01a4
+#define PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO 0x01b1
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS 0x01b4
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE 0x01bc
+#define PCI_DEVICE_ID_NVIDIA_MCP1_MODEM 0x01c1
+#define PCI_DEVICE_ID_NVIDIA_NVENET_1 0x01c3
+#define PCI_DEVICE_ID_NVIDIA_NFORCE2 0x01e0
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE3 0x0200
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1 0x0201
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_2 0x0202
+#define PCI_DEVICE_ID_NVIDIA_QUADRO_DDC 0x0203
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B 0x0211
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_LE 0x0212
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_GT 0x0215
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600 0x0250
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400 0x0251
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200 0x0253
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL 0x0258
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL 0x0259
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL 0x025B
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS 0x0264
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE 0x0265
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA 0x0266
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2 0x0267
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS 0x0368
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE 0x036E
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA 0x037E
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2 0x037F
+#define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268
+#define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X 0x0281
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE 0x0282
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO 0x0286
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_980_XGL 0x0288
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_780_XGL 0x0289
+#define PCI_DEVICE_ID_NVIDIA_QUADRO4_700_GOGL 0x028C
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_ULTRA 0x0301
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800 0x0302
+#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_2000 0x0308
+#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1000 0x0309
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_ULTRA 0x0311
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600 0x0312
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600SE 0x0314
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5600 0x031A
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5650 0x031B
+#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO700 0x031C
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200 0x0320
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_ULTRA 0x0321
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_1 0x0322
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200SE 0x0323
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5200 0x0324
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5250 0x0325
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5500 0x0326
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5100 0x0327
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5250_32 0x0328
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200 0x0329
+#define PCI_DEVICE_ID_NVIDIA_QUADRO_NVS_280_PCI 0x032A
+#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_500 0x032B
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5300 0x032C
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5100 0x032D
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900_ULTRA 0x0330
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900 0x0331
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900XT 0x0332
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5950_ULTRA 0x0333
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900ZT 0x0334
+#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_3000 0x0338
+#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_700 0x033F
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700_ULTRA 0x0341
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700 0x0342
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700LE 0x0343
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700VE 0x0344
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_1 0x0347
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_2 0x0348
+#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO1000 0x034C
+#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100 0x034E
+#define PCI_DEVICE_ID_NVIDIA_NVENET_14 0x0372
+#define PCI_DEVICE_ID_NVIDIA_NVENET_15 0x0373
+#define PCI_DEVICE_ID_NVIDIA_NVENET_16 0x03E5
+#define PCI_DEVICE_ID_NVIDIA_NVENET_17 0x03E6
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA 0x03E7
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE 0x03EC
+#define PCI_DEVICE_ID_NVIDIA_NVENET_18 0x03EE
+#define PCI_DEVICE_ID_NVIDIA_NVENET_19 0x03EF
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2 0x03F6
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3 0x03F7
+#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE 0x0448
+#define PCI_DEVICE_ID_NVIDIA_NVENET_20 0x0450
+#define PCI_DEVICE_ID_NVIDIA_NVENET_21 0x0451
+#define PCI_DEVICE_ID_NVIDIA_NVENET_22 0x0452
+#define PCI_DEVICE_ID_NVIDIA_NVENET_23 0x0453
+
+#define PCI_VENDOR_ID_IMS 0x10e0
+#define PCI_DEVICE_ID_IMS_TT128 0x9128
+#define PCI_DEVICE_ID_IMS_TT3D 0x9135
+
+#define PCI_VENDOR_ID_INTERG 0x10ea
+#define PCI_DEVICE_ID_INTERG_1682 0x1682
+#define PCI_DEVICE_ID_INTERG_2000 0x2000
+#define PCI_DEVICE_ID_INTERG_2010 0x2010
+#define PCI_DEVICE_ID_INTERG_5000 0x5000
+#define PCI_DEVICE_ID_INTERG_5050 0x5050
+
+#define PCI_VENDOR_ID_REALTEK 0x10ec
+#define PCI_DEVICE_ID_REALTEK_8139 0x8139
+
+#define PCI_VENDOR_ID_XILINX 0x10ee
+#define PCI_DEVICE_ID_RME_DIGI96 0x3fc0
+#define PCI_DEVICE_ID_RME_DIGI96_8 0x3fc1
+#define PCI_DEVICE_ID_RME_DIGI96_8_PRO 0x3fc2
+#define PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST 0x3fc3
+#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5
+#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6
+
+#define PCI_VENDOR_ID_INIT 0x1101
+
+#define PCI_VENDOR_ID_CREATIVE 0x1102  
+#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002
+
+#define PCI_VENDOR_ID_ECTIVA 0x1102  
+#define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938
+
+#define PCI_VENDOR_ID_TTI 0x1103
+#define PCI_DEVICE_ID_TTI_HPT343 0x0003
+#define PCI_DEVICE_ID_TTI_HPT366 0x0004
+#define PCI_DEVICE_ID_TTI_HPT372 0x0005
+#define PCI_DEVICE_ID_TTI_HPT302 0x0006
+#define PCI_DEVICE_ID_TTI_HPT371 0x0007
+#define PCI_DEVICE_ID_TTI_HPT374 0x0008
+#define PCI_DEVICE_ID_TTI_HPT372N 0x0009  
+
+#define PCI_VENDOR_ID_VIA 0x1106
+#define PCI_DEVICE_ID_VIA_8763_0 0x0198
+#define PCI_DEVICE_ID_VIA_8380_0 0x0204
+#define PCI_DEVICE_ID_VIA_3238_0 0x0238
+#define PCI_DEVICE_ID_VIA_PT880 0x0258
+#define PCI_DEVICE_ID_VIA_PT880ULTRA 0x0308
+#define PCI_DEVICE_ID_VIA_PX8X0_0 0x0259
+#define PCI_DEVICE_ID_VIA_3269_0 0x0269
+#define PCI_DEVICE_ID_VIA_K8T800PRO_0 0x0282
+#define PCI_DEVICE_ID_VIA_3296_0 0x0296
+#define PCI_DEVICE_ID_VIA_8363_0 0x0305
+#define PCI_DEVICE_ID_VIA_P4M800CE 0x0314
+#define PCI_DEVICE_ID_VIA_8371_0 0x0391
+#define PCI_DEVICE_ID_VIA_8501_0 0x0501
+#define PCI_DEVICE_ID_VIA_82C561 0x0561
+#define PCI_DEVICE_ID_VIA_82C586_1 0x0571
+#define PCI_DEVICE_ID_VIA_82C576 0x0576
+#define PCI_DEVICE_ID_VIA_SATA_EIDE 0x0581
+#define PCI_DEVICE_ID_VIA_82C586_0 0x0586
+#define PCI_DEVICE_ID_VIA_82C596 0x0596
+#define PCI_DEVICE_ID_VIA_82C597_0 0x0597
+#define PCI_DEVICE_ID_VIA_82C598_0 0x0598
+#define PCI_DEVICE_ID_VIA_8601_0 0x0601
+#define PCI_DEVICE_ID_VIA_8605_0 0x0605
+#define PCI_DEVICE_ID_VIA_82C686 0x0686
+#define PCI_DEVICE_ID_VIA_82C691_0 0x0691
+#define PCI_DEVICE_ID_VIA_82C576_1 0x1571
+#define PCI_DEVICE_ID_VIA_82C586_2 0x3038
+#define PCI_DEVICE_ID_VIA_82C586_3 0x3040
+#define PCI_DEVICE_ID_VIA_82C596_3 0x3050
+#define PCI_DEVICE_ID_VIA_82C596B_3 0x3051
+#define PCI_DEVICE_ID_VIA_82C686_4 0x3057
+#define PCI_DEVICE_ID_VIA_82C686_5 0x3058
+#define PCI_DEVICE_ID_VIA_8233_5 0x3059
+#define PCI_DEVICE_ID_VIA_8233_0 0x3074
+#define PCI_DEVICE_ID_VIA_8633_0 0x3091
+#define PCI_DEVICE_ID_VIA_8367_0 0x3099
+#define PCI_DEVICE_ID_VIA_8653_0 0x3101
+#define PCI_DEVICE_ID_VIA_8622 0x3102
+#define PCI_DEVICE_ID_VIA_8235_USB_2 0x3104
+#define PCI_DEVICE_ID_VIA_8233C_0 0x3109
+#define PCI_DEVICE_ID_VIA_8361 0x3112
+#define PCI_DEVICE_ID_VIA_XM266 0x3116
+#define PCI_DEVICE_ID_VIA_612X 0x3119
+#define PCI_DEVICE_ID_VIA_862X_0 0x3123
+#define PCI_DEVICE_ID_VIA_8753_0 0x3128
+#define PCI_DEVICE_ID_VIA_8233A 0x3147
+#define PCI_DEVICE_ID_VIA_8703_51_0 0x3148
+#define PCI_DEVICE_ID_VIA_8237_SATA 0x3149
+#define PCI_DEVICE_ID_VIA_XN266 0x3156
+#define PCI_DEVICE_ID_VIA_6410 0x3164
+#define PCI_DEVICE_ID_VIA_8754C_0 0x3168
+#define PCI_DEVICE_ID_VIA_8235 0x3177
+#define PCI_DEVICE_ID_VIA_8385_0 0x3188
+#define PCI_DEVICE_ID_VIA_8377_0 0x3189
+#define PCI_DEVICE_ID_VIA_8378_0 0x3205
+#define PCI_DEVICE_ID_VIA_8783_0 0x3208
+#define PCI_DEVICE_ID_VIA_8237 0x3227
+#define PCI_DEVICE_ID_VIA_8251 0x3287
+#define PCI_DEVICE_ID_VIA_8237A 0x3337
+#define PCI_DEVICE_ID_VIA_8231 0x8231
+#define PCI_DEVICE_ID_VIA_8231_4 0x8235
+#define PCI_DEVICE_ID_VIA_8365_1 0x8305
+#define PCI_DEVICE_ID_VIA_CX700 0x8324
+#define PCI_DEVICE_ID_VIA_8371_1 0x8391
+#define PCI_DEVICE_ID_VIA_82C598_1 0x8598
+#define PCI_DEVICE_ID_VIA_838X_1 0xB188
+#define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198
+
+#define PCI_VENDOR_ID_SIEMENS 0x110A
+#define PCI_DEVICE_ID_SIEMENS_DSCC4 0x2102
+
+#define PCI_VENDOR_ID_VORTEX 0x1119
+#define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000
+#define PCI_DEVICE_ID_VORTEX_GDT6000B 0x0001
+#define PCI_DEVICE_ID_VORTEX_GDT6x10 0x0002
+#define PCI_DEVICE_ID_VORTEX_GDT6x20 0x0003
+#define PCI_DEVICE_ID_VORTEX_GDT6530 0x0004
+#define PCI_DEVICE_ID_VORTEX_GDT6550 0x0005
+#define PCI_DEVICE_ID_VORTEX_GDT6x17 0x0006
+#define PCI_DEVICE_ID_VORTEX_GDT6x27 0x0007
+#define PCI_DEVICE_ID_VORTEX_GDT6537 0x0008
+#define PCI_DEVICE_ID_VORTEX_GDT6557 0x0009
+#define PCI_DEVICE_ID_VORTEX_GDT6x15 0x000a
+#define PCI_DEVICE_ID_VORTEX_GDT6x25 0x000b
+#define PCI_DEVICE_ID_VORTEX_GDT6535 0x000c
+#define PCI_DEVICE_ID_VORTEX_GDT6555 0x000d
+#define PCI_DEVICE_ID_VORTEX_GDT6x17RP 0x0100
+#define PCI_DEVICE_ID_VORTEX_GDT6x27RP 0x0101
+#define PCI_DEVICE_ID_VORTEX_GDT6537RP 0x0102
+#define PCI_DEVICE_ID_VORTEX_GDT6557RP 0x0103
+#define PCI_DEVICE_ID_VORTEX_GDT6x11RP 0x0104
+#define PCI_DEVICE_ID_VORTEX_GDT6x21RP 0x0105
+
+#define PCI_VENDOR_ID_EF 0x111a
+#define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000
+#define PCI_DEVICE_ID_EF_ATM_ASIC 0x0002
+#define PCI_VENDOR_ID_EF_ATM_LANAI2 0x0003
+#define PCI_VENDOR_ID_EF_ATM_LANAIHB 0x0005
+
+#define PCI_VENDOR_ID_IDT 0x111d
+#define PCI_DEVICE_ID_IDT_IDT77201 0x0001
+
+#define PCI_VENDOR_ID_FORE 0x1127
+#define PCI_DEVICE_ID_FORE_PCA200E 0x0300
+
+#define PCI_VENDOR_ID_PHILIPS 0x1131
+#define PCI_DEVICE_ID_PHILIPS_SAA7146 0x7146
+#define PCI_DEVICE_ID_PHILIPS_SAA9730 0x9730
+
+#define PCI_VENDOR_ID_EICON 0x1133
+#define PCI_DEVICE_ID_EICON_DIVA20 0xe002
+#define PCI_DEVICE_ID_EICON_DIVA20_U 0xe004
+#define PCI_DEVICE_ID_EICON_DIVA201 0xe005
+#define PCI_DEVICE_ID_EICON_DIVA202 0xe00b
+#define PCI_DEVICE_ID_EICON_MAESTRA 0xe010
+#define PCI_DEVICE_ID_EICON_MAESTRAQ 0xe012
+#define PCI_DEVICE_ID_EICON_MAESTRAQ_U 0xe013
+#define PCI_DEVICE_ID_EICON_MAESTRAP 0xe014
+
+#define PCI_VENDOR_ID_ZIATECH 0x1138
+#define PCI_DEVICE_ID_ZIATECH_5550_HC 0x5550
+
+#define PCI_VENDOR_ID_SYSKONNECT 0x1148
+#define PCI_DEVICE_ID_SYSKONNECT_TR 0x4200
+#define PCI_DEVICE_ID_SYSKONNECT_GE 0x4300
+#define PCI_DEVICE_ID_SYSKONNECT_YU 0x4320
+#define PCI_DEVICE_ID_SYSKONNECT_9DXX 0x4400
+#define PCI_DEVICE_ID_SYSKONNECT_9MXX 0x4500
+
+#define PCI_VENDOR_ID_DIGI 0x114f
+#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_E 0x0070
+#define PCI_DEVICE_ID_DIGI_DF_M_E 0x0071
+#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A 0x0072
+#define PCI_DEVICE_ID_DIGI_DF_M_A 0x0073
+#define PCI_DEVICE_ID_NEO_2DB9 0x00C8
+#define PCI_DEVICE_ID_NEO_2DB9PRI 0x00C9
+#define PCI_DEVICE_ID_NEO_2RJ45 0x00CA
+#define PCI_DEVICE_ID_NEO_2RJ45PRI 0x00CB
+
+#define PCI_VENDOR_ID_XIRCOM 0x115d
+#define PCI_DEVICE_ID_XIRCOM_RBM56G 0x0101
+#define PCI_DEVICE_ID_XIRCOM_X3201_MDM 0x0103
+
+#define PCI_VENDOR_ID_SERVERWORKS 0x1166
+#define PCI_DEVICE_ID_SERVERWORKS_HE 0x0008
+#define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009
+#define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017
+#define PCI_DEVICE_ID_SERVERWORKS_EPB 0x0103
+#define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200
+#define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201
+#define PCI_DEVICE_ID_SERVERWORKS_CSB6 0x0203
+#define PCI_DEVICE_ID_SERVERWORKS_HT1000SB 0x0205
+#define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211
+#define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212
+#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213
+#define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214
+#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217
+#define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227
+
+#define PCI_VENDOR_ID_SBE 0x1176
+#define PCI_DEVICE_ID_SBE_WANXL100 0x0301
+#define PCI_DEVICE_ID_SBE_WANXL200 0x0302
+#define PCI_DEVICE_ID_SBE_WANXL400 0x0104
+
+#define PCI_VENDOR_ID_TOSHIBA 0x1179
+#define PCI_DEVICE_ID_TOSHIBA_PICCOLO 0x0102
+#define PCI_DEVICE_ID_TOSHIBA_PICCOLO_1 0x0103
+#define PCI_DEVICE_ID_TOSHIBA_PICCOLO_2 0x0105
+#define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a
+#define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f
+#define PCI_DEVICE_ID_TOSHIBA_TOPIC100 0x0617
+
+#define PCI_VENDOR_ID_TOSHIBA_2 0x102f
+#define PCI_DEVICE_ID_TOSHIBA_TC35815CF 0x0030
+#define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108
+#define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3
+
+#define PCI_VENDOR_ID_RICOH 0x1180
+#define PCI_DEVICE_ID_RICOH_RL5C465 0x0465
+#define PCI_DEVICE_ID_RICOH_RL5C466 0x0466
+#define PCI_DEVICE_ID_RICOH_RL5C475 0x0475
+#define PCI_DEVICE_ID_RICOH_RL5C476 0x0476
+#define PCI_DEVICE_ID_RICOH_RL5C478 0x0478
+#define PCI_DEVICE_ID_RICOH_R5C822 0x0822
+
+#define PCI_VENDOR_ID_DLINK 0x1186
+#define PCI_DEVICE_ID_DLINK_DGE510T 0x4c00
+
+#define PCI_VENDOR_ID_ARTOP 0x1191
+#define PCI_DEVICE_ID_ARTOP_ATP850UF 0x0005
+#define PCI_DEVICE_ID_ARTOP_ATP860 0x0006
+#define PCI_DEVICE_ID_ARTOP_ATP860R 0x0007
+#define PCI_DEVICE_ID_ARTOP_ATP865 0x0008
+#define PCI_DEVICE_ID_ARTOP_ATP865R 0x0009
+#define PCI_DEVICE_ID_ARTOP_AEC7610 0x8002
+#define PCI_DEVICE_ID_ARTOP_AEC7612UW 0x8010
+#define PCI_DEVICE_ID_ARTOP_AEC7612U 0x8020
+#define PCI_DEVICE_ID_ARTOP_AEC7612S 0x8030
+#define PCI_DEVICE_ID_ARTOP_AEC7612D 0x8040
+#define PCI_DEVICE_ID_ARTOP_AEC7612SUW 0x8050
+#define PCI_DEVICE_ID_ARTOP_8060 0x8060
+
+#define PCI_VENDOR_ID_ZEITNET 0x1193
+#define PCI_DEVICE_ID_ZEITNET_1221 0x0001
+#define PCI_DEVICE_ID_ZEITNET_1225 0x0002
+
+#define PCI_VENDOR_ID_FUJITSU_ME 0x119e
+#define PCI_DEVICE_ID_FUJITSU_FS155 0x0001
+#define PCI_DEVICE_ID_FUJITSU_FS50 0x0003
+
+#define PCI_SUBVENDOR_ID_KEYSPAN 0x11a9
+#define PCI_SUBDEVICE_ID_KEYSPAN_SX2 0x5334
+
+#define PCI_VENDOR_ID_MARVELL 0x11ab
+#define PCI_DEVICE_ID_MARVELL_GT64111 0x4146
+#define PCI_DEVICE_ID_MARVELL_GT64260 0x6430
+#define PCI_DEVICE_ID_MARVELL_MV64360 0x6460
+#define PCI_DEVICE_ID_MARVELL_MV64460 0x6480
+#define PCI_DEVICE_ID_MARVELL_GT96100 0x9652
+#define PCI_DEVICE_ID_MARVELL_GT96100A 0x9653
+
+#define PCI_VENDOR_ID_V3 0x11b0
+#define PCI_DEVICE_ID_V3_V960 0x0001
+#define PCI_DEVICE_ID_V3_V351 0x0002
+
+#define PCI_VENDOR_ID_ATT 0x11c1
+#define PCI_DEVICE_ID_ATT_VENUS_MODEM 0x480
+
+#define PCI_VENDOR_ID_SPECIALIX 0x11cb
+#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000
+#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000
+#define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004
+
+#define PCI_VENDOR_ID_ANALOG_DEVICES 0x11d4
+#define PCI_DEVICE_ID_AD1889JS 0x1889
+
+#define PCI_DEVICE_ID_SEGA_BBA 0x1234
+
+#define PCI_VENDOR_ID_ZORAN 0x11de
+#define PCI_DEVICE_ID_ZORAN_36057 0x6057
+#define PCI_DEVICE_ID_ZORAN_36120 0x6120
+
+#define PCI_VENDOR_ID_COMPEX 0x11f6
+#define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112
+
+#define PCI_VENDOR_ID_RP 0x11fe
+#define PCI_DEVICE_ID_RP32INTF 0x0001
+#define PCI_DEVICE_ID_RP8INTF 0x0002
+#define PCI_DEVICE_ID_RP16INTF 0x0003
+#define PCI_DEVICE_ID_RP4QUAD 0x0004
+#define PCI_DEVICE_ID_RP8OCTA 0x0005
+#define PCI_DEVICE_ID_RP8J 0x0006
+#define PCI_DEVICE_ID_RP4J 0x0007
+#define PCI_DEVICE_ID_RP8SNI 0x0008 
+#define PCI_DEVICE_ID_RP16SNI 0x0009 
+#define PCI_DEVICE_ID_RPP4 0x000A
+#define PCI_DEVICE_ID_RPP8 0x000B
+#define PCI_DEVICE_ID_RP4M 0x000D
+#define PCI_DEVICE_ID_RP2_232 0x000E
+#define PCI_DEVICE_ID_RP2_422 0x000F
+#define PCI_DEVICE_ID_URP32INTF 0x0801
+#define PCI_DEVICE_ID_URP8INTF 0x0802
+#define PCI_DEVICE_ID_URP16INTF 0x0803
+#define PCI_DEVICE_ID_URP8OCTA 0x0805
+#define PCI_DEVICE_ID_UPCI_RM3_8PORT 0x080C 
+#define PCI_DEVICE_ID_UPCI_RM3_4PORT 0x080D
+#define PCI_DEVICE_ID_CRP16INTF 0x0903 
+
+#define PCI_VENDOR_ID_CYCLADES 0x120e
+#define PCI_DEVICE_ID_CYCLOM_Y_Lo 0x0100
+#define PCI_DEVICE_ID_CYCLOM_Y_Hi 0x0101
+#define PCI_DEVICE_ID_CYCLOM_4Y_Lo 0x0102
+#define PCI_DEVICE_ID_CYCLOM_4Y_Hi 0x0103
+#define PCI_DEVICE_ID_CYCLOM_8Y_Lo 0x0104
+#define PCI_DEVICE_ID_CYCLOM_8Y_Hi 0x0105
+#define PCI_DEVICE_ID_CYCLOM_Z_Lo 0x0200
+#define PCI_DEVICE_ID_CYCLOM_Z_Hi 0x0201
+#define PCI_DEVICE_ID_PC300_RX_2 0x0300
+#define PCI_DEVICE_ID_PC300_RX_1 0x0301
+#define PCI_DEVICE_ID_PC300_TE_2 0x0310
+#define PCI_DEVICE_ID_PC300_TE_1 0x0311
+#define PCI_DEVICE_ID_PC300_TE_M_2 0x0320
+#define PCI_DEVICE_ID_PC300_TE_M_1 0x0321
+
+#define PCI_VENDOR_ID_ESSENTIAL 0x120f
+#define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER 0x0001
+
+#define PCI_VENDOR_ID_O2 0x1217
+#define PCI_DEVICE_ID_O2_6729 0x6729
+#define PCI_DEVICE_ID_O2_6730 0x673a
+#define PCI_DEVICE_ID_O2_6832 0x6832
+#define PCI_DEVICE_ID_O2_6836 0x6836
+
+#define PCI_VENDOR_ID_3DFX 0x121a
+#define PCI_DEVICE_ID_3DFX_VOODOO 0x0001
+#define PCI_DEVICE_ID_3DFX_VOODOO2 0x0002
+#define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003
+#define PCI_DEVICE_ID_3DFX_VOODOO3 0x0005
+#define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009
+
+#define PCI_VENDOR_ID_AVM 0x1244
+#define PCI_DEVICE_ID_AVM_B1 0x0700
+#define PCI_DEVICE_ID_AVM_C4 0x0800
+#define PCI_DEVICE_ID_AVM_A1 0x0a00
+#define PCI_DEVICE_ID_AVM_A1_V2 0x0e00
+#define PCI_DEVICE_ID_AVM_C2 0x1100
+#define PCI_DEVICE_ID_AVM_T1 0x1200
+
+#define PCI_VENDOR_ID_STALLION 0x124d
+
+#define PCI_VENDOR_ID_AT 0x1259
+#define PCI_SUBDEVICE_ID_AT_2700FX 0x2701
+#define PCI_SUBDEVICE_ID_AT_2701FX 0x2703
+
+#define PCI_VENDOR_ID_ESS 0x125d
+#define PCI_DEVICE_ID_ESS_ESS1968 0x1968
+#define PCI_DEVICE_ID_ESS_ESS1978 0x1978
+#define PCI_DEVICE_ID_ESS_ALLEGRO_1 0x1988
+#define PCI_DEVICE_ID_ESS_ALLEGRO 0x1989
+#define PCI_DEVICE_ID_ESS_CANYON3D_2LE 0x1990
+#define PCI_DEVICE_ID_ESS_CANYON3D_2 0x1992
+#define PCI_DEVICE_ID_ESS_MAESTRO3 0x1998
+#define PCI_DEVICE_ID_ESS_MAESTRO3_1 0x1999
+#define PCI_DEVICE_ID_ESS_MAESTRO3_HW 0x199a
+#define PCI_DEVICE_ID_ESS_MAESTRO3_2 0x199b
+
+#define PCI_VENDOR_ID_SATSAGEM 0x1267
+#define PCI_DEVICE_ID_SATSAGEM_NICCY 0x1016
+
+#define PCI_VENDOR_ID_ENSONIQ 0x1274
+#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880
+#define PCI_DEVICE_ID_ENSONIQ_ES1370 0x5000
+#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371
+
+#define PCI_VENDOR_ID_TRANSMETA 0x1279
+#define PCI_DEVICE_ID_EFFICEON 0x0060
+
+#define PCI_VENDOR_ID_ROCKWELL 0x127A
+
+#define PCI_VENDOR_ID_ITE 0x1283
+#define PCI_DEVICE_ID_ITE_IT8172G 0x8172
+#define PCI_DEVICE_ID_ITE_IT8172G_AUDIO 0x0801
+#define PCI_DEVICE_ID_ITE_8211 0x8211
+#define PCI_DEVICE_ID_ITE_8212 0x8212
+#define PCI_DEVICE_ID_ITE_8872 0x8872
+#define PCI_DEVICE_ID_ITE_IT8330G_0 0xe886
+
+#define PCI_DEVICE_ID_ESS_ESS0100 0x0100
+
+#define PCI_VENDOR_ID_ALTEON 0x12ae
+
+#define PCI_SUBVENDOR_ID_CONNECT_TECH 0x12c4
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232 0x0001
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232 0x0002
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232 0x0003
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485 0x0004
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4 0x0005
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485 0x0006
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2 0x0007
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485 0x0008
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6 0x0009
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1 0x000A
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1 0x000B
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_20MHZ 0x000C
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_PTM 0x000D
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_NT960PCI 0x0100
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_2 0x0201
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4 0x0202
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232 0x0300
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_232 0x0301
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_232 0x0302
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_1_1 0x0310
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_2 0x0311
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4 0x0312
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2 0x0320
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4 0x0321
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8 0x0322
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_485 0x0330
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_485 0x0331
+#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485 0x0332
+
+#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2
+#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018
+
+#define PCI_SUBVENDOR_ID_CHASE_PCIFAST 0x12E0
+#define PCI_SUBDEVICE_ID_CHASE_PCIFAST4 0x0031
+#define PCI_SUBDEVICE_ID_CHASE_PCIFAST8 0x0021
+#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16 0x0011
+#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC 0x0041
+#define PCI_SUBVENDOR_ID_CHASE_PCIRAS 0x124D
+#define PCI_SUBDEVICE_ID_CHASE_PCIRAS4 0xF001
+#define PCI_SUBDEVICE_ID_CHASE_PCIRAS8 0xF010
+
+#define PCI_VENDOR_ID_AUREAL 0x12eb
+#define PCI_DEVICE_ID_AUREAL_VORTEX_1 0x0001
+#define PCI_DEVICE_ID_AUREAL_VORTEX_2 0x0002
+#define PCI_DEVICE_ID_AUREAL_ADVANTAGE 0x0003
+
+#define PCI_VENDOR_ID_ELECTRONICDESIGNGMBH 0x12f8
+#define PCI_DEVICE_ID_LML_33R10 0x8a02
+
+#define PCI_VENDOR_ID_SIIG 0x131f
+#define PCI_SUBVENDOR_ID_SIIG 0x131f
+#define PCI_DEVICE_ID_SIIG_1S_10x_550 0x1000
+#define PCI_DEVICE_ID_SIIG_1S_10x_650 0x1001
+#define PCI_DEVICE_ID_SIIG_1S_10x_850 0x1002
+#define PCI_DEVICE_ID_SIIG_1S1P_10x_550 0x1010
+#define PCI_DEVICE_ID_SIIG_1S1P_10x_650 0x1011
+#define PCI_DEVICE_ID_SIIG_1S1P_10x_850 0x1012
+#define PCI_DEVICE_ID_SIIG_1P_10x 0x1020
+#define PCI_DEVICE_ID_SIIG_2P_10x 0x1021
+#define PCI_DEVICE_ID_SIIG_2S_10x_550 0x1030
+#define PCI_DEVICE_ID_SIIG_2S_10x_650 0x1031
+#define PCI_DEVICE_ID_SIIG_2S_10x_850 0x1032
+#define PCI_DEVICE_ID_SIIG_2S1P_10x_550 0x1034
+#define PCI_DEVICE_ID_SIIG_2S1P_10x_650 0x1035
+#define PCI_DEVICE_ID_SIIG_2S1P_10x_850 0x1036
+#define PCI_DEVICE_ID_SIIG_4S_10x_550 0x1050
+#define PCI_DEVICE_ID_SIIG_4S_10x_650 0x1051
+#define PCI_DEVICE_ID_SIIG_4S_10x_850 0x1052
+#define PCI_DEVICE_ID_SIIG_1S_20x_550 0x2000
+#define PCI_DEVICE_ID_SIIG_1S_20x_650 0x2001
+#define PCI_DEVICE_ID_SIIG_1S_20x_850 0x2002
+#define PCI_DEVICE_ID_SIIG_1P_20x 0x2020
+#define PCI_DEVICE_ID_SIIG_2P_20x 0x2021
+#define PCI_DEVICE_ID_SIIG_2S_20x_550 0x2030
+#define PCI_DEVICE_ID_SIIG_2S_20x_650 0x2031
+#define PCI_DEVICE_ID_SIIG_2S_20x_850 0x2032
+#define PCI_DEVICE_ID_SIIG_2P1S_20x_550 0x2040
+#define PCI_DEVICE_ID_SIIG_2P1S_20x_650 0x2041
+#define PCI_DEVICE_ID_SIIG_2P1S_20x_850 0x2042
+#define PCI_DEVICE_ID_SIIG_1S1P_20x_550 0x2010
+#define PCI_DEVICE_ID_SIIG_1S1P_20x_650 0x2011
+#define PCI_DEVICE_ID_SIIG_1S1P_20x_850 0x2012
+#define PCI_DEVICE_ID_SIIG_4S_20x_550 0x2050
+#define PCI_DEVICE_ID_SIIG_4S_20x_650 0x2051
+#define PCI_DEVICE_ID_SIIG_4S_20x_850 0x2052
+#define PCI_DEVICE_ID_SIIG_2S1P_20x_550 0x2060
+#define PCI_DEVICE_ID_SIIG_2S1P_20x_650 0x2061
+#define PCI_DEVICE_ID_SIIG_2S1P_20x_850 0x2062
+#define PCI_DEVICE_ID_SIIG_8S_20x_550 0x2080
+#define PCI_DEVICE_ID_SIIG_8S_20x_650 0x2081
+#define PCI_DEVICE_ID_SIIG_8S_20x_850 0x2082
+#define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050
+
+#define PCI_VENDOR_ID_RADISYS 0x1331
+
+#define PCI_VENDOR_ID_DOMEX 0x134a
+#define PCI_DEVICE_ID_DOMEX_DMX3191D 0x0001
+
+#define PCI_VENDOR_ID_INTASHIELD 0x135a
+#define PCI_DEVICE_ID_INTASHIELD_IS200 0x0d80
+
+#define PCI_VENDOR_ID_QUATECH 0x135C
+#define PCI_DEVICE_ID_QUATECH_QSC100 0x0010
+#define PCI_DEVICE_ID_QUATECH_DSC100 0x0020
+#define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050
+#define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060
+
+#define PCI_VENDOR_ID_SEALEVEL 0x135e
+#define PCI_DEVICE_ID_SEALEVEL_U530 0x7101
+#define PCI_DEVICE_ID_SEALEVEL_UCOMM2 0x7201
+#define PCI_DEVICE_ID_SEALEVEL_UCOMM422 0x7402
+#define PCI_DEVICE_ID_SEALEVEL_UCOMM232 0x7202
+#define PCI_DEVICE_ID_SEALEVEL_COMM4 0x7401
+#define PCI_DEVICE_ID_SEALEVEL_COMM8 0x7801
+#define PCI_DEVICE_ID_SEALEVEL_UCOMM8 0x7804
+
+#define PCI_VENDOR_ID_HYPERCOPE 0x1365
+#define PCI_DEVICE_ID_HYPERCOPE_PLX 0x9050
+#define PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO 0x0104
+#define PCI_SUBDEVICE_ID_HYPERCOPE_ERGO 0x0106
+#define PCI_SUBDEVICE_ID_HYPERCOPE_METRO 0x0107
+#define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2 0x0108
+
+#define PCI_VENDOR_ID_KAWASAKI 0x136b
+#define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01
+
+#define PCI_VENDOR_ID_CNET 0x1371
+#define PCI_DEVICE_ID_CNET_GIGACARD 0x434e
+
+#define PCI_VENDOR_ID_LMC 0x1376
+#define PCI_DEVICE_ID_LMC_HSSI 0x0003
+#define PCI_DEVICE_ID_LMC_DS3 0x0004
+#define PCI_DEVICE_ID_LMC_SSI 0x0005
+#define PCI_DEVICE_ID_LMC_T1 0x0006
+
+#define PCI_VENDOR_ID_NETGEAR 0x1385
+#define PCI_DEVICE_ID_NETGEAR_GA620 0x620a
+
+#define PCI_VENDOR_ID_APPLICOM 0x1389
+#define PCI_DEVICE_ID_APPLICOM_PCIGENERIC 0x0001
+#define PCI_DEVICE_ID_APPLICOM_PCI2000IBS_CAN 0x0002
+#define PCI_DEVICE_ID_APPLICOM_PCI2000PFB 0x0003
+
+#define PCI_VENDOR_ID_MOXA 0x1393
+#define PCI_DEVICE_ID_MOXA_RC7000 0x0001
+#define PCI_DEVICE_ID_MOXA_CP102 0x1020
+#define PCI_DEVICE_ID_MOXA_CP102UL 0x1021
+#define PCI_DEVICE_ID_MOXA_CP102U 0x1022
+#define PCI_DEVICE_ID_MOXA_C104 0x1040
+#define PCI_DEVICE_ID_MOXA_CP104U 0x1041
+#define PCI_DEVICE_ID_MOXA_CP104JU 0x1042
+#define PCI_DEVICE_ID_MOXA_CT114 0x1140
+#define PCI_DEVICE_ID_MOXA_CP114 0x1141
+#define PCI_DEVICE_ID_MOXA_CP118U 0x1180
+#define PCI_DEVICE_ID_MOXA_CP132 0x1320
+#define PCI_DEVICE_ID_MOXA_CP132U 0x1321
+#define PCI_DEVICE_ID_MOXA_CP134U 0x1340
+#define PCI_DEVICE_ID_MOXA_C168 0x1680
+#define PCI_DEVICE_ID_MOXA_CP168U 0x1681
+
+#define PCI_VENDOR_ID_CCD 0x1397
+#define PCI_DEVICE_ID_CCD_2BD0 0x2bd0
+#define PCI_DEVICE_ID_CCD_B000 0xb000
+#define PCI_DEVICE_ID_CCD_B006 0xb006
+#define PCI_DEVICE_ID_CCD_B007 0xb007
+#define PCI_DEVICE_ID_CCD_B008 0xb008
+#define PCI_DEVICE_ID_CCD_B009 0xb009
+#define PCI_DEVICE_ID_CCD_B00A 0xb00a
+#define PCI_DEVICE_ID_CCD_B00B 0xb00b
+#define PCI_DEVICE_ID_CCD_B00C 0xb00c
+#define PCI_DEVICE_ID_CCD_B100 0xb100
+#define PCI_DEVICE_ID_CCD_B700 0xb700
+#define PCI_DEVICE_ID_CCD_B701 0xb701
+
+#define PCI_VENDOR_ID_EXAR 0x13a8
+#define PCI_DEVICE_ID_EXAR_XR17C152 0x0152
+#define PCI_DEVICE_ID_EXAR_XR17C154 0x0154
+#define PCI_DEVICE_ID_EXAR_XR17C158 0x0158
+
+#define PCI_VENDOR_ID_MICROGATE 0x13c0
+#define PCI_DEVICE_ID_MICROGATE_USC 0x0010
+#define PCI_DEVICE_ID_MICROGATE_SCA 0x0030
+
+#define PCI_VENDOR_ID_3WARE 0x13C1
+#define PCI_DEVICE_ID_3WARE_1000 0x1000
+#define PCI_DEVICE_ID_3WARE_7000 0x1001
+#define PCI_DEVICE_ID_3WARE_9000 0x1002
+
+#define PCI_VENDOR_ID_IOMEGA 0x13ca
+#define PCI_DEVICE_ID_IOMEGA_BUZ 0x4231
+
+#define PCI_VENDOR_ID_ABOCOM 0x13D1
+#define PCI_DEVICE_ID_ABOCOM_2BD1 0x2BD1
+
+#define PCI_VENDOR_ID_CMEDIA 0x13f6
+#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100
+#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101
+#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111
+#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112
+
+#define PCI_VENDOR_ID_LAVA 0x1407
+#define PCI_DEVICE_ID_LAVA_DSERIAL 0x0100  
+#define PCI_DEVICE_ID_LAVA_QUATRO_A 0x0101  
+#define PCI_DEVICE_ID_LAVA_QUATRO_B 0x0102  
+#define PCI_DEVICE_ID_LAVA_OCTO_A 0x0180  
+#define PCI_DEVICE_ID_LAVA_OCTO_B 0x0181  
+#define PCI_DEVICE_ID_LAVA_PORT_PLUS 0x0200  
+#define PCI_DEVICE_ID_LAVA_QUAD_A 0x0201  
+#define PCI_DEVICE_ID_LAVA_QUAD_B 0x0202  
+#define PCI_DEVICE_ID_LAVA_SSERIAL 0x0500  
+#define PCI_DEVICE_ID_LAVA_PORT_650 0x0600  
+#define PCI_DEVICE_ID_LAVA_PARALLEL 0x8000
+#define PCI_DEVICE_ID_LAVA_DUAL_PAR_A 0x8002  
+#define PCI_DEVICE_ID_LAVA_DUAL_PAR_B 0x8003  
+#define PCI_DEVICE_ID_LAVA_BOCA_IOPPAR 0x8800
+
+#define PCI_VENDOR_ID_TIMEDIA 0x1409
+#define PCI_DEVICE_ID_TIMEDIA_1889 0x7168
+
+#define PCI_VENDOR_ID_ICE 0x1412
+#define PCI_DEVICE_ID_ICE_1712 0x1712
+#define PCI_DEVICE_ID_VT1724 0x1724
+
+#define PCI_VENDOR_ID_OXSEMI 0x1415
+#define PCI_DEVICE_ID_OXSEMI_12PCI840 0x8403
+#define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501
+#define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511
+#define PCI_DEVICE_ID_OXSEMI_16PCI954PP 0x9513
+#define PCI_DEVICE_ID_OXSEMI_16PCI952 0x9521
+
+#define PCI_VENDOR_ID_SAMSUNG 0x144d
+
+#define PCI_VENDOR_ID_MYRICOM 0x14c1
+
+#define PCI_VENDOR_ID_TITAN 0x14D2
+#define PCI_DEVICE_ID_TITAN_010L 0x8001
+#define PCI_DEVICE_ID_TITAN_100L 0x8010
+#define PCI_DEVICE_ID_TITAN_110L 0x8011
+#define PCI_DEVICE_ID_TITAN_200L 0x8020
+#define PCI_DEVICE_ID_TITAN_210L 0x8021
+#define PCI_DEVICE_ID_TITAN_400L 0x8040
+#define PCI_DEVICE_ID_TITAN_800L 0x8080
+#define PCI_DEVICE_ID_TITAN_100 0xA001
+#define PCI_DEVICE_ID_TITAN_200 0xA005
+#define PCI_DEVICE_ID_TITAN_400 0xA003
+#define PCI_DEVICE_ID_TITAN_800B 0xA004
+
+#define PCI_VENDOR_ID_PANACOM 0x14d4
+#define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400
+#define PCI_DEVICE_ID_PANACOM_DUALMODEM 0x0402
+
+#define PCI_VENDOR_ID_AFAVLAB 0x14db
+#define PCI_DEVICE_ID_AFAVLAB_P028 0x2180
+#define PCI_DEVICE_ID_AFAVLAB_P030 0x2182
+#define PCI_SUBDEVICE_ID_AFAVLAB_P061 0x2150
+
+#define PCI_VENDOR_ID_BROADCOM 0x14e4
+#define PCI_DEVICE_ID_TIGON3_5752 0x1600
+#define PCI_DEVICE_ID_TIGON3_5752M 0x1601
+#define PCI_DEVICE_ID_TIGON3_5700 0x1644
+#define PCI_DEVICE_ID_TIGON3_5701 0x1645
+#define PCI_DEVICE_ID_TIGON3_5702 0x1646
+#define PCI_DEVICE_ID_TIGON3_5703 0x1647
+#define PCI_DEVICE_ID_TIGON3_5704 0x1648
+#define PCI_DEVICE_ID_TIGON3_5704S_2 0x1649
+#define PCI_DEVICE_ID_NX2_5706 0x164a
+#define PCI_DEVICE_ID_NX2_5708 0x164c
+#define PCI_DEVICE_ID_TIGON3_5702FE 0x164d
+#define PCI_DEVICE_ID_TIGON3_5705 0x1653
+#define PCI_DEVICE_ID_TIGON3_5705_2 0x1654
+#define PCI_DEVICE_ID_TIGON3_5720 0x1658
+#define PCI_DEVICE_ID_TIGON3_5721 0x1659
+#define PCI_DEVICE_ID_TIGON3_5705M 0x165d
+#define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e
+#define PCI_DEVICE_ID_TIGON3_5714 0x1668
+#define PCI_DEVICE_ID_TIGON3_5714S 0x1669
+#define PCI_DEVICE_ID_TIGON3_5780 0x166a
+#define PCI_DEVICE_ID_TIGON3_5780S 0x166b
+#define PCI_DEVICE_ID_TIGON3_5705F 0x166e
+#define PCI_DEVICE_ID_TIGON3_5754M 0x1672
+#define PCI_DEVICE_ID_TIGON3_5755M 0x1673
+#define PCI_DEVICE_ID_TIGON3_5750 0x1676
+#define PCI_DEVICE_ID_TIGON3_5751 0x1677
+#define PCI_DEVICE_ID_TIGON3_5715 0x1678
+#define PCI_DEVICE_ID_TIGON3_5715S 0x1679
+#define PCI_DEVICE_ID_TIGON3_5754 0x167a
+#define PCI_DEVICE_ID_TIGON3_5755 0x167b
+#define PCI_DEVICE_ID_TIGON3_5750M 0x167c
+#define PCI_DEVICE_ID_TIGON3_5751M 0x167d
+#define PCI_DEVICE_ID_TIGON3_5751F 0x167e
+#define PCI_DEVICE_ID_TIGON3_5787M 0x1693
+#define PCI_DEVICE_ID_TIGON3_5782 0x1696
+#define PCI_DEVICE_ID_TIGON3_5786 0x169a
+#define PCI_DEVICE_ID_TIGON3_5787 0x169b
+#define PCI_DEVICE_ID_TIGON3_5788 0x169c
+#define PCI_DEVICE_ID_TIGON3_5789 0x169d
+#define PCI_DEVICE_ID_TIGON3_5702X 0x16a6
+#define PCI_DEVICE_ID_TIGON3_5703X 0x16a7
+#define PCI_DEVICE_ID_TIGON3_5704S 0x16a8
+#define PCI_DEVICE_ID_NX2_5706S 0x16aa
+#define PCI_DEVICE_ID_NX2_5708S 0x16ac
+#define PCI_DEVICE_ID_TIGON3_5702A3 0x16c6
+#define PCI_DEVICE_ID_TIGON3_5703A3 0x16c7
+#define PCI_DEVICE_ID_TIGON3_5781 0x16dd
+#define PCI_DEVICE_ID_TIGON3_5753 0x16f7
+#define PCI_DEVICE_ID_TIGON3_5753M 0x16fd
+#define PCI_DEVICE_ID_TIGON3_5753F 0x16fe
+#define PCI_DEVICE_ID_TIGON3_5901 0x170d
+#define PCI_DEVICE_ID_BCM4401B1 0x170c
+#define PCI_DEVICE_ID_TIGON3_5901_2 0x170e
+#define PCI_DEVICE_ID_BCM4401 0x4401
+#define PCI_DEVICE_ID_BCM4401B0 0x4402
+
+#define PCI_VENDOR_ID_TOPIC 0x151f
+#define PCI_DEVICE_ID_TOPIC_TP560 0x0000
+
+#define PCI_VENDOR_ID_ENE 0x1524
+#define PCI_DEVICE_ID_ENE_1211 0x1211
+#define PCI_DEVICE_ID_ENE_1225 0x1225
+#define PCI_DEVICE_ID_ENE_1410 0x1410
+#define PCI_DEVICE_ID_ENE_710 0x1411
+#define PCI_DEVICE_ID_ENE_712 0x1412
+#define PCI_DEVICE_ID_ENE_1420 0x1420
+#define PCI_DEVICE_ID_ENE_720 0x1421
+#define PCI_DEVICE_ID_ENE_722 0x1422
+
+#define PCI_VENDOR_ID_CHELSIO 0x1425
+
+#define PCI_VENDOR_ID_SYBA 0x1592
+#define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782
+#define PCI_DEVICE_ID_SYBA_1P_ECP 0x0783
+
+#define PCI_VENDOR_ID_MORETON 0x15aa
+#define PCI_DEVICE_ID_RASTEL_2PORT 0x2000
+
+#define PCI_VENDOR_ID_ZOLTRIX 0x15b0
+#define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0 
+
+#define PCI_VENDOR_ID_MELLANOX 0x15b3
+#define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44
+#define PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE 0x5a46
+#define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT 0x6278
+#define PCI_DEVICE_ID_MELLANOX_ARBEL 0x6282
+#define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c
+#define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274
+
+#define PCI_VENDOR_ID_PDC 0x15e9
+
+#define PCI_VENDOR_ID_FARSITE 0x1619
+#define PCI_DEVICE_ID_FARSITE_T2P 0x0400
+#define PCI_DEVICE_ID_FARSITE_T4P 0x0440
+#define PCI_DEVICE_ID_FARSITE_T1U 0x0610
+#define PCI_DEVICE_ID_FARSITE_T2U 0x0620
+#define PCI_DEVICE_ID_FARSITE_T4U 0x0640
+#define PCI_DEVICE_ID_FARSITE_TE1 0x1610
+#define PCI_DEVICE_ID_FARSITE_TE1C 0x1612
+
+#define PCI_VENDOR_ID_SIBYTE 0x166d
+#define PCI_DEVICE_ID_BCM1250_HT 0x0002
+
+#define PCI_VENDOR_ID_NETCELL 0x169c
+#define PCI_DEVICE_ID_REVOLUTION 0x0044
+
+#define PCI_VENDOR_ID_VITESSE 0x1725
+#define PCI_DEVICE_ID_VITESSE_VSC7174 0x7174
+
+#define PCI_VENDOR_ID_LINKSYS 0x1737
+#define PCI_DEVICE_ID_LINKSYS_EG1064 0x1064
+
+#define PCI_VENDOR_ID_ALTIMA 0x173b
+#define PCI_DEVICE_ID_ALTIMA_AC1000 0x03e8
+#define PCI_DEVICE_ID_ALTIMA_AC1001 0x03e9
+#define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea
+#define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb
+
+#define PCI_VENDOR_ID_S2IO 0x17d5
+#define PCI_DEVICE_ID_S2IO_WIN 0x5731
+#define PCI_DEVICE_ID_S2IO_UNI 0x5831
+#define PCI_DEVICE_ID_HERC_WIN 0x5732
+#define PCI_DEVICE_ID_HERC_UNI 0x5832
+
+#define PCI_VENDOR_ID_SITECOM 0x182d
+#define PCI_DEVICE_ID_SITECOM_DC105V2 0x3069
+
+#define PCI_VENDOR_ID_TOPSPIN 0x1867
+
+#define PCI_VENDOR_ID_TDI 0x192E
+#define PCI_DEVICE_ID_TDI_EHCI 0x0101
+
+#define PCI_VENDOR_ID_JMICRON 0x197B
+#define PCI_DEVICE_ID_JMICRON_JMB360 0x2360
+#define PCI_DEVICE_ID_JMICRON_JMB361 0x2361
+#define PCI_DEVICE_ID_JMICRON_JMB363 0x2363
+#define PCI_DEVICE_ID_JMICRON_JMB365 0x2365
+#define PCI_DEVICE_ID_JMICRON_JMB366 0x2366
+#define PCI_DEVICE_ID_JMICRON_JMB368 0x2368
+
+#define PCI_VENDOR_ID_TEKRAM 0x1de1
+#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
+
+#define PCI_VENDOR_ID_HINT 0x3388
+#define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013
+
+#define PCI_VENDOR_ID_3DLABS 0x3d3d
+#define PCI_DEVICE_ID_3DLABS_PERMEDIA2 0x0007
+#define PCI_DEVICE_ID_3DLABS_PERMEDIA2V 0x0009
+
+#define PCI_VENDOR_ID_AKS 0x416c
+#define PCI_DEVICE_ID_AKS_ALADDINCARD 0x0100
+
+#define PCI_VENDOR_ID_S3 0x5333
+#define PCI_DEVICE_ID_S3_TRIO 0x8811
+#define PCI_DEVICE_ID_S3_868 0x8880
+#define PCI_DEVICE_ID_S3_968 0x88f0
+#define PCI_DEVICE_ID_S3_SAVAGE4 0x8a25
+#define PCI_DEVICE_ID_S3_PROSAVAGE8 0x8d04
+#define PCI_DEVICE_ID_S3_SONICVIBES 0xca00
+
+#define PCI_VENDOR_ID_DUNORD 0x5544
+#define PCI_DEVICE_ID_DUNORD_I3000 0x0001
+
+#define PCI_VENDOR_ID_DCI 0x6666
+#define PCI_DEVICE_ID_DCI_PCCOM4 0x0001
+#define PCI_DEVICE_ID_DCI_PCCOM8 0x0002
+#define PCI_DEVICE_ID_DCI_PCCOM2 0x0004
+
+#define PCI_VENDOR_ID_INTEL 0x8086
+#define PCI_DEVICE_ID_INTEL_EESSC 0x0008
+#define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320
+#define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321
+#define PCI_DEVICE_ID_INTEL_PXH_0 0x0329
+#define PCI_DEVICE_ID_INTEL_PXH_1 0x032A
+#define PCI_DEVICE_ID_INTEL_PXHV 0x032C
+#define PCI_DEVICE_ID_INTEL_82375 0x0482
+#define PCI_DEVICE_ID_INTEL_82424 0x0483
+#define PCI_DEVICE_ID_INTEL_82378 0x0484
+#define PCI_DEVICE_ID_INTEL_I960 0x0960
+#define PCI_DEVICE_ID_INTEL_I960RM 0x0962
+#define PCI_DEVICE_ID_INTEL_82815_MC 0x1130
+#define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132
+#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221
+#define PCI_DEVICE_ID_INTEL_7505_0 0x2550 
+#define PCI_DEVICE_ID_INTEL_7205_0 0x255d
+#define PCI_DEVICE_ID_INTEL_82437 0x122d
+#define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e
+#define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230
+#define PCI_DEVICE_ID_INTEL_82371MX 0x1234
+#define PCI_DEVICE_ID_INTEL_82441 0x1237
+#define PCI_DEVICE_ID_INTEL_82380FB 0x124b
+#define PCI_DEVICE_ID_INTEL_82439 0x1250
+#define PCI_DEVICE_ID_INTEL_80960_RP 0x1960
+#define PCI_DEVICE_ID_INTEL_82840_HB 0x1a21
+#define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30
+#define PCI_DEVICE_ID_INTEL_IOAT 0x1a38
+#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410
+#define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411
+#define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413
+#define PCI_DEVICE_ID_INTEL_82801AA_5 0x2415
+#define PCI_DEVICE_ID_INTEL_82801AA_6 0x2416
+#define PCI_DEVICE_ID_INTEL_82801AA_8 0x2418
+#define PCI_DEVICE_ID_INTEL_82801AB_0 0x2420
+#define PCI_DEVICE_ID_INTEL_82801AB_1 0x2421
+#define PCI_DEVICE_ID_INTEL_82801AB_3 0x2423
+#define PCI_DEVICE_ID_INTEL_82801AB_5 0x2425
+#define PCI_DEVICE_ID_INTEL_82801AB_6 0x2426
+#define PCI_DEVICE_ID_INTEL_82801AB_8 0x2428
+#define PCI_DEVICE_ID_INTEL_82801BA_0 0x2440
+#define PCI_DEVICE_ID_INTEL_82801BA_2 0x2443
+#define PCI_DEVICE_ID_INTEL_82801BA_4 0x2445
+#define PCI_DEVICE_ID_INTEL_82801BA_6 0x2448
+#define PCI_DEVICE_ID_INTEL_82801BA_8 0x244a
+#define PCI_DEVICE_ID_INTEL_82801BA_9 0x244b
+#define PCI_DEVICE_ID_INTEL_82801BA_10 0x244c
+#define PCI_DEVICE_ID_INTEL_82801BA_11 0x244e
+#define PCI_DEVICE_ID_INTEL_82801E_0 0x2450
+#define PCI_DEVICE_ID_INTEL_82801E_11 0x245b
+#define PCI_DEVICE_ID_INTEL_82801CA_0 0x2480
+#define PCI_DEVICE_ID_INTEL_82801CA_3 0x2483
+#define PCI_DEVICE_ID_INTEL_82801CA_5 0x2485
+#define PCI_DEVICE_ID_INTEL_82801CA_6 0x2486
+#define PCI_DEVICE_ID_INTEL_82801CA_10 0x248a
+#define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b
+#define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c
+#define PCI_DEVICE_ID_INTEL_82801DB_0 0x24c0
+#define PCI_DEVICE_ID_INTEL_82801DB_1 0x24c1
+#define PCI_DEVICE_ID_INTEL_82801DB_3 0x24c3
+#define PCI_DEVICE_ID_INTEL_82801DB_5 0x24c5
+#define PCI_DEVICE_ID_INTEL_82801DB_6 0x24c6
+#define PCI_DEVICE_ID_INTEL_82801DB_9 0x24c9
+#define PCI_DEVICE_ID_INTEL_82801DB_10 0x24ca
+#define PCI_DEVICE_ID_INTEL_82801DB_11 0x24cb
+#define PCI_DEVICE_ID_INTEL_82801DB_12 0x24cc
+#define PCI_DEVICE_ID_INTEL_82801EB_0 0x24d0
+#define PCI_DEVICE_ID_INTEL_82801EB_1 0x24d1
+#define PCI_DEVICE_ID_INTEL_82801EB_3 0x24d3
+#define PCI_DEVICE_ID_INTEL_82801EB_5 0x24d5
+#define PCI_DEVICE_ID_INTEL_82801EB_6 0x24d6
+#define PCI_DEVICE_ID_INTEL_82801EB_11 0x24db
+#define PCI_DEVICE_ID_INTEL_82801EB_13 0x24dd
+#define PCI_DEVICE_ID_INTEL_ESB_1 0x25a1
+#define PCI_DEVICE_ID_INTEL_ESB_2 0x25a2
+#define PCI_DEVICE_ID_INTEL_ESB_4 0x25a4
+#define PCI_DEVICE_ID_INTEL_ESB_5 0x25a6
+#define PCI_DEVICE_ID_INTEL_ESB_9 0x25ab
+#define PCI_DEVICE_ID_INTEL_82820_HB 0x2500
+#define PCI_DEVICE_ID_INTEL_82820_UP_HB 0x2501
+#define PCI_DEVICE_ID_INTEL_82850_HB 0x2530
+#define PCI_DEVICE_ID_INTEL_82860_HB 0x2531
+#define PCI_DEVICE_ID_INTEL_E7501_MCH 0x254c
+#define PCI_DEVICE_ID_INTEL_82845G_HB 0x2560
+#define PCI_DEVICE_ID_INTEL_82845G_IG 0x2562
+#define PCI_DEVICE_ID_INTEL_82865_HB 0x2570
+#define PCI_DEVICE_ID_INTEL_82865_IG 0x2572
+#define PCI_DEVICE_ID_INTEL_82875_HB 0x2578
+#define PCI_DEVICE_ID_INTEL_82915G_HB 0x2580
+#define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582
+#define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590
+#define PCI_DEVICE_ID_INTEL_82915GM_IG 0x2592
+#define PCI_DEVICE_ID_INTEL_82945G_HB 0x2770
+#define PCI_DEVICE_ID_INTEL_82945G_IG 0x2772
+#define PCI_DEVICE_ID_INTEL_82945GM_HB 0x27A0
+#define PCI_DEVICE_ID_INTEL_82945GM_IG 0x27A2
+#define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640
+#define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641
+#define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642
+#define PCI_DEVICE_ID_INTEL_ICH6_16 0x266a
+#define PCI_DEVICE_ID_INTEL_ICH6_17 0x266d
+#define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e
+#define PCI_DEVICE_ID_INTEL_ICH6_19 0x266f
+#define PCI_DEVICE_ID_INTEL_ESB2_0 0x2670
+#define PCI_DEVICE_ID_INTEL_ESB2_14 0x2698
+#define PCI_DEVICE_ID_INTEL_ESB2_17 0x269b
+#define PCI_DEVICE_ID_INTEL_ESB2_18 0x269e
+#define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8
+#define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9
+#define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0
+#define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd
+#define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da
+#define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd
+#define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de
+#define PCI_DEVICE_ID_INTEL_ICH7_21 0x27df
+#define PCI_DEVICE_ID_INTEL_ICH8_0 0x2810
+#define PCI_DEVICE_ID_INTEL_ICH8_1 0x2811
+#define PCI_DEVICE_ID_INTEL_ICH8_2 0x2812
+#define PCI_DEVICE_ID_INTEL_ICH8_3 0x2814
+#define PCI_DEVICE_ID_INTEL_ICH8_4 0x2815
+#define PCI_DEVICE_ID_INTEL_ICH8_5 0x283e
+#define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850
+#define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340
+#define PCI_DEVICE_ID_INTEL_82830_HB 0x3575
+#define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577
+#define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580
+#define PCI_DEVICE_ID_INTEL_82855GM_IG 0x3582
+#define PCI_DEVICE_ID_INTEL_E7520_MCH 0x3590
+#define PCI_DEVICE_ID_INTEL_E7320_MCH 0x3592
+#define PCI_DEVICE_ID_INTEL_MCH_PA 0x3595
+#define PCI_DEVICE_ID_INTEL_MCH_PA1 0x3596
+#define PCI_DEVICE_ID_INTEL_MCH_PB 0x3597
+#define PCI_DEVICE_ID_INTEL_MCH_PB1 0x3598
+#define PCI_DEVICE_ID_INTEL_MCH_PC 0x3599
+#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a
+#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e
+#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
+#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
+#define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020
+#define PCI_DEVICE_ID_INTEL_82437VX 0x7030
+#define PCI_DEVICE_ID_INTEL_82439TX 0x7100
+#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110
+#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
+#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
+#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
+#define PCI_DEVICE_ID_INTEL_82810_MC1 0x7120
+#define PCI_DEVICE_ID_INTEL_82810_IG1 0x7121
+#define PCI_DEVICE_ID_INTEL_82810_MC3 0x7122
+#define PCI_DEVICE_ID_INTEL_82810_IG3 0x7123
+#define PCI_DEVICE_ID_INTEL_82810E_MC 0x7124
+#define PCI_DEVICE_ID_INTEL_82810E_IG 0x7125
+#define PCI_DEVICE_ID_INTEL_82443LX_0 0x7180
+#define PCI_DEVICE_ID_INTEL_82443LX_1 0x7181
+#define PCI_DEVICE_ID_INTEL_82443BX_0 0x7190
+#define PCI_DEVICE_ID_INTEL_82443BX_1 0x7191
+#define PCI_DEVICE_ID_INTEL_82443BX_2 0x7192
+#define PCI_DEVICE_ID_INTEL_440MX 0x7195
+#define PCI_DEVICE_ID_INTEL_440MX_6 0x7196
+#define PCI_DEVICE_ID_INTEL_82443MX_0 0x7198
+#define PCI_DEVICE_ID_INTEL_82443MX_1 0x7199
+#define PCI_DEVICE_ID_INTEL_82443MX_3 0x719b
+#define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0
+#define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2
+#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601
+#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4
+#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5
+#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca
+#define PCI_DEVICE_ID_INTEL_82454NX 0x84cb
+#define PCI_DEVICE_ID_INTEL_84460GX 0x84ea
+#define PCI_DEVICE_ID_INTEL_IXP4XX 0x8500
+#define PCI_DEVICE_ID_INTEL_IXP2800 0x9004
+#define PCI_DEVICE_ID_INTEL_S21152BB 0xb152
+
+#define PCI_VENDOR_ID_SCALEMP 0x8686
+#define PCI_DEVICE_ID_SCALEMP_VSMP_CTL 0x1010
+
+#define PCI_VENDOR_ID_COMPUTONE 0x8e0e
+#define PCI_DEVICE_ID_COMPUTONE_IP2EX 0x0291
+#define PCI_DEVICE_ID_COMPUTONE_PG 0x0302
+#define PCI_SUBVENDOR_ID_COMPUTONE 0x8e0e
+#define PCI_SUBDEVICE_ID_COMPUTONE_PG4 0x0001
+#define PCI_SUBDEVICE_ID_COMPUTONE_PG8 0x0002
+#define PCI_SUBDEVICE_ID_COMPUTONE_PG6 0x0003
+
+#define PCI_VENDOR_ID_KTI 0x8e2e
+
+#define PCI_VENDOR_ID_ADAPTEC 0x9004
+#define PCI_DEVICE_ID_ADAPTEC_7810 0x1078
+#define PCI_DEVICE_ID_ADAPTEC_7821 0x2178
+#define PCI_DEVICE_ID_ADAPTEC_38602 0x3860
+#define PCI_DEVICE_ID_ADAPTEC_7850 0x5078
+#define PCI_DEVICE_ID_ADAPTEC_7855 0x5578
+#define PCI_DEVICE_ID_ADAPTEC_3860 0x6038
+#define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075
+#define PCI_DEVICE_ID_ADAPTEC_7860 0x6078
+#define PCI_DEVICE_ID_ADAPTEC_7861 0x6178
+#define PCI_DEVICE_ID_ADAPTEC_7870 0x7078
+#define PCI_DEVICE_ID_ADAPTEC_7871 0x7178
+#define PCI_DEVICE_ID_ADAPTEC_7872 0x7278
+#define PCI_DEVICE_ID_ADAPTEC_7873 0x7378
+#define PCI_DEVICE_ID_ADAPTEC_7874 0x7478
+#define PCI_DEVICE_ID_ADAPTEC_7895 0x7895
+#define PCI_DEVICE_ID_ADAPTEC_7880 0x8078
+#define PCI_DEVICE_ID_ADAPTEC_7881 0x8178
+#define PCI_DEVICE_ID_ADAPTEC_7882 0x8278
+#define PCI_DEVICE_ID_ADAPTEC_7883 0x8378
+#define PCI_DEVICE_ID_ADAPTEC_7884 0x8478
+#define PCI_DEVICE_ID_ADAPTEC_7885 0x8578
+#define PCI_DEVICE_ID_ADAPTEC_7886 0x8678
+#define PCI_DEVICE_ID_ADAPTEC_7887 0x8778
+#define PCI_DEVICE_ID_ADAPTEC_7888 0x8878
+
+#define PCI_VENDOR_ID_ADAPTEC2 0x9005
+#define PCI_DEVICE_ID_ADAPTEC2_2940U2 0x0010
+#define PCI_DEVICE_ID_ADAPTEC2_2930U2 0x0011
+#define PCI_DEVICE_ID_ADAPTEC2_7890B 0x0013
+#define PCI_DEVICE_ID_ADAPTEC2_7890 0x001f
+#define PCI_DEVICE_ID_ADAPTEC2_3940U2 0x0050
+#define PCI_DEVICE_ID_ADAPTEC2_3950U2D 0x0051
+#define PCI_DEVICE_ID_ADAPTEC2_7896 0x005f
+#define PCI_DEVICE_ID_ADAPTEC2_7892A 0x0080
+#define PCI_DEVICE_ID_ADAPTEC2_7892B 0x0081
+#define PCI_DEVICE_ID_ADAPTEC2_7892D 0x0083
+#define PCI_DEVICE_ID_ADAPTEC2_7892P 0x008f
+#define PCI_DEVICE_ID_ADAPTEC2_7899A 0x00c0
+#define PCI_DEVICE_ID_ADAPTEC2_7899B 0x00c1
+#define PCI_DEVICE_ID_ADAPTEC2_7899D 0x00c3
+#define PCI_DEVICE_ID_ADAPTEC2_7899P 0x00cf
+#define PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN 0x0500
+#define PCI_DEVICE_ID_ADAPTEC2_SCAMP 0x0503
+
+#define PCI_VENDOR_ID_HOLTEK 0x9412
+#define PCI_DEVICE_ID_HOLTEK_6565 0x6565
+
+#define PCI_VENDOR_ID_NETMOS 0x9710
+#define PCI_DEVICE_ID_NETMOS_9705 0x9705
+#define PCI_DEVICE_ID_NETMOS_9715 0x9715
+#define PCI_DEVICE_ID_NETMOS_9735 0x9735
+#define PCI_DEVICE_ID_NETMOS_9745 0x9745
+#define PCI_DEVICE_ID_NETMOS_9755 0x9755
+#define PCI_DEVICE_ID_NETMOS_9805 0x9805
+#define PCI_DEVICE_ID_NETMOS_9815 0x9815
+#define PCI_DEVICE_ID_NETMOS_9835 0x9835
+#define PCI_DEVICE_ID_NETMOS_9845 0x9845
+#define PCI_DEVICE_ID_NETMOS_9855 0x9855
+
+#define PCI_SUBVENDOR_ID_EXSYS 0xd84d
+#define PCI_SUBDEVICE_ID_EXSYS_4014 0x4014
+#define PCI_SUBDEVICE_ID_EXSYS_4055 0x4055
+
+#define PCI_VENDOR_ID_TIGERJET 0xe159
+#define PCI_DEVICE_ID_TIGERJET_300 0x0001
+#define PCI_DEVICE_ID_TIGERJET_100 0x0002
+
+#define PCI_VENDOR_ID_TTTECH 0x0357
+#define PCI_DEVICE_ID_TTTECH_MC322 0x000A
+
+#define PCI_VENDOR_ID_XILINX_RME 0xea60
+#define PCI_DEVICE_ID_RME_DIGI32 0x9896
+#define PCI_DEVICE_ID_RME_DIGI32_PRO 0x9897
+#define PCI_DEVICE_ID_RME_DIGI32_8 0x9898
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/pci_regs.h b/ndk/build/platforms/android-1.5/common/include/linux/pci_regs.h
new file mode 100644
index 0000000..93a21be
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/pci_regs.h
@@ -0,0 +1,422 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_PCI_REGS_H
+#define LINUX_PCI_REGS_H
+
+#define PCI_VENDOR_ID 0x00  
+#define PCI_DEVICE_ID 0x02  
+#define PCI_COMMAND 0x04  
+#define PCI_COMMAND_IO 0x1  
+#define PCI_COMMAND_MEMORY 0x2  
+#define PCI_COMMAND_MASTER 0x4  
+#define PCI_COMMAND_SPECIAL 0x8  
+#define PCI_COMMAND_INVALIDATE 0x10  
+#define PCI_COMMAND_VGA_PALETTE 0x20  
+#define PCI_COMMAND_PARITY 0x40  
+#define PCI_COMMAND_WAIT 0x80  
+#define PCI_COMMAND_SERR 0x100  
+#define PCI_COMMAND_FAST_BACK 0x200  
+#define PCI_COMMAND_INTX_DISABLE 0x400  
+
+#define PCI_STATUS 0x06  
+#define PCI_STATUS_CAP_LIST 0x10  
+#define PCI_STATUS_66MHZ 0x20  
+#define PCI_STATUS_UDF 0x40  
+#define PCI_STATUS_FAST_BACK 0x80  
+#define PCI_STATUS_PARITY 0x100  
+#define PCI_STATUS_DEVSEL_MASK 0x600  
+#define PCI_STATUS_DEVSEL_FAST 0x000
+#define PCI_STATUS_DEVSEL_MEDIUM 0x200
+#define PCI_STATUS_DEVSEL_SLOW 0x400
+#define PCI_STATUS_SIG_TARGET_ABORT 0x800  
+#define PCI_STATUS_REC_TARGET_ABORT 0x1000  
+#define PCI_STATUS_REC_MASTER_ABORT 0x2000  
+#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000  
+#define PCI_STATUS_DETECTED_PARITY 0x8000  
+
+#define PCI_CLASS_REVISION 0x08  
+#define PCI_REVISION_ID 0x08  
+#define PCI_CLASS_PROG 0x09  
+#define PCI_CLASS_DEVICE 0x0a  
+
+#define PCI_CACHE_LINE_SIZE 0x0c  
+#define PCI_LATENCY_TIMER 0x0d  
+#define PCI_HEADER_TYPE 0x0e  
+#define PCI_HEADER_TYPE_NORMAL 0
+#define PCI_HEADER_TYPE_BRIDGE 1
+#define PCI_HEADER_TYPE_CARDBUS 2
+
+#define PCI_BIST 0x0f  
+#define PCI_BIST_CODE_MASK 0x0f  
+#define PCI_BIST_START 0x40  
+#define PCI_BIST_CAPABLE 0x80  
+
+#define PCI_BASE_ADDRESS_0 0x10  
+#define PCI_BASE_ADDRESS_1 0x14  
+#define PCI_BASE_ADDRESS_2 0x18  
+#define PCI_BASE_ADDRESS_3 0x1c  
+#define PCI_BASE_ADDRESS_4 0x20  
+#define PCI_BASE_ADDRESS_5 0x24  
+#define PCI_BASE_ADDRESS_SPACE 0x01  
+#define PCI_BASE_ADDRESS_SPACE_IO 0x01
+#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
+#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
+#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00  
+#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02  
+#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04  
+#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08  
+#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
+#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
+
+#define PCI_CARDBUS_CIS 0x28
+#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
+#define PCI_SUBSYSTEM_ID 0x2e
+#define PCI_ROM_ADDRESS 0x30  
+#define PCI_ROM_ADDRESS_ENABLE 0x01
+#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
+
+#define PCI_CAPABILITY_LIST 0x34  
+
+#define PCI_INTERRUPT_LINE 0x3c  
+#define PCI_INTERRUPT_PIN 0x3d  
+#define PCI_MIN_GNT 0x3e  
+#define PCI_MAX_LAT 0x3f  
+
+#define PCI_PRIMARY_BUS 0x18  
+#define PCI_SECONDARY_BUS 0x19  
+#define PCI_SUBORDINATE_BUS 0x1a  
+#define PCI_SEC_LATENCY_TIMER 0x1b  
+#define PCI_IO_BASE 0x1c  
+#define PCI_IO_LIMIT 0x1d
+#define PCI_IO_RANGE_TYPE_MASK 0x0fUL  
+#define PCI_IO_RANGE_TYPE_16 0x00
+#define PCI_IO_RANGE_TYPE_32 0x01
+#define PCI_IO_RANGE_MASK (~0x0fUL)
+#define PCI_SEC_STATUS 0x1e  
+#define PCI_MEMORY_BASE 0x20  
+#define PCI_MEMORY_LIMIT 0x22
+#define PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL
+#define PCI_MEMORY_RANGE_MASK (~0x0fUL)
+#define PCI_PREF_MEMORY_BASE 0x24  
+#define PCI_PREF_MEMORY_LIMIT 0x26
+#define PCI_PREF_RANGE_TYPE_MASK 0x0fUL
+#define PCI_PREF_RANGE_TYPE_32 0x00
+#define PCI_PREF_RANGE_TYPE_64 0x01
+#define PCI_PREF_RANGE_MASK (~0x0fUL)
+#define PCI_PREF_BASE_UPPER32 0x28  
+#define PCI_PREF_LIMIT_UPPER32 0x2c
+#define PCI_IO_BASE_UPPER16 0x30  
+#define PCI_IO_LIMIT_UPPER16 0x32
+
+#define PCI_ROM_ADDRESS1 0x38  
+
+#define PCI_BRIDGE_CONTROL 0x3e
+#define PCI_BRIDGE_CTL_PARITY 0x01  
+#define PCI_BRIDGE_CTL_SERR 0x02  
+#define PCI_BRIDGE_CTL_NO_ISA 0x04  
+#define PCI_BRIDGE_CTL_VGA 0x08  
+#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20  
+#define PCI_BRIDGE_CTL_BUS_RESET 0x40  
+#define PCI_BRIDGE_CTL_FAST_BACK 0x80  
+
+#define PCI_CB_CAPABILITY_LIST 0x14
+
+#define PCI_CB_SEC_STATUS 0x16  
+#define PCI_CB_PRIMARY_BUS 0x18  
+#define PCI_CB_CARD_BUS 0x19  
+#define PCI_CB_SUBORDINATE_BUS 0x1a  
+#define PCI_CB_LATENCY_TIMER 0x1b  
+#define PCI_CB_MEMORY_BASE_0 0x1c
+#define PCI_CB_MEMORY_LIMIT_0 0x20
+#define PCI_CB_MEMORY_BASE_1 0x24
+#define PCI_CB_MEMORY_LIMIT_1 0x28
+#define PCI_CB_IO_BASE_0 0x2c
+#define PCI_CB_IO_BASE_0_HI 0x2e
+#define PCI_CB_IO_LIMIT_0 0x30
+#define PCI_CB_IO_LIMIT_0_HI 0x32
+#define PCI_CB_IO_BASE_1 0x34
+#define PCI_CB_IO_BASE_1_HI 0x36
+#define PCI_CB_IO_LIMIT_1 0x38
+#define PCI_CB_IO_LIMIT_1_HI 0x3a
+#define PCI_CB_IO_RANGE_MASK (~0x03UL)
+
+#define PCI_CB_BRIDGE_CONTROL 0x3e
+#define PCI_CB_BRIDGE_CTL_PARITY 0x01  
+#define PCI_CB_BRIDGE_CTL_SERR 0x02
+#define PCI_CB_BRIDGE_CTL_ISA 0x04
+#define PCI_CB_BRIDGE_CTL_VGA 0x08
+#define PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20
+#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40  
+#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80  
+#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100  
+#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
+#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
+#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
+#define PCI_CB_SUBSYSTEM_ID 0x42
+#define PCI_CB_LEGACY_MODE_BASE 0x44  
+
+#define PCI_CAP_LIST_ID 0  
+#define PCI_CAP_ID_PM 0x01  
+#define PCI_CAP_ID_AGP 0x02  
+#define PCI_CAP_ID_VPD 0x03  
+#define PCI_CAP_ID_SLOTID 0x04  
+#define PCI_CAP_ID_MSI 0x05  
+#define PCI_CAP_ID_CHSWP 0x06  
+#define PCI_CAP_ID_PCIX 0x07  
+#define PCI_CAP_ID_HT_IRQCONF 0x08  
+#define PCI_CAP_ID_VNDR 0x09  
+#define PCI_CAP_ID_SHPC 0x0C  
+#define PCI_CAP_ID_EXP 0x10  
+#define PCI_CAP_ID_MSIX 0x11  
+#define PCI_CAP_LIST_NEXT 1  
+#define PCI_CAP_FLAGS 2  
+#define PCI_CAP_SIZEOF 4
+
+#define PCI_PM_PMC 2  
+#define PCI_PM_CAP_VER_MASK 0x0007  
+#define PCI_PM_CAP_PME_CLOCK 0x0008  
+#define PCI_PM_CAP_RESERVED 0x0010  
+#define PCI_PM_CAP_DSI 0x0020  
+#define PCI_PM_CAP_AUX_POWER 0x01C0  
+#define PCI_PM_CAP_D1 0x0200  
+#define PCI_PM_CAP_D2 0x0400  
+#define PCI_PM_CAP_PME 0x0800  
+#define PCI_PM_CAP_PME_MASK 0xF800  
+#define PCI_PM_CAP_PME_D0 0x0800  
+#define PCI_PM_CAP_PME_D1 0x1000  
+#define PCI_PM_CAP_PME_D2 0x2000  
+#define PCI_PM_CAP_PME_D3 0x4000  
+#define PCI_PM_CAP_PME_D3cold 0x8000  
+#define PCI_PM_CTRL 4  
+#define PCI_PM_CTRL_STATE_MASK 0x0003  
+#define PCI_PM_CTRL_NO_SOFT_RESET 0x0004  
+#define PCI_PM_CTRL_PME_ENABLE 0x0100  
+#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00  
+#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000  
+#define PCI_PM_CTRL_PME_STATUS 0x8000  
+#define PCI_PM_PPB_EXTENSIONS 6  
+#define PCI_PM_PPB_B2_B3 0x40  
+#define PCI_PM_BPCC_ENABLE 0x80  
+#define PCI_PM_DATA_REGISTER 7  
+#define PCI_PM_SIZEOF 8
+
+#define PCI_AGP_VERSION 2  
+#define PCI_AGP_RFU 3  
+#define PCI_AGP_STATUS 4  
+#define PCI_AGP_STATUS_RQ_MASK 0xff000000  
+#define PCI_AGP_STATUS_SBA 0x0200  
+#define PCI_AGP_STATUS_64BIT 0x0020  
+#define PCI_AGP_STATUS_FW 0x0010  
+#define PCI_AGP_STATUS_RATE4 0x0004  
+#define PCI_AGP_STATUS_RATE2 0x0002  
+#define PCI_AGP_STATUS_RATE1 0x0001  
+#define PCI_AGP_COMMAND 8  
+#define PCI_AGP_COMMAND_RQ_MASK 0xff000000  
+#define PCI_AGP_COMMAND_SBA 0x0200  
+#define PCI_AGP_COMMAND_AGP 0x0100  
+#define PCI_AGP_COMMAND_64BIT 0x0020  
+#define PCI_AGP_COMMAND_FW 0x0010  
+#define PCI_AGP_COMMAND_RATE4 0x0004  
+#define PCI_AGP_COMMAND_RATE2 0x0002  
+#define PCI_AGP_COMMAND_RATE1 0x0001  
+#define PCI_AGP_SIZEOF 12
+
+#define PCI_VPD_ADDR 2  
+#define PCI_VPD_ADDR_MASK 0x7fff  
+#define PCI_VPD_ADDR_F 0x8000  
+#define PCI_VPD_DATA 4  
+
+#define PCI_SID_ESR 2  
+#define PCI_SID_ESR_NSLOTS 0x1f  
+#define PCI_SID_ESR_FIC 0x20  
+#define PCI_SID_CHASSIS_NR 3  
+
+#define PCI_MSI_FLAGS 2  
+#define PCI_MSI_FLAGS_64BIT 0x80  
+#define PCI_MSI_FLAGS_QSIZE 0x70  
+#define PCI_MSI_FLAGS_QMASK 0x0e  
+#define PCI_MSI_FLAGS_ENABLE 0x01  
+#define PCI_MSI_FLAGS_MASKBIT 0x100  
+#define PCI_MSI_RFU 3  
+#define PCI_MSI_ADDRESS_LO 4  
+#define PCI_MSI_ADDRESS_HI 8  
+#define PCI_MSI_DATA_32 8  
+#define PCI_MSI_DATA_64 12  
+#define PCI_MSI_MASK_BIT 16  
+
+#define PCI_CHSWP_CSR 2  
+#define PCI_CHSWP_DHA 0x01  
+#define PCI_CHSWP_EIM 0x02  
+#define PCI_CHSWP_PIE 0x04  
+#define PCI_CHSWP_LOO 0x08  
+#define PCI_CHSWP_PI 0x30  
+#define PCI_CHSWP_EXT 0x40  
+#define PCI_CHSWP_INS 0x80  
+
+#define PCI_X_CMD 2  
+#define PCI_X_CMD_DPERR_E 0x0001  
+#define PCI_X_CMD_ERO 0x0002  
+#define PCI_X_CMD_MAX_READ 0x000c  
+#define PCI_X_CMD_MAX_SPLIT 0x0070  
+#define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3)  
+#define PCI_X_STATUS 4  
+#define PCI_X_STATUS_DEVFN 0x000000ff  
+#define PCI_X_STATUS_BUS 0x0000ff00  
+#define PCI_X_STATUS_64BIT 0x00010000  
+#define PCI_X_STATUS_133MHZ 0x00020000  
+#define PCI_X_STATUS_SPL_DISC 0x00040000  
+#define PCI_X_STATUS_UNX_SPL 0x00080000  
+#define PCI_X_STATUS_COMPLEX 0x00100000  
+#define PCI_X_STATUS_MAX_READ 0x00600000  
+#define PCI_X_STATUS_MAX_SPLIT 0x03800000  
+#define PCI_X_STATUS_MAX_CUM 0x1c000000  
+#define PCI_X_STATUS_SPL_ERR 0x20000000  
+#define PCI_X_STATUS_266MHZ 0x40000000  
+#define PCI_X_STATUS_533MHZ 0x80000000  
+
+#define PCI_EXP_FLAGS 2  
+#define PCI_EXP_FLAGS_VERS 0x000f  
+#define PCI_EXP_FLAGS_TYPE 0x00f0  
+#define PCI_EXP_TYPE_ENDPOINT 0x0  
+#define PCI_EXP_TYPE_LEG_END 0x1  
+#define PCI_EXP_TYPE_ROOT_PORT 0x4  
+#define PCI_EXP_TYPE_UPSTREAM 0x5  
+#define PCI_EXP_TYPE_DOWNSTREAM 0x6  
+#define PCI_EXP_TYPE_PCI_BRIDGE 0x7  
+#define PCI_EXP_FLAGS_SLOT 0x0100  
+#define PCI_EXP_FLAGS_IRQ 0x3e00  
+#define PCI_EXP_DEVCAP 4  
+#define PCI_EXP_DEVCAP_PAYLOAD 0x07  
+#define PCI_EXP_DEVCAP_PHANTOM 0x18  
+#define PCI_EXP_DEVCAP_EXT_TAG 0x20  
+#define PCI_EXP_DEVCAP_L0S 0x1c0  
+#define PCI_EXP_DEVCAP_L1 0xe00  
+#define PCI_EXP_DEVCAP_ATN_BUT 0x1000  
+#define PCI_EXP_DEVCAP_ATN_IND 0x2000  
+#define PCI_EXP_DEVCAP_PWR_IND 0x4000  
+#define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000  
+#define PCI_EXP_DEVCAP_PWR_SCL 0xc000000  
+#define PCI_EXP_DEVCTL 8  
+#define PCI_EXP_DEVCTL_CERE 0x0001  
+#define PCI_EXP_DEVCTL_NFERE 0x0002  
+#define PCI_EXP_DEVCTL_FERE 0x0004  
+#define PCI_EXP_DEVCTL_URRE 0x0008  
+#define PCI_EXP_DEVCTL_RELAX_EN 0x0010  
+#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0  
+#define PCI_EXP_DEVCTL_EXT_TAG 0x0100  
+#define PCI_EXP_DEVCTL_PHANTOM 0x0200  
+#define PCI_EXP_DEVCTL_AUX_PME 0x0400  
+#define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800  
+#define PCI_EXP_DEVCTL_READRQ 0x7000  
+#define PCI_EXP_DEVSTA 10  
+#define PCI_EXP_DEVSTA_CED 0x01  
+#define PCI_EXP_DEVSTA_NFED 0x02  
+#define PCI_EXP_DEVSTA_FED 0x04  
+#define PCI_EXP_DEVSTA_URD 0x08  
+#define PCI_EXP_DEVSTA_AUXPD 0x10  
+#define PCI_EXP_DEVSTA_TRPND 0x20  
+#define PCI_EXP_LNKCAP 12  
+#define PCI_EXP_LNKCTL 16  
+#define PCI_EXP_LNKSTA 18  
+#define PCI_EXP_SLTCAP 20  
+#define PCI_EXP_SLTCTL 24  
+#define PCI_EXP_SLTSTA 26  
+#define PCI_EXP_RTCTL 28  
+#define PCI_EXP_RTCTL_SECEE 0x01  
+#define PCI_EXP_RTCTL_SENFEE 0x02  
+#define PCI_EXP_RTCTL_SEFEE 0x04  
+#define PCI_EXP_RTCTL_PMEIE 0x08  
+#define PCI_EXP_RTCTL_CRSSVE 0x10  
+#define PCI_EXP_RTCAP 30  
+#define PCI_EXP_RTSTA 32  
+
+#define PCI_EXT_CAP_ID(header) (header & 0x0000ffff)
+#define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf)
+#define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc)
+
+#define PCI_EXT_CAP_ID_ERR 1
+#define PCI_EXT_CAP_ID_VC 2
+#define PCI_EXT_CAP_ID_DSN 3
+#define PCI_EXT_CAP_ID_PWR 4
+
+#define PCI_ERR_UNCOR_STATUS 4  
+#define PCI_ERR_UNC_TRAIN 0x00000001  
+#define PCI_ERR_UNC_DLP 0x00000010  
+#define PCI_ERR_UNC_POISON_TLP 0x00001000  
+#define PCI_ERR_UNC_FCP 0x00002000  
+#define PCI_ERR_UNC_COMP_TIME 0x00004000  
+#define PCI_ERR_UNC_COMP_ABORT 0x00008000  
+#define PCI_ERR_UNC_UNX_COMP 0x00010000  
+#define PCI_ERR_UNC_RX_OVER 0x00020000  
+#define PCI_ERR_UNC_MALF_TLP 0x00040000  
+#define PCI_ERR_UNC_ECRC 0x00080000  
+#define PCI_ERR_UNC_UNSUP 0x00100000  
+#define PCI_ERR_UNCOR_MASK 8  
+
+#define PCI_ERR_UNCOR_SEVER 12  
+
+#define PCI_ERR_COR_STATUS 16  
+#define PCI_ERR_COR_RCVR 0x00000001  
+#define PCI_ERR_COR_BAD_TLP 0x00000040  
+#define PCI_ERR_COR_BAD_DLLP 0x00000080  
+#define PCI_ERR_COR_REP_ROLL 0x00000100  
+#define PCI_ERR_COR_REP_TIMER 0x00001000  
+#define PCI_ERR_COR_MASK 20  
+
+#define PCI_ERR_CAP 24  
+#define PCI_ERR_CAP_FEP(x) ((x) & 31)  
+#define PCI_ERR_CAP_ECRC_GENC 0x00000020  
+#define PCI_ERR_CAP_ECRC_GENE 0x00000040  
+#define PCI_ERR_CAP_ECRC_CHKC 0x00000080  
+#define PCI_ERR_CAP_ECRC_CHKE 0x00000100  
+#define PCI_ERR_HEADER_LOG 28  
+#define PCI_ERR_ROOT_COMMAND 44  
+
+#define PCI_ERR_ROOT_CMD_COR_EN 0x00000001
+
+#define PCI_ERR_ROOT_CMD_NONFATAL_EN 0x00000002
+
+#define PCI_ERR_ROOT_CMD_FATAL_EN 0x00000004
+#define PCI_ERR_ROOT_STATUS 48
+#define PCI_ERR_ROOT_COR_RCV 0x00000001  
+
+#define PCI_ERR_ROOT_MULTI_COR_RCV 0x00000002
+
+#define PCI_ERR_ROOT_UNCOR_RCV 0x00000004
+
+#define PCI_ERR_ROOT_MULTI_UNCOR_RCV 0x00000008
+#define PCI_ERR_ROOT_FIRST_FATAL 0x00000010  
+#define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020  
+#define PCI_ERR_ROOT_FATAL_RCV 0x00000040  
+#define PCI_ERR_ROOT_COR_SRC 52
+#define PCI_ERR_ROOT_SRC 54
+
+#define PCI_VC_PORT_REG1 4
+#define PCI_VC_PORT_REG2 8
+#define PCI_VC_PORT_CTRL 12
+#define PCI_VC_PORT_STATUS 14
+#define PCI_VC_RES_CAP 16
+#define PCI_VC_RES_CTRL 20
+#define PCI_VC_RES_STATUS 26
+
+#define PCI_PWR_DSR 4  
+#define PCI_PWR_DATA 8  
+#define PCI_PWR_DATA_BASE(x) ((x) & 0xff)  
+#define PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3)  
+#define PCI_PWR_DATA_PM_SUB(x) (((x) >> 10) & 7)  
+#define PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3)  
+#define PCI_PWR_DATA_TYPE(x) (((x) >> 15) & 7)  
+#define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7)  
+#define PCI_PWR_CAP 12  
+#define PCI_PWR_CAP_BUDGET(x) ((x) & 1)  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/percpu.h b/ndk/build/platforms/android-1.5/common/include/linux/percpu.h
new file mode 100644
index 0000000..c195616
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/percpu.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_PERCPU_H
+#define __LINUX_PERCPU_H
+#include <linux/spinlock.h>  
+#include <linux/slab.h>  
+#include <linux/smp.h>
+#include <linux/string.h>  
+#include <asm/percpu.h>
+
+#ifndef PERCPU_ENOUGH_ROOM
+#define PERCPU_ENOUGH_ROOM 32768
+#endif
+
+#define get_cpu_var(var) (*({ preempt_disable(); &__get_cpu_var(var); }))
+#define put_cpu_var(var) preempt_enable()
+
+#define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); })
+
+#define alloc_percpu(type) ((type *)(__alloc_percpu(sizeof(type))))
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/percpu_counter.h b/ndk/build/platforms/android-1.5/common/include/linux/percpu_counter.h
new file mode 100644
index 0000000..112375c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/percpu_counter.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_PERCPU_COUNTER_H
+#define _LINUX_PERCPU_COUNTER_H
+
+#include <linux/spinlock.h>
+#include <linux/smp.h>
+#include <linux/threads.h>
+#include <linux/percpu.h>
+#include <linux/types.h>
+
+struct percpu_counter {
+ s64 count;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/personality.h b/ndk/build/platforms/android-1.5/common/include/linux/personality.h
new file mode 100644
index 0000000..1f84b4e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/personality.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_PERSONALITY_H
+#define _LINUX_PERSONALITY_H
+
+struct exec_domain;
+struct pt_regs;
+
+enum {
+ ADDR_NO_RANDOMIZE = 0x0040000,
+ FDPIC_FUNCPTRS = 0x0080000,
+ MMAP_PAGE_ZERO = 0x0100000,
+ ADDR_COMPAT_LAYOUT = 0x0200000,
+ READ_IMPLIES_EXEC = 0x0400000,
+ ADDR_LIMIT_32BIT = 0x0800000,
+ SHORT_INODE = 0x1000000,
+ WHOLE_SECONDS = 0x2000000,
+ STICKY_TIMEOUTS = 0x4000000,
+ ADDR_LIMIT_3GB = 0x8000000,
+};
+
+#define PER_CLEAR_ON_SETID (READ_IMPLIES_EXEC|ADDR_NO_RANDOMIZE)
+
+enum {
+ PER_LINUX = 0x0000,
+ PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT,
+ PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS,
+ PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
+ PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE,
+ PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS |
+ WHOLE_SECONDS | SHORT_INODE,
+ PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS,
+ PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE,
+ PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS,
+ PER_BSD = 0x0006,
+ PER_SUNOS = 0x0006 | STICKY_TIMEOUTS,
+ PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE,
+ PER_LINUX32 = 0x0008,
+ PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB,
+ PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,
+ PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,
+ PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,
+ PER_RISCOS = 0x000c,
+ PER_SOLARIS = 0x000d | STICKY_TIMEOUTS,
+ PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
+ PER_OSF4 = 0x000f,
+ PER_HPUX = 0x0010,
+ PER_MASK = 0x00ff,
+};
+
+typedef void (*handler_t)(int, struct pt_regs *);
+
+struct exec_domain {
+ const char *name;
+ handler_t handler;
+ unsigned char pers_low;
+ unsigned char pers_high;
+ unsigned long *signal_map;
+ unsigned long *signal_invmap;
+ struct map_segment *err_map;
+ struct map_segment *socktype_map;
+ struct map_segment *sockopt_map;
+ struct map_segment *af_map;
+ struct module *module;
+ struct exec_domain *next;
+};
+
+#define personality(pers) (pers & PER_MASK)
+
+#define get_personality (current->personality)
+
+#define set_personality(pers)   ((current->personality == pers) ? 0 : __set_personality(pers))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/pfkeyv2.h b/ndk/build/platforms/android-1.5/common/include/linux/pfkeyv2.h
new file mode 100644
index 0000000..3ac9488
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/pfkeyv2.h
@@ -0,0 +1,306 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_PFKEY2_H
+#define _LINUX_PFKEY2_H
+
+#include <linux/types.h>
+
+#define PF_KEY_V2 2
+#define PFKEYV2_REVISION 199806L
+
+struct sadb_msg {
+ uint8_t sadb_msg_version;
+ uint8_t sadb_msg_type;
+ uint8_t sadb_msg_errno;
+ uint8_t sadb_msg_satype;
+ uint16_t sadb_msg_len;
+ uint16_t sadb_msg_reserved;
+ uint32_t sadb_msg_seq;
+ uint32_t sadb_msg_pid;
+} __attribute__((packed));
+
+struct sadb_ext {
+ uint16_t sadb_ext_len;
+ uint16_t sadb_ext_type;
+} __attribute__((packed));
+
+struct sadb_sa {
+ uint16_t sadb_sa_len;
+ uint16_t sadb_sa_exttype;
+ uint32_t sadb_sa_spi;
+ uint8_t sadb_sa_replay;
+ uint8_t sadb_sa_state;
+ uint8_t sadb_sa_auth;
+ uint8_t sadb_sa_encrypt;
+ uint32_t sadb_sa_flags;
+} __attribute__((packed));
+
+struct sadb_lifetime {
+ uint16_t sadb_lifetime_len;
+ uint16_t sadb_lifetime_exttype;
+ uint32_t sadb_lifetime_allocations;
+ uint64_t sadb_lifetime_bytes;
+ uint64_t sadb_lifetime_addtime;
+ uint64_t sadb_lifetime_usetime;
+} __attribute__((packed));
+
+struct sadb_address {
+ uint16_t sadb_address_len;
+ uint16_t sadb_address_exttype;
+ uint8_t sadb_address_proto;
+ uint8_t sadb_address_prefixlen;
+ uint16_t sadb_address_reserved;
+} __attribute__((packed));
+
+struct sadb_key {
+ uint16_t sadb_key_len;
+ uint16_t sadb_key_exttype;
+ uint16_t sadb_key_bits;
+ uint16_t sadb_key_reserved;
+} __attribute__((packed));
+
+struct sadb_ident {
+ uint16_t sadb_ident_len;
+ uint16_t sadb_ident_exttype;
+ uint16_t sadb_ident_type;
+ uint16_t sadb_ident_reserved;
+ uint64_t sadb_ident_id;
+} __attribute__((packed));
+
+struct sadb_sens {
+ uint16_t sadb_sens_len;
+ uint16_t sadb_sens_exttype;
+ uint32_t sadb_sens_dpd;
+ uint8_t sadb_sens_sens_level;
+ uint8_t sadb_sens_sens_len;
+ uint8_t sadb_sens_integ_level;
+ uint8_t sadb_sens_integ_len;
+ uint32_t sadb_sens_reserved;
+} __attribute__((packed));
+
+struct sadb_prop {
+ uint16_t sadb_prop_len;
+ uint16_t sadb_prop_exttype;
+ uint8_t sadb_prop_replay;
+ uint8_t sadb_prop_reserved[3];
+} __attribute__((packed));
+
+struct sadb_comb {
+ uint8_t sadb_comb_auth;
+ uint8_t sadb_comb_encrypt;
+ uint16_t sadb_comb_flags;
+ uint16_t sadb_comb_auth_minbits;
+ uint16_t sadb_comb_auth_maxbits;
+ uint16_t sadb_comb_encrypt_minbits;
+ uint16_t sadb_comb_encrypt_maxbits;
+ uint32_t sadb_comb_reserved;
+ uint32_t sadb_comb_soft_allocations;
+ uint32_t sadb_comb_hard_allocations;
+ uint64_t sadb_comb_soft_bytes;
+ uint64_t sadb_comb_hard_bytes;
+ uint64_t sadb_comb_soft_addtime;
+ uint64_t sadb_comb_hard_addtime;
+ uint64_t sadb_comb_soft_usetime;
+ uint64_t sadb_comb_hard_usetime;
+} __attribute__((packed));
+
+struct sadb_supported {
+ uint16_t sadb_supported_len;
+ uint16_t sadb_supported_exttype;
+ uint32_t sadb_supported_reserved;
+} __attribute__((packed));
+
+struct sadb_alg {
+ uint8_t sadb_alg_id;
+ uint8_t sadb_alg_ivlen;
+ uint16_t sadb_alg_minbits;
+ uint16_t sadb_alg_maxbits;
+ uint16_t sadb_alg_reserved;
+} __attribute__((packed));
+
+struct sadb_spirange {
+ uint16_t sadb_spirange_len;
+ uint16_t sadb_spirange_exttype;
+ uint32_t sadb_spirange_min;
+ uint32_t sadb_spirange_max;
+ uint32_t sadb_spirange_reserved;
+} __attribute__((packed));
+
+struct sadb_x_kmprivate {
+ uint16_t sadb_x_kmprivate_len;
+ uint16_t sadb_x_kmprivate_exttype;
+ uint32_t sadb_x_kmprivate_reserved;
+} __attribute__((packed));
+
+struct sadb_x_sa2 {
+ uint16_t sadb_x_sa2_len;
+ uint16_t sadb_x_sa2_exttype;
+ uint8_t sadb_x_sa2_mode;
+ uint8_t sadb_x_sa2_reserved1;
+ uint16_t sadb_x_sa2_reserved2;
+ uint32_t sadb_x_sa2_sequence;
+ uint32_t sadb_x_sa2_reqid;
+} __attribute__((packed));
+
+struct sadb_x_policy {
+ uint16_t sadb_x_policy_len;
+ uint16_t sadb_x_policy_exttype;
+ uint16_t sadb_x_policy_type;
+ uint8_t sadb_x_policy_dir;
+ uint8_t sadb_x_policy_reserved;
+ uint32_t sadb_x_policy_id;
+ uint32_t sadb_x_policy_priority;
+} __attribute__((packed));
+
+struct sadb_x_ipsecrequest {
+ uint16_t sadb_x_ipsecrequest_len;
+ uint16_t sadb_x_ipsecrequest_proto;
+ uint8_t sadb_x_ipsecrequest_mode;
+ uint8_t sadb_x_ipsecrequest_level;
+ uint16_t sadb_x_ipsecrequest_reserved1;
+ uint32_t sadb_x_ipsecrequest_reqid;
+ uint32_t sadb_x_ipsecrequest_reserved2;
+} __attribute__((packed));
+
+struct sadb_x_nat_t_type {
+ uint16_t sadb_x_nat_t_type_len;
+ uint16_t sadb_x_nat_t_type_exttype;
+ uint8_t sadb_x_nat_t_type_type;
+ uint8_t sadb_x_nat_t_type_reserved[3];
+} __attribute__((packed));
+
+struct sadb_x_nat_t_port {
+ uint16_t sadb_x_nat_t_port_len;
+ uint16_t sadb_x_nat_t_port_exttype;
+ uint16_t sadb_x_nat_t_port_port;
+ uint16_t sadb_x_nat_t_port_reserved;
+} __attribute__((packed));
+
+struct sadb_x_sec_ctx {
+ uint16_t sadb_x_sec_len;
+ uint16_t sadb_x_sec_exttype;
+ uint8_t sadb_x_ctx_alg;
+ uint8_t sadb_x_ctx_doi;
+ uint16_t sadb_x_ctx_len;
+} __attribute__((packed));
+
+#define SADB_RESERVED 0
+#define SADB_GETSPI 1
+#define SADB_UPDATE 2
+#define SADB_ADD 3
+#define SADB_DELETE 4
+#define SADB_GET 5
+#define SADB_ACQUIRE 6
+#define SADB_REGISTER 7
+#define SADB_EXPIRE 8
+#define SADB_FLUSH 9
+#define SADB_DUMP 10
+#define SADB_X_PROMISC 11
+#define SADB_X_PCHANGE 12
+#define SADB_X_SPDUPDATE 13
+#define SADB_X_SPDADD 14
+#define SADB_X_SPDDELETE 15
+#define SADB_X_SPDGET 16
+#define SADB_X_SPDACQUIRE 17
+#define SADB_X_SPDDUMP 18
+#define SADB_X_SPDFLUSH 19
+#define SADB_X_SPDSETIDX 20
+#define SADB_X_SPDEXPIRE 21
+#define SADB_X_SPDDELETE2 22
+#define SADB_X_NAT_T_NEW_MAPPING 23
+#define SADB_MAX 23
+
+#define SADB_SAFLAGS_PFS 1
+#define SADB_SAFLAGS_NOPMTUDISC 0x20000000
+#define SADB_SAFLAGS_DECAP_DSCP 0x40000000
+#define SADB_SAFLAGS_NOECN 0x80000000
+
+#define SADB_SASTATE_LARVAL 0
+#define SADB_SASTATE_MATURE 1
+#define SADB_SASTATE_DYING 2
+#define SADB_SASTATE_DEAD 3
+#define SADB_SASTATE_MAX 3
+
+#define SADB_SATYPE_UNSPEC 0
+#define SADB_SATYPE_AH 2
+#define SADB_SATYPE_ESP 3
+#define SADB_SATYPE_RSVP 5
+#define SADB_SATYPE_OSPFV2 6
+#define SADB_SATYPE_RIPV2 7
+#define SADB_SATYPE_MIP 8
+#define SADB_X_SATYPE_IPCOMP 9
+#define SADB_SATYPE_MAX 9
+
+#define SADB_AALG_NONE 0
+#define SADB_AALG_MD5HMAC 2
+#define SADB_AALG_SHA1HMAC 3
+#define SADB_X_AALG_SHA2_256HMAC 5
+#define SADB_X_AALG_SHA2_384HMAC 6
+#define SADB_X_AALG_SHA2_512HMAC 7
+#define SADB_X_AALG_RIPEMD160HMAC 8
+#define SADB_X_AALG_NULL 251  
+#define SADB_AALG_MAX 251
+
+#define SADB_EALG_NONE 0
+#define SADB_EALG_DESCBC 2
+#define SADB_EALG_3DESCBC 3
+#define SADB_X_EALG_CASTCBC 6
+#define SADB_X_EALG_BLOWFISHCBC 7
+#define SADB_EALG_NULL 11
+#define SADB_X_EALG_AESCBC 12
+#define SADB_EALG_MAX 253  
+
+#define SADB_X_EALG_SERPENTCBC 252  
+#define SADB_X_EALG_TWOFISHCBC 253  
+
+#define SADB_X_CALG_NONE 0
+#define SADB_X_CALG_OUI 1
+#define SADB_X_CALG_DEFLATE 2
+#define SADB_X_CALG_LZS 3
+#define SADB_X_CALG_LZJH 4
+#define SADB_X_CALG_MAX 4
+
+#define SADB_EXT_RESERVED 0
+#define SADB_EXT_SA 1
+#define SADB_EXT_LIFETIME_CURRENT 2
+#define SADB_EXT_LIFETIME_HARD 3
+#define SADB_EXT_LIFETIME_SOFT 4
+#define SADB_EXT_ADDRESS_SRC 5
+#define SADB_EXT_ADDRESS_DST 6
+#define SADB_EXT_ADDRESS_PROXY 7
+#define SADB_EXT_KEY_AUTH 8
+#define SADB_EXT_KEY_ENCRYPT 9
+#define SADB_EXT_IDENTITY_SRC 10
+#define SADB_EXT_IDENTITY_DST 11
+#define SADB_EXT_SENSITIVITY 12
+#define SADB_EXT_PROPOSAL 13
+#define SADB_EXT_SUPPORTED_AUTH 14
+#define SADB_EXT_SUPPORTED_ENCRYPT 15
+#define SADB_EXT_SPIRANGE 16
+#define SADB_X_EXT_KMPRIVATE 17
+#define SADB_X_EXT_POLICY 18
+#define SADB_X_EXT_SA2 19
+
+#define SADB_X_EXT_NAT_T_TYPE 20
+#define SADB_X_EXT_NAT_T_SPORT 21
+#define SADB_X_EXT_NAT_T_DPORT 22
+#define SADB_X_EXT_NAT_T_OA 23
+#define SADB_X_EXT_SEC_CTX 24
+#define SADB_EXT_MAX 24
+
+#define SADB_IDENTTYPE_RESERVED 0
+#define SADB_IDENTTYPE_PREFIX 1
+#define SADB_IDENTTYPE_FQDN 2
+#define SADB_IDENTTYPE_USERFQDN 3
+#define SADB_IDENTTYPE_MAX 3
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/pkt_cls.h b/ndk/build/platforms/android-1.5/common/include/linux/pkt_cls.h
new file mode 100644
index 0000000..601a683
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/pkt_cls.h
@@ -0,0 +1,372 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_PKT_CLS_H
+#define __LINUX_PKT_CLS_H
+
+#include <linux/pkt_sched.h>
+
+#define _TC_MAKE32(x) ((x))
+
+#define _TC_MAKEMASK1(n) (_TC_MAKE32(1) << _TC_MAKE32(n))
+#define _TC_MAKEMASK(v,n) (_TC_MAKE32((_TC_MAKE32(1)<<(v))-1) << _TC_MAKE32(n))
+#define _TC_MAKEVALUE(v,n) (_TC_MAKE32(v) << _TC_MAKE32(n))
+#define _TC_GETVALUE(v,n,m) ((_TC_MAKE32(v) & _TC_MAKE32(m)) >> _TC_MAKE32(n))
+
+#define TC_MUNGED _TC_MAKEMASK1(0)
+#define SET_TC_MUNGED(v) ( TC_MUNGED | (v & ~TC_MUNGED))
+#define CLR_TC_MUNGED(v) ( v & ~TC_MUNGED)
+
+#define TC_OK2MUNGE _TC_MAKEMASK1(1)
+#define SET_TC_OK2MUNGE(v) ( TC_OK2MUNGE | (v & ~TC_OK2MUNGE))
+#define CLR_TC_OK2MUNGE(v) ( v & ~TC_OK2MUNGE)
+
+#define S_TC_VERD _TC_MAKE32(2)
+#define M_TC_VERD _TC_MAKEMASK(4,S_TC_VERD)
+#define G_TC_VERD(x) _TC_GETVALUE(x,S_TC_VERD,M_TC_VERD)
+#define V_TC_VERD(x) _TC_MAKEVALUE(x,S_TC_VERD)
+#define SET_TC_VERD(v,n) ((V_TC_VERD(n)) | (v & ~M_TC_VERD))
+
+#define S_TC_FROM _TC_MAKE32(6)
+#define M_TC_FROM _TC_MAKEMASK(2,S_TC_FROM)
+#define G_TC_FROM(x) _TC_GETVALUE(x,S_TC_FROM,M_TC_FROM)
+#define V_TC_FROM(x) _TC_MAKEVALUE(x,S_TC_FROM)
+#define SET_TC_FROM(v,n) ((V_TC_FROM(n)) | (v & ~M_TC_FROM))
+#define AT_STACK 0x0
+#define AT_INGRESS 0x1
+#define AT_EGRESS 0x2
+
+#define TC_NCLS _TC_MAKEMASK1(8)
+#define SET_TC_NCLS(v) ( TC_NCLS | (v & ~TC_NCLS))
+#define CLR_TC_NCLS(v) ( v & ~TC_NCLS)
+
+#define S_TC_RTTL _TC_MAKE32(9)
+#define M_TC_RTTL _TC_MAKEMASK(3,S_TC_RTTL)
+#define G_TC_RTTL(x) _TC_GETVALUE(x,S_TC_RTTL,M_TC_RTTL)
+#define V_TC_RTTL(x) _TC_MAKEVALUE(x,S_TC_RTTL)
+#define SET_TC_RTTL(v,n) ((V_TC_RTTL(n)) | (v & ~M_TC_RTTL))
+
+#define S_TC_AT _TC_MAKE32(12)
+#define M_TC_AT _TC_MAKEMASK(2,S_TC_AT)
+#define G_TC_AT(x) _TC_GETVALUE(x,S_TC_AT,M_TC_AT)
+#define V_TC_AT(x) _TC_MAKEVALUE(x,S_TC_AT)
+#define SET_TC_AT(v,n) ((V_TC_AT(n)) | (v & ~M_TC_AT))
+
+enum
+{
+ TCA_ACT_UNSPEC,
+ TCA_ACT_KIND,
+ TCA_ACT_OPTIONS,
+ TCA_ACT_INDEX,
+ TCA_ACT_STATS,
+ __TCA_ACT_MAX
+};
+
+#define TCA_ACT_MAX __TCA_ACT_MAX
+#define TCA_OLD_COMPAT (TCA_ACT_MAX+1)
+#define TCA_ACT_MAX_PRIO 32
+#define TCA_ACT_BIND 1
+#define TCA_ACT_NOBIND 0
+#define TCA_ACT_UNBIND 1
+#define TCA_ACT_NOUNBIND 0
+#define TCA_ACT_REPLACE 1
+#define TCA_ACT_NOREPLACE 0
+#define MAX_REC_LOOP 4
+#define MAX_RED_LOOP 4
+
+#define TC_ACT_UNSPEC (-1)
+#define TC_ACT_OK 0
+#define TC_ACT_RECLASSIFY 1
+#define TC_ACT_SHOT 2
+#define TC_ACT_PIPE 3
+#define TC_ACT_STOLEN 4
+#define TC_ACT_QUEUED 5
+#define TC_ACT_REPEAT 6
+#define TC_ACT_JUMP 0x10000000
+
+enum
+{
+ TCA_ID_UNSPEC=0,
+ TCA_ID_POLICE=1,
+
+ __TCA_ID_MAX=255
+};
+
+#define TCA_ID_MAX __TCA_ID_MAX
+
+struct tc_police
+{
+ __u32 index;
+ int action;
+#define TC_POLICE_UNSPEC TC_ACT_UNSPEC
+#define TC_POLICE_OK TC_ACT_OK
+#define TC_POLICE_RECLASSIFY TC_ACT_RECLASSIFY
+#define TC_POLICE_SHOT TC_ACT_SHOT
+#define TC_POLICE_PIPE TC_ACT_PIPE
+
+ __u32 limit;
+ __u32 burst;
+ __u32 mtu;
+ struct tc_ratespec rate;
+ struct tc_ratespec peakrate;
+ int refcnt;
+ int bindcnt;
+ __u32 capab;
+};
+
+struct tcf_t
+{
+ __u64 install;
+ __u64 lastuse;
+ __u64 expires;
+};
+
+struct tc_cnt
+{
+ int refcnt;
+ int bindcnt;
+};
+
+#define tc_gen   __u32 index;   __u32 capab;   int action;   int refcnt;   int bindcnt
+
+enum
+{
+ TCA_POLICE_UNSPEC,
+ TCA_POLICE_TBF,
+ TCA_POLICE_RATE,
+ TCA_POLICE_PEAKRATE,
+ TCA_POLICE_AVRATE,
+ TCA_POLICE_RESULT,
+ __TCA_POLICE_MAX
+#define TCA_POLICE_RESULT TCA_POLICE_RESULT
+};
+
+#define TCA_POLICE_MAX (__TCA_POLICE_MAX - 1)
+
+#define TC_U32_HTID(h) ((h)&0xFFF00000)
+#define TC_U32_USERHTID(h) (TC_U32_HTID(h)>>20)
+#define TC_U32_HASH(h) (((h)>>12)&0xFF)
+#define TC_U32_NODE(h) ((h)&0xFFF)
+#define TC_U32_KEY(h) ((h)&0xFFFFF)
+#define TC_U32_UNSPEC 0
+#define TC_U32_ROOT (0xFFF00000)
+
+enum
+{
+ TCA_U32_UNSPEC,
+ TCA_U32_CLASSID,
+ TCA_U32_HASH,
+ TCA_U32_LINK,
+ TCA_U32_DIVISOR,
+ TCA_U32_SEL,
+ TCA_U32_POLICE,
+ TCA_U32_ACT,
+ TCA_U32_INDEV,
+ TCA_U32_PCNT,
+ TCA_U32_MARK,
+ __TCA_U32_MAX
+};
+
+#define TCA_U32_MAX (__TCA_U32_MAX - 1)
+
+struct tc_u32_key
+{
+ __u32 mask;
+ __u32 val;
+ int off;
+ int offmask;
+};
+
+struct tc_u32_sel
+{
+ unsigned char flags;
+ unsigned char offshift;
+ unsigned char nkeys;
+
+ __u16 offmask;
+ __u16 off;
+ short offoff;
+
+ short hoff;
+ __u32 hmask;
+ struct tc_u32_key keys[0];
+};
+
+struct tc_u32_mark
+{
+ __u32 val;
+ __u32 mask;
+ __u32 success;
+};
+
+struct tc_u32_pcnt
+{
+ __u64 rcnt;
+ __u64 rhit;
+ __u64 kcnts[0];
+};
+
+#define TC_U32_TERMINAL 1
+#define TC_U32_OFFSET 2
+#define TC_U32_VAROFFSET 4
+#define TC_U32_EAT 8
+
+#define TC_U32_MAXDEPTH 8
+
+enum
+{
+ TCA_RSVP_UNSPEC,
+ TCA_RSVP_CLASSID,
+ TCA_RSVP_DST,
+ TCA_RSVP_SRC,
+ TCA_RSVP_PINFO,
+ TCA_RSVP_POLICE,
+ TCA_RSVP_ACT,
+ __TCA_RSVP_MAX
+};
+
+#define TCA_RSVP_MAX (__TCA_RSVP_MAX - 1 )
+
+struct tc_rsvp_gpi
+{
+ __u32 key;
+ __u32 mask;
+ int offset;
+};
+
+struct tc_rsvp_pinfo
+{
+ struct tc_rsvp_gpi dpi;
+ struct tc_rsvp_gpi spi;
+ __u8 protocol;
+ __u8 tunnelid;
+ __u8 tunnelhdr;
+ __u8 pad;
+};
+
+enum
+{
+ TCA_ROUTE4_UNSPEC,
+ TCA_ROUTE4_CLASSID,
+ TCA_ROUTE4_TO,
+ TCA_ROUTE4_FROM,
+ TCA_ROUTE4_IIF,
+ TCA_ROUTE4_POLICE,
+ TCA_ROUTE4_ACT,
+ __TCA_ROUTE4_MAX
+};
+
+#define TCA_ROUTE4_MAX (__TCA_ROUTE4_MAX - 1)
+
+enum
+{
+ TCA_FW_UNSPEC,
+ TCA_FW_CLASSID,
+ TCA_FW_POLICE,
+ TCA_FW_INDEV,
+ TCA_FW_ACT,
+ __TCA_FW_MAX
+};
+
+#define TCA_FW_MAX (__TCA_FW_MAX - 1)
+
+enum
+{
+ TCA_TCINDEX_UNSPEC,
+ TCA_TCINDEX_HASH,
+ TCA_TCINDEX_MASK,
+ TCA_TCINDEX_SHIFT,
+ TCA_TCINDEX_FALL_THROUGH,
+ TCA_TCINDEX_CLASSID,
+ TCA_TCINDEX_POLICE,
+ TCA_TCINDEX_ACT,
+ __TCA_TCINDEX_MAX
+};
+
+#define TCA_TCINDEX_MAX (__TCA_TCINDEX_MAX - 1)
+
+enum
+{
+ TCA_BASIC_UNSPEC,
+ TCA_BASIC_CLASSID,
+ TCA_BASIC_EMATCHES,
+ TCA_BASIC_ACT,
+ TCA_BASIC_POLICE,
+ __TCA_BASIC_MAX
+};
+
+#define TCA_BASIC_MAX (__TCA_BASIC_MAX - 1)
+
+struct tcf_ematch_tree_hdr
+{
+ __u16 nmatches;
+ __u16 progid;
+};
+
+enum
+{
+ TCA_EMATCH_TREE_UNSPEC,
+ TCA_EMATCH_TREE_HDR,
+ TCA_EMATCH_TREE_LIST,
+ __TCA_EMATCH_TREE_MAX
+};
+#define TCA_EMATCH_TREE_MAX (__TCA_EMATCH_TREE_MAX - 1)
+
+struct tcf_ematch_hdr
+{
+ __u16 matchid;
+ __u16 kind;
+ __u16 flags;
+ __u16 pad;
+};
+
+#define TCF_EM_REL_END 0
+#define TCF_EM_REL_AND (1<<0)
+#define TCF_EM_REL_OR (1<<1)
+#define TCF_EM_INVERT (1<<2)
+#define TCF_EM_SIMPLE (1<<3)
+
+#define TCF_EM_REL_MASK 3
+#define TCF_EM_REL_VALID(v) (((v) & TCF_EM_REL_MASK) != TCF_EM_REL_MASK)
+
+enum
+{
+ TCF_LAYER_LINK,
+ TCF_LAYER_NETWORK,
+ TCF_LAYER_TRANSPORT,
+ __TCF_LAYER_MAX
+};
+#define TCF_LAYER_MAX (__TCF_LAYER_MAX - 1)
+
+enum
+{
+ TCF_EM_CONTAINER,
+ TCF_EM_CMP,
+ TCF_EM_NBYTE,
+ TCF_EM_U32,
+ TCF_EM_META,
+ TCF_EM_TEXT,
+ __TCF_EM_MAX
+};
+
+enum
+{
+ TCF_EM_PROG_TC
+};
+
+enum
+{
+ TCF_EM_OPND_EQ,
+ TCF_EM_OPND_GT,
+ TCF_EM_OPND_LT
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/pkt_sched.h b/ndk/build/platforms/android-1.5/common/include/linux/pkt_sched.h
new file mode 100644
index 0000000..1e15d83
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/pkt_sched.h
@@ -0,0 +1,405 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_PKT_SCHED_H
+#define __LINUX_PKT_SCHED_H
+
+#define TC_PRIO_BESTEFFORT 0
+#define TC_PRIO_FILLER 1
+#define TC_PRIO_BULK 2
+#define TC_PRIO_INTERACTIVE_BULK 4
+#define TC_PRIO_INTERACTIVE 6
+#define TC_PRIO_CONTROL 7
+
+#define TC_PRIO_MAX 15
+
+struct tc_stats
+{
+ __u64 bytes;
+ __u32 packets;
+ __u32 drops;
+ __u32 overlimits;
+ __u32 bps;
+ __u32 pps;
+ __u32 qlen;
+ __u32 backlog;
+};
+
+struct tc_estimator
+{
+ signed char interval;
+ unsigned char ewma_log;
+};
+
+#define TC_H_MAJ_MASK (0xFFFF0000U)
+#define TC_H_MIN_MASK (0x0000FFFFU)
+#define TC_H_MAJ(h) ((h)&TC_H_MAJ_MASK)
+#define TC_H_MIN(h) ((h)&TC_H_MIN_MASK)
+#define TC_H_MAKE(maj,min) (((maj)&TC_H_MAJ_MASK)|((min)&TC_H_MIN_MASK))
+
+#define TC_H_UNSPEC (0U)
+#define TC_H_ROOT (0xFFFFFFFFU)
+#define TC_H_INGRESS (0xFFFFFFF1U)
+
+struct tc_ratespec
+{
+ unsigned char cell_log;
+ unsigned char __reserved;
+ unsigned short feature;
+ short addend;
+ unsigned short mpu;
+ __u32 rate;
+};
+
+struct tc_fifo_qopt
+{
+ __u32 limit;
+};
+
+#define TCQ_PRIO_BANDS 16
+#define TCQ_MIN_PRIO_BANDS 2
+
+struct tc_prio_qopt
+{
+ int bands;
+ __u8 priomap[TC_PRIO_MAX+1];
+};
+
+struct tc_tbf_qopt
+{
+ struct tc_ratespec rate;
+ struct tc_ratespec peakrate;
+ __u32 limit;
+ __u32 buffer;
+ __u32 mtu;
+};
+
+enum
+{
+ TCA_TBF_UNSPEC,
+ TCA_TBF_PARMS,
+ TCA_TBF_RTAB,
+ TCA_TBF_PTAB,
+ __TCA_TBF_MAX,
+};
+
+#define TCA_TBF_MAX (__TCA_TBF_MAX - 1)
+
+struct tc_sfq_qopt
+{
+ unsigned quantum;
+ int perturb_period;
+ __u32 limit;
+ unsigned divisor;
+ unsigned flows;
+};
+
+enum
+{
+ TCA_RED_UNSPEC,
+ TCA_RED_PARMS,
+ TCA_RED_STAB,
+ __TCA_RED_MAX,
+};
+
+#define TCA_RED_MAX (__TCA_RED_MAX - 1)
+
+struct tc_red_qopt
+{
+ __u32 limit;
+ __u32 qth_min;
+ __u32 qth_max;
+ unsigned char Wlog;
+ unsigned char Plog;
+ unsigned char Scell_log;
+ unsigned char flags;
+#define TC_RED_ECN 1
+#define TC_RED_HARDDROP 2
+};
+
+struct tc_red_xstats
+{
+ __u32 early;
+ __u32 pdrop;
+ __u32 other;
+ __u32 marked;
+};
+
+#define MAX_DPs 16
+
+enum
+{
+ TCA_GRED_UNSPEC,
+ TCA_GRED_PARMS,
+ TCA_GRED_STAB,
+ TCA_GRED_DPS,
+ __TCA_GRED_MAX,
+};
+
+#define TCA_GRED_MAX (__TCA_GRED_MAX - 1)
+
+struct tc_gred_qopt
+{
+ __u32 limit;
+ __u32 qth_min;
+ __u32 qth_max;
+ __u32 DP;
+ __u32 backlog;
+ __u32 qave;
+ __u32 forced;
+ __u32 early;
+ __u32 other;
+ __u32 pdrop;
+ __u8 Wlog;
+ __u8 Plog;
+ __u8 Scell_log;
+ __u8 prio;
+ __u32 packets;
+ __u32 bytesin;
+};
+
+struct tc_gred_sopt
+{
+ __u32 DPs;
+ __u32 def_DP;
+ __u8 grio;
+ __u8 flags;
+ __u16 pad1;
+};
+
+#define TC_HTB_NUMPRIO 8
+#define TC_HTB_MAXDEPTH 8
+#define TC_HTB_PROTOVER 3  
+
+struct tc_htb_opt
+{
+ struct tc_ratespec rate;
+ struct tc_ratespec ceil;
+ __u32 buffer;
+ __u32 cbuffer;
+ __u32 quantum;
+ __u32 level;
+ __u32 prio;
+};
+struct tc_htb_glob
+{
+ __u32 version;
+ __u32 rate2quantum;
+ __u32 defcls;
+ __u32 debug;
+
+ __u32 direct_pkts;
+};
+enum
+{
+ TCA_HTB_UNSPEC,
+ TCA_HTB_PARMS,
+ TCA_HTB_INIT,
+ TCA_HTB_CTAB,
+ TCA_HTB_RTAB,
+ __TCA_HTB_MAX,
+};
+
+#define TCA_HTB_MAX (__TCA_HTB_MAX - 1)
+
+struct tc_htb_xstats
+{
+ __u32 lends;
+ __u32 borrows;
+ __u32 giants;
+ __u32 tokens;
+ __u32 ctokens;
+};
+
+struct tc_hfsc_qopt
+{
+ __u16 defcls;
+};
+
+struct tc_service_curve
+{
+ __u32 m1;
+ __u32 d;
+ __u32 m2;
+};
+
+struct tc_hfsc_stats
+{
+ __u64 work;
+ __u64 rtwork;
+ __u32 period;
+ __u32 level;
+};
+
+enum
+{
+ TCA_HFSC_UNSPEC,
+ TCA_HFSC_RSC,
+ TCA_HFSC_FSC,
+ TCA_HFSC_USC,
+ __TCA_HFSC_MAX,
+};
+
+#define TCA_HFSC_MAX (__TCA_HFSC_MAX - 1)
+
+#define TC_CBQ_MAXPRIO 8
+#define TC_CBQ_MAXLEVEL 8
+#define TC_CBQ_DEF_EWMA 5
+
+struct tc_cbq_lssopt
+{
+ unsigned char change;
+ unsigned char flags;
+#define TCF_CBQ_LSS_BOUNDED 1
+#define TCF_CBQ_LSS_ISOLATED 2
+ unsigned char ewma_log;
+ unsigned char level;
+#define TCF_CBQ_LSS_FLAGS 1
+#define TCF_CBQ_LSS_EWMA 2
+#define TCF_CBQ_LSS_MAXIDLE 4
+#define TCF_CBQ_LSS_MINIDLE 8
+#define TCF_CBQ_LSS_OFFTIME 0x10
+#define TCF_CBQ_LSS_AVPKT 0x20
+ __u32 maxidle;
+ __u32 minidle;
+ __u32 offtime;
+ __u32 avpkt;
+};
+
+struct tc_cbq_wrropt
+{
+ unsigned char flags;
+ unsigned char priority;
+ unsigned char cpriority;
+ unsigned char __reserved;
+ __u32 allot;
+ __u32 weight;
+};
+
+struct tc_cbq_ovl
+{
+ unsigned char strategy;
+#define TC_CBQ_OVL_CLASSIC 0
+#define TC_CBQ_OVL_DELAY 1
+#define TC_CBQ_OVL_LOWPRIO 2
+#define TC_CBQ_OVL_DROP 3
+#define TC_CBQ_OVL_RCLASSIC 4
+ unsigned char priority2;
+ __u16 pad;
+ __u32 penalty;
+};
+
+struct tc_cbq_police
+{
+ unsigned char police;
+ unsigned char __res1;
+ unsigned short __res2;
+};
+
+struct tc_cbq_fopt
+{
+ __u32 split;
+ __u32 defmap;
+ __u32 defchange;
+};
+
+struct tc_cbq_xstats
+{
+ __u32 borrows;
+ __u32 overactions;
+ __s32 avgidle;
+ __s32 undertime;
+};
+
+enum
+{
+ TCA_CBQ_UNSPEC,
+ TCA_CBQ_LSSOPT,
+ TCA_CBQ_WRROPT,
+ TCA_CBQ_FOPT,
+ TCA_CBQ_OVL_STRATEGY,
+ TCA_CBQ_RATE,
+ TCA_CBQ_RTAB,
+ TCA_CBQ_POLICE,
+ __TCA_CBQ_MAX,
+};
+
+#define TCA_CBQ_MAX (__TCA_CBQ_MAX - 1)
+
+enum {
+ TCA_DSMARK_UNSPEC,
+ TCA_DSMARK_INDICES,
+ TCA_DSMARK_DEFAULT_INDEX,
+ TCA_DSMARK_SET_TC_INDEX,
+ TCA_DSMARK_MASK,
+ TCA_DSMARK_VALUE,
+ __TCA_DSMARK_MAX,
+};
+
+#define TCA_DSMARK_MAX (__TCA_DSMARK_MAX - 1)
+
+enum {
+ TCA_ATM_UNSPEC,
+ TCA_ATM_FD,
+ TCA_ATM_PTR,
+ TCA_ATM_HDR,
+ TCA_ATM_EXCESS,
+ TCA_ATM_ADDR,
+ TCA_ATM_STATE,
+ __TCA_ATM_MAX,
+};
+
+#define TCA_ATM_MAX (__TCA_ATM_MAX - 1)
+
+enum
+{
+ TCA_NETEM_UNSPEC,
+ TCA_NETEM_CORR,
+ TCA_NETEM_DELAY_DIST,
+ TCA_NETEM_REORDER,
+ TCA_NETEM_CORRUPT,
+ __TCA_NETEM_MAX,
+};
+
+#define TCA_NETEM_MAX (__TCA_NETEM_MAX - 1)
+
+struct tc_netem_qopt
+{
+ __u32 latency;
+ __u32 limit;
+ __u32 loss;
+ __u32 gap;
+ __u32 duplicate;
+ __u32 jitter;
+};
+
+struct tc_netem_corr
+{
+ __u32 delay_corr;
+ __u32 loss_corr;
+ __u32 dup_corr;
+};
+
+struct tc_netem_reorder
+{
+ __u32 probability;
+ __u32 correlation;
+};
+
+struct tc_netem_corrupt
+{
+ __u32 probability;
+ __u32 correlation;
+};
+
+#define NETEM_DIST_SCALE 8192
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/platform_device.h b/ndk/build/platforms/android-1.5/common/include/linux/platform_device.h
new file mode 100644
index 0000000..a761b5b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/platform_device.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _PLATFORM_DEVICE_H_
+#define _PLATFORM_DEVICE_H_
+
+#include <linux/device.h>
+
+struct platform_device {
+ const char * name;
+ u32 id;
+ struct device dev;
+ u32 num_resources;
+ struct resource * resource;
+};
+
+#define to_platform_device(x) container_of((x), struct platform_device, dev)
+
+struct platform_driver {
+ int (*probe)(struct platform_device *);
+ int (*remove)(struct platform_device *);
+ void (*shutdown)(struct platform_device *);
+ int (*suspend)(struct platform_device *, pm_message_t state);
+ int (*resume)(struct platform_device *);
+ struct device_driver driver;
+};
+
+#define platform_get_drvdata(_dev) dev_get_drvdata(&(_dev)->dev)
+#define platform_set_drvdata(_dev,data) dev_set_drvdata(&(_dev)->dev, (data))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/plist.h b/ndk/build/platforms/android-1.5/common/include/linux/plist.h
new file mode 100644
index 0000000..5d65783
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/plist.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_PLIST_H_
+#define _LINUX_PLIST_H_
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/spinlock_types.h>
+
+struct plist_head {
+ struct list_head prio_list;
+ struct list_head node_list;
+};
+
+struct plist_node {
+ int prio;
+ struct plist_head plist;
+};
+
+#define PLIST_HEAD_LOCK_INIT(_lock)
+
+#define PLIST_HEAD_INIT(head, _lock)  {   .prio_list = LIST_HEAD_INIT((head).prio_list),   .node_list = LIST_HEAD_INIT((head).node_list),   PLIST_HEAD_LOCK_INIT(&(_lock))  }
+
+#define PLIST_NODE_INIT(node, __prio)  {   .prio = (__prio),   .plist = PLIST_HEAD_INIT((node).plist, NULL),  }
+
+#define plist_for_each(pos, head)   list_for_each_entry(pos, &(head)->node_list, plist.node_list)
+
+#define plist_for_each_safe(pos, n, head)   list_for_each_entry_safe(pos, n, &(head)->node_list, plist.node_list)
+
+#define plist_for_each_entry(pos, head, mem)   list_for_each_entry(pos, &(head)->node_list, mem.plist.node_list)
+
+#define plist_for_each_entry_safe(pos, n, head, m)   list_for_each_entry_safe(pos, n, &(head)->node_list, m.plist.node_list)
+
+#define plist_first_entry(head, type, member)   container_of(plist_first(head), type, member)
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/pm.h b/ndk/build/platforms/android-1.5/common/include/linux/pm.h
new file mode 100644
index 0000000..0548791
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/pm.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_PM_H
+#define _LINUX_PM_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/pnp.h b/ndk/build/platforms/android-1.5/common/include/linux/pnp.h
new file mode 100644
index 0000000..30b0af7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/pnp.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_PNP_H
+#define _LINUX_PNP_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/poll.h b/ndk/build/platforms/android-1.5/common/include/linux/poll.h
new file mode 100644
index 0000000..6822509
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/poll.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_POLL_H
+#define _LINUX_POLL_H
+
+#include <asm/poll.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/posix_acl.h b/ndk/build/platforms/android-1.5/common/include/linux/posix_acl.h
new file mode 100644
index 0000000..bdaee5b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/posix_acl.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_POSIX_ACL_H
+#define __LINUX_POSIX_ACL_H
+
+#include <linux/slab.h>
+
+#define ACL_UNDEFINED_ID (-1)
+
+#define ACL_TYPE_ACCESS (0x8000)
+#define ACL_TYPE_DEFAULT (0x4000)
+
+#define ACL_USER_OBJ (0x01)
+#define ACL_USER (0x02)
+#define ACL_GROUP_OBJ (0x04)
+#define ACL_GROUP (0x08)
+#define ACL_MASK (0x10)
+#define ACL_OTHER (0x20)
+
+#define ACL_READ (0x04)
+#define ACL_WRITE (0x02)
+#define ACL_EXECUTE (0x01)
+
+struct posix_acl_entry {
+ short e_tag;
+ unsigned short e_perm;
+ unsigned int e_id;
+};
+
+struct posix_acl {
+ atomic_t a_refcount;
+ unsigned int a_count;
+ struct posix_acl_entry a_entries[0];
+};
+
+#define FOREACH_ACL_ENTRY(pa, acl, pe)   for(pa=(acl)->a_entries, pe=pa+(acl)->a_count; pa<pe; pa++)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/posix_types.h b/ndk/build/platforms/android-1.5/common/include/linux/posix_types.h
new file mode 100644
index 0000000..d7d0ad2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/posix_types.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_POSIX_TYPES_H
+#define _LINUX_POSIX_TYPES_H
+
+#include <linux/stddef.h>
+
+#undef __NFDBITS
+#define __NFDBITS (8 * sizeof(unsigned long))
+
+#undef __FD_SETSIZE
+#define __FD_SETSIZE 1024
+
+#undef __FDSET_LONGS
+#define __FDSET_LONGS (__FD_SETSIZE/__NFDBITS)
+
+#undef __FDELT
+#define __FDELT(d) ((d) / __NFDBITS)
+
+#undef __FDMASK
+#define __FDMASK(d) (1UL << ((d) % __NFDBITS))
+
+typedef struct {
+ unsigned long fds_bits [__FDSET_LONGS];
+} __kernel_fd_set;
+
+typedef void (*__kernel_sighandler_t)(int);
+
+typedef int __kernel_key_t;
+typedef int __kernel_mqd_t;
+
+#include <asm/posix_types.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ppdev.h b/ndk/build/platforms/android-1.5/common/include/linux/ppdev.h
new file mode 100644
index 0000000..c43f8b9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ppdev.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#define PP_IOCTL 'p'
+
+#define PPSETMODE _IOW(PP_IOCTL, 0x80, int)
+
+#define PPRSTATUS _IOR(PP_IOCTL, 0x81, unsigned char)
+#define PPWSTATUS OBSOLETE__IOW(PP_IOCTL, 0x82, unsigned char)
+
+#define PPRCONTROL _IOR(PP_IOCTL, 0x83, unsigned char)
+#define PPWCONTROL _IOW(PP_IOCTL, 0x84, unsigned char)
+
+struct ppdev_frob_struct {
+ unsigned char mask;
+ unsigned char val;
+};
+#define PPFCONTROL _IOW(PP_IOCTL, 0x8e, struct ppdev_frob_struct)
+
+#define PPRDATA _IOR(PP_IOCTL, 0x85, unsigned char)
+#define PPWDATA _IOW(PP_IOCTL, 0x86, unsigned char)
+
+#define PPRECONTROL OBSOLETE__IOR(PP_IOCTL, 0x87, unsigned char)
+#define PPWECONTROL OBSOLETE__IOW(PP_IOCTL, 0x88, unsigned char)
+
+#define PPRFIFO OBSOLETE__IOR(PP_IOCTL, 0x89, unsigned char)
+#define PPWFIFO OBSOLETE__IOW(PP_IOCTL, 0x8a, unsigned char)
+
+#define PPCLAIM _IO(PP_IOCTL, 0x8b)
+
+#define PPRELEASE _IO(PP_IOCTL, 0x8c)
+
+#define PPYIELD _IO(PP_IOCTL, 0x8d)
+
+#define PPEXCL _IO(PP_IOCTL, 0x8f)
+
+#define PPDATADIR _IOW(PP_IOCTL, 0x90, int)
+
+#define PPNEGOT _IOW(PP_IOCTL, 0x91, int)
+
+#define PPWCTLONIRQ _IOW(PP_IOCTL, 0x92, unsigned char)
+
+#define PPCLRIRQ _IOR(PP_IOCTL, 0x93, int)
+
+#define PPSETPHASE _IOW(PP_IOCTL, 0x94, int)
+
+#define PPGETTIME _IOR(PP_IOCTL, 0x95, struct timeval)
+#define PPSETTIME _IOW(PP_IOCTL, 0x96, struct timeval)
+
+#define PPGETMODES _IOR(PP_IOCTL, 0x97, unsigned int)
+
+#define PPGETMODE _IOR(PP_IOCTL, 0x98, int)
+#define PPGETPHASE _IOR(PP_IOCTL, 0x99, int)
+
+#define PPGETFLAGS _IOR(PP_IOCTL, 0x9a, int)
+#define PPSETFLAGS _IOW(PP_IOCTL, 0x9b, int)
+
+#define PP_FASTWRITE (1<<2)
+#define PP_FASTREAD (1<<3)
+#define PP_W91284PIC (1<<4)
+
+#define PP_FLAGMASK (PP_FASTWRITE | PP_FASTREAD | PP_W91284PIC)
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ppp_defs.h b/ndk/build/platforms/android-1.5/common/include/linux/ppp_defs.h
new file mode 100644
index 0000000..da54ac7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ppp_defs.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _PPP_DEFS_H_
+#define _PPP_DEFS_H_
+
+#define PPP_HDRLEN 4  
+#define PPP_FCSLEN 2  
+#define PPP_MRU 1500  
+
+#define PPP_ADDRESS(p) (((__u8 *)(p))[0])
+#define PPP_CONTROL(p) (((__u8 *)(p))[1])
+#define PPP_PROTOCOL(p) ((((__u8 *)(p))[2] << 8) + ((__u8 *)(p))[3])
+
+#define PPP_ALLSTATIONS 0xff  
+#define PPP_UI 0x03  
+#define PPP_FLAG 0x7e  
+#define PPP_ESCAPE 0x7d  
+#define PPP_TRANS 0x20  
+
+#define PPP_IP 0x21  
+#define PPP_AT 0x29  
+#define PPP_IPX 0x2b  
+#define PPP_VJC_COMP 0x2d  
+#define PPP_VJC_UNCOMP 0x2f  
+#define PPP_MP 0x3d  
+#define PPP_IPV6 0x57  
+#define PPP_COMPFRAG 0xfb  
+#define PPP_COMP 0xfd  
+#define PPP_MPLS_UC 0x0281  
+#define PPP_MPLS_MC 0x0283  
+#define PPP_IPCP 0x8021  
+#define PPP_ATCP 0x8029  
+#define PPP_IPXCP 0x802b  
+#define PPP_IPV6CP 0x8057  
+#define PPP_CCPFRAG 0x80fb  
+#define PPP_CCP 0x80fd  
+#define PPP_MPLSCP 0x80fd  
+#define PPP_LCP 0xc021  
+#define PPP_PAP 0xc023  
+#define PPP_LQR 0xc025  
+#define PPP_CHAP 0xc223  
+#define PPP_CBCP 0xc029  
+
+#define PPP_INITFCS 0xffff  
+#define PPP_GOODFCS 0xf0b8  
+
+typedef __u32 ext_accm[8];
+
+enum NPmode {
+ NPMODE_PASS,
+ NPMODE_DROP,
+ NPMODE_ERROR,
+ NPMODE_QUEUE
+};
+
+struct pppstat {
+ __u32 ppp_discards;
+
+ __u32 ppp_ibytes;
+ __u32 ppp_ioctects;
+ __u32 ppp_ipackets;
+ __u32 ppp_ierrors;
+ __u32 ppp_ilqrs;
+
+ __u32 ppp_obytes;
+ __u32 ppp_ooctects;
+ __u32 ppp_opackets;
+ __u32 ppp_oerrors;
+ __u32 ppp_olqrs;
+};
+
+struct vjstat {
+ __u32 vjs_packets;
+ __u32 vjs_compressed;
+ __u32 vjs_searches;
+ __u32 vjs_misses;
+ __u32 vjs_uncompressedin;
+ __u32 vjs_compressedin;
+ __u32 vjs_errorin;
+ __u32 vjs_tossed;
+};
+
+struct compstat {
+ __u32 unc_bytes;
+ __u32 unc_packets;
+ __u32 comp_bytes;
+ __u32 comp_packets;
+ __u32 inc_bytes;
+ __u32 inc_packets;
+
+ __u32 in_count;
+ __u32 bytes_out;
+
+ double ratio;
+};
+
+struct ppp_stats {
+ struct pppstat p;
+ struct vjstat vj;
+};
+
+struct ppp_comp_stats {
+ struct compstat c;
+ struct compstat d;
+};
+
+struct ppp_idle {
+ time_t xmit_idle;
+ time_t recv_idle;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/prctl.h b/ndk/build/platforms/android-1.5/common/include/linux/prctl.h
new file mode 100644
index 0000000..a7631a2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/prctl.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_PRCTL_H
+#define _LINUX_PRCTL_H
+
+#define PR_SET_PDEATHSIG 1  
+#define PR_GET_PDEATHSIG 2  
+
+#define PR_GET_DUMPABLE 3
+#define PR_SET_DUMPABLE 4
+
+#define PR_GET_UNALIGN 5
+#define PR_SET_UNALIGN 6
+#define PR_UNALIGN_NOPRINT 1  
+#define PR_UNALIGN_SIGBUS 2  
+
+#define PR_GET_KEEPCAPS 7
+#define PR_SET_KEEPCAPS 8
+
+#define PR_GET_FPEMU 9
+#define PR_SET_FPEMU 10
+#define PR_FPEMU_NOPRINT 1  
+#define PR_FPEMU_SIGFPE 2  
+
+#define PR_GET_FPEXC 11
+#define PR_SET_FPEXC 12
+#define PR_FP_EXC_SW_ENABLE 0x80  
+#define PR_FP_EXC_DIV 0x010000  
+#define PR_FP_EXC_OVF 0x020000  
+#define PR_FP_EXC_UND 0x040000  
+#define PR_FP_EXC_RES 0x080000  
+#define PR_FP_EXC_INV 0x100000  
+#define PR_FP_EXC_DISABLED 0  
+#define PR_FP_EXC_NONRECOV 1  
+#define PR_FP_EXC_ASYNC 2  
+#define PR_FP_EXC_PRECISE 3  
+
+#define PR_GET_TIMING 13
+#define PR_SET_TIMING 14
+#define PR_TIMING_STATISTICAL 0  
+#define PR_TIMING_TIMESTAMP 1  
+
+#define PR_SET_NAME 15  
+#define PR_GET_NAME 16  
+
+#define PR_GET_ENDIAN 19
+#define PR_SET_ENDIAN 20
+#define PR_ENDIAN_BIG 0
+#define PR_ENDIAN_LITTLE 1  
+#define PR_ENDIAN_PPC_LITTLE 2  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/preempt.h b/ndk/build/platforms/android-1.5/common/include/linux/preempt.h
new file mode 100644
index 0000000..b703dd3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/preempt.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_PREEMPT_H
+#define __LINUX_PREEMPT_H
+
+#include <linux/thread_info.h>
+#include <linux/linkage.h>
+
+#define add_preempt_count(val) do { preempt_count() += (val); } while (0)
+#define sub_preempt_count(val) do { preempt_count() -= (val); } while (0)
+
+#define inc_preempt_count() add_preempt_count(1)
+#define dec_preempt_count() sub_preempt_count(1)
+
+#define preempt_count() (current_thread_info()->preempt_count)
+
+#define preempt_disable() do { } while (0)
+#define preempt_enable_no_resched() do { } while (0)
+#define preempt_enable() do { } while (0)
+#define preempt_check_resched() do { } while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/proc_fs.h b/ndk/build/platforms/android-1.5/common/include/linux/proc_fs.h
new file mode 100644
index 0000000..ccb22ac
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/proc_fs.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_PROC_FS_H
+#define _LINUX_PROC_FS_H
+
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/spinlock.h>
+#include <asm/atomic.h>
+
+#define FIRST_PROCESS_ENTRY 256
+
+enum {
+ PROC_ROOT_INO = 1,
+};
+
+#define PROC_SUPER_MAGIC 0x9fa0
+
+typedef int (read_proc_t)(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+typedef int (write_proc_t)(struct file *file, const char __user *buffer,
+ unsigned long count, void *data);
+typedef int (get_info_t)(char *, char **, off_t, int);
+
+struct proc_dir_entry {
+ unsigned int low_ino;
+ unsigned short namelen;
+ const char *name;
+ mode_t mode;
+ nlink_t nlink;
+ uid_t uid;
+ gid_t gid;
+ loff_t size;
+ struct inode_operations * proc_iops;
+ const struct file_operations * proc_fops;
+ get_info_t *get_info;
+ struct module *owner;
+ struct proc_dir_entry *next, *parent, *subdir;
+ void *data;
+ read_proc_t *read_proc;
+ write_proc_t *write_proc;
+ atomic_t count;
+ int deleted;
+ void *set;
+};
+
+struct kcore_list {
+ struct kcore_list *next;
+ unsigned long addr;
+ size_t size;
+};
+
+struct vmcore {
+ struct list_head list;
+ unsigned long long paddr;
+ unsigned long long size;
+ loff_t offset;
+};
+
+#define proc_root_driver NULL
+#define proc_net NULL
+#define proc_bus NULL
+
+#define proc_net_fops_create(name, mode, fops) ({ (void)(mode), NULL; })
+#define proc_net_create(name, mode, info) ({ (void)(mode), NULL; })
+#define remove_proc_entry(name, parent) do {} while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ptrace.h b/ndk/build/platforms/android-1.5/common/include/linux/ptrace.h
new file mode 100644
index 0000000..079c0c8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ptrace.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_PTRACE_H
+#define _LINUX_PTRACE_H
+
+#define PTRACE_TRACEME 0
+#define PTRACE_PEEKTEXT 1
+#define PTRACE_PEEKDATA 2
+#define PTRACE_PEEKUSR 3
+#define PTRACE_POKETEXT 4
+#define PTRACE_POKEDATA 5
+#define PTRACE_POKEUSR 6
+#define PTRACE_CONT 7
+#define PTRACE_KILL 8
+#define PTRACE_SINGLESTEP 9
+
+#define PTRACE_ATTACH 0x10
+#define PTRACE_DETACH 0x11
+
+#define PTRACE_SYSCALL 24
+
+#define PTRACE_SETOPTIONS 0x4200
+#define PTRACE_GETEVENTMSG 0x4201
+#define PTRACE_GETSIGINFO 0x4202
+#define PTRACE_SETSIGINFO 0x4203
+
+#define PTRACE_O_TRACESYSGOOD 0x00000001
+#define PTRACE_O_TRACEFORK 0x00000002
+#define PTRACE_O_TRACEVFORK 0x00000004
+#define PTRACE_O_TRACECLONE 0x00000008
+#define PTRACE_O_TRACEEXEC 0x00000010
+#define PTRACE_O_TRACEVFORKDONE 0x00000020
+#define PTRACE_O_TRACEEXIT 0x00000040
+
+#define PTRACE_O_MASK 0x0000007f
+
+#define PTRACE_EVENT_FORK 1
+#define PTRACE_EVENT_VFORK 2
+#define PTRACE_EVENT_CLONE 3
+#define PTRACE_EVENT_EXEC 4
+#define PTRACE_EVENT_VFORK_DONE 5
+#define PTRACE_EVENT_EXIT 6
+
+#include <asm/ptrace.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/qic117.h b/ndk/build/platforms/android-1.5/common/include/linux/qic117.h
new file mode 100644
index 0000000..e077090
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/qic117.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _QIC117_H
+#define _QIC117_H
+
+typedef enum {
+ QIC_NO_COMMAND = 0,
+ QIC_RESET = 1,
+ QIC_REPORT_NEXT_BIT = 2,
+ QIC_PAUSE = 3,
+ QIC_MICRO_STEP_PAUSE = 4,
+ QIC_ALTERNATE_TIMEOUT = 5,
+ QIC_REPORT_DRIVE_STATUS = 6,
+ QIC_REPORT_ERROR_CODE = 7,
+ QIC_REPORT_DRIVE_CONFIGURATION = 8,
+ QIC_REPORT_ROM_VERSION = 9,
+ QIC_LOGICAL_FORWARD = 10,
+ QIC_PHYSICAL_REVERSE = 11,
+ QIC_PHYSICAL_FORWARD = 12,
+ QIC_SEEK_HEAD_TO_TRACK = 13,
+ QIC_SEEK_LOAD_POINT = 14,
+ QIC_ENTER_FORMAT_MODE = 15,
+ QIC_WRITE_REFERENCE_BURST = 16,
+ QIC_ENTER_VERIFY_MODE = 17,
+ QIC_STOP_TAPE = 18,
+
+ QIC_MICRO_STEP_HEAD_UP = 21,
+ QIC_MICRO_STEP_HEAD_DOWN = 22,
+ QIC_SOFT_SELECT = 23,
+ QIC_SOFT_DESELECT = 24,
+ QIC_SKIP_REVERSE = 25,
+ QIC_SKIP_FORWARD = 26,
+ QIC_SELECT_RATE = 27,
+
+ QIC_ENTER_DIAGNOSTIC_1 = 28,
+ QIC_ENTER_DIAGNOSTIC_2 = 29,
+ QIC_ENTER_PRIMARY_MODE = 30,
+
+ QIC_REPORT_VENDOR_ID = 32,
+ QIC_REPORT_TAPE_STATUS = 33,
+ QIC_SKIP_EXTENDED_REVERSE = 34,
+ QIC_SKIP_EXTENDED_FORWARD = 35,
+ QIC_CALIBRATE_TAPE_LENGTH = 36,
+ QIC_REPORT_FORMAT_SEGMENTS = 37,
+ QIC_SET_FORMAT_SEGMENTS = 38,
+
+ QIC_PHANTOM_SELECT = 46,
+ QIC_PHANTOM_DESELECT = 47
+} qic117_cmd_t;
+
+typedef enum {
+ discretional = 0, required, ccs1, ccs2
+} qic_compatibility;
+
+typedef enum {
+ unused, mode, motion, report
+} command_types;
+
+struct qic117_command_table {
+ char *name;
+ __u8 mask;
+ __u8 state;
+ __u8 cmd_type;
+ __u8 non_intr;
+ __u8 level;
+};
+
+#define QIC117_COMMANDS {         {NULL, 0x00, 0x00, mode, 0, discretional},   {"soft reset", 0x00, 0x00, motion, 1, required},   {"report next bit", 0x00, 0x00, report, 0, required},   {"pause", 0x36, 0x24, motion, 1, required},   {"micro step pause", 0x36, 0x24, motion, 1, required},   {"alternate command timeout", 0x00, 0x00, mode, 0, required},   {"report drive status", 0x00, 0x00, report, 0, required},   {"report error code", 0x01, 0x01, report, 0, required},   {"report drive configuration",0x00, 0x00, report, 0, required},   {"report rom version", 0x00, 0x00, report, 0, required},   {"logical forward", 0x37, 0x25, motion, 0, required},   {"physical reverse", 0x17, 0x05, motion, 0, required},   {"physical forward", 0x17, 0x05, motion, 0, required},   {"seek head to track", 0x37, 0x25, motion, 0, required},   {"seek load point", 0x17, 0x05, motion, 1, required},   {"enter format mode", 0x1f, 0x05, mode, 0, required},   {"write reference burst", 0x1f, 0x05, motion, 1, required},   {"enter verify mode", 0x37, 0x25, mode, 0, required},   {"stop tape", 0x00, 0x00, motion, 1, required},   {"reserved (19)", 0x00, 0x00, unused, 0, discretional},   {"reserved (20)", 0x00, 0x00, unused, 0, discretional},   {"micro step head up", 0x02, 0x00, motion, 0, required},   {"micro step head down", 0x02, 0x00, motion, 0, required},   {"soft select", 0x00, 0x00, mode, 0, discretional},   {"soft deselect", 0x00, 0x00, mode, 0, discretional},   {"skip segments reverse", 0x36, 0x24, motion, 1, required},   {"skip segments forward", 0x36, 0x24, motion, 1, required},   {"select rate or format", 0x03, 0x01, mode, 0, required  },   {"enter diag mode 1", 0x00, 0x00, mode, 0, discretional},   {"enter diag mode 2", 0x00, 0x00, mode, 0, discretional},   {"enter primary mode", 0x00, 0x00, mode, 0, required},   {"vendor unique (31)", 0x00, 0x00, unused, 0, discretional},   {"report vendor id", 0x00, 0x00, report, 0, required},   {"report tape status", 0x04, 0x04, report, 0, ccs1},   {"skip extended reverse", 0x36, 0x24, motion, 1, ccs1},   {"skip extended forward", 0x36, 0x24, motion, 1, ccs1},   {"calibrate tape length", 0x17, 0x05, motion, 1, ccs2},   {"report format segments", 0x17, 0x05, report, 0, ccs2},   {"set format segments", 0x17, 0x05, mode, 0, ccs2},   {"reserved (39)", 0x00, 0x00, unused, 0, discretional},   {"vendor unique (40)", 0x00, 0x00, unused, 0, discretional},   {"vendor unique (41)", 0x00, 0x00, unused, 0, discretional},   {"vendor unique (42)", 0x00, 0x00, unused, 0, discretional},   {"vendor unique (43)", 0x00, 0x00, unused, 0, discretional},   {"vendor unique (44)", 0x00, 0x00, unused, 0, discretional},   {"vendor unique (45)", 0x00, 0x00, unused, 0, discretional},   {"phantom select", 0x00, 0x00, mode, 0, discretional},   {"phantom deselect", 0x00, 0x00, mode, 0, discretional}, }
+
+#define QIC_STATUS_READY 0x01  
+#define QIC_STATUS_ERROR 0x02  
+#define QIC_STATUS_CARTRIDGE_PRESENT 0x04  
+#define QIC_STATUS_WRITE_PROTECT 0x08  
+#define QIC_STATUS_NEW_CARTRIDGE 0x10  
+#define QIC_STATUS_REFERENCED 0x20  
+#define QIC_STATUS_AT_BOT 0x40  
+#define QIC_STATUS_AT_EOT 0x80  
+
+#define QIC_CONFIG_RATE_MASK 0x18
+#define QIC_CONFIG_RATE_SHIFT 3
+#define QIC_CONFIG_RATE_250 0
+#define QIC_CONFIG_RATE_500 2
+#define QIC_CONFIG_RATE_1000 3
+#define QIC_CONFIG_RATE_2000 1
+#define QIC_CONFIG_RATE_4000 0  
+
+#define QIC_CONFIG_LONG 0x40  
+#define QIC_CONFIG_80 0x80  
+
+#define QIC_TAPE_STD_MASK 0x0f
+#define QIC_TAPE_QIC40 0x01
+#define QIC_TAPE_QIC80 0x02
+#define QIC_TAPE_QIC3020 0x03
+#define QIC_TAPE_QIC3010 0x04
+
+#define QIC_TAPE_LEN_MASK 0x70
+#define QIC_TAPE_205FT 0x10
+#define QIC_TAPE_307FT 0x20
+#define QIC_TAPE_VARIABLE 0x30
+#define QIC_TAPE_1100FT 0x40
+#define QIC_TAPE_FLEX 0x60
+
+#define QIC_TAPE_WIDE 0x80
+
+#define QIC_TOP_TAPE_LEN 1500
+
+typedef struct {
+ char *message;
+ unsigned int fatal:1;
+} ftape_error;
+
+#define QIC117_ERRORS {    { "No error", 0, },    { "Command Received while Drive Not Ready", 0, },    { "Cartridge Not Present or Removed", 1, },    { "Motor Speed Error (not within 1%)", 1, },    { "Motor Speed Fault (jammed, or gross speed error", 1, },    { "Cartridge Write Protected", 1, },    { "Undefined or Reserved Command Code", 1, },    { "Illegal Track Address Specified for Seek", 1, },    { "Illegal Command in Report Subcontext", 0, },    { "Illegal Entry into a Diagnostic Mode", 1, },    { "Broken Tape Detected (based on hole sensor)", 1, },    { "Warning--Read Gain Setting Error", 1, },    { "Command Received While Error Status Pending (obs)", 1, },    { "Command Received While New Cartridge Pending", 1, },    { "Command Illegal or Undefined in Primary Mode", 1, },    { "Command Illegal or Undefined in Format Mode", 1, },    { "Command Illegal or Undefined in Verify Mode", 1, },    { "Logical Forward Not at Logical BOT or no Format Segments in Format Mode", 1, },    { "Logical EOT Before All Segments generated", 1, },    { "Command Illegal When Cartridge Not Referenced", 1, },    { "Self-Diagnostic Failed (cannot be cleared)", 1, },    { "Warning EEPROM Not Initialized, Defaults Set", 1, },    { "EEPROM Corrupted or Hardware Failure", 1, },    { "Motion Time-out Error", 1, },    { "Data Segment Too Long -- Logical Forward or Pause", 1, },    { "Transmit Overrun (obs)", 1, },    { "Power On Reset Occurred", 0, },    { "Software Reset Occurred", 0, },    { "Diagnostic Mode 1 Error", 1, },    { "Diagnostic Mode 2 Error", 1, },    { "Command Received During Non-Interruptible Process", 1, },    { "Rate or Format Selection Error", 1, },    { "Illegal Command While in High Speed Mode", 1, },    { "Illegal Seek Segment Value", 1, },    { "Invalid Media", 1, },    { "Head Positioning Failure", 1, },    { "Write Reference Burst Failure", 1, },    { "Prom Code Missing", 1, },    { "Invalid Format", 1, },    { "EOT/BOT System Failure", 1, },    { "Prom A Checksum Error", 1, },    { "Drive Wakeup Reset Occurred", 1, },    { "Prom B Checksum Error", 1, },    { "Illegal Entry into Format Mode", 1, }, }
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/qnxtypes.h b/ndk/build/platforms/android-1.5/common/include/linux/qnxtypes.h
new file mode 100644
index 0000000..53cd20c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/qnxtypes.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _QNX4TYPES_H
+#define _QNX4TYPES_H
+
+typedef __le16 qnx4_nxtnt_t;
+typedef __u8 qnx4_ftype_t;
+
+typedef struct {
+ __le32 xtnt_blk;
+ __le32 xtnt_size;
+} qnx4_xtnt_t;
+
+typedef __le16 qnx4_mode_t;
+typedef __le16 qnx4_muid_t;
+typedef __le16 qnx4_mgid_t;
+typedef __le32 qnx4_off_t;
+typedef __le16 qnx4_nlink_t;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/quota.h b/ndk/build/platforms/android-1.5/common/include/linux/quota.h
new file mode 100644
index 0000000..054af5a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/quota.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_QUOTA_
+#define _LINUX_QUOTA_
+
+#include <linux/errno.h>
+#include <linux/types.h>
+
+#define __DQUOT_VERSION__ "dquot_6.5.1"
+#define __DQUOT_NUM_VERSION__ 6*10000+5*100+1
+
+typedef __kernel_uid32_t qid_t;
+typedef __u64 qsize_t;
+
+#define QUOTABLOCK_BITS 10
+#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
+
+#define qb2kb(x) ((x) << (QUOTABLOCK_BITS-10))
+#define kb2qb(x) ((x) >> (QUOTABLOCK_BITS-10))
+#define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS)
+
+#define MAXQUOTAS 2
+#define USRQUOTA 0  
+#define GRPQUOTA 1  
+
+#define INITQFNAMES {   "user",     "group",     "undefined",  };
+
+#define SUBCMDMASK 0x00ff
+#define SUBCMDSHIFT 8
+#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
+
+#define Q_SYNC 0x800001  
+#define Q_QUOTAON 0x800002  
+#define Q_QUOTAOFF 0x800003  
+#define Q_GETFMT 0x800004  
+#define Q_GETINFO 0x800005  
+#define Q_SETINFO 0x800006  
+#define Q_GETQUOTA 0x800007  
+#define Q_SETQUOTA 0x800008  
+
+#define QIF_BLIMITS 1
+#define QIF_SPACE 2
+#define QIF_ILIMITS 4
+#define QIF_INODES 8
+#define QIF_BTIME 16
+#define QIF_ITIME 32
+#define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS)
+#define QIF_USAGE (QIF_SPACE | QIF_INODES)
+#define QIF_TIMES (QIF_BTIME | QIF_ITIME)
+#define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES)
+
+struct if_dqblk {
+ __u64 dqb_bhardlimit;
+ __u64 dqb_bsoftlimit;
+ __u64 dqb_curspace;
+ __u64 dqb_ihardlimit;
+ __u64 dqb_isoftlimit;
+ __u64 dqb_curinodes;
+ __u64 dqb_btime;
+ __u64 dqb_itime;
+ __u32 dqb_valid;
+};
+
+#define IIF_BGRACE 1
+#define IIF_IGRACE 2
+#define IIF_FLAGS 4
+#define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
+
+struct if_dqinfo {
+ __u64 dqi_bgrace;
+ __u64 dqi_igrace;
+ __u32 dqi_flags;
+ __u32 dqi_valid;
+};
+
+#include <sys/cdefs.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/raid/md.h b/ndk/build/platforms/android-1.5/common/include/linux/raid/md.h
new file mode 100644
index 0000000..d609c06
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/raid/md.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _MD_H
+#define _MD_H
+
+#include <linux/blkdev.h>
+#include <asm/semaphore.h>
+#include <linux/major.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/hdreg.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/smp_lock.h>
+#include <linux/delay.h>
+#include <net/checksum.h>
+#include <linux/random.h>
+#include <linux/kernel_stat.h>
+#include <asm/io.h>
+#include <linux/completion.h>
+#include <linux/mempool.h>
+#include <linux/list.h>
+#include <linux/reboot.h>
+#include <linux/vmalloc.h>
+#include <linux/blkpg.h>
+#include <linux/bio.h>
+
+#include <linux/raid/md_p.h>
+#include <linux/raid/md_u.h>
+#include <linux/raid/md_k.h>
+
+#define MD_MAJOR_VERSION 0
+#define MD_MINOR_VERSION 90
+
+#define MD_PATCHLEVEL_VERSION 3
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/raid/md_k.h b/ndk/build/platforms/android-1.5/common/include/linux/raid/md_k.h
new file mode 100644
index 0000000..c8b858c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/raid/md_k.h
@@ -0,0 +1,184 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _MD_K_H
+#define _MD_K_H
+
+#include "../../../drivers/md/dm-bio-list.h"
+
+#define LEVEL_MULTIPATH (-4)
+#define LEVEL_LINEAR (-1)
+#define LEVEL_FAULTY (-5)
+
+#define LEVEL_NONE (-1000000)
+
+#define MaxSector (~(sector_t)0)
+#define MD_THREAD_NAME_MAX 14
+
+typedef struct mddev_s mddev_t;
+typedef struct mdk_rdev_s mdk_rdev_t;
+
+#define MAX_MD_DEVS 256  
+
+#define MAX_CHUNK_SIZE (1<<30)
+
+struct mdk_rdev_s
+{
+ struct list_head same_set;
+
+ sector_t size;
+ mddev_t *mddev;
+ unsigned long last_events;
+
+ struct block_device *bdev;
+
+ struct page *sb_page;
+ int sb_loaded;
+ __u64 sb_events;
+ sector_t data_offset;
+ sector_t sb_offset;
+ int sb_size;
+ int preferred_minor;
+
+ struct kobject kobj;
+
+ unsigned long flags;
+#define Faulty 1  
+#define In_sync 2  
+#define WriteMostly 4  
+#define BarriersNotsupp 5  
+
+ int desc_nr;
+ int raid_disk;
+ int saved_raid_disk;
+ sector_t recovery_offset;
+
+ atomic_t nr_pending;
+ atomic_t read_errors;
+ atomic_t corrected_errors;
+};
+
+struct mddev_s
+{
+ void *private;
+ struct mdk_personality *pers;
+ dev_t unit;
+ int md_minor;
+ struct list_head disks;
+ int sb_dirty;
+ int ro;
+
+ struct gendisk *gendisk;
+
+ struct kobject kobj;
+
+ int major_version,
+ minor_version,
+ patch_version;
+ int persistent;
+ int chunk_size;
+ time_t ctime, utime;
+ int level, layout;
+ char clevel[16];
+ int raid_disks;
+ int max_disks;
+ sector_t size;
+ sector_t array_size;
+ __u64 events;
+
+ char uuid[16];
+
+ sector_t reshape_position;
+ int delta_disks, new_level, new_layout, new_chunk;
+
+ struct mdk_thread_s *thread;
+ struct mdk_thread_s *sync_thread;
+ sector_t curr_resync;
+ unsigned long resync_mark;
+ sector_t resync_mark_cnt;
+ sector_t curr_mark_cnt;
+
+ sector_t resync_max_sectors;
+
+ sector_t resync_mismatches;
+
+ sector_t suspend_lo;
+ sector_t suspend_hi;
+
+ int sync_speed_min;
+ int sync_speed_max;
+
+ int ok_start_degraded;
+
+#define MD_RECOVERY_RUNNING 0
+#define MD_RECOVERY_SYNC 1
+#define MD_RECOVERY_ERR 2
+#define MD_RECOVERY_INTR 3
+#define MD_RECOVERY_DONE 4
+#define MD_RECOVERY_NEEDED 5
+#define MD_RECOVERY_REQUESTED 6
+#define MD_RECOVERY_CHECK 7
+#define MD_RECOVERY_RESHAPE 8
+#define MD_RECOVERY_FROZEN 9
+
+ unsigned long recovery;
+
+ int in_sync;
+ struct mutex reconfig_mutex;
+ atomic_t active;
+
+ int changed;
+ int degraded;
+ int barriers_work;
+ struct bio *biolist;
+
+ atomic_t recovery_active;
+ wait_queue_head_t recovery_wait;
+ sector_t recovery_cp;
+
+ spinlock_t write_lock;
+ wait_queue_head_t sb_wait;
+ atomic_t pending_writes;
+
+ unsigned int safemode;
+ unsigned int safemode_delay;
+ struct timer_list safemode_timer;
+ atomic_t writes_pending;
+ request_queue_t *queue;
+
+ atomic_t write_behind;
+ unsigned int max_write_behind;
+
+ struct bitmap *bitmap;
+ struct file *bitmap_file;
+ long bitmap_offset;
+ long default_bitmap_offset;
+
+ struct list_head all_mddevs;
+};
+
+struct md_sysfs_entry {
+ struct attribute attr;
+ ssize_t (*show)(mddev_t *, char *);
+ ssize_t (*store)(mddev_t *, const char *, size_t);
+};
+
+#define ITERATE_RDEV_GENERIC(head,rdev,tmp)     for ((tmp) = (head).next;   (rdev) = (list_entry((tmp), mdk_rdev_t, same_set)),   (tmp) = (tmp)->next, (tmp)->prev != &(head)   ; )
+#define ITERATE_RDEV(mddev,rdev,tmp)   ITERATE_RDEV_GENERIC((mddev)->disks,rdev,tmp)
+#define ITERATE_RDEV_PENDING(rdev,tmp)   ITERATE_RDEV_GENERIC(pending_raid_disks,rdev,tmp)
+
+#define THREAD_WAKEUP 0
+
+#define __wait_event_lock_irq(wq, condition, lock, cmd)  do {   wait_queue_t __wait;   init_waitqueue_entry(&__wait, current);     add_wait_queue(&wq, &__wait);   for (;;) {   set_current_state(TASK_UNINTERRUPTIBLE);   if (condition)   break;   spin_unlock_irq(&lock);   cmd;   schedule();   spin_lock_irq(&lock);   }   current->state = TASK_RUNNING;   remove_wait_queue(&wq, &__wait);  } while (0)
+
+#define wait_event_lock_irq(wq, condition, lock, cmd)  do {   if (condition)   break;   __wait_event_lock_irq(wq, condition, lock, cmd);  } while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/raid/md_p.h b/ndk/build/platforms/android-1.5/common/include/linux/raid/md_p.h
new file mode 100644
index 0000000..ab856a7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/raid/md_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _MD_P_H
+#define _MD_P_H
+
+#define MD_RESERVED_BYTES (64 * 1024)
+#define MD_RESERVED_SECTORS (MD_RESERVED_BYTES / 512)
+#define MD_RESERVED_BLOCKS (MD_RESERVED_BYTES / BLOCK_SIZE)
+
+#define MD_NEW_SIZE_SECTORS(x) ((x & ~(MD_RESERVED_SECTORS - 1)) - MD_RESERVED_SECTORS)
+#define MD_NEW_SIZE_BLOCKS(x) ((x & ~(MD_RESERVED_BLOCKS - 1)) - MD_RESERVED_BLOCKS)
+
+#define MD_SB_BYTES 4096
+#define MD_SB_WORDS (MD_SB_BYTES / 4)
+#define MD_SB_BLOCKS (MD_SB_BYTES / BLOCK_SIZE)
+#define MD_SB_SECTORS (MD_SB_BYTES / 512)
+
+#define MD_SB_GENERIC_OFFSET 0
+#define MD_SB_PERSONALITY_OFFSET 64
+#define MD_SB_DISKS_OFFSET 128
+#define MD_SB_DESCRIPTOR_OFFSET 992
+
+#define MD_SB_GENERIC_CONSTANT_WORDS 32
+#define MD_SB_GENERIC_STATE_WORDS 32
+#define MD_SB_GENERIC_WORDS (MD_SB_GENERIC_CONSTANT_WORDS + MD_SB_GENERIC_STATE_WORDS)
+#define MD_SB_PERSONALITY_WORDS 64
+#define MD_SB_DESCRIPTOR_WORDS 32
+#define MD_SB_DISKS 27
+#define MD_SB_DISKS_WORDS (MD_SB_DISKS*MD_SB_DESCRIPTOR_WORDS)
+#define MD_SB_RESERVED_WORDS (1024 - MD_SB_GENERIC_WORDS - MD_SB_PERSONALITY_WORDS - MD_SB_DISKS_WORDS - MD_SB_DESCRIPTOR_WORDS)
+#define MD_SB_EQUAL_WORDS (MD_SB_GENERIC_WORDS + MD_SB_PERSONALITY_WORDS + MD_SB_DISKS_WORDS)
+
+#define MD_DISK_FAULTY 0  
+#define MD_DISK_ACTIVE 1  
+#define MD_DISK_SYNC 2  
+#define MD_DISK_REMOVED 3  
+
+#define MD_DISK_WRITEMOSTLY 9  
+
+typedef struct mdp_device_descriptor_s {
+ __u32 number;
+ __u32 major;
+ __u32 minor;
+ __u32 raid_disk;
+ __u32 state;
+ __u32 reserved[MD_SB_DESCRIPTOR_WORDS - 5];
+} mdp_disk_t;
+
+#define MD_SB_MAGIC 0xa92b4efc
+
+#define MD_SB_CLEAN 0
+#define MD_SB_ERRORS 1
+
+#define MD_SB_BITMAP_PRESENT 8  
+
+typedef struct mdp_superblock_s {
+
+ __u32 md_magic;
+ __u32 major_version;
+ __u32 minor_version;
+ __u32 patch_version;
+ __u32 gvalid_words;
+ __u32 set_uuid0;
+ __u32 ctime;
+ __u32 level;
+ __u32 size;
+ __u32 nr_disks;
+ __u32 raid_disks;
+ __u32 md_minor;
+ __u32 not_persistent;
+ __u32 set_uuid1;
+ __u32 set_uuid2;
+ __u32 set_uuid3;
+ __u32 gstate_creserved[MD_SB_GENERIC_CONSTANT_WORDS - 16];
+
+ __u32 utime;
+ __u32 state;
+ __u32 active_disks;
+ __u32 working_disks;
+ __u32 failed_disks;
+ __u32 spare_disks;
+ __u32 sb_csum;
+#ifdef __BIG_ENDIAN
+ __u32 events_hi;
+ __u32 events_lo;
+ __u32 cp_events_hi;
+ __u32 cp_events_lo;
+#else
+ __u32 events_lo;
+ __u32 events_hi;
+ __u32 cp_events_lo;
+ __u32 cp_events_hi;
+#endif
+ __u32 recovery_cp;
+
+ __u64 reshape_position;
+ __u32 new_level;
+ __u32 delta_disks;
+ __u32 new_layout;
+ __u32 new_chunk;
+ __u32 gstate_sreserved[MD_SB_GENERIC_STATE_WORDS - 18];
+
+ __u32 layout;
+ __u32 chunk_size;
+ __u32 root_pv;
+ __u32 root_block;
+ __u32 pstate_reserved[MD_SB_PERSONALITY_WORDS - 4];
+
+ mdp_disk_t disks[MD_SB_DISKS];
+
+ __u32 reserved[MD_SB_RESERVED_WORDS];
+
+ mdp_disk_t this_disk;
+
+} mdp_super_t;
+
+#define WriteMostly1 1  
+
+#define MD_FEATURE_BITMAP_OFFSET 1
+#define MD_FEATURE_RECOVERY_OFFSET 2  
+#define MD_FEATURE_RESHAPE_ACTIVE 4
+
+#define MD_FEATURE_ALL (1|2|4)
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/raid/md_u.h b/ndk/build/platforms/android-1.5/common/include/linux/raid/md_u.h
new file mode 100644
index 0000000..3671187
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/raid/md_u.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _MD_U_H
+#define _MD_U_H
+
+#define RAID_VERSION _IOR (MD_MAJOR, 0x10, mdu_version_t)
+#define GET_ARRAY_INFO _IOR (MD_MAJOR, 0x11, mdu_array_info_t)
+#define GET_DISK_INFO _IOR (MD_MAJOR, 0x12, mdu_disk_info_t)
+#define PRINT_RAID_DEBUG _IO (MD_MAJOR, 0x13)
+#define RAID_AUTORUN _IO (MD_MAJOR, 0x14)
+#define GET_BITMAP_FILE _IOR (MD_MAJOR, 0x15, mdu_bitmap_file_t)
+
+#define CLEAR_ARRAY _IO (MD_MAJOR, 0x20)
+#define ADD_NEW_DISK _IOW (MD_MAJOR, 0x21, mdu_disk_info_t)
+#define HOT_REMOVE_DISK _IO (MD_MAJOR, 0x22)
+#define SET_ARRAY_INFO _IOW (MD_MAJOR, 0x23, mdu_array_info_t)
+#define SET_DISK_INFO _IO (MD_MAJOR, 0x24)
+#define WRITE_RAID_INFO _IO (MD_MAJOR, 0x25)
+#define UNPROTECT_ARRAY _IO (MD_MAJOR, 0x26)
+#define PROTECT_ARRAY _IO (MD_MAJOR, 0x27)
+#define HOT_ADD_DISK _IO (MD_MAJOR, 0x28)
+#define SET_DISK_FAULTY _IO (MD_MAJOR, 0x29)
+#define HOT_GENERATE_ERROR _IO (MD_MAJOR, 0x2a)
+#define SET_BITMAP_FILE _IOW (MD_MAJOR, 0x2b, int)
+
+#define RUN_ARRAY _IOW (MD_MAJOR, 0x30, mdu_param_t)
+#define START_ARRAY _IO (MD_MAJOR, 0x31)
+#define STOP_ARRAY _IO (MD_MAJOR, 0x32)
+#define STOP_ARRAY_RO _IO (MD_MAJOR, 0x33)
+#define RESTART_ARRAY_RW _IO (MD_MAJOR, 0x34)
+
+typedef struct mdu_version_s {
+ int major;
+ int minor;
+ int patchlevel;
+} mdu_version_t;
+
+typedef struct mdu_array_info_s {
+
+ int major_version;
+ int minor_version;
+ int patch_version;
+ int ctime;
+ int level;
+ int size;
+ int nr_disks;
+ int raid_disks;
+ int md_minor;
+ int not_persistent;
+
+ int utime;
+ int state;
+ int active_disks;
+ int working_disks;
+ int failed_disks;
+ int spare_disks;
+
+ int layout;
+ int chunk_size;
+
+} mdu_array_info_t;
+
+typedef struct mdu_disk_info_s {
+
+ int number;
+ int major;
+ int minor;
+ int raid_disk;
+ int state;
+
+} mdu_disk_info_t;
+
+typedef struct mdu_start_info_s {
+
+ int major;
+ int minor;
+ int raid_disk;
+ int state;
+
+} mdu_start_info_t;
+
+typedef struct mdu_bitmap_file_s
+{
+ char pathname[4096];
+} mdu_bitmap_file_t;
+
+typedef struct mdu_param_s
+{
+ int personality;
+ int chunk_size;
+ int max_fault;
+} mdu_param_t;
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/raid/xor.h b/ndk/build/platforms/android-1.5/common/include/linux/raid/xor.h
new file mode 100644
index 0000000..01e9f45
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/raid/xor.h
@@ -0,0 +1,32 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _XOR_H
+#define _XOR_H
+
+#include <linux/raid/md.h>
+
+#define MAX_XOR_BLOCKS 5
+
+struct xor_block_template {
+ struct xor_block_template *next;
+ const char *name;
+ int speed;
+ void (*do_2)(unsigned long, unsigned long *, unsigned long *);
+ void (*do_3)(unsigned long, unsigned long *, unsigned long *,
+ unsigned long *);
+ void (*do_4)(unsigned long, unsigned long *, unsigned long *,
+ unsigned long *, unsigned long *);
+ void (*do_5)(unsigned long, unsigned long *, unsigned long *,
+ unsigned long *, unsigned long *, unsigned long *);
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/random.h b/ndk/build/platforms/android-1.5/common/include/linux/random.h
new file mode 100644
index 0000000..d2bef97
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/random.h
@@ -0,0 +1,35 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_RANDOM_H
+#define _LINUX_RANDOM_H
+
+#include <linux/ioctl.h>
+
+#define RNDGETENTCNT _IOR( 'R', 0x00, int )
+
+#define RNDADDTOENTCNT _IOW( 'R', 0x01, int )
+
+#define RNDGETPOOL _IOR( 'R', 0x02, int [2] )
+
+#define RNDADDENTROPY _IOW( 'R', 0x03, int [2] )
+
+#define RNDZAPENTCNT _IO( 'R', 0x04 )
+
+#define RNDCLEARPOOL _IO( 'R', 0x06 )
+
+struct rand_pool_info {
+ int entropy_count;
+ int buf_size;
+ __u32 buf[0];
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/rbtree.h b/ndk/build/platforms/android-1.5/common/include/linux/rbtree.h
new file mode 100644
index 0000000..714ffe9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/rbtree.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_RBTREE_H
+#define _LINUX_RBTREE_H
+
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+
+struct rb_node
+{
+ unsigned long rb_parent_color;
+#define RB_RED 0
+#define RB_BLACK 1
+ struct rb_node *rb_right;
+ struct rb_node *rb_left;
+} __attribute__((aligned(sizeof(long))));
+
+struct rb_root
+{
+ struct rb_node *rb_node;
+};
+
+#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3))
+#define rb_color(r) ((r)->rb_parent_color & 1)
+#define rb_is_red(r) (!rb_color(r))
+#define rb_is_black(r) rb_color(r)
+#define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0)
+#define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0)
+
+#define RB_ROOT (struct rb_root) { NULL, }
+#define rb_entry(ptr, type, member) container_of(ptr, type, member)
+#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
+#define RB_EMPTY_NODE(node) (rb_parent(node) != node)
+#define RB_CLEAR_NODE(node) (rb_set_parent(node, node))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/rcupdate.h b/ndk/build/platforms/android-1.5/common/include/linux/rcupdate.h
new file mode 100644
index 0000000..5547a4d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/rcupdate.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_RCUPDATE_H
+#define __LINUX_RCUPDATE_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/reboot.h b/ndk/build/platforms/android-1.5/common/include/linux/reboot.h
new file mode 100644
index 0000000..e10ff14
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/reboot.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_REBOOT_H
+#define _LINUX_REBOOT_H
+
+#define LINUX_REBOOT_MAGIC1 0xfee1dead
+#define LINUX_REBOOT_MAGIC2 672274793
+#define LINUX_REBOOT_MAGIC2A 85072278
+#define LINUX_REBOOT_MAGIC2B 369367448
+#define LINUX_REBOOT_MAGIC2C 537993216
+
+#define LINUX_REBOOT_CMD_RESTART 0x01234567
+#define LINUX_REBOOT_CMD_HALT 0xCDEF0123
+#define LINUX_REBOOT_CMD_CAD_ON 0x89ABCDEF
+#define LINUX_REBOOT_CMD_CAD_OFF 0x00000000
+#define LINUX_REBOOT_CMD_POWER_OFF 0x4321FEDC
+#define LINUX_REBOOT_CMD_RESTART2 0xA1B2C3D4
+#define LINUX_REBOOT_CMD_SW_SUSPEND 0xD000FCE2
+#define LINUX_REBOOT_CMD_KEXEC 0x45584543
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/relay.h b/ndk/build/platforms/android-1.5/common/include/linux/relay.h
new file mode 100644
index 0000000..09f7219
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/relay.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_RELAY_H
+#define _LINUX_RELAY_H
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/kref.h>
+
+#define FIX_SIZE(x) ((((x) - 1) & PAGE_MASK) + PAGE_SIZE)
+
+#define RELAYFS_CHANNEL_VERSION 6
+
+struct rchan_buf
+{
+ void *start;
+ void *data;
+ size_t offset;
+ size_t subbufs_produced;
+ size_t subbufs_consumed;
+ struct rchan *chan;
+ wait_queue_head_t read_wait;
+ struct work_struct wake_readers;
+ struct dentry *dentry;
+ struct kref kref;
+ struct page **page_array;
+ unsigned int page_count;
+ unsigned int finalized;
+ size_t *padding;
+ size_t prev_padding;
+ size_t bytes_consumed;
+ unsigned int cpu;
+} ____cacheline_aligned;
+
+struct rchan
+{
+ u32 version;
+ size_t subbuf_size;
+ size_t n_subbufs;
+ size_t alloc_size;
+ struct rchan_callbacks *cb;
+ struct kref kref;
+ void *private_data;
+ size_t last_toobig;
+ struct rchan_buf *buf[NR_CPUS];
+};
+
+struct rchan_callbacks
+{
+
+ int (*subbuf_start) (struct rchan_buf *buf,
+ void *subbuf,
+ void *prev_subbuf,
+ size_t prev_padding);
+
+ void (*buf_mapped)(struct rchan_buf *buf,
+ struct file *filp);
+
+ void (*buf_unmapped)(struct rchan_buf *buf,
+ struct file *filp);
+
+ struct dentry *(*create_buf_file)(const char *filename,
+ struct dentry *parent,
+ int mode,
+ struct rchan_buf *buf,
+ int *is_global);
+
+ int (*remove_buf_file)(struct dentry *dentry);
+};
+
+struct rchan *relay_open(const char *base_filename,
+ struct dentry *parent,
+ size_t subbuf_size,
+ size_t n_subbufs,
+ struct rchan_callbacks *cb);
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/resource.h b/ndk/build/platforms/android-1.5/common/include/linux/resource.h
new file mode 100644
index 0000000..347b524
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/resource.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_RESOURCE_H
+#define _LINUX_RESOURCE_H
+
+#include <linux/time.h>
+
+struct task_struct;
+
+#define RUSAGE_SELF 0
+#define RUSAGE_CHILDREN (-1)
+#define RUSAGE_BOTH (-2)  
+
+struct rusage {
+ struct timeval ru_utime;
+ struct timeval ru_stime;
+ long ru_maxrss;
+ long ru_ixrss;
+ long ru_idrss;
+ long ru_isrss;
+ long ru_minflt;
+ long ru_majflt;
+ long ru_nswap;
+ long ru_inblock;
+ long ru_oublock;
+ long ru_msgsnd;
+ long ru_msgrcv;
+ long ru_nsignals;
+ long ru_nvcsw;
+ long ru_nivcsw;
+};
+
+struct rlimit {
+ unsigned long rlim_cur;
+ unsigned long rlim_max;
+};
+
+#define PRIO_MIN (-20)
+#define PRIO_MAX 20
+
+#define PRIO_PROCESS 0
+#define PRIO_PGRP 1
+#define PRIO_USER 2
+
+#define _STK_LIM (8*1024*1024)
+
+#define MLOCK_LIMIT (8 * PAGE_SIZE)
+
+#include <asm/resource.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/route.h b/ndk/build/platforms/android-1.5/common/include/linux/route.h
new file mode 100644
index 0000000..cdb8744
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/route.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_ROUTE_H
+#define _LINUX_ROUTE_H
+
+#include <linux/if.h>
+#include <linux/compiler.h>
+
+struct rtentry
+{
+ unsigned long rt_pad1;
+ struct sockaddr rt_dst;
+ struct sockaddr rt_gateway;
+ struct sockaddr rt_genmask;
+ unsigned short rt_flags;
+ short rt_pad2;
+ unsigned long rt_pad3;
+ void *rt_pad4;
+ short rt_metric;
+ char __user *rt_dev;
+ unsigned long rt_mtu;
+#define rt_mss rt_mtu  
+ unsigned long rt_window;
+ unsigned short rt_irtt;
+};
+
+#define RTF_UP 0x0001  
+#define RTF_GATEWAY 0x0002  
+#define RTF_HOST 0x0004  
+#define RTF_REINSTATE 0x0008  
+#define RTF_DYNAMIC 0x0010  
+#define RTF_MODIFIED 0x0020  
+#define RTF_MTU 0x0040  
+#define RTF_MSS RTF_MTU  
+#define RTF_WINDOW 0x0080  
+#define RTF_IRTT 0x0100  
+#define RTF_REJECT 0x0200  
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/rtc.h b/ndk/build/platforms/android-1.5/common/include/linux/rtc.h
new file mode 100644
index 0000000..b51bc71
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/rtc.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_RTC_H_
+#define _LINUX_RTC_H_
+
+struct rtc_time {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+};
+
+struct rtc_wkalrm {
+ unsigned char enabled;
+ unsigned char pending;
+ struct rtc_time time;
+};
+
+struct rtc_pll_info {
+ int pll_ctrl;
+ int pll_value;
+ int pll_max;
+ int pll_min;
+ int pll_posmult;
+ int pll_negmult;
+ long pll_clock;
+};
+
+#define RTC_AIE_ON _IO('p', 0x01)  
+#define RTC_AIE_OFF _IO('p', 0x02)  
+#define RTC_UIE_ON _IO('p', 0x03)  
+#define RTC_UIE_OFF _IO('p', 0x04)  
+#define RTC_PIE_ON _IO('p', 0x05)  
+#define RTC_PIE_OFF _IO('p', 0x06)  
+#define RTC_WIE_ON _IO('p', 0x0f)  
+#define RTC_WIE_OFF _IO('p', 0x10)  
+
+#define RTC_ALM_SET _IOW('p', 0x07, struct rtc_time)  
+#define RTC_ALM_READ _IOR('p', 0x08, struct rtc_time)  
+#define RTC_RD_TIME _IOR('p', 0x09, struct rtc_time)  
+#define RTC_SET_TIME _IOW('p', 0x0a, struct rtc_time)  
+#define RTC_IRQP_READ _IOR('p', 0x0b, unsigned long)  
+#define RTC_IRQP_SET _IOW('p', 0x0c, unsigned long)  
+#define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long)  
+#define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long)  
+
+#define RTC_WKALM_SET _IOW('p', 0x0f, struct rtc_wkalrm) 
+#define RTC_WKALM_RD _IOR('p', 0x10, struct rtc_wkalrm) 
+
+#define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info)  
+#define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info)  
+
+#define RTC_IRQF 0x80  
+#define RTC_PF 0x40
+#define RTC_AF 0x20
+#define RTC_UF 0x10
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/rtnetlink.h b/ndk/build/platforms/android-1.5/common/include/linux/rtnetlink.h
new file mode 100644
index 0000000..ddcffaa
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/rtnetlink.h
@@ -0,0 +1,723 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_RTNETLINK_H
+#define __LINUX_RTNETLINK_H
+
+#include <linux/netlink.h>
+
+enum {
+ RTM_BASE = 16,
+#define RTM_BASE RTM_BASE
+
+ RTM_NEWLINK = 16,
+#define RTM_NEWLINK RTM_NEWLINK
+ RTM_DELLINK,
+#define RTM_DELLINK RTM_DELLINK
+ RTM_GETLINK,
+#define RTM_GETLINK RTM_GETLINK
+ RTM_SETLINK,
+#define RTM_SETLINK RTM_SETLINK
+
+ RTM_NEWADDR = 20,
+#define RTM_NEWADDR RTM_NEWADDR
+ RTM_DELADDR,
+#define RTM_DELADDR RTM_DELADDR
+ RTM_GETADDR,
+#define RTM_GETADDR RTM_GETADDR
+
+ RTM_NEWROUTE = 24,
+#define RTM_NEWROUTE RTM_NEWROUTE
+ RTM_DELROUTE,
+#define RTM_DELROUTE RTM_DELROUTE
+ RTM_GETROUTE,
+#define RTM_GETROUTE RTM_GETROUTE
+
+ RTM_NEWNEIGH = 28,
+#define RTM_NEWNEIGH RTM_NEWNEIGH
+ RTM_DELNEIGH,
+#define RTM_DELNEIGH RTM_DELNEIGH
+ RTM_GETNEIGH,
+#define RTM_GETNEIGH RTM_GETNEIGH
+
+ RTM_NEWRULE = 32,
+#define RTM_NEWRULE RTM_NEWRULE
+ RTM_DELRULE,
+#define RTM_DELRULE RTM_DELRULE
+ RTM_GETRULE,
+#define RTM_GETRULE RTM_GETRULE
+
+ RTM_NEWQDISC = 36,
+#define RTM_NEWQDISC RTM_NEWQDISC
+ RTM_DELQDISC,
+#define RTM_DELQDISC RTM_DELQDISC
+ RTM_GETQDISC,
+#define RTM_GETQDISC RTM_GETQDISC
+
+ RTM_NEWTCLASS = 40,
+#define RTM_NEWTCLASS RTM_NEWTCLASS
+ RTM_DELTCLASS,
+#define RTM_DELTCLASS RTM_DELTCLASS
+ RTM_GETTCLASS,
+#define RTM_GETTCLASS RTM_GETTCLASS
+
+ RTM_NEWTFILTER = 44,
+#define RTM_NEWTFILTER RTM_NEWTFILTER
+ RTM_DELTFILTER,
+#define RTM_DELTFILTER RTM_DELTFILTER
+ RTM_GETTFILTER,
+#define RTM_GETTFILTER RTM_GETTFILTER
+
+ RTM_NEWACTION = 48,
+#define RTM_NEWACTION RTM_NEWACTION
+ RTM_DELACTION,
+#define RTM_DELACTION RTM_DELACTION
+ RTM_GETACTION,
+#define RTM_GETACTION RTM_GETACTION
+
+ RTM_NEWPREFIX = 52,
+#define RTM_NEWPREFIX RTM_NEWPREFIX
+ RTM_GETPREFIX = 54,
+#define RTM_GETPREFIX RTM_GETPREFIX
+
+ RTM_GETMULTICAST = 58,
+#define RTM_GETMULTICAST RTM_GETMULTICAST
+
+ RTM_GETANYCAST = 62,
+#define RTM_GETANYCAST RTM_GETANYCAST
+
+ RTM_NEWNEIGHTBL = 64,
+#define RTM_NEWNEIGHTBL RTM_NEWNEIGHTBL
+ RTM_GETNEIGHTBL = 66,
+#define RTM_GETNEIGHTBL RTM_GETNEIGHTBL
+ RTM_SETNEIGHTBL,
+#define RTM_SETNEIGHTBL RTM_SETNEIGHTBL
+
+ __RTM_MAX,
+#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
+};
+
+#define RTM_NR_MSGTYPES (RTM_MAX + 1 - RTM_BASE)
+#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2)
+#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2)
+
+struct rtattr
+{
+ unsigned short rta_len;
+ unsigned short rta_type;
+};
+
+#define RTA_ALIGNTO 4
+#define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) )
+#define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) &&   (rta)->rta_len >= sizeof(struct rtattr) &&   (rta)->rta_len <= (len))
+#define RTA_NEXT(rta,attrlen) ((attrlen) -= RTA_ALIGN((rta)->rta_len),   (struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len)))
+#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
+#define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len))
+#define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
+#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
+
+struct rtmsg
+{
+ unsigned char rtm_family;
+ unsigned char rtm_dst_len;
+ unsigned char rtm_src_len;
+ unsigned char rtm_tos;
+
+ unsigned char rtm_table;
+ unsigned char rtm_protocol;
+ unsigned char rtm_scope;
+ unsigned char rtm_type;
+
+ unsigned rtm_flags;
+};
+
+enum
+{
+ RTN_UNSPEC,
+ RTN_UNICAST,
+ RTN_LOCAL,
+ RTN_BROADCAST,
+ RTN_ANYCAST,
+ RTN_MULTICAST,
+ RTN_BLACKHOLE,
+ RTN_UNREACHABLE,
+ RTN_PROHIBIT,
+ RTN_THROW,
+ RTN_NAT,
+ RTN_XRESOLVE,
+ __RTN_MAX
+};
+
+#define RTN_MAX (__RTN_MAX - 1)
+
+#define RTPROT_UNSPEC 0
+#define RTPROT_REDIRECT 1  
+#define RTPROT_KERNEL 2  
+#define RTPROT_BOOT 3  
+#define RTPROT_STATIC 4  
+
+#define RTPROT_GATED 8  
+#define RTPROT_RA 9  
+#define RTPROT_MRT 10  
+#define RTPROT_ZEBRA 11  
+#define RTPROT_BIRD 12  
+#define RTPROT_DNROUTED 13  
+#define RTPROT_XORP 14  
+#define RTPROT_NTK 15  
+
+enum rt_scope_t
+{
+ RT_SCOPE_UNIVERSE=0,
+
+ RT_SCOPE_SITE=200,
+ RT_SCOPE_LINK=253,
+ RT_SCOPE_HOST=254,
+ RT_SCOPE_NOWHERE=255
+};
+
+#define RTM_F_NOTIFY 0x100  
+#define RTM_F_CLONED 0x200  
+#define RTM_F_EQUALIZE 0x400  
+#define RTM_F_PREFIX 0x800  
+
+enum rt_class_t
+{
+ RT_TABLE_UNSPEC=0,
+
+ RT_TABLE_DEFAULT=253,
+ RT_TABLE_MAIN=254,
+ RT_TABLE_LOCAL=255,
+ __RT_TABLE_MAX
+};
+#define RT_TABLE_MAX (__RT_TABLE_MAX - 1)
+
+enum rtattr_type_t
+{
+ RTA_UNSPEC,
+ RTA_DST,
+ RTA_SRC,
+ RTA_IIF,
+ RTA_OIF,
+ RTA_GATEWAY,
+ RTA_PRIORITY,
+ RTA_PREFSRC,
+ RTA_METRICS,
+ RTA_MULTIPATH,
+ RTA_PROTOINFO,
+ RTA_FLOW,
+ RTA_CACHEINFO,
+ RTA_SESSION,
+ RTA_MP_ALGO,
+ __RTA_MAX
+};
+
+#define RTA_MAX (__RTA_MAX - 1)
+
+#define RTM_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
+#define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
+
+struct rtnexthop
+{
+ unsigned short rtnh_len;
+ unsigned char rtnh_flags;
+ unsigned char rtnh_hops;
+ int rtnh_ifindex;
+};
+
+#define RTNH_F_DEAD 1  
+#define RTNH_F_PERVASIVE 2  
+#define RTNH_F_ONLINK 4  
+
+#define RTNH_ALIGNTO 4
+#define RTNH_ALIGN(len) ( ((len)+RTNH_ALIGNTO-1) & ~(RTNH_ALIGNTO-1) )
+#define RTNH_OK(rtnh,len) ((rtnh)->rtnh_len >= sizeof(struct rtnexthop) &&   ((int)(rtnh)->rtnh_len) <= (len))
+#define RTNH_NEXT(rtnh) ((struct rtnexthop*)(((char*)(rtnh)) + RTNH_ALIGN((rtnh)->rtnh_len)))
+#define RTNH_LENGTH(len) (RTNH_ALIGN(sizeof(struct rtnexthop)) + (len))
+#define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len))
+#define RTNH_DATA(rtnh) ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0)))
+
+struct rta_cacheinfo
+{
+ __u32 rta_clntref;
+ __u32 rta_lastuse;
+ __s32 rta_expires;
+ __u32 rta_error;
+ __u32 rta_used;
+
+#define RTNETLINK_HAVE_PEERINFO 1
+ __u32 rta_id;
+ __u32 rta_ts;
+ __u32 rta_tsage;
+};
+
+enum
+{
+ RTAX_UNSPEC,
+#define RTAX_UNSPEC RTAX_UNSPEC
+ RTAX_LOCK,
+#define RTAX_LOCK RTAX_LOCK
+ RTAX_MTU,
+#define RTAX_MTU RTAX_MTU
+ RTAX_WINDOW,
+#define RTAX_WINDOW RTAX_WINDOW
+ RTAX_RTT,
+#define RTAX_RTT RTAX_RTT
+ RTAX_RTTVAR,
+#define RTAX_RTTVAR RTAX_RTTVAR
+ RTAX_SSTHRESH,
+#define RTAX_SSTHRESH RTAX_SSTHRESH
+ RTAX_CWND,
+#define RTAX_CWND RTAX_CWND
+ RTAX_ADVMSS,
+#define RTAX_ADVMSS RTAX_ADVMSS
+ RTAX_REORDERING,
+#define RTAX_REORDERING RTAX_REORDERING
+ RTAX_HOPLIMIT,
+#define RTAX_HOPLIMIT RTAX_HOPLIMIT
+ RTAX_INITCWND,
+#define RTAX_INITCWND RTAX_INITCWND
+ RTAX_FEATURES,
+#define RTAX_FEATURES RTAX_FEATURES
+ __RTAX_MAX
+};
+
+#define RTAX_MAX (__RTAX_MAX - 1)
+
+#define RTAX_FEATURE_ECN 0x00000001
+#define RTAX_FEATURE_SACK 0x00000002
+#define RTAX_FEATURE_TIMESTAMP 0x00000004
+#define RTAX_FEATURE_ALLFRAG 0x00000008
+
+struct rta_session
+{
+ __u8 proto;
+ __u8 pad1;
+ __u16 pad2;
+
+ union {
+ struct {
+ __u16 sport;
+ __u16 dport;
+ } ports;
+
+ struct {
+ __u8 type;
+ __u8 code;
+ __u16 ident;
+ } icmpt;
+
+ __u32 spi;
+ } u;
+};
+
+struct ifaddrmsg
+{
+ unsigned char ifa_family;
+ unsigned char ifa_prefixlen;
+ unsigned char ifa_flags;
+ unsigned char ifa_scope;
+ int ifa_index;
+};
+
+enum
+{
+ IFA_UNSPEC,
+ IFA_ADDRESS,
+ IFA_LOCAL,
+ IFA_LABEL,
+ IFA_BROADCAST,
+ IFA_ANYCAST,
+ IFA_CACHEINFO,
+ IFA_MULTICAST,
+ __IFA_MAX
+};
+
+#define IFA_MAX (__IFA_MAX - 1)
+
+#define IFA_F_SECONDARY 0x01
+#define IFA_F_TEMPORARY IFA_F_SECONDARY
+
+#define IFA_F_DEPRECATED 0x20
+#define IFA_F_TENTATIVE 0x40
+#define IFA_F_PERMANENT 0x80
+
+struct ifa_cacheinfo
+{
+ __u32 ifa_prefered;
+ __u32 ifa_valid;
+ __u32 cstamp;
+ __u32 tstamp;
+};
+
+#define IFA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
+#define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg))
+
+struct ndmsg
+{
+ unsigned char ndm_family;
+ unsigned char ndm_pad1;
+ unsigned short ndm_pad2;
+ int ndm_ifindex;
+ __u16 ndm_state;
+ __u8 ndm_flags;
+ __u8 ndm_type;
+};
+
+enum
+{
+ NDA_UNSPEC,
+ NDA_DST,
+ NDA_LLADDR,
+ NDA_CACHEINFO,
+ NDA_PROBES,
+ __NDA_MAX
+};
+
+#define NDA_MAX (__NDA_MAX - 1)
+
+#define NDA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
+#define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg))
+
+#define NTF_PROXY 0x08  
+#define NTF_ROUTER 0x80
+
+#define NUD_INCOMPLETE 0x01
+#define NUD_REACHABLE 0x02
+#define NUD_STALE 0x04
+#define NUD_DELAY 0x08
+#define NUD_PROBE 0x10
+#define NUD_FAILED 0x20
+
+#define NUD_NOARP 0x40
+#define NUD_PERMANENT 0x80
+#define NUD_NONE 0x00
+
+struct nda_cacheinfo
+{
+ __u32 ndm_confirmed;
+ __u32 ndm_used;
+ __u32 ndm_updated;
+ __u32 ndm_refcnt;
+};
+
+struct ndt_stats
+{
+ __u64 ndts_allocs;
+ __u64 ndts_destroys;
+ __u64 ndts_hash_grows;
+ __u64 ndts_res_failed;
+ __u64 ndts_lookups;
+ __u64 ndts_hits;
+ __u64 ndts_rcv_probes_mcast;
+ __u64 ndts_rcv_probes_ucast;
+ __u64 ndts_periodic_gc_runs;
+ __u64 ndts_forced_gc_runs;
+};
+
+enum {
+ NDTPA_UNSPEC,
+ NDTPA_IFINDEX,
+ NDTPA_REFCNT,
+ NDTPA_REACHABLE_TIME,
+ NDTPA_BASE_REACHABLE_TIME,
+ NDTPA_RETRANS_TIME,
+ NDTPA_GC_STALETIME,
+ NDTPA_DELAY_PROBE_TIME,
+ NDTPA_QUEUE_LEN,
+ NDTPA_APP_PROBES,
+ NDTPA_UCAST_PROBES,
+ NDTPA_MCAST_PROBES,
+ NDTPA_ANYCAST_DELAY,
+ NDTPA_PROXY_DELAY,
+ NDTPA_PROXY_QLEN,
+ NDTPA_LOCKTIME,
+ __NDTPA_MAX
+};
+#define NDTPA_MAX (__NDTPA_MAX - 1)
+
+struct ndtmsg
+{
+ __u8 ndtm_family;
+ __u8 ndtm_pad1;
+ __u16 ndtm_pad2;
+};
+
+struct ndt_config
+{
+ __u16 ndtc_key_len;
+ __u16 ndtc_entry_size;
+ __u32 ndtc_entries;
+ __u32 ndtc_last_flush;
+ __u32 ndtc_last_rand;
+ __u32 ndtc_hash_rnd;
+ __u32 ndtc_hash_mask;
+ __u32 ndtc_hash_chain_gc;
+ __u32 ndtc_proxy_qlen;
+};
+
+enum {
+ NDTA_UNSPEC,
+ NDTA_NAME,
+ NDTA_THRESH1,
+ NDTA_THRESH2,
+ NDTA_THRESH3,
+ NDTA_CONFIG,
+ NDTA_PARMS,
+ NDTA_STATS,
+ NDTA_GC_INTERVAL,
+ __NDTA_MAX
+};
+#define NDTA_MAX (__NDTA_MAX - 1)
+
+#define NDTA_RTA(r) ((struct rtattr*)(((char*)(r)) +   NLMSG_ALIGN(sizeof(struct ndtmsg))))
+#define NDTA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndtmsg))
+
+struct rtgenmsg
+{
+ unsigned char rtgen_family;
+};
+
+struct ifinfomsg
+{
+ unsigned char ifi_family;
+ unsigned char __ifi_pad;
+ unsigned short ifi_type;
+ int ifi_index;
+ unsigned ifi_flags;
+ unsigned ifi_change;
+};
+
+struct prefixmsg
+{
+ unsigned char prefix_family;
+ unsigned char prefix_pad1;
+ unsigned short prefix_pad2;
+ int prefix_ifindex;
+ unsigned char prefix_type;
+ unsigned char prefix_len;
+ unsigned char prefix_flags;
+ unsigned char prefix_pad3;
+};
+
+enum
+{
+ PREFIX_UNSPEC,
+ PREFIX_ADDRESS,
+ PREFIX_CACHEINFO,
+ __PREFIX_MAX
+};
+
+#define PREFIX_MAX (__PREFIX_MAX - 1)
+
+struct prefix_cacheinfo
+{
+ __u32 preferred_time;
+ __u32 valid_time;
+};
+
+struct rtnl_link_stats
+{
+ __u32 rx_packets;
+ __u32 tx_packets;
+ __u32 rx_bytes;
+ __u32 tx_bytes;
+ __u32 rx_errors;
+ __u32 tx_errors;
+ __u32 rx_dropped;
+ __u32 tx_dropped;
+ __u32 multicast;
+ __u32 collisions;
+
+ __u32 rx_length_errors;
+ __u32 rx_over_errors;
+ __u32 rx_crc_errors;
+ __u32 rx_frame_errors;
+ __u32 rx_fifo_errors;
+ __u32 rx_missed_errors;
+
+ __u32 tx_aborted_errors;
+ __u32 tx_carrier_errors;
+ __u32 tx_fifo_errors;
+ __u32 tx_heartbeat_errors;
+ __u32 tx_window_errors;
+
+ __u32 rx_compressed;
+ __u32 tx_compressed;
+};
+
+struct rtnl_link_ifmap
+{
+ __u64 mem_start;
+ __u64 mem_end;
+ __u64 base_addr;
+ __u16 irq;
+ __u8 dma;
+ __u8 port;
+};
+
+enum
+{
+ IFLA_UNSPEC,
+ IFLA_ADDRESS,
+ IFLA_BROADCAST,
+ IFLA_IFNAME,
+ IFLA_MTU,
+ IFLA_LINK,
+ IFLA_QDISC,
+ IFLA_STATS,
+ IFLA_COST,
+#define IFLA_COST IFLA_COST
+ IFLA_PRIORITY,
+#define IFLA_PRIORITY IFLA_PRIORITY
+ IFLA_MASTER,
+#define IFLA_MASTER IFLA_MASTER
+ IFLA_WIRELESS,
+#define IFLA_WIRELESS IFLA_WIRELESS
+ IFLA_PROTINFO,
+#define IFLA_PROTINFO IFLA_PROTINFO
+ IFLA_TXQLEN,
+#define IFLA_TXQLEN IFLA_TXQLEN
+ IFLA_MAP,
+#define IFLA_MAP IFLA_MAP
+ IFLA_WEIGHT,
+#define IFLA_WEIGHT IFLA_WEIGHT
+ IFLA_OPERSTATE,
+ IFLA_LINKMODE,
+ __IFLA_MAX
+};
+
+#define IFLA_MAX (__IFLA_MAX - 1)
+
+#define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
+#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
+
+enum
+{
+ IFLA_INET6_UNSPEC,
+ IFLA_INET6_FLAGS,
+ IFLA_INET6_CONF,
+ IFLA_INET6_STATS,
+ IFLA_INET6_MCAST,
+ IFLA_INET6_CACHEINFO,
+ __IFLA_INET6_MAX
+};
+
+#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
+
+struct ifla_cacheinfo
+{
+ __u32 max_reasm_len;
+ __u32 tstamp;
+ __u32 reachable_time;
+ __u32 retrans_time;
+};
+
+struct tcmsg
+{
+ unsigned char tcm_family;
+ unsigned char tcm__pad1;
+ unsigned short tcm__pad2;
+ int tcm_ifindex;
+ __u32 tcm_handle;
+ __u32 tcm_parent;
+ __u32 tcm_info;
+};
+
+enum
+{
+ TCA_UNSPEC,
+ TCA_KIND,
+ TCA_OPTIONS,
+ TCA_STATS,
+ TCA_XSTATS,
+ TCA_RATE,
+ TCA_FCNT,
+ TCA_STATS2,
+ __TCA_MAX
+};
+
+#define TCA_MAX (__TCA_MAX - 1)
+
+#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
+#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
+
+#define RTMGRP_LINK 1
+#define RTMGRP_NOTIFY 2
+#define RTMGRP_NEIGH 4
+#define RTMGRP_TC 8
+
+#define RTMGRP_IPV4_IFADDR 0x10
+#define RTMGRP_IPV4_MROUTE 0x20
+#define RTMGRP_IPV4_ROUTE 0x40
+#define RTMGRP_IPV4_RULE 0x80
+
+#define RTMGRP_IPV6_IFADDR 0x100
+#define RTMGRP_IPV6_MROUTE 0x200
+#define RTMGRP_IPV6_ROUTE 0x400
+#define RTMGRP_IPV6_IFINFO 0x800
+
+#define RTMGRP_DECnet_IFADDR 0x1000
+#define RTMGRP_DECnet_ROUTE 0x4000
+
+#define RTMGRP_IPV6_PREFIX 0x20000
+
+enum rtnetlink_groups {
+ RTNLGRP_NONE,
+#define RTNLGRP_NONE RTNLGRP_NONE
+ RTNLGRP_LINK,
+#define RTNLGRP_LINK RTNLGRP_LINK
+ RTNLGRP_NOTIFY,
+#define RTNLGRP_NOTIFY RTNLGRP_NOTIFY
+ RTNLGRP_NEIGH,
+#define RTNLGRP_NEIGH RTNLGRP_NEIGH
+ RTNLGRP_TC,
+#define RTNLGRP_TC RTNLGRP_TC
+ RTNLGRP_IPV4_IFADDR,
+#define RTNLGRP_IPV4_IFADDR RTNLGRP_IPV4_IFADDR
+ RTNLGRP_IPV4_MROUTE,
+#define RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_MROUTE
+ RTNLGRP_IPV4_ROUTE,
+#define RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_ROUTE
+ RTNLGRP_IPV4_RULE,
+#define RTNLGRP_IPV4_RULE RTNLGRP_IPV4_RULE
+ RTNLGRP_IPV6_IFADDR,
+#define RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_IFADDR
+ RTNLGRP_IPV6_MROUTE,
+#define RTNLGRP_IPV6_MROUTE RTNLGRP_IPV6_MROUTE
+ RTNLGRP_IPV6_ROUTE,
+#define RTNLGRP_IPV6_ROUTE RTNLGRP_IPV6_ROUTE
+ RTNLGRP_IPV6_IFINFO,
+#define RTNLGRP_IPV6_IFINFO RTNLGRP_IPV6_IFINFO
+ RTNLGRP_DECnet_IFADDR,
+#define RTNLGRP_DECnet_IFADDR RTNLGRP_DECnet_IFADDR
+ RTNLGRP_NOP2,
+ RTNLGRP_DECnet_ROUTE,
+#define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE
+ RTNLGRP_NOP3,
+ RTNLGRP_NOP4,
+ RTNLGRP_IPV6_PREFIX,
+#define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX
+ __RTNLGRP_MAX
+};
+#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
+
+struct tcamsg
+{
+ unsigned char tca_family;
+ unsigned char tca__pad1;
+ unsigned short tca__pad2;
+};
+#define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg))))
+#define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg))
+#define TCA_ACT_TAB 1   
+#define TCAA_MAX 1
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/rwsem.h b/ndk/build/platforms/android-1.5/common/include/linux/rwsem.h
new file mode 100644
index 0000000..e64c4c8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/rwsem.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_RWSEM_H
+#define _LINUX_RWSEM_H
+
+#include <linux/linkage.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sched.h b/ndk/build/platforms/android-1.5/common/include/linux/sched.h
new file mode 100644
index 0000000..6b781eb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sched.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SCHED_H
+#define _LINUX_SCHED_H
+
+#include <linux/auxvec.h>  
+
+#define CSIGNAL 0x000000ff  
+#define CLONE_VM 0x00000100  
+#define CLONE_FS 0x00000200  
+#define CLONE_FILES 0x00000400  
+#define CLONE_SIGHAND 0x00000800  
+#define CLONE_PTRACE 0x00002000  
+#define CLONE_VFORK 0x00004000  
+#define CLONE_PARENT 0x00008000  
+#define CLONE_THREAD 0x00010000  
+#define CLONE_NEWNS 0x00020000  
+#define CLONE_SYSVSEM 0x00040000  
+#define CLONE_SETTLS 0x00080000  
+#define CLONE_PARENT_SETTID 0x00100000  
+#define CLONE_CHILD_CLEARTID 0x00200000  
+#define CLONE_DETACHED 0x00400000  
+#define CLONE_UNTRACED 0x00800000  
+#define CLONE_CHILD_SETTID 0x01000000  
+#define CLONE_STOPPED 0x02000000  
+
+#define SCHED_NORMAL 0
+#define SCHED_FIFO 1
+#define SCHED_RR 2
+#define SCHED_BATCH 3
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sem.h b/ndk/build/platforms/android-1.5/common/include/linux/sem.h
new file mode 100644
index 0000000..dfa531b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sem.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SEM_H
+#define _LINUX_SEM_H
+
+#include <linux/ipc.h>
+
+#define SEM_UNDO 0x1000  
+
+#define GETPID 11  
+#define GETVAL 12  
+#define GETALL 13  
+#define GETNCNT 14  
+#define GETZCNT 15  
+#define SETVAL 16  
+#define SETALL 17  
+
+#define SEM_STAT 18
+#define SEM_INFO 19
+
+struct semid_ds {
+ struct ipc_perm sem_perm;
+ __kernel_time_t sem_otime;
+ __kernel_time_t sem_ctime;
+ struct sem *sem_base;
+ struct sem_queue *sem_pending;
+ struct sem_queue **sem_pending_last;
+ struct sem_undo *undo;
+ unsigned short sem_nsems;
+};
+
+#include <asm/sembuf.h>
+
+struct sembuf {
+ unsigned short sem_num;
+ short sem_op;
+ short sem_flg;
+};
+
+union semun {
+ int val;
+ struct semid_ds __user *buf;
+ unsigned short __user *array;
+ struct seminfo __user *__buf;
+ void __user *__pad;
+};
+
+struct seminfo {
+ int semmap;
+ int semmni;
+ int semmns;
+ int semmnu;
+ int semmsl;
+ int semopm;
+ int semume;
+ int semusz;
+ int semvmx;
+ int semaem;
+};
+
+#define SEMMNI 128  
+#define SEMMSL 250  
+#define SEMMNS (SEMMNI*SEMMSL)  
+#define SEMOPM 32  
+#define SEMVMX 32767  
+#define SEMAEM SEMVMX  
+
+#define SEMUME SEMOPM  
+#define SEMMNU SEMMNS  
+#define SEMMAP SEMMNS  
+#define SEMUSZ 20  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/seq_file.h b/ndk/build/platforms/android-1.5/common/include/linux/seq_file.h
new file mode 100644
index 0000000..81e314d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/seq_file.h
@@ -0,0 +1,14 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SEQ_FILE_H
+#define _LINUX_SEQ_FILE_H
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/seqlock.h b/ndk/build/platforms/android-1.5/common/include/linux/seqlock.h
new file mode 100644
index 0000000..a1e05d4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/seqlock.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_SEQLOCK_H
+#define __LINUX_SEQLOCK_H
+
+#include <linux/spinlock.h>
+#include <linux/preempt.h>
+
+typedef struct {
+ unsigned sequence;
+ spinlock_t lock;
+} seqlock_t;
+
+#define __SEQLOCK_UNLOCKED(lockname)   { 0, __SPIN_LOCK_UNLOCKED(lockname) }
+
+#define SEQLOCK_UNLOCKED   __SEQLOCK_UNLOCKED(old_style_seqlock_init)
+
+#define seqlock_init(x)   do { *(x) = (seqlock_t) __SEQLOCK_UNLOCKED(x); } while (0)
+
+#define DEFINE_SEQLOCK(x)   seqlock_t x = __SEQLOCK_UNLOCKED(x)
+
+#define SEQCNT_ZERO { 0 }
+#define seqcount_init(x) do { *(x) = (seqcount_t) SEQCNT_ZERO; } while (0)
+
+#define write_seqlock_irqsave(lock, flags)   do { local_irq_save(flags); write_seqlock(lock); } while (0)
+#define write_seqlock_irq(lock)   do { local_irq_disable(); write_seqlock(lock); } while (0)
+#define write_seqlock_bh(lock)   do { local_bh_disable(); write_seqlock(lock); } while (0)
+#define write_sequnlock_irqrestore(lock, flags)   do { write_sequnlock(lock); local_irq_restore(flags); } while(0)
+#define write_sequnlock_irq(lock)   do { write_sequnlock(lock); local_irq_enable(); } while(0)
+#define write_sequnlock_bh(lock)   do { write_sequnlock(lock); local_bh_enable(); } while(0)
+#define read_seqbegin_irqsave(lock, flags)   ({ local_irq_save(flags); read_seqbegin(lock); })
+#define read_seqretry_irqrestore(lock, iv, flags)   ({   int ret = read_seqretry(lock, iv);   local_irq_restore(flags);   ret;   })
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/serial_core.h b/ndk/build/platforms/android-1.5/common/include/linux/serial_core.h
new file mode 100644
index 0000000..79f0375
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/serial_core.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef LINUX_SERIAL_CORE_H
+#define LINUX_SERIAL_CORE_H
+
+#define PORT_UNKNOWN 0
+#define PORT_8250 1
+#define PORT_16450 2
+#define PORT_16550 3
+#define PORT_16550A 4
+#define PORT_CIRRUS 5
+#define PORT_16650 6
+#define PORT_16650V2 7
+#define PORT_16750 8
+#define PORT_STARTECH 9
+#define PORT_16C950 10
+#define PORT_16654 11
+#define PORT_16850 12
+#define PORT_RSA 13
+#define PORT_NS16550A 14
+#define PORT_XSCALE 15
+#define PORT_MAX_8250 15  
+
+#define PORT_PXA 31
+#define PORT_AMBA 32
+#define PORT_CLPS711X 33
+#define PORT_SA1100 34
+#define PORT_UART00 35
+#define PORT_21285 37
+
+#define PORT_SUNZILOG 38
+#define PORT_SUNSAB 39
+
+#define PORT_V850E_UART 40
+
+#define PORT_DZ 47
+
+#define PORT_MUX 48
+
+#define PORT_AT91 49
+
+#define PORT_MAC_ZILOG 50  
+#define PORT_PMAC_ZILOG 51
+
+#define PORT_SCI 52
+#define PORT_SCIF 53
+#define PORT_IRDA 54
+
+#define PORT_S3C2410 55
+
+#define PORT_IP22ZILOG 56
+
+#define PORT_LH7A40X 57
+
+#define PORT_CPM 58
+
+#define PORT_MPC52xx 59
+
+#define PORT_ICOM 60
+
+#define PORT_S3C2440 61
+
+#define PORT_IMX 62
+
+#define PORT_MPSC 63
+
+#define PORT_TXX9 64
+
+#define PORT_VR41XX_SIU 65
+#define PORT_VR41XX_DSIU 66
+
+#define PORT_S3C2400 67
+
+#define PORT_M32R_SIO 68
+
+#define PORT_JSM 69
+
+#define PORT_IP3106 70
+
+#define PORT_NETX 71
+
+#define PORT_SUNHV 72
+
+#define PORT_S3C2412 73
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/serial_reg.h b/ndk/build/platforms/android-1.5/common/include/linux/serial_reg.h
new file mode 100644
index 0000000..97b149a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/serial_reg.h
@@ -0,0 +1,249 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SERIAL_REG_H
+#define _LINUX_SERIAL_REG_H
+
+#define UART_RX 0  
+#define UART_TX 0  
+
+#define UART_IER 1  
+#define UART_IER_MSI 0x08  
+#define UART_IER_RLSI 0x04  
+#define UART_IER_THRI 0x02  
+#define UART_IER_RDI 0x01  
+
+#define UART_IERX_SLEEP 0x10  
+
+#define UART_IIR 2  
+#define UART_IIR_NO_INT 0x01  
+#define UART_IIR_ID 0x06  
+#define UART_IIR_MSI 0x00  
+#define UART_IIR_THRI 0x02  
+#define UART_IIR_RDI 0x04  
+#define UART_IIR_RLSI 0x06  
+
+#define UART_FCR 2  
+#define UART_FCR_ENABLE_FIFO 0x01  
+#define UART_FCR_CLEAR_RCVR 0x02  
+#define UART_FCR_CLEAR_XMIT 0x04  
+#define UART_FCR_DMA_SELECT 0x08  
+
+#define UART_FCR_R_TRIG_00 0x00
+#define UART_FCR_R_TRIG_01 0x40
+#define UART_FCR_R_TRIG_10 0x80
+#define UART_FCR_R_TRIG_11 0xc0
+#define UART_FCR_T_TRIG_00 0x00
+#define UART_FCR_T_TRIG_01 0x10
+#define UART_FCR_T_TRIG_10 0x20
+#define UART_FCR_T_TRIG_11 0x30
+
+#define UART_FCR_TRIGGER_MASK 0xC0  
+#define UART_FCR_TRIGGER_1 0x00  
+#define UART_FCR_TRIGGER_4 0x40  
+#define UART_FCR_TRIGGER_8 0x80  
+#define UART_FCR_TRIGGER_14 0xC0  
+
+#define UART_FCR6_R_TRIGGER_8 0x00  
+#define UART_FCR6_R_TRIGGER_16 0x40  
+#define UART_FCR6_R_TRIGGER_24 0x80  
+#define UART_FCR6_R_TRIGGER_28 0xC0  
+#define UART_FCR6_T_TRIGGER_16 0x00  
+#define UART_FCR6_T_TRIGGER_8 0x10  
+#define UART_FCR6_T_TRIGGER_24 0x20  
+#define UART_FCR6_T_TRIGGER_30 0x30  
+#define UART_FCR7_64BYTE 0x20  
+
+#define UART_LCR 3  
+
+#define UART_LCR_DLAB 0x80  
+#define UART_LCR_SBC 0x40  
+#define UART_LCR_SPAR 0x20  
+#define UART_LCR_EPAR 0x10  
+#define UART_LCR_PARITY 0x08  
+#define UART_LCR_STOP 0x04  
+#define UART_LCR_WLEN5 0x00  
+#define UART_LCR_WLEN6 0x01  
+#define UART_LCR_WLEN7 0x02  
+#define UART_LCR_WLEN8 0x03  
+
+#define UART_MCR 4  
+#define UART_MCR_CLKSEL 0x80  
+#define UART_MCR_TCRTLR 0x40  
+#define UART_MCR_XONANY 0x20  
+#define UART_MCR_AFE 0x20  
+#define UART_MCR_LOOP 0x10  
+#define UART_MCR_OUT2 0x08  
+#define UART_MCR_OUT1 0x04  
+#define UART_MCR_RTS 0x02  
+#define UART_MCR_DTR 0x01  
+
+#define UART_LSR 5  
+#define UART_LSR_TEMT 0x40  
+#define UART_LSR_THRE 0x20  
+#define UART_LSR_BI 0x10  
+#define UART_LSR_FE 0x08  
+#define UART_LSR_PE 0x04  
+#define UART_LSR_OE 0x02  
+#define UART_LSR_DR 0x01  
+
+#define UART_MSR 6  
+#define UART_MSR_DCD 0x80  
+#define UART_MSR_RI 0x40  
+#define UART_MSR_DSR 0x20  
+#define UART_MSR_CTS 0x10  
+#define UART_MSR_DDCD 0x08  
+#define UART_MSR_TERI 0x04  
+#define UART_MSR_DDSR 0x02  
+#define UART_MSR_DCTS 0x01  
+#define UART_MSR_ANY_DELTA 0x0F  
+
+#define UART_SCR 7  
+
+#define UART_DLL 0  
+#define UART_DLM 1  
+
+#define UART_EFR 2  
+#define UART_EFR_CTS 0x80  
+#define UART_EFR_RTS 0x40  
+#define UART_EFR_SCD 0x20  
+#define UART_EFR_ECB 0x10  
+
+#define UART_XON1 4  
+#define UART_XON2 5  
+#define UART_XOFF1 6  
+#define UART_XOFF2 7  
+
+#define UART_TI752_TCR 6  
+#define UART_TI752_TLR 7  
+
+#define UART_TRG 0  
+
+#define UART_TRG_1 0x01
+#define UART_TRG_4 0x04
+#define UART_TRG_8 0x08
+#define UART_TRG_16 0x10
+#define UART_TRG_32 0x20
+#define UART_TRG_64 0x40
+#define UART_TRG_96 0x60
+#define UART_TRG_120 0x78
+#define UART_TRG_128 0x80
+
+#define UART_FCTR 1  
+#define UART_FCTR_RTS_NODELAY 0x00  
+#define UART_FCTR_RTS_4DELAY 0x01
+#define UART_FCTR_RTS_6DELAY 0x02
+#define UART_FCTR_RTS_8DELAY 0x03
+#define UART_FCTR_IRDA 0x04  
+#define UART_FCTR_TX_INT 0x08  
+#define UART_FCTR_TRGA 0x00  
+#define UART_FCTR_TRGB 0x10  
+#define UART_FCTR_TRGC 0x20  
+#define UART_FCTR_TRGD 0x30  
+#define UART_FCTR_SCR_SWAP 0x40  
+#define UART_FCTR_RX 0x00  
+#define UART_FCTR_TX 0x80  
+
+#define UART_EMSR 7  
+#define UART_EMSR_FIFO_COUNT 0x01  
+#define UART_EMSR_ALT_COUNT 0x02  
+
+#define UART_IER_DMAE 0x80  
+#define UART_IER_UUE 0x40  
+#define UART_IER_NRZE 0x20  
+#define UART_IER_RTOIE 0x10  
+
+#define UART_IIR_TOD 0x08  
+
+#define UART_FCR_PXAR1 0x00  
+#define UART_FCR_PXAR8 0x40  
+#define UART_FCR_PXAR16 0x80  
+#define UART_FCR_PXAR32 0xc0  
+
+#define UART_ASR 0x01  
+#define UART_RFL 0x03  
+#define UART_TFL 0x04  
+#define UART_ICR 0x05  
+
+#define UART_ACR 0x00  
+#define UART_CPR 0x01  
+#define UART_TCR 0x02  
+#define UART_CKS 0x03  
+#define UART_TTL 0x04  
+#define UART_RTL 0x05  
+#define UART_FCL 0x06  
+#define UART_FCH 0x07  
+#define UART_ID1 0x08  
+#define UART_ID2 0x09  
+#define UART_ID3 0x0A  
+#define UART_REV 0x0B  
+#define UART_CSR 0x0C  
+#define UART_NMR 0x0D  
+#define UART_CTR 0xFF
+
+#define UART_ACR_RXDIS 0x01  
+#define UART_ACR_TXDIS 0x02  
+#define UART_ACR_DSRFC 0x04  
+#define UART_ACR_TLENB 0x20  
+#define UART_ACR_ICRRD 0x40  
+#define UART_ACR_ASREN 0x80  
+
+#define UART_RSA_BASE (-8)
+
+#define UART_RSA_MSR ((UART_RSA_BASE) + 0)  
+
+#define UART_RSA_MSR_SWAP (1 << 0)  
+#define UART_RSA_MSR_FIFO (1 << 2)  
+#define UART_RSA_MSR_FLOW (1 << 3)  
+#define UART_RSA_MSR_ITYP (1 << 4)  
+
+#define UART_RSA_IER ((UART_RSA_BASE) + 1)  
+
+#define UART_RSA_IER_Rx_FIFO_H (1 << 0)  
+#define UART_RSA_IER_Tx_FIFO_H (1 << 1)  
+#define UART_RSA_IER_Tx_FIFO_E (1 << 2)  
+#define UART_RSA_IER_Rx_TOUT (1 << 3)  
+#define UART_RSA_IER_TIMER (1 << 4)  
+
+#define UART_RSA_SRR ((UART_RSA_BASE) + 2)  
+
+#define UART_RSA_SRR_Tx_FIFO_NEMP (1 << 0)  
+#define UART_RSA_SRR_Tx_FIFO_NHFL (1 << 1)  
+#define UART_RSA_SRR_Tx_FIFO_NFUL (1 << 2)  
+#define UART_RSA_SRR_Rx_FIFO_NEMP (1 << 3)  
+#define UART_RSA_SRR_Rx_FIFO_NHFL (1 << 4)  
+#define UART_RSA_SRR_Rx_FIFO_NFUL (1 << 5)  
+#define UART_RSA_SRR_Rx_TOUT (1 << 6)  
+#define UART_RSA_SRR_TIMER (1 << 7)  
+
+#define UART_RSA_FRR ((UART_RSA_BASE) + 2)  
+
+#define UART_RSA_TIVSR ((UART_RSA_BASE) + 3)  
+
+#define UART_RSA_TCR ((UART_RSA_BASE) + 4)  
+
+#define UART_RSA_TCR_SWITCH (1 << 0)  
+
+#define SERIAL_RSA_BAUD_BASE (921600)
+#define SERIAL_RSA_BAUD_BASE_LO (SERIAL_RSA_BAUD_BASE / 8)
+
+#define UART_OMAP_MDR1 0x08  
+#define UART_OMAP_MDR2 0x09  
+#define UART_OMAP_SCR 0x10  
+#define UART_OMAP_SSR 0x11  
+#define UART_OMAP_EBLR 0x12  
+#define UART_OMAP_OSC_12M_SEL 0x13  
+#define UART_OMAP_MVER 0x14  
+#define UART_OMAP_SYSC 0x15  
+#define UART_OMAP_SYSS 0x16  
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/serio.h b/ndk/build/platforms/android-1.5/common/include/linux/serio.h
new file mode 100644
index 0000000..7f04987
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/serio.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _SERIO_H
+#define _SERIO_H
+
+#include <linux/ioctl.h>
+
+#define SPIOCSTYPE _IOW('q', 0x01, unsigned long)
+
+#define SERIO_TIMEOUT 1
+#define SERIO_PARITY 2
+#define SERIO_FRAME 4
+
+#define SERIO_XT 0x00
+#define SERIO_8042 0x01
+#define SERIO_RS232 0x02
+#define SERIO_HIL_MLC 0x03
+#define SERIO_PS_PSTHRU 0x05
+#define SERIO_8042_XL 0x06
+
+#define SERIO_UNKNOWN 0x00
+#define SERIO_MSC 0x01
+#define SERIO_SUN 0x02
+#define SERIO_MS 0x03
+#define SERIO_MP 0x04
+#define SERIO_MZ 0x05
+#define SERIO_MZP 0x06
+#define SERIO_MZPP 0x07
+#define SERIO_VSXXXAA 0x08
+#define SERIO_SUNKBD 0x10
+#define SERIO_WARRIOR 0x18
+#define SERIO_SPACEORB 0x19
+#define SERIO_MAGELLAN 0x1a
+#define SERIO_SPACEBALL 0x1b
+#define SERIO_GUNZE 0x1c
+#define SERIO_IFORCE 0x1d
+#define SERIO_STINGER 0x1e
+#define SERIO_NEWTON 0x1f
+#define SERIO_STOWAWAY 0x20
+#define SERIO_H3600 0x21
+#define SERIO_PS2SER 0x22
+#define SERIO_TWIDKBD 0x23
+#define SERIO_TWIDJOY 0x24
+#define SERIO_HIL 0x25
+#define SERIO_SNES232 0x26
+#define SERIO_SEMTECH 0x27
+#define SERIO_LKKBD 0x28
+#define SERIO_ELO 0x29
+#define SERIO_MICROTOUCH 0x30
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/shm.h b/ndk/build/platforms/android-1.5/common/include/linux/shm.h
new file mode 100644
index 0000000..a7056db
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/shm.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SHM_H_
+#define _LINUX_SHM_H_
+
+#include <linux/ipc.h>
+#include <linux/errno.h>
+#include <asm/page.h>
+
+#define SHMMAX 0x2000000  
+#define SHMMIN 1  
+#define SHMMNI 4096  
+#define SHMALL (SHMMAX/PAGE_SIZE*(SHMMNI/16))  
+#define SHMSEG SHMMNI  
+
+#include <asm/shmparam.h>
+
+struct shmid_ds {
+ struct ipc_perm shm_perm;
+ int shm_segsz;
+ __kernel_time_t shm_atime;
+ __kernel_time_t shm_dtime;
+ __kernel_time_t shm_ctime;
+ __kernel_ipc_pid_t shm_cpid;
+ __kernel_ipc_pid_t shm_lpid;
+ unsigned short shm_nattch;
+ unsigned short shm_unused;
+ void *shm_unused2;
+ void *shm_unused3;
+};
+
+#include <asm/shmbuf.h>
+
+#define SHM_R 0400  
+#define SHM_W 0200  
+
+#define SHM_RDONLY 010000  
+#define SHM_RND 020000  
+#define SHM_REMAP 040000  
+#define SHM_EXEC 0100000  
+
+#define SHM_LOCK 11
+#define SHM_UNLOCK 12
+
+#define SHM_STAT 13
+#define SHM_INFO 14
+
+struct shminfo {
+ int shmmax;
+ int shmmin;
+ int shmmni;
+ int shmseg;
+ int shmall;
+};
+
+struct shm_info {
+ int used_ids;
+ unsigned long shm_tot;
+ unsigned long shm_rss;
+ unsigned long shm_swp;
+ unsigned long swap_attempts;
+ unsigned long swap_successes;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/signal.h b/ndk/build/platforms/android-1.5/common/include/linux/signal.h
new file mode 100644
index 0000000..4577e54
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/signal.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SIGNAL_H
+#define _LINUX_SIGNAL_H
+
+#include <asm/signal.h>
+#include <asm/siginfo.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/skbuff.h b/ndk/build/platforms/android-1.5/common/include/linux/skbuff.h
new file mode 100644
index 0000000..82140a6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/skbuff.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SKBUFF_H
+#define _LINUX_SKBUFF_H
+
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/time.h>
+#include <linux/cache.h>
+
+#include <asm/atomic.h>
+#include <asm/types.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>
+#include <linux/poll.h>
+#include <linux/net.h>
+#include <linux/textsearch.h>
+#include <net/checksum.h>
+#include <linux/dmaengine.h>
+
+#define HAVE_ALLOC_SKB  
+#define HAVE_ALIGNABLE_SKB  
+
+#define CHECKSUM_NONE 0
+#define CHECKSUM_HW 1
+#define CHECKSUM_UNNECESSARY 2
+
+#define SKB_DATA_ALIGN(X) (((X) + (SMP_CACHE_BYTES - 1)) &   ~(SMP_CACHE_BYTES - 1))
+#define SKB_MAX_ORDER(X, ORDER) (((PAGE_SIZE << (ORDER)) - (X) -   sizeof(struct skb_shared_info)) &   ~(SMP_CACHE_BYTES - 1))
+#define SKB_MAX_HEAD(X) (SKB_MAX_ORDER((X), 0))
+#define SKB_MAX_ALLOC (SKB_MAX_ORDER(0, 2))
+
+struct net_device;
+
+struct sk_buff_head {
+
+ struct sk_buff *next;
+ struct sk_buff *prev;
+
+ __u32 qlen;
+ spinlock_t lock;
+};
+
+struct sk_buff;
+
+#define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2)
+
+typedef struct skb_frag_struct skb_frag_t;
+
+struct skb_frag_struct {
+ struct page *page;
+ __u16 page_offset;
+ __u16 size;
+};
+
+struct skb_shared_info {
+ atomic_t dataref;
+ unsigned short nr_frags;
+ unsigned short gso_size;
+
+ unsigned short gso_segs;
+ unsigned short gso_type;
+ unsigned int ip6_frag_id;
+ struct sk_buff *frag_list;
+ skb_frag_t frags[MAX_SKB_FRAGS];
+};
+
+#define SKB_DATAREF_SHIFT 16
+#define SKB_DATAREF_MASK ((1 << SKB_DATAREF_SHIFT) - 1)
+
+struct skb_timeval {
+ u32 off_sec;
+ u32 off_usec;
+};
+
+enum {
+ SKB_FCLONE_UNAVAILABLE,
+ SKB_FCLONE_ORIG,
+ SKB_FCLONE_CLONE,
+};
+
+enum {
+ SKB_GSO_TCPV4 = 1 << 0,
+ SKB_GSO_UDP = 1 << 1,
+
+ SKB_GSO_DODGY = 1 << 2,
+
+ SKB_GSO_TCP_ECN = 1 << 3,
+
+ SKB_GSO_TCPV6 = 1 << 4,
+};
+
+struct sk_buff {
+
+ struct sk_buff *next;
+ struct sk_buff *prev;
+
+ struct sock *sk;
+ struct skb_timeval tstamp;
+ struct net_device *dev;
+ struct net_device *input_dev;
+
+ union {
+ struct tcphdr *th;
+ struct udphdr *uh;
+ struct icmphdr *icmph;
+ struct igmphdr *igmph;
+ struct iphdr *ipiph;
+ struct ipv6hdr *ipv6h;
+ unsigned char *raw;
+ } h;
+
+ union {
+ struct iphdr *iph;
+ struct ipv6hdr *ipv6h;
+ struct arphdr *arph;
+ unsigned char *raw;
+ } nh;
+
+ union {
+ unsigned char *raw;
+ } mac;
+
+ struct dst_entry *dst;
+ struct sec_path *sp;
+
+ char cb[48];
+
+ unsigned int len,
+ data_len,
+ mac_len,
+ csum;
+ __u32 priority;
+ __u8 local_df:1,
+ cloned:1,
+ ip_summed:2,
+ nohdr:1,
+ nfctinfo:3;
+ __u8 pkt_type:3,
+ fclone:2,
+ ipvs_property:1;
+ __be16 protocol;
+
+ void (*destructor)(struct sk_buff *skb);
+
+ unsigned int truesize;
+ atomic_t users;
+ unsigned char *head,
+ *data,
+ *tail,
+ *end;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/slab.h b/ndk/build/platforms/android-1.5/common/include/linux/slab.h
new file mode 100644
index 0000000..f165a93
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/slab.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SLAB_H
+#define _LINUX_SLAB_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/smb.h b/ndk/build/platforms/android-1.5/common/include/linux/smb.h
new file mode 100644
index 0000000..72c8967
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/smb.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SMB_H
+#define _LINUX_SMB_H
+
+#include <linux/types.h>
+
+enum smb_protocol {
+ SMB_PROTOCOL_NONE,
+ SMB_PROTOCOL_CORE,
+ SMB_PROTOCOL_COREPLUS,
+ SMB_PROTOCOL_LANMAN1,
+ SMB_PROTOCOL_LANMAN2,
+ SMB_PROTOCOL_NT1
+};
+
+enum smb_case_hndl {
+ SMB_CASE_DEFAULT,
+ SMB_CASE_LOWER,
+ SMB_CASE_UPPER
+};
+
+struct smb_dskattr {
+ __u16 total;
+ __u16 allocblocks;
+ __u16 blocksize;
+ __u16 free;
+};
+
+struct smb_conn_opt {
+
+ unsigned int fd;
+
+ enum smb_protocol protocol;
+ enum smb_case_hndl case_handling;
+
+ __u32 max_xmit;
+ __u16 server_uid;
+ __u16 tid;
+
+ __u16 secmode;
+ __u16 maxmux;
+ __u16 maxvcs;
+ __u16 rawmode;
+ __u32 sesskey;
+
+ __u32 maxraw;
+ __u32 capabilities;
+ __s16 serverzone;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/smp.h b/ndk/build/platforms/android-1.5/common/include/linux/smp.h
new file mode 100644
index 0000000..ab4982d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/smp.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_SMP_H
+#define __LINUX_SMP_H
+
+#define raw_smp_processor_id() 0
+#define hard_smp_processor_id() 0
+#define smp_call_function(func,info,retry,wait) (up_smp_call_function())
+#define on_each_cpu(func,info,retry,wait)   ({   local_irq_disable();   func(info);   local_irq_enable();   0;   })
+#define num_booting_cpus() 1
+#define smp_prepare_boot_cpu() do {} while (0)
+#define smp_processor_id() raw_smp_processor_id()
+#define get_cpu() ({ preempt_disable(); smp_processor_id(); })
+#define put_cpu() preempt_enable()
+#define put_cpu_no_resched() preempt_enable_no_resched()
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/smp_lock.h b/ndk/build/platforms/android-1.5/common/include/linux/smp_lock.h
new file mode 100644
index 0000000..523a970
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/smp_lock.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_SMPLOCK_H
+#define __LINUX_SMPLOCK_H
+
+#define lock_kernel() do { } while(0)
+#define unlock_kernel() do { } while(0)
+#define release_kernel_lock(task) do { } while(0)
+#define reacquire_kernel_lock(task) 0
+#define kernel_locked() 1
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/socket.h b/ndk/build/platforms/android-1.5/common/include/linux/socket.h
new file mode 100644
index 0000000..b578df9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/socket.h
@@ -0,0 +1,227 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SOCKET_H
+#define _LINUX_SOCKET_H
+
+#define _K_SS_MAXSIZE 128  
+#define _K_SS_ALIGNSIZE (__alignof__ (struct sockaddr *))
+
+struct __kernel_sockaddr_storage {
+ unsigned short ss_family;
+
+ char __data[_K_SS_MAXSIZE - sizeof(unsigned short)];
+
+} __attribute__ ((aligned(_K_SS_ALIGNSIZE)));
+
+#if !defined(__GLIBC__) || __GLIBC__ < 2
+
+#include <asm/socket.h>  
+#include <linux/sockios.h>  
+#include <linux/uio.h>  
+#include <linux/types.h>  
+#include <linux/compiler.h>  
+
+typedef unsigned short sa_family_t;
+
+struct sockaddr {
+ sa_family_t sa_family;
+ char sa_data[14];
+};
+
+struct linger {
+ int l_onoff;
+ int l_linger;
+};
+
+#define sockaddr_storage __kernel_sockaddr_storage
+
+struct msghdr {
+ void * msg_name;
+ int msg_namelen;
+ struct iovec * msg_iov;
+ __kernel_size_t msg_iovlen;
+ void * msg_control;
+ __kernel_size_t msg_controllen;
+ unsigned msg_flags;
+};
+
+struct cmsghdr {
+ __kernel_size_t cmsg_len;
+ int cmsg_level;
+ int cmsg_type;
+};
+
+#define __CMSG_NXTHDR(ctl, len, cmsg) __cmsg_nxthdr((ctl),(len),(cmsg))
+#define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr((mhdr), (cmsg))
+
+#define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) )
+
+#define CMSG_DATA(cmsg) ((void *)((char *)(cmsg) + CMSG_ALIGN(sizeof(struct cmsghdr))))
+#define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len))
+#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
+
+#define __CMSG_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr) ?   (struct cmsghdr *)(ctl) :   (struct cmsghdr *)NULL)
+#define CMSG_FIRSTHDR(msg) __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
+#define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) &&   (cmsg)->cmsg_len <= (unsigned long)   ((mhdr)->msg_controllen -   ((char *)(cmsg) - (char *)(mhdr)->msg_control)))
+
+#ifdef __GNUC__
+#define __KINLINE static __inline__
+#elif defined(__cplusplus)
+#define __KINLINE static inline
+#else
+#define __KINLINE static
+#endif
+
+__KINLINE struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size,
+ struct cmsghdr *__cmsg)
+{
+ struct cmsghdr * __ptr;
+
+ __ptr = (struct cmsghdr*)(((unsigned char *) __cmsg) + CMSG_ALIGN(__cmsg->cmsg_len));
+ if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
+ return (struct cmsghdr *)0;
+
+ return __ptr;
+}
+
+__KINLINE struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg)
+{
+ return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg);
+}
+
+#define SCM_RIGHTS 0x01  
+#define SCM_CREDENTIALS 0x02  
+#define SCM_SECURITY 0x03  
+
+struct ucred {
+ __u32 pid;
+ __u32 uid;
+ __u32 gid;
+};
+
+#define AF_UNSPEC 0
+#define AF_UNIX 1  
+#define AF_LOCAL 1  
+#define AF_INET 2  
+#define AF_AX25 3  
+#define AF_IPX 4  
+#define AF_APPLETALK 5  
+#define AF_NETROM 6  
+#define AF_BRIDGE 7  
+#define AF_ATMPVC 8  
+#define AF_X25 9  
+#define AF_INET6 10  
+#define AF_ROSE 11  
+#define AF_DECnet 12  
+#define AF_NETBEUI 13  
+#define AF_SECURITY 14  
+#define AF_KEY 15  
+#define AF_NETLINK 16
+#define AF_ROUTE AF_NETLINK  
+#define AF_PACKET 17  
+#define AF_ASH 18  
+#define AF_ECONET 19  
+#define AF_ATMSVC 20  
+#define AF_SNA 22  
+#define AF_IRDA 23  
+#define AF_PPPOX 24  
+#define AF_WANPIPE 25  
+#define AF_LLC 26  
+#define AF_TIPC 30  
+#define AF_BLUETOOTH 31  
+#define AF_MAX 32  
+
+#define PF_UNSPEC AF_UNSPEC
+#define PF_UNIX AF_UNIX
+#define PF_LOCAL AF_LOCAL
+#define PF_INET AF_INET
+#define PF_AX25 AF_AX25
+#define PF_IPX AF_IPX
+#define PF_APPLETALK AF_APPLETALK
+#define PF_NETROM AF_NETROM
+#define PF_BRIDGE AF_BRIDGE
+#define PF_ATMPVC AF_ATMPVC
+#define PF_X25 AF_X25
+#define PF_INET6 AF_INET6
+#define PF_ROSE AF_ROSE
+#define PF_DECnet AF_DECnet
+#define PF_NETBEUI AF_NETBEUI
+#define PF_SECURITY AF_SECURITY
+#define PF_KEY AF_KEY
+#define PF_NETLINK AF_NETLINK
+#define PF_ROUTE AF_ROUTE
+#define PF_PACKET AF_PACKET
+#define PF_ASH AF_ASH
+#define PF_ECONET AF_ECONET
+#define PF_ATMSVC AF_ATMSVC
+#define PF_SNA AF_SNA
+#define PF_IRDA AF_IRDA
+#define PF_PPPOX AF_PPPOX
+#define PF_WANPIPE AF_WANPIPE
+#define PF_LLC AF_LLC
+#define PF_TIPC AF_TIPC
+#define PF_BLUETOOTH AF_BLUETOOTH
+#define PF_MAX AF_MAX
+
+#define SOMAXCONN 128
+
+#define MSG_OOB 1
+#define MSG_PEEK 2
+#define MSG_DONTROUTE 4
+#define MSG_TRYHARD 4  
+#define MSG_CTRUNC 8
+#define MSG_PROBE 0x10  
+#define MSG_TRUNC 0x20
+#define MSG_DONTWAIT 0x40  
+#define MSG_EOR 0x80  
+#define MSG_WAITALL 0x100  
+#define MSG_FIN 0x200
+#define MSG_SYN 0x400
+#define MSG_CONFIRM 0x800  
+#define MSG_RST 0x1000
+#define MSG_ERRQUEUE 0x2000  
+#define MSG_NOSIGNAL 0x4000  
+#define MSG_MORE 0x8000  
+
+#define MSG_EOF MSG_FIN
+
+#define MSG_CMSG_COMPAT 0  
+
+#define SOL_IP 0
+
+#define SOL_TCP 6
+#define SOL_UDP 17
+#define SOL_IPV6 41
+#define SOL_ICMPV6 58
+#define SOL_SCTP 132
+#define SOL_RAW 255
+#define SOL_IPX 256
+#define SOL_AX25 257
+#define SOL_ATALK 258
+#define SOL_NETROM 259
+#define SOL_ROSE 260
+#define SOL_DECNET 261
+#define SOL_X25 262
+#define SOL_PACKET 263
+#define SOL_ATM 264  
+#define SOL_AAL 265  
+#define SOL_IRDA 266
+#define SOL_NETBEUI 267
+#define SOL_LLC 268
+#define SOL_DCCP 269
+#define SOL_NETLINK 270
+#define SOL_TIPC 271
+
+#define IPX_TYPE 1
+
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sockios.h b/ndk/build/platforms/android-1.5/common/include/linux/sockios.h
new file mode 100644
index 0000000..d111359
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sockios.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SOCKIOS_H
+#define _LINUX_SOCKIOS_H
+
+#include <asm/sockios.h>
+
+#define SIOCINQ FIONREAD
+#define SIOCOUTQ TIOCOUTQ
+
+#define SIOCADDRT 0x890B  
+#define SIOCDELRT 0x890C  
+#define SIOCRTMSG 0x890D  
+
+#define SIOCGIFNAME 0x8910  
+#define SIOCSIFLINK 0x8911  
+#define SIOCGIFCONF 0x8912  
+#define SIOCGIFFLAGS 0x8913  
+#define SIOCSIFFLAGS 0x8914  
+#define SIOCGIFADDR 0x8915  
+#define SIOCSIFADDR 0x8916  
+#define SIOCGIFDSTADDR 0x8917  
+#define SIOCSIFDSTADDR 0x8918  
+#define SIOCGIFBRDADDR 0x8919  
+#define SIOCSIFBRDADDR 0x891a  
+#define SIOCGIFNETMASK 0x891b  
+#define SIOCSIFNETMASK 0x891c  
+#define SIOCGIFMETRIC 0x891d  
+#define SIOCSIFMETRIC 0x891e  
+#define SIOCGIFMEM 0x891f  
+#define SIOCSIFMEM 0x8920  
+#define SIOCGIFMTU 0x8921  
+#define SIOCSIFMTU 0x8922  
+#define SIOCSIFNAME 0x8923  
+#define SIOCSIFHWADDR 0x8924  
+#define SIOCGIFENCAP 0x8925  
+#define SIOCSIFENCAP 0x8926 
+#define SIOCGIFHWADDR 0x8927  
+#define SIOCGIFSLAVE 0x8929  
+#define SIOCSIFSLAVE 0x8930
+#define SIOCADDMULTI 0x8931  
+#define SIOCDELMULTI 0x8932
+#define SIOCGIFINDEX 0x8933  
+#define SIOGIFINDEX SIOCGIFINDEX  
+#define SIOCSIFPFLAGS 0x8934  
+#define SIOCGIFPFLAGS 0x8935
+#define SIOCDIFADDR 0x8936  
+#define SIOCSIFHWBROADCAST 0x8937  
+#define SIOCGIFCOUNT 0x8938  
+#define SIOCKILLADDR 0x8939  
+
+#define SIOCGIFBR 0x8940  
+#define SIOCSIFBR 0x8941  
+
+#define SIOCGIFTXQLEN 0x8942  
+#define SIOCSIFTXQLEN 0x8943  
+
+#define SIOCETHTOOL 0x8946  
+
+#define SIOCGMIIPHY 0x8947  
+#define SIOCGMIIREG 0x8948  
+#define SIOCSMIIREG 0x8949  
+
+#define SIOCWANDEV 0x894A  
+
+#define SIOCDARP 0x8953  
+#define SIOCGARP 0x8954  
+#define SIOCSARP 0x8955  
+
+#define SIOCDRARP 0x8960  
+#define SIOCGRARP 0x8961  
+#define SIOCSRARP 0x8962  
+
+#define SIOCGIFMAP 0x8970  
+#define SIOCSIFMAP 0x8971  
+
+#define SIOCADDDLCI 0x8980  
+#define SIOCDELDLCI 0x8981  
+
+#define SIOCGIFVLAN 0x8982  
+#define SIOCSIFVLAN 0x8983  
+
+#define SIOCBONDENSLAVE 0x8990  
+#define SIOCBONDRELEASE 0x8991  
+#define SIOCBONDSETHWADDR 0x8992  
+#define SIOCBONDSLAVEINFOQUERY 0x8993  
+#define SIOCBONDINFOQUERY 0x8994  
+#define SIOCBONDCHANGEACTIVE 0x8995  
+
+#define SIOCBRADDBR 0x89a0  
+#define SIOCBRDELBR 0x89a1  
+#define SIOCBRADDIF 0x89a2  
+#define SIOCBRDELIF 0x89a3  
+
+#define SIOCDEVPRIVATE 0x89F0  
+
+#define SIOCPROTOPRIVATE 0x89E0  
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/soundcard.h b/ndk/build/platforms/android-1.5/common/include/linux/soundcard.h
new file mode 100644
index 0000000..8c69c28
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/soundcard.h
@@ -0,0 +1,831 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef SOUNDCARD_H
+#define SOUNDCARD_H
+
+#define SOUND_VERSION 0x030802
+#define OPEN_SOUND_SYSTEM
+
+#include <linux/ioctl.h>
+
+#include <endian.h>
+
+#define SNDCARD_ADLIB 1
+#define SNDCARD_SB 2
+#define SNDCARD_PAS 3
+#define SNDCARD_GUS 4
+#define SNDCARD_MPU401 5
+#define SNDCARD_SB16 6
+#define SNDCARD_SB16MIDI 7
+#define SNDCARD_UART6850 8
+#define SNDCARD_GUS16 9
+#define SNDCARD_MSS 10
+#define SNDCARD_PSS 11
+#define SNDCARD_SSCAPE 12
+#define SNDCARD_PSS_MPU 13
+#define SNDCARD_PSS_MSS 14
+#define SNDCARD_SSCAPE_MSS 15
+#define SNDCARD_TRXPRO 16
+#define SNDCARD_TRXPRO_SB 17
+#define SNDCARD_TRXPRO_MPU 18
+#define SNDCARD_MAD16 19
+#define SNDCARD_MAD16_MPU 20
+#define SNDCARD_CS4232 21
+#define SNDCARD_CS4232_MPU 22
+#define SNDCARD_MAUI 23
+#define SNDCARD_PSEUDO_MSS 24
+#define SNDCARD_GUSPNP 25
+#define SNDCARD_UART401 26
+
+#ifndef _SIOWR
+#if defined(_IOWR) && (defined(_AIX) || !defined(sun) && !defined(sparc) && !defined(__sparc__) && !defined(__INCioctlh) && !defined(__Lynx__))
+
+#define SIOCPARM_MASK IOCPARM_MASK
+#define SIOC_VOID IOC_VOID
+#define SIOC_OUT IOC_OUT
+#define SIOC_IN IOC_IN
+#define SIOC_INOUT IOC_INOUT
+#define _SIOC_SIZE _IOC_SIZE
+#define _SIOC_DIR _IOC_DIR
+#define _SIOC_NONE _IOC_NONE
+#define _SIOC_READ _IOC_READ
+#define _SIOC_WRITE _IOC_WRITE
+#define _SIO _IO
+#define _SIOR _IOR
+#define _SIOW _IOW
+#define _SIOWR _IOWR
+#else
+
+#define SIOCPARM_MASK 0x1fff  
+#define SIOC_VOID 0x00000000  
+#define SIOC_OUT 0x20000000  
+#define SIOC_IN 0x40000000  
+#define SIOC_INOUT (SIOC_IN|SIOC_OUT)
+
+#define _SIO(x,y) ((int)(SIOC_VOID|(x<<8)|y))
+#define _SIOR(x,y,t) ((int)(SIOC_OUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y))
+#define _SIOW(x,y,t) ((int)(SIOC_IN|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y))
+
+#define _SIOWR(x,y,t) ((int)(SIOC_INOUT|((sizeof(t)&SIOCPARM_MASK)<<16)|(x<<8)|y))
+#define _SIOC_SIZE(x) ((x>>16)&SIOCPARM_MASK) 
+#define _SIOC_DIR(x) (x & 0xf0000000)
+#define _SIOC_NONE SIOC_VOID
+#define _SIOC_READ SIOC_OUT
+#define _SIOC_WRITE SIOC_IN
+#endif
+#endif
+
+#define SNDCTL_SEQ_RESET _SIO ('Q', 0)
+#define SNDCTL_SEQ_SYNC _SIO ('Q', 1)
+#define SNDCTL_SYNTH_INFO _SIOWR('Q', 2, struct synth_info)
+#define SNDCTL_SEQ_CTRLRATE _SIOWR('Q', 3, int)  
+#define SNDCTL_SEQ_GETOUTCOUNT _SIOR ('Q', 4, int)
+#define SNDCTL_SEQ_GETINCOUNT _SIOR ('Q', 5, int)
+#define SNDCTL_SEQ_PERCMODE _SIOW ('Q', 6, int)
+#define SNDCTL_FM_LOAD_INSTR _SIOW ('Q', 7, struct sbi_instrument)  
+#define SNDCTL_SEQ_TESTMIDI _SIOW ('Q', 8, int)
+#define SNDCTL_SEQ_RESETSAMPLES _SIOW ('Q', 9, int)
+#define SNDCTL_SEQ_NRSYNTHS _SIOR ('Q',10, int)
+#define SNDCTL_SEQ_NRMIDIS _SIOR ('Q',11, int)
+#define SNDCTL_MIDI_INFO _SIOWR('Q',12, struct midi_info)
+#define SNDCTL_SEQ_THRESHOLD _SIOW ('Q',13, int)
+#define SNDCTL_SYNTH_MEMAVL _SIOWR('Q',14, int)  
+#define SNDCTL_FM_4OP_ENABLE _SIOW ('Q',15, int)  
+#define SNDCTL_SEQ_PANIC _SIO ('Q',17)
+#define SNDCTL_SEQ_OUTOFBAND _SIOW ('Q',18, struct seq_event_rec)
+#define SNDCTL_SEQ_GETTIME _SIOR ('Q',19, int)
+#define SNDCTL_SYNTH_ID _SIOWR('Q',20, struct synth_info)
+#define SNDCTL_SYNTH_CONTROL _SIOWR('Q',21, struct synth_control)
+#define SNDCTL_SYNTH_REMOVESAMPLE _SIOWR('Q',22, struct remove_sample)
+
+typedef struct synth_control
+{
+ int devno;
+ char data[4000];
+}synth_control;
+
+typedef struct remove_sample
+{
+ int devno;
+ int bankno;
+ int instrno;
+} remove_sample;
+
+typedef struct seq_event_rec {
+ unsigned char arr[8];
+} seq_event_rec;
+
+#define SNDCTL_TMR_TIMEBASE _SIOWR('T', 1, int)
+#define SNDCTL_TMR_START _SIO ('T', 2)
+#define SNDCTL_TMR_STOP _SIO ('T', 3)
+#define SNDCTL_TMR_CONTINUE _SIO ('T', 4)
+#define SNDCTL_TMR_TEMPO _SIOWR('T', 5, int)
+#define SNDCTL_TMR_SOURCE _SIOWR('T', 6, int)
+#define TMR_INTERNAL 0x00000001
+#define TMR_EXTERNAL 0x00000002
+#define TMR_MODE_MIDI 0x00000010
+#define TMR_MODE_FSK 0x00000020
+#define TMR_MODE_CLS 0x00000040
+#define TMR_MODE_SMPTE 0x00000080
+#define SNDCTL_TMR_METRONOME _SIOW ('T', 7, int)
+#define SNDCTL_TMR_SELECT _SIOW ('T', 8, int)
+
+#define _LINUX_PATCHKEY_H_INDIRECT
+#include <linux/patchkey.h>
+#undef _LINUX_PATCHKEY_H_INDIRECT
+
+#ifdef __BYTE_ORDER
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define AFMT_S16_NE AFMT_S16_BE
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#define AFMT_S16_NE AFMT_S16_LE
+#else
+#error "could not determine byte order"
+#endif
+#endif
+
+struct patch_info {
+ unsigned short key;
+#define WAVE_PATCH _PATCHKEY(0x04)
+#define GUS_PATCH WAVE_PATCH
+#define WAVEFRONT_PATCH _PATCHKEY(0x06)
+
+ short device_no;
+ short instr_no;
+
+ unsigned int mode;
+
+#define WAVE_16_BITS 0x01  
+#define WAVE_UNSIGNED 0x02  
+#define WAVE_LOOPING 0x04  
+#define WAVE_BIDIR_LOOP 0x08  
+#define WAVE_LOOP_BACK 0x10  
+#define WAVE_SUSTAIN_ON 0x20  
+#define WAVE_ENVELOPES 0x40  
+#define WAVE_FAST_RELEASE 0x80  
+
+#define WAVE_VIBRATO 0x00010000  
+#define WAVE_TREMOLO 0x00020000  
+#define WAVE_SCALE 0x00040000  
+#define WAVE_FRACTIONS 0x00080000  
+
+#define WAVE_ROM 0x40000000  
+#define WAVE_MULAW 0x20000000  
+
+ int len;
+ int loop_start, loop_end;
+
+ unsigned int base_freq;
+ unsigned int base_note;
+ unsigned int high_note;
+ unsigned int low_note;
+ int panning;
+ int detuning;
+
+ unsigned char env_rate[ 6 ];
+ unsigned char env_offset[ 6 ];
+
+ unsigned char tremolo_sweep;
+ unsigned char tremolo_rate;
+ unsigned char tremolo_depth;
+
+ unsigned char vibrato_sweep;
+ unsigned char vibrato_rate;
+ unsigned char vibrato_depth;
+
+ int scale_frequency;
+ unsigned int scale_factor;
+
+ int volume;
+ int fractions;
+ int reserved1;
+ int spare[2];
+ char data[1];
+ };
+
+struct sysex_info {
+ short key;
+#define SYSEX_PATCH _PATCHKEY(0x05)
+#define MAUI_PATCH _PATCHKEY(0x06)
+ short device_no;
+ int len;
+ unsigned char data[1];
+ };
+
+#define SEQ_NOTEOFF 0
+#define SEQ_FMNOTEOFF SEQ_NOTEOFF  
+#define SEQ_NOTEON 1
+#define SEQ_FMNOTEON SEQ_NOTEON
+#define SEQ_WAIT TMR_WAIT_ABS
+#define SEQ_PGMCHANGE 3
+#define SEQ_FMPGMCHANGE SEQ_PGMCHANGE
+#define SEQ_SYNCTIMER TMR_START
+#define SEQ_MIDIPUTC 5
+#define SEQ_DRUMON 6  
+#define SEQ_DRUMOFF 7  
+#define SEQ_ECHO TMR_ECHO  
+#define SEQ_AFTERTOUCH 9
+#define SEQ_CONTROLLER 10
+
+#define CTL_BANK_SELECT 0x00
+#define CTL_MODWHEEL 0x01
+#define CTL_BREATH 0x02
+
+#define CTL_FOOT 0x04
+#define CTL_PORTAMENTO_TIME 0x05
+#define CTL_DATA_ENTRY 0x06
+#define CTL_MAIN_VOLUME 0x07
+#define CTL_BALANCE 0x08
+
+#define CTL_PAN 0x0a
+#define CTL_EXPRESSION 0x0b
+
+#define CTL_GENERAL_PURPOSE1 0x10
+#define CTL_GENERAL_PURPOSE2 0x11
+#define CTL_GENERAL_PURPOSE3 0x12
+#define CTL_GENERAL_PURPOSE4 0x13
+
+#define CTL_DAMPER_PEDAL 0x40
+#define CTL_SUSTAIN 0x40  
+#define CTL_HOLD 0x40  
+#define CTL_PORTAMENTO 0x41
+#define CTL_SOSTENUTO 0x42
+#define CTL_SOFT_PEDAL 0x43
+
+#define CTL_HOLD2 0x45
+
+#define CTL_GENERAL_PURPOSE5 0x50
+#define CTL_GENERAL_PURPOSE6 0x51
+#define CTL_GENERAL_PURPOSE7 0x52
+#define CTL_GENERAL_PURPOSE8 0x53
+
+#define CTL_EXT_EFF_DEPTH 0x5b
+#define CTL_TREMOLO_DEPTH 0x5c
+#define CTL_CHORUS_DEPTH 0x5d
+#define CTL_DETUNE_DEPTH 0x5e
+#define CTL_CELESTE_DEPTH 0x5e  
+#define CTL_PHASER_DEPTH 0x5f
+#define CTL_DATA_INCREMENT 0x60
+#define CTL_DATA_DECREMENT 0x61
+#define CTL_NONREG_PARM_NUM_LSB 0x62
+#define CTL_NONREG_PARM_NUM_MSB 0x63
+#define CTL_REGIST_PARM_NUM_LSB 0x64
+#define CTL_REGIST_PARM_NUM_MSB 0x65
+
+#define CTRL_PITCH_BENDER 255
+#define CTRL_PITCH_BENDER_RANGE 254
+#define CTRL_EXPRESSION 253  
+#define CTRL_MAIN_VOLUME 252  
+#define SEQ_BALANCE 11
+#define SEQ_VOLMODE 12
+
+#define VOL_METHOD_ADAGIO 1
+#define VOL_METHOD_LINEAR 2
+
+#define SEQ_FULLSIZE 0xfd  
+
+#define SEQ_PRIVATE 0xfe  
+#define SEQ_EXTENDED 0xff  
+
+typedef unsigned char sbi_instr_data[32];
+
+struct sbi_instrument {
+ unsigned short key;
+#define FM_PATCH _PATCHKEY(0x01)
+#define OPL3_PATCH _PATCHKEY(0x03)
+ short device;
+ int channel;
+ sbi_instr_data operators;
+ };
+
+struct synth_info {
+ char name[30];
+ int device;
+ int synth_type;
+#define SYNTH_TYPE_FM 0
+#define SYNTH_TYPE_SAMPLE 1
+#define SYNTH_TYPE_MIDI 2  
+
+ int synth_subtype;
+#define FM_TYPE_ADLIB 0x00
+#define FM_TYPE_OPL3 0x01
+#define MIDI_TYPE_MPU401 0x401
+
+#define SAMPLE_TYPE_BASIC 0x10
+#define SAMPLE_TYPE_GUS SAMPLE_TYPE_BASIC
+#define SAMPLE_TYPE_WAVEFRONT 0x11
+
+ int perc_mode;
+ int nr_voices;
+ int nr_drums;
+ int instr_bank_size;
+ unsigned int capabilities;
+#define SYNTH_CAP_PERCMODE 0x00000001  
+#define SYNTH_CAP_OPL3 0x00000002  
+#define SYNTH_CAP_INPUT 0x00000004  
+ int dummies[19];
+ };
+
+struct sound_timer_info {
+ char name[32];
+ int caps;
+ };
+
+#define MIDI_CAP_MPU401 1  
+
+struct midi_info {
+ char name[30];
+ int device;
+ unsigned int capabilities;
+ int dev_type;
+ int dummies[18];
+ };
+
+typedef struct {
+ unsigned char cmd;
+ char nr_args, nr_returns;
+ unsigned char data[30];
+ } mpu_command_rec;
+
+#define SNDCTL_MIDI_PRETIME _SIOWR('m', 0, int)
+#define SNDCTL_MIDI_MPUMODE _SIOWR('m', 1, int)
+#define SNDCTL_MIDI_MPUCMD _SIOWR('m', 2, mpu_command_rec)
+
+#define SNDCTL_DSP_RESET _SIO ('P', 0)
+#define SNDCTL_DSP_SYNC _SIO ('P', 1)
+#define SNDCTL_DSP_SPEED _SIOWR('P', 2, int)
+#define SNDCTL_DSP_STEREO _SIOWR('P', 3, int)
+#define SNDCTL_DSP_GETBLKSIZE _SIOWR('P', 4, int)
+#define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT
+#define SNDCTL_DSP_CHANNELS _SIOWR('P', 6, int)
+#define SOUND_PCM_WRITE_CHANNELS SNDCTL_DSP_CHANNELS
+#define SOUND_PCM_WRITE_FILTER _SIOWR('P', 7, int)
+#define SNDCTL_DSP_POST _SIO ('P', 8)
+#define SNDCTL_DSP_SUBDIVIDE _SIOWR('P', 9, int)
+#define SNDCTL_DSP_SETFRAGMENT _SIOWR('P',10, int)
+
+#define SNDCTL_DSP_GETFMTS _SIOR ('P',11, int)  
+#define SNDCTL_DSP_SETFMT _SIOWR('P',5, int)  
+#define AFMT_QUERY 0x00000000  
+#define AFMT_MU_LAW 0x00000001
+#define AFMT_A_LAW 0x00000002
+#define AFMT_IMA_ADPCM 0x00000004
+#define AFMT_U8 0x00000008
+#define AFMT_S16_LE 0x00000010  
+#define AFMT_S16_BE 0x00000020  
+#define AFMT_S8 0x00000040
+#define AFMT_U16_LE 0x00000080  
+#define AFMT_U16_BE 0x00000100  
+#define AFMT_MPEG 0x00000200  
+#define AFMT_AC3 0x00000400  
+
+typedef struct audio_buf_info {
+ int fragments;
+ int fragstotal;
+ int fragsize;
+
+ int bytes;
+
+ } audio_buf_info;
+
+#define SNDCTL_DSP_GETOSPACE _SIOR ('P',12, audio_buf_info)
+#define SNDCTL_DSP_GETISPACE _SIOR ('P',13, audio_buf_info)
+#define SNDCTL_DSP_NONBLOCK _SIO ('P',14)
+#define SNDCTL_DSP_GETCAPS _SIOR ('P',15, int)
+#define DSP_CAP_REVISION 0x000000ff  
+#define DSP_CAP_DUPLEX 0x00000100  
+#define DSP_CAP_REALTIME 0x00000200  
+#define DSP_CAP_BATCH 0x00000400  
+
+#define DSP_CAP_COPROC 0x00000800  
+
+#define DSP_CAP_TRIGGER 0x00001000  
+#define DSP_CAP_MMAP 0x00002000  
+#define DSP_CAP_MULTI 0x00004000  
+#define DSP_CAP_BIND 0x00008000  
+
+#define SNDCTL_DSP_GETTRIGGER _SIOR ('P',16, int)
+#define SNDCTL_DSP_SETTRIGGER _SIOW ('P',16, int)
+#define PCM_ENABLE_INPUT 0x00000001
+#define PCM_ENABLE_OUTPUT 0x00000002
+
+typedef struct count_info {
+ int bytes;
+ int blocks;
+ int ptr;
+ } count_info;
+
+#define SNDCTL_DSP_GETIPTR _SIOR ('P',17, count_info)
+#define SNDCTL_DSP_GETOPTR _SIOR ('P',18, count_info)
+
+typedef struct buffmem_desc {
+ unsigned *buffer;
+ int size;
+ } buffmem_desc;
+#define SNDCTL_DSP_MAPINBUF _SIOR ('P', 19, buffmem_desc)
+#define SNDCTL_DSP_MAPOUTBUF _SIOR ('P', 20, buffmem_desc)
+#define SNDCTL_DSP_SETSYNCRO _SIO ('P', 21)
+#define SNDCTL_DSP_SETDUPLEX _SIO ('P', 22)
+#define SNDCTL_DSP_GETODELAY _SIOR ('P', 23, int)
+
+#define SNDCTL_DSP_GETCHANNELMASK _SIOWR('P', 64, int)
+#define SNDCTL_DSP_BIND_CHANNEL _SIOWR('P', 65, int)
+#define DSP_BIND_QUERY 0x00000000
+#define DSP_BIND_FRONT 0x00000001
+#define DSP_BIND_SURR 0x00000002
+#define DSP_BIND_CENTER_LFE 0x00000004
+#define DSP_BIND_HANDSET 0x00000008
+#define DSP_BIND_MIC 0x00000010
+#define DSP_BIND_MODEM1 0x00000020
+#define DSP_BIND_MODEM2 0x00000040
+#define DSP_BIND_I2S 0x00000080
+#define DSP_BIND_SPDIF 0x00000100
+
+#define SNDCTL_DSP_SETSPDIF _SIOW ('P', 66, int)
+#define SNDCTL_DSP_GETSPDIF _SIOR ('P', 67, int)
+#define SPDIF_PRO 0x0001
+#define SPDIF_N_AUD 0x0002
+#define SPDIF_COPY 0x0004
+#define SPDIF_PRE 0x0008
+#define SPDIF_CC 0x07f0
+#define SPDIF_L 0x0800
+#define SPDIF_DRS 0x4000
+#define SPDIF_V 0x8000
+
+#define SNDCTL_DSP_PROFILE _SIOW ('P', 23, int)
+#define APF_NORMAL 0  
+#define APF_NETWORK 1  
+#define APF_CPUINTENS 2  
+
+#define SOUND_PCM_READ_RATE _SIOR ('P', 2, int)
+#define SOUND_PCM_READ_CHANNELS _SIOR ('P', 6, int)
+#define SOUND_PCM_READ_BITS _SIOR ('P', 5, int)
+#define SOUND_PCM_READ_FILTER _SIOR ('P', 7, int)
+
+#define SOUND_PCM_WRITE_BITS SNDCTL_DSP_SETFMT
+#define SOUND_PCM_WRITE_RATE SNDCTL_DSP_SPEED
+#define SOUND_PCM_POST SNDCTL_DSP_POST
+#define SOUND_PCM_RESET SNDCTL_DSP_RESET
+#define SOUND_PCM_SYNC SNDCTL_DSP_SYNC
+#define SOUND_PCM_SUBDIVIDE SNDCTL_DSP_SUBDIVIDE
+#define SOUND_PCM_SETFRAGMENT SNDCTL_DSP_SETFRAGMENT
+#define SOUND_PCM_GETFMTS SNDCTL_DSP_GETFMTS
+#define SOUND_PCM_SETFMT SNDCTL_DSP_SETFMT
+#define SOUND_PCM_GETOSPACE SNDCTL_DSP_GETOSPACE
+#define SOUND_PCM_GETISPACE SNDCTL_DSP_GETISPACE
+#define SOUND_PCM_NONBLOCK SNDCTL_DSP_NONBLOCK
+#define SOUND_PCM_GETCAPS SNDCTL_DSP_GETCAPS
+#define SOUND_PCM_GETTRIGGER SNDCTL_DSP_GETTRIGGER
+#define SOUND_PCM_SETTRIGGER SNDCTL_DSP_SETTRIGGER
+#define SOUND_PCM_SETSYNCRO SNDCTL_DSP_SETSYNCRO
+#define SOUND_PCM_GETIPTR SNDCTL_DSP_GETIPTR
+#define SOUND_PCM_GETOPTR SNDCTL_DSP_GETOPTR
+#define SOUND_PCM_MAPINBUF SNDCTL_DSP_MAPINBUF
+#define SOUND_PCM_MAPOUTBUF SNDCTL_DSP_MAPOUTBUF
+
+typedef struct copr_buffer {
+ int command;
+ int flags;
+#define CPF_NONE 0x0000
+#define CPF_FIRST 0x0001  
+#define CPF_LAST 0x0002  
+ int len;
+ int offs;
+
+ unsigned char data[4000];
+ } copr_buffer;
+
+typedef struct copr_debug_buf {
+ int command;
+ int parm1;
+ int parm2;
+ int flags;
+ int len;
+ } copr_debug_buf;
+
+typedef struct copr_msg {
+ int len;
+ unsigned char data[4000];
+ } copr_msg;
+
+#define SNDCTL_COPR_RESET _SIO ('C', 0)
+#define SNDCTL_COPR_LOAD _SIOWR('C', 1, copr_buffer)
+#define SNDCTL_COPR_RDATA _SIOWR('C', 2, copr_debug_buf)
+#define SNDCTL_COPR_RCODE _SIOWR('C', 3, copr_debug_buf)
+#define SNDCTL_COPR_WDATA _SIOW ('C', 4, copr_debug_buf)
+#define SNDCTL_COPR_WCODE _SIOW ('C', 5, copr_debug_buf)
+#define SNDCTL_COPR_RUN _SIOWR('C', 6, copr_debug_buf)
+#define SNDCTL_COPR_HALT _SIOWR('C', 7, copr_debug_buf)
+#define SNDCTL_COPR_SENDMSG _SIOWR('C', 8, copr_msg)
+#define SNDCTL_COPR_RCVMSG _SIOR ('C', 9, copr_msg)
+
+#define SOUND_MIXER_NRDEVICES 25
+#define SOUND_MIXER_VOLUME 0
+#define SOUND_MIXER_BASS 1
+#define SOUND_MIXER_TREBLE 2
+#define SOUND_MIXER_SYNTH 3
+#define SOUND_MIXER_PCM 4
+#define SOUND_MIXER_SPEAKER 5
+#define SOUND_MIXER_LINE 6
+#define SOUND_MIXER_MIC 7
+#define SOUND_MIXER_CD 8
+#define SOUND_MIXER_IMIX 9  
+#define SOUND_MIXER_ALTPCM 10
+#define SOUND_MIXER_RECLEV 11  
+#define SOUND_MIXER_IGAIN 12  
+#define SOUND_MIXER_OGAIN 13  
+
+#define SOUND_MIXER_LINE1 14  
+#define SOUND_MIXER_LINE2 15  
+#define SOUND_MIXER_LINE3 16  
+#define SOUND_MIXER_DIGITAL1 17  
+#define SOUND_MIXER_DIGITAL2 18  
+#define SOUND_MIXER_DIGITAL3 19  
+#define SOUND_MIXER_PHONEIN 20  
+#define SOUND_MIXER_PHONEOUT 21  
+#define SOUND_MIXER_VIDEO 22  
+#define SOUND_MIXER_RADIO 23  
+#define SOUND_MIXER_MONITOR 24  
+
+#define SOUND_ONOFF_MIN 28
+#define SOUND_ONOFF_MAX 30
+
+#define SOUND_MIXER_NONE 31
+
+#define SOUND_MIXER_ENHANCE SOUND_MIXER_NONE
+#define SOUND_MIXER_MUTE SOUND_MIXER_NONE
+#define SOUND_MIXER_LOUD SOUND_MIXER_NONE
+
+#define SOUND_DEVICE_LABELS {"Vol  ", "Bass ", "Trebl", "Synth", "Pcm  ", "Spkr ", "Line ",   "Mic  ", "CD   ", "Mix  ", "Pcm2 ", "Rec  ", "IGain", "OGain",   "Line1", "Line2", "Line3", "Digital1", "Digital2", "Digital3",   "PhoneIn", "PhoneOut", "Video", "Radio", "Monitor"}
+
+#define SOUND_DEVICE_NAMES {"vol", "bass", "treble", "synth", "pcm", "speaker", "line",   "mic", "cd", "mix", "pcm2", "rec", "igain", "ogain",   "line1", "line2", "line3", "dig1", "dig2", "dig3",   "phin", "phout", "video", "radio", "monitor"}
+
+#define SOUND_MIXER_RECSRC 0xff  
+#define SOUND_MIXER_DEVMASK 0xfe  
+#define SOUND_MIXER_RECMASK 0xfd  
+#define SOUND_MIXER_CAPS 0xfc
+#define SOUND_CAP_EXCL_INPUT 0x00000001  
+#define SOUND_MIXER_STEREODEVS 0xfb  
+#define SOUND_MIXER_OUTSRC 0xfa  
+#define SOUND_MIXER_OUTMASK 0xf9  
+
+#define SOUND_MASK_VOLUME (1 << SOUND_MIXER_VOLUME)
+#define SOUND_MASK_BASS (1 << SOUND_MIXER_BASS)
+#define SOUND_MASK_TREBLE (1 << SOUND_MIXER_TREBLE)
+#define SOUND_MASK_SYNTH (1 << SOUND_MIXER_SYNTH)
+#define SOUND_MASK_PCM (1 << SOUND_MIXER_PCM)
+#define SOUND_MASK_SPEAKER (1 << SOUND_MIXER_SPEAKER)
+#define SOUND_MASK_LINE (1 << SOUND_MIXER_LINE)
+#define SOUND_MASK_MIC (1 << SOUND_MIXER_MIC)
+#define SOUND_MASK_CD (1 << SOUND_MIXER_CD)
+#define SOUND_MASK_IMIX (1 << SOUND_MIXER_IMIX)
+#define SOUND_MASK_ALTPCM (1 << SOUND_MIXER_ALTPCM)
+#define SOUND_MASK_RECLEV (1 << SOUND_MIXER_RECLEV)
+#define SOUND_MASK_IGAIN (1 << SOUND_MIXER_IGAIN)
+#define SOUND_MASK_OGAIN (1 << SOUND_MIXER_OGAIN)
+#define SOUND_MASK_LINE1 (1 << SOUND_MIXER_LINE1)
+#define SOUND_MASK_LINE2 (1 << SOUND_MIXER_LINE2)
+#define SOUND_MASK_LINE3 (1 << SOUND_MIXER_LINE3)
+#define SOUND_MASK_DIGITAL1 (1 << SOUND_MIXER_DIGITAL1)
+#define SOUND_MASK_DIGITAL2 (1 << SOUND_MIXER_DIGITAL2)
+#define SOUND_MASK_DIGITAL3 (1 << SOUND_MIXER_DIGITAL3)
+#define SOUND_MASK_PHONEIN (1 << SOUND_MIXER_PHONEIN)
+#define SOUND_MASK_PHONEOUT (1 << SOUND_MIXER_PHONEOUT)
+#define SOUND_MASK_RADIO (1 << SOUND_MIXER_RADIO)
+#define SOUND_MASK_VIDEO (1 << SOUND_MIXER_VIDEO)
+#define SOUND_MASK_MONITOR (1 << SOUND_MIXER_MONITOR)
+
+#define SOUND_MASK_MUTE (1 << SOUND_MIXER_MUTE)
+#define SOUND_MASK_ENHANCE (1 << SOUND_MIXER_ENHANCE)
+#define SOUND_MASK_LOUD (1 << SOUND_MIXER_LOUD)
+
+#define MIXER_READ(dev) _SIOR('M', dev, int)
+#define SOUND_MIXER_READ_VOLUME MIXER_READ(SOUND_MIXER_VOLUME)
+#define SOUND_MIXER_READ_BASS MIXER_READ(SOUND_MIXER_BASS)
+#define SOUND_MIXER_READ_TREBLE MIXER_READ(SOUND_MIXER_TREBLE)
+#define SOUND_MIXER_READ_SYNTH MIXER_READ(SOUND_MIXER_SYNTH)
+#define SOUND_MIXER_READ_PCM MIXER_READ(SOUND_MIXER_PCM)
+#define SOUND_MIXER_READ_SPEAKER MIXER_READ(SOUND_MIXER_SPEAKER)
+#define SOUND_MIXER_READ_LINE MIXER_READ(SOUND_MIXER_LINE)
+#define SOUND_MIXER_READ_MIC MIXER_READ(SOUND_MIXER_MIC)
+#define SOUND_MIXER_READ_CD MIXER_READ(SOUND_MIXER_CD)
+#define SOUND_MIXER_READ_IMIX MIXER_READ(SOUND_MIXER_IMIX)
+#define SOUND_MIXER_READ_ALTPCM MIXER_READ(SOUND_MIXER_ALTPCM)
+#define SOUND_MIXER_READ_RECLEV MIXER_READ(SOUND_MIXER_RECLEV)
+#define SOUND_MIXER_READ_IGAIN MIXER_READ(SOUND_MIXER_IGAIN)
+#define SOUND_MIXER_READ_OGAIN MIXER_READ(SOUND_MIXER_OGAIN)
+#define SOUND_MIXER_READ_LINE1 MIXER_READ(SOUND_MIXER_LINE1)
+#define SOUND_MIXER_READ_LINE2 MIXER_READ(SOUND_MIXER_LINE2)
+#define SOUND_MIXER_READ_LINE3 MIXER_READ(SOUND_MIXER_LINE3)
+
+#define SOUND_MIXER_READ_MUTE MIXER_READ(SOUND_MIXER_MUTE)
+#define SOUND_MIXER_READ_ENHANCE MIXER_READ(SOUND_MIXER_ENHANCE)
+#define SOUND_MIXER_READ_LOUD MIXER_READ(SOUND_MIXER_LOUD)
+
+#define SOUND_MIXER_READ_RECSRC MIXER_READ(SOUND_MIXER_RECSRC)
+#define SOUND_MIXER_READ_DEVMASK MIXER_READ(SOUND_MIXER_DEVMASK)
+#define SOUND_MIXER_READ_RECMASK MIXER_READ(SOUND_MIXER_RECMASK)
+#define SOUND_MIXER_READ_STEREODEVS MIXER_READ(SOUND_MIXER_STEREODEVS)
+#define SOUND_MIXER_READ_CAPS MIXER_READ(SOUND_MIXER_CAPS)
+
+#define MIXER_WRITE(dev) _SIOWR('M', dev, int)
+#define SOUND_MIXER_WRITE_VOLUME MIXER_WRITE(SOUND_MIXER_VOLUME)
+#define SOUND_MIXER_WRITE_BASS MIXER_WRITE(SOUND_MIXER_BASS)
+#define SOUND_MIXER_WRITE_TREBLE MIXER_WRITE(SOUND_MIXER_TREBLE)
+#define SOUND_MIXER_WRITE_SYNTH MIXER_WRITE(SOUND_MIXER_SYNTH)
+#define SOUND_MIXER_WRITE_PCM MIXER_WRITE(SOUND_MIXER_PCM)
+#define SOUND_MIXER_WRITE_SPEAKER MIXER_WRITE(SOUND_MIXER_SPEAKER)
+#define SOUND_MIXER_WRITE_LINE MIXER_WRITE(SOUND_MIXER_LINE)
+#define SOUND_MIXER_WRITE_MIC MIXER_WRITE(SOUND_MIXER_MIC)
+#define SOUND_MIXER_WRITE_CD MIXER_WRITE(SOUND_MIXER_CD)
+#define SOUND_MIXER_WRITE_IMIX MIXER_WRITE(SOUND_MIXER_IMIX)
+#define SOUND_MIXER_WRITE_ALTPCM MIXER_WRITE(SOUND_MIXER_ALTPCM)
+#define SOUND_MIXER_WRITE_RECLEV MIXER_WRITE(SOUND_MIXER_RECLEV)
+#define SOUND_MIXER_WRITE_IGAIN MIXER_WRITE(SOUND_MIXER_IGAIN)
+#define SOUND_MIXER_WRITE_OGAIN MIXER_WRITE(SOUND_MIXER_OGAIN)
+#define SOUND_MIXER_WRITE_LINE1 MIXER_WRITE(SOUND_MIXER_LINE1)
+#define SOUND_MIXER_WRITE_LINE2 MIXER_WRITE(SOUND_MIXER_LINE2)
+#define SOUND_MIXER_WRITE_LINE3 MIXER_WRITE(SOUND_MIXER_LINE3)
+
+#define SOUND_MIXER_WRITE_MUTE MIXER_WRITE(SOUND_MIXER_MUTE)
+#define SOUND_MIXER_WRITE_ENHANCE MIXER_WRITE(SOUND_MIXER_ENHANCE)
+#define SOUND_MIXER_WRITE_LOUD MIXER_WRITE(SOUND_MIXER_LOUD)
+
+#define SOUND_MIXER_WRITE_RECSRC MIXER_WRITE(SOUND_MIXER_RECSRC)
+
+typedef struct mixer_info
+{
+ char id[16];
+ char name[32];
+ int modify_counter;
+ int fillers[10];
+} mixer_info;
+
+typedef struct _old_mixer_info
+{
+ char id[16];
+ char name[32];
+} _old_mixer_info;
+
+#define SOUND_MIXER_INFO _SIOR ('M', 101, mixer_info)
+#define SOUND_OLD_MIXER_INFO _SIOR ('M', 101, _old_mixer_info)
+
+typedef unsigned char mixer_record[128];
+
+#define SOUND_MIXER_ACCESS _SIOWR('M', 102, mixer_record)
+
+#define SOUND_MIXER_AGC _SIOWR('M', 103, int)
+#define SOUND_MIXER_3DSE _SIOWR('M', 104, int)
+
+#define SOUND_MIXER_PRIVATE1 _SIOWR('M', 111, int)
+#define SOUND_MIXER_PRIVATE2 _SIOWR('M', 112, int)
+#define SOUND_MIXER_PRIVATE3 _SIOWR('M', 113, int)
+#define SOUND_MIXER_PRIVATE4 _SIOWR('M', 114, int)
+#define SOUND_MIXER_PRIVATE5 _SIOWR('M', 115, int)
+
+typedef struct mixer_vol_table {
+ int num;
+ char name[32];
+ int levels[32];
+} mixer_vol_table;
+
+#define SOUND_MIXER_GETLEVELS _SIOWR('M', 116, mixer_vol_table)
+#define SOUND_MIXER_SETLEVELS _SIOWR('M', 117, mixer_vol_table)
+
+#define OSS_GETVERSION _SIOR ('M', 118, int)
+
+#define EV_SEQ_LOCAL 0x80
+#define EV_TIMING 0x81
+#define EV_CHN_COMMON 0x92
+#define EV_CHN_VOICE 0x93
+#define EV_SYSEX 0x94
+
+#define MIDI_NOTEOFF 0x80
+#define MIDI_NOTEON 0x90
+#define MIDI_KEY_PRESSURE 0xA0
+
+#define MIDI_CTL_CHANGE 0xB0
+#define MIDI_PGM_CHANGE 0xC0
+#define MIDI_CHN_PRESSURE 0xD0
+#define MIDI_PITCH_BEND 0xE0
+
+#define MIDI_SYSTEM_PREFIX 0xF0
+
+#define TMR_WAIT_REL 1  
+#define TMR_WAIT_ABS 2  
+#define TMR_STOP 3
+#define TMR_START 4
+#define TMR_CONTINUE 5
+#define TMR_TEMPO 6
+#define TMR_ECHO 8
+#define TMR_CLOCK 9  
+#define TMR_SPP 10  
+#define TMR_TIMESIG 11  
+
+#define LOCL_STARTAUDIO 1
+
+#if !defined(__KERNEL__) && !defined(KERNEL) && !defined(INKERNEL) && !defined(_KERNEL) || defined(USE_SEQ_MACROS)
+
+#define SEQ_DECLAREBUF() SEQ_USE_EXTBUF()
+
+#define SEQ_PM_DEFINES int __foo_bar___
+#ifdef OSSLIB
+#define SEQ_USE_EXTBUF()   extern unsigned char *_seqbuf;   extern int _seqbuflen;extern int _seqbufptr
+#define SEQ_DEFINEBUF(len) SEQ_USE_EXTBUF();static int _requested_seqbuflen=len
+#define _SEQ_ADVBUF(len) OSS_seq_advbuf(len, seqfd, _seqbuf, _seqbuflen)
+#define _SEQ_NEEDBUF(len) OSS_seq_needbuf(len, seqfd, _seqbuf, _seqbuflen)
+#define SEQ_DUMPBUF() OSS_seqbuf_dump(seqfd, _seqbuf, _seqbuflen)
+
+#define SEQ_LOAD_GMINSTR(dev, instr)   OSS_patch_caching(dev, -1, instr, seqfd, _seqbuf, _seqbuflen)
+#define SEQ_LOAD_GMDRUM(dev, drum)   OSS_drum_caching(dev, -1, drum, seqfd, _seqbuf, _seqbuflen)
+#else
+
+#define SEQ_LOAD_GMINSTR(dev, instr)
+#define SEQ_LOAD_GMDRUM(dev, drum)
+
+#define SEQ_USE_EXTBUF()   extern unsigned char _seqbuf[];   extern int _seqbuflen;extern int _seqbufptr
+
+#ifndef USE_SIMPLE_MACROS
+
+#define SEQ_DEFINEBUF(len) unsigned char _seqbuf[len]; int _seqbuflen = len;int _seqbufptr = 0
+#define _SEQ_NEEDBUF(len) if ((_seqbufptr+(len)) > _seqbuflen) seqbuf_dump()
+#define _SEQ_ADVBUF(len) _seqbufptr += len
+#define SEQ_DUMPBUF seqbuf_dump
+#else
+
+#define _SEQ_NEEDBUF(len)  
+#endif
+#endif
+
+#define SEQ_VOLUME_MODE(dev, mode) {_SEQ_NEEDBUF(8);  _seqbuf[_seqbufptr] = SEQ_EXTENDED;  _seqbuf[_seqbufptr+1] = SEQ_VOLMODE;  _seqbuf[_seqbufptr+2] = (dev);  _seqbuf[_seqbufptr+3] = (mode);  _seqbuf[_seqbufptr+4] = 0;  _seqbuf[_seqbufptr+5] = 0;  _seqbuf[_seqbufptr+6] = 0;  _seqbuf[_seqbufptr+7] = 0;  _SEQ_ADVBUF(8);}
+
+#define _CHN_VOICE(dev, event, chn, note, parm)   {_SEQ_NEEDBUF(8);  _seqbuf[_seqbufptr] = EV_CHN_VOICE;  _seqbuf[_seqbufptr+1] = (dev);  _seqbuf[_seqbufptr+2] = (event);  _seqbuf[_seqbufptr+3] = (chn);  _seqbuf[_seqbufptr+4] = (note);  _seqbuf[_seqbufptr+5] = (parm);  _seqbuf[_seqbufptr+6] = (0);  _seqbuf[_seqbufptr+7] = 0;  _SEQ_ADVBUF(8);}
+
+#define SEQ_START_NOTE(dev, chn, note, vol)   _CHN_VOICE(dev, MIDI_NOTEON, chn, note, vol)
+
+#define SEQ_STOP_NOTE(dev, chn, note, vol)   _CHN_VOICE(dev, MIDI_NOTEOFF, chn, note, vol)
+
+#define SEQ_KEY_PRESSURE(dev, chn, note, pressure)   _CHN_VOICE(dev, MIDI_KEY_PRESSURE, chn, note, pressure)
+
+#define _CHN_COMMON(dev, event, chn, p1, p2, w14)   {_SEQ_NEEDBUF(8);  _seqbuf[_seqbufptr] = EV_CHN_COMMON;  _seqbuf[_seqbufptr+1] = (dev);  _seqbuf[_seqbufptr+2] = (event);  _seqbuf[_seqbufptr+3] = (chn);  _seqbuf[_seqbufptr+4] = (p1);  _seqbuf[_seqbufptr+5] = (p2);  *(short *)&_seqbuf[_seqbufptr+6] = (w14);  _SEQ_ADVBUF(8);}
+
+#define SEQ_SYSEX(dev, buf, len)   {int ii, ll=(len);   unsigned char *bufp=buf;  if (ll>6)ll=6;  _SEQ_NEEDBUF(8);  _seqbuf[_seqbufptr] = EV_SYSEX;  _seqbuf[_seqbufptr+1] = (dev);  for(ii=0;ii<ll;ii++)  _seqbuf[_seqbufptr+ii+2] = bufp[ii];  for(ii=ll;ii<6;ii++)  _seqbuf[_seqbufptr+ii+2] = 0xff;  _SEQ_ADVBUF(8);}
+
+#define SEQ_CHN_PRESSURE(dev, chn, pressure)   _CHN_COMMON(dev, MIDI_CHN_PRESSURE, chn, pressure, 0, 0)
+
+#define SEQ_SET_PATCH SEQ_PGM_CHANGE
+#ifdef OSSLIB
+#define SEQ_PGM_CHANGE(dev, chn, patch)   {OSS_patch_caching(dev, chn, patch, seqfd, _seqbuf, _seqbuflen);   _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0);}
+#else
+#define SEQ_PGM_CHANGE(dev, chn, patch)   _CHN_COMMON(dev, MIDI_PGM_CHANGE, chn, patch, 0, 0)
+#endif
+
+#define SEQ_CONTROL(dev, chn, controller, value)   _CHN_COMMON(dev, MIDI_CTL_CHANGE, chn, controller, 0, value)
+
+#define SEQ_BENDER(dev, chn, value)   _CHN_COMMON(dev, MIDI_PITCH_BEND, chn, 0, 0, value)
+
+#define SEQ_V2_X_CONTROL(dev, voice, controller, value) {_SEQ_NEEDBUF(8);  _seqbuf[_seqbufptr] = SEQ_EXTENDED;  _seqbuf[_seqbufptr+1] = SEQ_CONTROLLER;  _seqbuf[_seqbufptr+2] = (dev);  _seqbuf[_seqbufptr+3] = (voice);  _seqbuf[_seqbufptr+4] = (controller);  _seqbuf[_seqbufptr+5] = ((value)&0xff);  _seqbuf[_seqbufptr+6] = ((value>>8)&0xff);  _seqbuf[_seqbufptr+7] = 0;  _SEQ_ADVBUF(8);}
+
+#define SEQ_PITCHBEND(dev, voice, value) SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER, value)
+#define SEQ_BENDER_RANGE(dev, voice, value) SEQ_V2_X_CONTROL(dev, voice, CTRL_PITCH_BENDER_RANGE, value)
+#define SEQ_EXPRESSION(dev, voice, value) SEQ_CONTROL(dev, voice, CTL_EXPRESSION, value*128)
+#define SEQ_MAIN_VOLUME(dev, voice, value) SEQ_CONTROL(dev, voice, CTL_MAIN_VOLUME, (value*16383)/100)
+#define SEQ_PANNING(dev, voice, pos) SEQ_CONTROL(dev, voice, CTL_PAN, (pos+128) / 2)
+
+#define _TIMER_EVENT(ev, parm) {_SEQ_NEEDBUF(8);  _seqbuf[_seqbufptr+0] = EV_TIMING;   _seqbuf[_seqbufptr+1] = (ev);   _seqbuf[_seqbufptr+2] = 0;  _seqbuf[_seqbufptr+3] = 0;  *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm);   _SEQ_ADVBUF(8);}
+
+#define SEQ_START_TIMER() _TIMER_EVENT(TMR_START, 0)
+#define SEQ_STOP_TIMER() _TIMER_EVENT(TMR_STOP, 0)
+#define SEQ_CONTINUE_TIMER() _TIMER_EVENT(TMR_CONTINUE, 0)
+#define SEQ_WAIT_TIME(ticks) _TIMER_EVENT(TMR_WAIT_ABS, ticks)
+#define SEQ_DELTA_TIME(ticks) _TIMER_EVENT(TMR_WAIT_REL, ticks)
+#define SEQ_ECHO_BACK(key) _TIMER_EVENT(TMR_ECHO, key)
+#define SEQ_SET_TEMPO(value) _TIMER_EVENT(TMR_TEMPO, value)
+#define SEQ_SONGPOS(pos) _TIMER_EVENT(TMR_SPP, pos)
+#define SEQ_TIME_SIGNATURE(sig) _TIMER_EVENT(TMR_TIMESIG, sig)
+
+#define _LOCAL_EVENT(ev, parm) {_SEQ_NEEDBUF(8);  _seqbuf[_seqbufptr+0] = EV_SEQ_LOCAL;   _seqbuf[_seqbufptr+1] = (ev);   _seqbuf[_seqbufptr+2] = 0;  _seqbuf[_seqbufptr+3] = 0;  *(unsigned int *)&_seqbuf[_seqbufptr+4] = (parm);   _SEQ_ADVBUF(8);}
+
+#define SEQ_PLAYAUDIO(devmask) _LOCAL_EVENT(LOCL_STARTAUDIO, devmask)
+
+#define SEQ_MIDIOUT(device, byte) {_SEQ_NEEDBUF(4);  _seqbuf[_seqbufptr] = SEQ_MIDIPUTC;  _seqbuf[_seqbufptr+1] = (byte);  _seqbuf[_seqbufptr+2] = (device);  _seqbuf[_seqbufptr+3] = 0;  _SEQ_ADVBUF(4);}
+
+#ifdef OSSLIB
+#define SEQ_WRPATCH(patchx, len)   OSS_write_patch(seqfd, (char*)(patchx), len)
+#define SEQ_WRPATCH2(patchx, len)   OSS_write_patch2(seqfd, (char*)(patchx), len)
+#else
+#define SEQ_WRPATCH(patchx, len)   {if (_seqbufptr) SEQ_DUMPBUF();  if (write(seqfd, (char*)(patchx), len)==-1)   perror("Write patch: /dev/sequencer");}
+#define SEQ_WRPATCH2(patchx, len)   (SEQ_DUMPBUF(), write(seqfd, (char*)(patchx), len))
+#endif
+
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/spinlock.h b/ndk/build/platforms/android-1.5/common/include/linux/spinlock.h
new file mode 100644
index 0000000..5504c9e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/spinlock.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_SPINLOCK_H
+#define __LINUX_SPINLOCK_H
+
+#include <linux/preempt.h>
+#include <linux/linkage.h>
+#include <linux/compiler.h>
+#include <linux/thread_info.h>
+#include <linux/kernel.h>
+#include <linux/stringify.h>
+
+#include <asm/system.h>
+
+#define LOCK_SECTION_NAME ".text.lock."KBUILD_BASENAME
+
+#define LOCK_SECTION_START(extra)   ".subsection 1\n\t"   extra   ".ifndef " LOCK_SECTION_NAME "\n\t"   LOCK_SECTION_NAME ":\n\t"   ".endif\n"
+
+#define LOCK_SECTION_END   ".previous\n\t"
+
+#define __lockfunc fastcall __attribute__((section(".spinlock.text")))
+
+#include <linux/spinlock_types.h>
+
+#include <linux/spinlock_up.h>
+
+#define spin_lock_init(lock)   do { *(lock) = SPIN_LOCK_UNLOCKED; } while (0)
+
+#define rwlock_init(lock)   do { *(lock) = RW_LOCK_UNLOCKED; } while (0)
+
+#define spin_is_locked(lock) __raw_spin_is_locked(&(lock)->raw_lock)
+
+#define spin_unlock_wait(lock) __raw_spin_unlock_wait(&(lock)->raw_lock)
+
+#include <linux/spinlock_api_up.h>
+
+#define _raw_spin_lock(lock) __raw_spin_lock(&(lock)->raw_lock)
+#define _raw_spin_lock_flags(lock, flags)   __raw_spin_lock_flags(&(lock)->raw_lock, *(flags))
+#define _raw_spin_trylock(lock) __raw_spin_trylock(&(lock)->raw_lock)
+#define _raw_spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock)
+#define _raw_read_lock(rwlock) __raw_read_lock(&(rwlock)->raw_lock)
+#define _raw_read_trylock(rwlock) __raw_read_trylock(&(rwlock)->raw_lock)
+#define _raw_read_unlock(rwlock) __raw_read_unlock(&(rwlock)->raw_lock)
+#define _raw_write_lock(rwlock) __raw_write_lock(&(rwlock)->raw_lock)
+#define _raw_write_trylock(rwlock) __raw_write_trylock(&(rwlock)->raw_lock)
+#define _raw_write_unlock(rwlock) __raw_write_unlock(&(rwlock)->raw_lock)
+
+#define read_can_lock(rwlock) __raw_read_can_lock(&(rwlock)->raw_lock)
+#define write_can_lock(rwlock) __raw_write_can_lock(&(rwlock)->raw_lock)
+
+#define spin_trylock(lock) __cond_lock(_spin_trylock(lock))
+#define read_trylock(lock) __cond_lock(_read_trylock(lock))
+#define write_trylock(lock) __cond_lock(_write_trylock(lock))
+
+#define spin_lock(lock) _spin_lock(lock)
+
+#define spin_lock_nested(lock, subclass) _spin_lock(lock)
+
+#define write_lock(lock) _write_lock(lock)
+#define read_lock(lock) _read_lock(lock)
+
+#define spin_lock_irqsave(lock, flags) _spin_lock_irqsave(lock, flags)
+#define read_lock_irqsave(lock, flags) _read_lock_irqsave(lock, flags)
+#define write_lock_irqsave(lock, flags) _write_lock_irqsave(lock, flags)
+
+#define spin_lock_irq(lock) _spin_lock_irq(lock)
+#define spin_lock_bh(lock) _spin_lock_bh(lock)
+
+#define read_lock_irq(lock) _read_lock_irq(lock)
+#define read_lock_bh(lock) _read_lock_bh(lock)
+
+#define write_lock_irq(lock) _write_lock_irq(lock)
+#define write_lock_bh(lock) _write_lock_bh(lock)
+
+#define spin_unlock(lock) _spin_unlock(lock)
+#define read_unlock(lock) _read_unlock(lock)
+#define write_unlock(lock) _write_unlock(lock)
+#define spin_unlock_irq(lock) _spin_unlock_irq(lock)
+#define read_unlock_irq(lock) _read_unlock_irq(lock)
+#define write_unlock_irq(lock) _write_unlock_irq(lock)
+
+#define spin_unlock_irqrestore(lock, flags)   _spin_unlock_irqrestore(lock, flags)
+#define spin_unlock_bh(lock) _spin_unlock_bh(lock)
+
+#define read_unlock_irqrestore(lock, flags)   _read_unlock_irqrestore(lock, flags)
+#define read_unlock_bh(lock) _read_unlock_bh(lock)
+
+#define write_unlock_irqrestore(lock, flags)   _write_unlock_irqrestore(lock, flags)
+#define write_unlock_bh(lock) _write_unlock_bh(lock)
+
+#define spin_trylock_bh(lock) __cond_lock(_spin_trylock_bh(lock))
+
+#define spin_trylock_irq(lock)  ({   local_irq_disable();   _spin_trylock(lock) ?   1 : ({ local_irq_enable(); 0; });  })
+
+#define spin_trylock_irqsave(lock, flags)  ({   local_irq_save(flags);   _spin_trylock(lock) ?   1 : ({ local_irq_restore(flags); 0; });  })
+
+#include <asm/atomic.h>
+
+#define atomic_dec_and_lock(atomic, lock)   __cond_lock(_atomic_dec_and_lock(atomic, lock))
+
+#define spin_can_lock(lock) (!spin_is_locked(lock))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/spinlock_api_smp.h b/ndk/build/platforms/android-1.5/common/include/linux/spinlock_api_smp.h
new file mode 100644
index 0000000..74d8cc9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/spinlock_api_smp.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_SPINLOCK_API_SMP_H
+#define __LINUX_SPINLOCK_API_SMP_H
+
+#ifndef __LINUX_SPINLOCK_H
+#error "please don't include this file directly"
+#endif
+
+#define assert_spin_locked(x) BUG_ON(!spin_is_locked(x))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/spinlock_api_up.h b/ndk/build/platforms/android-1.5/common/include/linux/spinlock_api_up.h
new file mode 100644
index 0000000..c9a5c01
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/spinlock_api_up.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_SPINLOCK_API_UP_H
+#define __LINUX_SPINLOCK_API_UP_H
+
+#ifndef __LINUX_SPINLOCK_H
+#error "please don't include this file directly"
+#endif
+
+#define in_lock_functions(ADDR) 0
+
+#define assert_spin_locked(lock) do { (void)(lock); } while (0)
+
+#define __LOCK(lock)   do { preempt_disable(); __acquire(lock); (void)(lock); } while (0)
+
+#define __LOCK_BH(lock)   do { local_bh_disable(); __LOCK(lock); } while (0)
+
+#define __LOCK_IRQ(lock)   do { local_irq_disable(); __LOCK(lock); } while (0)
+
+#define __LOCK_IRQSAVE(lock, flags)   do { local_irq_save(flags); __LOCK(lock); } while (0)
+
+#define __UNLOCK(lock)   do { preempt_enable(); __release(lock); (void)(lock); } while (0)
+
+#define __UNLOCK_BH(lock)   do { preempt_enable_no_resched(); local_bh_enable(); __release(lock); (void)(lock); } while (0)
+
+#define __UNLOCK_IRQ(lock)   do { local_irq_enable(); __UNLOCK(lock); } while (0)
+
+#define __UNLOCK_IRQRESTORE(lock, flags)   do { local_irq_restore(flags); __UNLOCK(lock); } while (0)
+
+#define _spin_lock(lock) __LOCK(lock)
+#define _spin_lock_nested(lock, subclass) __LOCK(lock)
+#define _read_lock(lock) __LOCK(lock)
+#define _write_lock(lock) __LOCK(lock)
+#define _spin_lock_bh(lock) __LOCK_BH(lock)
+#define _read_lock_bh(lock) __LOCK_BH(lock)
+#define _write_lock_bh(lock) __LOCK_BH(lock)
+#define _spin_lock_irq(lock) __LOCK_IRQ(lock)
+#define _read_lock_irq(lock) __LOCK_IRQ(lock)
+#define _write_lock_irq(lock) __LOCK_IRQ(lock)
+#define _spin_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags)
+#define _read_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags)
+#define _write_lock_irqsave(lock, flags) __LOCK_IRQSAVE(lock, flags)
+#define _spin_trylock(lock) ({ __LOCK(lock); 1; })
+#define _read_trylock(lock) ({ __LOCK(lock); 1; })
+#define _write_trylock(lock) ({ __LOCK(lock); 1; })
+#define _spin_trylock_bh(lock) ({ __LOCK_BH(lock); 1; })
+#define _spin_unlock(lock) __UNLOCK(lock)
+#define _read_unlock(lock) __UNLOCK(lock)
+#define _write_unlock(lock) __UNLOCK(lock)
+#define _spin_unlock_bh(lock) __UNLOCK_BH(lock)
+#define _write_unlock_bh(lock) __UNLOCK_BH(lock)
+#define _read_unlock_bh(lock) __UNLOCK_BH(lock)
+#define _spin_unlock_irq(lock) __UNLOCK_IRQ(lock)
+#define _read_unlock_irq(lock) __UNLOCK_IRQ(lock)
+#define _write_unlock_irq(lock) __UNLOCK_IRQ(lock)
+#define _spin_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags)
+#define _read_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags)
+#define _write_unlock_irqrestore(lock, flags) __UNLOCK_IRQRESTORE(lock, flags)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/spinlock_types.h b/ndk/build/platforms/android-1.5/common/include/linux/spinlock_types.h
new file mode 100644
index 0000000..0938b51
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/spinlock_types.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_SPINLOCK_TYPES_H
+#define __LINUX_SPINLOCK_TYPES_H
+
+#include <linux/lockdep.h>
+
+#include <linux/spinlock_types_up.h>
+
+typedef struct {
+ raw_spinlock_t raw_lock;
+} spinlock_t;
+
+#define SPINLOCK_MAGIC 0xdead4ead
+
+typedef struct {
+ raw_rwlock_t raw_lock;
+} rwlock_t;
+
+#define RWLOCK_MAGIC 0xdeaf1eed
+
+#define SPINLOCK_OWNER_INIT ((void *)-1L)
+
+#define SPIN_DEP_MAP_INIT(lockname)
+
+#define RW_DEP_MAP_INIT(lockname)
+
+#define __SPIN_LOCK_UNLOCKED(lockname)   (spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED,   SPIN_DEP_MAP_INIT(lockname) }
+#define __RW_LOCK_UNLOCKED(lockname)   (rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED,   RW_DEP_MAP_INIT(lockname) }
+
+#define SPIN_LOCK_UNLOCKED __SPIN_LOCK_UNLOCKED(old_style_spin_init)
+#define RW_LOCK_UNLOCKED __RW_LOCK_UNLOCKED(old_style_rw_init)
+
+#define DEFINE_SPINLOCK(x) spinlock_t x = __SPIN_LOCK_UNLOCKED(x)
+#define DEFINE_RWLOCK(x) rwlock_t x = __RW_LOCK_UNLOCKED(x)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/spinlock_types_up.h b/ndk/build/platforms/android-1.5/common/include/linux/spinlock_types_up.h
new file mode 100644
index 0000000..0db3037
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/spinlock_types_up.h
@@ -0,0 +1,29 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_SPINLOCK_TYPES_UP_H
+#define __LINUX_SPINLOCK_TYPES_UP_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+#error "please don't include this file directly"
+#endif
+
+typedef struct { } raw_spinlock_t;
+
+#define __RAW_SPIN_LOCK_UNLOCKED { }
+
+typedef struct {
+
+} raw_rwlock_t;
+
+#define __RAW_RW_LOCK_UNLOCKED { }
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/spinlock_up.h b/ndk/build/platforms/android-1.5/common/include/linux/spinlock_up.h
new file mode 100644
index 0000000..b4958dc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/spinlock_up.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_SPINLOCK_UP_H
+#define __LINUX_SPINLOCK_UP_H
+
+#ifndef __LINUX_SPINLOCK_H
+#error "please don't include this file directly"
+#endif
+
+#define __raw_spin_is_locked(lock) ((void)(lock), 0)
+
+#define __raw_spin_lock(lock) do { (void)(lock); } while (0)
+#define __raw_spin_unlock(lock) do { (void)(lock); } while (0)
+#define __raw_spin_trylock(lock) ({ (void)(lock); 1; })
+
+#define __raw_read_can_lock(lock) (((void)(lock), 1))
+#define __raw_write_can_lock(lock) (((void)(lock), 1))
+
+#define __raw_spin_unlock_wait(lock)   do { cpu_relax(); } while (__raw_spin_is_locked(lock))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/stacktrace.h b/ndk/build/platforms/android-1.5/common/include/linux/stacktrace.h
new file mode 100644
index 0000000..af7ecc8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/stacktrace.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_STACKTRACE_H
+#define __LINUX_STACKTRACE_H
+
+#define save_stack_trace(trace, task, all, skip) do { } while (0)
+#define print_stack_trace(trace) do { } while (0)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/stat.h b/ndk/build/platforms/android-1.5/common/include/linux/stat.h
new file mode 100644
index 0000000..0d757f4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/stat.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_STAT_H
+#define _LINUX_STAT_H
+
+#if !defined(__GLIBC__) || __GLIBC__ < 2
+
+#define S_IFMT 00170000
+#define S_IFSOCK 0140000
+#define S_IFLNK 0120000
+#define S_IFREG 0100000
+#define S_IFBLK 0060000
+#define S_IFDIR 0040000
+#define S_IFCHR 0020000
+#define S_IFIFO 0010000
+#define S_ISUID 0004000
+#define S_ISGID 0002000
+#define S_ISVTX 0001000
+
+#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+
+#define S_IRWXU 00700
+#define S_IRUSR 00400
+#define S_IWUSR 00200
+#define S_IXUSR 00100
+
+#define S_IRWXG 00070
+#define S_IRGRP 00040
+#define S_IWGRP 00020
+#define S_IXGRP 00010
+
+#define S_IRWXO 00007
+#define S_IROTH 00004
+#define S_IWOTH 00002
+#define S_IXOTH 00001
+
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/statfs.h b/ndk/build/platforms/android-1.5/common/include/linux/statfs.h
new file mode 100644
index 0000000..43a5d70
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/statfs.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_STATFS_H
+#define _LINUX_STATFS_H
+
+#include <linux/types.h>
+
+#include <asm/statfs.h>
+
+struct kstatfs {
+ long f_type;
+ long f_bsize;
+ u64 f_blocks;
+ u64 f_bfree;
+ u64 f_bavail;
+ u64 f_files;
+ u64 f_ffree;
+ __kernel_fsid_t f_fsid;
+ long f_namelen;
+ long f_frsize;
+ long f_spare[5];
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/stddef.h b/ndk/build/platforms/android-1.5/common/include/linux/stddef.h
new file mode 100644
index 0000000..5412f47
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/stddef.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_STDDEF_H
+#define _LINUX_STDDEF_H
+
+#include <linux/compiler.h>
+
+#undef NULL
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+
+#undef offsetof
+#ifdef __compiler_offsetof
+#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
+#else
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/string.h b/ndk/build/platforms/android-1.5/common/include/linux/string.h
new file mode 100644
index 0000000..6759068
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/string.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_STRING_H_
+#define _LINUX_STRING_H_
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/stringify.h b/ndk/build/platforms/android-1.5/common/include/linux/stringify.h
new file mode 100644
index 0000000..cbb9e5b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/stringify.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_STRINGIFY_H
+#define __LINUX_STRINGIFY_H
+
+#define __stringify_1(x) #x
+#define __stringify(x) __stringify_1(x)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/auth.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/auth.h
new file mode 100644
index 0000000..ae0a3d0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/auth.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SUNRPC_AUTH_H
+#define _LINUX_SUNRPC_AUTH_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/auth_gss.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/auth_gss.h
new file mode 100644
index 0000000..a64f1f8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/auth_gss.h
@@ -0,0 +1,16 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SUNRPC_AUTH_GSS_H
+#define _LINUX_SUNRPC_AUTH_GSS_H
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/clnt.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/clnt.h
new file mode 100644
index 0000000..a562ad9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/clnt.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SUNRPC_CLNT_H
+#define _LINUX_SUNRPC_CLNT_H
+
+#include <linux/sunrpc/msg_prot.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/xprt.h>
+#include <linux/sunrpc/auth.h>
+#include <linux/sunrpc/stats.h>
+#include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/timer.h>
+#include <asm/signal.h>
+
+struct rpc_portmap {
+ __u32 pm_prog;
+ __u32 pm_vers;
+ __u32 pm_prot;
+ __u16 pm_port;
+ unsigned char pm_binding : 1;
+ struct rpc_wait_queue pm_bindwait;
+};
+
+struct rpc_inode;
+
+struct rpc_clnt {
+ atomic_t cl_count;
+ atomic_t cl_users;
+ struct rpc_xprt * cl_xprt;
+ struct rpc_procinfo * cl_procinfo;
+ u32 cl_maxproc;
+
+ char * cl_server;
+ char * cl_protname;
+ struct rpc_auth * cl_auth;
+ struct rpc_stat * cl_stats;
+ struct rpc_iostats * cl_metrics;
+
+ unsigned int cl_softrtry : 1,
+ cl_intr : 1,
+ cl_autobind : 1,
+ cl_oneshot : 1,
+ cl_dead : 1;
+
+ struct rpc_rtt * cl_rtt;
+ struct rpc_portmap * cl_pmap;
+
+ int cl_nodelen;
+ char cl_nodename[UNX_MAXNODENAME];
+ char cl_pathname[30];
+ struct vfsmount * cl_vfsmnt;
+ struct dentry * cl_dentry;
+ struct rpc_clnt * cl_parent;
+ struct rpc_rtt cl_rtt_default;
+ struct rpc_portmap cl_pmap_default;
+ char cl_inline_name[32];
+};
+#define cl_timeout cl_xprt->timeout
+#define cl_prog cl_pmap->pm_prog
+#define cl_vers cl_pmap->pm_vers
+#define cl_port cl_pmap->pm_port
+#define cl_prot cl_pmap->pm_prot
+
+#define RPC_MAXVERSION 4
+struct rpc_program {
+ char * name;
+ u32 number;
+ unsigned int nrvers;
+ struct rpc_version ** version;
+ struct rpc_stat * stats;
+ char * pipe_dir_name;
+};
+
+struct rpc_version {
+ u32 number;
+ unsigned int nrprocs;
+ struct rpc_procinfo * procs;
+};
+
+struct rpc_procinfo {
+ u32 p_proc;
+ kxdrproc_t p_encode;
+ kxdrproc_t p_decode;
+ unsigned int p_bufsiz;
+ unsigned int p_count;
+ unsigned int p_timer;
+ u32 p_statidx;
+ char * p_name;
+};
+
+#define RPC_CONGESTED(clnt) (RPCXPRT_CONGESTED((clnt)->cl_xprt))
+#define RPC_PEERADDR(clnt) (&(clnt)->cl_xprt->addr)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/debug.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/debug.h
new file mode 100644
index 0000000..e2689f1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/debug.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SUNRPC_DEBUG_H_
+#define _LINUX_SUNRPC_DEBUG_H_
+
+#define RPCDBG_XPRT 0x0001
+#define RPCDBG_CALL 0x0002
+#define RPCDBG_DEBUG 0x0004
+#define RPCDBG_NFS 0x0008
+#define RPCDBG_AUTH 0x0010
+#define RPCDBG_PMAP 0x0020
+#define RPCDBG_SCHED 0x0040
+#define RPCDBG_TRANS 0x0080
+#define RPCDBG_SVCSOCK 0x0100
+#define RPCDBG_SVCDSP 0x0200
+#define RPCDBG_MISC 0x0400
+#define RPCDBG_CACHE 0x0800
+#define RPCDBG_ALL 0x7fff
+
+#define CTL_SUNRPC 7249  
+
+enum {
+ CTL_RPCDEBUG = 1,
+ CTL_NFSDEBUG,
+ CTL_NFSDDEBUG,
+ CTL_NLMDEBUG,
+ CTL_SLOTTABLE_UDP,
+ CTL_SLOTTABLE_TCP,
+ CTL_MIN_RESVPORT,
+ CTL_MAX_RESVPORT,
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/gss_api.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/gss_api.h
new file mode 100644
index 0000000..cbc77c2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/gss_api.h
@@ -0,0 +1,16 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SUNRPC_GSS_API_H
+#define _LINUX_SUNRPC_GSS_API_H
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/gss_asn1.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/gss_asn1.h
new file mode 100644
index 0000000..8f18ba0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/gss_asn1.h
@@ -0,0 +1,35 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <linux/sunrpc/gss_api.h>
+
+#define SIZEOF_INT 4
+
+#define G_BAD_SERVICE_NAME (-2045022976L)
+#define G_BAD_STRING_UID (-2045022975L)
+#define G_NOUSER (-2045022974L)
+#define G_VALIDATE_FAILED (-2045022973L)
+#define G_BUFFER_ALLOC (-2045022972L)
+#define G_BAD_MSG_CTX (-2045022971L)
+#define G_WRONG_SIZE (-2045022970L)
+#define G_BAD_USAGE (-2045022969L)
+#define G_UNKNOWN_QOP (-2045022968L)
+#define G_NO_HOSTNAME (-2045022967L)
+#define G_BAD_HOSTNAME (-2045022966L)
+#define G_WRONG_MECH (-2045022965L)
+#define G_BAD_TOK_HEADER (-2045022964L)
+#define G_BAD_DIRECTION (-2045022963L)
+#define G_TOK_TRUNC (-2045022962L)
+#define G_REFLECT (-2045022961L)
+#define G_WRONG_TOKID (-2045022960L)
+
+#define g_OID_equal(o1,o2)   (((o1)->len == (o2)->len) &&   (memcmp((o1)->data,(o2)->data,(int) (o1)->len) == 0))
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/gss_err.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/gss_err.h
new file mode 100644
index 0000000..01fb1b4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/gss_err.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SUNRPC_GSS_ERR_H
+#define _LINUX_SUNRPC_GSS_ERR_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/msg_prot.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/msg_prot.h
new file mode 100644
index 0000000..52f4e76
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/msg_prot.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SUNRPC_MSGPROT_H_
+#define _LINUX_SUNRPC_MSGPROT_H_
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/sched.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/sched.h
new file mode 100644
index 0000000..859b2d8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/sched.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SUNRPC_SCHED_H_
+#define _LINUX_SUNRPC_SCHED_H_
+
+#include <linux/timer.h>
+#include <linux/sunrpc/types.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <linux/sunrpc/xdr.h>
+
+struct rpc_procinfo;
+struct rpc_message {
+ struct rpc_procinfo * rpc_proc;
+ void * rpc_argp;
+ void * rpc_resp;
+ struct rpc_cred * rpc_cred;
+};
+
+struct rpc_call_ops;
+struct rpc_wait_queue;
+struct rpc_wait {
+ struct list_head list;
+ struct list_head links;
+ struct rpc_wait_queue * rpc_waitq;
+};
+
+struct rpc_task {
+#ifdef RPC_DEBUG
+ unsigned long tk_magic;
+#endif
+ atomic_t tk_count;
+ struct list_head tk_task;
+ struct rpc_clnt * tk_client;
+ struct rpc_rqst * tk_rqstp;
+ int tk_status;
+
+ struct rpc_message tk_msg;
+ __u8 tk_garb_retry;
+ __u8 tk_cred_retry;
+
+ unsigned long tk_cookie;
+
+ void (*tk_timeout_fn)(struct rpc_task *);
+ void (*tk_callback)(struct rpc_task *);
+ void (*tk_action)(struct rpc_task *);
+ const struct rpc_call_ops *tk_ops;
+ void * tk_calldata;
+
+ struct timer_list tk_timer;
+ unsigned long tk_timeout;
+ unsigned short tk_flags;
+ unsigned char tk_priority : 2;
+ unsigned long tk_runstate;
+ struct workqueue_struct *tk_workqueue;
+ union {
+ struct work_struct tk_work;
+ struct rpc_wait tk_wait;
+ } u;
+
+ unsigned short tk_timeouts;
+ size_t tk_bytes_sent;
+ unsigned long tk_start;
+ long tk_rtt;
+
+#ifdef RPC_DEBUG
+ unsigned short tk_pid;
+#endif
+};
+#define tk_auth tk_client->cl_auth
+#define tk_xprt tk_client->cl_xprt
+
+#define task_for_each(task, pos, head)   list_for_each(pos, head)   if ((task=list_entry(pos, struct rpc_task, u.tk_wait.list)),1)
+
+#define task_for_first(task, head)   if (!list_empty(head) &&   ((task=list_entry((head)->next, struct rpc_task, u.tk_wait.list)),1))
+
+#define alltask_for_each(task, pos, head)   list_for_each(pos, head)   if ((task=list_entry(pos, struct rpc_task, tk_task)),1)
+
+typedef void (*rpc_action)(struct rpc_task *);
+
+struct rpc_call_ops {
+ void (*rpc_call_prepare)(struct rpc_task *, void *);
+ void (*rpc_call_done)(struct rpc_task *, void *);
+ void (*rpc_release)(void *);
+};
+
+#define RPC_TASK_ASYNC 0x0001  
+#define RPC_TASK_SWAPPER 0x0002  
+#define RPC_TASK_CHILD 0x0008  
+#define RPC_CALL_MAJORSEEN 0x0020  
+#define RPC_TASK_ROOTCREDS 0x0040  
+#define RPC_TASK_DYNAMIC 0x0080  
+#define RPC_TASK_KILLED 0x0100  
+#define RPC_TASK_SOFT 0x0200  
+#define RPC_TASK_NOINTR 0x0400  
+
+#define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC)
+#define RPC_IS_CHILD(t) ((t)->tk_flags & RPC_TASK_CHILD)
+#define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER)
+#define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS)
+#define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED)
+#define RPC_DO_CALLBACK(t) ((t)->tk_callback != NULL)
+#define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT)
+#define RPC_TASK_UNINTERRUPTIBLE(t) ((t)->tk_flags & RPC_TASK_NOINTR)
+
+#define RPC_TASK_RUNNING 0
+#define RPC_TASK_QUEUED 1
+#define RPC_TASK_WAKEUP 2
+#define RPC_TASK_HAS_TIMER 3
+#define RPC_TASK_ACTIVE 4
+
+#define RPC_IS_RUNNING(t) (test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
+#define rpc_set_running(t) (set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
+#define rpc_test_and_set_running(t)   (test_and_set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
+#define rpc_clear_running(t)   do {   smp_mb__before_clear_bit();   clear_bit(RPC_TASK_RUNNING, &(t)->tk_runstate);   smp_mb__after_clear_bit();   } while (0)
+
+#define RPC_IS_QUEUED(t) (test_bit(RPC_TASK_QUEUED, &(t)->tk_runstate))
+#define rpc_set_queued(t) (set_bit(RPC_TASK_QUEUED, &(t)->tk_runstate))
+#define rpc_clear_queued(t)   do {   smp_mb__before_clear_bit();   clear_bit(RPC_TASK_QUEUED, &(t)->tk_runstate);   smp_mb__after_clear_bit();   } while (0)
+
+#define rpc_start_wakeup(t)   (test_and_set_bit(RPC_TASK_WAKEUP, &(t)->tk_runstate) == 0)
+#define rpc_finish_wakeup(t)   do {   smp_mb__before_clear_bit();   clear_bit(RPC_TASK_WAKEUP, &(t)->tk_runstate);   smp_mb__after_clear_bit();   } while (0)
+
+#define RPC_IS_ACTIVATED(t) (test_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate))
+#define rpc_set_active(t) (set_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate))
+#define rpc_clear_active(t)   do {   smp_mb__before_clear_bit();   clear_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate);   smp_mb__after_clear_bit();   } while(0)
+
+#define RPC_PRIORITY_LOW 0
+#define RPC_PRIORITY_NORMAL 1
+#define RPC_PRIORITY_HIGH 2
+#define RPC_NR_PRIORITY (RPC_PRIORITY_HIGH+1)
+
+struct rpc_wait_queue {
+ spinlock_t lock;
+ struct list_head tasks[RPC_NR_PRIORITY];
+ unsigned long cookie;
+ unsigned char maxpriority;
+ unsigned char priority;
+ unsigned char count;
+ unsigned char nr;
+ unsigned short qlen;
+#ifdef RPC_DEBUG
+ const char * name;
+#endif
+};
+
+#define RPC_BATCH_COUNT 16
+
+#ifndef RPC_DEBUG
+#define RPC_WAITQ_INIT(var,qname) {   .lock = SPIN_LOCK_UNLOCKED,   .tasks = {   [0] = LIST_HEAD_INIT(var.tasks[0]),   [1] = LIST_HEAD_INIT(var.tasks[1]),   [2] = LIST_HEAD_INIT(var.tasks[2]),   },   }
+#else
+#define RPC_WAITQ_INIT(var,qname) {   .lock = SPIN_LOCK_UNLOCKED,   .tasks = {   [0] = LIST_HEAD_INIT(var.tasks[0]),   [1] = LIST_HEAD_INIT(var.tasks[1]),   [2] = LIST_HEAD_INIT(var.tasks[2]),   },   .name = qname,   }
+#endif
+#define RPC_WAITQ(var,qname) struct rpc_wait_queue var = RPC_WAITQ_INIT(var,qname)
+
+#define RPC_IS_PRIORITY(q) ((q)->maxpriority > 0)
+
+struct rpc_task *rpc_new_task(struct rpc_clnt *, int flags,
+ const struct rpc_call_ops *ops, void *data);
+struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
+ const struct rpc_call_ops *ops, void *data);
+struct rpc_task *rpc_new_child(struct rpc_clnt *, struct rpc_task *parent);
+
+struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *);
+
+#ifdef RPC_DEBUG
+
+#endif
+
+#ifdef RPC_DEBUG
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/stats.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/stats.h
new file mode 100644
index 0000000..03e7338
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/stats.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SUNRPC_STATS_H
+#define _LINUX_SUNRPC_STATS_H
+
+#include <linux/proc_fs.h>
+
+struct rpc_stat {
+ struct rpc_program * program;
+
+ unsigned int netcnt,
+ netudpcnt,
+ nettcpcnt,
+ nettcpconn,
+ netreconn;
+ unsigned int rpccnt,
+ rpcretrans,
+ rpcauthrefresh,
+ rpcgarbage;
+};
+
+struct svc_stat {
+ struct svc_program * program;
+
+ unsigned int netcnt,
+ netudpcnt,
+ nettcpcnt,
+ nettcpconn;
+ unsigned int rpccnt,
+ rpcbadfmt,
+ rpcbadauth,
+ rpcbadclnt;
+};
+
+#ifdef MODULE
+
+#endif
+
+#define proc_net_rpc NULL
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/svc.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/svc.h
new file mode 100644
index 0000000..7a0cc2d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/svc.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef SUNRPC_SVC_H
+#define SUNRPC_SVC_H
+
+#include <linux/in.h>
+#include <linux/sunrpc/types.h>
+#include <linux/sunrpc/xdr.h>
+#include <linux/sunrpc/svcauth.h>
+#include <linux/wait.h>
+#include <linux/mm.h>
+
+struct svc_serv {
+ struct list_head sv_threads;
+ struct list_head sv_sockets;
+ struct svc_program * sv_program;
+ struct svc_stat * sv_stats;
+ spinlock_t sv_lock;
+ unsigned int sv_nrthreads;
+ unsigned int sv_bufsz;
+ unsigned int sv_xdrsize;
+
+ struct list_head sv_permsocks;
+ struct list_head sv_tempsocks;
+ int sv_tmpcnt;
+
+ char * sv_name;
+};
+
+#define RPCSVC_MAXPAYLOAD (64*1024u)
+
+#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2)
+
+struct svc_program {
+ struct svc_program * pg_next;
+ u32 pg_prog;
+ unsigned int pg_lovers;
+ unsigned int pg_hivers;
+ unsigned int pg_nvers;
+ struct svc_version ** pg_vers;
+ char * pg_name;
+ char * pg_class;
+ struct svc_stat * pg_stats;
+ int (*pg_authenticate)(struct svc_rqst *);
+};
+
+struct svc_version {
+ u32 vs_vers;
+ u32 vs_nproc;
+ struct svc_procedure * vs_proc;
+ u32 vs_xdrsize;
+
+ int (*vs_dispatch)(struct svc_rqst *, u32 *);
+};
+
+typedef int (*svc_procfunc)(struct svc_rqst *, void *argp, void *resp);
+struct svc_procedure {
+ svc_procfunc pc_func;
+ kxdrproc_t pc_decode;
+ kxdrproc_t pc_encode;
+ kxdrproc_t pc_release;
+ unsigned int pc_argsize;
+ unsigned int pc_ressize;
+ unsigned int pc_count;
+ unsigned int pc_cachetype;
+ unsigned int pc_xdrressize;
+};
+
+typedef void (*svc_thread_fn)(struct svc_rqst *);
+
+struct svc_serv * svc_create(struct svc_program *, unsigned int);
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/svcauth.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/svcauth.h
new file mode 100644
index 0000000..9b414d7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/svcauth.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SUNRPC_SVCAUTH_H_
+#define _LINUX_SUNRPC_SVCAUTH_H_
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/timer.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/timer.h
new file mode 100644
index 0000000..8fb78e5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/timer.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SUNRPC_TIMER_H
+#define _LINUX_SUNRPC_TIMER_H
+
+#include <asm/atomic.h>
+
+struct rpc_rtt {
+ unsigned long timeo;
+ unsigned long srtt[5];
+ unsigned long sdrtt[5];
+ int ntimeouts[5];
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/types.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/types.h
new file mode 100644
index 0000000..ce52052
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/types.h
@@ -0,0 +1,22 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SUNRPC_TYPES_H_
+#define _LINUX_SUNRPC_TYPES_H_
+
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <linux/sunrpc/debug.h>
+#include <linux/list.h>
+
+#define signalled() (signal_pending(current))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/xdr.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/xdr.h
new file mode 100644
index 0000000..d513843
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/xdr.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _SUNRPC_XDR_H_
+#define _SUNRPC_XDR_H_
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/xprt.h b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/xprt.h
new file mode 100644
index 0000000..145a26d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sunrpc/xprt.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SUNRPC_XPRT_H
+#define _LINUX_SUNRPC_XPRT_H
+
+#include <linux/uio.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/sunrpc/sched.h>
+#include <linux/sunrpc/xdr.h>
+
+#define RPC_MIN_SLOT_TABLE (2U)
+#define RPC_DEF_SLOT_TABLE (16U)
+#define RPC_MAX_SLOT_TABLE (128U)
+
+#define RPC_CALLHDRSIZE 6
+#define RPC_REPHDRSIZE 4
+
+#define RPC_MIN_RESVPORT (1U)
+#define RPC_MAX_RESVPORT (65535U)
+#define RPC_DEF_MIN_RESVPORT (665U)
+#define RPC_DEF_MAX_RESVPORT (1023U)
+
+struct rpc_timeout {
+ unsigned long to_initval,
+ to_maxval,
+ to_increment;
+ unsigned int to_retries;
+ unsigned char to_exponential;
+};
+
+struct rpc_task;
+struct rpc_xprt;
+struct seq_file;
+
+struct rpc_rqst {
+
+ struct rpc_xprt * rq_xprt;
+ struct xdr_buf rq_snd_buf;
+ struct xdr_buf rq_rcv_buf;
+
+ struct rpc_task * rq_task;
+ __u32 rq_xid;
+ int rq_cong;
+ int rq_received;
+ u32 rq_seqno;
+ int rq_enc_pages_num;
+ struct page **rq_enc_pages;
+ void (*rq_release_snd_buf)(struct rpc_rqst *);
+ struct list_head rq_list;
+
+ __u32 * rq_buffer;
+ size_t rq_bufsize;
+
+ struct xdr_buf rq_private_buf;
+ unsigned long rq_majortimeo;
+ unsigned long rq_timeout;
+ unsigned int rq_retries;
+
+ u32 rq_bytes_sent;
+
+ unsigned long rq_xtime;
+ int rq_ntrans;
+};
+#define rq_svec rq_snd_buf.head
+#define rq_slen rq_snd_buf.len
+
+struct rpc_xprt_ops {
+ void (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize);
+ int (*reserve_xprt)(struct rpc_task *task);
+ void (*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task);
+ void (*set_port)(struct rpc_xprt *xprt, unsigned short port);
+ void (*connect)(struct rpc_task *task);
+ void * (*buf_alloc)(struct rpc_task *task, size_t size);
+ void (*buf_free)(struct rpc_task *task);
+ int (*send_request)(struct rpc_task *task);
+ void (*set_retrans_timeout)(struct rpc_task *task);
+ void (*timer)(struct rpc_task *task);
+ void (*release_request)(struct rpc_task *task);
+ void (*close)(struct rpc_xprt *xprt);
+ void (*destroy)(struct rpc_xprt *xprt);
+ void (*print_stats)(struct rpc_xprt *xprt, struct seq_file *seq);
+};
+
+struct rpc_xprt {
+ struct rpc_xprt_ops * ops;
+ struct socket * sock;
+ struct sock * inet;
+
+ struct rpc_timeout timeout;
+ struct sockaddr_in addr;
+ int prot;
+
+ unsigned long cong;
+ unsigned long cwnd;
+
+ size_t rcvsize,
+ sndsize;
+
+ size_t max_payload;
+ unsigned int tsh_size;
+
+ struct rpc_wait_queue sending;
+ struct rpc_wait_queue resend;
+ struct rpc_wait_queue pending;
+ struct rpc_wait_queue backlog;
+ struct list_head free;
+ struct rpc_rqst * slot;
+ unsigned int max_reqs;
+ unsigned long state;
+ unsigned char shutdown : 1,
+ resvport : 1;
+
+ __u32 xid;
+
+ u32 tcp_recm,
+ tcp_xid,
+ tcp_reclen,
+ tcp_offset;
+ unsigned long tcp_copied,
+ tcp_flags;
+
+ unsigned long connect_timeout,
+ bind_timeout,
+ reestablish_timeout;
+ struct work_struct connect_worker;
+ unsigned short port;
+
+ struct work_struct task_cleanup;
+ struct timer_list timer;
+ unsigned long last_used,
+ idle_timeout;
+
+ spinlock_t transport_lock;
+ spinlock_t reserve_lock;
+ struct rpc_task * snd_task;
+
+ struct list_head recv;
+
+ struct {
+ unsigned long bind_count,
+ connect_count,
+ connect_start,
+ connect_time,
+ sends,
+ recvs,
+ bad_xids;
+
+ unsigned long long req_u,
+ bklog_u;
+ } stat;
+
+ void (*old_data_ready)(struct sock *, int);
+ void (*old_state_change)(struct sock *);
+ void (*old_write_space)(struct sock *);
+};
+
+#define XPRT_LAST_FRAG (1 << 0)
+#define XPRT_COPY_RECM (1 << 1)
+#define XPRT_COPY_XID (1 << 2)
+#define XPRT_COPY_DATA (1 << 3)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/swap.h b/ndk/build/platforms/android-1.5/common/include/linux/swap.h
new file mode 100644
index 0000000..63ba556
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/swap.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SWAP_H
+#define _LINUX_SWAP_H
+
+#include <linux/spinlock.h>
+#include <linux/linkage.h>
+#include <linux/mmzone.h>
+#include <linux/list.h>
+#include <linux/sched.h>
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+
+#define SWAP_FLAG_PREFER 0x8000  
+#define SWAP_FLAG_PRIO_MASK 0x7fff
+#define SWAP_FLAG_PRIO_SHIFT 0
+
+#define MAX_SWAPFILES_SHIFT 5
+#define MAX_SWAPFILES (1 << MAX_SWAPFILES_SHIFT)
+
+typedef struct {
+ unsigned long val;
+} swp_entry_t;
+
+struct reclaim_state {
+ unsigned long reclaimed_slab;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sysctl.h b/ndk/build/platforms/android-1.5/common/include/linux/sysctl.h
new file mode 100644
index 0000000..329e561
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sysctl.h
@@ -0,0 +1,824 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_SYSCTL_H
+#define _LINUX_SYSCTL_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+struct file;
+struct completion;
+
+#define CTL_MAXNAME 10  
+
+struct __sysctl_args {
+ int __user *name;
+ int nlen;
+ void __user *oldval;
+ size_t __user *oldlenp;
+ void __user *newval;
+ size_t newlen;
+ unsigned long __unused[4];
+};
+
+enum
+{
+ CTL_KERN=1,
+ CTL_VM=2,
+ CTL_NET=3,
+
+ CTL_FS=5,
+ CTL_DEBUG=6,
+ CTL_DEV=7,
+ CTL_BUS=8,
+ CTL_ABI=9,
+ CTL_CPU=10
+};
+
+enum
+{
+ CTL_BUS_ISA=1
+};
+
+enum
+{
+ INOTIFY_MAX_USER_INSTANCES=1,
+ INOTIFY_MAX_USER_WATCHES=2,
+ INOTIFY_MAX_QUEUED_EVENTS=3
+};
+
+enum
+{
+ KERN_OSTYPE=1,
+ KERN_OSRELEASE=2,
+ KERN_OSREV=3,
+ KERN_VERSION=4,
+ KERN_SECUREMASK=5,
+ KERN_PROF=6,
+ KERN_NODENAME=7,
+ KERN_DOMAINNAME=8,
+
+ KERN_CAP_BSET=14,
+ KERN_PANIC=15,
+ KERN_REALROOTDEV=16,
+
+ KERN_SPARC_REBOOT=21,
+ KERN_CTLALTDEL=22,
+ KERN_PRINTK=23,
+ KERN_NAMETRANS=24,
+ KERN_PPC_HTABRECLAIM=25,
+ KERN_PPC_ZEROPAGED=26,
+ KERN_PPC_POWERSAVE_NAP=27,
+ KERN_MODPROBE=28,
+ KERN_SG_BIG_BUFF=29,
+ KERN_ACCT=30,
+ KERN_PPC_L2CR=31,
+
+ KERN_RTSIGNR=32,
+ KERN_RTSIGMAX=33,
+
+ KERN_SHMMAX=34,
+ KERN_MSGMAX=35,
+ KERN_MSGMNB=36,
+ KERN_MSGPOOL=37,
+ KERN_SYSRQ=38,
+ KERN_MAX_THREADS=39,
+ KERN_RANDOM=40,
+ KERN_SHMALL=41,
+ KERN_MSGMNI=42,
+ KERN_SEM=43,
+ KERN_SPARC_STOP_A=44,
+ KERN_SHMMNI=45,
+ KERN_OVERFLOWUID=46,
+ KERN_OVERFLOWGID=47,
+ KERN_SHMPATH=48,
+ KERN_HOTPLUG=49,
+ KERN_IEEE_EMULATION_WARNINGS=50,
+ KERN_S390_USER_DEBUG_LOGGING=51,
+ KERN_CORE_USES_PID=52,
+ KERN_TAINTED=53,
+ KERN_CADPID=54,
+ KERN_PIDMAX=55,
+ KERN_CORE_PATTERN=56,
+ KERN_PANIC_ON_OOPS=57,
+ KERN_HPPA_PWRSW=58,
+ KERN_HPPA_UNALIGNED=59,
+ KERN_PRINTK_RATELIMIT=60,
+ KERN_PRINTK_RATELIMIT_BURST=61,
+ KERN_PTY=62,
+ KERN_NGROUPS_MAX=63,
+ KERN_SPARC_SCONS_PWROFF=64,
+ KERN_HZ_TIMER=65,
+ KERN_UNKNOWN_NMI_PANIC=66,
+ KERN_BOOTLOADER_TYPE=67,
+ KERN_RANDOMIZE=68,
+ KERN_SETUID_DUMPABLE=69,
+ KERN_SPIN_RETRY=70,
+ KERN_ACPI_VIDEO_FLAGS=71,
+ KERN_IA64_UNALIGNED=72,
+ KERN_COMPAT_LOG=73,
+ KERN_MAX_LOCK_DEPTH=74,
+};
+
+enum
+{
+ VM_UNUSED1=1,
+ VM_UNUSED2=2,
+ VM_UNUSED3=3,
+ VM_UNUSED4=4,
+ VM_OVERCOMMIT_MEMORY=5,
+ VM_UNUSED5=6,
+ VM_UNUSED7=7,
+ VM_UNUSED8=8,
+ VM_UNUSED9=9,
+ VM_PAGE_CLUSTER=10,
+ VM_DIRTY_BACKGROUND=11,
+ VM_DIRTY_RATIO=12,
+ VM_DIRTY_WB_CS=13,
+ VM_DIRTY_EXPIRE_CS=14,
+ VM_NR_PDFLUSH_THREADS=15,
+ VM_OVERCOMMIT_RATIO=16,
+ VM_PAGEBUF=17,
+ VM_HUGETLB_PAGES=18,
+ VM_SWAPPINESS=19,
+ VM_LOWMEM_RESERVE_RATIO=20,
+ VM_MIN_FREE_KBYTES=21,
+ VM_MAX_MAP_COUNT=22,
+ VM_LAPTOP_MODE=23,
+ VM_BLOCK_DUMP=24,
+ VM_HUGETLB_GROUP=25,
+ VM_VFS_CACHE_PRESSURE=26,
+ VM_LEGACY_VA_LAYOUT=27,
+ VM_SWAP_TOKEN_TIMEOUT=28,
+ VM_DROP_PAGECACHE=29,
+ VM_PERCPU_PAGELIST_FRACTION=30,
+ VM_ZONE_RECLAIM_MODE=31,
+ VM_MIN_UNMAPPED=32,
+ VM_PANIC_ON_OOM=33,
+ VM_VDSO_ENABLED=34,
+};
+
+enum
+{
+ NET_CORE=1,
+ NET_ETHER=2,
+ NET_802=3,
+ NET_UNIX=4,
+ NET_IPV4=5,
+ NET_IPX=6,
+ NET_ATALK=7,
+ NET_NETROM=8,
+ NET_AX25=9,
+ NET_BRIDGE=10,
+ NET_ROSE=11,
+ NET_IPV6=12,
+ NET_X25=13,
+ NET_TR=14,
+ NET_DECNET=15,
+ NET_ECONET=16,
+ NET_SCTP=17,
+ NET_LLC=18,
+ NET_NETFILTER=19,
+ NET_DCCP=20,
+};
+
+enum
+{
+ RANDOM_POOLSIZE=1,
+ RANDOM_ENTROPY_COUNT=2,
+ RANDOM_READ_THRESH=3,
+ RANDOM_WRITE_THRESH=4,
+ RANDOM_BOOT_ID=5,
+ RANDOM_UUID=6
+};
+
+enum
+{
+ PTY_MAX=1,
+ PTY_NR=2
+};
+
+enum
+{
+ BUS_ISA_MEM_BASE=1,
+ BUS_ISA_PORT_BASE=2,
+ BUS_ISA_PORT_SHIFT=3
+};
+
+enum
+{
+ NET_CORE_WMEM_MAX=1,
+ NET_CORE_RMEM_MAX=2,
+ NET_CORE_WMEM_DEFAULT=3,
+ NET_CORE_RMEM_DEFAULT=4,
+
+ NET_CORE_MAX_BACKLOG=6,
+ NET_CORE_FASTROUTE=7,
+ NET_CORE_MSG_COST=8,
+ NET_CORE_MSG_BURST=9,
+ NET_CORE_OPTMEM_MAX=10,
+ NET_CORE_HOT_LIST_LENGTH=11,
+ NET_CORE_DIVERT_VERSION=12,
+ NET_CORE_NO_CONG_THRESH=13,
+ NET_CORE_NO_CONG=14,
+ NET_CORE_LO_CONG=15,
+ NET_CORE_MOD_CONG=16,
+ NET_CORE_DEV_WEIGHT=17,
+ NET_CORE_SOMAXCONN=18,
+ NET_CORE_BUDGET=19,
+ NET_CORE_AEVENT_ETIME=20,
+ NET_CORE_AEVENT_RSEQTH=21,
+};
+
+enum
+{
+ NET_UNIX_DESTROY_DELAY=1,
+ NET_UNIX_DELETE_DELAY=2,
+ NET_UNIX_MAX_DGRAM_QLEN=3,
+};
+
+enum
+{
+ NET_NF_CONNTRACK_MAX=1,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9,
+ NET_NF_CONNTRACK_UDP_TIMEOUT=10,
+ NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11,
+ NET_NF_CONNTRACK_ICMP_TIMEOUT=12,
+ NET_NF_CONNTRACK_GENERIC_TIMEOUT=13,
+ NET_NF_CONNTRACK_BUCKETS=14,
+ NET_NF_CONNTRACK_LOG_INVALID=15,
+ NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16,
+ NET_NF_CONNTRACK_TCP_LOOSE=17,
+ NET_NF_CONNTRACK_TCP_BE_LIBERAL=18,
+ NET_NF_CONNTRACK_TCP_MAX_RETRANS=19,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25,
+ NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26,
+ NET_NF_CONNTRACK_COUNT=27,
+ NET_NF_CONNTRACK_ICMPV6_TIMEOUT=28,
+ NET_NF_CONNTRACK_FRAG6_TIMEOUT=29,
+ NET_NF_CONNTRACK_FRAG6_LOW_THRESH=30,
+ NET_NF_CONNTRACK_FRAG6_HIGH_THRESH=31,
+ NET_NF_CONNTRACK_CHECKSUM=32,
+};
+
+enum
+{
+
+ NET_IPV4_FORWARD=8,
+ NET_IPV4_DYNADDR=9,
+
+ NET_IPV4_CONF=16,
+ NET_IPV4_NEIGH=17,
+ NET_IPV4_ROUTE=18,
+ NET_IPV4_FIB_HASH=19,
+ NET_IPV4_NETFILTER=20,
+
+ NET_IPV4_TCP_TIMESTAMPS=33,
+ NET_IPV4_TCP_WINDOW_SCALING=34,
+ NET_IPV4_TCP_SACK=35,
+ NET_IPV4_TCP_RETRANS_COLLAPSE=36,
+ NET_IPV4_DEFAULT_TTL=37,
+ NET_IPV4_AUTOCONFIG=38,
+ NET_IPV4_NO_PMTU_DISC=39,
+ NET_IPV4_TCP_SYN_RETRIES=40,
+ NET_IPV4_IPFRAG_HIGH_THRESH=41,
+ NET_IPV4_IPFRAG_LOW_THRESH=42,
+ NET_IPV4_IPFRAG_TIME=43,
+ NET_IPV4_TCP_MAX_KA_PROBES=44,
+ NET_IPV4_TCP_KEEPALIVE_TIME=45,
+ NET_IPV4_TCP_KEEPALIVE_PROBES=46,
+ NET_IPV4_TCP_RETRIES1=47,
+ NET_IPV4_TCP_RETRIES2=48,
+ NET_IPV4_TCP_FIN_TIMEOUT=49,
+ NET_IPV4_IP_MASQ_DEBUG=50,
+ NET_TCP_SYNCOOKIES=51,
+ NET_TCP_STDURG=52,
+ NET_TCP_RFC1337=53,
+ NET_TCP_SYN_TAILDROP=54,
+ NET_TCP_MAX_SYN_BACKLOG=55,
+ NET_IPV4_LOCAL_PORT_RANGE=56,
+ NET_IPV4_ICMP_ECHO_IGNORE_ALL=57,
+ NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS=58,
+ NET_IPV4_ICMP_SOURCEQUENCH_RATE=59,
+ NET_IPV4_ICMP_DESTUNREACH_RATE=60,
+ NET_IPV4_ICMP_TIMEEXCEED_RATE=61,
+ NET_IPV4_ICMP_PARAMPROB_RATE=62,
+ NET_IPV4_ICMP_ECHOREPLY_RATE=63,
+ NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES=64,
+ NET_IPV4_IGMP_MAX_MEMBERSHIPS=65,
+ NET_TCP_TW_RECYCLE=66,
+ NET_IPV4_ALWAYS_DEFRAG=67,
+ NET_IPV4_TCP_KEEPALIVE_INTVL=68,
+ NET_IPV4_INET_PEER_THRESHOLD=69,
+ NET_IPV4_INET_PEER_MINTTL=70,
+ NET_IPV4_INET_PEER_MAXTTL=71,
+ NET_IPV4_INET_PEER_GC_MINTIME=72,
+ NET_IPV4_INET_PEER_GC_MAXTIME=73,
+ NET_TCP_ORPHAN_RETRIES=74,
+ NET_TCP_ABORT_ON_OVERFLOW=75,
+ NET_TCP_SYNACK_RETRIES=76,
+ NET_TCP_MAX_ORPHANS=77,
+ NET_TCP_MAX_TW_BUCKETS=78,
+ NET_TCP_FACK=79,
+ NET_TCP_REORDERING=80,
+ NET_TCP_ECN=81,
+ NET_TCP_DSACK=82,
+ NET_TCP_MEM=83,
+ NET_TCP_WMEM=84,
+ NET_TCP_RMEM=85,
+ NET_TCP_APP_WIN=86,
+ NET_TCP_ADV_WIN_SCALE=87,
+ NET_IPV4_NONLOCAL_BIND=88,
+ NET_IPV4_ICMP_RATELIMIT=89,
+ NET_IPV4_ICMP_RATEMASK=90,
+ NET_TCP_TW_REUSE=91,
+ NET_TCP_FRTO=92,
+ NET_TCP_LOW_LATENCY=93,
+ NET_IPV4_IPFRAG_SECRET_INTERVAL=94,
+ NET_IPV4_IGMP_MAX_MSF=96,
+ NET_TCP_NO_METRICS_SAVE=97,
+ NET_TCP_DEFAULT_WIN_SCALE=105,
+ NET_TCP_MODERATE_RCVBUF=106,
+ NET_TCP_TSO_WIN_DIVISOR=107,
+ NET_TCP_BIC_BETA=108,
+ NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
+ NET_TCP_CONG_CONTROL=110,
+ NET_TCP_ABC=111,
+ NET_IPV4_IPFRAG_MAX_DIST=112,
+ NET_TCP_MTU_PROBING=113,
+ NET_TCP_BASE_MSS=114,
+ NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS=115,
+ NET_TCP_DMA_COPYBREAK=116,
+ NET_TCP_SLOW_START_AFTER_IDLE=117,
+};
+
+enum {
+ NET_IPV4_ROUTE_FLUSH=1,
+ NET_IPV4_ROUTE_MIN_DELAY=2,
+ NET_IPV4_ROUTE_MAX_DELAY=3,
+ NET_IPV4_ROUTE_GC_THRESH=4,
+ NET_IPV4_ROUTE_MAX_SIZE=5,
+ NET_IPV4_ROUTE_GC_MIN_INTERVAL=6,
+ NET_IPV4_ROUTE_GC_TIMEOUT=7,
+ NET_IPV4_ROUTE_GC_INTERVAL=8,
+ NET_IPV4_ROUTE_REDIRECT_LOAD=9,
+ NET_IPV4_ROUTE_REDIRECT_NUMBER=10,
+ NET_IPV4_ROUTE_REDIRECT_SILENCE=11,
+ NET_IPV4_ROUTE_ERROR_COST=12,
+ NET_IPV4_ROUTE_ERROR_BURST=13,
+ NET_IPV4_ROUTE_GC_ELASTICITY=14,
+ NET_IPV4_ROUTE_MTU_EXPIRES=15,
+ NET_IPV4_ROUTE_MIN_PMTU=16,
+ NET_IPV4_ROUTE_MIN_ADVMSS=17,
+ NET_IPV4_ROUTE_SECRET_INTERVAL=18,
+ NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS=19,
+};
+
+enum
+{
+ NET_PROTO_CONF_ALL=-2,
+ NET_PROTO_CONF_DEFAULT=-3
+
+};
+
+enum
+{
+ NET_IPV4_CONF_FORWARDING=1,
+ NET_IPV4_CONF_MC_FORWARDING=2,
+ NET_IPV4_CONF_PROXY_ARP=3,
+ NET_IPV4_CONF_ACCEPT_REDIRECTS=4,
+ NET_IPV4_CONF_SECURE_REDIRECTS=5,
+ NET_IPV4_CONF_SEND_REDIRECTS=6,
+ NET_IPV4_CONF_SHARED_MEDIA=7,
+ NET_IPV4_CONF_RP_FILTER=8,
+ NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE=9,
+ NET_IPV4_CONF_BOOTP_RELAY=10,
+ NET_IPV4_CONF_LOG_MARTIANS=11,
+ NET_IPV4_CONF_TAG=12,
+ NET_IPV4_CONF_ARPFILTER=13,
+ NET_IPV4_CONF_MEDIUM_ID=14,
+ NET_IPV4_CONF_NOXFRM=15,
+ NET_IPV4_CONF_NOPOLICY=16,
+ NET_IPV4_CONF_FORCE_IGMP_VERSION=17,
+ NET_IPV4_CONF_ARP_ANNOUNCE=18,
+ NET_IPV4_CONF_ARP_IGNORE=19,
+ NET_IPV4_CONF_PROMOTE_SECONDARIES=20,
+ NET_IPV4_CONF_ARP_ACCEPT=21,
+ __NET_IPV4_CONF_MAX
+};
+
+enum
+{
+ NET_IPV4_NF_CONNTRACK_MAX=1,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9,
+ NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT=10,
+ NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11,
+ NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=12,
+ NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=13,
+ NET_IPV4_NF_CONNTRACK_BUCKETS=14,
+ NET_IPV4_NF_CONNTRACK_LOG_INVALID=15,
+ NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS=16,
+ NET_IPV4_NF_CONNTRACK_TCP_LOOSE=17,
+ NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL=18,
+ NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS=19,
+ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=20,
+ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=21,
+ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=22,
+ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=23,
+ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=24,
+ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=25,
+ NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=26,
+ NET_IPV4_NF_CONNTRACK_COUNT=27,
+ NET_IPV4_NF_CONNTRACK_CHECKSUM=28,
+};
+
+enum {
+ NET_IPV6_CONF=16,
+ NET_IPV6_NEIGH=17,
+ NET_IPV6_ROUTE=18,
+ NET_IPV6_ICMP=19,
+ NET_IPV6_BINDV6ONLY=20,
+ NET_IPV6_IP6FRAG_HIGH_THRESH=21,
+ NET_IPV6_IP6FRAG_LOW_THRESH=22,
+ NET_IPV6_IP6FRAG_TIME=23,
+ NET_IPV6_IP6FRAG_SECRET_INTERVAL=24,
+ NET_IPV6_MLD_MAX_MSF=25,
+};
+
+enum {
+ NET_IPV6_ROUTE_FLUSH=1,
+ NET_IPV6_ROUTE_GC_THRESH=2,
+ NET_IPV6_ROUTE_MAX_SIZE=3,
+ NET_IPV6_ROUTE_GC_MIN_INTERVAL=4,
+ NET_IPV6_ROUTE_GC_TIMEOUT=5,
+ NET_IPV6_ROUTE_GC_INTERVAL=6,
+ NET_IPV6_ROUTE_GC_ELASTICITY=7,
+ NET_IPV6_ROUTE_MTU_EXPIRES=8,
+ NET_IPV6_ROUTE_MIN_ADVMSS=9,
+ NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS=10
+};
+
+enum {
+ NET_IPV6_FORWARDING=1,
+ NET_IPV6_HOP_LIMIT=2,
+ NET_IPV6_MTU=3,
+ NET_IPV6_ACCEPT_RA=4,
+ NET_IPV6_ACCEPT_REDIRECTS=5,
+ NET_IPV6_AUTOCONF=6,
+ NET_IPV6_DAD_TRANSMITS=7,
+ NET_IPV6_RTR_SOLICITS=8,
+ NET_IPV6_RTR_SOLICIT_INTERVAL=9,
+ NET_IPV6_RTR_SOLICIT_DELAY=10,
+ NET_IPV6_USE_TEMPADDR=11,
+ NET_IPV6_TEMP_VALID_LFT=12,
+ NET_IPV6_TEMP_PREFERED_LFT=13,
+ NET_IPV6_REGEN_MAX_RETRY=14,
+ NET_IPV6_MAX_DESYNC_FACTOR=15,
+ NET_IPV6_MAX_ADDRESSES=16,
+ NET_IPV6_FORCE_MLD_VERSION=17,
+ NET_IPV6_ACCEPT_RA_DEFRTR=18,
+ NET_IPV6_ACCEPT_RA_PINFO=19,
+ NET_IPV6_ACCEPT_RA_RTR_PREF=20,
+ NET_IPV6_RTR_PROBE_INTERVAL=21,
+ NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22,
+ __NET_IPV6_MAX
+};
+
+enum {
+ NET_IPV6_ICMP_RATELIMIT=1
+};
+
+enum {
+ NET_NEIGH_MCAST_SOLICIT=1,
+ NET_NEIGH_UCAST_SOLICIT=2,
+ NET_NEIGH_APP_SOLICIT=3,
+ NET_NEIGH_RETRANS_TIME=4,
+ NET_NEIGH_REACHABLE_TIME=5,
+ NET_NEIGH_DELAY_PROBE_TIME=6,
+ NET_NEIGH_GC_STALE_TIME=7,
+ NET_NEIGH_UNRES_QLEN=8,
+ NET_NEIGH_PROXY_QLEN=9,
+ NET_NEIGH_ANYCAST_DELAY=10,
+ NET_NEIGH_PROXY_DELAY=11,
+ NET_NEIGH_LOCKTIME=12,
+ NET_NEIGH_GC_INTERVAL=13,
+ NET_NEIGH_GC_THRESH1=14,
+ NET_NEIGH_GC_THRESH2=15,
+ NET_NEIGH_GC_THRESH3=16,
+ NET_NEIGH_RETRANS_TIME_MS=17,
+ NET_NEIGH_REACHABLE_TIME_MS=18,
+ __NET_NEIGH_MAX
+};
+
+enum {
+ NET_DCCP_DEFAULT=1,
+};
+
+enum {
+ NET_DCCP_DEFAULT_SEQ_WINDOW = 1,
+ NET_DCCP_DEFAULT_RX_CCID = 2,
+ NET_DCCP_DEFAULT_TX_CCID = 3,
+ NET_DCCP_DEFAULT_ACK_RATIO = 4,
+ NET_DCCP_DEFAULT_SEND_ACKVEC = 5,
+ NET_DCCP_DEFAULT_SEND_NDP = 6,
+};
+
+enum {
+ NET_IPX_PPROP_BROADCASTING=1,
+ NET_IPX_FORWARDING=2
+};
+
+enum {
+ NET_LLC2=1,
+ NET_LLC_STATION=2,
+};
+
+enum {
+ NET_LLC2_TIMEOUT=1,
+};
+
+enum {
+ NET_LLC_STATION_ACK_TIMEOUT=1,
+};
+
+enum {
+ NET_LLC2_ACK_TIMEOUT=1,
+ NET_LLC2_P_TIMEOUT=2,
+ NET_LLC2_REJ_TIMEOUT=3,
+ NET_LLC2_BUSY_TIMEOUT=4,
+};
+
+enum {
+ NET_ATALK_AARP_EXPIRY_TIME=1,
+ NET_ATALK_AARP_TICK_TIME=2,
+ NET_ATALK_AARP_RETRANSMIT_LIMIT=3,
+ NET_ATALK_AARP_RESOLVE_TIME=4
+};
+
+enum {
+ NET_NETROM_DEFAULT_PATH_QUALITY=1,
+ NET_NETROM_OBSOLESCENCE_COUNT_INITIALISER=2,
+ NET_NETROM_NETWORK_TTL_INITIALISER=3,
+ NET_NETROM_TRANSPORT_TIMEOUT=4,
+ NET_NETROM_TRANSPORT_MAXIMUM_TRIES=5,
+ NET_NETROM_TRANSPORT_ACKNOWLEDGE_DELAY=6,
+ NET_NETROM_TRANSPORT_BUSY_DELAY=7,
+ NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE=8,
+ NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT=9,
+ NET_NETROM_ROUTING_CONTROL=10,
+ NET_NETROM_LINK_FAILS_COUNT=11,
+ NET_NETROM_RESET=12
+};
+
+enum {
+ NET_AX25_IP_DEFAULT_MODE=1,
+ NET_AX25_DEFAULT_MODE=2,
+ NET_AX25_BACKOFF_TYPE=3,
+ NET_AX25_CONNECT_MODE=4,
+ NET_AX25_STANDARD_WINDOW=5,
+ NET_AX25_EXTENDED_WINDOW=6,
+ NET_AX25_T1_TIMEOUT=7,
+ NET_AX25_T2_TIMEOUT=8,
+ NET_AX25_T3_TIMEOUT=9,
+ NET_AX25_IDLE_TIMEOUT=10,
+ NET_AX25_N2=11,
+ NET_AX25_PACLEN=12,
+ NET_AX25_PROTOCOL=13,
+ NET_AX25_DAMA_SLAVE_TIMEOUT=14
+};
+
+enum {
+ NET_ROSE_RESTART_REQUEST_TIMEOUT=1,
+ NET_ROSE_CALL_REQUEST_TIMEOUT=2,
+ NET_ROSE_RESET_REQUEST_TIMEOUT=3,
+ NET_ROSE_CLEAR_REQUEST_TIMEOUT=4,
+ NET_ROSE_ACK_HOLD_BACK_TIMEOUT=5,
+ NET_ROSE_ROUTING_CONTROL=6,
+ NET_ROSE_LINK_FAIL_TIMEOUT=7,
+ NET_ROSE_MAX_VCS=8,
+ NET_ROSE_WINDOW_SIZE=9,
+ NET_ROSE_NO_ACTIVITY_TIMEOUT=10
+};
+
+enum {
+ NET_X25_RESTART_REQUEST_TIMEOUT=1,
+ NET_X25_CALL_REQUEST_TIMEOUT=2,
+ NET_X25_RESET_REQUEST_TIMEOUT=3,
+ NET_X25_CLEAR_REQUEST_TIMEOUT=4,
+ NET_X25_ACK_HOLD_BACK_TIMEOUT=5
+};
+
+enum
+{
+ NET_TR_RIF_TIMEOUT=1
+};
+
+enum {
+ NET_DECNET_NODE_TYPE = 1,
+ NET_DECNET_NODE_ADDRESS = 2,
+ NET_DECNET_NODE_NAME = 3,
+ NET_DECNET_DEFAULT_DEVICE = 4,
+ NET_DECNET_TIME_WAIT = 5,
+ NET_DECNET_DN_COUNT = 6,
+ NET_DECNET_DI_COUNT = 7,
+ NET_DECNET_DR_COUNT = 8,
+ NET_DECNET_DST_GC_INTERVAL = 9,
+ NET_DECNET_CONF = 10,
+ NET_DECNET_NO_FC_MAX_CWND = 11,
+ NET_DECNET_MEM = 12,
+ NET_DECNET_RMEM = 13,
+ NET_DECNET_WMEM = 14,
+ NET_DECNET_DEBUG_LEVEL = 255
+};
+
+enum {
+ NET_DECNET_CONF_LOOPBACK = -2,
+ NET_DECNET_CONF_DDCMP = -3,
+ NET_DECNET_CONF_PPP = -4,
+ NET_DECNET_CONF_X25 = -5,
+ NET_DECNET_CONF_GRE = -6,
+ NET_DECNET_CONF_ETHER = -7
+
+};
+
+enum {
+ NET_DECNET_CONF_DEV_PRIORITY = 1,
+ NET_DECNET_CONF_DEV_T1 = 2,
+ NET_DECNET_CONF_DEV_T2 = 3,
+ NET_DECNET_CONF_DEV_T3 = 4,
+ NET_DECNET_CONF_DEV_FORWARDING = 5,
+ NET_DECNET_CONF_DEV_BLKSIZE = 6,
+ NET_DECNET_CONF_DEV_STATE = 7
+};
+
+enum {
+ NET_SCTP_RTO_INITIAL = 1,
+ NET_SCTP_RTO_MIN = 2,
+ NET_SCTP_RTO_MAX = 3,
+ NET_SCTP_RTO_ALPHA = 4,
+ NET_SCTP_RTO_BETA = 5,
+ NET_SCTP_VALID_COOKIE_LIFE = 6,
+ NET_SCTP_ASSOCIATION_MAX_RETRANS = 7,
+ NET_SCTP_PATH_MAX_RETRANS = 8,
+ NET_SCTP_MAX_INIT_RETRANSMITS = 9,
+ NET_SCTP_HB_INTERVAL = 10,
+ NET_SCTP_PRESERVE_ENABLE = 11,
+ NET_SCTP_MAX_BURST = 12,
+ NET_SCTP_ADDIP_ENABLE = 13,
+ NET_SCTP_PRSCTP_ENABLE = 14,
+ NET_SCTP_SNDBUF_POLICY = 15,
+ NET_SCTP_SACK_TIMEOUT = 16,
+ NET_SCTP_RCVBUF_POLICY = 17,
+};
+
+enum {
+ NET_BRIDGE_NF_CALL_ARPTABLES = 1,
+ NET_BRIDGE_NF_CALL_IPTABLES = 2,
+ NET_BRIDGE_NF_CALL_IP6TABLES = 3,
+ NET_BRIDGE_NF_FILTER_VLAN_TAGGED = 4,
+};
+
+enum
+{
+ FS_NRINODE=1,
+ FS_STATINODE=2,
+ FS_MAXINODE=3,
+ FS_NRDQUOT=4,
+ FS_MAXDQUOT=5,
+ FS_NRFILE=6,
+ FS_MAXFILE=7,
+ FS_DENTRY=8,
+ FS_NRSUPER=9,
+ FS_MAXSUPER=10,
+ FS_OVERFLOWUID=11,
+ FS_OVERFLOWGID=12,
+ FS_LEASES=13,
+ FS_DIR_NOTIFY=14,
+ FS_LEASE_TIME=15,
+ FS_DQSTATS=16,
+ FS_XFS=17,
+ FS_AIO_NR=18,
+ FS_AIO_MAX_NR=19,
+ FS_INOTIFY=20,
+};
+
+enum {
+ FS_DQ_LOOKUPS = 1,
+ FS_DQ_DROPS = 2,
+ FS_DQ_READS = 3,
+ FS_DQ_WRITES = 4,
+ FS_DQ_CACHE_HITS = 5,
+ FS_DQ_ALLOCATED = 6,
+ FS_DQ_FREE = 7,
+ FS_DQ_SYNCS = 8,
+ FS_DQ_WARNINGS = 9,
+};
+
+enum {
+ DEV_CDROM=1,
+ DEV_HWMON=2,
+ DEV_PARPORT=3,
+ DEV_RAID=4,
+ DEV_MAC_HID=5,
+ DEV_SCSI=6,
+ DEV_IPMI=7,
+};
+
+enum {
+ DEV_CDROM_INFO=1,
+ DEV_CDROM_AUTOCLOSE=2,
+ DEV_CDROM_AUTOEJECT=3,
+ DEV_CDROM_DEBUG=4,
+ DEV_CDROM_LOCK=5,
+ DEV_CDROM_CHECK_MEDIA=6
+};
+
+enum {
+ DEV_PARPORT_DEFAULT=-3
+};
+
+enum {
+ DEV_RAID_SPEED_LIMIT_MIN=1,
+ DEV_RAID_SPEED_LIMIT_MAX=2
+};
+
+enum {
+ DEV_PARPORT_DEFAULT_TIMESLICE=1,
+ DEV_PARPORT_DEFAULT_SPINTIME=2
+};
+
+enum {
+ DEV_PARPORT_SPINTIME=1,
+ DEV_PARPORT_BASE_ADDR=2,
+ DEV_PARPORT_IRQ=3,
+ DEV_PARPORT_DMA=4,
+ DEV_PARPORT_MODES=5,
+ DEV_PARPORT_DEVICES=6,
+ DEV_PARPORT_AUTOPROBE=16
+};
+
+enum {
+ DEV_PARPORT_DEVICES_ACTIVE=-3,
+};
+
+enum {
+ DEV_PARPORT_DEVICE_TIMESLICE=1,
+};
+
+enum {
+ DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES=1,
+ DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES=2,
+ DEV_MAC_HID_MOUSE_BUTTON_EMULATION=3,
+ DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE=4,
+ DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE=5,
+ DEV_MAC_HID_ADB_MOUSE_SENDS_KEYCODES=6
+};
+
+enum {
+ DEV_SCSI_LOGGING_LEVEL=1,
+};
+
+enum {
+ DEV_IPMI_POWEROFF_POWERCYCLE=1,
+};
+
+enum
+{
+ ABI_DEFHANDLER_COFF=1,
+ ABI_DEFHANDLER_ELF=2,
+ ABI_DEFHANDLER_LCALL7=3,
+ ABI_DEFHANDLER_LIBCSO=4,
+ ABI_TRACE=5,
+ ABI_FAKE_UTSNAME=6,
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sysdev.h b/ndk/build/platforms/android-1.5/common/include/linux/sysdev.h
new file mode 100644
index 0000000..6ae2b26
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sysdev.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _SYSDEV_H_
+#define _SYSDEV_H_
+
+#include <linux/kobject.h>
+#include <linux/pm.h>
+
+struct sys_device;
+
+struct sysdev_class {
+ struct list_head drivers;
+
+ int (*shutdown)(struct sys_device *);
+ int (*suspend)(struct sys_device *, pm_message_t state);
+ int (*resume)(struct sys_device *);
+ struct kset kset;
+};
+
+struct sysdev_class_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct sysdev_class *, char *);
+ ssize_t (*store)(struct sysdev_class *, const char *, size_t);
+};
+
+#define SYSDEV_CLASS_ATTR(_name,_mode,_show,_store)  struct sysdev_class_attribute attr_##_name = {   .attr = {.name = __stringify(_name), .mode = _mode },   .show = _show,   .store = _store,  };
+
+struct sysdev_driver {
+ struct list_head entry;
+ int (*add)(struct sys_device *);
+ int (*remove)(struct sys_device *);
+ int (*shutdown)(struct sys_device *);
+ int (*suspend)(struct sys_device *, pm_message_t state);
+ int (*resume)(struct sys_device *);
+};
+
+struct sys_device {
+ u32 id;
+ struct sysdev_class * cls;
+ struct kobject kobj;
+};
+
+struct sysdev_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct sys_device *, char *);
+ ssize_t (*store)(struct sys_device *, const char *, size_t);
+};
+
+#define SYSDEV_ATTR(_name,_mode,_show,_store)  struct sysdev_attribute attr_##_name = {   .attr = {.name = __stringify(_name), .mode = _mode },   .show = _show,   .store = _store,  };
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/sysfs.h b/ndk/build/platforms/android-1.5/common/include/linux/sysfs.h
new file mode 100644
index 0000000..00b5f5a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/sysfs.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _SYSFS_H_
+#define _SYSFS_H_
+
+#include <asm/atomic.h>
+
+struct kobject;
+struct module;
+
+struct attribute {
+ const char * name;
+ struct module * owner;
+ mode_t mode;
+};
+
+struct attribute_group {
+ const char * name;
+ struct attribute ** attrs;
+};
+
+#define __ATTR(_name,_mode,_show,_store) {   .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE },   .show = _show,   .store = _store,  }
+
+#define __ATTR_RO(_name) {   .attr = { .name = __stringify(_name), .mode = 0444, .owner = THIS_MODULE },   .show = _name##_show,  }
+
+#define __ATTR_NULL { .attr = { .name = NULL } }
+
+#define attr_name(_attr) (_attr).attr.name
+
+struct vm_area_struct;
+
+struct bin_attribute {
+ struct attribute attr;
+ size_t size;
+ void *private;
+ ssize_t (*read)(struct kobject *, char *, loff_t, size_t);
+ ssize_t (*write)(struct kobject *, char *, loff_t, size_t);
+ int (*mmap)(struct kobject *, struct bin_attribute *attr,
+ struct vm_area_struct *vma);
+};
+
+struct sysfs_ops {
+ ssize_t (*show)(struct kobject *, struct attribute *,char *);
+ ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
+};
+
+struct sysfs_dirent {
+ atomic_t s_count;
+ struct list_head s_sibling;
+ struct list_head s_children;
+ void * s_element;
+ int s_type;
+ umode_t s_mode;
+ struct dentry * s_dentry;
+ struct iattr * s_iattr;
+ atomic_t s_event;
+};
+
+#define SYSFS_ROOT 0x0001
+#define SYSFS_DIR 0x0002
+#define SYSFS_KOBJ_ATTR 0x0004
+#define SYSFS_KOBJ_BIN_ATTR 0x0008
+#define SYSFS_KOBJ_DEVICE 0x0010
+#define SYSFS_KOBJ_LINK 0x0020
+#define SYSFS_NOT_PINNED (SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR | SYSFS_KOBJ_DEVICE | SYSFS_KOBJ_LINK)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/taskstats.h b/ndk/build/platforms/android-1.5/common/include/linux/taskstats.h
new file mode 100644
index 0000000..3e8ae4a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/taskstats.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TASKSTATS_H
+#define _LINUX_TASKSTATS_H
+
+#define TASKSTATS_VERSION 1
+
+struct taskstats {
+
+ __u16 version;
+ __u16 padding[3];
+
+ __u64 cpu_count;
+ __u64 cpu_delay_total;
+
+ __u64 blkio_count;
+ __u64 blkio_delay_total;
+
+ __u64 swapin_count;
+ __u64 swapin_delay_total;
+
+ __u64 cpu_run_real_total;
+
+ __u64 cpu_run_virtual_total;
+
+};
+
+enum {
+ TASKSTATS_CMD_UNSPEC = 0,
+ TASKSTATS_CMD_GET,
+ TASKSTATS_CMD_NEW,
+ __TASKSTATS_CMD_MAX,
+};
+
+#define TASKSTATS_CMD_MAX (__TASKSTATS_CMD_MAX - 1)
+
+enum {
+ TASKSTATS_TYPE_UNSPEC = 0,
+ TASKSTATS_TYPE_PID,
+ TASKSTATS_TYPE_TGID,
+ TASKSTATS_TYPE_STATS,
+ TASKSTATS_TYPE_AGGR_PID,
+ TASKSTATS_TYPE_AGGR_TGID,
+ __TASKSTATS_TYPE_MAX,
+};
+
+#define TASKSTATS_TYPE_MAX (__TASKSTATS_TYPE_MAX - 1)
+
+enum {
+ TASKSTATS_CMD_ATTR_UNSPEC = 0,
+ TASKSTATS_CMD_ATTR_PID,
+ TASKSTATS_CMD_ATTR_TGID,
+ TASKSTATS_CMD_ATTR_REGISTER_CPUMASK,
+ TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK,
+ __TASKSTATS_CMD_ATTR_MAX,
+};
+
+#define TASKSTATS_CMD_ATTR_MAX (__TASKSTATS_CMD_ATTR_MAX - 1)
+
+#define TASKSTATS_GENL_NAME "TASKSTATS"
+#define TASKSTATS_GENL_VERSION 0x1
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/taskstats_kern.h b/ndk/build/platforms/android-1.5/common/include/linux/taskstats_kern.h
new file mode 100644
index 0000000..4948410
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/taskstats_kern.h
@@ -0,0 +1,19 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TASKSTATS_KERN_H
+#define _LINUX_TASKSTATS_KERN_H
+
+#include <linux/taskstats.h>
+#include <linux/sched.h>
+#include <net/genetlink.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/tcp.h b/ndk/build/platforms/android-1.5/common/include/linux/tcp.h
new file mode 100644
index 0000000..3fa95f8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/tcp.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TCP_H
+#define _LINUX_TCP_H
+
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+struct tcphdr {
+ __u16 source;
+ __u16 dest;
+ __u32 seq;
+ __u32 ack_seq;
+#ifdef __LITTLE_ENDIAN_BITFIELD
+ __u16 res1:4,
+ doff:4,
+ fin:1,
+ syn:1,
+ rst:1,
+ psh:1,
+ ack:1,
+ urg:1,
+ ece:1,
+ cwr:1;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ __u16 doff:4,
+ res1:4,
+ cwr:1,
+ ece:1,
+ urg:1,
+ ack:1,
+ psh:1,
+ rst:1,
+ syn:1,
+ fin:1;
+#else
+#error "Adjust your <asm/byteorder.h> defines"
+#endif
+ __u16 window;
+ __u16 check;
+ __u16 urg_ptr;
+};
+
+union tcp_word_hdr {
+ struct tcphdr hdr;
+ __u32 words[5];
+};
+
+#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3]) 
+
+enum {
+ TCP_FLAG_CWR = __constant_htonl(0x00800000),
+ TCP_FLAG_ECE = __constant_htonl(0x00400000),
+ TCP_FLAG_URG = __constant_htonl(0x00200000),
+ TCP_FLAG_ACK = __constant_htonl(0x00100000),
+ TCP_FLAG_PSH = __constant_htonl(0x00080000),
+ TCP_FLAG_RST = __constant_htonl(0x00040000),
+ TCP_FLAG_SYN = __constant_htonl(0x00020000),
+ TCP_FLAG_FIN = __constant_htonl(0x00010000),
+ TCP_RESERVED_BITS = __constant_htonl(0x0F000000),
+ TCP_DATA_OFFSET = __constant_htonl(0xF0000000)
+};
+
+#define TCP_NODELAY 1  
+#define TCP_MAXSEG 2  
+#define TCP_CORK 3  
+#define TCP_KEEPIDLE 4  
+#define TCP_KEEPINTVL 5  
+#define TCP_KEEPCNT 6  
+#define TCP_SYNCNT 7  
+#define TCP_LINGER2 8  
+#define TCP_DEFER_ACCEPT 9  
+#define TCP_WINDOW_CLAMP 10  
+#define TCP_INFO 11  
+#define TCP_QUICKACK 12  
+#define TCP_CONGESTION 13  
+
+#define TCPI_OPT_TIMESTAMPS 1
+#define TCPI_OPT_SACK 2
+#define TCPI_OPT_WSCALE 4
+#define TCPI_OPT_ECN 8
+
+enum tcp_ca_state
+{
+ TCP_CA_Open = 0,
+#define TCPF_CA_Open (1<<TCP_CA_Open)
+ TCP_CA_Disorder = 1,
+#define TCPF_CA_Disorder (1<<TCP_CA_Disorder)
+ TCP_CA_CWR = 2,
+#define TCPF_CA_CWR (1<<TCP_CA_CWR)
+ TCP_CA_Recovery = 3,
+#define TCPF_CA_Recovery (1<<TCP_CA_Recovery)
+ TCP_CA_Loss = 4
+#define TCPF_CA_Loss (1<<TCP_CA_Loss)
+};
+
+struct tcp_info
+{
+ __u8 tcpi_state;
+ __u8 tcpi_ca_state;
+ __u8 tcpi_retransmits;
+ __u8 tcpi_probes;
+ __u8 tcpi_backoff;
+ __u8 tcpi_options;
+ __u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
+
+ __u32 tcpi_rto;
+ __u32 tcpi_ato;
+ __u32 tcpi_snd_mss;
+ __u32 tcpi_rcv_mss;
+
+ __u32 tcpi_unacked;
+ __u32 tcpi_sacked;
+ __u32 tcpi_lost;
+ __u32 tcpi_retrans;
+ __u32 tcpi_fackets;
+
+ __u32 tcpi_last_data_sent;
+ __u32 tcpi_last_ack_sent;
+ __u32 tcpi_last_data_recv;
+ __u32 tcpi_last_ack_recv;
+
+ __u32 tcpi_pmtu;
+ __u32 tcpi_rcv_ssthresh;
+ __u32 tcpi_rtt;
+ __u32 tcpi_rttvar;
+ __u32 tcpi_snd_ssthresh;
+ __u32 tcpi_snd_cwnd;
+ __u32 tcpi_advmss;
+ __u32 tcpi_reordering;
+
+ __u32 tcpi_rcv_rtt;
+ __u32 tcpi_rcv_space;
+
+ __u32 tcpi_total_retrans;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/telephony.h b/ndk/build/platforms/android-1.5/common/include/linux/telephony.h
new file mode 100644
index 0000000..0c1d83d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/telephony.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef TELEPHONY_H
+#define TELEPHONY_H
+
+#define TELEPHONY_VERSION 3013
+
+#define PHONE_VENDOR_IXJ 1
+#define PHONE_VENDOR_QUICKNET PHONE_VENDOR_IXJ
+#define PHONE_VENDOR_VOICETRONIX 2
+#define PHONE_VENDOR_ACULAB 3
+#define PHONE_VENDOR_DIGI 4
+#define PHONE_VENDOR_FRANKLIN 5
+
+#define QTI_PHONEJACK 100
+#define QTI_LINEJACK 300
+#define QTI_PHONEJACK_LITE 400
+#define QTI_PHONEJACK_PCI 500
+#define QTI_PHONECARD 600
+
+typedef enum {
+ vendor = 0,
+ device,
+ port,
+ codec,
+ dsp
+} phone_cap;
+
+struct phone_capability {
+ char desc[80];
+ phone_cap captype;
+ int cap;
+ int handle;
+};
+
+typedef enum {
+ pots = 0,
+ pstn,
+ handset,
+ speaker
+} phone_ports;
+
+#define PHONE_CAPABILITIES _IO ('q', 0x80)
+#define PHONE_CAPABILITIES_LIST _IOR ('q', 0x81, struct phone_capability *)
+#define PHONE_CAPABILITIES_CHECK _IOW ('q', 0x82, struct phone_capability *)
+
+typedef struct {
+ char month[3];
+ char day[3];
+ char hour[3];
+ char min[3];
+ int numlen;
+ char number[11];
+ int namelen;
+ char name[80];
+} PHONE_CID;
+
+#define PHONE_RING _IO ('q', 0x83)
+#define PHONE_HOOKSTATE _IO ('q', 0x84)
+#define PHONE_MAXRINGS _IOW ('q', 0x85, char)
+#define PHONE_RING_CADENCE _IOW ('q', 0x86, short)
+#define OLD_PHONE_RING_START _IO ('q', 0x87)
+#define PHONE_RING_START _IOW ('q', 0x87, PHONE_CID *)
+#define PHONE_RING_STOP _IO ('q', 0x88)
+
+#define USA_RING_CADENCE 0xC0C0
+
+#define PHONE_REC_CODEC _IOW ('q', 0x89, int)
+#define PHONE_REC_START _IO ('q', 0x8A)
+#define PHONE_REC_STOP _IO ('q', 0x8B)
+#define PHONE_REC_DEPTH _IOW ('q', 0x8C, int)
+#define PHONE_FRAME _IOW ('q', 0x8D, int)
+#define PHONE_REC_VOLUME _IOW ('q', 0x8E, int)
+#define PHONE_REC_VOLUME_LINEAR _IOW ('q', 0xDB, int)
+#define PHONE_REC_LEVEL _IO ('q', 0x8F)
+
+#define PHONE_PLAY_CODEC _IOW ('q', 0x90, int)
+#define PHONE_PLAY_START _IO ('q', 0x91)
+#define PHONE_PLAY_STOP _IO ('q', 0x92)
+#define PHONE_PLAY_DEPTH _IOW ('q', 0x93, int)
+#define PHONE_PLAY_VOLUME _IOW ('q', 0x94, int)
+#define PHONE_PLAY_VOLUME_LINEAR _IOW ('q', 0xDC, int)
+#define PHONE_PLAY_LEVEL _IO ('q', 0x95)
+#define PHONE_DTMF_READY _IOR ('q', 0x96, int)
+#define PHONE_GET_DTMF _IOR ('q', 0x97, int)
+#define PHONE_GET_DTMF_ASCII _IOR ('q', 0x98, int)
+#define PHONE_DTMF_OOB _IOW ('q', 0x99, int)
+#define PHONE_EXCEPTION _IOR ('q', 0x9A, int)
+#define PHONE_PLAY_TONE _IOW ('q', 0x9B, char)
+#define PHONE_SET_TONE_ON_TIME _IOW ('q', 0x9C, int)
+#define PHONE_SET_TONE_OFF_TIME _IOW ('q', 0x9D, int)
+#define PHONE_GET_TONE_ON_TIME _IO ('q', 0x9E)
+#define PHONE_GET_TONE_OFF_TIME _IO ('q', 0x9F)
+#define PHONE_GET_TONE_STATE _IO ('q', 0xA0)
+#define PHONE_BUSY _IO ('q', 0xA1)
+#define PHONE_RINGBACK _IO ('q', 0xA2)
+#define PHONE_DIALTONE _IO ('q', 0xA3)
+#define PHONE_CPT_STOP _IO ('q', 0xA4)
+
+#define PHONE_PSTN_SET_STATE _IOW ('q', 0xA4, int)
+#define PHONE_PSTN_GET_STATE _IO ('q', 0xA5)
+
+#define PSTN_ON_HOOK 0
+#define PSTN_RINGING 1
+#define PSTN_OFF_HOOK 2
+#define PSTN_PULSE_DIAL 3
+
+#define PHONE_WINK_DURATION _IOW ('q', 0xA6, int)
+#define PHONE_WINK _IOW ('q', 0xAA, int)
+
+typedef enum {
+ G723_63 = 1,
+ G723_53 = 2,
+ TS85 = 3,
+ TS48 = 4,
+ TS41 = 5,
+ G728 = 6,
+ G729 = 7,
+ ULAW = 8,
+ ALAW = 9,
+ LINEAR16 = 10,
+ LINEAR8 = 11,
+ WSS = 12,
+ G729B = 13
+} phone_codec;
+
+struct phone_codec_data
+{
+ phone_codec type;
+ unsigned short buf_min, buf_opt, buf_max;
+};
+
+#define PHONE_QUERY_CODEC _IOWR ('q', 0xA7, struct phone_codec_data *)
+#define PHONE_PSTN_LINETEST _IO ('q', 0xA8)
+
+#define PHONE_VAD _IOW ('q', 0xA9, int)
+
+struct phone_except
+{
+ unsigned int dtmf_ready:1;
+ unsigned int hookstate:1;
+ unsigned int pstn_ring:1;
+ unsigned int caller_id:1;
+ unsigned int pstn_wink:1;
+ unsigned int f0:1;
+ unsigned int f1:1;
+ unsigned int f2:1;
+ unsigned int f3:1;
+ unsigned int flash:1;
+ unsigned int fc0:1;
+ unsigned int fc1:1;
+ unsigned int fc2:1;
+ unsigned int fc3:1;
+ unsigned int reserved:18;
+};
+
+union telephony_exception {
+ struct phone_except bits;
+ unsigned int bytes;
+};
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/termios.h b/ndk/build/platforms/android-1.5/common/include/linux/termios.h
new file mode 100644
index 0000000..e28439d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/termios.h
@@ -0,0 +1,18 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TERMIOS_H
+#define _LINUX_TERMIOS_H
+
+#include <linux/types.h>
+#include <asm/termios.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/textsearch.h b/ndk/build/platforms/android-1.5/common/include/linux/textsearch.h
new file mode 100644
index 0000000..a921cdd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/textsearch.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_TEXTSEARCH_H
+#define __LINUX_TEXTSEARCH_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/thread_info.h b/ndk/build/platforms/android-1.5/common/include/linux/thread_info.h
new file mode 100644
index 0000000..074a1f9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/thread_info.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_THREAD_INFO_H
+#define _LINUX_THREAD_INFO_H
+
+struct restart_block {
+ long (*fn)(struct restart_block *);
+ unsigned long arg0, arg1, arg2, arg3;
+};
+
+#include <linux/bitops.h>
+#include <asm/thread_info.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/threads.h b/ndk/build/platforms/android-1.5/common/include/linux/threads.h
new file mode 100644
index 0000000..5d85878
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/threads.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_THREADS_H
+#define _LINUX_THREADS_H
+
+#define NR_CPUS 1
+
+#define MIN_THREADS_LEFT_FOR_ROOT 4
+
+#define PID_MAX_DEFAULT (CONFIG_BASE_SMALL ? 0x1000 : 0x8000)
+
+#define PID_MAX_LIMIT (CONFIG_BASE_SMALL ? PAGE_SIZE * 8 :   (sizeof(long) > 4 ? 4 * 1024 * 1024 : PID_MAX_DEFAULT))
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/time.h b/ndk/build/platforms/android-1.5/common/include/linux/time.h
new file mode 100644
index 0000000..3e6e440
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/time.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TIME_H
+#define _LINUX_TIME_H
+
+#include <linux/types.h>
+
+#ifndef _STRUCT_TIMESPEC
+#define _STRUCT_TIMESPEC
+struct timespec {
+ time_t tv_sec;
+ long tv_nsec;
+};
+#endif
+
+struct timeval {
+ time_t tv_sec;
+ suseconds_t tv_usec;
+};
+
+struct timezone {
+ int tz_minuteswest;
+ int tz_dsttime;
+};
+
+#define NFDBITS __NFDBITS
+
+#define FD_SETSIZE __FD_SETSIZE
+#define FD_SET(fd,fdsetp) __FD_SET(fd,fdsetp)
+#define FD_CLR(fd,fdsetp) __FD_CLR(fd,fdsetp)
+#define FD_ISSET(fd,fdsetp) __FD_ISSET(fd,fdsetp)
+#define FD_ZERO(fdsetp) __FD_ZERO(fdsetp)
+
+#define ITIMER_REAL 0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF 2
+
+struct itimerspec {
+ struct timespec it_interval;
+ struct timespec it_value;
+};
+
+struct itimerval {
+ struct timeval it_interval;
+ struct timeval it_value;
+};
+
+#define CLOCK_REALTIME 0
+#define CLOCK_MONOTONIC 1
+#define CLOCK_PROCESS_CPUTIME_ID 2
+#define CLOCK_THREAD_CPUTIME_ID 3
+
+#define CLOCK_SGI_CYCLE 10
+#define MAX_CLOCKS 16
+#define CLOCKS_MASK (CLOCK_REALTIME | CLOCK_MONOTONIC)
+#define CLOCKS_MONO CLOCK_MONOTONIC
+
+#define TIMER_ABSTIME 0x01
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/timer.h b/ndk/build/platforms/android-1.5/common/include/linux/timer.h
new file mode 100644
index 0000000..071a759
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/timer.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TIMER_H
+#define _LINUX_TIMER_H
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/stddef.h>
+
+struct tvec_t_base_s;
+
+struct timer_list {
+ struct list_head entry;
+ unsigned long expires;
+
+ void (*function)(unsigned long);
+ unsigned long data;
+
+ struct tvec_t_base_s *base;
+};
+
+#define TIMER_INITIALIZER(_function, _expires, _data) {   .function = (_function),   .expires = (_expires),   .data = (_data),   .base = &boot_tvec_bases,   }
+
+#define DEFINE_TIMER(_name, _function, _expires, _data)   struct timer_list _name =   TIMER_INITIALIZER(_function, _expires, _data)
+
+#define try_to_del_timer_sync(t) del_timer(t)
+#define del_timer_sync(t) del_timer(t)
+#define del_singleshot_timer_sync(t) del_timer_sync(t)
+
+struct hrtimer;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/times.h b/ndk/build/platforms/android-1.5/common/include/linux/times.h
new file mode 100644
index 0000000..4ae415c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/times.h
@@ -0,0 +1,24 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TIMES_H
+#define _LINUX_TIMES_H
+
+#include <linux/types.h>
+
+struct tms {
+ clock_t tms_utime;
+ clock_t tms_stime;
+ clock_t tms_cutime;
+ clock_t tms_cstime;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/timex.h b/ndk/build/platforms/android-1.5/common/include/linux/timex.h
new file mode 100644
index 0000000..342470b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/timex.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TIMEX_H
+#define _LINUX_TIMEX_H
+
+#include <linux/compiler.h>
+#include <linux/time.h>
+
+#include <asm/param.h>
+
+#define SHIFT_KG 6  
+#define SHIFT_KF 16  
+#define SHIFT_KH 2  
+#define MAXTC 6  
+
+#define SHIFT_SCALE 22  
+#define SHIFT_UPDATE (SHIFT_KG + MAXTC)  
+#define SHIFT_USEC 16  
+#define FINENSEC (1L << (SHIFT_SCALE - 10))  
+
+#define MAXPHASE 512000L  
+#define MAXFREQ (512L << SHIFT_USEC)  
+#define MINSEC 16L  
+#define MAXSEC 1200L  
+#define NTP_PHASE_LIMIT (MAXPHASE << 5)  
+
+struct timex {
+ unsigned int modes;
+ long offset;
+ long freq;
+ long maxerror;
+ long esterror;
+ int status;
+ long constant;
+ long precision;
+ long tolerance;
+ struct timeval time;
+ long tick;
+
+ long ppsfreq;
+ long jitter;
+ int shift;
+ long stabil;
+ long jitcnt;
+ long calcnt;
+ long errcnt;
+ long stbcnt;
+
+ int :32; int :32; int :32; int :32;
+ int :32; int :32; int :32; int :32;
+ int :32; int :32; int :32; int :32;
+};
+
+#define ADJ_OFFSET 0x0001  
+#define ADJ_FREQUENCY 0x0002  
+#define ADJ_MAXERROR 0x0004  
+#define ADJ_ESTERROR 0x0008  
+#define ADJ_STATUS 0x0010  
+#define ADJ_TIMECONST 0x0020  
+#define ADJ_TICK 0x4000  
+#define ADJ_OFFSET_SINGLESHOT 0x8001  
+
+#define MOD_OFFSET ADJ_OFFSET
+#define MOD_FREQUENCY ADJ_FREQUENCY
+#define MOD_MAXERROR ADJ_MAXERROR
+#define MOD_ESTERROR ADJ_ESTERROR
+#define MOD_STATUS ADJ_STATUS
+#define MOD_TIMECONST ADJ_TIMECONST
+#define MOD_CLKB ADJ_TICK
+#define MOD_CLKA ADJ_OFFSET_SINGLESHOT  
+
+#define STA_PLL 0x0001  
+#define STA_PPSFREQ 0x0002  
+#define STA_PPSTIME 0x0004  
+#define STA_FLL 0x0008  
+
+#define STA_INS 0x0010  
+#define STA_DEL 0x0020  
+#define STA_UNSYNC 0x0040  
+#define STA_FREQHOLD 0x0080  
+
+#define STA_PPSSIGNAL 0x0100  
+#define STA_PPSJITTER 0x0200  
+#define STA_PPSWANDER 0x0400  
+#define STA_PPSERROR 0x0800  
+
+#define STA_CLOCKERR 0x1000  
+
+#define STA_RONLY (STA_PPSSIGNAL | STA_PPSJITTER | STA_PPSWANDER |   STA_PPSERROR | STA_CLOCKERR)  
+
+#define TIME_OK 0  
+#define TIME_INS 1  
+#define TIME_DEL 2  
+#define TIME_OOP 3  
+#define TIME_WAIT 4  
+#define TIME_ERROR 5  
+#define TIME_BAD TIME_ERROR  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/tiocl.h b/ndk/build/platforms/android-1.5/common/include/linux/tiocl.h
new file mode 100644
index 0000000..db15a8d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/tiocl.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TIOCL_H
+#define _LINUX_TIOCL_H
+
+#define TIOCL_SETSEL 2  
+#define TIOCL_SELCHAR 0  
+#define TIOCL_SELWORD 1  
+#define TIOCL_SELLINE 2  
+#define TIOCL_SELPOINTER 3  
+#define TIOCL_SELCLEAR 4  
+#define TIOCL_SELMOUSEREPORT 16  
+#define TIOCL_SELBUTTONMASK 15  
+
+struct tiocl_selection {
+ unsigned short xs;
+ unsigned short ys;
+ unsigned short xe;
+ unsigned short ye;
+ unsigned short sel_mode;
+};
+
+#define TIOCL_PASTESEL 3  
+#define TIOCL_UNBLANKSCREEN 4  
+
+#define TIOCL_SELLOADLUT 5
+
+#define TIOCL_GETSHIFTSTATE 6  
+#define TIOCL_GETMOUSEREPORTING 7  
+#define TIOCL_SETVESABLANK 10  
+#define TIOCL_SETKMSGREDIRECT 11  
+#define TIOCL_GETFGCONSOLE 12  
+#define TIOCL_SCROLLCONSOLE 13  
+#define TIOCL_BLANKSCREEN 14  
+#define TIOCL_BLANKEDSCREEN 15  
+#define TIOCL_GETKMSGREDIRECT 17  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/transport_class.h b/ndk/build/platforms/android-1.5/common/include/linux/transport_class.h
new file mode 100644
index 0000000..71ad084
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/transport_class.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _TRANSPORT_CLASS_H_
+#define _TRANSPORT_CLASS_H_
+
+#include <linux/device.h>
+#include <linux/attribute_container.h>
+
+struct transport_container;
+
+struct transport_class {
+ struct class class;
+ int (*setup)(struct transport_container *, struct device *,
+ struct class_device *);
+ int (*configure)(struct transport_container *, struct device *,
+ struct class_device *);
+ int (*remove)(struct transport_container *, struct device *,
+ struct class_device *);
+};
+
+#define DECLARE_TRANSPORT_CLASS(cls, nm, su, rm, cfg)  struct transport_class cls = {   .class = {   .name = nm,   },   .setup = su,   .remove = rm,   .configure = cfg,  }
+
+struct anon_transport_class {
+ struct transport_class tclass;
+ struct attribute_container container;
+};
+
+#define DECLARE_ANON_TRANSPORT_CLASS(cls, mtch, cfg)  struct anon_transport_class cls = {   .tclass = {   .configure = cfg,   },   . container = {   .match = mtch,   },  }
+
+#define class_to_transport_class(x)   container_of(x, struct transport_class, class)
+
+struct transport_container {
+ struct attribute_container ac;
+ struct attribute_group *statistics;
+};
+
+#define attribute_container_to_transport_container(x)   container_of(x, struct transport_container, ac)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/tty.h b/ndk/build/platforms/android-1.5/common/include/linux/tty.h
new file mode 100644
index 0000000..b28791c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/tty.h
@@ -0,0 +1,15 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TTY_H
+#define _LINUX_TTY_H
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/types.h b/ndk/build/platforms/android-1.5/common/include/linux/types.h
new file mode 100644
index 0000000..b118db0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/types.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_TYPES_H
+#define _LINUX_TYPES_H
+
+#include <linux/posix_types.h>
+#include <asm/types.h>
+
+#define __bitwise__
+#define __bitwise
+
+typedef __u16 __bitwise __le16;
+typedef __u16 __bitwise __be16;
+typedef __u32 __bitwise __le32;
+typedef __u32 __bitwise __be32;
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __u64 __bitwise __le64;
+typedef __u64 __bitwise __be64;
+#endif
+
+struct ustat {
+ __kernel_daddr_t f_tfree;
+ __kernel_ino_t f_tinode;
+ char f_fname[6];
+ char f_fpack[6];
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/udp.h b/ndk/build/platforms/android-1.5/common/include/linux/udp.h
new file mode 100644
index 0000000..e4bf864
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/udp.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_UDP_H
+#define _LINUX_UDP_H
+
+#include <linux/types.h>
+
+struct udphdr {
+ __u16 source;
+ __u16 dest;
+ __u16 len;
+ __u16 check;
+};
+
+#define UDP_CORK 1  
+#define UDP_ENCAP 100  
+
+#define UDP_ENCAP_ESPINUDP_NON_IKE 1  
+#define UDP_ENCAP_ESPINUDP 2  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ufs_fs_i.h b/ndk/build/platforms/android-1.5/common/include/linux/ufs_fs_i.h
new file mode 100644
index 0000000..d71adb6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ufs_fs_i.h
@@ -0,0 +1,33 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_UFS_FS_I_H
+#define _LINUX_UFS_FS_I_H
+
+struct ufs_inode_info {
+ union {
+ __fs32 i_data[15];
+ __u8 i_symlink[4*15];
+ __fs64 u2_i_data[15];
+ } i_u1;
+ __u32 i_flags;
+ __u32 i_gen;
+ __u32 i_shadow;
+ __u32 i_unused1;
+ __u32 i_unused2;
+ __u32 i_oeftflag;
+ __u16 i_osync;
+ __u32 i_lastfrag;
+ __u32 i_dir_start_lookup;
+ struct inode vfs_inode;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/ufs_fs_sb.h b/ndk/build/platforms/android-1.5/common/include/linux/ufs_fs_sb.h
new file mode 100644
index 0000000..9c7226d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/ufs_fs_sb.h
@@ -0,0 +1,35 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_UFS_FS_SB_H
+#define __LINUX_UFS_FS_SB_H
+
+#define UFS_MAX_GROUP_LOADED 8
+#define UFS_CGNO_EMPTY ((unsigned)-1)
+
+struct ufs_sb_private_info;
+struct ufs_cg_private_info;
+struct ufs_csum;
+#define UFS_MAXCSBUFS 31
+
+struct ufs_sb_info {
+ struct ufs_sb_private_info * s_uspi;
+ struct ufs_csum * s_csp;
+ unsigned s_bytesex;
+ unsigned s_flags;
+ struct buffer_head ** s_ucg;
+ struct ufs_cg_private_info * s_ucpi[UFS_MAX_GROUP_LOADED];
+ unsigned s_cgno[UFS_MAX_GROUP_LOADED];
+ unsigned short s_cg_loaded;
+ unsigned s_mount_opt;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/uio.h b/ndk/build/platforms/android-1.5/common/include/linux/uio.h
new file mode 100644
index 0000000..b0895af
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/uio.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_UIO_H
+#define __LINUX_UIO_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+struct iovec
+{
+ void __user *iov_base;
+ __kernel_size_t iov_len;
+};
+
+#define UIO_FASTIOV 8
+#define UIO_MAXIOV 1024
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/un.h b/ndk/build/platforms/android-1.5/common/include/linux/un.h
new file mode 100644
index 0000000..5b51b7c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/un.h
@@ -0,0 +1,22 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_UN_H
+#define _LINUX_UN_H
+
+#define UNIX_PATH_MAX 108
+
+struct sockaddr_un {
+ sa_family_t sun_family;
+ char sun_path[UNIX_PATH_MAX];
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/unistd.h b/ndk/build/platforms/android-1.5/common/include/linux/unistd.h
new file mode 100644
index 0000000..6a3ec4c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/unistd.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_UNISTD_H_
+#define _LINUX_UNISTD_H_
+
+#include <asm/unistd.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/usb.h b/ndk/build/platforms/android-1.5/common/include/linux/usb.h
new file mode 100644
index 0000000..ceee194
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/usb.h
@@ -0,0 +1,21 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_USB_H
+#define __LINUX_USB_H
+
+#include <linux/mod_devicetable.h>
+#include <linux/usb_ch9.h>
+
+#define USB_MAJOR 180
+#define USB_DEVICE_MAJOR 189
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/usb_ch9.h b/ndk/build/platforms/android-1.5/common/include/linux/usb_ch9.h
new file mode 100644
index 0000000..74e31e7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/usb_ch9.h
@@ -0,0 +1,388 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_USB_CH9_H
+#define __LINUX_USB_CH9_H
+
+#include <linux/types.h>  
+
+#define USB_DIR_OUT 0  
+#define USB_DIR_IN 0x80  
+
+#define USB_TYPE_MASK (0x03 << 5)
+#define USB_TYPE_STANDARD (0x00 << 5)
+#define USB_TYPE_CLASS (0x01 << 5)
+#define USB_TYPE_VENDOR (0x02 << 5)
+#define USB_TYPE_RESERVED (0x03 << 5)
+
+#define USB_RECIP_MASK 0x1f
+#define USB_RECIP_DEVICE 0x00
+#define USB_RECIP_INTERFACE 0x01
+#define USB_RECIP_ENDPOINT 0x02
+#define USB_RECIP_OTHER 0x03
+
+#define USB_RECIP_PORT 0x04
+#define USB_RECIP_RPIPE 0x05
+
+#define USB_REQ_GET_STATUS 0x00
+#define USB_REQ_CLEAR_FEATURE 0x01
+#define USB_REQ_SET_FEATURE 0x03
+#define USB_REQ_SET_ADDRESS 0x05
+#define USB_REQ_GET_DESCRIPTOR 0x06
+#define USB_REQ_SET_DESCRIPTOR 0x07
+#define USB_REQ_GET_CONFIGURATION 0x08
+#define USB_REQ_SET_CONFIGURATION 0x09
+#define USB_REQ_GET_INTERFACE 0x0A
+#define USB_REQ_SET_INTERFACE 0x0B
+#define USB_REQ_SYNCH_FRAME 0x0C
+
+#define USB_REQ_SET_ENCRYPTION 0x0D  
+#define USB_REQ_GET_ENCRYPTION 0x0E
+#define USB_REQ_RPIPE_ABORT 0x0E
+#define USB_REQ_SET_HANDSHAKE 0x0F
+#define USB_REQ_RPIPE_RESET 0x0F
+#define USB_REQ_GET_HANDSHAKE 0x10
+#define USB_REQ_SET_CONNECTION 0x11
+#define USB_REQ_SET_SECURITY_DATA 0x12
+#define USB_REQ_GET_SECURITY_DATA 0x13
+#define USB_REQ_SET_WUSB_DATA 0x14
+#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
+#define USB_REQ_LOOPBACK_DATA_READ 0x16
+#define USB_REQ_SET_INTERFACE_DS 0x17
+
+#define USB_DEVICE_SELF_POWERED 0  
+#define USB_DEVICE_REMOTE_WAKEUP 1  
+#define USB_DEVICE_TEST_MODE 2  
+#define USB_DEVICE_BATTERY 2  
+#define USB_DEVICE_B_HNP_ENABLE 3  
+#define USB_DEVICE_WUSB_DEVICE 3  
+#define USB_DEVICE_A_HNP_SUPPORT 4  
+#define USB_DEVICE_A_ALT_HNP_SUPPORT 5  
+#define USB_DEVICE_DEBUG_MODE 6  
+
+#define USB_ENDPOINT_HALT 0  
+
+struct usb_ctrlrequest {
+ __u8 bRequestType;
+ __u8 bRequest;
+ __le16 wValue;
+ __le16 wIndex;
+ __le16 wLength;
+} __attribute__ ((packed));
+
+#define USB_DT_DEVICE 0x01
+#define USB_DT_CONFIG 0x02
+#define USB_DT_STRING 0x03
+#define USB_DT_INTERFACE 0x04
+#define USB_DT_ENDPOINT 0x05
+#define USB_DT_DEVICE_QUALIFIER 0x06
+#define USB_DT_OTHER_SPEED_CONFIG 0x07
+#define USB_DT_INTERFACE_POWER 0x08
+
+#define USB_DT_OTG 0x09
+#define USB_DT_DEBUG 0x0a
+#define USB_DT_INTERFACE_ASSOCIATION 0x0b
+
+#define USB_DT_SECURITY 0x0c
+#define USB_DT_KEY 0x0d
+#define USB_DT_ENCRYPTION_TYPE 0x0e
+#define USB_DT_BOS 0x0f
+#define USB_DT_DEVICE_CAPABILITY 0x10
+#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11
+#define USB_DT_WIRE_ADAPTER 0x21
+#define USB_DT_RPIPE 0x22
+
+#define USB_DT_CS_DEVICE 0x21
+#define USB_DT_CS_CONFIG 0x22
+#define USB_DT_CS_STRING 0x23
+#define USB_DT_CS_INTERFACE 0x24
+#define USB_DT_CS_ENDPOINT 0x25
+
+struct usb_descriptor_header {
+ __u8 bLength;
+ __u8 bDescriptorType;
+} __attribute__ ((packed));
+
+struct usb_device_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ __le16 bcdUSB;
+ __u8 bDeviceClass;
+ __u8 bDeviceSubClass;
+ __u8 bDeviceProtocol;
+ __u8 bMaxPacketSize0;
+ __le16 idVendor;
+ __le16 idProduct;
+ __le16 bcdDevice;
+ __u8 iManufacturer;
+ __u8 iProduct;
+ __u8 iSerialNumber;
+ __u8 bNumConfigurations;
+} __attribute__ ((packed));
+
+#define USB_DT_DEVICE_SIZE 18
+
+#define USB_CLASS_PER_INTERFACE 0  
+#define USB_CLASS_AUDIO 1
+#define USB_CLASS_COMM 2
+#define USB_CLASS_HID 3
+#define USB_CLASS_PHYSICAL 5
+#define USB_CLASS_STILL_IMAGE 6
+#define USB_CLASS_PRINTER 7
+#define USB_CLASS_MASS_STORAGE 8
+#define USB_CLASS_HUB 9
+#define USB_CLASS_CDC_DATA 0x0a
+#define USB_CLASS_CSCID 0x0b  
+#define USB_CLASS_CONTENT_SEC 0x0d  
+#define USB_CLASS_VIDEO 0x0e
+#define USB_CLASS_WIRELESS_CONTROLLER 0xe0
+#define USB_CLASS_APP_SPEC 0xfe
+#define USB_CLASS_VENDOR_SPEC 0xff
+
+struct usb_config_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ __le16 wTotalLength;
+ __u8 bNumInterfaces;
+ __u8 bConfigurationValue;
+ __u8 iConfiguration;
+ __u8 bmAttributes;
+ __u8 bMaxPower;
+} __attribute__ ((packed));
+
+#define USB_DT_CONFIG_SIZE 9
+
+#define USB_CONFIG_ATT_ONE (1 << 7)  
+#define USB_CONFIG_ATT_SELFPOWER (1 << 6)  
+#define USB_CONFIG_ATT_WAKEUP (1 << 5)  
+#define USB_CONFIG_ATT_BATTERY (1 << 4)  
+
+struct usb_string_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ __le16 wData[1];
+} __attribute__ ((packed));
+
+struct usb_interface_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ __u8 bInterfaceNumber;
+ __u8 bAlternateSetting;
+ __u8 bNumEndpoints;
+ __u8 bInterfaceClass;
+ __u8 bInterfaceSubClass;
+ __u8 bInterfaceProtocol;
+ __u8 iInterface;
+} __attribute__ ((packed));
+
+#define USB_DT_INTERFACE_SIZE 9
+
+struct usb_endpoint_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ __u8 bEndpointAddress;
+ __u8 bmAttributes;
+ __le16 wMaxPacketSize;
+ __u8 bInterval;
+
+ __u8 bRefresh;
+ __u8 bSynchAddress;
+} __attribute__ ((packed));
+
+#define USB_DT_ENDPOINT_SIZE 7
+#define USB_DT_ENDPOINT_AUDIO_SIZE 9  
+
+#define USB_ENDPOINT_NUMBER_MASK 0x0f  
+#define USB_ENDPOINT_DIR_MASK 0x80
+
+#define USB_ENDPOINT_XFERTYPE_MASK 0x03  
+#define USB_ENDPOINT_XFER_CONTROL 0
+#define USB_ENDPOINT_XFER_ISOC 1
+#define USB_ENDPOINT_XFER_BULK 2
+#define USB_ENDPOINT_XFER_INT 3
+#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80
+
+struct usb_qualifier_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ __le16 bcdUSB;
+ __u8 bDeviceClass;
+ __u8 bDeviceSubClass;
+ __u8 bDeviceProtocol;
+ __u8 bMaxPacketSize0;
+ __u8 bNumConfigurations;
+ __u8 bRESERVED;
+} __attribute__ ((packed));
+
+struct usb_otg_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ __u8 bmAttributes;
+} __attribute__ ((packed));
+
+#define USB_OTG_SRP (1 << 0)
+#define USB_OTG_HNP (1 << 1)  
+
+struct usb_debug_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ __u8 bDebugInEndpoint;
+ __u8 bDebugOutEndpoint;
+};
+
+struct usb_interface_assoc_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ __u8 bFirstInterface;
+ __u8 bInterfaceCount;
+ __u8 bFunctionClass;
+ __u8 bFunctionSubClass;
+ __u8 bFunctionProtocol;
+ __u8 iFunction;
+} __attribute__ ((packed));
+
+struct usb_security_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ __le16 wTotalLength;
+ __u8 bNumEncryptionTypes;
+};
+
+struct usb_key_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ __u8 tTKID[3];
+ __u8 bReserved;
+ __u8 bKeyData[0];
+};
+
+struct usb_encryption_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ __u8 bEncryptionType;
+#define USB_ENC_TYPE_UNSECURE 0
+#define USB_ENC_TYPE_WIRED 1  
+#define USB_ENC_TYPE_CCM_1 2  
+#define USB_ENC_TYPE_RSA_1 3  
+ __u8 bEncryptionValue;
+ __u8 bAuthKeyIndex;
+};
+
+struct usb_bos_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ __le16 wTotalLength;
+ __u8 bNumDeviceCaps;
+};
+
+struct usb_dev_cap_header {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDevCapabilityType;
+};
+
+#define USB_CAP_TYPE_WIRELESS_USB 1
+
+struct usb_wireless_cap_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDevCapabilityType;
+
+ __u8 bmAttributes;
+#define USB_WIRELESS_P2P_DRD (1 << 1)
+#define USB_WIRELESS_BEACON_MASK (3 << 2)
+#define USB_WIRELESS_BEACON_SELF (1 << 2)
+#define USB_WIRELESS_BEACON_DIRECTED (2 << 2)
+#define USB_WIRELESS_BEACON_NONE (3 << 2)
+ __le16 wPHYRates;
+#define USB_WIRELESS_PHY_53 (1 << 0)  
+#define USB_WIRELESS_PHY_80 (1 << 1)
+#define USB_WIRELESS_PHY_107 (1 << 2)  
+#define USB_WIRELESS_PHY_160 (1 << 3)
+#define USB_WIRELESS_PHY_200 (1 << 4)  
+#define USB_WIRELESS_PHY_320 (1 << 5)
+#define USB_WIRELESS_PHY_400 (1 << 6)
+#define USB_WIRELESS_PHY_480 (1 << 7)
+ __u8 bmTFITXPowerInfo;
+ __u8 bmFFITXPowerInfo;
+ __le16 bmBandGroup;
+ __u8 bReserved;
+};
+
+struct usb_wireless_ep_comp_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+
+ __u8 bMaxBurst;
+ __u8 bMaxSequence;
+ __le16 wMaxStreamDelay;
+ __le16 wOverTheAirPacketSize;
+ __u8 bOverTheAirInterval;
+ __u8 bmCompAttributes;
+#define USB_ENDPOINT_SWITCH_MASK 0x03  
+#define USB_ENDPOINT_SWITCH_NO 0
+#define USB_ENDPOINT_SWITCH_SWITCH 1
+#define USB_ENDPOINT_SWITCH_SCALE 2
+};
+
+struct usb_handshake {
+ __u8 bMessageNumber;
+ __u8 bStatus;
+ __u8 tTKID[3];
+ __u8 bReserved;
+ __u8 CDID[16];
+ __u8 nonce[16];
+ __u8 MIC[8];
+};
+
+struct usb_connection_context {
+ __u8 CHID[16];
+ __u8 CDID[16];
+ __u8 CK[16];
+};
+
+enum usb_device_speed {
+ USB_SPEED_UNKNOWN = 0,
+ USB_SPEED_LOW, USB_SPEED_FULL,
+ USB_SPEED_HIGH,
+ USB_SPEED_VARIABLE,
+};
+
+enum usb_device_state {
+
+ USB_STATE_NOTATTACHED = 0,
+
+ USB_STATE_ATTACHED,
+ USB_STATE_POWERED,
+ USB_STATE_UNAUTHENTICATED,
+ USB_STATE_RECONNECTING,
+ USB_STATE_DEFAULT,
+ USB_STATE_ADDRESS,
+ USB_STATE_CONFIGURED,
+
+ USB_STATE_SUSPENDED
+
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/usbdevice_fs.h b/ndk/build/platforms/android-1.5/common/include/linux/usbdevice_fs.h
new file mode 100644
index 0000000..f36efdc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/usbdevice_fs.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_USBDEVICE_FS_H
+#define _LINUX_USBDEVICE_FS_H
+
+#include <linux/types.h>
+
+#define USBDEVICE_SUPER_MAGIC 0x9fa2
+
+struct usbdevfs_ctrltransfer {
+ __u8 bRequestType;
+ __u8 bRequest;
+ __u16 wValue;
+ __u16 wIndex;
+ __u16 wLength;
+ __u32 timeout;
+ void __user *data;
+};
+
+struct usbdevfs_bulktransfer {
+ unsigned int ep;
+ unsigned int len;
+ unsigned int timeout;
+ void __user *data;
+};
+
+struct usbdevfs_setinterface {
+ unsigned int interface;
+ unsigned int altsetting;
+};
+
+struct usbdevfs_disconnectsignal {
+ unsigned int signr;
+ void __user *context;
+};
+
+#define USBDEVFS_MAXDRIVERNAME 255
+
+struct usbdevfs_getdriver {
+ unsigned int interface;
+ char driver[USBDEVFS_MAXDRIVERNAME + 1];
+};
+
+struct usbdevfs_connectinfo {
+ unsigned int devnum;
+ unsigned char slow;
+};
+
+#define USBDEVFS_URB_SHORT_NOT_OK 1
+#define USBDEVFS_URB_ISO_ASAP 2
+
+#define USBDEVFS_URB_TYPE_ISO 0
+#define USBDEVFS_URB_TYPE_INTERRUPT 1
+#define USBDEVFS_URB_TYPE_CONTROL 2
+#define USBDEVFS_URB_TYPE_BULK 3
+
+struct usbdevfs_iso_packet_desc {
+ unsigned int length;
+ unsigned int actual_length;
+ unsigned int status;
+};
+
+struct usbdevfs_urb {
+ unsigned char type;
+ unsigned char endpoint;
+ int status;
+ unsigned int flags;
+ void __user *buffer;
+ int buffer_length;
+ int actual_length;
+ int start_frame;
+ int number_of_packets;
+ int error_count;
+ unsigned int signr;
+ void *usercontext;
+ struct usbdevfs_iso_packet_desc iso_frame_desc[0];
+};
+
+struct usbdevfs_ioctl {
+ int ifno;
+ int ioctl_code;
+ void __user *data;
+};
+
+struct usbdevfs_hub_portinfo {
+ char nports;
+ char port [127];
+};
+
+#define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer)
+#define USBDEVFS_BULK _IOWR('U', 2, struct usbdevfs_bulktransfer)
+#define USBDEVFS_RESETEP _IOR('U', 3, unsigned int)
+#define USBDEVFS_SETINTERFACE _IOR('U', 4, struct usbdevfs_setinterface)
+#define USBDEVFS_SETCONFIGURATION _IOR('U', 5, unsigned int)
+#define USBDEVFS_GETDRIVER _IOW('U', 8, struct usbdevfs_getdriver)
+#define USBDEVFS_SUBMITURB _IOR('U', 10, struct usbdevfs_urb)
+#define USBDEVFS_SUBMITURB32 _IOR('U', 10, struct usbdevfs_urb32)
+#define USBDEVFS_DISCARDURB _IO('U', 11)
+#define USBDEVFS_REAPURB _IOW('U', 12, void *)
+#define USBDEVFS_REAPURB32 _IOW('U', 12, u32)
+#define USBDEVFS_REAPURBNDELAY _IOW('U', 13, void *)
+#define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, u32)
+#define USBDEVFS_DISCSIGNAL _IOR('U', 14, struct usbdevfs_disconnectsignal)
+#define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int)
+#define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int)
+#define USBDEVFS_CONNECTINFO _IOW('U', 17, struct usbdevfs_connectinfo)
+#define USBDEVFS_IOCTL _IOWR('U', 18, struct usbdevfs_ioctl)
+#define USBDEVFS_IOCTL32 _IOWR('U', 18, struct usbdevfs_ioctl32)
+#define USBDEVFS_HUB_PORTINFO _IOR('U', 19, struct usbdevfs_hub_portinfo)
+#define USBDEVFS_RESET _IO('U', 20)
+#define USBDEVFS_CLEAR_HALT _IOR('U', 21, unsigned int)
+#define USBDEVFS_DISCONNECT _IO('U', 22)
+#define USBDEVFS_CONNECT _IO('U', 23)
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/user.h b/ndk/build/platforms/android-1.5/common/include/linux/user.h
new file mode 100644
index 0000000..1c0b9cb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/user.h
@@ -0,0 +1,12 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#include <asm/user.h>
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/utime.h b/ndk/build/platforms/android-1.5/common/include/linux/utime.h
new file mode 100644
index 0000000..4b1ba9c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/utime.h
@@ -0,0 +1,20 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_UTIME_H
+#define _LINUX_UTIME_H
+
+struct utimbuf {
+ time_t actime;
+ time_t modtime;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/utsname.h b/ndk/build/platforms/android-1.5/common/include/linux/utsname.h
new file mode 100644
index 0000000..ea6ee89
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/utsname.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_UTSNAME_H
+#define _LINUX_UTSNAME_H
+
+#define __OLD_UTS_LEN 8
+
+struct oldold_utsname {
+ char sysname[9];
+ char nodename[9];
+ char release[9];
+ char version[9];
+ char machine[9];
+};
+
+#define __NEW_UTS_LEN 64
+
+struct old_utsname {
+ char sysname[65];
+ char nodename[65];
+ char release[65];
+ char version[65];
+ char machine[65];
+};
+
+struct new_utsname {
+ char sysname[65];
+ char nodename[65];
+ char release[65];
+ char version[65];
+ char machine[65];
+ char domainname[65];
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/version.h b/ndk/build/platforms/android-1.5/common/include/linux/version.h
new file mode 100644
index 0000000..beff0ed
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/version.h
@@ -0,0 +1,13 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#define LINUX_VERSION_CODE 132626
+#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/vfs.h b/ndk/build/platforms/android-1.5/common/include/linux/vfs.h
new file mode 100644
index 0000000..70636e9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/vfs.h
@@ -0,0 +1,17 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_VFS_H
+#define _LINUX_VFS_H
+
+#include <linux/statfs.h>
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/videodev.h b/ndk/build/platforms/android-1.5/common/include/linux/videodev.h
new file mode 100644
index 0000000..1f37fde
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/videodev.h
@@ -0,0 +1,327 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_VIDEODEV_H
+#define __LINUX_VIDEODEV_H
+
+#include <linux/videodev2.h>
+
+struct video_capability
+{
+ char name[32];
+ int type;
+ int channels;
+ int audios;
+ int maxwidth;
+ int maxheight;
+ int minwidth;
+ int minheight;
+};
+
+struct video_channel
+{
+ int channel;
+ char name[32];
+ int tuners;
+ __u32 flags;
+#define VIDEO_VC_TUNER 1  
+#define VIDEO_VC_AUDIO 2  
+ __u16 type;
+#define VIDEO_TYPE_TV 1
+#define VIDEO_TYPE_CAMERA 2
+ __u16 norm;
+};
+
+struct video_tuner
+{
+ int tuner;
+ char name[32];
+ unsigned long rangelow, rangehigh;
+ __u32 flags;
+#define VIDEO_TUNER_PAL 1
+#define VIDEO_TUNER_NTSC 2
+#define VIDEO_TUNER_SECAM 4
+#define VIDEO_TUNER_LOW 8  
+#define VIDEO_TUNER_NORM 16  
+#define VIDEO_TUNER_STEREO_ON 128  
+#define VIDEO_TUNER_RDS_ON 256  
+#define VIDEO_TUNER_MBS_ON 512  
+ __u16 mode;
+#define VIDEO_MODE_PAL 0
+#define VIDEO_MODE_NTSC 1
+#define VIDEO_MODE_SECAM 2
+#define VIDEO_MODE_AUTO 3
+ __u16 signal;
+};
+
+struct video_picture
+{
+ __u16 brightness;
+ __u16 hue;
+ __u16 colour;
+ __u16 contrast;
+ __u16 whiteness;
+ __u16 depth;
+ __u16 palette;
+#define VIDEO_PALETTE_GREY 1  
+#define VIDEO_PALETTE_HI240 2  
+#define VIDEO_PALETTE_RGB565 3  
+#define VIDEO_PALETTE_RGB24 4  
+#define VIDEO_PALETTE_RGB32 5  
+#define VIDEO_PALETTE_RGB555 6  
+#define VIDEO_PALETTE_YUV422 7  
+#define VIDEO_PALETTE_YUYV 8
+#define VIDEO_PALETTE_UYVY 9  
+#define VIDEO_PALETTE_YUV420 10
+#define VIDEO_PALETTE_YUV411 11  
+#define VIDEO_PALETTE_RAW 12  
+#define VIDEO_PALETTE_YUV422P 13  
+#define VIDEO_PALETTE_YUV411P 14  
+#define VIDEO_PALETTE_YUV420P 15  
+#define VIDEO_PALETTE_YUV410P 16  
+#define VIDEO_PALETTE_PLANAR 13  
+#define VIDEO_PALETTE_COMPONENT 7  
+};
+
+struct video_audio
+{
+ int audio;
+ __u16 volume;
+ __u16 bass, treble;
+ __u32 flags;
+#define VIDEO_AUDIO_MUTE 1
+#define VIDEO_AUDIO_MUTABLE 2
+#define VIDEO_AUDIO_VOLUME 4
+#define VIDEO_AUDIO_BASS 8
+#define VIDEO_AUDIO_TREBLE 16
+#define VIDEO_AUDIO_BALANCE 32
+ char name[16];
+#define VIDEO_SOUND_MONO 1
+#define VIDEO_SOUND_STEREO 2
+#define VIDEO_SOUND_LANG1 4
+#define VIDEO_SOUND_LANG2 8
+ __u16 mode;
+ __u16 balance;
+ __u16 step;
+};
+
+struct video_clip
+{
+ __s32 x,y;
+ __s32 width, height;
+ struct video_clip *next;
+};
+
+struct video_window
+{
+ __u32 x,y;
+ __u32 width,height;
+ __u32 chromakey;
+ __u32 flags;
+ struct video_clip __user *clips;
+ int clipcount;
+#define VIDEO_WINDOW_INTERLACE 1
+#define VIDEO_WINDOW_CHROMAKEY 16  
+#define VIDEO_CLIP_BITMAP -1
+
+#define VIDEO_CLIPMAP_SIZE (128 * 625)
+};
+
+struct video_capture
+{
+ __u32 x,y;
+ __u32 width, height;
+ __u16 decimation;
+ __u16 flags;
+#define VIDEO_CAPTURE_ODD 0  
+#define VIDEO_CAPTURE_EVEN 1
+};
+
+struct video_buffer
+{
+ void *base;
+ int height,width;
+ int depth;
+ int bytesperline;
+};
+
+struct video_mmap
+{
+ unsigned int frame;
+ int height,width;
+ unsigned int format;
+};
+
+struct video_key
+{
+ __u8 key[8];
+ __u32 flags;
+};
+
+struct video_mbuf
+{
+ int size;
+ int frames;
+ int offsets[VIDEO_MAX_FRAME];
+};
+
+#define VIDEO_NO_UNIT (-1)
+
+struct video_unit
+{
+ int video;
+ int vbi;
+ int radio;
+ int audio;
+ int teletext;
+};
+
+struct vbi_format {
+ __u32 sampling_rate;
+ __u32 samples_per_line;
+ __u32 sample_format;
+ __s32 start[2];
+ __u32 count[2];
+ __u32 flags;
+#define VBI_UNSYNC 1  
+#define VBI_INTERLACED 2  
+};
+
+struct video_info
+{
+ __u32 frame_count;
+ __u32 h_size;
+ __u32 v_size;
+ __u32 smpte_timecode;
+ __u32 picture_type;
+ __u32 temporal_reference;
+ __u8 user_data[256];
+
+};
+
+struct video_play_mode
+{
+ int mode;
+ int p1;
+ int p2;
+};
+
+struct video_code
+{
+ char loadwhat[16];
+ int datasize;
+ __u8 *data;
+};
+
+#define VIDIOCGCAP _IOR('v',1,struct video_capability)  
+#define VIDIOCGCHAN _IOWR('v',2,struct video_channel)  
+#define VIDIOCSCHAN _IOW('v',3,struct video_channel)  
+#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner)  
+#define VIDIOCSTUNER _IOW('v',5,struct video_tuner)  
+#define VIDIOCGPICT _IOR('v',6,struct video_picture)  
+#define VIDIOCSPICT _IOW('v',7,struct video_picture)  
+#define VIDIOCCAPTURE _IOW('v',8,int)  
+#define VIDIOCGWIN _IOR('v',9, struct video_window)  
+#define VIDIOCSWIN _IOW('v',10, struct video_window)  
+#define VIDIOCGFBUF _IOR('v',11, struct video_buffer)  
+#define VIDIOCSFBUF _IOW('v',12, struct video_buffer)  
+#define VIDIOCKEY _IOR('v',13, struct video_key)  
+#define VIDIOCGFREQ _IOR('v',14, unsigned long)  
+#define VIDIOCSFREQ _IOW('v',15, unsigned long)  
+#define VIDIOCGAUDIO _IOR('v',16, struct video_audio)  
+#define VIDIOCSAUDIO _IOW('v',17, struct video_audio)  
+#define VIDIOCSYNC _IOW('v',18, int)  
+#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap)  
+#define VIDIOCGMBUF _IOR('v',20, struct video_mbuf)  
+#define VIDIOCGUNIT _IOR('v',21, struct video_unit)  
+#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture)  
+#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture)  
+#define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode)  
+#define VIDIOCSWRITEMODE _IOW('v',25, int)  
+#define VIDIOCGPLAYINFO _IOR('v',26, struct video_info)  
+#define VIDIOCSMICROCODE _IOW('v',27, struct video_code)  
+#define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format)  
+#define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format)  
+
+#define BASE_VIDIOCPRIVATE 192  
+
+#define VID_WRITE_MPEG_AUD 0
+#define VID_WRITE_MPEG_VID 1
+#define VID_WRITE_OSD 2
+#define VID_WRITE_TTX 3
+#define VID_WRITE_CC 4
+#define VID_WRITE_MJPEG 5
+
+#define VID_PLAY_VID_OUT_MODE 0
+
+#define VID_PLAY_GENLOCK 1
+
+#define VID_PLAY_NORMAL 2
+#define VID_PLAY_PAUSE 3
+#define VID_PLAY_SINGLE_FRAME 4
+#define VID_PLAY_FAST_FORWARD 5
+#define VID_PLAY_SLOW_MOTION 6
+#define VID_PLAY_IMMEDIATE_NORMAL 7
+#define VID_PLAY_SWITCH_CHANNELS 8
+#define VID_PLAY_FREEZE_FRAME 9
+#define VID_PLAY_STILL_MODE 10
+#define VID_PLAY_MASTER_MODE 11
+
+#define VID_PLAY_MASTER_NONE 1
+#define VID_PLAY_MASTER_VIDEO 2
+#define VID_PLAY_MASTER_AUDIO 3
+#define VID_PLAY_ACTIVE_SCANLINES 12
+
+#define VID_PLAY_RESET 13
+#define VID_PLAY_END_MARK 14
+
+#define VID_HARDWARE_BT848 1
+#define VID_HARDWARE_QCAM_BW 2
+#define VID_HARDWARE_PMS 3
+#define VID_HARDWARE_QCAM_C 4
+#define VID_HARDWARE_PSEUDO 5
+#define VID_HARDWARE_SAA5249 6
+#define VID_HARDWARE_AZTECH 7
+#define VID_HARDWARE_SF16MI 8
+#define VID_HARDWARE_RTRACK 9
+#define VID_HARDWARE_ZOLTRIX 10
+#define VID_HARDWARE_SAA7146 11
+#define VID_HARDWARE_VIDEUM 12  
+#define VID_HARDWARE_RTRACK2 13
+#define VID_HARDWARE_PERMEDIA2 14  
+#define VID_HARDWARE_RIVA128 15  
+#define VID_HARDWARE_PLANB 16  
+#define VID_HARDWARE_BROADWAY 17  
+#define VID_HARDWARE_GEMTEK 18
+#define VID_HARDWARE_TYPHOON 19
+#define VID_HARDWARE_VINO 20  
+#define VID_HARDWARE_CADET 21  
+#define VID_HARDWARE_TRUST 22  
+#define VID_HARDWARE_TERRATEC 23  
+#define VID_HARDWARE_CPIA 24
+#define VID_HARDWARE_ZR36120 25  
+#define VID_HARDWARE_ZR36067 26  
+#define VID_HARDWARE_OV511 27
+#define VID_HARDWARE_ZR356700 28  
+#define VID_HARDWARE_W9966 29
+#define VID_HARDWARE_SE401 30  
+#define VID_HARDWARE_PWC 31  
+#define VID_HARDWARE_MEYE 32  
+#define VID_HARDWARE_CPIA2 33
+#define VID_HARDWARE_VICAM 34
+#define VID_HARDWARE_SF16FMR2 35
+#define VID_HARDWARE_W9968CF 36
+#define VID_HARDWARE_SAA7114H 37
+#define VID_HARDWARE_SN9C102 38
+#define VID_HARDWARE_ARV 39
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/videodev2.h b/ndk/build/platforms/android-1.5/common/include/linux/videodev2.h
new file mode 100644
index 0000000..dae4e93
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/videodev2.h
@@ -0,0 +1,963 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __LINUX_VIDEODEV2_H
+#define __LINUX_VIDEODEV2_H
+#define __user
+#include <linux/types.h>
+
+#define VIDEO_MAX_FRAME 32
+
+#define VID_TYPE_CAPTURE 1  
+#define VID_TYPE_TUNER 2  
+#define VID_TYPE_TELETEXT 4  
+#define VID_TYPE_OVERLAY 8  
+#define VID_TYPE_CHROMAKEY 16  
+#define VID_TYPE_CLIPPING 32  
+#define VID_TYPE_FRAMERAM 64  
+#define VID_TYPE_SCALES 128  
+#define VID_TYPE_MONOCHROME 256  
+#define VID_TYPE_SUBCAPTURE 512  
+#define VID_TYPE_MPEG_DECODER 1024  
+#define VID_TYPE_MPEG_ENCODER 2048  
+#define VID_TYPE_MJPEG_DECODER 4096  
+#define VID_TYPE_MJPEG_ENCODER 8192  
+
+#define v4l2_fourcc(a,b,c,d)  (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
+
+enum v4l2_field {
+ V4L2_FIELD_ANY = 0,
+ V4L2_FIELD_NONE = 1,
+ V4L2_FIELD_TOP = 2,
+ V4L2_FIELD_BOTTOM = 3,
+ V4L2_FIELD_INTERLACED = 4,
+ V4L2_FIELD_SEQ_TB = 5,
+ V4L2_FIELD_SEQ_BT = 6,
+ V4L2_FIELD_ALTERNATE = 7,
+};
+#define V4L2_FIELD_HAS_TOP(field)   ((field) == V4L2_FIELD_TOP ||  (field) == V4L2_FIELD_INTERLACED ||  (field) == V4L2_FIELD_SEQ_TB ||  (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_BOTTOM(field)   ((field) == V4L2_FIELD_BOTTOM ||  (field) == V4L2_FIELD_INTERLACED ||  (field) == V4L2_FIELD_SEQ_TB ||  (field) == V4L2_FIELD_SEQ_BT)
+#define V4L2_FIELD_HAS_BOTH(field)   ((field) == V4L2_FIELD_INTERLACED ||  (field) == V4L2_FIELD_SEQ_TB ||  (field) == V4L2_FIELD_SEQ_BT)
+
+enum v4l2_buf_type {
+ V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
+ V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
+ V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
+ V4L2_BUF_TYPE_VBI_CAPTURE = 4,
+ V4L2_BUF_TYPE_VBI_OUTPUT = 5,
+
+ V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6,
+ V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7,
+ V4L2_BUF_TYPE_PRIVATE = 0x80,
+};
+
+enum v4l2_ctrl_type {
+ V4L2_CTRL_TYPE_INTEGER = 1,
+ V4L2_CTRL_TYPE_BOOLEAN = 2,
+ V4L2_CTRL_TYPE_MENU = 3,
+ V4L2_CTRL_TYPE_BUTTON = 4,
+ V4L2_CTRL_TYPE_INTEGER64 = 5,
+ V4L2_CTRL_TYPE_CTRL_CLASS = 6,
+};
+
+enum v4l2_tuner_type {
+ V4L2_TUNER_RADIO = 1,
+ V4L2_TUNER_ANALOG_TV = 2,
+ V4L2_TUNER_DIGITAL_TV = 3,
+};
+
+enum v4l2_memory {
+ V4L2_MEMORY_MMAP = 1,
+ V4L2_MEMORY_USERPTR = 2,
+ V4L2_MEMORY_OVERLAY = 3,
+};
+
+enum v4l2_colorspace {
+
+ V4L2_COLORSPACE_SMPTE170M = 1,
+
+ V4L2_COLORSPACE_SMPTE240M = 2,
+
+ V4L2_COLORSPACE_REC709 = 3,
+
+ V4L2_COLORSPACE_BT878 = 4,
+
+ V4L2_COLORSPACE_470_SYSTEM_M = 5,
+ V4L2_COLORSPACE_470_SYSTEM_BG = 6,
+
+ V4L2_COLORSPACE_JPEG = 7,
+
+ V4L2_COLORSPACE_SRGB = 8,
+};
+
+enum v4l2_priority {
+ V4L2_PRIORITY_UNSET = 0,
+ V4L2_PRIORITY_BACKGROUND = 1,
+ V4L2_PRIORITY_INTERACTIVE = 2,
+ V4L2_PRIORITY_RECORD = 3,
+ V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE,
+};
+
+struct v4l2_rect {
+ __s32 left;
+ __s32 top;
+ __s32 width;
+ __s32 height;
+};
+
+struct v4l2_fract {
+ __u32 numerator;
+ __u32 denominator;
+};
+
+struct v4l2_capability
+{
+ __u8 driver[16];
+ __u8 card[32];
+ __u8 bus_info[32];
+ __u32 version;
+ __u32 capabilities;
+ __u32 reserved[4];
+};
+
+#define V4L2_CAP_VIDEO_CAPTURE 0x00000001  
+#define V4L2_CAP_VIDEO_OUTPUT 0x00000002  
+#define V4L2_CAP_VIDEO_OVERLAY 0x00000004  
+#define V4L2_CAP_VBI_CAPTURE 0x00000010  
+#define V4L2_CAP_VBI_OUTPUT 0x00000020  
+#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040  
+#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080  
+#define V4L2_CAP_RDS_CAPTURE 0x00000100  
+
+#define V4L2_CAP_TUNER 0x00010000  
+#define V4L2_CAP_AUDIO 0x00020000  
+#define V4L2_CAP_RADIO 0x00040000  
+
+#define V4L2_CAP_READWRITE 0x01000000  
+#define V4L2_CAP_ASYNCIO 0x02000000  
+#define V4L2_CAP_STREAMING 0x04000000  
+
+struct v4l2_pix_format
+{
+ __u32 width;
+ __u32 height;
+ __u32 pixelformat;
+ enum v4l2_field field;
+ __u32 bytesperline;
+ __u32 sizeimage;
+ enum v4l2_colorspace colorspace;
+ __u32 priv;
+};
+
+#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R','G','B','1')  
+#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R','G','B','O')  
+#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R','G','B','P')  
+#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q')  
+#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R')  
+#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B','G','R','3')  
+#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R','G','B','3')  
+#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4')  
+#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4')  
+#define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y')  
+#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9')  
+#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2')  
+#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y','U','Y','V')  
+#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U','Y','V','Y')  
+#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P')  
+#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P')  
+#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y','4','1','P')  
+
+#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N','V','1','2')  
+#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N','V','2','1')  
+
+#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y','U','V','9')  
+#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y','U','1','2')  
+#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y','Y','U','V')  
+#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H','I','2','4')  
+#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H','M','1','2')  
+
+#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B','A','8','1')  
+
+#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M','J','P','G')  
+#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J','P','E','G')  
+#define V4L2_PIX_FMT_DV v4l2_fourcc('d','v','s','d')  
+#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M','P','E','G')  
+
+#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A')  
+#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S','9','1','0')  
+#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1')  
+#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2')  
+#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E','6','2','5')  
+
+struct v4l2_fmtdesc
+{
+ __u32 index;
+ enum v4l2_buf_type type;
+ __u32 flags;
+ __u8 description[32];
+ __u32 pixelformat;
+ __u32 reserved[4];
+};
+
+#define V4L2_FMT_FLAG_COMPRESSED 0x0001
+
+struct v4l2_timecode
+{
+ __u32 type;
+ __u32 flags;
+ __u8 frames;
+ __u8 seconds;
+ __u8 minutes;
+ __u8 hours;
+ __u8 userbits[4];
+};
+
+#define V4L2_TC_TYPE_24FPS 1
+#define V4L2_TC_TYPE_25FPS 2
+#define V4L2_TC_TYPE_30FPS 3
+#define V4L2_TC_TYPE_50FPS 4
+#define V4L2_TC_TYPE_60FPS 5
+
+#define V4L2_TC_FLAG_DROPFRAME 0x0001  
+#define V4L2_TC_FLAG_COLORFRAME 0x0002
+#define V4L2_TC_USERBITS_field 0x000C
+#define V4L2_TC_USERBITS_USERDEFINED 0x0000
+#define V4L2_TC_USERBITS_8BITCHARS 0x0008
+
+struct v4l2_jpegcompression
+{
+ int quality;
+
+ int APPn;
+ int APP_len;
+ char APP_data[60];
+
+ int COM_len;
+ char COM_data[60];
+
+ __u32 jpeg_markers;
+
+#define V4L2_JPEG_MARKER_DHT (1<<3)  
+#define V4L2_JPEG_MARKER_DQT (1<<4)  
+#define V4L2_JPEG_MARKER_DRI (1<<5)  
+#define V4L2_JPEG_MARKER_COM (1<<6)  
+#define V4L2_JPEG_MARKER_APP (1<<7)  
+};
+
+struct v4l2_requestbuffers
+{
+ __u32 count;
+ enum v4l2_buf_type type;
+ enum v4l2_memory memory;
+ __u32 reserved[2];
+};
+
+struct v4l2_buffer
+{
+ __u32 index;
+ enum v4l2_buf_type type;
+ __u32 bytesused;
+ __u32 flags;
+ enum v4l2_field field;
+ struct timeval timestamp;
+ struct v4l2_timecode timecode;
+ __u32 sequence;
+
+ enum v4l2_memory memory;
+ union {
+ __u32 offset;
+ unsigned long userptr;
+ } m;
+ __u32 length;
+ __u32 input;
+ __u32 reserved;
+};
+
+#define V4L2_BUF_FLAG_MAPPED 0x0001  
+#define V4L2_BUF_FLAG_QUEUED 0x0002  
+#define V4L2_BUF_FLAG_DONE 0x0004  
+#define V4L2_BUF_FLAG_KEYFRAME 0x0008  
+#define V4L2_BUF_FLAG_PFRAME 0x0010  
+#define V4L2_BUF_FLAG_BFRAME 0x0020  
+#define V4L2_BUF_FLAG_TIMECODE 0x0100  
+#define V4L2_BUF_FLAG_INPUT 0x0200  
+
+struct v4l2_framebuffer
+{
+ __u32 capability;
+ __u32 flags;
+
+ void* base;
+ struct v4l2_pix_format fmt;
+};
+
+#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001
+#define V4L2_FBUF_CAP_CHROMAKEY 0x0002
+#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004
+#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008
+
+#define V4L2_FBUF_FLAG_PRIMARY 0x0001
+#define V4L2_FBUF_FLAG_OVERLAY 0x0002
+#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004
+
+struct v4l2_clip
+{
+ struct v4l2_rect c;
+ struct v4l2_clip __user *next;
+};
+
+struct v4l2_window
+{
+ struct v4l2_rect w;
+ enum v4l2_field field;
+ __u32 chromakey;
+ struct v4l2_clip __user *clips;
+ __u32 clipcount;
+ void __user *bitmap;
+};
+
+struct v4l2_captureparm
+{
+ __u32 capability;
+ __u32 capturemode;
+ struct v4l2_fract timeperframe;
+ __u32 extendedmode;
+ __u32 readbuffers;
+ __u32 reserved[4];
+};
+
+#define V4L2_MODE_HIGHQUALITY 0x0001  
+#define V4L2_CAP_TIMEPERFRAME 0x1000  
+
+struct v4l2_outputparm
+{
+ __u32 capability;
+ __u32 outputmode;
+ struct v4l2_fract timeperframe;
+ __u32 extendedmode;
+ __u32 writebuffers;
+ __u32 reserved[4];
+};
+
+struct v4l2_cropcap {
+ enum v4l2_buf_type type;
+ struct v4l2_rect bounds;
+ struct v4l2_rect defrect;
+ struct v4l2_fract pixelaspect;
+};
+
+struct v4l2_crop {
+ enum v4l2_buf_type type;
+ struct v4l2_rect c;
+};
+
+typedef __u64 v4l2_std_id;
+
+#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001)
+#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002)
+#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004)
+#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008)
+#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010)
+#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020)
+#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040)
+#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080)
+
+#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100)
+#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200)
+#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400)
+#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800)
+
+#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000)
+#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000)
+#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000)
+#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000)
+
+#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
+#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
+#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000)
+#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000)
+#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000)
+#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000)
+#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000)
+#define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000)
+
+#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000)
+#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000)
+
+#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
+#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
+#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
+#define V4L2_STD_DK (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK)
+
+#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |  V4L2_STD_PAL_B1 |  V4L2_STD_PAL_G)
+#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |  V4L2_STD_PAL_D1 |  V4L2_STD_PAL_K)
+#define V4L2_STD_PAL (V4L2_STD_PAL_BG |  V4L2_STD_PAL_DK |  V4L2_STD_PAL_H |  V4L2_STD_PAL_I)
+#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |  V4L2_STD_NTSC_M_JP |  V4L2_STD_NTSC_M_KR)
+#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |  V4L2_STD_SECAM_K |  V4L2_STD_SECAM_K1)
+#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |  V4L2_STD_SECAM_G |  V4L2_STD_SECAM_H |  V4L2_STD_SECAM_DK |  V4L2_STD_SECAM_L |  V4L2_STD_SECAM_LC)
+
+#define V4L2_STD_525_60 (V4L2_STD_PAL_M |  V4L2_STD_PAL_60 |  V4L2_STD_NTSC |  V4L2_STD_NTSC_443)
+#define V4L2_STD_625_50 (V4L2_STD_PAL |  V4L2_STD_PAL_N |  V4L2_STD_PAL_Nc |  V4L2_STD_SECAM)
+#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |  V4L2_STD_ATSC_16_VSB)
+
+#define V4L2_STD_UNKNOWN 0
+#define V4L2_STD_ALL (V4L2_STD_525_60 |  V4L2_STD_625_50)
+
+struct v4l2_standard
+{
+ __u32 index;
+ v4l2_std_id id;
+ __u8 name[24];
+ struct v4l2_fract frameperiod;
+ __u32 framelines;
+ __u32 reserved[4];
+};
+
+struct v4l2_input
+{
+ __u32 index;
+ __u8 name[32];
+ __u32 type;
+ __u32 audioset;
+ __u32 tuner;
+ v4l2_std_id std;
+ __u32 status;
+ __u32 reserved[4];
+};
+
+#define V4L2_INPUT_TYPE_TUNER 1
+#define V4L2_INPUT_TYPE_CAMERA 2
+
+#define V4L2_IN_ST_NO_POWER 0x00000001  
+#define V4L2_IN_ST_NO_SIGNAL 0x00000002
+#define V4L2_IN_ST_NO_COLOR 0x00000004
+
+#define V4L2_IN_ST_NO_H_LOCK 0x00000100  
+#define V4L2_IN_ST_COLOR_KILL 0x00000200  
+
+#define V4L2_IN_ST_NO_SYNC 0x00010000  
+#define V4L2_IN_ST_NO_EQU 0x00020000  
+#define V4L2_IN_ST_NO_CARRIER 0x00040000  
+
+#define V4L2_IN_ST_MACROVISION 0x01000000  
+#define V4L2_IN_ST_NO_ACCESS 0x02000000  
+#define V4L2_IN_ST_VTR 0x04000000  
+
+struct v4l2_output
+{
+ __u32 index;
+ __u8 name[32];
+ __u32 type;
+ __u32 audioset;
+ __u32 modulator;
+ v4l2_std_id std;
+ __u32 reserved[4];
+};
+
+#define V4L2_OUTPUT_TYPE_MODULATOR 1
+#define V4L2_OUTPUT_TYPE_ANALOG 2
+#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3
+
+struct v4l2_control
+{
+ __u32 id;
+ __s32 value;
+};
+
+struct v4l2_ext_control
+{
+ __u32 id;
+ __u32 reserved2[2];
+ union {
+ __s32 value;
+ __s64 value64;
+ void *reserved;
+ };
+} __attribute__ ((packed));
+
+struct v4l2_ext_controls
+{
+ __u32 ctrl_class;
+ __u32 count;
+ __u32 error_idx;
+ __u32 reserved[2];
+ struct v4l2_ext_control *controls;
+};
+
+#define V4L2_CTRL_CLASS_USER 0x00980000  
+#define V4L2_CTRL_CLASS_MPEG 0x00990000  
+
+#define V4L2_CTRL_ID_MASK (0x0fffffff)
+#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)
+#define V4L2_CTRL_DRIVER_PRIV(id) (((id) & 0xffff) >= 0x1000)
+
+struct v4l2_queryctrl
+{
+ __u32 id;
+ enum v4l2_ctrl_type type;
+ __u8 name[32];
+ __s32 minimum;
+ __s32 maximum;
+ __s32 step;
+ __s32 default_value;
+ __u32 flags;
+ __u32 reserved[2];
+};
+
+struct v4l2_querymenu
+{
+ __u32 id;
+ __u32 index;
+ __u8 name[32];
+ __u32 reserved;
+};
+
+#define V4L2_CTRL_FLAG_DISABLED 0x0001
+#define V4L2_CTRL_FLAG_GRABBED 0x0002
+#define V4L2_CTRL_FLAG_READ_ONLY 0x0004
+#define V4L2_CTRL_FLAG_UPDATE 0x0008
+#define V4L2_CTRL_FLAG_INACTIVE 0x0010
+#define V4L2_CTRL_FLAG_SLIDER 0x0020
+
+#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000
+
+#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900)
+#define V4L2_CID_USER_BASE V4L2_CID_BASE
+
+#define V4L2_CID_PRIVATE_BASE 0x08000000
+
+#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1)
+#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0)
+#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1)
+#define V4L2_CID_SATURATION (V4L2_CID_BASE+2)
+#define V4L2_CID_HUE (V4L2_CID_BASE+3)
+#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5)
+#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6)
+#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7)
+#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8)
+#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9)
+#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10)
+#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11)
+#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12)
+#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13)
+#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14)
+#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15)
+#define V4L2_CID_GAMMA (V4L2_CID_BASE+16)
+#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA)  
+#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17)
+#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18)
+#define V4L2_CID_GAIN (V4L2_CID_BASE+19)
+#define V4L2_CID_HFLIP (V4L2_CID_BASE+20)
+#define V4L2_CID_VFLIP (V4L2_CID_BASE+21)
+#define V4L2_CID_HCENTER (V4L2_CID_BASE+22)
+#define V4L2_CID_VCENTER (V4L2_CID_BASE+23)
+#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24)  
+
+#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
+#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1)
+
+#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0)
+enum v4l2_mpeg_stream_type {
+ V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1,
+ V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3,
+ V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5,
+};
+#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1)
+#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2)
+#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3)
+#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4)
+#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5)
+#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6)
+#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7)
+enum v4l2_mpeg_stream_vbi_fmt {
+ V4L2_MPEG_STREAM_VBI_FMT_NONE = 0,
+ V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1,
+};
+
+#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100)
+enum v4l2_mpeg_audio_sampling_freq {
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2,
+};
+#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101)
+enum v4l2_mpeg_audio_encoding {
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2,
+};
+#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102)
+enum v4l2_mpeg_audio_l1_bitrate {
+ V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0,
+ V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1,
+ V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2,
+ V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3,
+ V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4,
+ V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5,
+ V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6,
+ V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7,
+ V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8,
+ V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9,
+ V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10,
+ V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11,
+ V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12,
+ V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13,
+};
+#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103)
+enum v4l2_mpeg_audio_l2_bitrate {
+ V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0,
+ V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1,
+ V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2,
+ V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3,
+ V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4,
+ V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5,
+ V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6,
+ V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7,
+ V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8,
+ V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9,
+ V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10,
+ V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11,
+ V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12,
+ V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13,
+};
+#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104)
+enum v4l2_mpeg_audio_l3_bitrate {
+ V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0,
+ V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1,
+ V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2,
+ V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3,
+ V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4,
+ V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5,
+ V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6,
+ V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7,
+ V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8,
+ V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9,
+ V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10,
+ V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11,
+ V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12,
+ V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13,
+};
+#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105)
+enum v4l2_mpeg_audio_mode {
+ V4L2_MPEG_AUDIO_MODE_STEREO = 0,
+ V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1,
+ V4L2_MPEG_AUDIO_MODE_DUAL = 2,
+ V4L2_MPEG_AUDIO_MODE_MONO = 3,
+};
+#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106)
+enum v4l2_mpeg_audio_mode_extension {
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3,
+};
+#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107)
+enum v4l2_mpeg_audio_emphasis {
+ V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0,
+ V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1,
+ V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2,
+};
+#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108)
+enum v4l2_mpeg_audio_crc {
+ V4L2_MPEG_AUDIO_CRC_NONE = 0,
+ V4L2_MPEG_AUDIO_CRC_CRC16 = 1,
+};
+
+#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200)
+enum v4l2_mpeg_video_encoding {
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1,
+};
+#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201)
+enum v4l2_mpeg_video_aspect {
+ V4L2_MPEG_VIDEO_ASPECT_1x1 = 0,
+ V4L2_MPEG_VIDEO_ASPECT_4x3 = 1,
+ V4L2_MPEG_VIDEO_ASPECT_16x9 = 2,
+ V4L2_MPEG_VIDEO_ASPECT_221x100 = 3,
+};
+#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202)
+#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203)
+#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204)
+#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205)
+#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206)
+enum v4l2_mpeg_video_bitrate_mode {
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1,
+};
+#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207)
+#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208)
+#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209)
+
+#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0)
+enum v4l2_mpeg_cx2341x_video_spatial_filter_mode {
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0,
+ V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2)
+enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type {
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3,
+ V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3)
+enum v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type {
+ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0,
+ V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4)
+enum v4l2_mpeg_cx2341x_video_temporal_filter_mode {
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0,
+ V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6)
+enum v4l2_mpeg_cx2341x_video_median_filter_type {
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3,
+ V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4,
+};
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9)
+#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10)
+
+struct v4l2_tuner
+{
+ __u32 index;
+ __u8 name[32];
+ enum v4l2_tuner_type type;
+ __u32 capability;
+ __u32 rangelow;
+ __u32 rangehigh;
+ __u32 rxsubchans;
+ __u32 audmode;
+ __s32 signal;
+ __s32 afc;
+ __u32 reserved[4];
+};
+
+struct v4l2_modulator
+{
+ __u32 index;
+ __u8 name[32];
+ __u32 capability;
+ __u32 rangelow;
+ __u32 rangehigh;
+ __u32 txsubchans;
+ __u32 reserved[4];
+};
+
+#define V4L2_TUNER_CAP_LOW 0x0001
+#define V4L2_TUNER_CAP_NORM 0x0002
+#define V4L2_TUNER_CAP_STEREO 0x0010
+#define V4L2_TUNER_CAP_LANG2 0x0020
+#define V4L2_TUNER_CAP_SAP 0x0020
+#define V4L2_TUNER_CAP_LANG1 0x0040
+
+#define V4L2_TUNER_SUB_MONO 0x0001
+#define V4L2_TUNER_SUB_STEREO 0x0002
+#define V4L2_TUNER_SUB_LANG2 0x0004
+#define V4L2_TUNER_SUB_SAP 0x0004
+#define V4L2_TUNER_SUB_LANG1 0x0008
+
+#define V4L2_TUNER_MODE_MONO 0x0000
+#define V4L2_TUNER_MODE_STEREO 0x0001
+#define V4L2_TUNER_MODE_LANG2 0x0002
+#define V4L2_TUNER_MODE_SAP 0x0002
+#define V4L2_TUNER_MODE_LANG1 0x0003
+#define V4L2_TUNER_MODE_LANG1_LANG2 0x0004
+
+struct v4l2_frequency
+{
+ __u32 tuner;
+ enum v4l2_tuner_type type;
+ __u32 frequency;
+ __u32 reserved[8];
+};
+
+struct v4l2_audio
+{
+ __u32 index;
+ __u8 name[32];
+ __u32 capability;
+ __u32 mode;
+ __u32 reserved[2];
+};
+
+#define V4L2_AUDCAP_STEREO 0x00001
+#define V4L2_AUDCAP_AVL 0x00002
+
+#define V4L2_AUDMODE_AVL 0x00001
+
+struct v4l2_audioout
+{
+ __u32 index;
+ __u8 name[32];
+ __u32 capability;
+ __u32 mode;
+ __u32 reserved[2];
+};
+
+struct v4l2_vbi_format
+{
+ __u32 sampling_rate;
+ __u32 offset;
+ __u32 samples_per_line;
+ __u32 sample_format;
+ __s32 start[2];
+ __u32 count[2];
+ __u32 flags;
+ __u32 reserved[2];
+};
+
+#define V4L2_VBI_UNSYNC (1<< 0)
+#define V4L2_VBI_INTERLACED (1<< 1)
+
+struct v4l2_sliced_vbi_format
+{
+ __u16 service_set;
+
+ __u16 service_lines[2][24];
+ __u32 io_size;
+ __u32 reserved[2];
+};
+
+#define V4L2_SLICED_TELETEXT_B (0x0001)
+
+#define V4L2_SLICED_VPS (0x0400)
+
+#define V4L2_SLICED_CAPTION_525 (0x1000)
+
+#define V4L2_SLICED_WSS_625 (0x4000)
+
+#define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525)
+#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625)
+
+struct v4l2_sliced_vbi_cap
+{
+ __u16 service_set;
+
+ __u16 service_lines[2][24];
+ __u32 reserved[4];
+};
+
+struct v4l2_sliced_vbi_data
+{
+ __u32 id;
+ __u32 field;
+ __u32 line;
+ __u32 reserved;
+ __u8 data[48];
+};
+
+struct v4l2_format
+{
+ enum v4l2_buf_type type;
+ union
+ {
+ struct v4l2_pix_format pix;
+ struct v4l2_window win;
+ struct v4l2_vbi_format vbi;
+ struct v4l2_sliced_vbi_format sliced;
+ __u8 raw_data[200];
+ } fmt;
+};
+
+struct v4l2_streamparm
+{
+ enum v4l2_buf_type type;
+ union
+ {
+ struct v4l2_captureparm capture;
+ struct v4l2_outputparm output;
+ __u8 raw_data[200];
+ } parm;
+};
+
+#define VIDIOC_QUERYCAP _IOR ('V', 0, struct v4l2_capability)
+#define VIDIOC_RESERVED _IO ('V', 1)
+#define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc)
+#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format)
+#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format)
+#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers)
+#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer)
+#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer)
+#define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer)
+#define VIDIOC_OVERLAY _IOW ('V', 14, int)
+#define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer)
+#define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer)
+#define VIDIOC_STREAMON _IOW ('V', 18, int)
+#define VIDIOC_STREAMOFF _IOW ('V', 19, int)
+#define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm)
+#define VIDIOC_S_PARM _IOWR ('V', 22, struct v4l2_streamparm)
+#define VIDIOC_G_STD _IOR ('V', 23, v4l2_std_id)
+#define VIDIOC_S_STD _IOW ('V', 24, v4l2_std_id)
+#define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_standard)
+#define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input)
+#define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control)
+#define VIDIOC_S_CTRL _IOWR ('V', 28, struct v4l2_control)
+#define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner)
+#define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner)
+#define VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio)
+#define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio)
+#define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl)
+#define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu)
+#define VIDIOC_G_INPUT _IOR ('V', 38, int)
+#define VIDIOC_S_INPUT _IOWR ('V', 39, int)
+#define VIDIOC_G_OUTPUT _IOR ('V', 46, int)
+#define VIDIOC_S_OUTPUT _IOWR ('V', 47, int)
+#define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output)
+#define VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout)
+#define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout)
+#define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator)
+#define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator)
+#define VIDIOC_G_FREQUENCY _IOWR ('V', 56, struct v4l2_frequency)
+#define VIDIOC_S_FREQUENCY _IOW ('V', 57, struct v4l2_frequency)
+#define VIDIOC_CROPCAP _IOWR ('V', 58, struct v4l2_cropcap)
+#define VIDIOC_G_CROP _IOWR ('V', 59, struct v4l2_crop)
+#define VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop)
+#define VIDIOC_G_JPEGCOMP _IOR ('V', 61, struct v4l2_jpegcompression)
+#define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression)
+#define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id)
+#define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format)
+#define VIDIOC_ENUMAUDIO _IOWR ('V', 65, struct v4l2_audio)
+#define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout)
+#define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority)
+#define VIDIOC_S_PRIORITY _IOW ('V', 68, enum v4l2_priority)
+#define VIDIOC_G_SLICED_VBI_CAP _IOR ('V', 69, struct v4l2_sliced_vbi_cap)
+#define VIDIOC_LOG_STATUS _IO ('V', 70)
+#define VIDIOC_G_EXT_CTRLS _IOWR ('V', 71, struct v4l2_ext_controls)
+#define VIDIOC_S_EXT_CTRLS _IOWR ('V', 72, struct v4l2_ext_controls)
+#define VIDIOC_TRY_EXT_CTRLS _IOWR ('V', 73, struct v4l2_ext_controls)
+
+#ifdef __OLD_VIDIOC_
+
+#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int)
+#define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm)
+#define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control)
+#define VIDIOC_G_AUDIO_OLD _IOWR ('V', 33, struct v4l2_audio)
+#define VIDIOC_G_AUDOUT_OLD _IOWR ('V', 49, struct v4l2_audioout)
+#define VIDIOC_CROPCAP_OLD _IOR ('V', 58, struct v4l2_cropcap)
+#endif
+
+#define BASE_VIDIOC_PRIVATE 192  
+
+#endif
+
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/vmalloc.h b/ndk/build/platforms/android-1.5/common/include/linux/vmalloc.h
new file mode 100644
index 0000000..c7fd103
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/vmalloc.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_VMALLOC_H
+#define _LINUX_VMALLOC_H
+
+#include <linux/spinlock.h>
+#include <asm/page.h>  
+
+struct vm_area_struct;
+
+#define VM_IOREMAP 0x00000001  
+#define VM_ALLOC 0x00000002  
+#define VM_MAP 0x00000004  
+#define VM_USERMAP 0x00000008  
+#define VM_VPAGES 0x00000010  
+
+#ifndef IOREMAP_MAX_ORDER
+#define IOREMAP_MAX_ORDER (7 + PAGE_SHIFT)  
+#endif
+
+struct vm_struct {
+ void *addr;
+ unsigned long size;
+ unsigned long flags;
+ struct page **pages;
+ unsigned int nr_pages;
+ unsigned long phys_addr;
+ struct vm_struct *next;
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/vt.h b/ndk/build/platforms/android-1.5/common/include/linux/vt.h
new file mode 100644
index 0000000..9992b3a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/vt.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_VT_H
+#define _LINUX_VT_H
+
+#define MIN_NR_CONSOLES 1  
+#define MAX_NR_CONSOLES 63  
+#define MAX_NR_USER_CONSOLES 63  
+
+#define VT_OPENQRY 0x5600  
+
+struct vt_mode {
+ char mode;
+ char waitv;
+ short relsig;
+ short acqsig;
+ short frsig;
+};
+#define VT_GETMODE 0x5601  
+#define VT_SETMODE 0x5602  
+#define VT_AUTO 0x00  
+#define VT_PROCESS 0x01  
+#define VT_ACKACQ 0x02  
+
+struct vt_stat {
+ unsigned short v_active;
+ unsigned short v_signal;
+ unsigned short v_state;
+};
+#define VT_GETSTATE 0x5603  
+#define VT_SENDSIG 0x5604  
+
+#define VT_RELDISP 0x5605  
+
+#define VT_ACTIVATE 0x5606  
+#define VT_WAITACTIVE 0x5607  
+#define VT_DISALLOCATE 0x5608  
+
+struct vt_sizes {
+ unsigned short v_rows;
+ unsigned short v_cols;
+ unsigned short v_scrollsize;
+};
+#define VT_RESIZE 0x5609  
+
+struct vt_consize {
+ unsigned short v_rows;
+ unsigned short v_cols;
+ unsigned short v_vlin;
+ unsigned short v_clin;
+ unsigned short v_vcol;
+ unsigned short v_ccol;
+};
+#define VT_RESIZEX 0x560A  
+#define VT_LOCKSWITCH 0x560B  
+#define VT_UNLOCKSWITCH 0x560C  
+#define VT_GETHIFONTMASK 0x560D  
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/vt_buffer.h b/ndk/build/platforms/android-1.5/common/include/linux/vt_buffer.h
new file mode 100644
index 0000000..46ce79d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/vt_buffer.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_VT_BUFFER_H_
+#define _LINUX_VT_BUFFER_H_
+
+#ifndef VT_BUF_HAVE_RW
+#define scr_writew(val, addr) (*(addr) = (val))
+#define scr_readw(addr) (*(addr))
+#define scr_memcpyw(d, s, c) memcpy(d, s, c)
+#define scr_memmovew(d, s, c) memmove(d, s, c)
+#define VT_BUF_HAVE_MEMCPYW
+#define VT_BUF_HAVE_MEMMOVEW
+#endif
+
+#ifndef VT_BUF_HAVE_MEMSETW
+#endif
+#ifndef VT_BUF_HAVE_MEMCPYW
+#endif
+#ifndef VT_BUF_HAVE_MEMMOVEW
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/wait.h b/ndk/build/platforms/android-1.5/common/include/linux/wait.h
new file mode 100644
index 0000000..7d9aa68
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/wait.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_WAIT_H
+#define _LINUX_WAIT_H
+
+#define WNOHANG 0x00000001
+#define WUNTRACED 0x00000002
+#define WSTOPPED WUNTRACED
+#define WEXITED 0x00000004
+#define WCONTINUED 0x00000008
+#define WNOWAIT 0x01000000  
+
+#define __WNOTHREAD 0x20000000  
+#define __WALL 0x40000000  
+#define __WCLONE 0x80000000  
+
+#define P_ALL 0
+#define P_PID 1
+#define P_PGID 2
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/wanrouter.h b/ndk/build/platforms/android-1.5/common/include/linux/wanrouter.h
new file mode 100644
index 0000000..8f25a86
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/wanrouter.h
@@ -0,0 +1,356 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ROUTER_H
+#define _ROUTER_H
+
+#define ROUTER_NAME "wanrouter"  
+#define ROUTER_VERSION 1  
+#define ROUTER_RELEASE 1  
+#define ROUTER_IOCTL 'W'  
+#define ROUTER_MAGIC 0x524D4157L  
+
+enum router_ioctls
+{
+ ROUTER_SETUP = ROUTER_IOCTL<<8,
+ ROUTER_DOWN,
+ ROUTER_STAT,
+ ROUTER_IFNEW,
+ ROUTER_IFDEL,
+ ROUTER_IFSTAT,
+ ROUTER_USER = (ROUTER_IOCTL<<8)+16,
+ ROUTER_USER_MAX = (ROUTER_IOCTL<<8)+31
+};
+
+#define PROC_DATA_PORT_0 0x8000  
+#define PROC_DATA_PORT_1 0x8001  
+
+#define NLPID_IP 0xCC  
+#define NLPID_SNAP 0x80  
+#define NLPID_CLNP 0x81  
+#define NLPID_ESIS 0x82  
+#define NLPID_ISIS 0x83  
+#define NLPID_Q933 0x08  
+
+#define WAN_IFNAME_SZ 15  
+#define WAN_DRVNAME_SZ 15  
+#define WAN_ADDRESS_SZ 31  
+#define USED_BY_FIELD 8  
+
+#define UDP_PTPIPE_TYPE 0x01
+#define UDP_FPIPE_TYPE 0x02
+#define UDP_CPIPE_TYPE 0x03
+#define UDP_DRVSTATS_TYPE 0x04
+#define UDP_INVALID_TYPE 0x05
+
+#define CMD_OK 0  
+#define CMD_TIMEOUT 0xFF  
+
+#define UDP_PKT_FRM_STACK 0x00
+#define UDP_PKT_FRM_NETWORK 0x01
+
+#define MAX_INTR_TEST_COUNTER 100
+
+#define CRITICAL_IN_ISR 0xA1
+#define CRITICAL_INTR_HANDLED 0xB1
+
+typedef struct wan_x25_conf
+{
+ unsigned lo_pvc;
+ unsigned hi_pvc;
+ unsigned lo_svc;
+ unsigned hi_svc;
+ unsigned hdlc_window;
+ unsigned pkt_window;
+ unsigned t1;
+ unsigned t2;
+ unsigned t4;
+ unsigned n2;
+ unsigned t10_t20;
+ unsigned t11_t21;
+ unsigned t12_t22;
+ unsigned t13_t23;
+ unsigned t16_t26;
+ unsigned t28;
+ unsigned r10_r20;
+ unsigned r12_r22;
+ unsigned r13_r23;
+ unsigned ccitt_compat;
+ unsigned x25_conf_opt;
+ unsigned char LAPB_hdlc_only;
+ unsigned char logging;
+ unsigned char oob_on_modem;
+} wan_x25_conf_t;
+
+typedef struct wan_fr_conf
+{
+ unsigned signalling;
+ unsigned t391;
+ unsigned t392;
+ unsigned n391;
+ unsigned n392;
+ unsigned n393;
+ unsigned dlci_num;
+ unsigned dlci[100];
+} wan_fr_conf_t;
+
+typedef struct wan_ppp_conf
+{
+ unsigned restart_tmr;
+ unsigned auth_rsrt_tmr;
+ unsigned auth_wait_tmr;
+ unsigned mdm_fail_tmr;
+ unsigned dtr_drop_tmr;
+ unsigned connect_tmout;
+ unsigned conf_retry;
+ unsigned term_retry;
+ unsigned fail_retry;
+ unsigned auth_retry;
+ unsigned auth_options;
+ unsigned ip_options;
+ char authenticator;
+ char ip_mode;
+} wan_ppp_conf_t;
+
+typedef struct wan_chdlc_conf
+{
+ unsigned char ignore_dcd;
+ unsigned char ignore_cts;
+ unsigned char ignore_keepalive;
+ unsigned char hdlc_streaming;
+ unsigned char receive_only;
+ unsigned keepalive_tx_tmr;
+ unsigned keepalive_rx_tmr;
+ unsigned keepalive_err_margin;
+ unsigned slarp_timer;
+} wan_chdlc_conf_t;
+
+typedef struct wandev_conf
+{
+ unsigned magic;
+ unsigned config_id;
+
+ unsigned ioport;
+ unsigned long maddr;
+ unsigned msize;
+ int irq;
+ int dma;
+ char S514_CPU_no[1];
+ unsigned PCI_slot_no;
+ char auto_pci_cfg;
+ char comm_port;
+ unsigned bps;
+ unsigned mtu;
+ unsigned udp_port;
+ unsigned char ttl;
+ unsigned char ft1;
+ char interface;
+ char clocking;
+ char line_coding;
+ char station;
+ char connection;
+ char read_mode;
+ char receive_only;
+ char tty;
+ unsigned tty_major;
+ unsigned tty_minor;
+ unsigned tty_mode;
+ char backup;
+ unsigned hw_opt[4];
+ unsigned reserved[4];
+
+ unsigned data_size;
+ void* data;
+ union
+ {
+ wan_x25_conf_t x25;
+ wan_ppp_conf_t ppp;
+ wan_fr_conf_t fr;
+ wan_chdlc_conf_t chdlc;
+ } u;
+} wandev_conf_t;
+
+#define WANCONFIG_X25 101  
+#define WANCONFIG_FR 102  
+#define WANCONFIG_PPP 103  
+#define WANCONFIG_CHDLC 104  
+#define WANCONFIG_BSC 105  
+#define WANCONFIG_HDLC 106  
+#define WANCONFIG_MPPP 107  
+
+#define WANOPT_OFF 0
+#define WANOPT_ON 1
+#define WANOPT_NO 0
+#define WANOPT_YES 1
+
+#define WANOPT_RS232 0
+#define WANOPT_V35 1
+
+#define WANOPT_NRZ 0
+#define WANOPT_NRZI 1
+#define WANOPT_FM0 2
+#define WANOPT_FM1 3
+
+#define WANOPT_POINTTOPOINT 0  
+#define WANOPT_MULTIDROP 1  
+
+#define WANOPT_EXTERNAL 0
+#define WANOPT_INTERNAL 1
+
+#define WANOPT_DTE 0
+#define WANOPT_DCE 1
+#define WANOPT_CPE 0
+#define WANOPT_NODE 1
+#define WANOPT_SECONDARY 0
+#define WANOPT_PRIMARY 1
+
+#define WANOPT_PERMANENT 0  
+#define WANOPT_SWITCHED 1  
+#define WANOPT_ONDEMAND 2  
+
+#define WANOPT_FR_ANSI 1  
+#define WANOPT_FR_Q933 2  
+#define WANOPT_FR_LMI 3  
+
+#define WANOPT_PPP_STATIC 0
+#define WANOPT_PPP_HOST 1
+#define WANOPT_PPP_PEER 2
+
+#define WANOPT_ONE 1
+#define WANOPT_TWO 2
+#define WANOPT_ONE_AND_HALF 3
+
+#define WANOPT_NONE 0
+#define WANOPT_ODD 1
+#define WANOPT_EVEN 2
+
+#define WANOPT_PRI 0
+#define WANOPT_SEC 1
+
+#define WANOPT_INTR 0
+#define WANOPT_POLL 1
+
+#define WANOPT_TTY_SYNC 0
+#define WANOPT_TTY_ASYNC 1
+
+typedef struct wandev_stat
+{
+ unsigned state;
+ unsigned ndev;
+
+ unsigned connection;
+ unsigned media_type;
+ unsigned mtu;
+
+ unsigned modem_status;
+ unsigned rx_frames;
+ unsigned rx_overruns;
+ unsigned rx_crc_err;
+ unsigned rx_aborts;
+ unsigned rx_bad_length;
+ unsigned rx_dropped;
+ unsigned tx_frames;
+ unsigned tx_underruns;
+ unsigned tx_timeouts;
+ unsigned tx_rejects;
+
+ unsigned rx_bad_format;
+ unsigned rx_bad_addr;
+ unsigned tx_retries;
+ unsigned reserved[16];
+} wandev_stat_t;
+
+enum wan_states
+{
+ WAN_UNCONFIGURED,
+ WAN_DISCONNECTED,
+ WAN_CONNECTING,
+ WAN_CONNECTED,
+ WAN_LIMIT,
+ WAN_DUALPORT,
+ WAN_DISCONNECTING,
+ WAN_FT1_READY
+};
+
+enum {
+ WAN_LOCAL_IP,
+ WAN_POINTOPOINT_IP,
+ WAN_NETMASK_IP,
+ WAN_BROADCAST_IP
+};
+
+#define WAN_MODEM_CTS 0x0001  
+#define WAN_MODEM_DCD 0x0002  
+#define WAN_MODEM_DTR 0x0010  
+#define WAN_MODEM_RTS 0x0020  
+
+typedef struct wanif_conf
+{
+ unsigned magic;
+ unsigned config_id;
+ char name[WAN_IFNAME_SZ+1];
+ char addr[WAN_ADDRESS_SZ+1];
+ char usedby[USED_BY_FIELD];
+ unsigned idle_timeout;
+ unsigned hold_timeout;
+ unsigned cir;
+ unsigned bc;
+ unsigned be;
+ unsigned char enable_IPX;
+ unsigned char inarp;
+ unsigned inarp_interval;
+ unsigned long network_number;
+ char mc;
+ char local_addr[WAN_ADDRESS_SZ+1];
+ unsigned char port;
+ unsigned char protocol;
+ char pap;
+ char chap;
+ unsigned char userid[511];
+ unsigned char passwd[511];
+ unsigned char sysname[31];
+ unsigned char ignore_dcd;
+ unsigned char ignore_cts;
+ unsigned char ignore_keepalive;
+ unsigned char hdlc_streaming;
+ unsigned keepalive_tx_tmr;
+ unsigned keepalive_rx_tmr;
+ unsigned keepalive_err_margin;
+ unsigned slarp_timer;
+ unsigned char ttl;
+ char interface;
+ char clocking;
+ unsigned bps;
+ unsigned mtu;
+ unsigned char if_down;
+ unsigned char gateway;
+ unsigned char true_if_encoding;
+
+ unsigned char asy_data_trans;
+ unsigned char rts_hs_for_receive;
+ unsigned char xon_xoff_hs_for_receive;
+ unsigned char xon_xoff_hs_for_transmit;
+ unsigned char dcd_hs_for_transmit;
+ unsigned char cts_hs_for_transmit;
+ unsigned char async_mode;
+ unsigned tx_bits_per_char;
+ unsigned rx_bits_per_char;
+ unsigned stop_bits;
+ unsigned char parity;
+ unsigned break_timer;
+ unsigned inter_char_timer;
+ unsigned rx_complete_length;
+ unsigned xon_char;
+ unsigned xoff_char;
+ unsigned char receive_only;
+} wanif_conf_t;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/wireless.h b/ndk/build/platforms/android-1.5/common/include/linux/wireless.h
new file mode 100644
index 0000000..81ceb75
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/wireless.h
@@ -0,0 +1,542 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_WIRELESS_H
+#define _LINUX_WIRELESS_H
+
+#include <linux/types.h>  
+#include <linux/socket.h>  
+#include <linux/if.h>  
+
+#define WIRELESS_EXT 20
+
+#define SIOCSIWCOMMIT 0x8B00  
+#define SIOCGIWNAME 0x8B01  
+
+#define SIOCSIWNWID 0x8B02  
+#define SIOCGIWNWID 0x8B03  
+#define SIOCSIWFREQ 0x8B04  
+#define SIOCGIWFREQ 0x8B05  
+#define SIOCSIWMODE 0x8B06  
+#define SIOCGIWMODE 0x8B07  
+#define SIOCSIWSENS 0x8B08  
+#define SIOCGIWSENS 0x8B09  
+
+#define SIOCSIWRANGE 0x8B0A  
+#define SIOCGIWRANGE 0x8B0B  
+#define SIOCSIWPRIV 0x8B0C  
+#define SIOCGIWPRIV 0x8B0D  
+#define SIOCSIWSTATS 0x8B0E  
+#define SIOCGIWSTATS 0x8B0F  
+
+#define SIOCSIWSPY 0x8B10  
+#define SIOCGIWSPY 0x8B11  
+#define SIOCSIWTHRSPY 0x8B12  
+#define SIOCGIWTHRSPY 0x8B13  
+
+#define SIOCSIWAP 0x8B14  
+#define SIOCGIWAP 0x8B15  
+#define SIOCGIWAPLIST 0x8B17  
+#define SIOCSIWSCAN 0x8B18  
+#define SIOCGIWSCAN 0x8B19  
+
+#define SIOCSIWESSID 0x8B1A  
+#define SIOCGIWESSID 0x8B1B  
+#define SIOCSIWNICKN 0x8B1C  
+#define SIOCGIWNICKN 0x8B1D  
+
+#define SIOCSIWRATE 0x8B20  
+#define SIOCGIWRATE 0x8B21  
+#define SIOCSIWRTS 0x8B22  
+#define SIOCGIWRTS 0x8B23  
+#define SIOCSIWFRAG 0x8B24  
+#define SIOCGIWFRAG 0x8B25  
+#define SIOCSIWTXPOW 0x8B26  
+#define SIOCGIWTXPOW 0x8B27  
+#define SIOCSIWRETRY 0x8B28  
+#define SIOCGIWRETRY 0x8B29  
+
+#define SIOCSIWENCODE 0x8B2A  
+#define SIOCGIWENCODE 0x8B2B  
+
+#define SIOCSIWPOWER 0x8B2C  
+#define SIOCGIWPOWER 0x8B2D  
+
+#define SIOCSIWGENIE 0x8B30  
+#define SIOCGIWGENIE 0x8B31  
+
+#define SIOCSIWMLME 0x8B16  
+
+#define SIOCSIWAUTH 0x8B32  
+#define SIOCGIWAUTH 0x8B33  
+
+#define SIOCSIWENCODEEXT 0x8B34  
+#define SIOCGIWENCODEEXT 0x8B35  
+
+#define SIOCSIWPMKSA 0x8B36  
+
+#define SIOCIWFIRSTPRIV 0x8BE0
+#define SIOCIWLASTPRIV 0x8BFF
+
+#define SIOCIWFIRST 0x8B00
+#define SIOCIWLAST SIOCIWLASTPRIV  
+#define IW_IOCTL_IDX(cmd) ((cmd) - SIOCIWFIRST)
+
+#define IW_IS_SET(cmd) (!((cmd) & 0x1))
+#define IW_IS_GET(cmd) ((cmd) & 0x1)
+
+#define IWEVTXDROP 0x8C00  
+#define IWEVQUAL 0x8C01  
+#define IWEVCUSTOM 0x8C02  
+#define IWEVREGISTERED 0x8C03  
+#define IWEVEXPIRED 0x8C04  
+#define IWEVGENIE 0x8C05  
+#define IWEVMICHAELMICFAILURE 0x8C06  
+#define IWEVASSOCREQIE 0x8C07  
+#define IWEVASSOCRESPIE 0x8C08  
+#define IWEVPMKIDCAND 0x8C09  
+
+#define IWEVFIRST 0x8C00
+#define IW_EVENT_IDX(cmd) ((cmd) - IWEVFIRST)
+
+#define IW_PRIV_TYPE_MASK 0x7000  
+#define IW_PRIV_TYPE_NONE 0x0000
+#define IW_PRIV_TYPE_BYTE 0x1000  
+#define IW_PRIV_TYPE_CHAR 0x2000  
+#define IW_PRIV_TYPE_INT 0x4000  
+#define IW_PRIV_TYPE_FLOAT 0x5000  
+#define IW_PRIV_TYPE_ADDR 0x6000  
+
+#define IW_PRIV_SIZE_FIXED 0x0800  
+
+#define IW_PRIV_SIZE_MASK 0x07FF  
+
+#define IW_MAX_FREQUENCIES 32
+
+#define IW_MAX_BITRATES 32
+
+#define IW_MAX_TXPOWER 8
+
+#define IW_MAX_SPY 8
+
+#define IW_MAX_AP 64
+
+#define IW_ESSID_MAX_SIZE 32
+
+#define IW_MODE_AUTO 0  
+#define IW_MODE_ADHOC 1  
+#define IW_MODE_INFRA 2  
+#define IW_MODE_MASTER 3  
+#define IW_MODE_REPEAT 4  
+#define IW_MODE_SECOND 5  
+#define IW_MODE_MONITOR 6  
+
+#define IW_QUAL_QUAL_UPDATED 0x01  
+#define IW_QUAL_LEVEL_UPDATED 0x02
+#define IW_QUAL_NOISE_UPDATED 0x04
+#define IW_QUAL_ALL_UPDATED 0x07
+#define IW_QUAL_DBM 0x08  
+#define IW_QUAL_QUAL_INVALID 0x10  
+#define IW_QUAL_LEVEL_INVALID 0x20
+#define IW_QUAL_NOISE_INVALID 0x40
+#define IW_QUAL_ALL_INVALID 0x70
+
+#define IW_FREQ_AUTO 0x00  
+#define IW_FREQ_FIXED 0x01  
+
+#define IW_MAX_ENCODING_SIZES 8
+
+#define IW_ENCODING_TOKEN_MAX 64  
+
+#define IW_ENCODE_INDEX 0x00FF  
+#define IW_ENCODE_FLAGS 0xFF00  
+#define IW_ENCODE_MODE 0xF000  
+#define IW_ENCODE_DISABLED 0x8000  
+#define IW_ENCODE_ENABLED 0x0000  
+#define IW_ENCODE_RESTRICTED 0x4000  
+#define IW_ENCODE_OPEN 0x2000  
+#define IW_ENCODE_NOKEY 0x0800  
+#define IW_ENCODE_TEMP 0x0400  
+
+#define IW_POWER_ON 0x0000  
+#define IW_POWER_TYPE 0xF000  
+#define IW_POWER_PERIOD 0x1000  
+#define IW_POWER_TIMEOUT 0x2000  
+#define IW_POWER_MODE 0x0F00  
+#define IW_POWER_UNICAST_R 0x0100  
+#define IW_POWER_MULTICAST_R 0x0200  
+#define IW_POWER_ALL_R 0x0300  
+#define IW_POWER_FORCE_S 0x0400  
+#define IW_POWER_REPEATER 0x0800  
+#define IW_POWER_MODIFIER 0x000F  
+#define IW_POWER_MIN 0x0001  
+#define IW_POWER_MAX 0x0002  
+#define IW_POWER_RELATIVE 0x0004  
+
+#define IW_TXPOW_TYPE 0x00FF  
+#define IW_TXPOW_DBM 0x0000  
+#define IW_TXPOW_MWATT 0x0001  
+#define IW_TXPOW_RELATIVE 0x0002  
+#define IW_TXPOW_RANGE 0x1000  
+
+#define IW_RETRY_ON 0x0000  
+#define IW_RETRY_TYPE 0xF000  
+#define IW_RETRY_LIMIT 0x1000  
+#define IW_RETRY_LIFETIME 0x2000  
+#define IW_RETRY_MODIFIER 0x000F  
+#define IW_RETRY_MIN 0x0001  
+#define IW_RETRY_MAX 0x0002  
+#define IW_RETRY_RELATIVE 0x0004  
+
+#define IW_SCAN_DEFAULT 0x0000  
+#define IW_SCAN_ALL_ESSID 0x0001  
+#define IW_SCAN_THIS_ESSID 0x0002  
+#define IW_SCAN_ALL_FREQ 0x0004  
+#define IW_SCAN_THIS_FREQ 0x0008  
+#define IW_SCAN_ALL_MODE 0x0010  
+#define IW_SCAN_THIS_MODE 0x0020  
+#define IW_SCAN_ALL_RATE 0x0040  
+#define IW_SCAN_THIS_RATE 0x0080  
+
+#define IW_SCAN_TYPE_ACTIVE 0
+#define IW_SCAN_TYPE_PASSIVE 1
+
+#define IW_SCAN_MAX_DATA 4096  
+
+#define IW_CUSTOM_MAX 256  
+
+#define IW_GENERIC_IE_MAX 1024
+
+#define IW_MLME_DEAUTH 0
+#define IW_MLME_DISASSOC 1
+
+#define IW_AUTH_INDEX 0x0FFF
+#define IW_AUTH_FLAGS 0xF000
+
+#define IW_AUTH_WPA_VERSION 0
+#define IW_AUTH_CIPHER_PAIRWISE 1
+#define IW_AUTH_CIPHER_GROUP 2
+#define IW_AUTH_KEY_MGMT 3
+#define IW_AUTH_TKIP_COUNTERMEASURES 4
+#define IW_AUTH_DROP_UNENCRYPTED 5
+#define IW_AUTH_80211_AUTH_ALG 6
+#define IW_AUTH_WPA_ENABLED 7
+#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8
+#define IW_AUTH_ROAMING_CONTROL 9
+#define IW_AUTH_PRIVACY_INVOKED 10
+
+#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001
+#define IW_AUTH_WPA_VERSION_WPA 0x00000002
+#define IW_AUTH_WPA_VERSION_WPA2 0x00000004
+
+#define IW_AUTH_CIPHER_NONE 0x00000001
+#define IW_AUTH_CIPHER_WEP40 0x00000002
+#define IW_AUTH_CIPHER_TKIP 0x00000004
+#define IW_AUTH_CIPHER_CCMP 0x00000008
+#define IW_AUTH_CIPHER_WEP104 0x00000010
+
+#define IW_AUTH_KEY_MGMT_802_1X 1
+#define IW_AUTH_KEY_MGMT_PSK 2
+
+#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001
+#define IW_AUTH_ALG_SHARED_KEY 0x00000002
+#define IW_AUTH_ALG_LEAP 0x00000004
+
+#define IW_AUTH_ROAMING_ENABLE 0  
+#define IW_AUTH_ROAMING_DISABLE 1  
+
+#define IW_ENCODE_SEQ_MAX_SIZE 8
+
+#define IW_ENCODE_ALG_NONE 0
+#define IW_ENCODE_ALG_WEP 1
+#define IW_ENCODE_ALG_TKIP 2
+#define IW_ENCODE_ALG_CCMP 3
+
+#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001
+#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002
+#define IW_ENCODE_EXT_GROUP_KEY 0x00000004
+#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008
+
+#define IW_MICFAILURE_KEY_ID 0x00000003  
+#define IW_MICFAILURE_GROUP 0x00000004
+#define IW_MICFAILURE_PAIRWISE 0x00000008
+#define IW_MICFAILURE_STAKEY 0x00000010
+#define IW_MICFAILURE_COUNT 0x00000060  
+
+#define IW_ENC_CAPA_WPA 0x00000001
+#define IW_ENC_CAPA_WPA2 0x00000002
+#define IW_ENC_CAPA_CIPHER_TKIP 0x00000004
+#define IW_ENC_CAPA_CIPHER_CCMP 0x00000008
+
+#define IW_EVENT_CAPA_BASE(cmd) ((cmd >= SIOCIWFIRSTPRIV) ?   (cmd - SIOCIWFIRSTPRIV + 0x60) :   (cmd - SIOCSIWCOMMIT))
+#define IW_EVENT_CAPA_INDEX(cmd) (IW_EVENT_CAPA_BASE(cmd) >> 5)
+#define IW_EVENT_CAPA_MASK(cmd) (1 << (IW_EVENT_CAPA_BASE(cmd) & 0x1F))
+
+#define IW_EVENT_CAPA_K_0 (IW_EVENT_CAPA_MASK(0x8B04) |   IW_EVENT_CAPA_MASK(0x8B06) |   IW_EVENT_CAPA_MASK(0x8B1A))
+#define IW_EVENT_CAPA_K_1 (IW_EVENT_CAPA_MASK(0x8B2A))
+
+#define IW_EVENT_CAPA_SET(event_capa, cmd) (event_capa[IW_EVENT_CAPA_INDEX(cmd)] |= IW_EVENT_CAPA_MASK(cmd))
+#define IW_EVENT_CAPA_SET_KERNEL(event_capa) {event_capa[0] |= IW_EVENT_CAPA_K_0; event_capa[1] |= IW_EVENT_CAPA_K_1; }
+
+struct iw_param
+{
+ __s32 value;
+ __u8 fixed;
+ __u8 disabled;
+ __u16 flags;
+};
+
+struct iw_point
+{
+ void __user *pointer;
+ __u16 length;
+ __u16 flags;
+};
+
+struct iw_freq
+{
+ __s32 m;
+ __s16 e;
+ __u8 i;
+ __u8 flags;
+};
+
+struct iw_quality
+{
+ __u8 qual;
+ __u8 level;
+ __u8 noise;
+ __u8 updated;
+};
+
+struct iw_discarded
+{
+ __u32 nwid;
+ __u32 code;
+ __u32 fragment;
+ __u32 retries;
+ __u32 misc;
+};
+
+struct iw_missed
+{
+ __u32 beacon;
+};
+
+struct iw_thrspy
+{
+ struct sockaddr addr;
+ struct iw_quality qual;
+ struct iw_quality low;
+ struct iw_quality high;
+};
+
+struct iw_scan_req
+{
+ __u8 scan_type;
+ __u8 essid_len;
+ __u8 num_channels;
+ __u8 flags;
+ struct sockaddr bssid;
+
+ __u8 essid[IW_ESSID_MAX_SIZE];
+
+ __u32 min_channel_time;
+ __u32 max_channel_time;
+
+ struct iw_freq channel_list[IW_MAX_FREQUENCIES];
+};
+
+struct iw_encode_ext
+{
+ __u32 ext_flags;
+ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE];
+ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE];
+ struct sockaddr addr;
+ __u16 alg;
+ __u16 key_len;
+ __u8 key[0];
+};
+
+struct iw_mlme
+{
+ __u16 cmd;
+ __u16 reason_code;
+ struct sockaddr addr;
+};
+
+#define IW_PMKSA_ADD 1
+#define IW_PMKSA_REMOVE 2
+#define IW_PMKSA_FLUSH 3
+
+#define IW_PMKID_LEN 16
+
+struct iw_pmksa
+{
+ __u32 cmd;
+ struct sockaddr bssid;
+ __u8 pmkid[IW_PMKID_LEN];
+};
+
+struct iw_michaelmicfailure
+{
+ __u32 flags;
+ struct sockaddr src_addr;
+ __u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
+};
+
+#define IW_PMKID_CAND_PREAUTH 0x00000001  
+struct iw_pmkid_cand
+{
+ __u32 flags;
+ __u32 index;
+ struct sockaddr bssid;
+};
+
+struct iw_statistics
+{
+ __u16 status;
+
+ struct iw_quality qual;
+ struct iw_discarded discard;
+ struct iw_missed miss;
+};
+
+union iwreq_data
+{
+
+ char name[IFNAMSIZ];
+
+ struct iw_point essid;
+ struct iw_param nwid;
+ struct iw_freq freq;
+
+ struct iw_param sens;
+ struct iw_param bitrate;
+ struct iw_param txpower;
+ struct iw_param rts;
+ struct iw_param frag;
+ __u32 mode;
+ struct iw_param retry;
+
+ struct iw_point encoding;
+ struct iw_param power;
+ struct iw_quality qual;
+
+ struct sockaddr ap_addr;
+ struct sockaddr addr;
+
+ struct iw_param param;
+ struct iw_point data;
+};
+
+struct iwreq
+{
+ union
+ {
+ char ifrn_name[IFNAMSIZ];
+ } ifr_ifrn;
+
+ union iwreq_data u;
+};
+
+struct iw_range
+{
+
+ __u32 throughput;
+
+ __u32 min_nwid;
+ __u32 max_nwid;
+
+ __u16 old_num_channels;
+ __u8 old_num_frequency;
+
+ __u32 event_capa[6];
+
+ __s32 sensitivity;
+
+ struct iw_quality max_qual;
+
+ struct iw_quality avg_qual;
+
+ __u8 num_bitrates;
+ __s32 bitrate[IW_MAX_BITRATES];
+
+ __s32 min_rts;
+ __s32 max_rts;
+
+ __s32 min_frag;
+ __s32 max_frag;
+
+ __s32 min_pmp;
+ __s32 max_pmp;
+ __s32 min_pmt;
+ __s32 max_pmt;
+ __u16 pmp_flags;
+ __u16 pmt_flags;
+ __u16 pm_capa;
+
+ __u16 encoding_size[IW_MAX_ENCODING_SIZES];
+ __u8 num_encoding_sizes;
+ __u8 max_encoding_tokens;
+
+ __u8 encoding_login_index;
+
+ __u16 txpower_capa;
+ __u8 num_txpower;
+ __s32 txpower[IW_MAX_TXPOWER];
+
+ __u8 we_version_compiled;
+ __u8 we_version_source;
+
+ __u16 retry_capa;
+ __u16 retry_flags;
+ __u16 r_time_flags;
+ __s32 min_retry;
+ __s32 max_retry;
+ __s32 min_r_time;
+ __s32 max_r_time;
+
+ __u16 num_channels;
+ __u8 num_frequency;
+ struct iw_freq freq[IW_MAX_FREQUENCIES];
+
+ __u32 enc_capa;
+};
+
+struct iw_priv_args
+{
+ __u32 cmd;
+ __u16 set_args;
+ __u16 get_args;
+ char name[IFNAMSIZ];
+};
+
+struct iw_event
+{
+ __u16 len;
+ __u16 cmd;
+ union iwreq_data u;
+};
+
+#define IW_EV_LCP_LEN (sizeof(struct iw_event) - sizeof(union iwreq_data))
+
+#define IW_EV_CHAR_LEN (IW_EV_LCP_LEN + IFNAMSIZ)
+#define IW_EV_UINT_LEN (IW_EV_LCP_LEN + sizeof(__u32))
+#define IW_EV_FREQ_LEN (IW_EV_LCP_LEN + sizeof(struct iw_freq))
+#define IW_EV_PARAM_LEN (IW_EV_LCP_LEN + sizeof(struct iw_param))
+#define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr))
+#define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality))
+
+#define IW_EV_POINT_OFF (((char *) &(((struct iw_point *) NULL)->length)) -   (char *) NULL)
+#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) -   IW_EV_POINT_OFF)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/workqueue.h b/ndk/build/platforms/android-1.5/common/include/linux/workqueue.h
new file mode 100644
index 0000000..12fab2c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/workqueue.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_WORKQUEUE_H
+#define _LINUX_WORKQUEUE_H
+
+#include <linux/timer.h>
+#include <linux/linkage.h>
+#include <linux/bitops.h>
+
+struct workqueue_struct;
+
+struct work_struct {
+ unsigned long pending;
+ struct list_head entry;
+ void (*func)(void *);
+ void *data;
+ void *wq_data;
+ struct timer_list timer;
+};
+
+struct execute_work {
+ struct work_struct work;
+};
+
+#define __WORK_INITIALIZER(n, f, d) {   .entry = { &(n).entry, &(n).entry },   .func = (f),   .data = (d),   .timer = TIMER_INITIALIZER(NULL, 0, 0),   }
+
+#define DECLARE_WORK(n, f, d)   struct work_struct n = __WORK_INITIALIZER(n, f, d)
+
+#define PREPARE_WORK(_work, _func, _data)   do {   (_work)->func = _func;   (_work)->data = _data;   } while (0)
+
+#define INIT_WORK(_work, _func, _data)   do {   INIT_LIST_HEAD(&(_work)->entry);   (_work)->pending = 0;   PREPARE_WORK((_work), (_func), (_data));   init_timer(&(_work)->timer);   } while (0)
+
+#define create_workqueue(name) __create_workqueue((name), 0)
+#define create_singlethread_workqueue(name) __create_workqueue((name), 1)
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/xattr.h b/ndk/build/platforms/android-1.5/common/include/linux/xattr.h
new file mode 100644
index 0000000..f5f640d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/xattr.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _LINUX_XATTR_H
+#define _LINUX_XATTR_H
+
+#define XATTR_CREATE 0x1  
+#define XATTR_REPLACE 0x2  
+
+#define XATTR_OS2_PREFIX "os2."
+#define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1)
+
+#define XATTR_SECURITY_PREFIX "security."
+#define XATTR_SECURITY_PREFIX_LEN (sizeof (XATTR_SECURITY_PREFIX) - 1)
+
+#define XATTR_SYSTEM_PREFIX "system."
+#define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1)
+
+#define XATTR_TRUSTED_PREFIX "trusted."
+#define XATTR_TRUSTED_PREFIX_LEN (sizeof (XATTR_TRUSTED_PREFIX) - 1)
+
+#define XATTR_USER_PREFIX "user."
+#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)
+
+struct xattr_handler {
+ char *prefix;
+ size_t (*list)(struct inode *inode, char *list, size_t list_size,
+ const char *name, size_t name_len);
+ int (*get)(struct inode *inode, const char *name, void *buffer,
+ size_t size);
+ int (*set)(struct inode *inode, const char *name, const void *buffer,
+ size_t size, int flags);
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/zconf.h b/ndk/build/platforms/android-1.5/common/include/linux/zconf.h
new file mode 100644
index 0000000..18ea78c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/zconf.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ZCONF_H
+#define _ZCONF_H
+
+#ifndef MAX_MEM_LEVEL
+#define MAX_MEM_LEVEL 8
+#endif
+
+#ifndef MAX_WBITS
+#define MAX_WBITS 15  
+#endif
+
+#ifndef DEF_WBITS
+#define DEF_WBITS MAX_WBITS
+#endif
+
+#if MAX_MEM_LEVEL >= 8
+#define DEF_MEM_LEVEL 8
+#else
+#define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+
+typedef unsigned char Byte;
+typedef unsigned int uInt;
+typedef unsigned long uLong;
+typedef void *voidp;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/zlib.h b/ndk/build/platforms/android-1.5/common/include/linux/zlib.h
new file mode 100644
index 0000000..052adfe
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/zlib.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+#include <linux/zconf.h>
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ Byte *next_in;
+ uInt avail_in;
+ uLong total_in;
+
+ Byte *next_out;
+ uInt avail_out;
+ uLong total_out;
+
+ char *msg;
+ struct internal_state *state;
+
+ void *workspace;
+
+ int data_type;
+ uLong adler;
+ uLong reserved;
+} z_stream;
+
+typedef z_stream *z_streamp;
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1  
+#define Z_PACKET_FLUSH 2
+#define Z_SYNC_FLUSH 3
+#define Z_FULL_FLUSH 4
+#define Z_FINISH 5
+#define Z_BLOCK 6  
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_DEFAULT_STRATEGY 0
+
+#define Z_BINARY 0
+#define Z_ASCII 1
+#define Z_UNKNOWN 2
+
+#define Z_DEFLATED 8
+
+#define zlib_deflateInit(strm, level)   zlib_deflateInit2((strm), (level), Z_DEFLATED, MAX_WBITS,   DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY)
+#define zlib_inflateInit(strm)   zlib_inflateInit2((strm), DEF_WBITS)
+
+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;};
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/linux/zorro_ids.h b/ndk/build/platforms/android-1.5/common/include/linux/zorro_ids.h
new file mode 100644
index 0000000..e6b1d48
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/linux/zorro_ids.h
@@ -0,0 +1,549 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#define ZORRO_MANUF_PACIFIC_PERIPHERALS 0x00D3
+#define ZORRO_PROD_PACIFIC_PERIPHERALS_SE_2000_A500 ZORRO_ID(PACIFIC_PERIPHERALS, 0x00, 0)
+#define ZORRO_PROD_PACIFIC_PERIPHERALS_SCSI ZORRO_ID(PACIFIC_PERIPHERALS, 0x0A, 0)
+
+#define ZORRO_MANUF_MACROSYSTEMS_USA_2 0x0100
+#define ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE ZORRO_ID(MACROSYSTEMS_USA_2, 0x13, 0)
+
+#define ZORRO_MANUF_KUPKE_1 0x00DD
+#define ZORRO_PROD_KUPKE_GOLEM_RAM_BOX_2MB ZORRO_ID(KUPKE_1, 0x00, 0)
+
+#define ZORRO_MANUF_MEMPHIS 0x0100
+#define ZORRO_PROD_MEMPHIS_STORMBRINGER ZORRO_ID(MEMPHIS, 0x00, 0)
+
+#define ZORRO_MANUF_3_STATE 0x0200
+#define ZORRO_PROD_3_STATE_MEGAMIX_2000 ZORRO_ID(3_STATE, 0x02, 0)
+
+#define ZORRO_MANUF_COMMODORE_BRAUNSCHWEIG 0x0201
+#define ZORRO_PROD_CBM_A2088_A2286 ZORRO_ID(COMMODORE_BRAUNSCHWEIG, 0x01, 0)
+#define ZORRO_PROD_CBM_A2286 ZORRO_ID(COMMODORE_BRAUNSCHWEIG, 0x02, 0)
+#define ZORRO_PROD_CBM_A4091_1 ZORRO_ID(COMMODORE_BRAUNSCHWEIG, 0x54, 0)
+#define ZORRO_PROD_CBM_A2386SX_1 ZORRO_ID(COMMODORE_BRAUNSCHWEIG, 0x67, 0)
+
+#define ZORRO_MANUF_COMMODORE_WEST_CHESTER_1 0x0202
+#define ZORRO_PROD_CBM_A2090A ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x01, 0)
+#define ZORRO_PROD_CBM_A590_A2091_1 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x02, 0)
+#define ZORRO_PROD_CBM_A590_A2091_2 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x03, 0)
+#define ZORRO_PROD_CBM_A2090B ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x04, 0)
+#define ZORRO_PROD_CBM_A2060 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x09, 0)
+#define ZORRO_PROD_CBM_A590_A2052_A2058_A2091 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x0A, 0)
+#define ZORRO_PROD_CBM_A560_RAM ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x20, 0)
+#define ZORRO_PROD_CBM_A2232_PROTOTYPE ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x45, 0)
+#define ZORRO_PROD_CBM_A2232 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x46, 0)
+#define ZORRO_PROD_CBM_A2620 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x50, 0)
+#define ZORRO_PROD_CBM_A2630 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x51, 0)
+#define ZORRO_PROD_CBM_A4091_2 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x54, 0)
+#define ZORRO_PROD_CBM_A2065_1 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x5A, 0)
+#define ZORRO_PROD_CBM_ROMULATOR ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x60, 0)
+#define ZORRO_PROD_CBM_A3000_TEST_FIXTURE ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x61, 0)
+#define ZORRO_PROD_CBM_A2386SX_2 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x67, 0)
+#define ZORRO_PROD_CBM_A2065_2 ZORRO_ID(COMMODORE_WEST_CHESTER_1, 0x70, 0)
+
+#define ZORRO_MANUF_COMMODORE_WEST_CHESTER_2 0x0203
+#define ZORRO_PROD_CBM_A2090A_CM ZORRO_ID(COMMODORE_WEST_CHESTER_2, 0x03, 0)
+
+#define ZORRO_MANUF_PROGRESSIVE_PERIPHERALS_AND_SYSTEMS_2 0x02F4
+#define ZORRO_PROD_PPS_EXP8000 ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS_2, 0x02, 0)
+
+#define ZORRO_MANUF_KOLFF_COMPUTER_SUPPLIES 0x02FF
+#define ZORRO_PROD_KCS_POWER_PC_BOARD ZORRO_ID(KOLFF_COMPUTER_SUPPLIES, 0x00, 0)
+
+#define ZORRO_MANUF_CARDCO_1 0x03EC
+#define ZORRO_PROD_CARDCO_KRONOS_2000_1 ZORRO_ID(CARDCO_1, 0x04, 0)
+#define ZORRO_PROD_CARDCO_A1000_1 ZORRO_ID(CARDCO_1, 0x0C, 0)
+#define ZORRO_PROD_CARDCO_ESCORT ZORRO_ID(CARDCO_1, 0x0E, 0)
+#define ZORRO_PROD_CARDCO_A2410 ZORRO_ID(CARDCO_1, 0xF5, 0)
+
+#define ZORRO_MANUF_A_SQUARED 0x03ED
+#define ZORRO_PROD_A_SQUARED_LIVE_2000 ZORRO_ID(A_SQUARED, 0x01, 0)
+
+#define ZORRO_MANUF_COMSPEC_COMMUNICATIONS 0x03EE
+#define ZORRO_PROD_COMSPEC_COMMUNICATIONS_AX2000 ZORRO_ID(COMSPEC_COMMUNICATIONS, 0x01, 0)
+
+#define ZORRO_MANUF_ANAKIN_RESEARCH 0x03F1
+#define ZORRO_PROD_ANAKIN_RESEARCH_EASYL ZORRO_ID(ANAKIN_RESEARCH, 0x01, 0)
+
+#define ZORRO_MANUF_MICROBOTICS 0x03F2
+#define ZORRO_PROD_MICROBOTICS_STARBOARD_II ZORRO_ID(MICROBOTICS, 0x00, 0)
+#define ZORRO_PROD_MICROBOTICS_STARDRIVE ZORRO_ID(MICROBOTICS, 0x02, 0)
+#define ZORRO_PROD_MICROBOTICS_8_UP_A ZORRO_ID(MICROBOTICS, 0x03, 0)
+#define ZORRO_PROD_MICROBOTICS_8_UP_Z ZORRO_ID(MICROBOTICS, 0x04, 0)
+#define ZORRO_PROD_MICROBOTICS_DELTA_RAM ZORRO_ID(MICROBOTICS, 0x20, 0)
+#define ZORRO_PROD_MICROBOTICS_8_STAR_RAM ZORRO_ID(MICROBOTICS, 0x40, 0)
+#define ZORRO_PROD_MICROBOTICS_8_STAR ZORRO_ID(MICROBOTICS, 0x41, 0)
+#define ZORRO_PROD_MICROBOTICS_VXL_RAM_32 ZORRO_ID(MICROBOTICS, 0x44, 0)
+#define ZORRO_PROD_MICROBOTICS_VXL_68030 ZORRO_ID(MICROBOTICS, 0x45, 0)
+#define ZORRO_PROD_MICROBOTICS_DELTA ZORRO_ID(MICROBOTICS, 0x60, 0)
+#define ZORRO_PROD_MICROBOTICS_MBX_1200_1200Z_RAM ZORRO_ID(MICROBOTICS, 0x81, 0)
+#define ZORRO_PROD_MICROBOTICS_HARDFRAME_2000_1 ZORRO_ID(MICROBOTICS, 0x96, 0)
+#define ZORRO_PROD_MICROBOTICS_HARDFRAME_2000_2 ZORRO_ID(MICROBOTICS, 0x9E, 0)
+#define ZORRO_PROD_MICROBOTICS_MBX_1200_1200Z ZORRO_ID(MICROBOTICS, 0xC1, 0)
+
+#define ZORRO_MANUF_ACCESS_ASSOCIATES_ALEGRA 0x03F4
+
+#define ZORRO_MANUF_EXPANSION_TECHNOLOGIES 0x03F6
+
+#define ZORRO_MANUF_ASDG 0x03FF
+#define ZORRO_PROD_ASDG_MEMORY_1 ZORRO_ID(ASDG, 0x01, 0)
+#define ZORRO_PROD_ASDG_MEMORY_2 ZORRO_ID(ASDG, 0x02, 0)
+#define ZORRO_PROD_ASDG_EB920_LAN_ROVER ZORRO_ID(ASDG, 0xFE, 0)
+#define ZORRO_PROD_ASDG_GPIB_DUALIEEE488_TWIN_X ZORRO_ID(ASDG, 0xFF, 0)
+
+#define ZORRO_MANUF_IMTRONICS_1 0x0404
+#define ZORRO_PROD_IMTRONICS_HURRICANE_2800_1 ZORRO_ID(IMTRONICS_1, 0x39, 0)
+#define ZORRO_PROD_IMTRONICS_HURRICANE_2800_2 ZORRO_ID(IMTRONICS_1, 0x57, 0)
+
+#define ZORRO_MANUF_CBM_UNIVERSITY_OF_LOWELL 0x0406
+#define ZORRO_PROD_CBM_A2410 ZORRO_ID(CBM_UNIVERSITY_OF_LOWELL, 0x00, 0)
+
+#define ZORRO_MANUF_AMERISTAR 0x041D
+#define ZORRO_PROD_AMERISTAR_A2065 ZORRO_ID(AMERISTAR, 0x01, 0)
+#define ZORRO_PROD_AMERISTAR_A560 ZORRO_ID(AMERISTAR, 0x09, 0)
+#define ZORRO_PROD_AMERISTAR_A4066 ZORRO_ID(AMERISTAR, 0x0A, 0)
+
+#define ZORRO_MANUF_SUPRA 0x0420
+#define ZORRO_PROD_SUPRA_SUPRADRIVE_4x4 ZORRO_ID(SUPRA, 0x01, 0)
+#define ZORRO_PROD_SUPRA_1000_RAM ZORRO_ID(SUPRA, 0x02, 0)
+#define ZORRO_PROD_SUPRA_2000_DMA ZORRO_ID(SUPRA, 0x03, 0)
+#define ZORRO_PROD_SUPRA_500 ZORRO_ID(SUPRA, 0x05, 0)
+#define ZORRO_PROD_SUPRA_500_SCSI ZORRO_ID(SUPRA, 0x08, 0)
+#define ZORRO_PROD_SUPRA_500XP_2000_RAM ZORRO_ID(SUPRA, 0x09, 0)
+#define ZORRO_PROD_SUPRA_500RX_2000_RAM ZORRO_ID(SUPRA, 0x0A, 0)
+#define ZORRO_PROD_SUPRA_2400ZI ZORRO_ID(SUPRA, 0x0B, 0)
+#define ZORRO_PROD_SUPRA_500XP_SUPRADRIVE_WORDSYNC ZORRO_ID(SUPRA, 0x0C, 0)
+#define ZORRO_PROD_SUPRA_SUPRADRIVE_WORDSYNC_II ZORRO_ID(SUPRA, 0x0D, 0)
+#define ZORRO_PROD_SUPRA_2400ZIPLUS ZORRO_ID(SUPRA, 0x10, 0)
+
+#define ZORRO_MANUF_COMPUTER_SYSTEMS_ASSOCIATES 0x0422
+#define ZORRO_PROD_CSA_MAGNUM ZORRO_ID(COMPUTER_SYSTEMS_ASSOCIATES, 0x11, 0)
+#define ZORRO_PROD_CSA_12_GAUGE ZORRO_ID(COMPUTER_SYSTEMS_ASSOCIATES, 0x15, 0)
+
+#define ZORRO_MANUF_MARC_MICHAEL_GROTH 0x0439
+
+#define ZORRO_MANUF_M_TECH 0x0502
+#define ZORRO_PROD_MTEC_AT500_1 ZORRO_ID(M_TECH, 0x03, 0)
+
+#define ZORRO_MANUF_GREAT_VALLEY_PRODUCTS_1 0x06E1
+#define ZORRO_PROD_GVP_IMPACT_SERIES_I ZORRO_ID(GREAT_VALLEY_PRODUCTS_1, 0x08, 0)
+
+#define ZORRO_MANUF_BYTEBOX 0x07DA
+#define ZORRO_PROD_BYTEBOX_A500 ZORRO_ID(BYTEBOX, 0x00, 0)
+
+#define ZORRO_MANUF_DKB_POWER_COMPUTING 0x07DC
+#define ZORRO_PROD_DKB_POWER_COMPUTING_SECUREKEY ZORRO_ID(DKB_POWER_COMPUTING, 0x09, 0)
+#define ZORRO_PROD_DKB_POWER_COMPUTING_DKM_3128 ZORRO_ID(DKB_POWER_COMPUTING, 0x0E, 0)
+#define ZORRO_PROD_DKB_POWER_COMPUTING_RAPID_FIRE ZORRO_ID(DKB_POWER_COMPUTING, 0x0F, 0)
+#define ZORRO_PROD_DKB_POWER_COMPUTING_DKM_1202 ZORRO_ID(DKB_POWER_COMPUTING, 0x10, 0)
+#define ZORRO_PROD_DKB_POWER_COMPUTING_COBRA_VIPER_II_68EC030 ZORRO_ID(DKB_POWER_COMPUTING, 0x12, 0)
+#define ZORRO_PROD_DKB_POWER_COMPUTING_WILDFIRE_060_1 ZORRO_ID(DKB_POWER_COMPUTING, 0x17, 0)
+#define ZORRO_PROD_DKB_POWER_COMPUTING_WILDFIRE_060_2 ZORRO_ID(DKB_POWER_COMPUTING, 0xFF, 0)
+
+#define ZORRO_MANUF_GREAT_VALLEY_PRODUCTS_2 0x07E1
+#define ZORRO_PROD_GVP_IMPACT_SERIES_I_4K ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x01, 0)
+#define ZORRO_PROD_GVP_IMPACT_SERIES_I_16K_2 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x02, 0)
+#define ZORRO_PROD_GVP_IMPACT_SERIES_I_16K_3 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x03, 0)
+#define ZORRO_PROD_GVP_IMPACT_3001_IDE_1 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x08, 0)
+#define ZORRO_PROD_GVP_IMPACT_3001_RAM ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x09, 0)
+#define ZORRO_PROD_GVP_IMPACT_SERIES_II_RAM_1 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0A, 0)
+#define ZORRO_PROD_GVP_EPC_BASE ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0)
+#define ZORRO_PROD_GVP_GFORCE_040_1 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x20)
+#define ZORRO_PROD_GVP_GFORCE_040_SCSI_1 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x30)
+#define ZORRO_PROD_GVP_A1291 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x40)
+#define ZORRO_PROD_GVP_COMBO_030_R4 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x60)
+#define ZORRO_PROD_GVP_COMBO_030_R4_SCSI ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x70)
+#define ZORRO_PROD_GVP_PHONEPAK ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x78)
+#define ZORRO_PROD_GVP_IO_EXTENDER ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0x98)
+#define ZORRO_PROD_GVP_GFORCE_030 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xa0)
+#define ZORRO_PROD_GVP_GFORCE_030_SCSI ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xb0)
+#define ZORRO_PROD_GVP_A530 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xc0)
+#define ZORRO_PROD_GVP_A530_SCSI ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xd0)
+#define ZORRO_PROD_GVP_COMBO_030_R3 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xe0)
+#define ZORRO_PROD_GVP_COMBO_030_R3_SCSI ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xf0)
+#define ZORRO_PROD_GVP_SERIES_II ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0B, 0xf8)
+#define ZORRO_PROD_GVP_IMPACT_3001_IDE_2 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x0D, 0)
+
+#define ZORRO_PROD_GVP_GFORCE_040_060 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x16, 0)
+#define ZORRO_PROD_GVP_IMPACT_VISION_24 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0x20, 0)
+#define ZORRO_PROD_GVP_GFORCE_040_2 ZORRO_ID(GREAT_VALLEY_PRODUCTS_2, 0xFF, 0)
+
+#define ZORRO_MANUF_CALIFORNIA_ACCESS_SYNERGY 0x07E5
+#define ZORRO_PROD_CALIFORNIA_ACCESS_SYNERGY_MALIBU ZORRO_ID(CALIFORNIA_ACCESS_SYNERGY, 0x01, 0)
+
+#define ZORRO_MANUF_XETEC 0x07E6
+#define ZORRO_PROD_XETEC_FASTCARD ZORRO_ID(XETEC, 0x01, 0)
+#define ZORRO_PROD_XETEC_FASTCARD_RAM ZORRO_ID(XETEC, 0x02, 0)
+#define ZORRO_PROD_XETEC_FASTCARD_PLUS ZORRO_ID(XETEC, 0x03, 0)
+
+#define ZORRO_MANUF_PROGRESSIVE_PERIPHERALS_AND_SYSTEMS 0x07EA
+#define ZORRO_PROD_PPS_MERCURY ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0x00, 0)
+#define ZORRO_PROD_PPS_A3000_68040 ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0x01, 0)
+#define ZORRO_PROD_PPS_A2000_68040 ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0x69, 0)
+#define ZORRO_PROD_PPS_ZEUS ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0x96, 0)
+#define ZORRO_PROD_PPS_A500_68040 ZORRO_ID(PROGRESSIVE_PERIPHERALS_AND_SYSTEMS, 0xBB, 0)
+
+#define ZORRO_MANUF_XEBEC 0x07EC
+
+#define ZORRO_MANUF_SPIRIT_TECHNOLOGY 0x07F2
+#define ZORRO_PROD_SPIRIT_TECHNOLOGY_INSIDER_IN1000 ZORRO_ID(SPIRIT_TECHNOLOGY, 0x01, 0)
+#define ZORRO_PROD_SPIRIT_TECHNOLOGY_INSIDER_IN500 ZORRO_ID(SPIRIT_TECHNOLOGY, 0x02, 0)
+#define ZORRO_PROD_SPIRIT_TECHNOLOGY_SIN500 ZORRO_ID(SPIRIT_TECHNOLOGY, 0x03, 0)
+#define ZORRO_PROD_SPIRIT_TECHNOLOGY_HDA_506 ZORRO_ID(SPIRIT_TECHNOLOGY, 0x04, 0)
+#define ZORRO_PROD_SPIRIT_TECHNOLOGY_AX_S ZORRO_ID(SPIRIT_TECHNOLOGY, 0x05, 0)
+#define ZORRO_PROD_SPIRIT_TECHNOLOGY_OCTABYTE ZORRO_ID(SPIRIT_TECHNOLOGY, 0x06, 0)
+#define ZORRO_PROD_SPIRIT_TECHNOLOGY_INMATE ZORRO_ID(SPIRIT_TECHNOLOGY, 0x08, 0)
+
+#define ZORRO_MANUF_SPIRIT_TECHNOLOGY_2 0x07F3
+
+#define ZORRO_MANUF_BSC_ALFADATA_1 0x07FE
+#define ZORRO_PROD_BSC_ALF_3_1 ZORRO_ID(BSC_ALFADATA_1, 0x03, 0)
+
+#define ZORRO_MANUF_BSC_ALFADATA_2 0x0801
+#define ZORRO_PROD_BSC_ALF_2_1 ZORRO_ID(BSC_ALFADATA_2, 0x01, 0)
+#define ZORRO_PROD_BSC_ALF_2_2 ZORRO_ID(BSC_ALFADATA_2, 0x02, 0)
+#define ZORRO_PROD_BSC_ALF_3_2 ZORRO_ID(BSC_ALFADATA_2, 0x03, 0)
+
+#define ZORRO_MANUF_CARDCO_2 0x0802
+#define ZORRO_PROD_CARDCO_KRONOS_2000_2 ZORRO_ID(CARDCO_2, 0x04, 0)
+#define ZORRO_PROD_CARDCO_A1000_2 ZORRO_ID(CARDCO_2, 0x0C, 0)
+
+#define ZORRO_MANUF_JOCHHEIM 0x0804
+#define ZORRO_PROD_JOCHHEIM_RAM ZORRO_ID(JOCHHEIM, 0x01, 0)
+
+#define ZORRO_MANUF_CHECKPOINT_TECHNOLOGIES 0x0807
+#define ZORRO_PROD_CHECKPOINT_TECHNOLOGIES_SERIAL_SOLUTION ZORRO_ID(CHECKPOINT_TECHNOLOGIES, 0x00, 0)
+
+#define ZORRO_MANUF_EDOTRONIK 0x0810
+#define ZORRO_PROD_EDOTRONIK_IEEE_488 ZORRO_ID(EDOTRONIK, 0x01, 0)
+#define ZORRO_PROD_EDOTRONIK_8032 ZORRO_ID(EDOTRONIK, 0x02, 0)
+#define ZORRO_PROD_EDOTRONIK_MULTISERIAL ZORRO_ID(EDOTRONIK, 0x03, 0)
+#define ZORRO_PROD_EDOTRONIK_VIDEODIGITIZER ZORRO_ID(EDOTRONIK, 0x04, 0)
+#define ZORRO_PROD_EDOTRONIK_PARALLEL_IO ZORRO_ID(EDOTRONIK, 0x05, 0)
+#define ZORRO_PROD_EDOTRONIK_PIC_PROTOYPING ZORRO_ID(EDOTRONIK, 0x06, 0)
+#define ZORRO_PROD_EDOTRONIK_ADC ZORRO_ID(EDOTRONIK, 0x07, 0)
+#define ZORRO_PROD_EDOTRONIK_VME ZORRO_ID(EDOTRONIK, 0x08, 0)
+#define ZORRO_PROD_EDOTRONIK_DSP96000 ZORRO_ID(EDOTRONIK, 0x09, 0)
+
+#define ZORRO_MANUF_NES_INC 0x0813
+#define ZORRO_PROD_NES_INC_RAM ZORRO_ID(NES_INC, 0x00, 0)
+
+#define ZORRO_MANUF_ICD 0x0817
+#define ZORRO_PROD_ICD_ADVANTAGE_2000_SCSI ZORRO_ID(ICD, 0x01, 0)
+#define ZORRO_PROD_ICD_ADVANTAGE_IDE ZORRO_ID(ICD, 0x03, 0)
+#define ZORRO_PROD_ICD_ADVANTAGE_2080_RAM ZORRO_ID(ICD, 0x04, 0)
+
+#define ZORRO_MANUF_KUPKE_2 0x0819
+#define ZORRO_PROD_KUPKE_OMTI ZORRO_ID(KUPKE_2, 0x01, 0)
+#define ZORRO_PROD_KUPKE_SCSI_II ZORRO_ID(KUPKE_2, 0x02, 0)
+#define ZORRO_PROD_KUPKE_GOLEM_BOX ZORRO_ID(KUPKE_2, 0x03, 0)
+#define ZORRO_PROD_KUPKE_030_882 ZORRO_ID(KUPKE_2, 0x04, 0)
+#define ZORRO_PROD_KUPKE_SCSI_AT ZORRO_ID(KUPKE_2, 0x05, 0)
+
+#define ZORRO_MANUF_GREAT_VALLEY_PRODUCTS_3 0x081D
+#define ZORRO_PROD_GVP_A2000_RAM8 ZORRO_ID(GREAT_VALLEY_PRODUCTS_3, 0x09, 0)
+#define ZORRO_PROD_GVP_IMPACT_SERIES_II_RAM_2 ZORRO_ID(GREAT_VALLEY_PRODUCTS_3, 0x0A, 0)
+
+#define ZORRO_MANUF_INTERWORKS_NETWORK 0x081E
+
+#define ZORRO_MANUF_HARDITAL_SYNTHESIS 0x0820
+#define ZORRO_PROD_HARDITAL_SYNTHESIS_TQM_68030_68882 ZORRO_ID(HARDITAL_SYNTHESIS, 0x14, 0)
+
+#define ZORRO_MANUF_APPLIED_ENGINEERING 0x0828
+#define ZORRO_PROD_APPLIED_ENGINEERING_DL2000 ZORRO_ID(APPLIED_ENGINEERING, 0x10, 0)
+#define ZORRO_PROD_APPLIED_ENGINEERING_RAM_WORKS ZORRO_ID(APPLIED_ENGINEERING, 0xE0, 0)
+
+#define ZORRO_MANUF_BSC_ALFADATA_3 0x082C
+#define ZORRO_PROD_BSC_OKTAGON_2008 ZORRO_ID(BSC_ALFADATA_3, 0x05, 0)
+#define ZORRO_PROD_BSC_TANDEM_AT_2008_508 ZORRO_ID(BSC_ALFADATA_3, 0x06, 0)
+#define ZORRO_PROD_BSC_ALFA_RAM_1200 ZORRO_ID(BSC_ALFADATA_3, 0x07, 0)
+#define ZORRO_PROD_BSC_OKTAGON_2008_RAM ZORRO_ID(BSC_ALFADATA_3, 0x08, 0)
+#define ZORRO_PROD_BSC_MULTIFACE_I ZORRO_ID(BSC_ALFADATA_3, 0x10, 0)
+#define ZORRO_PROD_BSC_MULTIFACE_II ZORRO_ID(BSC_ALFADATA_3, 0x11, 0)
+#define ZORRO_PROD_BSC_MULTIFACE_III ZORRO_ID(BSC_ALFADATA_3, 0x12, 0)
+#define ZORRO_PROD_BSC_FRAMEMASTER_II ZORRO_ID(BSC_ALFADATA_3, 0x20, 0)
+#define ZORRO_PROD_BSC_GRAFFITI_RAM ZORRO_ID(BSC_ALFADATA_3, 0x21, 0)
+#define ZORRO_PROD_BSC_GRAFFITI_REG ZORRO_ID(BSC_ALFADATA_3, 0x22, 0)
+#define ZORRO_PROD_BSC_ISDN_MASTERCARD ZORRO_ID(BSC_ALFADATA_3, 0x40, 0)
+#define ZORRO_PROD_BSC_ISDN_MASTERCARD_II ZORRO_ID(BSC_ALFADATA_3, 0x41, 0)
+
+#define ZORRO_MANUF_PHOENIX 0x0835
+#define ZORRO_PROD_PHOENIX_ST506 ZORRO_ID(PHOENIX, 0x21, 0)
+#define ZORRO_PROD_PHOENIX_SCSI ZORRO_ID(PHOENIX, 0x22, 0)
+#define ZORRO_PROD_PHOENIX_RAM ZORRO_ID(PHOENIX, 0xBE, 0)
+
+#define ZORRO_MANUF_ADVANCED_STORAGE_SYSTEMS 0x0836
+#define ZORRO_PROD_ADVANCED_STORAGE_SYSTEMS_NEXUS ZORRO_ID(ADVANCED_STORAGE_SYSTEMS, 0x01, 0)
+#define ZORRO_PROD_ADVANCED_STORAGE_SYSTEMS_NEXUS_RAM ZORRO_ID(ADVANCED_STORAGE_SYSTEMS, 0x08, 0)
+
+#define ZORRO_MANUF_IMPULSE 0x0838
+#define ZORRO_PROD_IMPULSE_FIRECRACKER_24 ZORRO_ID(IMPULSE, 0x00, 0)
+
+#define ZORRO_MANUF_IVS 0x0840
+#define ZORRO_PROD_IVS_GRANDSLAM_PIC_2 ZORRO_ID(IVS, 0x02, 0)
+#define ZORRO_PROD_IVS_GRANDSLAM_PIC_1 ZORRO_ID(IVS, 0x04, 0)
+#define ZORRO_PROD_IVS_OVERDRIVE ZORRO_ID(IVS, 0x10, 0)
+#define ZORRO_PROD_IVS_TRUMPCARD_CLASSIC ZORRO_ID(IVS, 0x30, 0)
+#define ZORRO_PROD_IVS_TRUMPCARD_PRO_GRANDSLAM ZORRO_ID(IVS, 0x34, 0)
+#define ZORRO_PROD_IVS_META_4 ZORRO_ID(IVS, 0x40, 0)
+#define ZORRO_PROD_IVS_WAVETOOLS ZORRO_ID(IVS, 0xBF, 0)
+#define ZORRO_PROD_IVS_VECTOR_1 ZORRO_ID(IVS, 0xF3, 0)
+#define ZORRO_PROD_IVS_VECTOR_2 ZORRO_ID(IVS, 0xF4, 0)
+
+#define ZORRO_MANUF_VECTOR_1 0x0841
+#define ZORRO_PROD_VECTOR_CONNECTION_1 ZORRO_ID(VECTOR_1, 0xE3, 0)
+
+#define ZORRO_MANUF_XPERT_PRODEV 0x0845
+#define ZORRO_PROD_XPERT_PRODEV_VISIONA_RAM ZORRO_ID(XPERT_PRODEV, 0x01, 0)
+#define ZORRO_PROD_XPERT_PRODEV_VISIONA_REG ZORRO_ID(XPERT_PRODEV, 0x02, 0)
+#define ZORRO_PROD_XPERT_PRODEV_MERLIN_RAM ZORRO_ID(XPERT_PRODEV, 0x03, 0)
+#define ZORRO_PROD_XPERT_PRODEV_MERLIN_REG_1 ZORRO_ID(XPERT_PRODEV, 0x04, 0)
+#define ZORRO_PROD_XPERT_PRODEV_MERLIN_REG_2 ZORRO_ID(XPERT_PRODEV, 0xC9, 0)
+
+#define ZORRO_MANUF_HYDRA_SYSTEMS 0x0849
+#define ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET ZORRO_ID(HYDRA_SYSTEMS, 0x01, 0)
+
+#define ZORRO_MANUF_SUNRIZE_INDUSTRIES 0x084F
+#define ZORRO_PROD_SUNRIZE_INDUSTRIES_AD1012 ZORRO_ID(SUNRIZE_INDUSTRIES, 0x01, 0)
+#define ZORRO_PROD_SUNRIZE_INDUSTRIES_AD516 ZORRO_ID(SUNRIZE_INDUSTRIES, 0x02, 0)
+#define ZORRO_PROD_SUNRIZE_INDUSTRIES_DD512 ZORRO_ID(SUNRIZE_INDUSTRIES, 0x03, 0)
+
+#define ZORRO_MANUF_TRICERATOPS 0x0850
+#define ZORRO_PROD_TRICERATOPS_MULTI_IO ZORRO_ID(TRICERATOPS, 0x01, 0)
+
+#define ZORRO_MANUF_APPLIED_MAGIC 0x0851
+#define ZORRO_PROD_APPLIED_MAGIC_DMI_RESOLVER ZORRO_ID(APPLIED_MAGIC, 0x01, 0)
+#define ZORRO_PROD_APPLIED_MAGIC_DIGITAL_BROADCASTER ZORRO_ID(APPLIED_MAGIC, 0x06, 0)
+
+#define ZORRO_MANUF_GFX_BASE 0x085E
+#define ZORRO_PROD_GFX_BASE_GDA_1_VRAM ZORRO_ID(GFX_BASE, 0x00, 0)
+#define ZORRO_PROD_GFX_BASE_GDA_1 ZORRO_ID(GFX_BASE, 0x01, 0)
+
+#define ZORRO_MANUF_ROCTEC 0x0860
+#define ZORRO_PROD_ROCTEC_RH_800C ZORRO_ID(ROCTEC, 0x01, 0)
+#define ZORRO_PROD_ROCTEC_RH_800C_RAM ZORRO_ID(ROCTEC, 0x01, 0)
+
+#define ZORRO_MANUF_KATO 0x0861
+#define ZORRO_PROD_KATO_MELODY ZORRO_ID(KATO, 0x80, 0)
+
+#define ZORRO_MANUF_HELFRICH_1 0x0861
+#define ZORRO_PROD_HELFRICH_RAINBOW_II ZORRO_ID(HELFRICH_1, 0x20, 0)
+#define ZORRO_PROD_HELFRICH_RAINBOW_III ZORRO_ID(HELFRICH_1, 0x21, 0)
+
+#define ZORRO_MANUF_ATLANTIS 0x0862
+
+#define ZORRO_MANUF_PROTAR 0x0864
+
+#define ZORRO_MANUF_ACS 0x0865
+
+#define ZORRO_MANUF_SOFTWARE_RESULTS_ENTERPRISES 0x0866
+#define ZORRO_PROD_SOFTWARE_RESULTS_ENTERPRISES_GOLDEN_GATE_2_BUS_PLUS ZORRO_ID(SOFTWARE_RESULTS_ENTERPRISES, 0x01, 0)
+
+#define ZORRO_MANUF_MASOBOSHI 0x086D
+#define ZORRO_PROD_MASOBOSHI_MASTER_CARD_SC201 ZORRO_ID(MASOBOSHI, 0x03, 0)
+#define ZORRO_PROD_MASOBOSHI_MASTER_CARD_MC702 ZORRO_ID(MASOBOSHI, 0x04, 0)
+#define ZORRO_PROD_MASOBOSHI_MVD_819 ZORRO_ID(MASOBOSHI, 0x07, 0)
+
+#define ZORRO_MANUF_MAINHATTAN_DATA 0x086F
+#define ZORRO_PROD_MAINHATTAN_DATA_IDE ZORRO_ID(MAINHATTAN_DATA, 0x01, 0)
+
+#define ZORRO_MANUF_VILLAGE_TRONIC 0x0877
+#define ZORRO_PROD_VILLAGE_TRONIC_DOMINO_RAM ZORRO_ID(VILLAGE_TRONIC, 0x01, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_DOMINO_REG ZORRO_ID(VILLAGE_TRONIC, 0x02, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_DOMINO_16M_PROTOTYPE ZORRO_ID(VILLAGE_TRONIC, 0x03, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM ZORRO_ID(VILLAGE_TRONIC, 0x0B, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG ZORRO_ID(VILLAGE_TRONIC, 0x0C, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_SEGMENTED_MODE ZORRO_ID(VILLAGE_TRONIC, 0x0D, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_MEM1 ZORRO_ID(VILLAGE_TRONIC, 0x15, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_MEM2 ZORRO_ID(VILLAGE_TRONIC, 0x16, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_REG ZORRO_ID(VILLAGE_TRONIC, 0x17, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3 ZORRO_ID(VILLAGE_TRONIC, 0x18, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_ARIADNE ZORRO_ID(VILLAGE_TRONIC, 0xC9, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2 ZORRO_ID(VILLAGE_TRONIC, 0xCA, 0)
+
+#define ZORRO_MANUF_UTILITIES_UNLIMITED 0x087B
+#define ZORRO_PROD_UTILITIES_UNLIMITED_EMPLANT_DELUXE ZORRO_ID(UTILITIES_UNLIMITED, 0x15, 0)
+#define ZORRO_PROD_UTILITIES_UNLIMITED_EMPLANT_DELUXE2 ZORRO_ID(UTILITIES_UNLIMITED, 0x20, 0)
+
+#define ZORRO_MANUF_AMITRIX 0x0880
+#define ZORRO_PROD_AMITRIX_MULTI_IO ZORRO_ID(AMITRIX, 0x01, 0)
+#define ZORRO_PROD_AMITRIX_CD_RAM ZORRO_ID(AMITRIX, 0x02, 0)
+
+#define ZORRO_MANUF_ARMAX 0x0885
+#define ZORRO_PROD_ARMAX_OMNIBUS ZORRO_ID(ARMAX, 0x00, 0)
+
+#define ZORRO_MANUF_ZEUS 0x088D
+#define ZORRO_PROD_ZEUS_SPIDER ZORRO_ID(ZEUS, 0x04, 0)
+
+#define ZORRO_MANUF_NEWTEK 0x088F
+#define ZORRO_PROD_NEWTEK_VIDEOTOASTER ZORRO_ID(NEWTEK, 0x00, 0)
+
+#define ZORRO_MANUF_M_TECH_GERMANY 0x0890
+#define ZORRO_PROD_MTEC_AT500_2 ZORRO_ID(M_TECH_GERMANY, 0x01, 0)
+#define ZORRO_PROD_MTEC_68030 ZORRO_ID(M_TECH_GERMANY, 0x03, 0)
+#define ZORRO_PROD_MTEC_68020I ZORRO_ID(M_TECH_GERMANY, 0x06, 0)
+#define ZORRO_PROD_MTEC_A1200_T68030_RTC ZORRO_ID(M_TECH_GERMANY, 0x20, 0)
+#define ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530 ZORRO_ID(M_TECH_GERMANY, 0x21, 0)
+#define ZORRO_PROD_MTEC_8_MB_RAM ZORRO_ID(M_TECH_GERMANY, 0x22, 0)
+#define ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE ZORRO_ID(M_TECH_GERMANY, 0x24, 0)
+
+#define ZORRO_MANUF_GREAT_VALLEY_PRODUCTS_4 0x0891
+#define ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM ZORRO_ID(GREAT_VALLEY_PRODUCTS_4, 0x01, 0)
+#define ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG ZORRO_ID(GREAT_VALLEY_PRODUCTS_4, 0x02, 0)
+
+#define ZORRO_MANUF_APOLLO_1 0x0892
+#define ZORRO_PROD_APOLLO_A1200 ZORRO_ID(APOLLO_1, 0x01, 0)
+
+#define ZORRO_MANUF_HELFRICH_2 0x0893
+#define ZORRO_PROD_HELFRICH_PICCOLO_RAM ZORRO_ID(HELFRICH_2, 0x05, 0)
+#define ZORRO_PROD_HELFRICH_PICCOLO_REG ZORRO_ID(HELFRICH_2, 0x06, 0)
+#define ZORRO_PROD_HELFRICH_PEGGY_PLUS_MPEG ZORRO_ID(HELFRICH_2, 0x07, 0)
+#define ZORRO_PROD_HELFRICH_VIDEOCRUNCHER ZORRO_ID(HELFRICH_2, 0x08, 0)
+#define ZORRO_PROD_HELFRICH_SD64_RAM ZORRO_ID(HELFRICH_2, 0x0A, 0)
+#define ZORRO_PROD_HELFRICH_SD64_REG ZORRO_ID(HELFRICH_2, 0x0B, 0)
+
+#define ZORRO_MANUF_MACROSYSTEMS_USA 0x089B
+#define ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx ZORRO_ID(MACROSYSTEMS_USA, 0x13, 0)
+
+#define ZORRO_MANUF_ELBOX_COMPUTER 0x089E
+#define ZORRO_PROD_ELBOX_COMPUTER_1200_4 ZORRO_ID(ELBOX_COMPUTER, 0x06, 0)
+
+#define ZORRO_MANUF_HARMS_PROFESSIONAL 0x0A00
+#define ZORRO_PROD_HARMS_PROFESSIONAL_030_PLUS ZORRO_ID(HARMS_PROFESSIONAL, 0x10, 0)
+#define ZORRO_PROD_HARMS_PROFESSIONAL_3500 ZORRO_ID(HARMS_PROFESSIONAL, 0xD0, 0)
+
+#define ZORRO_MANUF_MICRONIK 0x0A50
+#define ZORRO_PROD_MICRONIK_RCA_120 ZORRO_ID(MICRONIK, 0x0A, 0)
+
+#define ZORRO_MANUF_MICRONIK2 0x0F0F
+#define ZORRO_PROD_MICRONIK2_Z3I ZORRO_ID(MICRONIK2, 0x01, 0)
+
+#define ZORRO_MANUF_MEGAMICRO 0x1000
+#define ZORRO_PROD_MEGAMICRO_SCRAM_500 ZORRO_ID(MEGAMICRO, 0x03, 0)
+#define ZORRO_PROD_MEGAMICRO_SCRAM_500_RAM ZORRO_ID(MEGAMICRO, 0x04, 0)
+
+#define ZORRO_MANUF_IMTRONICS_2 0x1028
+#define ZORRO_PROD_IMTRONICS_HURRICANE_2800_3 ZORRO_ID(IMTRONICS_2, 0x39, 0)
+#define ZORRO_PROD_IMTRONICS_HURRICANE_2800_4 ZORRO_ID(IMTRONICS_2, 0x57, 0)
+
+#define ZORRO_MANUF_INDIVIDUAL_COMPUTERS 0x1212
+#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x00, 0)
+#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x17, 0)
+#define ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL ZORRO_ID(INDIVIDUAL_COMPUTERS, 0x2A, 0)
+
+#define ZORRO_MANUF_KUPKE_3 0x1248
+#define ZORRO_PROD_KUPKE_GOLEM_HD_3000 ZORRO_ID(KUPKE_3, 0x01, 0)
+
+#define ZORRO_MANUF_ITH 0x1388
+#define ZORRO_PROD_ITH_ISDN_MASTER_II ZORRO_ID(ITH, 0x01, 0)
+
+#define ZORRO_MANUF_VMC 0x1389
+#define ZORRO_PROD_VMC_ISDN_BLASTER_Z2 ZORRO_ID(VMC, 0x01, 0)
+#define ZORRO_PROD_VMC_HYPERCOM_4 ZORRO_ID(VMC, 0x02, 0)
+
+#define ZORRO_MANUF_INFORMATION 0x157C
+#define ZORRO_PROD_INFORMATION_ISDN_ENGINE_I ZORRO_ID(INFORMATION, 0x64, 0)
+
+#define ZORRO_MANUF_VORTEX 0x2017
+#define ZORRO_PROD_VORTEX_GOLDEN_GATE_80386SX ZORRO_ID(VORTEX, 0x07, 0)
+#define ZORRO_PROD_VORTEX_GOLDEN_GATE_RAM ZORRO_ID(VORTEX, 0x08, 0)
+#define ZORRO_PROD_VORTEX_GOLDEN_GATE_80486 ZORRO_ID(VORTEX, 0x09, 0)
+
+#define ZORRO_MANUF_EXPANSION_SYSTEMS 0x2062
+#define ZORRO_PROD_EXPANSION_SYSTEMS_DATAFLYER_4000SX ZORRO_ID(EXPANSION_SYSTEMS, 0x01, 0)
+#define ZORRO_PROD_EXPANSION_SYSTEMS_DATAFLYER_4000SX_RAM ZORRO_ID(EXPANSION_SYSTEMS, 0x02, 0)
+
+#define ZORRO_MANUF_READYSOFT 0x2100
+#define ZORRO_PROD_READYSOFT_AMAX_II_IV ZORRO_ID(READYSOFT, 0x01, 0)
+
+#define ZORRO_MANUF_PHASE5 0x2140
+#define ZORRO_PROD_PHASE5_BLIZZARD_RAM ZORRO_ID(PHASE5, 0x01, 0)
+#define ZORRO_PROD_PHASE5_BLIZZARD ZORRO_ID(PHASE5, 0x02, 0)
+#define ZORRO_PROD_PHASE5_BLIZZARD_1220_IV ZORRO_ID(PHASE5, 0x06, 0)
+#define ZORRO_PROD_PHASE5_FASTLANE_Z3_RAM ZORRO_ID(PHASE5, 0x0A, 0)
+#define ZORRO_PROD_PHASE5_BLIZZARD_1230_II_FASTLANE_Z3_CYBERSCSI_CYBERSTORM060 ZORRO_ID(PHASE5, 0x0B, 0)
+#define ZORRO_PROD_PHASE5_BLIZZARD_1220_CYBERSTORM ZORRO_ID(PHASE5, 0x0C, 0)
+#define ZORRO_PROD_PHASE5_BLIZZARD_1230 ZORRO_ID(PHASE5, 0x0D, 0)
+#define ZORRO_PROD_PHASE5_BLIZZARD_1230_IV_1260 ZORRO_ID(PHASE5, 0x11, 0)
+#define ZORRO_PROD_PHASE5_BLIZZARD_2060 ZORRO_ID(PHASE5, 0x18, 0)
+#define ZORRO_PROD_PHASE5_CYBERSTORM_MK_II ZORRO_ID(PHASE5, 0x19, 0)
+#define ZORRO_PROD_PHASE5_CYBERVISION64 ZORRO_ID(PHASE5, 0x22, 0)
+#define ZORRO_PROD_PHASE5_CYBERVISION64_3D_PROTOTYPE ZORRO_ID(PHASE5, 0x32, 0)
+#define ZORRO_PROD_PHASE5_CYBERVISION64_3D ZORRO_ID(PHASE5, 0x43, 0)
+#define ZORRO_PROD_PHASE5_CYBERSTORM_MK_III ZORRO_ID(PHASE5, 0x64, 0)
+#define ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS ZORRO_ID(PHASE5, 0x6e, 0)
+
+#define ZORRO_MANUF_DPS 0x2169
+#define ZORRO_PROD_DPS_PERSONAL_ANIMATION_RECORDER ZORRO_ID(DPS, 0x01, 0)
+
+#define ZORRO_MANUF_APOLLO_2 0x2200
+#define ZORRO_PROD_APOLLO_A620_68020_1 ZORRO_ID(APOLLO_2, 0x00, 0)
+#define ZORRO_PROD_APOLLO_A620_68020_2 ZORRO_ID(APOLLO_2, 0x01, 0)
+
+#define ZORRO_MANUF_APOLLO_3 0x2222
+#define ZORRO_PROD_APOLLO_AT_APOLLO ZORRO_ID(APOLLO_3, 0x22, 0)
+#define ZORRO_PROD_APOLLO_1230_1240_1260_2030_4040_4060 ZORRO_ID(APOLLO_3, 0x23, 0)
+
+#define ZORRO_MANUF_PETSOFF_LP 0x38A5
+#define ZORRO_PROD_PETSOFF_LP_DELFINA ZORRO_ID(PETSOFF_LP, 0x00, 0)
+#define ZORRO_PROD_PETSOFF_LP_DELFINA_LITE ZORRO_ID(PETSOFF_LP, 0x01, 0)
+
+#define ZORRO_MANUF_UWE_GERLACH 0x3FF7
+#define ZORRO_PROD_UWE_GERLACH_RAM_ROM ZORRO_ID(UWE_GERLACH, 0xd4, 0)
+
+#define ZORRO_MANUF_ACT 0x4231
+#define ZORRO_PROD_ACT_PRELUDE ZORRO_ID(ACT, 0x01, 0)
+
+#define ZORRO_MANUF_MACROSYSTEMS_GERMANY 0x4754
+#define ZORRO_PROD_MACROSYSTEMS_MAESTRO ZORRO_ID(MACROSYSTEMS_GERMANY, 0x03, 0)
+#define ZORRO_PROD_MACROSYSTEMS_VLAB ZORRO_ID(MACROSYSTEMS_GERMANY, 0x04, 0)
+#define ZORRO_PROD_MACROSYSTEMS_MAESTRO_PRO ZORRO_ID(MACROSYSTEMS_GERMANY, 0x05, 0)
+#define ZORRO_PROD_MACROSYSTEMS_RETINA ZORRO_ID(MACROSYSTEMS_GERMANY, 0x06, 0)
+#define ZORRO_PROD_MACROSYSTEMS_MULTI_EVOLUTION ZORRO_ID(MACROSYSTEMS_GERMANY, 0x08, 0)
+#define ZORRO_PROD_MACROSYSTEMS_TOCCATA ZORRO_ID(MACROSYSTEMS_GERMANY, 0x0C, 0)
+#define ZORRO_PROD_MACROSYSTEMS_RETINA_Z3 ZORRO_ID(MACROSYSTEMS_GERMANY, 0x10, 0)
+#define ZORRO_PROD_MACROSYSTEMS_VLAB_MOTION ZORRO_ID(MACROSYSTEMS_GERMANY, 0x12, 0)
+#define ZORRO_PROD_MACROSYSTEMS_ALTAIS ZORRO_ID(MACROSYSTEMS_GERMANY, 0x13, 0)
+#define ZORRO_PROD_MACROSYSTEMS_FALCON_040 ZORRO_ID(MACROSYSTEMS_GERMANY, 0xFD, 0)
+
+#define ZORRO_MANUF_COMBITEC 0x6766
+
+#define ZORRO_MANUF_SKI_PERIPHERALS 0x8000
+#define ZORRO_PROD_SKI_PERIPHERALS_MAST_FIREBALL ZORRO_ID(SKI_PERIPHERALS, 0x08, 0)
+#define ZORRO_PROD_SKI_PERIPHERALS_SCSI_DUAL_SERIAL ZORRO_ID(SKI_PERIPHERALS, 0x80, 0)
+
+#define ZORRO_MANUF_REIS_WARE_2 0xA9AD
+#define ZORRO_PROD_REIS_WARE_SCAN_KING ZORRO_ID(REIS_WARE_2, 0x11, 0)
+
+#define ZORRO_MANUF_CAMERON 0xAA01
+#define ZORRO_PROD_CAMERON_PERSONAL_A4 ZORRO_ID(CAMERON, 0x10, 0)
+
+#define ZORRO_MANUF_REIS_WARE 0xAA11
+#define ZORRO_PROD_REIS_WARE_HANDYSCANNER ZORRO_ID(REIS_WARE, 0x11, 0)
+
+#define ZORRO_MANUF_PHOENIX_2 0xB5A8
+#define ZORRO_PROD_PHOENIX_ST506_2 ZORRO_ID(PHOENIX_2, 0x21, 0)
+#define ZORRO_PROD_PHOENIX_SCSI_2 ZORRO_ID(PHOENIX_2, 0x22, 0)
+#define ZORRO_PROD_PHOENIX_RAM_2 ZORRO_ID(PHOENIX_2, 0xBE, 0)
+
+#define ZORRO_MANUF_COMBITEC_2 0xC008
+#define ZORRO_PROD_COMBITEC_HD ZORRO_ID(COMBITEC_2, 0x2A, 0)
+#define ZORRO_PROD_COMBITEC_SRAM ZORRO_ID(COMBITEC_2, 0x2B, 0)
+
+#define ZORRO_MANUF_HACKER 0x07DB
+#define ZORRO_PROD_GENERAL_PROTOTYPE ZORRO_ID(HACKER, 0x00, 0)
+#define ZORRO_PROD_HACKER_SCSI ZORRO_ID(HACKER, 0x01, 0)
+#define ZORRO_PROD_RESOURCE_MANAGEMENT_FORCE_QUICKNET_QN2000 ZORRO_ID(HACKER, 0x02, 0)
+#define ZORRO_PROD_VECTOR_CONNECTION_2 ZORRO_ID(HACKER, 0xE0, 0)
+#define ZORRO_PROD_VECTOR_CONNECTION_3 ZORRO_ID(HACKER, 0xE1, 0)
+#define ZORRO_PROD_VECTOR_CONNECTION_4 ZORRO_ID(HACKER, 0xE2, 0)
+#define ZORRO_PROD_VECTOR_CONNECTION_5 ZORRO_ID(HACKER, 0xE3, 0)
diff --git a/ndk/build/platforms/android-1.5/common/include/locale.h b/ndk/build/platforms/android-1.5/common/include/locale.h
new file mode 100644
index 0000000..65b5c7d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/locale.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _LOCALE_H_
+#define _LOCALE_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+enum {
+    LC_CTYPE     = 0,
+    LC_NUMERIC   = 1,
+    LC_TIME      = 2,
+    LC_COLLATE   = 3,
+    LC_MONETARY  = 4,
+    LC_MESSAGES  = 5,
+    LC_ALL       = 6,
+    LC_PAPER     = 7,
+    LC_NAME      = 8,
+    LC_ADDRESS   = 9,
+
+    LC_TELEPHONE      = 10,
+    LC_MEASUREMENT    = 11,
+    LC_IDENTIFICATION = 12
+};
+
+extern char *setlocale(int category, const char *locale);
+
+/* Make libstdc++-v3 happy.  */
+struct lconv { };
+struct lconv *localeconv(void);
+
+__END_DECLS
+
+#endif /* _LOCALE_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/malloc.h b/ndk/build/platforms/android-1.5/common/include/malloc.h
new file mode 100644
index 0000000..a864286
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/malloc.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _MALLOC_H_
+#define _MALLOC_H_
+
+#include <sys/cdefs.h>
+#include <stddef.h>
+
+__BEGIN_DECLS
+
+extern __mallocfunc void*  malloc(size_t);
+extern __mallocfunc void*  calloc(size_t, size_t);
+extern __mallocfunc void*  realloc(void *, size_t);
+extern                void   free(void *);
+
+extern void*   memalign(size_t  alignment, size_t  bytesize);
+extern void*   valloc(size_t  bytesize);
+extern void*   pvalloc(size_t  bytesize);
+extern int     mallopt(int  param_number, int  param_value);
+extern size_t  malloc_footprint(void);
+extern size_t  malloc_max_footprint(void);
+
+struct mallinfo {
+    size_t arena;    /* non-mmapped space allocated from system */
+    size_t ordblks;  /* number of free chunks */
+    size_t smblks;   /* always 0 */
+    size_t hblks;    /* always 0 */
+    size_t hblkhd;   /* space in mmapped regions */
+    size_t usmblks;  /* maximum total allocated space */
+    size_t fsmblks;  /* always 0 */
+    size_t uordblks; /* total allocated space */
+    size_t fordblks; /* total free space */
+    size_t keepcost; /* releasable (via malloc_trim) space */
+};
+
+extern struct mallinfo  mallinfo(void);
+
+
+/*
+  malloc_usable_size(void* p);
+
+  Returns the number of bytes you can actually use in
+  an allocated chunk, which may be more than you requested (although
+  often not) due to alignment and minimum size constraints.
+  You can use this many bytes without worrying about
+  overwriting other allocated objects. This is not a particularly great
+  programming practice. malloc_usable_size can be more useful in
+  debugging and assertions, for example:
+
+  p = malloc(n);
+  assert(malloc_usable_size(p) >= 256);
+*/
+extern size_t malloc_usable_size(void*  block);
+
+/*
+  malloc_stats();
+  Prints on stderr the amount of space obtained from the system (both
+  via sbrk and mmap), the maximum amount (which may be more than
+  current if malloc_trim and/or munmap got called), and the current
+  number of bytes allocated via malloc (or realloc, etc) but not yet
+  freed. Note that this is the number of bytes allocated, not the
+  number requested. It will be larger than the number requested
+  because of alignment and bookkeeping overhead. Because it includes
+  alignment wastage as being in use, this figure may be greater than
+  zero even when no user-level chunks are allocated.
+
+  The reported current and maximum system memory can be inaccurate if
+  a program makes other calls to system memory allocation functions
+  (normally sbrk) outside of malloc.
+
+  malloc_stats prints only the most commonly interesting statistics.
+  More information can be obtained by calling mallinfo.
+*/
+extern void  malloc_stats(void);
+
+__END_DECLS
+
+#endif /* _MALLOC_H_ */
+
diff --git a/ndk/build/platforms/android-1.5/common/include/math.h b/ndk/build/platforms/android-1.5/common/include/math.h
new file mode 100644
index 0000000..ef6a9e6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/math.h
@@ -0,0 +1,486 @@
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/*
+ * from: @(#)fdlibm.h 5.1 93/09/24
+ * $FreeBSD: src/lib/msun/src/math.h,v 1.61 2005/04/16 21:12:47 das Exp $
+ */
+
+#ifndef _MATH_H_
+#define	_MATH_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <limits.h>
+
+#define __pure2
+
+/*
+ * ANSI/POSIX
+ */
+extern const union __infinity_un {
+	unsigned char	__uc[8];
+	double		__ud;
+} __infinity;
+
+extern const union __nan_un {
+	unsigned char	__uc[sizeof(float)];
+	float		__uf;
+} __nan;
+
+/* #if __GNUC_PREREQ__(3, 3) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800) */
+#if 1
+#define	__MATH_BUILTIN_CONSTANTS
+#endif
+
+/* #if __GNUC_PREREQ__(3, 0) && !defined(__INTEL_COMPILER) */
+#if 1
+#define	__MATH_BUILTIN_RELOPS
+#endif
+
+/* #ifdef __MATH_BUILTIN_CONSTANTS */
+#if 1
+#define	HUGE_VAL	__builtin_huge_val()
+#else
+#define	HUGE_VAL	(__infinity.__ud)
+#endif
+
+/* #if __ISO_C_VISIBLE >= 1999 */
+#if 0
+#define	FP_ILOGB0	(-__INT_MAX)
+#define	FP_ILOGBNAN	__INT_MAX
+#else
+#define	FP_ILOGB0	(-INT_MAX)
+#define	FP_ILOGBNAN	INT_MAX
+#endif
+
+#ifdef __MATH_BUILTIN_CONSTANTS
+#define	HUGE_VALF	__builtin_huge_valf()
+#define	HUGE_VALL	__builtin_huge_vall()
+#define	INFINITY	__builtin_inf()
+#define	NAN		__builtin_nan("")
+#else
+#define	HUGE_VALF	(float)HUGE_VAL
+#define	HUGE_VALL	(long double)HUGE_VAL
+#define	INFINITY	HUGE_VALF
+#define	NAN		(__nan.__uf)
+#endif /* __MATH_BUILTIN_CONSTANTS */
+
+#define	MATH_ERRNO	1
+#define	MATH_ERREXCEPT	2
+#define	math_errhandling	MATH_ERREXCEPT
+
+/* XXX We need a <machine/math.h>. */
+#if defined(__ia64__) || defined(__sparc64__)
+#define	FP_FAST_FMA
+#endif
+#ifdef __ia64__
+#define	FP_FAST_FMAL
+#endif
+#define	FP_FAST_FMAF
+
+/* Symbolic constants to classify floating point numbers. */
+#define	FP_INFINITE	0x01
+#define	FP_NAN		0x02
+#define	FP_NORMAL	0x04
+#define	FP_SUBNORMAL	0x08
+#define	FP_ZERO		0x10
+#define	fpclassify(x) \
+    ((sizeof (x) == sizeof (float)) ? __fpclassifyf(x) \
+    : (sizeof (x) == sizeof (double)) ? __fpclassifyd(x) \
+    : __fpclassifyl(x))
+
+#define	isfinite(x)					\
+    ((sizeof (x) == sizeof (float)) ? __isfinitef(x)	\
+    : (sizeof (x) == sizeof (double)) ? __isfinite(x)	\
+    : __isfinitel(x))
+#define	isinf(x)					\
+    ((sizeof (x) == sizeof (float)) ? __isinff(x)	\
+    : (sizeof (x) == sizeof (double)) ? __isinf(x)	\
+    : __isinfl(x))
+#define	isnan(x)					\
+    ((sizeof (x) == sizeof (float)) ? isnanf(x)		\
+    : (sizeof (x) == sizeof (double)) ? isnan(x)	\
+    : __isnanl(x))
+#define	isnormal(x)					\
+    ((sizeof (x) == sizeof (float)) ? __isnormalf(x)	\
+    : (sizeof (x) == sizeof (double)) ? __isnormal(x)	\
+    : __isnormall(x))
+
+#ifdef __MATH_BUILTIN_RELOPS
+#define	isgreater(x, y)		__builtin_isgreater((x), (y))
+#define	isgreaterequal(x, y)	__builtin_isgreaterequal((x), (y))
+#define	isless(x, y)		__builtin_isless((x), (y))
+#define	islessequal(x, y)	__builtin_islessequal((x), (y))
+#define	islessgreater(x, y)	__builtin_islessgreater((x), (y))
+#define	isunordered(x, y)	__builtin_isunordered((x), (y))
+#else
+#define	isgreater(x, y)		(!isunordered((x), (y)) && (x) > (y))
+#define	isgreaterequal(x, y)	(!isunordered((x), (y)) && (x) >= (y))
+#define	isless(x, y)		(!isunordered((x), (y)) && (x) < (y))
+#define	islessequal(x, y)	(!isunordered((x), (y)) && (x) <= (y))
+#define	islessgreater(x, y)	(!isunordered((x), (y)) && \
+					((x) > (y) || (y) > (x)))
+#define	isunordered(x, y)	(isnan(x) || isnan(y))
+#endif /* __MATH_BUILTIN_RELOPS */
+
+#define	signbit(x)					\
+    ((sizeof (x) == sizeof (float)) ? __signbitf(x)	\
+    : (sizeof (x) == sizeof (double)) ? __signbit(x)	\
+    : __signbitl(x))
+
+#if 0
+typedef	__double_t	double_t;
+typedef	__float_t	float_t;
+#endif 
+/* #endif */ /* __ISO_C_VISIBLE >= 1999 */
+
+/*
+ * XOPEN/SVID
+ */
+/* #if __BSD_VISIBLE || __XSI_VISIBLE */
+#define	M_E		2.7182818284590452354	/* e */
+#define	M_LOG2E		1.4426950408889634074	/* log 2e */
+#define	M_LOG10E	0.43429448190325182765	/* log 10e */
+#define	M_LN2		0.69314718055994530942	/* log e2 */
+#define	M_LN10		2.30258509299404568402	/* log e10 */
+#define	M_PI		3.14159265358979323846	/* pi */
+#define	M_PI_2		1.57079632679489661923	/* pi/2 */
+#define	M_PI_4		0.78539816339744830962	/* pi/4 */
+#define	M_1_PI		0.31830988618379067154	/* 1/pi */
+#define	M_2_PI		0.63661977236758134308	/* 2/pi */
+#define	M_2_SQRTPI	1.12837916709551257390	/* 2/sqrt(pi) */
+#define	M_SQRT2		1.41421356237309504880	/* sqrt(2) */
+#define	M_SQRT1_2	0.70710678118654752440	/* 1/sqrt(2) */
+
+#define	MAXFLOAT	((float)3.40282346638528860e+38)
+extern int signgam;
+/* #endif */ /* __BSD_VISIBLE || __XSI_VISIBLE */
+
+#if __BSD_VISIBLE
+#if 0
+/* Old value from 4.4BSD-Lite math.h; this is probably better. */
+#define	HUGE		HUGE_VAL
+#else
+#define	HUGE		MAXFLOAT
+#endif
+#endif /* __BSD_VISIBLE */
+
+/*
+ * Most of these functions depend on the rounding mode and have the side
+ * effect of raising floating-point exceptions, so they are not declared
+ * as __pure2.  In C99, FENV_ACCESS affects the purity of these functions.
+ */
+__BEGIN_DECLS
+/*
+ * ANSI/POSIX
+ */
+int	__fpclassifyd(double) __pure2;
+int	__fpclassifyf(float) __pure2;
+int	__fpclassifyl(long double) __pure2;
+int	__isfinitef(float) __pure2;
+int	__isfinite(double) __pure2;
+int	__isfinitel(long double) __pure2;
+int	__isinff(float) __pure2;
+int     __isinf(double) __pure2;
+int	__isinfl(long double) __pure2;
+int	__isnanl(long double) __pure2;
+int	__isnormalf(float) __pure2;
+int	__isnormal(double) __pure2;
+int	__isnormall(long double) __pure2;
+int	__signbit(double) __pure2;
+int	__signbitf(float) __pure2;
+int	__signbitl(long double) __pure2;
+
+double	acos(double);
+double	asin(double);
+double	atan(double);
+double	atan2(double, double);
+double	cos(double);
+double	sin(double);
+double	tan(double);
+
+double	cosh(double);
+double	sinh(double);
+double	tanh(double);
+
+double	exp(double);
+double	frexp(double, int *);	/* fundamentally !__pure2 */
+double	ldexp(double, int);
+double	log(double);
+double	log10(double);
+double	modf(double, double *);	/* fundamentally !__pure2 */
+
+double	pow(double, double);
+double	sqrt(double);
+
+double	ceil(double);
+double	fabs(double) __pure2;
+double	floor(double);
+double	fmod(double, double);
+
+/*
+ * These functions are not in C90.
+ */
+/* #if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __XSI_VISIBLE */
+double	acosh(double);
+double	asinh(double);
+double	atanh(double);
+double	cbrt(double);
+double	erf(double);
+double	erfc(double);
+double	exp2(double);
+double	expm1(double);
+double	fma(double, double, double);
+double	hypot(double, double);
+int	ilogb(double) __pure2;
+/* int	(isinf)(double) __pure2; */
+int	(isnan)(double) __pure2;
+double	lgamma(double);
+long long llrint(double);
+long long llround(double);
+double	log1p(double);
+double	logb(double);
+long	lrint(double);
+long	lround(double);
+double	nextafter(double, double);
+double	remainder(double, double);
+double	remquo(double, double, int *);
+double	rint(double);
+/* #endif */ /* __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __XSI_VISIBLE */
+
+/* #if __BSD_VISIBLE || __XSI_VISIBLE */
+double	j0(double);
+double	j1(double);
+double	jn(int, double);
+double	scalb(double, double);
+double	y0(double);
+double	y1(double);
+double	yn(int, double);
+
+/* #if __XSI_VISIBLE <= 500 || __BSD_VISIBLE */
+double	gamma(double);
+/* #endif */
+/* #endif */ /* __BSD_VISIBLE || __XSI_VISIBLE */
+
+/* #if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 */
+double	copysign(double, double) __pure2;
+double	fdim(double, double);
+double	fmax(double, double) __pure2;
+double	fmin(double, double) __pure2;
+double	nearbyint(double);
+double	round(double);
+double	scalbln(double, long);
+double	scalbn(double, int);
+double	tgamma(double);
+double	trunc(double);
+/* #endif */
+
+/*
+ * BSD math library entry points
+ */
+/* #if __BSD_VISIBLE */
+double	drem(double, double);
+int	finite(double) __pure2;
+int	isnanf(float) __pure2;
+
+/*
+ * Reentrant version of gamma & lgamma; passes signgam back by reference
+ * as the second argument; user must allocate space for signgam.
+ */
+double	gamma_r(double, int *);
+double	lgamma_r(double, int *);
+
+/*
+ * IEEE Test Vector
+ */
+double	significand(double);
+/* #endif */ /* __BSD_VISIBLE */
+
+/* float versions of ANSI/POSIX functions */
+/*#if __ISO_C_VISIBLE >= 1999 */
+float	acosf(float);
+float	asinf(float);
+float	atanf(float);
+float	atan2f(float, float);
+float	cosf(float);
+float	sinf(float);
+float	tanf(float);
+
+float	coshf(float);
+float	sinhf(float);
+float	tanhf(float);
+
+float	exp2f(float);
+float	expf(float);
+float	expm1f(float);
+float	frexpf(float, int *);	/* fundamentally !__pure2 */
+int	ilogbf(float) __pure2;
+float	ldexpf(float, int);
+float	log10f(float);
+float	log1pf(float);
+float	logf(float);
+float	modff(float, float *);	/* fundamentally !__pure2 */
+
+float	powf(float, float);
+float	sqrtf(float);
+
+float	ceilf(float);
+float	fabsf(float) __pure2;
+float	floorf(float);
+float	fmodf(float, float);
+float	roundf(float);
+
+float	erff(float);
+float	erfcf(float);
+float	hypotf(float, float);
+float	lgammaf(float);
+
+float	acoshf(float);
+float	asinhf(float);
+float	atanhf(float);
+float	cbrtf(float);
+float	logbf(float);
+float	copysignf(float, float) __pure2;
+long long llrintf(float);
+long long llroundf(float);
+long	lrintf(float);
+long	lroundf(float);
+float	nearbyintf(float);
+float	nextafterf(float, float);
+float	remainderf(float, float);
+float	remquof(float, float, int *);
+float	rintf(float);
+float	scalblnf(float, long);
+float	scalbnf(float, int);
+float	truncf(float);
+
+float	fdimf(float, float);
+float	fmaf(float, float, float);
+float	fmaxf(float, float) __pure2;
+float	fminf(float, float) __pure2;
+/* #endif */
+
+/*
+ * float versions of BSD math library entry points
+ */
+/* #if __BSD_VISIBLE */
+float	dremf(float, float);
+int	finitef(float) __pure2;
+float	gammaf(float);
+float	j0f(float);
+float	j1f(float);
+float	jnf(int, float);
+float	scalbf(float, float);
+float	y0f(float);
+float	y1f(float);
+float	ynf(int, float);
+
+/*
+ * Float versions of reentrant version of gamma & lgamma; passes
+ * signgam back by reference as the second argument; user must
+ * allocate space for signgam.
+ */
+float	gammaf_r(float, int *);
+float	lgammaf_r(float, int *);
+
+/*
+ * float version of IEEE Test Vector
+ */
+float	significandf(float);
+/* #endif */	/* __BSD_VISIBLE */ 
+
+/*
+ * long double versions of ISO/POSIX math functions
+ */
+/* #if __ISO_C_VISIBLE >= 1999 */
+#if 0
+long double	acoshl(long double);
+long double	acosl(long double);
+long double	asinhl(long double);
+long double	asinl(long double);
+long double	atan2l(long double, long double);
+long double	atanhl(long double);
+long double	atanl(long double);
+long double	cbrtl(long double);
+#endif
+long double	ceill(long double);
+long double	copysignl(long double, long double) __pure2;
+#if 0
+long double	coshl(long double);
+long double	cosl(long double);
+long double	erfcl(long double);
+long double	erfl(long double);
+long double	exp2l(long double);
+long double	expl(long double);
+long double	expm1l(long double);
+#endif
+long double	fabsl(long double) __pure2;
+long double	fdiml(long double, long double);
+long double	floorl(long double);
+long double	fmal(long double, long double, long double);
+long double	fmaxl(long double, long double) __pure2;
+long double	fminl(long double, long double) __pure2;
+#if 0
+long double	fmodl(long double, long double);
+#endif
+long double	frexpl(long double value, int *); /* fundamentally !__pure2 */
+#if 0
+long double	hypotl(long double, long double);
+#endif
+int		ilogbl(long double) __pure2;
+long double	ldexpl(long double, int);
+#if 0
+long double	lgammal(long double);
+long long	llrintl(long double);
+#endif
+long long	llroundl(long double);
+#if 0
+long double	log10l(long double);
+long double	log1pl(long double);
+long double	log2l(long double);
+long double	logbl(long double);
+long double	logl(long double);
+long		lrintl(long double);
+#endif
+long		lroundl(long double);
+#if 0
+long double	modfl(long double, long double *); /* fundamentally !__pure2 */
+long double	nanl(const char *) __pure2;
+long double	nearbyintl(long double);
+#endif
+long double	nextafterl(long double, long double);
+double		nexttoward(double, long double);
+float		nexttowardf(float, long double);
+long double	nexttowardl(long double, long double);
+#if 0
+long double	powl(long double, long double);
+long double	remainderl(long double, long double);
+long double	remquol(long double, long double, int *);
+long double	rintl(long double);
+#endif
+long double	roundl(long double);
+long double	scalblnl(long double, long);
+long double	scalbnl(long double, int);
+#if 0
+long double	sinhl(long double);
+long double	sinl(long double);
+long double	sqrtl(long double);
+long double	tanhl(long double);
+long double	tanl(long double);
+long double	tgammal(long double);
+#endif
+long double	truncl(long double);
+
+/* #endif */ /* __ISO_C_VISIBLE >= 1999 */
+__END_DECLS
+
+#endif /* !_MATH_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/memory.h b/ndk/build/platforms/android-1.5/common/include/memory.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/memory.h
diff --git a/ndk/build/platforms/android-1.5/common/include/mntent.h b/ndk/build/platforms/android-1.5/common/include/mntent.h
new file mode 100644
index 0000000..468ff74
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/mntent.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _MNTENT_H_
+#define _MNTENT_H_
+
+
+#define MNTTYPE_IGNORE "ignore"
+
+struct mntent
+{
+    char* mnt_fsname;
+    char* mnt_dir;
+    char* mnt_type;
+    char* mnt_opts;
+    int mnt_freq;
+    int mnt_passno;
+};
+
+
+__BEGIN_DECLS
+
+
+struct mntent* getmntent(FILE*);
+
+__END_DECLS
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/mtd/mtd-abi.h b/ndk/build/platforms/android-1.5/common/include/mtd/mtd-abi.h
new file mode 100644
index 0000000..0ae2263
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/mtd/mtd-abi.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __MTD_ABI_H__
+#define __MTD_ABI_H__
+
+struct erase_info_user {
+ uint32_t start;
+ uint32_t length;
+};
+
+struct mtd_oob_buf {
+ uint32_t start;
+ uint32_t length;
+ unsigned char __user *ptr;
+};
+
+#define MTD_ABSENT 0
+#define MTD_RAM 1
+#define MTD_ROM 2
+#define MTD_NORFLASH 3
+#define MTD_NANDFLASH 4
+#define MTD_DATAFLASH 6
+
+#define MTD_WRITEABLE 0x400  
+#define MTD_BIT_WRITEABLE 0x800  
+#define MTD_NO_ERASE 0x1000  
+#define MTD_STUPID_LOCK 0x2000  
+
+#define MTD_CAP_ROM 0
+#define MTD_CAP_RAM (MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE)
+#define MTD_CAP_NORFLASH (MTD_WRITEABLE | MTD_BIT_WRITEABLE)
+#define MTD_CAP_NANDFLASH (MTD_WRITEABLE)
+
+#define MTD_NANDECC_OFF 0 
+#define MTD_NANDECC_PLACE 1 
+#define MTD_NANDECC_AUTOPLACE 2 
+#define MTD_NANDECC_PLACEONLY 3 
+#define MTD_NANDECC_AUTOPL_USR 4 
+
+#define MTD_OTP_OFF 0
+#define MTD_OTP_FACTORY 1
+#define MTD_OTP_USER 2
+
+struct mtd_info_user {
+ uint8_t type;
+ uint32_t flags;
+ uint32_t size;
+ uint32_t erasesize;
+ uint32_t writesize;
+ uint32_t oobsize;
+
+ uint32_t ecctype;
+ uint32_t eccsize;
+};
+
+struct region_info_user {
+ uint32_t offset;
+ uint32_t erasesize;
+ uint32_t numblocks;
+ uint32_t regionindex;
+};
+
+struct otp_info {
+ uint32_t start;
+ uint32_t length;
+ uint32_t locked;
+};
+
+#define MEMGETINFO _IOR('M', 1, struct mtd_info_user)
+#define MEMERASE _IOW('M', 2, struct erase_info_user)
+#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf)
+#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf)
+#define MEMLOCK _IOW('M', 5, struct erase_info_user)
+#define MEMUNLOCK _IOW('M', 6, struct erase_info_user)
+#define MEMGETREGIONCOUNT _IOR('M', 7, int)
+#define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user)
+#define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo)
+#define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo)
+#define MEMGETBADBLOCK _IOW('M', 11, loff_t)
+#define MEMSETBADBLOCK _IOW('M', 12, loff_t)
+#define OTPSELECT _IOR('M', 13, int)
+#define OTPGETREGIONCOUNT _IOW('M', 14, int)
+#define OTPGETREGIONINFO _IOW('M', 15, struct otp_info)
+#define OTPLOCK _IOR('M', 16, struct otp_info)
+#define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout)
+#define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats)
+#define MTDFILEMODE _IO('M', 19)
+
+struct nand_oobinfo {
+ uint32_t useecc;
+ uint32_t eccbytes;
+ uint32_t oobfree[8][2];
+ uint32_t eccpos[32];
+};
+
+struct nand_oobfree {
+ uint32_t offset;
+ uint32_t length;
+};
+
+#define MTD_MAX_OOBFREE_ENTRIES 8
+
+struct nand_ecclayout {
+ uint32_t eccbytes;
+ uint32_t eccpos[64];
+ uint32_t oobavail;
+ struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES];
+};
+
+struct mtd_ecc_stats {
+ uint32_t corrected;
+ uint32_t failed;
+ uint32_t badblocks;
+ uint32_t bbtblocks;
+};
+
+enum mtd_file_modes {
+ MTD_MODE_NORMAL = MTD_OTP_OFF,
+ MTD_MODE_OTP_FACTORY = MTD_OTP_FACTORY,
+ MTD_MODE_OTP_USER = MTD_OTP_USER,
+ MTD_MODE_RAW,
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/mtd/mtd-user.h b/ndk/build/platforms/android-1.5/common/include/mtd/mtd-user.h
new file mode 100644
index 0000000..1d37dc1
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/mtd/mtd-user.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef __MTD_USER_H__
+#define __MTD_USER_H__
+
+#include <stdint.h>
+
+#include <mtd/mtd-abi.h>
+
+typedef struct mtd_info_user mtd_info_t;
+typedef struct erase_info_user erase_info_t;
+typedef struct region_info_user region_info_t;
+typedef struct nand_oobinfo nand_oobinfo_t;
+typedef struct nand_ecclayout nand_ecclayout_t;
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/net/ethertypes.h b/ndk/build/platforms/android-1.5/common/include/net/ethertypes.h
new file mode 100644
index 0000000..1cfd2cd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/net/ethertypes.h
@@ -0,0 +1,313 @@
+/*	$NetBSD: ethertypes.h,v 1.17 2005/12/10 23:21:38 elad Exp $	*/
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)if_ether.h	8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * Ethernet protocol types.
+ *
+ * According to "assigned numbers", the Ethernet protocol numbers are also
+ * used as ARP protocol type numbers.
+ *
+ * I factor them out here to avoid pulling all the Ethernet header file
+ * into the hardware independent ARP code. -is
+ *
+ * Additional sources of information:
+ *	http://www.mit.edu/~map/Ethernet/Ethernet.txt
+ *	ftp://venera.isi.edu/in-notes/iana/assignments/ethernet-numbers
+ *
+ */
+
+#ifndef _NET_ETHERTYPES_H_
+#define	_NET_ETHERTYPES_H_
+
+/*
+ *  NOTE: 0x0000-0x05DC (0..1500) are generally IEEE 802.3 length fields.
+ *  However, there are some conflicts.
+ */
+
+#define	ETHERTYPE_8023		0x0004	/* IEEE 802.3 packet */
+		   /* 0x0101 .. 0x1FF	   Experimental */
+#define	ETHERTYPE_PUP		0x0200	/* Xerox PUP protocol - see 0A00 */
+#define	ETHERTYPE_PUPAT		0x0200	/* PUP Address Translation - see 0A01 */
+#define	ETHERTYPE_SPRITE	0x0500	/* ??? */
+			     /* 0x0400	   Nixdorf */
+#define	ETHERTYPE_NS		0x0600	/* XNS */
+#define	ETHERTYPE_NSAT		0x0601	/* XNS Address Translation (3Mb only) */
+#define	ETHERTYPE_DLOG1 	0x0660	/* DLOG (?) */
+#define	ETHERTYPE_DLOG2 	0x0661	/* DLOG (?) */
+#define	ETHERTYPE_IP		0x0800	/* IP protocol */
+#define	ETHERTYPE_X75		0x0801	/* X.75 Internet */
+#define	ETHERTYPE_NBS		0x0802	/* NBS Internet */
+#define	ETHERTYPE_ECMA		0x0803	/* ECMA Internet */
+#define	ETHERTYPE_CHAOS 	0x0804	/* CHAOSnet */
+#define	ETHERTYPE_X25		0x0805	/* X.25 Level 3 */
+#define	ETHERTYPE_ARP		0x0806	/* Address resolution protocol */
+#define	ETHERTYPE_NSCOMPAT	0x0807	/* XNS Compatibility */
+#define	ETHERTYPE_FRARP 	0x0808	/* Frame Relay ARP (RFC1701) */
+			     /* 0x081C	   Symbolics Private */
+		    /* 0x0888 - 0x088A	   Xyplex */
+#define	ETHERTYPE_UBDEBUG	0x0900	/* Ungermann-Bass network debugger */
+#define	ETHERTYPE_IEEEPUP	0x0A00	/* Xerox IEEE802.3 PUP */
+#define	ETHERTYPE_IEEEPUPAT	0x0A01	/* Xerox IEEE802.3 PUP Address Translation */
+#define	ETHERTYPE_VINES 	0x0BAD	/* Banyan VINES */
+#define	ETHERTYPE_VINESLOOP	0x0BAE	/* Banyan VINES Loopback */
+#define	ETHERTYPE_VINESECHO	0x0BAF	/* Banyan VINES Echo */
+
+/*		       0x1000 - 0x100F	   Berkeley Trailer */
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define	ETHERTYPE_TRAIL		0x1000	/* Trailer packet */
+#define	ETHERTYPE_NTRAILER	16
+
+#define	ETHERTYPE_DCA		0x1234	/* DCA - Multicast */
+#define	ETHERTYPE_VALID 	0x1600	/* VALID system protocol */
+#define	ETHERTYPE_DOGFIGHT	0x1989	/* Artificial Horizons ("Aviator" dogfight simulator [on Sun]) */
+#define	ETHERTYPE_RCL		0x1995	/* Datapoint Corporation (RCL lan protocol) */
+
+					/* The following 3C0x types
+					   are unregistered: */
+#define	ETHERTYPE_NBPVCD	0x3C00	/* 3Com NBP virtual circuit datagram (like XNS SPP) not registered */
+#define	ETHERTYPE_NBPSCD	0x3C01	/* 3Com NBP System control datagram not registered */
+#define	ETHERTYPE_NBPCREQ	0x3C02	/* 3Com NBP Connect request (virtual cct) not registered */
+#define	ETHERTYPE_NBPCRSP	0x3C03	/* 3Com NBP Connect repsonse not registered */
+#define	ETHERTYPE_NBPCC		0x3C04	/* 3Com NBP Connect complete not registered */
+#define	ETHERTYPE_NBPCLREQ	0x3C05	/* 3Com NBP Close request (virtual cct) not registered */
+#define	ETHERTYPE_NBPCLRSP	0x3C06	/* 3Com NBP Close response not registered */
+#define	ETHERTYPE_NBPDG		0x3C07	/* 3Com NBP Datagram (like XNS IDP) not registered */
+#define	ETHERTYPE_NBPDGB	0x3C08	/* 3Com NBP Datagram broadcast not registered */
+#define	ETHERTYPE_NBPCLAIM	0x3C09	/* 3Com NBP Claim NetBIOS name not registered */
+#define	ETHERTYPE_NBPDLTE	0x3C0A	/* 3Com NBP Delete Netbios name not registered */
+#define	ETHERTYPE_NBPRAS	0x3C0B	/* 3Com NBP Remote adaptor status request not registered */
+#define	ETHERTYPE_NBPRAR	0x3C0C	/* 3Com NBP Remote adaptor response not registered */
+#define	ETHERTYPE_NBPRST	0x3C0D	/* 3Com NBP Reset not registered */
+
+#define	ETHERTYPE_PCS		0x4242	/* PCS Basic Block Protocol */
+#define	ETHERTYPE_IMLBLDIAG	0x424C	/* Information Modes Little Big LAN diagnostic */
+#define	ETHERTYPE_DIDDLE	0x4321	/* THD - Diddle */
+#define	ETHERTYPE_IMLBL		0x4C42	/* Information Modes Little Big LAN */
+#define	ETHERTYPE_SIMNET	0x5208	/* BBN Simnet Private */
+#define	ETHERTYPE_DECEXPER	0x6000	/* DEC Unassigned, experimental */
+#define	ETHERTYPE_MOPDL		0x6001	/* DEC MOP dump/load */
+#define	ETHERTYPE_MOPRC		0x6002	/* DEC MOP remote console */
+#define	ETHERTYPE_DECnet	0x6003	/* DEC DECNET Phase IV route */
+#define	ETHERTYPE_DN		ETHERTYPE_DECnet	/* libpcap, tcpdump */
+#define	ETHERTYPE_LAT		0x6004	/* DEC LAT */
+#define	ETHERTYPE_DECDIAG	0x6005	/* DEC diagnostic protocol (at interface initialization?) */
+#define	ETHERTYPE_DECCUST	0x6006	/* DEC customer protocol */
+#define	ETHERTYPE_SCA		0x6007	/* DEC LAVC, SCA */
+#define	ETHERTYPE_AMBER		0x6008	/* DEC AMBER */
+#define	ETHERTYPE_DECMUMPS	0x6009	/* DEC MUMPS */
+		    /* 0x6010 - 0x6014	   3Com Corporation */
+#define	ETHERTYPE_TRANSETHER	0x6558	/* Trans Ether Bridging (RFC1701)*/
+#define	ETHERTYPE_RAWFR		0x6559	/* Raw Frame Relay (RFC1701) */
+#define	ETHERTYPE_UBDL		0x7000	/* Ungermann-Bass download */
+#define	ETHERTYPE_UBNIU		0x7001	/* Ungermann-Bass NIUs */
+#define	ETHERTYPE_UBDIAGLOOP	0x7002	/* Ungermann-Bass diagnostic/loopback */
+#define	ETHERTYPE_UBNMC		0x7003	/* Ungermann-Bass ??? (NMC to/from UB Bridge) */
+#define	ETHERTYPE_UBBST		0x7005	/* Ungermann-Bass Bridge Spanning Tree */
+#define	ETHERTYPE_OS9		0x7007	/* OS/9 Microware */
+#define	ETHERTYPE_OS9NET	0x7009	/* OS/9 Net? */
+		    /* 0x7020 - 0x7029	   LRT (England) (now Sintrom) */
+#define	ETHERTYPE_RACAL		0x7030	/* Racal-Interlan */
+#define	ETHERTYPE_PRIMENTS	0x7031	/* Prime NTS (Network Terminal Service) */
+#define	ETHERTYPE_CABLETRON	0x7034	/* Cabletron */
+#define	ETHERTYPE_CRONUSVLN	0x8003	/* Cronus VLN */
+#define	ETHERTYPE_CRONUS	0x8004	/* Cronus Direct */
+#define	ETHERTYPE_HP		0x8005	/* HP Probe */
+#define	ETHERTYPE_NESTAR	0x8006	/* Nestar */
+#define	ETHERTYPE_ATTSTANFORD	0x8008	/* AT&T/Stanford (local use) */
+#define	ETHERTYPE_EXCELAN	0x8010	/* Excelan */
+#define	ETHERTYPE_SG_DIAG	0x8013	/* SGI diagnostic type */
+#define	ETHERTYPE_SG_NETGAMES	0x8014	/* SGI network games */
+#define	ETHERTYPE_SG_RESV	0x8015	/* SGI reserved type */
+#define	ETHERTYPE_SG_BOUNCE	0x8016	/* SGI bounce server */
+#define	ETHERTYPE_APOLLODOMAIN	0x8019	/* Apollo DOMAIN */
+#define	ETHERTYPE_TYMSHARE	0x802E	/* Tymeshare */
+#define	ETHERTYPE_TIGAN		0x802F	/* Tigan, Inc. */
+#define	ETHERTYPE_REVARP	0x8035	/* Reverse addr resolution protocol */
+#define	ETHERTYPE_AEONIC	0x8036	/* Aeonic Systems */
+#define	ETHERTYPE_IPXNEW	0x8037	/* IPX (Novell Netware?) */
+#define	ETHERTYPE_LANBRIDGE	0x8038	/* DEC LANBridge */
+#define	ETHERTYPE_DSMD	0x8039	/* DEC DSM/DDP */
+#define	ETHERTYPE_ARGONAUT	0x803A	/* DEC Argonaut Console */
+#define	ETHERTYPE_VAXELN	0x803B	/* DEC VAXELN */
+#define	ETHERTYPE_DECDNS	0x803C	/* DEC DNS Naming Service */
+#define	ETHERTYPE_ENCRYPT	0x803D	/* DEC Ethernet Encryption */
+#define	ETHERTYPE_DECDTS	0x803E	/* DEC Distributed Time Service */
+#define	ETHERTYPE_DECLTM	0x803F	/* DEC LAN Traffic Monitor */
+#define	ETHERTYPE_DECNETBIOS	0x8040	/* DEC PATHWORKS DECnet NETBIOS Emulation */
+#define	ETHERTYPE_DECLAST	0x8041	/* DEC Local Area System Transport */
+			     /* 0x8042	   DEC Unassigned */
+#define	ETHERTYPE_PLANNING	0x8044	/* Planning Research Corp. */
+		    /* 0x8046 - 0x8047	   AT&T */
+#define	ETHERTYPE_DECAM		0x8048	/* DEC Availability Manager for Distributed Systems DECamds (but someone at DEC says not) */
+#define	ETHERTYPE_EXPERDATA	0x8049	/* ExperData */
+#define	ETHERTYPE_VEXP		0x805B	/* Stanford V Kernel exp. */
+#define	ETHERTYPE_VPROD		0x805C	/* Stanford V Kernel prod. */
+#define	ETHERTYPE_ES		0x805D	/* Evans & Sutherland */
+#define	ETHERTYPE_LITTLE	0x8060	/* Little Machines */
+#define	ETHERTYPE_COUNTERPOINT	0x8062	/* Counterpoint Computers */
+		    /* 0x8065 - 0x8066	   Univ. of Mass @ Amherst */
+#define	ETHERTYPE_VEECO		0x8067	/* Veeco Integrated Auto. */
+#define	ETHERTYPE_GENDYN	0x8068	/* General Dynamics */
+#define	ETHERTYPE_ATT		0x8069	/* AT&T */
+#define	ETHERTYPE_AUTOPHON	0x806A	/* Autophon */
+#define	ETHERTYPE_COMDESIGN	0x806C	/* ComDesign */
+#define	ETHERTYPE_COMPUGRAPHIC	0x806D	/* Compugraphic Corporation */
+		    /* 0x806E - 0x8077	   Landmark Graphics Corp. */
+#define	ETHERTYPE_MATRA		0x807A	/* Matra */
+#define	ETHERTYPE_DDE		0x807B	/* Dansk Data Elektronik */
+#define	ETHERTYPE_MERIT		0x807C	/* Merit Internodal (or Univ of Michigan?) */
+		    /* 0x807D - 0x807F	   Vitalink Communications */
+#define	ETHERTYPE_VLTLMAN	0x8080	/* Vitalink TransLAN III Management */
+		    /* 0x8081 - 0x8083	   Counterpoint Computers */
+		    /* 0x8088 - 0x808A	   Xyplex */
+#define	ETHERTYPE_ATALK		0x809B	/* AppleTalk */
+#define	ETHERTYPE_AT		ETHERTYPE_ATALK		/* old NetBSD */
+#define	ETHERTYPE_APPLETALK	ETHERTYPE_ATALK		/* HP-UX */
+		    /* 0x809C - 0x809E	   Datability */
+#define	ETHERTYPE_SPIDER	0x809F	/* Spider Systems Ltd. */
+			     /* 0x80A3	   Nixdorf */
+		    /* 0x80A4 - 0x80B3	   Siemens Gammasonics Inc. */
+		    /* 0x80C0 - 0x80C3	   DCA (Digital Comm. Assoc.) Data Exchange Cluster */
+		    /* 0x80C4 - 0x80C5	   Banyan Systems */
+#define	ETHERTYPE_PACER		0x80C6	/* Pacer Software */
+#define	ETHERTYPE_APPLITEK	0x80C7	/* Applitek Corporation */
+		    /* 0x80C8 - 0x80CC	   Intergraph Corporation */
+		    /* 0x80CD - 0x80CE	   Harris Corporation */
+		    /* 0x80CF - 0x80D2	   Taylor Instrument */
+		    /* 0x80D3 - 0x80D4	   Rosemount Corporation */
+#define	ETHERTYPE_SNA		0x80D5	/* IBM SNA Services over Ethernet */
+#define	ETHERTYPE_VARIAN	0x80DD	/* Varian Associates */
+		    /* 0x80DE - 0x80DF	   TRFS (Integrated Solutions Transparent Remote File System) */
+		    /* 0x80E0 - 0x80E3	   Allen-Bradley */
+		    /* 0x80E4 - 0x80F0	   Datability */
+#define	ETHERTYPE_RETIX		0x80F2	/* Retix */
+#define	ETHERTYPE_AARP		0x80F3	/* AppleTalk AARP */
+		    /* 0x80F4 - 0x80F5	   Kinetics */
+#define	ETHERTYPE_APOLLO	0x80F7	/* Apollo Computer */
+#define ETHERTYPE_VLAN		0x8100	/* IEEE 802.1Q VLAN tagging (XXX conflicts) */
+		    /* 0x80FF - 0x8101	   Wellfleet Communications (XXX conflicts) */
+#define	ETHERTYPE_BOFL		0x8102	/* Wellfleet; BOFL (Breath OF Life) pkts [every 5-10 secs.] */
+#define	ETHERTYPE_WELLFLEET	0x8103	/* Wellfleet Communications */
+		    /* 0x8107 - 0x8109	   Symbolics Private */
+#define	ETHERTYPE_TALARIS	0x812B	/* Talaris */
+#define	ETHERTYPE_WATERLOO	0x8130	/* Waterloo Microsystems Inc. (XXX which?) */
+#define	ETHERTYPE_HAYES		0x8130	/* Hayes Microcomputers (XXX which?) */
+#define	ETHERTYPE_VGLAB		0x8131	/* VG Laboratory Systems */
+		    /* 0x8132 - 0x8137	   Bridge Communications */
+#define	ETHERTYPE_IPX		0x8137	/* Novell (old) NetWare IPX (ECONFIG E option) */
+#define	ETHERTYPE_NOVELL	0x8138	/* Novell, Inc. */
+		    /* 0x8139 - 0x813D	   KTI */
+#define	ETHERTYPE_MUMPS		0x813F	/* M/MUMPS data sharing */
+#define	ETHERTYPE_AMOEBA	0x8145	/* Vrije Universiteit (NL) Amoeba 4 RPC (obsolete) */
+#define	ETHERTYPE_FLIP		0x8146	/* Vrije Universiteit (NL) FLIP (Fast Local Internet Protocol) */
+#define	ETHERTYPE_VURESERVED	0x8147	/* Vrije Universiteit (NL) [reserved] */
+#define	ETHERTYPE_LOGICRAFT	0x8148	/* Logicraft */
+#define	ETHERTYPE_NCD		0x8149	/* Network Computing Devices */
+#define	ETHERTYPE_ALPHA		0x814A	/* Alpha Micro */
+#define	ETHERTYPE_SNMP		0x814C	/* SNMP over Ethernet (see RFC1089) */
+		    /* 0x814D - 0x814E	   BIIN */
+#define	ETHERTYPE_TEC	0x814F	/* Technically Elite Concepts */
+#define	ETHERTYPE_RATIONAL	0x8150	/* Rational Corp */
+		    /* 0x8151 - 0x8153	   Qualcomm */
+		    /* 0x815C - 0x815E	   Computer Protocol Pty Ltd */
+		    /* 0x8164 - 0x8166	   Charles River Data Systems */
+#define	ETHERTYPE_XTP		0x817D	/* Protocol Engines XTP */
+#define	ETHERTYPE_SGITW		0x817E	/* SGI/Time Warner prop. */
+#define	ETHERTYPE_HIPPI_FP	0x8180	/* HIPPI-FP encapsulation */
+#define	ETHERTYPE_STP		0x8181	/* Scheduled Transfer STP, HIPPI-ST */
+		    /* 0x8182 - 0x8183	   Reserved for HIPPI-6400 */
+		    /* 0x8184 - 0x818C	   SGI prop. */
+#define	ETHERTYPE_MOTOROLA	0x818D	/* Motorola */
+#define	ETHERTYPE_NETBEUI	0x8191	/* PowerLAN NetBIOS/NetBEUI (PC) */
+		    /* 0x819A - 0x81A3	   RAD Network Devices */
+		    /* 0x81B7 - 0x81B9	   Xyplex */
+		    /* 0x81CC - 0x81D5	   Apricot Computers */
+		    /* 0x81D6 - 0x81DD	   Artisoft Lantastic */
+		    /* 0x81E6 - 0x81EF	   Polygon */
+		    /* 0x81F0 - 0x81F2	   Comsat Labs */
+		    /* 0x81F3 - 0x81F5	   SAIC */
+		    /* 0x81F6 - 0x81F8	   VG Analytical */
+		    /* 0x8203 - 0x8205	   QNX Software Systems Ltd. */
+		    /* 0x8221 - 0x8222	   Ascom Banking Systems */
+		    /* 0x823E - 0x8240	   Advanced Encryption Systems */
+		    /* 0x8263 - 0x826A	   Charles River Data Systems */
+		    /* 0x827F - 0x8282	   Athena Programming */
+		    /* 0x829A - 0x829B	   Inst Ind Info Tech */
+		    /* 0x829C - 0x82AB	   Taurus Controls */
+		    /* 0x82AC - 0x8693	   Walker Richer & Quinn */
+#define	ETHERTYPE_ACCTON	0x8390	/* Accton Technologies (unregistered) */
+#define	ETHERTYPE_TALARISMC	0x852B	/* Talaris multicast */
+#define	ETHERTYPE_KALPANA	0x8582	/* Kalpana */
+		    /* 0x8694 - 0x869D	   Idea Courier */
+		    /* 0x869E - 0x86A1	   Computer Network Tech */
+		    /* 0x86A3 - 0x86AC	   Gateway Communications */
+#define	ETHERTYPE_SECTRA	0x86DB	/* SECTRA */
+#define	ETHERTYPE_IPV6		0x86DD	/* IP protocol version 6 */
+#define	ETHERTYPE_DELTACON	0x86DE	/* Delta Controls */
+#define	ETHERTYPE_ATOMIC	0x86DF	/* ATOMIC */
+		    /* 0x86E0 - 0x86EF	   Landis & Gyr Powers */
+		    /* 0x8700 - 0x8710	   Motorola */
+#define	ETHERTYPE_RDP		0x8739	/* Control Technology Inc. RDP Without IP */
+#define	ETHERTYPE_MICP		0x873A	/* Control Technology Inc. Mcast Industrial Ctrl Proto. */
+		    /* 0x873B - 0x873C	   Control Technology Inc. Proprietary */
+#define	ETHERTYPE_TCPCOMP	0x876B	/* TCP/IP Compression (RFC1701) */
+#define	ETHERTYPE_IPAS		0x876C	/* IP Autonomous Systems (RFC1701) */
+#define	ETHERTYPE_SECUREDATA	0x876D	/* Secure Data (RFC1701) */
+#define	ETHERTYPE_FLOWCONTROL	0x8808	/* 802.3x flow control packet */
+#define	ETHERTYPE_SLOWPROTOCOLS	0x8809	/* Slow protocols */
+#define	ETHERTYPE_PPP		0x880B	/* PPP (obsolete by PPPOE) */
+#define	ETHERTYPE_HITACHI	0x8820	/* Hitachi Cable (Optoelectronic Systems Laboratory) */
+#define	ETHERTYPE_MPLS		0x8847	/* MPLS Unicast */
+#define	ETHERTYPE_MPLS_MCAST	0x8848	/* MPLS Multicast */
+#define	ETHERTYPE_AXIS		0x8856	/* Axis Communications AB proprietary bootstrap/config */
+#define	ETHERTYPE_PPPOEDISC	0x8863	/* PPP Over Ethernet Discovery Stage */
+#define	ETHERTYPE_PPPOE		0x8864	/* PPP Over Ethernet Session Stage */
+#define	ETHERTYPE_LANPROBE	0x8888	/* HP LanProbe test? */
+#define	ETHERTYPE_PAE		0x888e	/* EAPOL PAE/802.1x */
+#define	ETHERTYPE_LOOPBACK	0x9000	/* Loopback */
+#define	ETHERTYPE_LBACK		ETHERTYPE_LOOPBACK	/* DEC MOP loopback */
+#define	ETHERTYPE_XNSSM		0x9001	/* 3Com (Formerly Bridge Communications), XNS Systems Management */
+#define	ETHERTYPE_TCPSM		0x9002	/* 3Com (Formerly Bridge Communications), TCP/IP Systems Management */
+#define	ETHERTYPE_BCLOOP	0x9003	/* 3Com (Formerly Bridge Communications), loopback detection */
+#define	ETHERTYPE_DEBNI		0xAAAA	/* DECNET? Used by VAX 6220 DEBNI */
+#define	ETHERTYPE_SONIX		0xFAF5	/* Sonix Arpeggio */
+#define	ETHERTYPE_VITAL		0xFF00	/* BBN VITAL-LanBridge cache wakeups */
+		    /* 0xFF00 - 0xFFOF	   ISC Bunker Ramo */
+
+#define	ETHERTYPE_MAX		0xFFFF	/* Maximum valid ethernet type, reserved */
+
+#endif /* !_NET_ETHERTYPES_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/net/if.h b/ndk/build/platforms/android-1.5/common/include/net/if.h
new file mode 100644
index 0000000..9044fc5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/net/if.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#include <linux/if.h>
+#include <sys/cdefs.h>
+#ifndef IF_NAMESIZE
+#define IF_NAMESIZE IFNAMSIZ
+#endif
+
+__BEGIN_DECLS
+
+/*
+ * Map an interface name into its corresponding index.
+ */
+extern unsigned int if_nametoindex(const char *);
+extern char*        if_indextoname(unsigned ifindex, char *ifname);
+
+__END_DECLS
diff --git a/ndk/build/platforms/android-1.5/common/include/net/if_arp.h b/ndk/build/platforms/android-1.5/common/include/net/if_arp.h
new file mode 100644
index 0000000..a25f1b4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/net/if_arp.h
@@ -0,0 +1 @@
+#include <linux/if_arp.h>
diff --git a/ndk/build/platforms/android-1.5/common/include/net/if_dl.h b/ndk/build/platforms/android-1.5/common/include/net/if_dl.h
new file mode 100644
index 0000000..1f0c080
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/net/if_dl.h
@@ -0,0 +1,87 @@
+/*	$NetBSD: if_dl.h,v 1.18 2005/12/11 23:05:24 thorpej Exp $	*/
+
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)if_dl.h	8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * A Link-Level Sockaddr may specify the interface in one of two
+ * ways: either by means of a system-provided index number (computed
+ * anew and possibly differently on every reboot), or by a human-readable
+ * string such as "il0" (for managerial convenience).
+ *
+ * Census taking actions, such as something akin to SIOCGCONF would return
+ * both the index and the human name.
+ *
+ * High volume transactions (such as giving a link-level ``from'' address
+ * in a recvfrom or recvmsg call) may be likely only to provide the indexed
+ * form, (which requires fewer copy operations and less space).
+ *
+ * The form and interpretation  of the link-level address is purely a matter
+ * of convention between the device driver and its consumers; however, it is
+ * expected that all drivers for an interface of a given if_type will agree.
+ */
+
+#ifndef _NET_IF_DL_H_
+#define _NET_IF_DL_H_
+
+#include <sys/socket.h>
+
+/*
+ * Structure of a Link-Level sockaddr:
+ */
+struct sockaddr_dl {
+	u_char	    sdl_len;	/* Total length of sockaddr */
+	sa_family_t sdl_family;	/* AF_LINK */
+	u_int16_t   sdl_index;	/* if != 0, system given index for interface */
+	u_char	    sdl_type;	/* interface type */
+	u_char	    sdl_nlen;	/* interface name length, no trailing 0 reqd. */
+	u_char	    sdl_alen;	/* link level address length */
+	u_char	    sdl_slen;	/* link layer selector length */
+	char	    sdl_data[12]; /* minimum work area, can be larger;
+				     contains both if name and ll address */
+};
+
+/* We do arithmetic directly with these, so keep them char instead of void */
+#define LLADDR(s) ((char *)((s)->sdl_data + (s)->sdl_nlen))
+#define CLLADDR(s) ((const char *)((s)->sdl_data + (s)->sdl_nlen))
+
+#ifndef _KERNEL
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+void	link_addr(const char *, struct sockaddr_dl *);
+char	*link_ntoa(const struct sockaddr_dl *);
+__END_DECLS
+
+#endif /* !_KERNEL */
+
+#endif /* !_NET_IF_DL_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/net/if_ether.h b/ndk/build/platforms/android-1.5/common/include/net/if_ether.h
new file mode 100644
index 0000000..121f9ac
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/net/if_ether.h
@@ -0,0 +1,217 @@
+/*	$NetBSD: if_ether.h,v 1.43 2006/11/24 01:04:30 rpaulo Exp $	*/
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)if_ether.h	8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NET_IF_ETHER_H_
+#define _NET_IF_ETHER_H_
+
+#ifdef _KERNEL
+#ifdef _KERNEL_OPT
+#include "opt_mbuftrace.h"
+#endif
+#include <sys/mbuf.h>
+#endif
+
+/*
+ * Some basic Ethernet constants.
+ */
+#define	ETHER_ADDR_LEN	6	/* length of an Ethernet address */
+#define	ETHER_TYPE_LEN	2	/* length of the Ethernet type field */
+#define	ETHER_CRC_LEN	4	/* length of the Ethernet CRC */
+#define	ETHER_HDR_LEN	((ETHER_ADDR_LEN * 2) + ETHER_TYPE_LEN)
+#define	ETHER_MIN_LEN	64	/* minimum frame length, including CRC */
+#define	ETHER_MAX_LEN	1518	/* maximum frame length, including CRC */
+#define	ETHER_MAX_LEN_JUMBO 9018 /* maximum jumbo frame len, including CRC */
+
+/*
+ * Some Ethernet extensions.
+ */
+#define	ETHER_VLAN_ENCAP_LEN 4	/* length of 802.1Q VLAN encapsulation */
+
+/*
+ * Ethernet address - 6 octets
+ * this is only used by the ethers(3) functions.
+ */
+struct ether_addr {
+	u_int8_t ether_addr_octet[ETHER_ADDR_LEN];
+} __attribute__((__packed__));
+
+/*
+ * Structure of a 10Mb/s Ethernet header.
+ */
+struct	ether_header {
+	u_int8_t  ether_dhost[ETHER_ADDR_LEN];
+	u_int8_t  ether_shost[ETHER_ADDR_LEN];
+	u_int16_t ether_type;
+} __attribute__((__packed__));
+
+#include <net/ethertypes.h>
+
+#define	ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
+
+#define	ETHERMTU_JUMBO	(ETHER_MAX_LEN_JUMBO - ETHER_HDR_LEN - ETHER_CRC_LEN)
+#define	ETHERMTU	(ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
+#define	ETHERMIN	(ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
+
+/*
+ * Compute the maximum frame size based on ethertype (i.e. possible
+ * encapsulation) and whether or not an FCS is present.
+ */
+#define	ETHER_MAX_FRAME(ifp, etype, hasfcs)				\
+	((ifp)->if_mtu + ETHER_HDR_LEN +				\
+	 ((hasfcs) ? ETHER_CRC_LEN : 0) +				\
+	 (((etype) == ETHERTYPE_VLAN) ? ETHER_VLAN_ENCAP_LEN : 0))
+
+/*
+ * Ethernet CRC32 polynomials (big- and little-endian verions).
+ */
+#define	ETHER_CRC_POLY_LE	0xedb88320
+#define	ETHER_CRC_POLY_BE	0x04c11db6
+
+#ifndef _STANDALONE
+
+/*
+ * Ethernet-specific mbuf flags.
+ */
+#define	M_HASFCS	M_LINK0	/* FCS included at end of frame */
+#define	M_PROMISC	M_LINK1	/* this packet is not for us */
+
+#ifdef _KERNEL
+/*
+ * Macro to map an IP multicast address to an Ethernet multicast address.
+ * The high-order 25 bits of the Ethernet address are statically assigned,
+ * and the low-order 23 bits are taken from the low end of the IP address.
+ */
+#define ETHER_MAP_IP_MULTICAST(ipaddr, enaddr)				\
+	/* struct in_addr *ipaddr; */					\
+	/* u_int8_t enaddr[ETHER_ADDR_LEN]; */				\
+{									\
+	(enaddr)[0] = 0x01;						\
+	(enaddr)[1] = 0x00;						\
+	(enaddr)[2] = 0x5e;						\
+	(enaddr)[3] = ((u_int8_t *)ipaddr)[1] & 0x7f;			\
+	(enaddr)[4] = ((u_int8_t *)ipaddr)[2];				\
+	(enaddr)[5] = ((u_int8_t *)ipaddr)[3];				\
+}
+/*
+ * Macro to map an IP6 multicast address to an Ethernet multicast address.
+ * The high-order 16 bits of the Ethernet address are statically assigned,
+ * and the low-order 32 bits are taken from the low end of the IP6 address.
+ */
+#define ETHER_MAP_IPV6_MULTICAST(ip6addr, enaddr)			\
+	/* struct in6_addr *ip6addr; */					\
+	/* u_int8_t enaddr[ETHER_ADDR_LEN]; */				\
+{                                                                       \
+	(enaddr)[0] = 0x33;						\
+	(enaddr)[1] = 0x33;						\
+	(enaddr)[2] = ((u_int8_t *)ip6addr)[12];			\
+	(enaddr)[3] = ((u_int8_t *)ip6addr)[13];			\
+	(enaddr)[4] = ((u_int8_t *)ip6addr)[14];			\
+	(enaddr)[5] = ((u_int8_t *)ip6addr)[15];			\
+}
+#endif
+
+#define	ETHERCAP_VLAN_MTU	0x00000001	/* VLAN-compatible MTU */
+#define	ETHERCAP_VLAN_HWTAGGING	0x00000002	/* hardware VLAN tag support */
+#define	ETHERCAP_JUMBO_MTU	0x00000004	/* 9000 byte MTU supported */
+
+#ifdef	_KERNEL
+extern const uint8_t etherbroadcastaddr[ETHER_ADDR_LEN];
+extern const uint8_t ethermulticastaddr_slowprotocols[ETHER_ADDR_LEN];
+extern const uint8_t ether_ipmulticast_min[ETHER_ADDR_LEN];
+extern const uint8_t ether_ipmulticast_max[ETHER_ADDR_LEN];
+
+int	ether_ioctl(struct ifnet *, u_long, caddr_t);
+int	ether_addmulti (struct ifreq *, struct ethercom *);
+int	ether_delmulti (struct ifreq *, struct ethercom *);
+int	ether_changeaddr (struct ifreq *, struct ethercom *);
+int	ether_multiaddr(struct sockaddr *, u_int8_t[], u_int8_t[]);
+
+/*
+ * Ethernet 802.1Q VLAN structures.
+ */
+
+/* add VLAN tag to input/received packet */
+#define	VLAN_INPUT_TAG(ifp, m, vlanid, _errcase)	\
+	do {								\
+                struct m_tag *mtag =					\
+                    m_tag_get(PACKET_TAG_VLAN, sizeof(u_int), M_NOWAIT);\
+                if (mtag == NULL) {					\
+			ifp->if_ierrors++;				\
+                        printf("%s: unable to allocate VLAN tag\n",	\
+                            ifp->if_xname);				\
+                        m_freem(m);					\
+                        _errcase;					\
+                }							\
+                *(u_int *)(mtag + 1) = vlanid;				\
+                m_tag_prepend(m, mtag);					\
+	} while(0)
+
+/* extract VLAN tag from output/trasmit packet */
+#define VLAN_OUTPUT_TAG(ec, m0)			\
+	VLAN_ATTACHED(ec) ? m_tag_find((m0), PACKET_TAG_VLAN, NULL) : NULL
+
+/* extract VLAN ID value from a VLAN tag */
+#define VLAN_TAG_VALUE(mtag)	\
+	((*(u_int *)(mtag + 1)) & 4095)
+
+/* test if any VLAN is configured for this interface */
+#define VLAN_ATTACHED(ec)	((ec)->ec_nvlans > 0)
+
+void	ether_ifattach(struct ifnet *, const u_int8_t *);
+void	ether_ifdetach(struct ifnet *);
+
+char	*ether_sprintf(const u_int8_t *);
+char	*ether_snprintf(char *, size_t, const u_int8_t *);
+
+u_int32_t ether_crc32_le(const u_int8_t *, size_t);
+u_int32_t ether_crc32_be(const u_int8_t *, size_t);
+
+int	ether_nonstatic_aton(u_char *, char *);
+#else
+/*
+ * Prototype ethers(3) functions.
+ */
+#include <sys/cdefs.h>
+__BEGIN_DECLS
+char *	ether_ntoa __P((const struct ether_addr *));
+struct ether_addr *
+	ether_aton __P((const char *));
+int	ether_ntohost __P((char *, const struct ether_addr *));
+int	ether_hostton __P((const char *, struct ether_addr *));
+int	ether_line __P((const char *, struct ether_addr *, char *));
+__END_DECLS
+#endif
+
+#endif /* _STANDALONE */
+
+#endif /* !_NET_IF_ETHER_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/net/if_ieee1394.h b/ndk/build/platforms/android-1.5/common/include/net/if_ieee1394.h
new file mode 100644
index 0000000..5a61581
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/net/if_ieee1394.h
@@ -0,0 +1,127 @@
+/*	$NetBSD: if_ieee1394.h,v 1.6 2005/12/10 23:21:38 elad Exp $	*/
+
+/*
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Atsushi Onoe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the NetBSD
+ *	Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 THE FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+#ifndef _NET_IF_IEEE1394_H_
+#define _NET_IF_IEEE1394_H_
+
+/* hardware address information for arp / nd */
+struct ieee1394_hwaddr {
+	u_int8_t	iha_uid[8];		/* node unique ID */
+	u_int8_t	iha_maxrec;		/* max_rec in the config ROM */
+	u_int8_t	iha_speed;		/* min of link/PHY speed */
+	u_int8_t	iha_offset[6];		/* unicast FIFO address */
+};
+
+/*
+ * BPF wants to see one of these.
+ */
+struct ieee1394_bpfhdr {
+	uint8_t		ibh_dhost[8];
+	uint8_t		ibh_shost[8];
+	uint16_t	ibh_type;
+};
+
+#ifdef _KERNEL
+
+/* pseudo header */
+struct ieee1394_header {
+	u_int8_t	ih_uid[8];		/* dst/src uid */
+	u_int8_t	ih_maxrec;		/* dst maxrec for tx */
+	u_int8_t	ih_speed;		/* speed */
+	u_int8_t	ih_offset[6];		/* dst offset */
+};
+
+/* unfragment encapsulation header */
+struct ieee1394_unfraghdr {
+	u_int16_t	iuh_ft;			/* fragment type == 0 */
+	u_int16_t	iuh_etype;		/* ether_type */
+};
+
+/* fragmented encapsulation header */
+struct ieee1394_fraghdr {
+	u_int16_t	ifh_ft_size;		/* fragment type, data size-1 */
+	u_int16_t	ifh_etype_off;		/* etype for first fragment */
+						/* offset for subseq frag */
+	u_int16_t	ifh_dgl;		/* datagram label */
+	u_int16_t	ifh_reserved;
+};
+
+#define	IEEE1394_FT_SUBSEQ	0x8000
+#define	IEEE1394_FT_MORE	0x4000
+
+#define	IEEE1394MTU		1500
+
+#define	IEEE1394_GASP_LEN	8		/* GASP header for Stream */
+#define	IEEE1394_ADDR_LEN	8
+#define	IEEE1394_CRC_LEN	4
+
+struct ieee1394_reass_pkt {
+	LIST_ENTRY(ieee1394_reass_pkt) rp_next;
+	struct mbuf	*rp_m;
+	u_int16_t	rp_size;
+	u_int16_t	rp_etype;
+	u_int16_t	rp_off;
+	u_int16_t	rp_dgl;
+	u_int16_t	rp_len;
+	u_int16_t	rp_ttl;
+};
+
+struct ieee1394_reassq {
+	LIST_ENTRY(ieee1394_reassq) rq_node;
+	LIST_HEAD(, ieee1394_reass_pkt) rq_pkt;
+	u_int32_t	fr_id;
+};
+
+struct ieee1394com {
+	struct ifnet	fc_if;
+	struct ieee1394_hwaddr ic_hwaddr;
+	u_int16_t	ic_dgl;
+	LIST_HEAD(, ieee1394_reassq) ic_reassq;
+};
+
+const char *ieee1394_sprintf(const u_int8_t *);
+void ieee1394_input(struct ifnet *, struct mbuf *, u_int16_t);
+void ieee1394_ifattach(struct ifnet *, const struct ieee1394_hwaddr *);
+void ieee1394_ifdetach(struct ifnet *);
+int  ieee1394_ioctl(struct ifnet *, u_long, caddr_t);
+struct mbuf * ieee1394_fragment(struct ifnet *, struct mbuf *, int, u_int16_t);
+void ieee1394_drain(struct ifnet *);
+void ieee1394_watchdog(struct ifnet *);
+#endif /* _KERNEL */
+
+#endif /* !_NET_IF_IEEE1394_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/net/if_packet.h b/ndk/build/platforms/android-1.5/common/include/net/if_packet.h
new file mode 100644
index 0000000..b5e8e0e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/net/if_packet.h
@@ -0,0 +1 @@
+#include <linux/if_packet.h>
diff --git a/ndk/build/platforms/android-1.5/common/include/net/if_types.h b/ndk/build/platforms/android-1.5/common/include/net/if_types.h
new file mode 100644
index 0000000..f0a04f7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/net/if_types.h
@@ -0,0 +1,267 @@
+/*	$NetBSD: if_types.h,v 1.24 2005/12/10 23:21:38 elad Exp $	*/
+
+/*
+ * Copyright (c) 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)if_types.h	8.3 (Berkeley) 4/28/95
+ */
+
+#ifndef _NET_IF_TYPES_H_
+#define _NET_IF_TYPES_H_
+
+/*
+ * Interface types for benefit of parsing media address headers.
+ * This list is derived from the SNMP list of ifTypes, originally
+ * documented in RFC1573, now maintained as:
+ *
+ * <URL:http://www.iana.org/assignments/smi-numbers>
+ */
+
+#define	IFT_OTHER	0x1		/* none of the following */
+#define	IFT_1822	0x2		/* old-style arpanet imp */
+#define	IFT_HDH1822	0x3		/* HDH arpanet imp */
+#define	IFT_X25DDN	0x4		/* x25 to imp */
+#define	IFT_X25		0x5		/* PDN X25 interface (RFC877) */
+#define	IFT_ETHER	0x6		/* Ethernet CSMA/CD */
+#define	IFT_ISO88023	0x7		/* CSMA/CD */
+#define	IFT_ISO88024	0x8		/* Token Bus */
+#define	IFT_ISO88025	0x9		/* Token Ring */
+#define	IFT_ISO88026	0xa		/* MAN */
+#define	IFT_STARLAN	0xb
+#define	IFT_P10		0xc		/* Proteon 10MBit ring */
+#define	IFT_P80		0xd		/* Proteon 80MBit ring */
+#define	IFT_HY		0xe		/* Hyperchannel */
+#define	IFT_FDDI	0xf
+#define	IFT_LAPB	0x10
+#define	IFT_SDLC	0x11
+#define	IFT_T1		0x12
+#define	IFT_CEPT	0x13		/* E1 - european T1 */
+#define	IFT_ISDNBASIC	0x14
+#define	IFT_ISDNPRIMARY	0x15
+#define	IFT_PTPSERIAL	0x16		/* Proprietary PTP serial */
+#define	IFT_PPP		0x17		/* RFC 1331 */
+#define	IFT_LOOP	0x18		/* loopback */
+#define	IFT_EON		0x19		/* ISO over IP */
+#define	IFT_XETHER	0x1a		/* obsolete 3MB experimental ethernet */
+#define	IFT_NSIP	0x1b		/* XNS over IP */
+#define	IFT_SLIP	0x1c		/* IP over generic TTY */
+#define	IFT_ULTRA	0x1d		/* Ultra Technologies */
+#define	IFT_DS3		0x1e		/* Generic T3 */
+#define	IFT_SIP		0x1f		/* SMDS */
+#define	IFT_FRELAY	0x20		/* Frame Relay DTE only */
+#define	IFT_RS232	0x21
+#define	IFT_PARA	0x22		/* parallel-port */
+#define	IFT_ARCNET	0x23
+#define	IFT_ARCNETPLUS	0x24
+#define	IFT_ATM		0x25		/* ATM cells */
+#define	IFT_MIOX25	0x26
+#define	IFT_SONET	0x27		/* SONET or SDH */
+#define	IFT_X25PLE	0x28
+#define	IFT_ISO88022LLC	0x29
+#define	IFT_LOCALTALK	0x2a
+#define	IFT_SMDSDXI	0x2b
+#define	IFT_FRELAYDCE	0x2c		/* Frame Relay DCE */
+#define	IFT_V35		0x2d
+#define	IFT_HSSI	0x2e
+#define	IFT_HIPPI	0x2f
+#define	IFT_MODEM	0x30		/* Generic Modem */
+#define	IFT_AAL5	0x31		/* AAL5 over ATM */
+#define	IFT_SONETPATH	0x32
+#define	IFT_SONETVT	0x33
+#define	IFT_SMDSICIP	0x34		/* SMDS InterCarrier Interface */
+#define	IFT_PROPVIRTUAL	0x35		/* Proprietary Virtual/internal */
+#define	IFT_PROPMUX	0x36		/* Proprietary Multiplexing */
+#define IFT_IEEE80212		   0x37 /* 100BaseVG */
+#define IFT_FIBRECHANNEL	   0x38 /* Fibre Channel */
+#define IFT_HIPPIINTERFACE	   0x39 /* HIPPI interfaces	 */
+#define IFT_FRAMERELAYINTERCONNECT 0x3a /* Obsolete, use either 0x20 or 0x2c */
+#define IFT_AFLANE8023		   0x3b /* ATM Emulated LAN for 802.3 */
+#define IFT_AFLANE8025		   0x3c /* ATM Emulated LAN for 802.5 */
+#define IFT_CCTEMUL		   0x3d /* ATM Emulated circuit		  */
+#define IFT_FASTETHER		   0x3e /* Fast Ethernet (100BaseT) */
+#define IFT_ISDN		   0x3f /* ISDN and X.25	    */
+#define IFT_V11			   0x40 /* CCITT V.11/X.21		*/
+#define IFT_V36			   0x41 /* CCITT V.36			*/
+#define IFT_G703AT64K		   0x42 /* CCITT G703 at 64Kbps */
+#define IFT_G703AT2MB		   0x43 /* Obsolete see DS1-MIB */
+#define IFT_QLLC		   0x44 /* SNA QLLC			*/
+#define IFT_FASTETHERFX		   0x45 /* Fast Ethernet (100BaseFX)	*/
+#define IFT_CHANNEL		   0x46 /* channel			*/
+#define IFT_IEEE80211		   0x47 /* radio spread spectrum	*/
+#define IFT_IBM370PARCHAN	   0x48 /* IBM System 360/370 OEMI Channel */
+#define IFT_ESCON		   0x49 /* IBM Enterprise Systems Connection */
+#define IFT_DLSW		   0x4a /* Data Link Switching */
+#define IFT_ISDNS		   0x4b /* ISDN S/T interface */
+#define IFT_ISDNU		   0x4c /* ISDN U interface */
+#define IFT_LAPD		   0x4d /* Link Access Protocol D */
+#define IFT_IPSWITCH		   0x4e /* IP Switching Objects */
+#define IFT_RSRB		   0x4f /* Remote Source Route Bridging */
+#define IFT_ATMLOGICAL		   0x50 /* ATM Logical Port */
+#define IFT_DS0			   0x51 /* Digital Signal Level 0 */
+#define IFT_DS0BUNDLE		   0x52 /* group of ds0s on the same ds1 */
+#define IFT_BSC			   0x53 /* Bisynchronous Protocol */
+#define IFT_ASYNC		   0x54 /* Asynchronous Protocol */
+#define IFT_CNR			   0x55 /* Combat Net Radio */
+#define IFT_ISO88025DTR		   0x56 /* ISO 802.5r DTR */
+#define IFT_EPLRS		   0x57 /* Ext Pos Loc Report Sys */
+#define IFT_ARAP		   0x58 /* Appletalk Remote Access Protocol */
+#define IFT_PROPCNLS		   0x59 /* Proprietary Connectionless Protocol*/
+#define IFT_HOSTPAD		   0x5a /* CCITT-ITU X.29 PAD Protocol */
+#define IFT_TERMPAD		   0x5b /* CCITT-ITU X.3 PAD Facility */
+#define IFT_FRAMERELAYMPI	   0x5c /* Multiproto Interconnect over FR */
+#define IFT_X213		   0x5d /* CCITT-ITU X213 */
+#define IFT_ADSL		   0x5e /* Asymmetric Digital Subscriber Loop */
+#define IFT_RADSL		   0x5f /* Rate-Adapt. Digital Subscriber Loop*/
+#define IFT_SDSL		   0x60 /* Symmetric Digital Subscriber Loop */
+#define IFT_VDSL		   0x61 /* Very H-Speed Digital Subscrib. Loop*/
+#define IFT_ISO88025CRFPINT	   0x62 /* ISO 802.5 CRFP */
+#define IFT_MYRINET		   0x63 /* Myricom Myrinet */
+#define IFT_VOICEEM		   0x64 /* voice recEive and transMit */
+#define IFT_VOICEFXO		   0x65 /* voice Foreign Exchange Office */
+#define IFT_VOICEFXS		   0x66 /* voice Foreign Exchange Station */
+#define IFT_VOICEENCAP		   0x67 /* voice encapsulation */
+#define IFT_VOICEOVERIP		   0x68 /* voice over IP encapsulation */
+#define IFT_ATMDXI		   0x69 /* ATM DXI */
+#define IFT_ATMFUNI		   0x6a /* ATM FUNI */
+#define IFT_ATMIMA		   0x6b /* ATM IMA		      */
+#define IFT_PPPMULTILINKBUNDLE	   0x6c /* PPP Multilink Bundle */
+#define IFT_IPOVERCDLC		   0x6d /* IBM ipOverCdlc */
+#define IFT_IPOVERCLAW		   0x6e /* IBM Common Link Access to Workstn */
+#define IFT_STACKTOSTACK	   0x6f /* IBM stackToStack */
+#define IFT_VIRTUALIPADDRESS	   0x70 /* IBM VIPA */
+#define IFT_MPC			   0x71 /* IBM multi-protocol channel support */
+#define IFT_IPOVERATM		   0x72 /* IBM ipOverAtm */
+#define IFT_ISO88025FIBER	   0x73 /* ISO 802.5j Fiber Token Ring */
+#define IFT_TDLC		   0x74 /* IBM twinaxial data link control */
+#define IFT_GIGABITETHERNET	   0x75 /* Gigabit Ethernet */
+#define IFT_HDLC		   0x76 /* HDLC */
+#define IFT_LAPF		   0x77 /* LAP F */
+#define IFT_V37			   0x78 /* V.37 */
+#define IFT_X25MLP		   0x79 /* Multi-Link Protocol */
+#define IFT_X25HUNTGROUP	   0x7a /* X25 Hunt Group */
+#define IFT_TRANSPHDLC		   0x7b /* Transp HDLC */
+#define IFT_INTERLEAVE		   0x7c /* Interleave channel */
+#define IFT_FAST		   0x7d /* Fast channel */
+#define IFT_IP			   0x7e /* IP (for APPN HPR in IP networks) */
+#define IFT_DOCSCABLEMACLAYER	   0x7f /* CATV Mac Layer */
+#define IFT_DOCSCABLEDOWNSTREAM	   0x80 /* CATV Downstream interface */
+#define IFT_DOCSCABLEUPSTREAM	   0x81 /* CATV Upstream interface */
+#define IFT_A12MPPSWITCH	   0x82	/* Avalon Parallel Processor */
+#define IFT_TUNNEL		   0x83	/* Encapsulation interface */
+#define IFT_COFFEE		   0x84	/* coffee pot */
+#define IFT_CES			   0x85	/* Circiut Emulation Service */
+#define IFT_ATMSUBINTERFACE	   0x86	/* (x)  ATM Sub Interface */
+#define IFT_L2VLAN		   0x87	/* Layer 2 Virtual LAN using 802.1Q */
+#define IFT_L3IPVLAN		   0x88	/* Layer 3 Virtual LAN - IP Protocol */
+#define IFT_L3IPXVLAN		   0x89	/* Layer 3 Virtual LAN - IPX Prot. */
+#define IFT_DIGITALPOWERLINE	   0x8a	/* IP over Power Lines */
+#define IFT_MEDIAMAILOVERIP	   0x8b	/* (xxx)  Multimedia Mail over IP */
+#define IFT_DTM			   0x8c	/* Dynamic synchronous Transfer Mode */
+#define IFT_DCN			   0x8d	/* Data Communications Network */
+#define IFT_IPFORWARD		   0x8e	/* IP Forwarding Interface */
+#define IFT_MSDSL		   0x8f	/* Multi-rate Symmetric DSL */
+#define IFT_IEEE1394		   0x90	/* IEEE1394 High Performance SerialBus*/
+#define IFT_IFGSN		   0x91	/* HIPPI-6400 */
+#define IFT_DVBRCCMACLAYER	   0x92	/* DVB-RCC MAC Layer */
+#define IFT_DVBRCCDOWNSTREAM	   0x93	/* DVB-RCC Downstream Channel */
+#define IFT_DVBRCCUPSTREAM	   0x94	/* DVB-RCC Upstream Channel */
+#define IFT_ATMVIRTUAL		   0x95	/* ATM Virtual Interface */
+#define IFT_MPLSTUNNEL		   0x96	/* MPLS Tunnel Virtual Interface */
+#define IFT_SRP			   0x97	/* Spatial Reuse Protocol */
+#define IFT_VOICEOVERATM	   0x98	/* Voice over ATM */
+#define IFT_VOICEOVERFRAMERELAY	   0x99	/* Voice Over Frame Relay */
+#define IFT_IDSL		   0x9a	/* Digital Subscriber Loop over ISDN */
+#define IFT_COMPOSITELINK	   0x9b	/* Avici Composite Link Interface */
+#define IFT_SS7SIGLINK		   0x9c	/* SS7 Signaling Link */
+#define IFT_PROPWIRELESSP2P	   0x9d	/* Prop. P2P wireless interface */
+#define IFT_FRFORWARD		   0x9e	/* Frame forward Interface */
+#define IFT_RFC1483		   0x9f	/* Multiprotocol over ATM AAL5 */
+#define IFT_USB			   0xa0	/* USB Interface */
+#define IFT_IEEE8023ADLAG	   0xa1	/* IEEE 802.3ad Link Aggregate*/
+#define IFT_BGPPOLICYACCOUNTING	   0xa2	/* BGP Policy Accounting */
+#define IFT_FRF16MFRBUNDLE	   0xa3	/* FRF.16 Multilik Frame Relay*/
+#define IFT_H323GATEKEEPER	   0xa4	/* H323 Gatekeeper */
+#define IFT_H323PROXY		   0xa5	/* H323 Voice and Video Proxy */
+#define IFT_MPLS		   0xa6	/* MPLS */
+#define IFT_MFSIGLINK		   0xa7	/* Multi-frequency signaling link */
+#define IFT_HDSL2		   0xa8	/* High Bit-Rate DSL, 2nd gen. */
+#define IFT_SHDSL		   0xa9	/* Multirate HDSL2 */
+#define IFT_DS1FDL		   0xaa	/* Facility Data Link (4Kbps) on a DS1*/
+#define IFT_POS			   0xab	/* Packet over SONET/SDH Interface */
+#define IFT_DVBASILN		   0xac	/* DVB-ASI Input */
+#define IFT_DVBASIOUT		   0xad	/* DVB-ASI Output */
+#define IFT_PLC			   0xae	/* Power Line Communications */
+#define IFT_NFAS		   0xaf	/* Non-Facility Associated Signaling */
+#define IFT_TR008		   0xb0	/* TROO8 */
+#define IFT_GR303RDT		   0xb1	/* Remote Digital Terminal */
+#define IFT_GR303IDT		   0xb2	/* Integrated Digital Terminal */
+#define IFT_ISUP		   0xb3	/* ISUP */
+#define IFT_PROPDOCSWIRELESSMACLAYER	   0xb4	/* prop/Wireless MAC Layer */
+#define IFT_PROPDOCSWIRELESSDOWNSTREAM	   0xb5	/* prop/Wireless Downstream */
+#define IFT_PROPDOCSWIRELESSUPSTREAM	   0xb6	/* prop/Wireless Upstream */
+#define IFT_HIPERLAN2		   0xb7	/* HIPERLAN Type 2 Radio Interface */
+#define IFT_PROPBWAP2MP		   0xb8	/* PropBroadbandWirelessAccess P2MP*/
+#define IFT_SONETOVERHEADCHANNEL   0xb9	/* SONET Overhead Channel */
+#define IFT_DIGITALWRAPPEROVERHEADCHANNEL  0xba	/* Digital Wrapper Overhead */
+#define IFT_AAL2		   0xbb	/* ATM adaptation layer 2 */
+#define IFT_RADIOMAC		   0xbc	/* MAC layer over radio links */
+#define IFT_ATMRADIO		   0xbd	/* ATM over radio links */
+#define IFT_IMT			   0xbe /* Inter-Machine Trunks */
+#define IFT_MVL			   0xbf /* Multiple Virtual Lines DSL */
+#define IFT_REACHDSL		   0xc0 /* Long Reach DSL */
+#define IFT_FRDLCIENDPT		   0xc1 /* Frame Relay DLCI End Point */
+#define IFT_ATMVCIENDPT		   0xc2 /* ATM VCI End Point */
+#define IFT_OPTICALCHANNEL	   0xc3 /* Optical Channel */
+#define IFT_OPTICALTRANSPORT	   0xc4 /* Optical Transport */
+#define IFT_PROPATM		   0xc5 /* Proprietary ATM */
+#define IFT_VOICEOVERCABLE	   0xc6 /* Voice Over Cable Interface */
+#define IFT_INFINIBAND		   0xc7 /* Infiniband */
+#define IFT_TELINK		   0xc8 /* TE Link */
+#define IFT_Q2931		   0xc9 /* Q.2931 */
+#define IFT_VIRTUALTG		   0xca /* Virtual Trunk Group */
+#define IFT_SIPTG		   0xcb /* SIP Trunk Group */
+#define IFT_SIPSIG		   0xcc /* SIP Signaling */
+#define IFT_DOCSCABLEUPSTREAMCHANNEL 0xcd /* CATV Upstream Channel */
+#define IFT_ECONET		   0xce /* Acorn Econet */
+#define IFT_PON155		   0xcf /* FSAN 155Mb Symetrical PON interface */
+#define IFT_PON622		   0xd0 /* FSAN 622Mb Symetrical PON interface */*/
+#define IFT_BRIDGE		   0xd1 /* Transparent bridge interface */
+#define IFT_LINEGROUP		   0xd2 /* Interface common to multiple lines */
+#define IFT_VOICEEMFGD		   0xd3 /* voice E&M Feature Group D */
+#define IFT_VOICEFGDEANA	   0xd4 /* voice FGD Exchange Access North American */
+#define IFT_VOICEDID		   0xd5 /* voice Direct Inward Dialing */
+#define IFT_STF			   0xd7	/* 6to4 interface */
+
+/* not based on IANA assignments - how should we treat these? */
+#define IFT_GIF		0xf0
+#define IFT_PVC		0xf1
+#define IFT_FAITH	0xf2
+#define IFT_PFLOG	0xf5		/* Packet filter logging */
+#define IFT_PFSYNC	0xf6		/* Packet filter state syncing */
+
+#endif /* !_NET_IF_TYPES_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/net/route.h b/ndk/build/platforms/android-1.5/common/include/net/route.h
new file mode 100644
index 0000000..a60df24
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/net/route.h
@@ -0,0 +1 @@
+#include <linux/route.h>
diff --git a/ndk/build/platforms/android-1.5/common/include/netdb.h b/ndk/build/platforms/android-1.5/common/include/netdb.h
new file mode 100644
index 0000000..b0c3b72
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/netdb.h
@@ -0,0 +1,253 @@
+/*-
+ * Copyright (c) 1980, 1983, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+/*
+ *      @(#)netdb.h	8.1 (Berkeley) 6/2/93
+ *      From: Id: netdb.h,v 8.9 1996/11/19 08:39:29 vixie Exp $
+ * $FreeBSD: /repoman/r/ncvs/src/include/netdb.h,v 1.41 2006/04/15 16:20:26 ume Exp $
+ */
+
+#ifndef _NETDB_H_
+#define _NETDB_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#ifndef _PATH_HEQUIV
+# define	_PATH_HEQUIV	"/system/etc/hosts.equiv"
+#endif
+#define	_PATH_HOSTS	"/system/etc/hosts"
+#define	_PATH_NETWORKS	"/system/etc/networks"
+#define	_PATH_PROTOCOLS	"/system/etc/protocols"
+#define	_PATH_SERVICES	"/system/etc/services"
+
+#define  MAXHOSTNAMELEN  256
+
+/* BIONIC-BEGIN */
+#define  h_errno   (*__get_h_errno())
+extern int*  __get_h_errno(void);
+/* BIONIC-END */
+
+/*
+ * Structures returned by network data base library.  All addresses are
+ * supplied in host order, and returned in network order (suitable for
+ * use in system calls).
+ */
+struct hostent {
+	char	*h_name;	/* official name of host */
+	char	**h_aliases;	/* alias list */
+	int	h_addrtype;	/* host address type */
+	int	h_length;	/* length of address */
+	char	**h_addr_list;	/* list of addresses from name server */
+#define	h_addr	h_addr_list[0]	/* address, for backward compatibility */
+};
+
+struct netent {
+	char		*n_name;	/* official name of net */
+	char		**n_aliases;	/* alias list */
+	int		n_addrtype;	/* net address type */
+	uint32_t	n_net;		/* network # */
+};
+
+struct servent {
+	char	*s_name;	/* official service name */
+	char	**s_aliases;	/* alias list */
+	int	s_port;		/* port # */
+	char	*s_proto;	/* protocol to use */
+};
+
+struct protoent {
+	char	*p_name;	/* official protocol name */
+	char	**p_aliases;	/* alias list */
+	int	p_proto;	/* protocol # */
+};
+
+struct addrinfo {
+	int	ai_flags;	/* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
+	int	ai_family;	/* PF_xxx */
+	int	ai_socktype;	/* SOCK_xxx */
+	int	ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+	socklen_t ai_addrlen;	/* length of ai_addr */
+	char	*ai_canonname;	/* canonical name for hostname */
+	struct	sockaddr *ai_addr;	/* binary address */
+	struct	addrinfo *ai_next;	/* next structure in linked list */
+};
+
+/*
+ * Error return codes from gethostbyname() and gethostbyaddr()
+ * (left in h_errno).
+ */
+
+#define	NETDB_INTERNAL	-1	/* see errno */
+#define	NETDB_SUCCESS	0	/* no problem */
+#define	HOST_NOT_FOUND	1 /* Authoritative Answer Host not found */
+#define	TRY_AGAIN	2 /* Non-Authoritative Host not found, or SERVERFAIL */
+#define	NO_RECOVERY	3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+#define	NO_DATA		4 /* Valid name, no data record of requested type */
+#define	NO_ADDRESS	NO_DATA		/* no address, look for MX record */
+
+/*
+ * Error return codes from getaddrinfo()
+ */
+#if 0
+/* obsoleted */
+#define	EAI_ADDRFAMILY	 1	/* address family for hostname not supported */
+#endif
+#define	EAI_AGAIN	 2	/* temporary failure in name resolution */
+#define	EAI_BADFLAGS	 3	/* invalid value for ai_flags */
+#define	EAI_FAIL	 4	/* non-recoverable failure in name resolution */
+#define	EAI_FAMILY	 5	/* ai_family not supported */
+#define	EAI_MEMORY	 6	/* memory allocation failure */
+#define	EAI_NODATA	 7	/* no address associated with hostname */
+#define	EAI_NONAME	 8	/* hostname nor servname provided, or not known */
+#define	EAI_SERVICE	 9	/* servname not supported for ai_socktype */
+#define	EAI_SOCKTYPE	10	/* ai_socktype not supported */
+#define	EAI_SYSTEM	11	/* system error returned in errno */
+#define	EAI_BADHINTS	12	/* invalid value for hints */
+#define	EAI_PROTOCOL	13	/* resolved protocol is unknown */
+#define	EAI_OVERFLOW	14	/* argument buffer overflow */
+#define	EAI_MAX		15
+
+/*
+ * Flag values for getaddrinfo()
+ */
+#define	AI_PASSIVE	0x00000001 /* get address to use bind() */
+#define	AI_CANONNAME	0x00000002 /* fill ai_canonname */
+#define	AI_NUMERICHOST	0x00000004 /* prevent host name resolution */
+#define	AI_NUMERICSERV	0x00000008 /* prevent service name resolution */
+/* valid flags for addrinfo (not a standard def, apps should not use it) */
+#define AI_MASK \
+    (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | \
+    AI_ADDRCONFIG)
+
+#define	AI_ALL		0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
+#define	AI_V4MAPPED_CFG	0x00000200 /* accept IPv4-mapped if kernel supports */
+#define	AI_ADDRCONFIG	0x00000400 /* only if any address is assigned */
+#define	AI_V4MAPPED	0x00000800 /* accept IPv4-mapped IPv6 address */
+/* special recommended flags for getipnodebyname */
+#define	AI_DEFAULT	(AI_V4MAPPED_CFG | AI_ADDRCONFIG)
+
+/*
+ * Constants for getnameinfo()
+ */
+#define	NI_MAXHOST	1025
+#define	NI_MAXSERV	32
+
+/*
+ * Flag values for getnameinfo()
+ */
+#define	NI_NOFQDN	0x00000001
+#define	NI_NUMERICHOST	0x00000002
+#define	NI_NAMEREQD	0x00000004
+#define	NI_NUMERICSERV	0x00000008
+#define	NI_DGRAM	0x00000010
+#if 0 /* obsolete */
+#define NI_WITHSCOPEID	0x00000020
+#endif
+
+/*
+ * Scope delimit character
+ */
+#define	SCOPE_DELIMITER	'%'
+
+__BEGIN_DECLS
+void endhostent(void);
+void endnetent(void);
+void endnetgrent(void);
+void endprotoent(void);
+void endservent(void);
+void freehostent(struct hostent *);
+struct hostent	*gethostbyaddr(const char *, int, int);
+int gethostbyaddr_r(const char *, int, int, struct hostent *, char *, size_t, struct hostent **, int *);
+struct hostent	*gethostbyname(const char *);
+int gethostbyname_r(const char *, struct hostent *, char *, size_t, struct hostent **, int *);
+struct hostent	*gethostbyname2(const char *, int);
+int gethostbyname2_r(const char *, int, struct hostent *, char *, size_t, struct hostent **, int *);
+struct hostent	*gethostent(void);
+int gethostent_r(struct hostent *, char *, size_t, struct hostent **, int *);
+struct hostent	*getipnodebyaddr(const void *, size_t, int, int *);
+struct hostent	*getipnodebyname(const char *, int, int, int *);
+struct netent	*getnetbyaddr(uint32_t, int);
+int getnetbyaddr_r(uint32_t, int, struct netent *, char *, size_t, struct netent**, int *);
+struct netent	*getnetbyname(const char *);
+int getnetbyname_r(const char *, struct netent *, char *, size_t, struct netent **, int *);
+struct netent	*getnetent(void);
+int getnetent_r(struct netent *, char *, size_t, struct netent **, int *);
+int getnetgrent(char **, char **, char **);
+struct protoent	*getprotobyname(const char *);
+int getprotobyname_r(const char *, struct protoent *, char *, size_t, struct protoent **);
+struct protoent	*getprotobynumber(int);
+int getprotobynumber_r(int, struct protoent *, char *, size_t, struct protoent **);
+struct protoent	*getprotoent(void);
+int getprotoent_r(struct protoent *, char *, size_t, struct protoent **);
+struct servent	*getservbyname(const char *, const char *);
+struct servent	*getservbyport(int, const char *);
+struct servent	*getservent(void);
+void herror(const char *);
+const char	*hstrerror(int);
+int innetgr(const char *, const char *, const char *, const char *);
+void sethostent(int);
+void setnetent(int);
+void setprotoent(int);
+int getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **);
+int getnameinfo(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t, int);
+void freeaddrinfo(struct addrinfo *);
+const char	*gai_strerror(int);
+void setnetgrent(const char *);
+void setservent(int);
+
+__END_DECLS
+
+#endif /* !_NETDB_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/netinet/ether.h b/ndk/build/platforms/android-1.5/common/include/netinet/ether.h
new file mode 100644
index 0000000..a1c9cbb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/netinet/ether.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#include <net/if_ether.h>
diff --git a/ndk/build/platforms/android-1.5/common/include/netinet/if_ether.h b/ndk/build/platforms/android-1.5/common/include/netinet/if_ether.h
new file mode 100644
index 0000000..700b9db
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/netinet/if_ether.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#ifndef ETHER_ADDR_LEN
+#define ETHER_ADDR_LEN ETH_ALEN
+#include <net/ethertypes.h>
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/netinet/in.h b/ndk/build/platforms/android-1.5/common/include/netinet/in.h
new file mode 100644
index 0000000..77ae506
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/netinet/in.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _NETINET_IN_H_
+#define _NETINET_IN_H_
+
+#include <endian.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+
+__BEGIN_DECLS
+
+#define IPPORT_RESERVED  1024
+
+extern int bindresvport (int sd, struct sockaddr_in *sin);
+
+__END_DECLS
+
+#endif /* _NETINET_IN_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/netinet/in6.h b/ndk/build/platforms/android-1.5/common/include/netinet/in6.h
new file mode 100644
index 0000000..e645c48
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/netinet/in6.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _NETINET_IN6_H
+#define _NETINET_IN6_H
+
+#include <linux/in6.h>
+
+#define IN6_IS_ADDR_UNSPECIFIED(a)	\
+	((*(const uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) &&	\
+	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[4]) == 0) &&	\
+	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[8]) == 0) &&	\
+	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[12]) == 0))
+
+#define IN6_IS_ADDR_LOOPBACK(a)		\
+	((*(const uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) &&	\
+	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[4]) == 0) &&	\
+	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[8]) == 0) &&	\
+	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[12]) == ntohl(1)))
+
+#define IN6_IS_ADDR_V4COMPAT(a)		\
+	((*(const uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) &&	\
+	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[4]) == 0) &&	\
+	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[8]) == 0) &&	\
+	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[12]) != 0) &&	\
+	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[12]) != ntohl(1)))
+
+#define IN6_IS_ADDR_V4MAPPED(a)		      \
+	((*(const uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) &&	\
+	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[4]) == 0) &&	\
+	 (*(const uint32_t *)(const void *)(&(a)->s6_addr[8]) == ntohl(0x0000ffff)))
+
+#define IN6_IS_ADDR_LINKLOCAL(a)	\
+	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
+
+#define IN6_IS_ADDR_SITELOCAL(a)	\
+	(((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
+
+#define IN6_IS_ADDR_MULTICAST(a)	\
+	(((__const uint8_t *) (a))[0] == 0xff)
+
+
+#define IPV6_ADDR_SCOPE_NODELOCAL       0x01
+#define IPV6_ADDR_SCOPE_INTFACELOCAL    0x01
+#define IPV6_ADDR_SCOPE_LINKLOCAL       0x02
+#define IPV6_ADDR_SCOPE_SITELOCAL       0x05
+#define IPV6_ADDR_SCOPE_ORGLOCAL        0x08
+#define IPV6_ADDR_SCOPE_GLOBAL          0x0e
+
+#define IPV6_ADDR_MC_SCOPE(a)	\
+	((a)->s6_addr[1] & 0x0f)
+
+#define IN6_IS_ADDR_MC_LINKLOCAL(a)	\
+	(IN6_IS_ADDR_MULTICAST(a) &&  \
+	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_LINKLOCAL))
+#define IN6_IS_ADDR_MC_SITELOCAL(a)     \
+	(IN6_IS_ADDR_MULTICAST(a) &&  \
+	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_SITELOCAL))
+#define IN6_IS_ADDR_MC_ORGLOCAL(a)     \
+	(IN6_IS_ADDR_MULTICAST(a) &&  \
+	 (IPV6_ADDR_MC_SCOPE(a) == IPV6_ADDR_SCOPE_ORGLOCAL))
+
+
+#define IN6_ARE_ADDR_EQUAL(a, b)			\
+    (memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
+
+#define INET6_ADDRSTRLEN 46
+
+#endif /* _NETINET_IN6_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/netinet/in_systm.h b/ndk/build/platforms/android-1.5/common/include/netinet/in_systm.h
new file mode 100644
index 0000000..ff53fb7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/netinet/in_systm.h
@@ -0,0 +1,59 @@
+/*	$NetBSD: in_systm.h,v 1.13 2005/12/10 23:36:23 elad Exp $	*/
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)in_systm.h	8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IN_SYSTM_H_
+#define _NETINET_IN_SYSTM_H_
+
+/*
+ * Miscellaneous internetwork
+ * definitions for kernel.
+ */
+
+/*
+ * Network types.
+ *
+ * Internally the system keeps counters in the headers with the bytes
+ * swapped so that VAX instructions will work on them.  It reverses
+ * the bytes before transmission at each protocol level.  The n_ types
+ * represent the types with the bytes in ``high-ender'' order.
+ */
+typedef u_int16_t n_short;		/* short as received from the net */
+typedef u_int32_t n_long;		/* long as received from the net */
+
+typedef u_int32_t n_time;		/* ms since 00:00 GMT, byte rev */
+
+#ifdef _KERNEL
+n_time	 iptime (void);
+#endif
+
+#endif /* !_NETINET_IN_SYSTM_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/netinet/ip.h b/ndk/build/platforms/android-1.5/common/include/netinet/ip.h
new file mode 100644
index 0000000..541905c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/netinet/ip.h
@@ -0,0 +1,275 @@
+/*	$OpenBSD: ip.h,v 1.12 2006/04/27 02:19:32 tedu Exp $	*/
+/*	$NetBSD: ip.h,v 1.9 1995/05/15 01:22:44 cgd Exp $	*/
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)ip.h	8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IP_H_
+#define _NETINET_IP_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <endian.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+__BEGIN_DECLS
+
+/*
+ * Definitions for internet protocol version 4.
+ * Per RFC 791, September 1981.
+ */
+#define	IPVERSION	4
+
+/*
+ * Structure of an internet header, naked of options.
+ */
+struct ip {
+#if BYTE_ORDER == LITTLE_ENDIAN
+	u_int32_t ip_hl:4,		/* header length */
+		  ip_v:4;		/* version */
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+	u_int32_t ip_v:4,		/* version */
+		  ip_hl:4;		/* header length */
+#endif
+	u_int8_t  ip_tos;		/* type of service */
+	u_int16_t ip_len;		/* total length */
+	u_int16_t ip_id;		/* identification */
+	u_int16_t ip_off;		/* fragment offset field */
+#define	IP_RF 0x8000			/* reserved fragment flag */
+#define	IP_DF 0x4000			/* dont fragment flag */
+#define	IP_MF 0x2000			/* more fragments flag */
+#define	IP_OFFMASK 0x1fff		/* mask for fragmenting bits */
+	u_int8_t  ip_ttl;		/* time to live */
+	u_int8_t  ip_p;			/* protocol */
+	u_int16_t ip_sum;		/* checksum */
+	struct	  in_addr ip_src, ip_dst; /* source and dest address */
+};
+
+#define	IP_MAXPACKET	65535		/* maximum packet size */
+
+/*
+ * Definitions for IP type of service (ip_tos)
+ */
+#define	IPTOS_LOWDELAY		0x10
+#define	IPTOS_THROUGHPUT	0x08
+#define	IPTOS_RELIABILITY	0x04
+/*	IPTOS_LOWCOST		0x02 XXX */
+#if 1
+/* ECN RFC3168 obsoletes RFC2481, and these will be deprecated soon. */
+#define IPTOS_CE		0x01	/* congestion experienced */
+#define IPTOS_ECT		0x02	/* ECN-capable transport */
+#endif
+
+/*
+ * Definitions for IP precedence (also in ip_tos) (hopefully unused)
+ */
+#define	IPTOS_PREC_NETCONTROL		0xe0
+#define	IPTOS_PREC_INTERNETCONTROL	0xc0
+#define	IPTOS_PREC_CRITIC_ECP		0xa0
+#define	IPTOS_PREC_FLASHOVERRIDE	0x80
+#define	IPTOS_PREC_FLASH		0x60
+#define	IPTOS_PREC_IMMEDIATE		0x40
+#define	IPTOS_PREC_PRIORITY		0x20
+#define	IPTOS_PREC_ROUTINE		0x00
+
+/*
+ * ECN (Explicit Congestion Notification) codepoints in RFC3168
+ * mapped to the lower 2 bits of the TOS field.
+ */
+#define	IPTOS_ECN_NOTECT	0x00	/* not-ECT */
+#define	IPTOS_ECN_ECT1		0x01	/* ECN-capable transport (1) */
+#define	IPTOS_ECN_ECT0		0x02	/* ECN-capable transport (0) */
+#define	IPTOS_ECN_CE		0x03	/* congestion experienced */
+#define	IPTOS_ECN_MASK		0x03	/* ECN field mask */
+
+/*
+ * Definitions for options.
+ */
+#define	IPOPT_COPIED(o)		((o)&0x80)
+#define	IPOPT_CLASS(o)		((o)&0x60)
+#define	IPOPT_NUMBER(o)		((o)&0x1f)
+
+#define	IPOPT_CONTROL		0x00
+#define	IPOPT_RESERVED1		0x20
+#define	IPOPT_DEBMEAS		0x40
+#define	IPOPT_RESERVED2		0x60
+
+#define	IPOPT_EOL		0		/* end of option list */
+#define	IPOPT_NOP		1		/* no operation */
+
+#define	IPOPT_RR		7		/* record packet route */
+#define	IPOPT_TS		68		/* timestamp */
+#define	IPOPT_SECURITY		130		/* provide s,c,h,tcc */
+#define	IPOPT_LSRR		131		/* loose source route */
+#define	IPOPT_SATID		136		/* satnet id */
+#define	IPOPT_SSRR		137		/* strict source route */
+
+/*
+ * Offsets to fields in options other than EOL and NOP.
+ */
+#define	IPOPT_OPTVAL		0		/* option ID */
+#define	IPOPT_OLEN		1		/* option length */
+#define	IPOPT_OFFSET		2		/* offset within option */
+#define	IPOPT_MINOFF		4		/* min value of above */
+
+/*
+ * Time stamp option structure.
+ */
+struct	ip_timestamp {
+	u_int8_t ipt_code;		/* IPOPT_TS */
+	u_int8_t ipt_len;		/* size of structure (variable) */
+	u_int8_t ipt_ptr;		/* index of current entry */
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+	u_int32_t ipt_flg:4,		/* flags, see below */
+		  ipt_oflw:4;		/* overflow counter */
+#endif
+#if _BYTE_ORDER == _BIG_ENDIAN
+	u_int32_t ipt_oflw:4,		/* overflow counter */
+		  ipt_flg:4;		/* flags, see below */
+#endif
+	union ipt_timestamp {
+	n_time	ipt_time[1];
+	struct	ipt_ta {
+		struct in_addr ipt_addr;
+		n_time ipt_time;
+	} ipt_ta[1];
+	} ipt_timestamp;
+};
+
+/* flag bits for ipt_flg */
+#define	IPOPT_TS_TSONLY		0		/* timestamps only */
+#define	IPOPT_TS_TSANDADDR	1		/* timestamps and addresses */
+#define	IPOPT_TS_PRESPEC	3		/* specified modules only */
+
+/* bits for security (not byte swapped) */
+#define	IPOPT_SECUR_UNCLASS	0x0000
+#define	IPOPT_SECUR_CONFID	0xf135
+#define	IPOPT_SECUR_EFTO	0x789a
+#define	IPOPT_SECUR_MMMM	0xbc4d
+#define	IPOPT_SECUR_RESTR	0xaf13
+#define	IPOPT_SECUR_SECRET	0xd788
+#define	IPOPT_SECUR_TOPSECRET	0x6bc5
+
+/*
+ * Internet implementation parameters.
+ */
+#define	MAXTTL		255		/* maximum time to live (seconds) */
+#define	IPDEFTTL	64		/* default ttl, from RFC 1340 */
+#define	IPFRAGTTL	60		/* time to live for frags, slowhz */
+#define	IPTTLDEC	1		/* subtracted when forwarding */
+
+#define	IP_MSS		576		/* default maximum segment size */
+
+/*
+ * This is the real IPv4 pseudo header, used for computing the TCP and UDP
+ * checksums. For the Internet checksum, struct ipovly can be used instead.
+ * For stronger checksums, the real thing must be used.
+ */
+struct ippseudo {
+	struct    in_addr ippseudo_src;	/* source internet address */
+	struct    in_addr ippseudo_dst;	/* destination internet address */
+	u_int8_t  ippseudo_pad;		/* pad, must be zero */
+	u_int8_t  ippseudo_p;		/* protocol */
+	u_int16_t ippseudo_len;		/* protocol length */
+};
+
+/* BIONIC addition: declarations matching the Linux kernel */
+/*                  some programs expect these...          */
+
+#define IPOPT_OPTVAL 0
+#define IPOPT_OLEN   1
+#define IPOPT_OFFSET 2
+#define IPOPT_MINOFF 4
+#define MAX_IPOPTLEN 40
+
+#define IPOPT_COPY		0x80
+#define IPOPT_CLASS_MASK	0x60
+#define IPOPT_NUMBER_MASK	0x1f
+
+#define	IPOPT_CONTROL		0x00
+#define	IPOPT_RESERVED1		0x20
+#define	IPOPT_MEASUREMENT	0x40
+#define	IPOPT_RESERVED2		0x60
+
+#define IPOPT_END	(0 |IPOPT_CONTROL)
+#define IPOPT_NOOP	(1 |IPOPT_CONTROL)
+#define IPOPT_SEC	(2 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_TIMESTAMP	(4 |IPOPT_MEASUREMENT)
+#define IPOPT_SID	(8 |IPOPT_CONTROL|IPOPT_COPY)
+#define IPOPT_RA	(20|IPOPT_CONTROL|IPOPT_COPY)
+
+struct iphdr {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+	uint8_t  ihl    :4,
+		 version:4;
+#elif defined (__BIG_ENDIAN_BITFIELD)
+	uint8_t  version:4,
+  		 ihl    :4;
+#else
+#error	"Please fix <asm/byteorder.h>"
+#endif
+	uint8_t	  tos;
+	uint16_t  tot_len;
+	uint16_t  id;
+	uint16_t  frag_off;
+	uint8_t   ttl;
+	uint8_t   protocol;
+	uint16_t  check;
+	int32_t   saddr;
+	int32_t   daddr;
+};
+
+struct ip_auth_hdr {
+	uint8_t  nexthdr;
+	uint8_t  hdrlen;
+	uint16_t reserved;
+	uint32_t spi;
+	uint32_t seq_no;
+	uint8_t  auth_data[0];
+};
+
+struct ip_esp_hdr {
+	uint32_t spi;
+	uint32_t seq_no;
+	uint8_t  enc_data[0];
+};
+
+struct ip_comp_hdr {
+	uint8_t  nexthdr;
+	uint8_t  flags;
+	uint16_t cpi;
+};
+
+__END_DECLS
+
+#endif /* _NETINET_IP_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/netinet/ip_icmp.h b/ndk/build/platforms/android-1.5/common/include/netinet/ip_icmp.h
new file mode 100644
index 0000000..7510592
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/netinet/ip_icmp.h
@@ -0,0 +1,214 @@
+/*	$OpenBSD: ip_icmp.h,v 1.21 2005/07/31 03:30:55 pascoe Exp $	*/
+/*	$NetBSD: ip_icmp.h,v 1.10 1996/02/13 23:42:28 christos Exp $	*/
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)ip_icmp.h	8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IP_ICMP_H_
+#define _NETINET_IP_ICMP_H_
+
+#include <netinet/ip.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/*
+ * Interface Control Message Protocol Definitions.
+ * Per RFC 792, September 1981.
+ * RFC 950, August 1985. (Address Mask Request / Reply)
+ * RFC 1256, September 1991. (Router Advertisement and Solicitation)
+ * RFC 1108, November 1991. (Param Problem, Missing Req. Option)
+ * RFC 1393, January 1993. (Traceroute)
+ * RFC 1475, June 1993. (Datagram Conversion Error)
+ * RFC 1812, June 1995. (adm prohib, host precedence, precedence cutoff)
+ * RFC 2002, October 1996. (Mobility changes to Router Advertisement)
+ */
+
+/*
+ * ICMP Router Advertisement data
+ */
+struct icmp_ra_addr {
+	uint32_t  ira_addr;
+	uint32_t  ira_preference;
+};
+
+/*
+ * Structure of an icmp header.
+ */
+struct icmp {
+	uint8_t  icmp_type;		/* type of message, see below */
+	uint8_t  icmp_code;		/* type sub code */
+	uint16_t icmp_cksum;		/* ones complement cksum of struct */
+	union {
+		uint8_t   ih_pptr;		/* ICMP_PARAMPROB */
+		struct in_addr ih_gwaddr;	/* ICMP_REDIRECT */
+		struct ih_idseq {
+			  uint16_t  icd_id;
+			  uint16_t  icd_seq;
+		} ih_idseq;
+		int32_t   ih_void;
+
+		/* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
+		struct ih_pmtu {
+			  uint16_t  ipm_void;
+			  uint16_t  ipm_nextmtu;
+		} ih_pmtu;
+
+		struct ih_rtradv {
+			uint8_t   irt_num_addrs;
+			uint8_t   irt_wpa;
+			uint16_t  irt_lifetime;
+		} ih_rtradv;
+	} icmp_hun;
+#define	icmp_pptr	  icmp_hun.ih_pptr
+#define	icmp_gwaddr	  icmp_hun.ih_gwaddr
+#define	icmp_id		  icmp_hun.ih_idseq.icd_id
+#define	icmp_seq	  icmp_hun.ih_idseq.icd_seq
+#define	icmp_void	  icmp_hun.ih_void
+#define	icmp_pmvoid	  icmp_hun.ih_pmtu.ipm_void
+#define	icmp_nextmtu	  icmp_hun.ih_pmtu.ipm_nextmtu
+#define	icmp_num_addrs	  icmp_hun.ih_rtradv.irt_num_addrs
+#define	icmp_wpa	  icmp_hun.ih_rtradv.irt_wpa
+#define	icmp_lifetime	  icmp_hun.ih_rtradv.irt_lifetime
+	union {
+		struct id_ts {
+			  uint32_t  its_otime;
+			  uint32_t  its_rtime;
+			  uint32_t  its_ttime;
+		} id_ts;
+		struct id_ip  {
+			  struct ip idi_ip;
+			  /* options and then 64 bits of data */
+		} id_ip;
+		uint32_t  id_mask;
+		int8_t	  id_data[1];
+	} icmp_dun;
+#define	icmp_otime	  icmp_dun.id_ts.its_otime
+#define	icmp_rtime	  icmp_dun.id_ts.its_rtime
+#define	icmp_ttime	  icmp_dun.id_ts.its_ttime
+#define	icmp_ip		  icmp_dun.id_ip.idi_ip
+#define	icmp_mask	  icmp_dun.id_mask
+#define	icmp_data	  icmp_dun.id_data
+};
+
+/*
+ * For IPv6 transition related ICMP errors.
+ */
+#define	ICMP_V6ADVLENMIN	(8 + sizeof(struct ip) + 40)
+#define	ICMP_V6ADVLEN(p)	(8 + ((p)->icmp_ip.ip_hl << 2) + 40)
+
+/*
+ * Lower bounds on packet lengths for various types.
+ * For the error advice packets must first insure that the
+ * packet is large enough to contain the returned ip header.
+ * Only then can we do the check to see if 64 bits of packet
+ * data have been returned, since we need to check the returned
+ * ip header length.
+ */
+#define	ICMP_MINLEN	8				/* abs minimum */
+#define	ICMP_TSLEN	(8 + 3 * sizeof (n_time))	/* timestamp */
+#define	ICMP_MASKLEN	12				/* address mask */
+#define	ICMP_ADVLENMIN	(8 + sizeof (struct ip) + 8)	/* min */
+#define	ICMP_ADVLEN(p)	(8 + ((p)->icmp_ip.ip_hl << 2) + 8)
+	/* N.B.: must separately check that ip_hl >= 5 */
+
+/*
+ * Definition of type and code field values.
+ *	http://www.iana.org/assignments/icmp-parameters
+ */
+#define	ICMP_ECHOREPLY		0		/* echo reply */
+#define	ICMP_UNREACH		3		/* dest unreachable, codes: */
+#define	ICMP_UNREACH_NET		0	/* bad net */
+#define	ICMP_UNREACH_HOST		1	/* bad host */
+#define	ICMP_UNREACH_PROTOCOL		2	/* bad protocol */
+#define	ICMP_UNREACH_PORT		3	/* bad port */
+#define	ICMP_UNREACH_NEEDFRAG		4	/* IP_DF caused drop */
+#define	ICMP_UNREACH_SRCFAIL		5	/* src route failed */
+#define	ICMP_UNREACH_NET_UNKNOWN	6	/* unknown net */
+#define	ICMP_UNREACH_HOST_UNKNOWN	7	/* unknown host */
+#define	ICMP_UNREACH_ISOLATED		8	/* src host isolated */
+#define	ICMP_UNREACH_NET_PROHIB		9	/* for crypto devs */
+#define	ICMP_UNREACH_HOST_PROHIB	10	/* ditto */
+#define	ICMP_UNREACH_TOSNET		11	/* bad tos for net */
+#define	ICMP_UNREACH_TOSHOST		12	/* bad tos for host */
+#define	ICMP_UNREACH_FILTER_PROHIB	13	/* prohibited access */
+#define	ICMP_UNREACH_HOST_PRECEDENCE	14	/* precedence violat'n*/
+#define	ICMP_UNREACH_PRECEDENCE_CUTOFF	15	/* precedence cutoff */
+#define	ICMP_SOURCEQUENCH	4		/* packet lost, slow down */
+#define	ICMP_REDIRECT		5		/* shorter route, codes: */
+#define	ICMP_REDIRECT_NET	0		/* for network */
+#define	ICMP_REDIRECT_HOST	1		/* for host */
+#define	ICMP_REDIRECT_TOSNET	2		/* for tos and net */
+#define	ICMP_REDIRECT_TOSHOST	3		/* for tos and host */
+#define	ICMP_ALTHOSTADDR	6		/* alternate host address */
+#define	ICMP_ECHO		8		/* echo service */
+#define	ICMP_ROUTERADVERT	9		/* router advertisement */
+#define	ICMP_ROUTERADVERT_NORMAL		0	/* normal advertisement */
+#define	ICMP_ROUTERADVERT_NOROUTE_COMMON	16	/* selective routing */
+#define	ICMP_ROUTERSOLICIT	10		/* router solicitation */
+#define	ICMP_TIMXCEED		11		/* time exceeded, code: */
+#define	ICMP_TIMXCEED_INTRANS	0		/* ttl==0 in transit */
+#define	ICMP_TIMXCEED_REASS	1		/* ttl==0 in reass */
+#define	ICMP_PARAMPROB		12		/* ip header bad */
+#define	ICMP_PARAMPROB_ERRATPTR 0		/* req. opt. absent */
+#define	ICMP_PARAMPROB_OPTABSENT 1		/* req. opt. absent */
+#define	ICMP_PARAMPROB_LENGTH	2		/* bad length */
+#define	ICMP_TSTAMP		13		/* timestamp request */
+#define	ICMP_TSTAMPREPLY	14		/* timestamp reply */
+#define	ICMP_IREQ		15		/* information request */
+#define	ICMP_IREQREPLY		16		/* information reply */
+#define	ICMP_MASKREQ		17		/* address mask request */
+#define	ICMP_MASKREPLY		18		/* address mask reply */
+#define	ICMP_TRACEROUTE		30		/* traceroute */
+#define	ICMP_DATACONVERR	31		/* data conversion error */
+#define	ICMP_MOBILE_REDIRECT	32		/* mobile host redirect */
+#define	ICMP_IPV6_WHEREAREYOU	33		/* IPv6 where-are-you */
+#define	ICMP_IPV6_IAMHERE	34		/* IPv6 i-am-here */
+#define	ICMP_MOBILE_REGREQUEST	35		/* mobile registration req */
+#define	ICMP_MOBILE_REGREPLY	36		/* mobile registration reply */
+#define	ICMP_SKIP		39		/* SKIP */
+#define	ICMP_PHOTURIS		40		/* Photuris */
+#define	ICMP_PHOTURIS_UNKNOWN_INDEX	1	/* unknown sec index */
+#define	ICMP_PHOTURIS_AUTH_FAILED	2	/* auth failed */
+#define	ICMP_PHOTURIS_DECRYPT_FAILED	3	/* decrypt failed */
+
+#define	ICMP_MAXTYPE		40
+
+#define	ICMP_INFOTYPE(type) \
+	((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
+	(type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
+	(type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
+	(type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
+	(type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
+
+__END_DECLS
+
+#endif /* _NETINET_IP_ICMP_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/netinet/tcp.h b/ndk/build/platforms/android-1.5/common/include/netinet/tcp.h
new file mode 100644
index 0000000..9adf904
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/netinet/tcp.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _NETINET_TCP_H
+#define _NETINET_TCP_H
+
+#include <endian.h>		/* Include *before* linux/tcp.h */
+#include <linux/tcp.h>
+
+#endif /* _NETINET_TCP_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/netinet/udp.h b/ndk/build/platforms/android-1.5/common/include/netinet/udp.h
new file mode 100644
index 0000000..25e0dfc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/netinet/udp.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _NETINET_UDP_H
+#define _NETINET_UDP_H
+
+/*
+ * We would include linux/udp.h, but it brings in too much other stuff
+ */
+
+#ifdef __FAVOR_BSD
+
+struct udphdr {
+    u_int16_t uh_sport;	/* source port */
+    u_int16_t uh_dport;	/* destination port */
+    u_int16_t uh_ulen;	/* udp length */
+    u_int16_t uh_sum;	/* udp checksum */
+};
+
+#else
+
+struct udphdr {
+    __u16  source;
+    __u16  dest;
+    __u16  len;
+    __u16  check;
+};
+
+#endif /* __FAVOR_BSD */
+
+#endif /* _NETINET_UDP_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/netpacket/packet.h b/ndk/build/platforms/android-1.5/common/include/netpacket/packet.h
new file mode 100644
index 0000000..b5e8e0e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/netpacket/packet.h
@@ -0,0 +1 @@
+#include <linux/if_packet.h>
diff --git a/ndk/build/platforms/android-1.5/common/include/new b/ndk/build/platforms/android-1.5/common/include/new
new file mode 100644
index 0000000..559308b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/new
@@ -0,0 +1,29 @@
+#ifndef __NEW__
+#define __NEW__
+
+#include <stddef.h>
+
+namespace std {
+    using ::size_t;
+
+    struct nothrow_t {};
+    extern const nothrow_t nothrow;
+}
+
+void* operator new(std::size_t);
+void* operator new[](std::size_t);
+void  operator delete(void*);
+void  operator delete[](void*);
+void* operator new(std::size_t, const std::nothrow_t&);
+void* operator new[](std::size_t, const std::nothrow_t&);
+void  operator delete(void*, const std::nothrow_t&);
+void  operator delete[](void*, const std::nothrow_t&);
+
+inline void* operator new(std::size_t, void* p) { return p; }
+inline void* operator new[](std::size_t, void* p) { return p; }
+
+// these next two are not really required, since exceptions are off
+inline void  operator delete(void*, void*) { }
+inline void  operator delete[](void*, void*) { }
+
+#endif // __NEW__
diff --git a/ndk/build/platforms/android-1.5/common/include/nsswitch.h b/ndk/build/platforms/android-1.5/common/include/nsswitch.h
new file mode 100644
index 0000000..d19d055
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/nsswitch.h
@@ -0,0 +1,236 @@
+/*	$NetBSD: nsswitch.h,v 1.18 2005/11/29 03:12:58 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1997, 1998, 1999, 2004 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Luke Mewburn.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 THE FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+#ifndef _NSSWITCH_H
+#define _NSSWITCH_H	1
+
+#include <sys/types.h>
+#include <stdarg.h>
+
+#define	NSS_MODULE_INTERFACE_VERSION	0
+
+#ifndef _PATH_NS_CONF
+#define _PATH_NS_CONF	"/etc/nsswitch.conf"
+#endif
+
+#define	NS_CONTINUE	0
+#define	NS_RETURN	1
+
+/*
+ * Layout of:
+ *	uint32_t ns_src.flags
+ */ 
+	/* nsswitch.conf status codes and nsdispatch(3) return values */
+#define	NS_SUCCESS	(1<<0)		/* entry was found */
+#define	NS_UNAVAIL	(1<<1)		/* source not responding, or corrupt */
+#define	NS_NOTFOUND	(1<<2)		/* source responded 'no such entry' */
+#define	NS_TRYAGAIN	(1<<3)		/* source busy, may respond to retrys */
+#define	NS_STATUSMASK	0x000000ff	/* bitmask to get the status flags */
+
+	/* internal nsdispatch(3) flags; not settable in nsswitch.conf(5)  */
+#define	NS_FORCEALL	(1<<8)		/* force all methods to be invoked; */
+
+/*
+ * Currently implemented sources.
+ */
+#define NSSRC_FILES	"files"		/* local files */
+#define	NSSRC_DNS	"dns"		/* DNS; IN for hosts, HS for others */
+#define	NSSRC_NIS	"nis"		/* YP/NIS */
+#define	NSSRC_COMPAT	"compat"	/* passwd,group in YP compat mode */
+
+/*
+ * Currently implemented databases.
+ */
+#define NSDB_HOSTS		"hosts"
+#define NSDB_GROUP		"group"
+#define NSDB_GROUP_COMPAT	"group_compat"
+#define NSDB_NETGROUP		"netgroup"
+#define NSDB_NETWORKS		"networks"
+#define NSDB_PASSWD		"passwd"
+#define NSDB_PASSWD_COMPAT	"passwd_compat"
+#define NSDB_SHELLS		"shells"
+
+/*
+ * Suggested databases to implement.
+ */
+#define NSDB_ALIASES		"aliases"
+#define NSDB_AUTH		"auth"
+#define NSDB_AUTOMOUNT		"automount"
+#define NSDB_BOOTPARAMS		"bootparams"
+#define NSDB_ETHERS		"ethers"
+#define NSDB_EXPORTS		"exports"
+#define NSDB_NETMASKS		"netmasks"
+#define NSDB_PHONES		"phones"
+#define NSDB_PRINTCAP		"printcap"
+#define NSDB_PROTOCOLS		"protocols"
+#define NSDB_REMOTE		"remote"
+#define NSDB_RPC		"rpc"
+#define NSDB_SENDMAILVARS	"sendmailvars"
+#define NSDB_SERVICES		"services"
+#define NSDB_TERMCAP		"termcap"
+#define NSDB_TTYS		"ttys"
+
+/*
+ * ns_dtab `callback' function signature.
+ */
+typedef	int (*nss_method)(void *, void *, va_list);
+
+/*
+ * ns_dtab - `nsswitch dispatch table'
+ * Contains an entry for each source and the appropriate function to call.
+ */
+typedef struct {
+	const char	 *src;
+	nss_method	 callback;
+	void		 *cb_data;
+} ns_dtab;
+
+/*
+ * Macros to help build an ns_dtab[]
+ */
+#define NS_FILES_CB(F,C)	{ NSSRC_FILES,	F,	__UNCONST(C) },
+#define NS_COMPAT_CB(F,C)	{ NSSRC_COMPAT,	F,	__UNCONST(C) },
+ 
+#ifdef HESIOD
+#   define NS_DNS_CB(F,C)	{ NSSRC_DNS,	F,	__UNCONST(C) },
+#else
+#   define NS_DNS_CB(F,C)
+#endif
+
+#ifdef YP
+#   define NS_NIS_CB(F,C)	{ NSSRC_NIS,	F,	__UNCONST(C) },
+#else
+#   define NS_NIS_CB(F,C)
+#endif
+
+/*
+ * ns_src - `nsswitch source'
+ * Used by the nsparser routines to store a mapping between a source
+ * and its dispatch control flags for a given database.
+ */
+typedef struct {
+	const char	*name;
+	uint32_t	 flags;
+} ns_src;
+
+
+/*
+ * Default sourcelists (if nsswitch.conf is missing, corrupt,
+ * or the requested database doesn't have an entry)
+ */
+extern const ns_src __nsdefaultsrc[];
+extern const ns_src __nsdefaultcompat[];
+extern const ns_src __nsdefaultcompat_forceall[];
+extern const ns_src __nsdefaultfiles[];
+extern const ns_src __nsdefaultfiles_forceall[];
+extern const ns_src __nsdefaultnis[];
+extern const ns_src __nsdefaultnis_forceall[];
+
+
+/*
+ * ns_mtab - `nsswitch method table'
+ * An nsswitch module provides a mapping from (database name, method name)
+ * tuples to the nss_method and associated callback data.  Effectively,
+ * ns_dtab, but used for dynamically loaded modules.
+ */
+typedef struct {
+	const char	*database;
+	const char	*name;
+	nss_method	 method;
+	void		*mdata;
+} ns_mtab;
+
+/*
+ * nss_module_register_fn - module registration function
+ *	called at module load
+ * nss_module_unregister_fn - module un-registration function
+ *	called at module unload
+ */
+typedef	void (*nss_module_unregister_fn)(ns_mtab *, u_int);
+typedef	ns_mtab *(*nss_module_register_fn)(const char *, u_int *,
+					   nss_module_unregister_fn *);
+
+#ifdef _NS_PRIVATE
+
+/*
+ * Private data structures for back-end nsswitch implementation.
+ */
+
+/*
+ * ns_dbt - `nsswitch database thang'
+ * For each database in /etc/nsswitch.conf there is a ns_dbt, with its
+ * name and a list of ns_src's containing the source information.
+ */
+typedef struct {
+	const char	*name;		/* name of database */
+	ns_src		*srclist;	/* list of sources */
+	u_int		 srclistsize;	/* size of srclist */
+} ns_dbt;
+
+/*
+ * ns_mod - `nsswitch module'
+ */
+typedef struct {
+	const char	*name;		/* module name */
+	void		*handle;	/* handle from dlopen() */
+	ns_mtab		*mtab;		/* method table */
+	u_int		 mtabsize;	/* size of mtab */
+					/* called to unload module */
+	nss_module_unregister_fn unregister;
+} ns_mod;
+
+#endif /* _NS_PRIVATE */
+
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int	nsdispatch(void *, const ns_dtab [], const char *,
+			const char *, const ns_src [], ...);
+
+#ifdef _NS_PRIVATE
+int		 _nsdbtaddsrc(ns_dbt *, const ns_src *);
+void		 _nsdbtdump(const ns_dbt *);
+int		 _nsdbtput(const ns_dbt *);
+void		 _nsyyerror(const char *);
+int		 _nsyylex(void);
+#endif /* _NS_PRIVATE */
+
+__END_DECLS
+
+#endif /* !_NSSWITCH_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/pathconf.h b/ndk/build/platforms/android-1.5/common/include/pathconf.h
new file mode 100644
index 0000000..4677f7b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/pathconf.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _PATHCONF_H_
+#define _PATHCONF_H_
+
+/* constants to be used for the 'name' paremeter of pathconf/fpathconf */
+
+#define  _PC_FILESIZEBITS       0x0000
+#define  _PC_LINK_MAX           0x0001
+#define  _PC_MAX_CANON          0x0002
+#define  _PC_MAX_INPUT          0x0003
+#define  _PC_NAME_MAX           0x0004
+#define  _PC_PATH_MAX           0x0005
+#define  _PC_PIPE_BUF           0x0006
+#define  _PC_2_SYMLINKS         0x0007
+#define  _PC_ALLOC_SIZE_MIN     0x0008
+#define  _PC_REC_INCR_XFER_SIZE 0x0009
+#define  _PC_REC_MAX_XFER_SIZE  0x000a
+#define  _PC_REC_MIN_XFER_SIZE  0x000b
+#define  _PC_REC_XFER_ALIGN     0x000c
+#define  _PC_SYMLINK_MAX        0x000d
+#define  _PC_CHOWN_RESTRICTED   0x000e
+#define  _PC_NO_TRUNC           0x000f
+#define  _PC_VDISABLE           0x0010
+#define  _PC_ASYNC_IO           0x0011
+#define  _PC_PRIO_IO            0x0012
+#define  _PC_SYNC_IO            0x0013
+
+extern long fpathconf(int fildes, int name);
+extern long pathconf(const char *path, int name);
+
+#endif /* _PATHCONF_H_ */
+
diff --git a/ndk/build/platforms/android-1.5/common/include/paths.h b/ndk/build/platforms/android-1.5/common/include/paths.h
new file mode 100644
index 0000000..a72162f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/paths.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 4. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)paths.h	8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _PATHS_H_
+#define	_PATHS_H_
+
+/* Default search path. */
+#define	_PATH_DEFPATH	"/usr/bin:/bin"
+/* All standard utilities path. */
+#define	_PATH_STDPATH \
+	"/usr/bin:/bin:/usr/sbin:/sbin"
+
+#define	_PATH_BSHELL	"/system/bin/sh"
+#define	_PATH_CONSOLE	"/dev/console"
+#define	_PATH_CSHELL	"/bin/csh"
+#define	_PATH_DEVDB	"/var/run/dev.db"
+#define	_PATH_DEVNULL	"/dev/null"
+#define	_PATH_DRUM	"/dev/drum"
+#define	_PATH_KLOG	"/proc/kmsg"
+#define	_PATH_KMEM	"/dev/kmem"
+#define	_PATH_LASTLOG	"/var/log/lastlog"
+#define	_PATH_MAILDIR	"/var/mail"
+#define	_PATH_MAN	"/usr/share/man"
+#define	_PATH_MEM	"/dev/mem"
+#define	_PATH_MNTTAB	"/etc/fstab"
+#define	_PATH_MOUNTED	"/etc/mtab"
+#define	_PATH_NOLOGIN	"/etc/nologin"
+#define	_PATH_PRESERVE	"/var/lib"
+#define	_PATH_RWHODIR	"/var/spool/rwho"
+#define	_PATH_SENDMAIL	"/usr/sbin/sendmail"
+#define	_PATH_SHADOW	"/etc/shadow"
+#define	_PATH_SHELLS	"/etc/shells"
+#define	_PATH_TTY	"/dev/tty"
+#define	_PATH_UNIX	"/boot/vmlinux"
+#define _PATH_UTMP	"/var/run/utmp"
+#define	_PATH_VI	"/bin/vi"
+#define _PATH_WTMP	"/var/log/wtmp"
+
+/* Provide trailing slash, since mostly used for building pathnames. */
+#define	_PATH_DEV	"/dev/"
+#define	_PATH_TMP	"/tmp/"
+#define	_PATH_VARDB	"/var/db/"
+#define	_PATH_VARRUN	"/var/run/"
+#define	_PATH_VARTMP	"/var/tmp/"
+
+#endif /* !_PATHS_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/poll.h b/ndk/build/platforms/android-1.5/common/include/poll.h
new file mode 100644
index 0000000..560be89
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/poll.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _POLL_H_
+#define _POLL_H_
+
+#include <sys/cdefs.h>
+#include <linux/poll.h>
+
+__BEGIN_DECLS
+
+typedef unsigned int  nfds_t;
+
+/* POSIX specifies "int" for the timeout, Linux seems to use long... */
+extern int poll(struct pollfd *, nfds_t, long);
+
+__END_DECLS
+
+#endif /* _POLL_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/pthread.h b/ndk/build/platforms/android-1.5/common/include/pthread.h
new file mode 100644
index 0000000..e3afdae
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/pthread.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _PTHREAD_H_
+#define _PTHREAD_H_
+
+#include <time.h>
+#include <signal.h>
+#include <sched.h>
+#include <limits.h>
+#include <sys/types.h>
+
+/*
+ * Types
+ */
+typedef struct
+{
+    int volatile value;
+} pthread_mutex_t;
+
+#define  PTHREAD_MUTEX_INITIALIZER             {0}
+#define  PTHREAD_RECURSIVE_MUTEX_INITIALIZER   {0x4000}
+#define  PTHREAD_ERRORCHECK_MUTEX_INITIALIZER  {0x8000}
+
+enum {
+    PTHREAD_MUTEX_NORMAL = 0,
+    PTHREAD_MUTEX_RECURSIVE = 1,
+    PTHREAD_MUTEX_ERRORCHECK = 2,
+
+    PTHREAD_MUTEX_ERRORCHECK_NP = PTHREAD_MUTEX_ERRORCHECK,
+    PTHREAD_MUTEX_RECURSIVE_NP  = PTHREAD_MUTEX_RECURSIVE,
+
+    PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
+};
+
+
+
+typedef struct
+{
+    int volatile value;
+} pthread_cond_t;
+
+typedef struct
+{
+    uint32_t flags;
+    void * stack_base;
+    size_t stack_size;
+    size_t guard_size;
+    int32_t sched_policy;
+    int32_t sched_priority;
+} pthread_attr_t;
+
+typedef long pthread_mutexattr_t;
+typedef long pthread_condattr_t;
+
+typedef int pthread_key_t;
+typedef long pthread_t;
+
+typedef volatile int  pthread_once_t;
+
+/*
+ * Defines
+ */
+#define PTHREAD_COND_INITIALIZER  {0}
+
+#define PTHREAD_STACK_MIN (2 * PAGE_SIZE)
+
+#define PTHREAD_CREATE_DETACHED  0x00000001
+#define PTHREAD_CREATE_JOINABLE  0x00000000
+
+#define PTHREAD_ONCE_INIT    0
+
+#define PTHREAD_PROCESS_PRIVATE  0
+#define PTHREAD_PROCESS_SHARED   1
+
+#define PTHREAD_SCOPE_SYSTEM     0
+#define PTHREAD_SCOPE_PROCESS    1
+
+/*
+ * Prototypes
+ */
+#if __cplusplus
+extern "C" {
+#endif
+
+int pthread_attr_init(pthread_attr_t * attr);
+int pthread_attr_destroy(pthread_attr_t * attr);
+
+int pthread_attr_setdetachstate(pthread_attr_t * attr, int state);
+int pthread_attr_getdetachstate(pthread_attr_t const * attr, int * state);
+
+int pthread_attr_setschedpolicy(pthread_attr_t * attr, int policy);
+int pthread_attr_getschedpolicy(pthread_attr_t const * attr, int * policy);
+
+int pthread_attr_setschedparam(pthread_attr_t * attr, struct sched_param const * param);
+int pthread_attr_getschedparam(pthread_attr_t const * attr, struct sched_param * param);
+
+int pthread_attr_setstacksize(pthread_attr_t * attr, size_t stack_size);
+int pthread_attr_getstacksize(pthread_attr_t const * attr, size_t * stack_size);
+
+int pthread_attr_setstackaddr(pthread_attr_t * attr, void * stackaddr);
+int pthread_attr_getstackaddr(pthread_attr_t const * attr, void ** stackaddr);
+
+int pthread_attr_setstack(pthread_attr_t * attr, void * stackaddr, size_t stack_size);
+int pthread_attr_getstack(pthread_attr_t const * attr, void ** stackaddr, size_t * stack_size);
+
+int pthread_attr_setguardsize(pthread_attr_t * attr, size_t guard_size);
+int pthread_attr_getguardsize(pthread_attr_t const * attr, size_t * guard_size);
+
+int pthread_attr_setscope(pthread_attr_t *attr, int  scope);
+int pthread_attr_getscope(pthread_attr_t const *attr);
+
+int pthread_getattr_np(pthread_t thid, pthread_attr_t * attr);
+
+int pthread_create(pthread_t *thread, pthread_attr_t const * attr,
+                   void *(*start_routine)(void *), void * arg);
+void pthread_exit(void * retval);
+int pthread_join(pthread_t thid, void ** ret_val);
+int pthread_detach(pthread_t  thid);
+
+pthread_t pthread_self(void);
+int pthread_equal(pthread_t one, pthread_t two);
+
+int pthread_getschedparam(pthread_t thid, int * policy,
+                          struct sched_param * param);
+int pthread_setschedparam(pthread_t thid, int poilcy,
+                          struct sched_param const * param);
+
+int pthread_mutexattr_init(pthread_mutexattr_t *attr);
+int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
+int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type);
+int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
+int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int  pshared);
+int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared);
+
+int pthread_mutex_init(pthread_mutex_t *mutex,
+                       const pthread_mutexattr_t *attr);
+int pthread_mutex_destroy(pthread_mutex_t *mutex);
+int pthread_mutex_lock(pthread_mutex_t *mutex);
+int pthread_mutex_unlock(pthread_mutex_t *mutex);
+int pthread_mutex_trylock(pthread_mutex_t *mutex);
+int pthread_mutex_timedlock(pthread_mutex_t *mutex, struct timespec*  ts);
+
+int pthread_cond_init(pthread_cond_t *cond,
+                      const pthread_condattr_t *attr);
+int pthread_cond_destroy(pthread_cond_t *cond);
+int pthread_cond_broadcast(pthread_cond_t *cond);
+int pthread_cond_signal(pthread_cond_t *cond);
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
+int pthread_cond_timedwait(pthread_cond_t *cond,
+                           pthread_mutex_t * mutex,
+                           const struct timespec *abstime);
+
+/* BIONIC: same as pthread_cond_timedwait, except the 'abstime' given refers
+ *         to the CLOCK_MONOTONIC clock instead, to avoid any problems when
+ *         the wall-clock time is changed brutally
+ */
+int pthread_cond_timedwait_monotonic(pthread_cond_t         *cond,
+                                     pthread_mutex_t        *mutex,
+                                     const struct timespec  *abstime);
+
+int pthread_cond_timeout_np(pthread_cond_t *cond,
+                            pthread_mutex_t * mutex,
+                            unsigned msecs);
+
+int pthread_key_create(pthread_key_t *key, void (*destructor_function)(void *));
+int pthread_key_delete (pthread_key_t);
+int pthread_setspecific(pthread_key_t key, const void *value);
+void *pthread_getspecific(pthread_key_t key);
+
+int pthread_kill(pthread_t tid, int sig);
+int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset);
+
+int pthread_getcpuclockid(pthread_t  tid, clockid_t  *clockid);
+
+int pthread_once(pthread_once_t  *once_control, void (*init_routine)(void));
+
+typedef void  (*__pthread_cleanup_func_t)(void*);
+
+typedef struct __pthread_cleanup_t {
+    struct __pthread_cleanup_t*   __cleanup_prev;
+    __pthread_cleanup_func_t      __cleanup_routine;
+    void*                         __cleanup_arg;
+} __pthread_cleanup_t;
+
+extern void  __pthread_cleanup_push(__pthread_cleanup_t*      c,
+                                    __pthread_cleanup_func_t  routine,
+                                    void*                     arg);
+
+extern void  __pthread_cleanup_pop(__pthread_cleanup_t*  c,
+                                   int                   execute);
+
+/* Believe or not, the definitions of pthread_cleanup_push and
+ * pthread_cleanup_pop below are correct. Posix states that these
+ * can be implemented as macros that might introduce opening and
+ * closing braces, and that using setjmp/longjmp/return/break/continue
+ * between them results in undefined behaviour.
+ *
+ * And indeed, GLibc and other C libraries use a similar definition
+ */
+#define  pthread_cleanup_push(routine, arg)                      \
+    do {                                                         \
+        __pthread_cleanup_t  __cleanup;                          \
+        __pthread_cleanup_push( &__cleanup, (routine), (arg) );  \
+
+#define  pthread_cleanup_pop(execute)                  \
+        __pthread_cleanup_pop( &__cleanup, (execute)); \
+    } while (0);
+
+#if __cplusplus
+} /* extern "C" */
+#endif
+
+/************ TO FIX ************/
+
+#define LONG_LONG_MAX __LONG_LONG_MAX__
+#define LONG_LONG_MIN (-__LONG_LONG_MAX__ - 1)
+
+#endif // _PTHREAD_H_
diff --git a/ndk/build/platforms/android-1.5/common/include/pwd.h b/ndk/build/platforms/android-1.5/common/include/pwd.h
new file mode 100644
index 0000000..6f3fad5
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/pwd.h
@@ -0,0 +1,125 @@
+/*-
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)pwd.h	8.2 (Berkeley) 1/21/94
+ */
+
+/*-
+ * Portions Copyright(C) 1995, Jason Downs.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 THE AUTHOR(S) 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.
+ */
+
+#ifndef _PWD_H_
+#define _PWD_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#define _PATH_PASSWD        "/etc/passwd"
+#define _PATH_MASTERPASSWD  "/etc/master.passwd"
+#define _PATH_MASTERPASSWD_LOCK "/etc/ptmp"
+
+#define _PATH_PASSWD_CONF   "/etc/passwd.conf"
+#define _PATH_PASSWDCONF    _PATH_PASSWD_CONF   /* XXX: compat */
+#define _PATH_USERMGMT_CONF "/etc/usermgmt.conf"
+
+#define _PATH_MP_DB     "/etc/pwd.db"
+#define _PATH_SMP_DB        "/etc/spwd.db"
+
+#define _PATH_PWD_MKDB      "/usr/sbin/pwd_mkdb"
+
+#define _PW_KEYBYNAME       '1' /* stored by name */
+#define _PW_KEYBYNUM        '2' /* stored by entry in the "file" */
+#define _PW_KEYBYUID        '3' /* stored by uid */
+
+#define _PASSWORD_EFMT1     '_' /* extended DES encryption format */
+#define _PASSWORD_NONDES    '$' /* non-DES encryption formats */
+
+#define _PASSWORD_LEN       128 /* max length, not counting NUL */
+
+#define _PASSWORD_NOUID     0x01    /* flag for no specified uid. */
+#define _PASSWORD_NOGID     0x02    /* flag for no specified gid. */
+#define _PASSWORD_NOCHG     0x04    /* flag for no specified change. */
+#define _PASSWORD_NOEXP     0x08    /* flag for no specified expire. */
+
+#define _PASSWORD_OLDFMT    0x10    /* flag to expect an old style entry */
+#define _PASSWORD_NOWARN    0x20    /* no warnings for bad entries */
+
+#define _PASSWORD_WARNDAYS  14  /* days to warn about expiry */
+#define _PASSWORD_CHGNOW    -1  /* special day to force password change at next login */
+
+struct passwd
+{
+    char* pw_name;
+    char* pw_passwd;
+    uid_t pw_uid;
+    gid_t pw_gid;
+    char* pw_dir;
+    char* pw_shell;
+};
+
+__BEGIN_DECLS
+
+struct passwd* getpwnam(const char*);
+struct passwd* getpwuid(uid_t);
+
+int getpwnam_r(const char*, struct passwd*, char*, size_t, struct passwd**);
+int getpwuid_r(uid_t, struct passwd*, char*, size_t, struct passwd**);
+
+void endpwent(void);
+struct passwd* getpwent(void);
+int setpwent(void);
+
+__END_DECLS
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/resolv.h b/ndk/build/platforms/android-1.5/common/include/resolv.h
new file mode 100644
index 0000000..4247d68
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/resolv.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _RESOLV_H_
+#define _RESOLV_H_
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/cdefs.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <arpa/nameser.h>
+
+__BEGIN_DECLS
+
+struct res_state;
+
+extern struct __res_state *__res_state(void);
+#define _res (*__res_state())
+
+/* Base-64 functions - because some code expects it there */
+
+#define b64_ntop        __b64_ntop
+#define b64_pton        __b64_pton
+extern int   b64_ntop(u_char const *, size_t, char *, size_t);
+extern int   b64_pton(char const *, u_char *, size_t);
+
+__END_DECLS
+
+#endif /* _RESOLV_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sched.h b/ndk/build/platforms/android-1.5/common/include/sched.h
new file mode 100644
index 0000000..6600bae
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sched.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SCHED_H_
+#define _SCHED_H_
+
+#include <sys/cdefs.h>
+#include <sys/time.h>
+
+__BEGIN_DECLS
+
+#define SCHED_NORMAL            0
+#define SCHED_OTHER             0
+#define SCHED_FIFO              1
+#define SCHED_RR                2
+
+struct sched_param {
+    int sched_priority;
+};
+
+extern int sched_setscheduler(pid_t, int, const struct sched_param *);
+extern int sched_getscheduler(pid_t);
+extern int sched_yield(void);
+extern int sched_get_priority_max(int policy);
+extern int sched_get_priority_min(int policy);
+extern int sched_setparam(pid_t, const struct sched_param *);
+extern int sched_getparam(pid_t, struct sched_param *);
+extern int sched_rr_get_interval(pid_t pid, struct timespec *tp);
+
+#define CLONE_VM             0x00000100
+#define CLONE_FS             0x00000200
+#define CLONE_FILES          0x00000400
+#define CLONE_SIGHAND        0x00000800
+#define CLONE_PTRACE         0x00002000
+#define CLONE_VFORK          0x00004000
+#define CLONE_PARENT         0x00008000
+#define CLONE_THREAD         0x00010000
+#define CLONE_NEWNS          0x00020000
+#define CLONE_SYSVSEM        0x00040000
+#define CLONE_SETTLS         0x00080000
+#define CLONE_PARENT_SETTID  0x00100000
+#define CLONE_CHILD_CLEARTID 0x00200000
+#define CLONE_DETACHED       0x00400000
+#define CLONE_UNTRACED       0x00800000
+#define CLONE_CHILD_SETTID   0x01000000
+#define CLONE_STOPPED        0x02000000
+
+extern int    clone(int (*fn)(void*), void *child_stack, int flags, void *arg);
+extern pid_t  __clone(int, void *);
+
+__END_DECLS
+
+#endif /* _SCHED_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/semaphore.h b/ndk/build/platforms/android-1.5/common/include/semaphore.h
new file mode 100644
index 0000000..30e3123
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/semaphore.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SEMAPHORE_H
+#define _SEMAPHORE_H
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+typedef struct {
+    volatile unsigned int  count;
+} sem_t;
+
+#define  SEM_FAILED  NULL
+
+extern int sem_init(sem_t *sem, int pshared, unsigned int value);
+
+extern int    sem_close(sem_t *);
+extern int    sem_destroy(sem_t *);
+extern int    sem_getvalue(sem_t *, int *);
+extern int    sem_init(sem_t *, int, unsigned int);
+extern sem_t *sem_open(const char *, int, ...);
+extern int    sem_post(sem_t *);
+extern int    sem_trywait(sem_t *);
+extern int    sem_unlink(const char *);
+extern int    sem_wait(sem_t *);
+
+struct timespec;
+extern int    sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
+
+__END_DECLS
+
+#endif /* _SEMAPHORE_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/setjmp.h b/ndk/build/platforms/android-1.5/common/include/setjmp.h
new file mode 100644
index 0000000..68fdcef
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/setjmp.h
@@ -0,0 +1,63 @@
+/*	$OpenBSD: setjmp.h,v 1.5 2005/12/13 00:35:22 millert Exp $	*/
+/*	$NetBSD: setjmp.h,v 1.11 1994/12/20 10:35:44 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)setjmp.h	8.2 (Berkeley) 1/21/94
+ */
+
+#ifndef _SETJMP_H_
+#define _SETJMP_H_
+
+#include <sys/cdefs.h>
+#include <machine/setjmp.h>
+
+typedef long sigjmp_buf[_JBLEN + 1];
+typedef long jmp_buf[_JBLEN];
+
+__BEGIN_DECLS
+
+int     _setjmp(jmp_buf);
+void    _longjmp(jmp_buf, int);
+void    longjmperror(void);
+
+int     setjmp(jmp_buf);
+void    longjmp(jmp_buf, int);
+
+int     sigsetjmp(sigjmp_buf, int);
+void    siglongjmp(sigjmp_buf, int);
+
+__END_DECLS
+
+#endif /* !_SETJMP_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sgtty.h b/ndk/build/platforms/android-1.5/common/include/sgtty.h
new file mode 100644
index 0000000..1ac3100
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sgtty.h
@@ -0,0 +1,48 @@
+/*	$NetBSD: sgtty.h,v 1.8 2005/02/03 04:39:32 perry Exp $	*/
+
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)sgtty.h	8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _SGTTY_H_
+#define _SGTTY_H_
+
+#ifndef USE_OLD_TTY
+#define	USE_OLD_TTY
+#endif
+#include <sys/ioctl.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int gtty(int, struct sgttyb *);
+int stty(int, struct sgttyb *);
+__END_DECLS
+
+#endif /* _SGTTY_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sha1.h b/ndk/build/platforms/android-1.5/common/include/sha1.h
new file mode 100644
index 0000000..f7ada46
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sha1.h
@@ -0,0 +1,31 @@
+/*	$NetBSD: sha1.h,v 1.13 2005/12/26 18:41:36 perry Exp $	*/
+
+/*
+ * SHA-1 in C
+ * By Steve Reid <steve@edmweb.com>
+ * 100% Public Domain
+ */
+
+#ifndef _SYS_SHA1_H_
+#define	_SYS_SHA1_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#define SHA1_DIGEST_LENGTH		20
+#define SHA1_DIGEST_STRING_LENGTH	41
+
+typedef struct {
+	uint32_t state[5];
+	uint32_t count[2];
+	u_char buffer[64];
+} SHA1_CTX;
+
+__BEGIN_DECLS
+void	SHA1Transform(uint32_t[5], const u_char[64]);
+void	SHA1Init(SHA1_CTX *);
+void	SHA1Update(SHA1_CTX *, const u_char *, u_int);
+void	SHA1Final(u_char[SHA1_DIGEST_LENGTH], SHA1_CTX *);
+__END_DECLS
+
+#endif /* _SYS_SHA1_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/signal.h b/ndk/build/platforms/android-1.5/common/include/signal.h
new file mode 100644
index 0000000..5540847
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/signal.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SIGNAL_H_
+#define _SIGNAL_H_
+
+#include <sys/cdefs.h>
+#include <limits.h>		/* For LONG_BIT */
+#include <string.h>		/* For memset() */
+#include <sys/types.h>
+#include <asm/signal.h>
+
+#define __ARCH_SI_UID_T __kernel_uid32_t
+#include <asm/siginfo.h>
+#undef __ARCH_SI_UID_T
+
+__BEGIN_DECLS
+
+typedef int sig_atomic_t;
+
+/* crepy NIG / _NSIG handling, just to be safe */
+#ifndef NSIG
+#  define NSIG  _NSIG
+#endif
+#ifndef _NSIG
+#  define _NSIG  NSIG
+#endif
+
+extern const char * const sys_siglist[];
+
+static __inline__ int sigismember(sigset_t *set, int signum)
+{
+    unsigned long *local_set = (unsigned long *)set;
+    signum--;
+    return (int)((local_set[signum/LONG_BIT] >> (signum%LONG_BIT)) & 1);
+}
+
+
+static __inline__ int sigaddset(sigset_t *set, int signum)
+{
+    unsigned long *local_set = (unsigned long *)set;
+    signum--;
+    local_set[signum/LONG_BIT] |= 1UL << (signum%LONG_BIT);
+    return 0;
+}
+
+
+static __inline__ int sigdelset(sigset_t *set, int signum)
+{
+    unsigned long *local_set = (unsigned long *)set;
+    signum--;
+    local_set[signum/LONG_BIT] &= ~(1UL << (signum%LONG_BIT));
+    return 0;
+}
+
+
+static __inline__ int sigemptyset(sigset_t *set)
+{
+    memset(set, 0, sizeof *set);
+    return 0;
+}
+
+static __inline__ int sigfillset(sigset_t *set)
+{
+    memset(set, ~0, sizeof *set);
+    return 0;
+}
+
+
+/* compatibility types */
+typedef void  (*sig_t)(int);
+typedef sig_t sighandler_t;
+
+/* differentiater between sysv and bsd behaviour 8*/
+extern __sighandler_t sysv_signal(int, __sighandler_t);
+extern __sighandler_t bsd_signal(int, __sighandler_t);
+
+/* the default is bsd */
+static __inline__ __sighandler_t signal(int s, __sighandler_t f)
+{
+    return bsd_signal(s,f);
+}
+
+/* the syscall itself */
+extern __sighandler_t __signal(int, __sighandler_t, int);
+
+extern int sigprocmask(int, const sigset_t *, sigset_t *);
+extern int sigaction(int, const struct sigaction *, struct sigaction *);
+
+extern int sigpending(sigset_t *);
+extern int sigsuspend(const sigset_t *);
+extern int sigwait(const sigset_t *set, int *sig);
+extern int siginterrupt(int  sig, int  flag);
+
+extern int raise(int);
+extern int kill(pid_t, int);
+
+
+__END_DECLS
+
+#endif /* _SIGNAL_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/stdint.h b/ndk/build/platforms/android-1.5/common/include/stdint.h
new file mode 100644
index 0000000..39a8ab8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/stdint.h
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _STDINT_H
+#define _STDINT_H
+
+#include <stddef.h>
+#include <sys/_types.h>
+
+
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
+#  define __STDINT_LIMITS
+#endif
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
+#  define  __STDINT_MACROS
+#endif
+
+/* the definitions of STDINT_LIMITS depend on those of STDINT_MACROS */
+#if defined __STDINT_LIMITS && !defined __STDINT_MACROS
+#  define  __STDINT_MACROS
+#endif
+
+typedef __int8_t      int8_t;
+typedef __uint8_t     uint8_t;
+typedef __int16_t     int16_t;
+typedef __uint16_t    uint16_t;
+typedef __int32_t     int32_t;
+typedef __uint32_t    uint32_t;
+#if !defined(__STRICT_ANSI__)
+typedef __int64_t     int64_t;
+typedef __uint64_t    uint64_t;
+#endif
+
+/*
+ * int8_t & uint8_t
+ */
+
+typedef int8_t        int_least8_t;
+typedef int8_t        int_fast8_t;
+
+typedef uint8_t       uint_least8_t;
+typedef uint8_t       uint_fast8_t;
+
+#ifdef __STDINT_LIMITS
+#  define INT8_MIN         (-128)
+#  define INT8_MAX         (127)
+#  define INT_LEAST8_MIN   INT8_MIN
+#  define INT_LEAST8_MAX   INT8_MAX
+#  define INT_FAST8_MIN    INT8_MIN
+#  define INT_FAST8_MAX    INT8_MAX
+
+#  define UINT8_MAX           (255U)
+#  define UINT_LEAST8_MAX     UINT8_MAX
+#  define UINT_FAST8_MAX      UINT8_MAX
+#endif
+
+#ifdef __STDINT_MACROS
+#  define INT8_C(c)	c
+#  define INT_LEAST8_C(c)	 INT8_C(c)
+#  define INT_FAST8_C(c)	INT8_C(c)
+
+#  define UINT8_C(c)	c ## U
+#  define UINT_LEAST8_C(c)  UINT8_C(c)
+#  define UINT_FAST8_C(c)  UINT8_C(c)
+#endif
+
+/*
+ * int16_t & uint16_t
+ */
+
+
+typedef int16_t       int_least16_t;
+typedef int32_t       int_fast16_t;
+
+typedef uint16_t      uint_least16_t;
+typedef uint32_t      uint_fast16_t;
+
+#ifdef __STDINT_LIMITS
+#  define INT16_MIN	(-32768)
+#  define INT16_MAX	(32767)
+#  define INT_LEAST16_MIN	INT16_MIN
+#  define INT_LEAST16_MAX	INT16_MAX
+#  define INT_FAST16_MIN	INT32_MIN
+#  define INT_FAST16_MAX	INT32_MAX
+
+#  define UINT16_MAX	(65535U)
+#  define UINT_LEAST16_MAX UINT16_MAX
+#  define UINT_FAST16_MAX UINT32_MAX
+#endif
+
+#ifdef __STDINT_MACROS
+#  define INT16_C(c)	c
+#  define INT_LEAST16_C(c) INT16_C(c)
+#  define INT_FAST16_C(c)	 INT32_C(c)
+
+#  define UINT16_C(c)	c ## U
+#  define UINT_LEAST16_C(c) UINT16_C(c)
+#  define UINT_FAST16_C(c) UINT32_C(c)
+#endif
+
+/*
+ * int32_t & uint32_t
+ */
+
+typedef int32_t       int_least32_t;
+typedef int32_t       int_fast32_t;
+
+typedef uint32_t      uint_least32_t;
+typedef uint32_t      uint_fast32_t;
+
+#ifdef __STDINT_LIMITS
+#  define INT32_MIN	(-2147483647-1)
+#  define INT32_MAX	(2147483647)
+#  define INT_LEAST32_MIN	INT32_MIN
+#  define INT_LEAST32_MAX	INT32_MAX
+#  define INT_FAST32_MIN	INT32_MIN
+#  define INT_FAST32_MAX	INT32_MAX
+
+#  define UINT32_MAX	(4294967295U)
+#  define UINT_LEAST32_MAX UINT32_MAX
+#  define UINT_FAST32_MAX UINT32_MAX
+#endif
+
+#ifdef __STDINT_MACROS
+#  define INT32_C(c)	c
+#  define INT_LEAST32_C(c) INT32_C(c)
+#  define INT_FAST32_C(c)  INT32_C(c)
+
+#  define UINT32_C(c)	c ## U
+#  define UINT_LEAST32_C(c) UINT32_C(c)
+#  define UINT_FAST32_C(c) UINT32_C(c)
+#endif
+
+#if !defined(__STRICT_ANSI__)
+/*
+ *  int64_t
+ */
+typedef int64_t       int_least64_t;
+typedef int64_t       int_fast64_t;
+
+typedef uint64_t      uint_least64_t;
+typedef uint64_t      uint_fast64_t;
+
+
+#ifdef __STDINT_LIMITS
+#  define INT64_MIN        (__INT64_C(-9223372036854775807)-1)
+#  define INT64_MAX        (__INT64_C(9223372036854775807))
+#  define INT_LEAST64_MIN  INT64_MIN
+#  define INT_LEAST64_MAX  INT64_MAX
+#  define INT_FAST64_MIN   INT64_MIN
+#  define INT_FAST64_MAX   INT64_MAX
+#  define UINT64_MAX       (__UINT64_C(18446744073709551615))
+
+#  define UINT_LEAST64_MAX UINT64_MAX
+#  define UINT_FAST64_MAX UINT64_MAX
+#endif
+
+#ifdef __STDINT_MACROS
+#  define __INT64_C(c)     c ## LL
+#  define INT64_C(c)       __INT64_C(c)
+#  define INT_LEAST64_C(c) INT64_C(c)
+#  define INT_FAST64_C(c)  INT64_C(c)
+
+#  define __UINT64_C(c)     c ## ULL
+#  define UINT64_C(c)       __UINT64_C(c)
+#  define UINT_LEAST64_C(c) UINT64_C(c)
+#  define UINT_FAST64_C(c)  UINT64_C(c)
+#endif
+
+
+#  define __PRI64_RANK   "ll"
+#  define __PRIFAST_RANK ""
+#  define __PRIPTR_RANK  ""
+
+#endif /* !__STRICT_ANSI__ */
+
+/*
+ * intptr_t & uintptr_t
+ */
+
+typedef int           intptr_t;
+typedef unsigned int  uintptr_t;
+
+#  define INTPTR_MIN    INT32_MIN
+#  define INTPTR_MAX    INT32_MAX
+#  define UINTPTR_MAX   UINT32_MAX
+#  define INTPTR_C(c)   INT32_C(c)
+#  define UINTPTR_C(c)  UINT32_C(c)
+#  define PTRDIFF_C(c)  INT32_C(c)
+#  define PTRDIFF_MIN   INT32_MIN
+#  define PTRDIFF_MAX   INT32_MAX
+
+
+/*
+ *  intmax_t & uintmax_t
+ */
+
+#if !defined(__STRICT_ANSI__)
+
+typedef uint64_t uintmax_t;
+typedef int64_t  intmax_t;
+
+#define INTMAX_MIN	INT64_MIN
+#define INTMAX_MAX	INT64_MAX
+#define UINTMAX_MAX	UINT64_MAX
+
+#define INTMAX_C(c)	INT64_C(c)
+#define UINTMAX_C(c)	UINT64_C(c)
+
+#else /* __STRICT_ANSI__ */
+
+typedef uint32_t  uintmax_t;
+typedef int32_t   intmax_t;
+
+#define  INTMAX_MIN    INT32_MIN
+#define  INTMAX_MAX    INT32_MAX
+#define  UINTMAX_MAX   UINT32_MAX
+
+#define INTMAX_C(c)	INT32_C(c)
+#define UINTMAX_C(c)	UINT32_C(c)
+
+#endif /* __STRICT_ANSI__ */
+
+
+/* size_t is defined by the GCC-specific <stddef.h> */
+#ifndef _SSIZE_T_DEFINED_
+#define _SSIZE_T_DEFINED_
+typedef long int  ssize_t;
+#endif
+
+#define _BITSIZE 32
+
+/* Keep the kernel from trying to define these types... */
+#define __BIT_TYPES_DEFINED__
+
+#endif /* _STDINT_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/stdio.h b/ndk/build/platforms/android-1.5/common/include/stdio.h
new file mode 100644
index 0000000..79e526b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/stdio.h
@@ -0,0 +1,437 @@
+/*	$OpenBSD: stdio.h,v 1.35 2006/01/13 18:10:09 miod Exp $	*/
+/*	$NetBSD: stdio.h,v 1.18 1996/04/25 18:29:21 jtc Exp $	*/
+
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)stdio.h	5.17 (Berkeley) 6/3/91
+ */
+
+#ifndef	_STDIO_H_
+#define	_STDIO_H_
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+
+/* va_list and size_t must be defined by stdio.h according to Posix */
+#define __need___va_list
+#include <stdarg.h>
+
+/* note that this forces stddef.h to *only* define size_t */
+#define __need_size_t
+#include <stddef.h>
+
+#include <stddef.h>
+
+#if __BSD_VISIBLE || __POSIX_VISIBLE || __XPG_VISIBLE
+#include <sys/types.h>	/* XXX should be removed */
+#endif
+
+#ifndef	_SIZE_T_DEFINED_
+#define	_SIZE_T_DEFINED_
+typedef	unsigned long    size_t;
+#endif
+
+#ifndef	_OFF_T_DEFINED_
+#define	_OFF_T_DEFINED_
+typedef	long    off_t;
+#endif
+
+#ifndef NULL
+#ifdef 	__GNUG__
+#define	NULL	__null
+#else
+#define	NULL	0L
+#endif
+#endif
+
+#define	_FSTDIO			/* Define for new stdio with functions. */
+
+typedef off_t fpos_t;		/* stdio file position type */
+
+/*
+ * NB: to fit things in six character monocase externals, the stdio
+ * code uses the prefix `__s' for stdio objects, typically followed
+ * by a three-character attempt at a mnemonic.
+ */
+
+/* stdio buffers */
+struct __sbuf {
+	unsigned char *_base;
+	int	_size;
+};
+
+/*
+ * stdio state variables.
+ *
+ * The following always hold:
+ *
+ *	if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR),
+ *		_lbfsize is -_bf._size, else _lbfsize is 0
+ *	if _flags&__SRD, _w is 0
+ *	if _flags&__SWR, _r is 0
+ *
+ * This ensures that the getc and putc macros (or inline functions) never
+ * try to write or read from a file that is in `read' or `write' mode.
+ * (Moreover, they can, and do, automatically switch from read mode to
+ * write mode, and back, on "r+" and "w+" files.)
+ *
+ * _lbfsize is used only to make the inline line-buffered output stream
+ * code as compact as possible.
+ *
+ * _ub, _up, and _ur are used when ungetc() pushes back more characters
+ * than fit in the current _bf, or when ungetc() pushes back a character
+ * that does not match the previous one in _bf.  When this happens,
+ * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff
+ * _ub._base!=NULL) and _up and _ur save the current values of _p and _r.
+ */
+typedef	struct __sFILE {
+	unsigned char *_p;	/* current position in (some) buffer */
+	int	_r;		/* read space left for getc() */
+	int	_w;		/* write space left for putc() */
+	short	_flags;		/* flags, below; this FILE is free if 0 */
+	short	_file;		/* fileno, if Unix descriptor, else -1 */
+	struct	__sbuf _bf;	/* the buffer (at least 1 byte, if !NULL) */
+	int	_lbfsize;	/* 0 or -_bf._size, for inline putc */
+
+	/* operations */
+	void	*_cookie;	/* cookie passed to io functions */
+	int	(*_close)(void *);
+	int	(*_read)(void *, char *, int);
+	fpos_t	(*_seek)(void *, fpos_t, int);
+	int	(*_write)(void *, const char *, int);
+
+	/* extension data, to avoid further ABI breakage */
+	struct	__sbuf _ext;
+	/* data for long sequences of ungetc() */
+	unsigned char *_up;	/* saved _p when _p is doing ungetc data */
+	int	_ur;		/* saved _r when _r is counting ungetc data */
+
+	/* tricks to meet minimum requirements even when malloc() fails */
+	unsigned char _ubuf[3];	/* guarantee an ungetc() buffer */
+	unsigned char _nbuf[1];	/* guarantee a getc() buffer */
+
+	/* separate buffer for fgetln() when line crosses buffer boundary */
+	struct	__sbuf _lb;	/* buffer for fgetln() */
+
+	/* Unix stdio files get aligned to block boundaries on fseek() */
+	int	_blksize;	/* stat.st_blksize (may be != _bf._size) */
+	fpos_t	_offset;	/* current lseek offset */
+} FILE;
+
+__BEGIN_DECLS
+extern FILE __sF[];
+__END_DECLS
+
+#define	__SLBF	0x0001		/* line buffered */
+#define	__SNBF	0x0002		/* unbuffered */
+#define	__SRD	0x0004		/* OK to read */
+#define	__SWR	0x0008		/* OK to write */
+	/* RD and WR are never simultaneously asserted */
+#define	__SRW	0x0010		/* open for reading & writing */
+#define	__SEOF	0x0020		/* found EOF */
+#define	__SERR	0x0040		/* found error */
+#define	__SMBF	0x0080		/* _buf is from malloc */
+#define	__SAPP	0x0100		/* fdopen()ed in append mode */
+#define	__SSTR	0x0200		/* this is an sprintf/snprintf string */
+#define	__SOPT	0x0400		/* do fseek() optimisation */
+#define	__SNPT	0x0800		/* do not do fseek() optimisation */
+#define	__SOFF	0x1000		/* set iff _offset is in fact correct */
+#define	__SMOD	0x2000		/* true => fgetln modified _p text */
+#define	__SALC	0x4000		/* allocate string space dynamically */
+
+/*
+ * The following three definitions are for ANSI C, which took them
+ * from System V, which brilliantly took internal interface macros and
+ * made them official arguments to setvbuf(), without renaming them.
+ * Hence, these ugly _IOxxx names are *supposed* to appear in user code.
+ *
+ * Although numbered as their counterparts above, the implementation
+ * does not rely on this.
+ */
+#define	_IOFBF	0		/* setvbuf should set fully buffered */
+#define	_IOLBF	1		/* setvbuf should set line buffered */
+#define	_IONBF	2		/* setvbuf should set unbuffered */
+
+#define	BUFSIZ	1024		/* size of buffer used by setbuf */
+
+#define	EOF	(-1)
+
+/*
+ * FOPEN_MAX is a minimum maximum, and should be the number of descriptors
+ * that the kernel can provide without allocation of a resource that can
+ * fail without the process sleeping.  Do not use this for anything.
+ */
+#define	FOPEN_MAX	20	/* must be <= OPEN_MAX <sys/syslimits.h> */
+#define	FILENAME_MAX	1024	/* must be <= PATH_MAX <sys/syslimits.h> */
+
+/* System V/ANSI C; this is the wrong way to do this, do *not* use these. */
+#if __BSD_VISIBLE || __XPG_VISIBLE
+#define	P_tmpdir	"/tmp/"
+#endif
+#define	L_tmpnam	1024	/* XXX must be == PATH_MAX */
+#define	TMP_MAX		308915776
+
+#ifndef SEEK_SET
+#define	SEEK_SET	0	/* set file offset to offset */
+#endif
+#ifndef SEEK_CUR
+#define	SEEK_CUR	1	/* set file offset to current plus offset */
+#endif
+#ifndef SEEK_END
+#define	SEEK_END	2	/* set file offset to EOF plus offset */
+#endif
+
+#define	stdin	(&__sF[0])
+#define	stdout	(&__sF[1])
+#define	stderr	(&__sF[2])
+
+/*
+ * Functions defined in ANSI C standard.
+ */
+__BEGIN_DECLS
+void	 clearerr(FILE *);
+int	 fclose(FILE *);
+int	 feof(FILE *);
+int	 ferror(FILE *);
+int	 fflush(FILE *);
+int	 fgetc(FILE *);
+int	 fgetpos(FILE *, fpos_t *);
+char	*fgets(char *, int, FILE *);
+FILE	*fopen(const char *, const char *);
+int	 fprintf(FILE *, const char *, ...);
+int	 fputc(int, FILE *);
+int	 fputs(const char *, FILE *);
+size_t	 fread(void *, size_t, size_t, FILE *);
+FILE	*freopen(const char *, const char *, FILE *);
+int	 fscanf(FILE *, const char *, ...);
+int	 fseek(FILE *, long, int);
+int	 fseeko(FILE *, off_t, int);
+int	 fsetpos(FILE *, const fpos_t *);
+long	 ftell(FILE *);
+off_t	 ftello(FILE *);
+size_t	 fwrite(const void *, size_t, size_t, FILE *);
+int	 getc(FILE *);
+int	 getchar(void);
+char	*gets(char *);
+#if __BSD_VISIBLE && !defined(__SYS_ERRLIST)
+#define __SYS_ERRLIST
+
+extern int sys_nerr;			/* perror(3) external variables */
+extern char *sys_errlist[];
+#endif
+void	 perror(const char *);
+int	 printf(const char *, ...);
+int	 putc(int, FILE *);
+int	 putchar(int);
+int	 puts(const char *);
+int	 remove(const char *);
+int	 rename(const char *, const char *);
+void	 rewind(FILE *);
+int	 scanf(const char *, ...);
+void	 setbuf(FILE *, char *);
+int	 setvbuf(FILE *, char *, int, size_t);
+int	 sprintf(char *, const char *, ...);
+int	 sscanf(const char *, const char *, ...);
+FILE	*tmpfile(void);
+char	*tmpnam(char *);
+int	 ungetc(int, FILE *);
+int	 vfprintf(FILE *, const char *, __va_list);
+int	 vprintf(const char *, __va_list);
+int	 vsprintf(char *, const char *, __va_list);
+
+#if __ISO_C_VISIBLE >= 1999 || __BSD_VISIBLE
+int	 snprintf(char *, size_t, const char *, ...)
+		__attribute__((__format__ (printf, 3, 4)))
+		__attribute__((__nonnull__ (3)));
+int	 vfscanf(FILE *, const char *, __va_list)
+		__attribute__((__format__ (scanf, 2, 0)))
+		__attribute__((__nonnull__ (2)));
+int	 vscanf(const char *, __va_list)
+		__attribute__((__format__ (scanf, 1, 0)))
+		__attribute__((__nonnull__ (1)));
+int	 vsnprintf(char *, size_t, const char *, __va_list)
+		__attribute__((__format__ (printf, 3, 0)))
+		__attribute__((__nonnull__ (3)));
+int	 vsscanf(const char *, const char *, __va_list)
+		__attribute__((__format__ (scanf, 2, 0)))
+		__attribute__((__nonnull__ (2)));
+#endif /* __ISO_C_VISIBLE >= 1999 || __BSD_VISIBLE */
+
+__END_DECLS
+
+
+/*
+ * Functions defined in POSIX 1003.1.
+ */
+#if __BSD_VISIBLE || __POSIX_VISIBLE || __XPG_VISIBLE
+#define	L_ctermid	1024	/* size for ctermid(); PATH_MAX */
+#define L_cuserid	9	/* size for cuserid(); UT_NAMESIZE + 1 */
+
+__BEGIN_DECLS
+char	*ctermid(char *);
+char	*cuserid(char *);
+FILE	*fdopen(int, const char *);
+int	 fileno(FILE *);
+
+#if (__POSIX_VISIBLE >= 199209) || 1 /* ANDROID: Bionic does include this */
+int	 pclose(FILE *);
+FILE	*popen(const char *, const char *);
+#endif
+
+#if __POSIX_VISIBLE >= 199506
+void	 flockfile(FILE *);
+int	 ftrylockfile(FILE *);
+void	 funlockfile(FILE *);
+
+/*
+ * These are normally used through macros as defined below, but POSIX
+ * requires functions as well.
+ */
+int	 getc_unlocked(FILE *);
+int	 getchar_unlocked(void);
+int	 putc_unlocked(int, FILE *);
+int	 putchar_unlocked(int);
+#endif /* __POSIX_VISIBLE >= 199506 */
+
+#if __XPG_VISIBLE
+char	*tempnam(const char *, const char *);
+#endif
+__END_DECLS
+
+#endif /* __BSD_VISIBLE || __POSIX_VISIBLE || __XPG_VISIBLE */
+
+/*
+ * Routines that are purely local.
+ */
+#if __BSD_VISIBLE
+__BEGIN_DECLS
+int	 asprintf(char **, const char *, ...)
+		__attribute__((__format__ (printf, 2, 3)))
+		__attribute__((__nonnull__ (2)));
+char	*fgetln(FILE *, size_t *);
+int	 fpurge(FILE *);
+int	 getw(FILE *);
+int	 putw(int, FILE *);
+void	 setbuffer(FILE *, char *, int);
+int	 setlinebuf(FILE *);
+int	 vasprintf(char **, const char *, __va_list)
+		__attribute__((__format__ (printf, 2, 0)))
+		__attribute__((__nonnull__ (2)));
+__END_DECLS
+
+/*
+ * Stdio function-access interface.
+ */
+__BEGIN_DECLS
+FILE	*funopen(const void *,
+		int (*)(void *, char *, int),
+		int (*)(void *, const char *, int),
+		fpos_t (*)(void *, fpos_t, int),
+		int (*)(void *));
+__END_DECLS
+#define	fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
+#define	fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
+#endif /* __BSD_VISIBLE */
+
+/*
+ * Functions internal to the implementation.
+ */
+__BEGIN_DECLS
+int	__srget(FILE *);
+int	__swbuf(int, FILE *);
+__END_DECLS
+
+/*
+ * The __sfoo macros are here so that we can
+ * define function versions in the C library.
+ */
+#define	__sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))
+#if defined(__GNUC__)
+static __inline int __sputc(int _c, FILE *_p) {
+	if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
+		return (*_p->_p++ = _c);
+	else
+		return (__swbuf(_c, _p));
+}
+#else
+/*
+ * This has been tuned to generate reasonable code on the vax using pcc.
+ */
+#define	__sputc(c, p) \
+	(--(p)->_w < 0 ? \
+		(p)->_w >= (p)->_lbfsize ? \
+			(*(p)->_p = (c)), *(p)->_p != '\n' ? \
+				(int)*(p)->_p++ : \
+				__swbuf('\n', p) : \
+			__swbuf((int)(c), p) : \
+		(*(p)->_p = (c), (int)*(p)->_p++))
+#endif
+
+#define	__sfeof(p)	(((p)->_flags & __SEOF) != 0)
+#define	__sferror(p)	(((p)->_flags & __SERR) != 0)
+#define	__sclearerr(p)	((void)((p)->_flags &= ~(__SERR|__SEOF)))
+#define	__sfileno(p)	((p)->_file)
+
+#define	feof(p)		__sfeof(p)
+#define	ferror(p)	__sferror(p)
+
+#ifndef _POSIX_THREADS
+#define	clearerr(p)	__sclearerr(p)
+#endif
+
+#if __POSIX_VISIBLE
+#define	fileno(p)	__sfileno(p)
+#endif
+
+#ifndef lint
+#ifndef _POSIX_THREADS
+#define	getc(fp)	__sgetc(fp)
+#endif /* _POSIX_THREADS */
+#define	getc_unlocked(fp)	__sgetc(fp)
+/*
+ * The macro implementations of putc and putc_unlocked are not
+ * fully POSIX compliant; they do not set errno on failure
+ */
+#if __BSD_VISIBLE
+#ifndef _POSIX_THREADS
+#define putc(x, fp)	__sputc(x, fp)
+#endif /* _POSIX_THREADS */
+#define putc_unlocked(x, fp)	__sputc(x, fp)
+#endif /* __BSD_VISIBLE */
+#endif /* lint */
+
+#define	getchar()	getc(stdin)
+#define	putchar(x)	putc(x, stdout)
+#define getchar_unlocked()	getc_unlocked(stdin)
+#define putchar_unlocked(c)	putc_unlocked(c, stdout)
+
+#endif /* _STDIO_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/stdlib.h b/ndk/build/platforms/android-1.5/common/include/stdlib.h
new file mode 100644
index 0000000..acfe694
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/stdlib.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _STDLIB_H_
+#define _STDLIB_H_
+
+#include <sys/cdefs.h>
+
+/* wchar_t is required in stdlib.h according to POSIX.
+ * note that defining __need_wchar_t prevents stddef.h
+ * to define all other symbols it does normally */
+#define __need_wchar_t
+#include <stddef.h>
+
+#include <stddef.h>
+#include <string.h>
+#include <alloca.h>
+#include <strings.h>
+#include <memory.h>
+
+__BEGIN_DECLS
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+extern __noreturn void exit(int);
+extern __noreturn void abort(void);
+extern int atexit(void (*)(void));
+extern int on_exit(void (*)(int, void *), void *);
+
+extern char *getenv(const char *);
+extern int putenv(const char *);
+extern int setenv(const char *, const char *, int);
+extern int unsetenv(const char *);
+extern int clearenv(void);
+
+extern char *mktemp (char *);
+extern int mkstemp (char *);
+
+extern long strtol(const char *, char **, int);
+extern long long strtoll(const char *, char **, int);
+extern unsigned long strtoul(const char *, char **, int);
+extern unsigned long long strtoull(const char *, char **, int);
+extern double strtod(const char *nptr, char **endptr);
+
+static __inline__ float strtof(const char *nptr, char **endptr)
+{
+    return (float)strtod(nptr, endptr);
+}
+
+extern int atoi(const char *);
+extern long atol(const char *);
+extern long long atoll(const char *);
+
+static __inline__ double atof(const char *nptr)
+{
+    return (strtod(nptr, NULL));
+}
+
+static __inline__ int abs(int __n) {
+    return (__n < 0) ? -__n : __n;
+}
+
+static __inline__ long labs(long __n) {
+    return (__n < 0L) ? -__n : __n;
+}
+
+static __inline__ long long llabs(long long __n) {
+    return (__n < 0LL) ? -__n : __n;
+}
+
+extern char * realpath(const char *path, char *resolved);
+extern int system(const char * string);
+
+extern void * bsearch(const void *key, const void *base0,
+	size_t nmemb, size_t size,
+	int (*compar)(const void *, const void *));
+
+extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
+
+extern long jrand48(unsigned short *);
+extern long mrand48(void);
+extern long nrand48(unsigned short *);
+extern long lrand48(void);
+extern unsigned short *seed48(unsigned short*);
+extern void srand48(long);
+extern unsigned int arc4random(void);
+extern void arc4random_stir(void);
+extern void arc4random_addrandom(unsigned char *, int);
+
+#define RAND_MAX 0x7fffffff
+static __inline__ int rand(void) {
+    return (int)lrand48();
+}
+static __inline__ void srand(unsigned int __s) {
+    srand48(__s);
+}
+static __inline__ long random(void)
+{
+    return lrand48();
+}
+static __inline__ void srandom(unsigned int __s)
+{
+    srand48(__s);
+}
+
+/* Basic PTY functions.  These only work if devpts is mounted! */
+
+extern int    unlockpt(int);
+extern char*  ptsname(int);
+extern char*  ptsname_r(int, char*, size_t);
+extern int    getpt(void);
+
+static __inline__ int grantpt(int __fd)
+{
+  (void)__fd;
+  return 0;     /* devpts does this all for us! */
+}
+
+typedef struct {
+    int  quot;
+    int  rem;
+} div_t;
+
+extern div_t   div(int, int);
+
+typedef struct {
+    long int  quot;
+    long int  rem;
+} ldiv_t;
+
+extern ldiv_t   ldiv(long, long);
+
+typedef struct {
+    long long int  quot;
+    long long int  rem;
+} lldiv_t;
+
+extern lldiv_t   lldiv(long long, long long);
+
+/* make STLPort happy */
+extern int      mblen(const char *, size_t);
+extern size_t   mbstowcs(wchar_t *, const char *, size_t);
+extern int      mbtowc(wchar_t *, const char *, size_t);
+
+/* Likewise, make libstdc++-v3 happy.  */
+extern int	wctomb(char *, wchar_t);
+extern size_t	wcstombs(char *, const wchar_t *, size_t);
+#define MB_CUR_MAX 1
+
+__END_DECLS
+
+#endif /* _STDLIB_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/stl_pair.h b/ndk/build/platforms/android-1.5/common/include/stl_pair.h
new file mode 100644
index 0000000..37f757b
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/stl_pair.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+/*
+ *
+ * Copyright (c) 1994
+ * Hewlett-Packard Company
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Hewlett-Packard Company makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ *
+ * Copyright (c) 1996,1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ */
+
+/* NOTE: This is an internal header file, included by other STL headers.
+ *   You should not attempt to use it directly.
+ */
+
+#ifndef __SGI_STL_INTERNAL_PAIR_H
+#define __SGI_STL_INTERNAL_PAIR_H
+
+__STL_BEGIN_NAMESPACE
+
+template <class _T1, class _T2>
+struct pair {
+  typedef _T1 first_type;
+  typedef _T2 second_type;
+
+  _T1 first;
+  _T2 second;
+  pair() : first(), second() {}
+  pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) {}
+
+  template <class _U1, class _U2>
+  pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
+};
+
+template <class _T1, class _T2>
+inline bool operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
+{
+  return __x.first == __y.first && __x.second == __y.second;
+}
+
+template <class _T1, class _T2>
+inline bool operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
+{
+  return __x.first < __y.first ||
+         (!(__y.first < __x.first) && __x.second < __y.second);
+}
+
+template <class _T1, class _T2>
+inline bool operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) {
+  return !(__x == __y);
+}
+
+template <class _T1, class _T2>
+inline bool operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) {
+  return __y < __x;
+}
+
+template <class _T1, class _T2>
+inline bool operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) {
+  return !(__y < __x);
+}
+
+template <class _T1, class _T2>
+inline bool operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) {
+  return !(__x < __y);
+}
+
+template <class _T1, class _T2>
+inline pair<_T1, _T2> make_pair(_T1 __x, _T2 __y)
+{
+  return pair<_T1, _T2>(__x, __y);
+}
+
+__STL_END_NAMESPACE
+
+#endif /* __SGI_STL_INTERNAL_PAIR_H */
+
+// Local Variables:
+// mode:C++
+// End:
diff --git a/ndk/build/platforms/android-1.5/common/include/string.h b/ndk/build/platforms/android-1.5/common/include/string.h
new file mode 100644
index 0000000..613dcd7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/string.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _STRING_H_
+#define _STRING_H_
+
+#include <sys/cdefs.h>
+#include <stddef.h>
+#include <malloc.h>
+
+__BEGIN_DECLS
+
+extern void*  memccpy(void *, const void *, int, size_t);
+extern void*  memchr(const void *, int, size_t);
+extern void*  memrchr(const void *, int, size_t);
+extern int    memcmp(const void *, const void *, size_t);
+extern void*  memcpy(void *, const void *, size_t);
+extern void*  memmove(void *, const void *, size_t);
+extern void*  memset(void *, int, size_t);
+extern void*  memmem(const void *, size_t, const void *, size_t);
+extern void   memswap(void *, void *, size_t);
+
+extern char*  index(const char *, int);
+extern char*  rindex(const char *, int);
+extern char*  strchr(const char *, int);
+extern char*  strrchr(const char *, int);
+
+extern size_t strlen(const char *);
+extern int    strcmp(const char *, const char *);
+extern char*  strcpy(char *, const char *);
+extern char*  strcat(char *, const char *);
+
+extern int    strcasecmp(const char *, const char *);
+extern int    strncasecmp(const char *, const char *, size_t);
+extern char*  strdup(const char *);
+
+extern char*  strstr(const char *, const char *);
+extern char*  strcasestr(const char *haystack, const char *needle);
+extern char*  strtok(char *, const char *);
+extern char*  strtok_r(char *, const char *, char**);
+
+extern char*  strerror(int);
+extern int    strerror_r(int errnum, char *buf, size_t n);
+
+extern size_t strnlen(const char *, size_t);
+extern char*  strncat(char *, const char *, size_t);
+extern char*  strndup(const char *, size_t);
+extern int    strncmp(const char *, const char *, size_t);
+extern char*  strncpy(char *, const char *, size_t);
+
+extern size_t strlcat(char *, const char *, size_t);
+extern size_t strlcpy(char *, const char *, size_t);
+
+extern size_t strcspn(const char *, const char *);
+extern char*  strpbrk(const char *, const char *);
+extern char*  strsep(char **, const char *);
+extern size_t strspn(const char *, const char *);
+
+extern char*  strsignal(int  sig);
+
+extern int    strcoll(const char *, const char *);
+extern size_t strxfrm(char *, const char *, size_t);
+
+__END_DECLS
+
+#endif /* _STRING_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/strings.h b/ndk/build/platforms/android-1.5/common/include/strings.h
new file mode 100644
index 0000000..1f73e21
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/strings.h
@@ -0,0 +1,55 @@
+/*	$NetBSD: strings.h,v 1.10 2005/02/03 04:39:32 perry Exp $	*/
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Klaus Klein.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``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 THE FOUNDATION OR CONTRIBUTORS
+ * 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.
+ */
+
+#ifndef _STRINGS_H_
+#define _STRINGS_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+int	 bcmp(const void *, const void *, size_t);
+void	 bcopy(const void *, void *, size_t);
+void	 bzero(void *, size_t);
+int	 ffs(int);
+char	*index(const char *, int);
+char	*rindex(const char *, int);
+int	 strcasecmp(const char *, const char *);
+int	 strncasecmp(const char *, const char *, size_t);
+__END_DECLS
+
+#endif /* !defined(_STRINGS_H_) */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/_errdefs.h b/ndk/build/platforms/android-1.5/common/include/sys/_errdefs.h
new file mode 100644
index 0000000..e27ab7a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/_errdefs.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+
+/* the following corresponds to the error codes of the Linux kernel used by the Android platform
+ * these are distinct from the OpenBSD ones, which is why we need to redeclare them here
+ *
+ * this file may be included several times to define either error constants or their
+ * string representation
+ */
+
+#ifndef __BIONIC_ERRDEF
+#error "__BIONIC_ERRDEF must be defined before including this file"
+#endif
+__BIONIC_ERRDEF( EPERM          ,   1, "Operation not permitted" )
+__BIONIC_ERRDEF( ENOENT         ,   2, "No such file or directory" )
+__BIONIC_ERRDEF( ESRCH          ,   3, "No such process" )
+__BIONIC_ERRDEF( EINTR          ,   4, "Interrupted system call" )
+__BIONIC_ERRDEF( EIO            ,   5, "I/O error" )
+__BIONIC_ERRDEF( ENXIO          ,   6, "No such device or address" )
+__BIONIC_ERRDEF( E2BIG          ,   7, "Argument list too long" )
+__BIONIC_ERRDEF( ENOEXEC        ,   8, "Exec format error" )
+__BIONIC_ERRDEF( EBADF          ,   9, "Bad file number" )
+__BIONIC_ERRDEF( ECHILD         ,  10, "No child processes" )
+__BIONIC_ERRDEF( EAGAIN         ,  11, "Try again" )
+__BIONIC_ERRDEF( ENOMEM         ,  12, "Out of memory" )
+__BIONIC_ERRDEF( EACCES         ,  13, "Permission denied" )
+__BIONIC_ERRDEF( EFAULT         ,  14, "Bad address" )
+__BIONIC_ERRDEF( ENOTBLK        ,  15, "Block device required" )
+__BIONIC_ERRDEF( EBUSY          ,  16, "Device or resource busy" )
+__BIONIC_ERRDEF( EEXIST         ,  17, "File exists" )
+__BIONIC_ERRDEF( EXDEV          ,  18, "Cross-device link" )
+__BIONIC_ERRDEF( ENODEV         ,  19, "No such device" )
+__BIONIC_ERRDEF( ENOTDIR        ,  20, "Not a directory" )
+__BIONIC_ERRDEF( EISDIR         ,  21, "Is a directory" )
+__BIONIC_ERRDEF( EINVAL         ,  22, "Invalid argument" )
+__BIONIC_ERRDEF( ENFILE         ,  23, "File table overflow" )
+__BIONIC_ERRDEF( EMFILE         ,  24, "Too many open files" )
+__BIONIC_ERRDEF( ENOTTY         ,  25, "Not a typewriter" )
+__BIONIC_ERRDEF( ETXTBSY        ,  26, "Text file busy" )
+__BIONIC_ERRDEF( EFBIG          ,  27, "File too large" )
+__BIONIC_ERRDEF( ENOSPC         ,  28, "No space left on device" )
+__BIONIC_ERRDEF( ESPIPE         ,  29, "Illegal seek" )
+__BIONIC_ERRDEF( EROFS          ,  30, "Read-only file system" )
+__BIONIC_ERRDEF( EMLINK         ,  31, "Too many links" )
+__BIONIC_ERRDEF( EPIPE          ,  32, "Broken pipe" )
+__BIONIC_ERRDEF( EDOM           ,  33, "Math argument out of domain of func" )
+__BIONIC_ERRDEF( ERANGE         ,  34, "Math result not representable" )
+__BIONIC_ERRDEF( EDEADLK        ,  35, "Resource deadlock would occur" )
+__BIONIC_ERRDEF( ENAMETOOLONG   ,  36, "File name too long" )
+__BIONIC_ERRDEF( ENOLCK         ,  37, "No record locks available" )
+__BIONIC_ERRDEF( ENOSYS         ,  38, "Function not implemented" )
+__BIONIC_ERRDEF( ENOTEMPTY      ,  39, "Directory not empty" )
+__BIONIC_ERRDEF( ELOOP          ,  40, "Too many symbolic links encountered" )
+__BIONIC_ERRDEF( ENOMSG         ,  42, "No message of desired type" )
+__BIONIC_ERRDEF( EIDRM          ,  43, "Identifier removed" )
+__BIONIC_ERRDEF( ECHRNG         ,  44, "Channel number out of range" )
+__BIONIC_ERRDEF( EL2NSYNC       ,  45, "Level 2 not synchronized" )
+__BIONIC_ERRDEF( EL3HLT         ,  46, "Level 3 halted" )
+__BIONIC_ERRDEF( EL3RST         ,  47, "Level 3 reset" )
+__BIONIC_ERRDEF( ELNRNG         ,  48, "Link number out of range" )
+__BIONIC_ERRDEF( EUNATCH        ,  49, "Protocol driver not attached" )
+__BIONIC_ERRDEF( ENOCSI         ,  50, "No CSI structure available" )
+__BIONIC_ERRDEF( EL2HLT         ,  51, "Level 2 halted" )
+__BIONIC_ERRDEF( EBADE          ,  52, "Invalid exchange" )
+__BIONIC_ERRDEF( EBADR          ,  53, "Invalid request descriptor" )
+__BIONIC_ERRDEF( EXFULL         ,  54, "Exchange full" )
+__BIONIC_ERRDEF( ENOANO         ,  55, "No anode" )
+__BIONIC_ERRDEF( EBADRQC        ,  56, "Invalid request code" )
+__BIONIC_ERRDEF( EBADSLT        ,  57, "Invalid slot" )
+__BIONIC_ERRDEF( EBFONT         ,  59, "Bad font file format" )
+__BIONIC_ERRDEF( ENOSTR         ,  60, "Device not a stream" )
+__BIONIC_ERRDEF( ENODATA        ,  61, "No data available" )
+__BIONIC_ERRDEF( ETIME          ,  62, "Timer expired" )
+__BIONIC_ERRDEF( ENOSR          ,  63, "Out of streams resources" )
+__BIONIC_ERRDEF( ENONET         ,  64, "Machine is not on the network" )
+__BIONIC_ERRDEF( ENOPKG         ,  65, "Package not installed" )
+__BIONIC_ERRDEF( EREMOTE        ,  66, "Object is remote" )
+__BIONIC_ERRDEF( ENOLINK        ,  67, "Link has been severed" )
+__BIONIC_ERRDEF( EADV           ,  68, "Advertise error" )
+__BIONIC_ERRDEF( ESRMNT         ,  69, "Srmount error" )
+__BIONIC_ERRDEF( ECOMM          ,  70, "Communication error on send" )
+__BIONIC_ERRDEF( EPROTO         ,  71, "Protocol error" )
+__BIONIC_ERRDEF( EMULTIHOP      ,  72, "Multihop attempted" )
+__BIONIC_ERRDEF( EDOTDOT        ,  73, "RFS specific error" )
+__BIONIC_ERRDEF( EBADMSG        ,  74, "Not a data message" )
+__BIONIC_ERRDEF( EOVERFLOW      ,  75, "Value too large for defined data type" )
+__BIONIC_ERRDEF( ENOTUNIQ       ,  76, "Name not unique on network" )
+__BIONIC_ERRDEF( EBADFD         ,  77, "File descriptor in bad state" )
+__BIONIC_ERRDEF( EREMCHG        ,  78, "Remote address changed" )
+__BIONIC_ERRDEF( ELIBACC        ,  79, "Can not access a needed shared library" )
+__BIONIC_ERRDEF( ELIBBAD        ,  80, "Accessing a corrupted shared library" )
+__BIONIC_ERRDEF( ELIBSCN        ,  81, ".lib section in a.out corrupted" )
+__BIONIC_ERRDEF( ELIBMAX        ,  82, "Attempting to link in too many shared libraries" )
+__BIONIC_ERRDEF( ELIBEXEC       ,  83, "Cannot exec a shared library directly" )
+__BIONIC_ERRDEF( EILSEQ         ,  84, "Illegal byte sequence" )
+__BIONIC_ERRDEF( ERESTART       ,  85, "Interrupted system call should be restarted" )
+__BIONIC_ERRDEF( ESTRPIPE       ,  86, "Streams pipe error" )
+__BIONIC_ERRDEF( EUSERS         ,  87, "Too many users" )
+__BIONIC_ERRDEF( ENOTSOCK       ,  88, "Socket operation on non-socket" )
+__BIONIC_ERRDEF( EDESTADDRREQ   ,  89, "Destination address required" )
+__BIONIC_ERRDEF( EMSGSIZE       ,  90, "Message too long" )
+__BIONIC_ERRDEF( EPROTOTYPE     ,  91, "Protocol wrong type for socket" )
+__BIONIC_ERRDEF( ENOPROTOOPT    ,  92, "Protocol not available" )
+__BIONIC_ERRDEF( EPROTONOSUPPORT,  93, "Protocol not supported" )
+__BIONIC_ERRDEF( ESOCKTNOSUPPORT,  94, "Socket type not supported" )
+__BIONIC_ERRDEF( EOPNOTSUPP     ,  95, "Operation not supported on transport endpoint" )
+__BIONIC_ERRDEF( EPFNOSUPPORT   ,  96, "Protocol family not supported" )
+__BIONIC_ERRDEF( EAFNOSUPPORT   ,  97, "Address family not supported by protocol" )
+__BIONIC_ERRDEF( EADDRINUSE     ,  98, "Address already in use" )
+__BIONIC_ERRDEF( EADDRNOTAVAIL  ,  99, "Cannot assign requested address" )
+__BIONIC_ERRDEF( ENETDOWN       , 100, "Network is down" )
+__BIONIC_ERRDEF( ENETUNREACH    , 101, "Network is unreachable" )
+__BIONIC_ERRDEF( ENETRESET      , 102, "Network dropped connection because of reset" )
+__BIONIC_ERRDEF( ECONNABORTED   , 103, "Software caused connection abort" )
+__BIONIC_ERRDEF( ECONNRESET     , 104, "Connection reset by peer" )
+__BIONIC_ERRDEF( ENOBUFS        , 105, "No buffer space available" )
+__BIONIC_ERRDEF( EISCONN        , 106, "Transport endpoint is already connected" )
+__BIONIC_ERRDEF( ENOTCONN       , 107, "Transport endpoint is not connected" )
+__BIONIC_ERRDEF( ESHUTDOWN      , 108, "Cannot send after transport endpoint shutdown" )
+__BIONIC_ERRDEF( ETOOMANYREFS   , 109, "Too many references: cannot splice" )
+__BIONIC_ERRDEF( ETIMEDOUT      , 110, "Connection timed out" )
+__BIONIC_ERRDEF( ECONNREFUSED   , 111, "Connection refused" )
+__BIONIC_ERRDEF( EHOSTDOWN      , 112, "Host is down" )
+__BIONIC_ERRDEF( EHOSTUNREACH   , 113, "No route to host" )
+__BIONIC_ERRDEF( EALREADY       , 114, "Operation already in progress" )
+__BIONIC_ERRDEF( EINPROGRESS    , 115, "Operation now in progress" )
+__BIONIC_ERRDEF( ESTALE         , 116, "Stale NFS file handle" )
+__BIONIC_ERRDEF( EUCLEAN        , 117, "Structure needs cleaning" )
+__BIONIC_ERRDEF( ENOTNAM        , 118, "Not a XENIX named type file" )
+__BIONIC_ERRDEF( ENAVAIL        , 119, "No XENIX semaphores available" )
+__BIONIC_ERRDEF( EISNAM         , 120, "Is a named type file" )
+__BIONIC_ERRDEF( EREMOTEIO      , 121, "Remote I/O error" )
+__BIONIC_ERRDEF( EDQUOT         , 122, "Quota exceeded" )
+__BIONIC_ERRDEF( ENOMEDIUM      , 123, "No medium found" )
+__BIONIC_ERRDEF( EMEDIUMTYPE    , 124, "Wrong medium type" )
+__BIONIC_ERRDEF( ECANCELED      , 125, "Operation Canceled" )
+__BIONIC_ERRDEF( ENOKEY         , 126, "Required key not available" )
+__BIONIC_ERRDEF( EKEYEXPIRED    , 127, "Key has expired" )
+__BIONIC_ERRDEF( EKEYREVOKED    , 128, "Key has been revoked" )
+__BIONIC_ERRDEF( EKEYREJECTED   , 129, "Key was rejected by service" )
+__BIONIC_ERRDEF( EOWNERDEAD     , 130, "Owner died" )
+__BIONIC_ERRDEF( ENOTRECOVERABLE, 131, "State not recoverable" )
+
+/* the following is not defined by Linux but needed for the BSD portions of the C library */
+__BIONIC_ERRDEF( EFTYPE, 1000, "Stupid C library hack !!" )
+
+#undef __BIONIC_ERRDEF
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/_sigdefs.h b/ndk/build/platforms/android-1.5/common/include/sys/_sigdefs.h
new file mode 100644
index 0000000..a3cb7a3
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/_sigdefs.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+/* this header is used to define signal constants and names; it might be included several times */
+#ifndef __BIONIC_SIGDEF
+#error __BIONIC_SIGDEF not defined
+#endif
+
+__BIONIC_SIGDEF(SIGHUP,1,"Hangup")
+__BIONIC_SIGDEF(SIGINT,2,"Interrupt")
+__BIONIC_SIGDEF(SIGQUIT,3,"Quit")
+__BIONIC_SIGDEF(SIGILL,4,"Illegal instruction")
+__BIONIC_SIGDEF(SIGTRAP,5,"Trap")
+__BIONIC_SIGDEF(SIGABRT,6,"Aborted")
+__BIONIC_SIGDEF(SIGBUS,7,"Bus error")
+__BIONIC_SIGDEF(SIGFPE,8,"Floating point exception")
+__BIONIC_SIGDEF(SIGKILL,9,"Killed")
+__BIONIC_SIGDEF(SIGUSR1,10,"User signal 1")
+__BIONIC_SIGDEF(SIGSEGV,11,"Segmentation fault")
+__BIONIC_SIGDEF(SIGUSR2,12,"User signal 2")
+__BIONIC_SIGDEF(SIGPIPE,13,"Broken pipe")
+__BIONIC_SIGDEF(SIGALRM,14,"Alarm clock")
+__BIONIC_SIGDEF(SIGTERM,15,"Terminated")
+__BIONIC_SIGDEF(SIGSTKFLT,16,"Stack fault")
+__BIONIC_SIGDEF(SIGCHLD,17,"Child exited")
+__BIONIC_SIGDEF(SIGCONT,18,"Continue")
+__BIONIC_SIGDEF(SIGSTOP,19,"Stopped (signal)")
+__BIONIC_SIGDEF(SIGTSTP,20,"Stopped")
+__BIONIC_SIGDEF(SIGTTIN,21,"Stopped (tty input)")
+__BIONIC_SIGDEF(SIGTTOU,22,"Stopper (tty output)")
+__BIONIC_SIGDEF(SIGURG,23,"Urgent I/O condition")
+__BIONIC_SIGDEF(SIGXCPU,24,"CPU time limit exceeded")
+__BIONIC_SIGDEF(SIGXFSZ,25,"File size limit exceeded")
+__BIONIC_SIGDEF(SIGVTALRM,26,"Virtual timer expired")
+__BIONIC_SIGDEF(SIGPROF,27,"Profiling timer expired")
+__BIONIC_SIGDEF(SIGWINCH,28,"Window size changed")
+__BIONIC_SIGDEF(SIGIO,29,"I/O possible")
+__BIONIC_SIGDEF(SIGPWR,30,"Power failure")
+__BIONIC_SIGDEF(SIGSYS,31,"Bad system call")
+
+#undef __BIONIC_SIGDEF
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/_system_properties.h b/ndk/build/platforms/android-1.5/common/include/sys/_system_properties.h
new file mode 100644
index 0000000..42a7f6c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/_system_properties.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+
+#ifndef _INCLUDE_SYS__SYSTEM_PROPERTIES_H
+#define _INCLUDE_SYS__SYSTEM_PROPERTIES_H
+
+#ifndef _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
+#error you should #include <sys/system_properties.h> instead
+#else
+#include <sys/system_properties.h>
+
+typedef struct prop_area prop_area;
+typedef struct prop_msg prop_msg;
+
+#define PROP_AREA_MAGIC   0x504f5250
+#define PROP_AREA_VERSION 0x45434f76
+
+#define PROP_SERVICE_NAME "property_service"
+
+/* #define PROP_MAX_ENTRIES 247 */
+/* 247 -> 32620 bytes (<32768) */
+
+#define TOC_NAME_LEN(toc)       ((toc) >> 24)
+#define TOC_TO_INFO(area, toc)  ((prop_info*) (((char*) area) + ((toc) & 0xFFFFFF)))
+
+struct prop_area {
+    unsigned volatile count;
+    unsigned volatile serial;
+    unsigned magic;
+    unsigned version;
+    unsigned reserved[4];
+    unsigned toc[1];
+};
+
+#define SERIAL_VALUE_LEN(serial) ((serial) >> 24)
+#define SERIAL_DIRTY(serial) ((serial) & 1)
+
+struct prop_info {
+    char name[PROP_NAME_MAX];
+    unsigned volatile serial;
+    char value[PROP_VALUE_MAX];
+};
+
+struct prop_msg 
+{
+    unsigned cmd;
+    char name[PROP_NAME_MAX];
+    char value[PROP_VALUE_MAX];
+};
+
+#define PROP_MSG_SETPROP 1
+    
+/*
+** Rules:
+**
+** - there is only one writer, but many readers
+** - prop_area.count will never decrease in value
+** - once allocated, a prop_info's name will not change
+** - once allocated, a prop_info's offset will not change
+** - reading a value requires the following steps
+**   1. serial = pi->serial
+**   2. if SERIAL_DIRTY(serial), wait*, then goto 1
+**   3. memcpy(local, pi->value, SERIAL_VALUE_LEN(serial) + 1)
+**   4. if pi->serial != serial, goto 2
+**
+** - writing a value requires the following steps
+**   1. pi->serial = pi->serial | 1
+**   2. memcpy(pi->value, local_value, value_len)
+**   3. pi->serial = (value_len << 24) | ((pi->serial + 1) & 0xffffff)
+**
+** Improvements:
+** - maintain the toc sorted by pi->name to allow lookup
+**   by binary search
+**
+*/
+
+#define PROP_PATH_RAMDISK_DEFAULT  "/default.prop"
+#define PROP_PATH_SYSTEM_BUILD     "/system/build.prop"
+#define PROP_PATH_SYSTEM_DEFAULT   "/system/default.prop"
+#define PROP_PATH_LOCAL_OVERRIDE   "/data/local.prop"
+
+#endif
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/_types.h b/ndk/build/platforms/android-1.5/common/include/sys/_types.h
new file mode 100644
index 0000000..7b99e06
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/_types.h
@@ -0,0 +1,77 @@
+/*	$OpenBSD: _types.h,v 1.1 2006/01/06 18:53:05 millert Exp $	*/
+
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)types.h	8.3 (Berkeley) 1/5/94
+ */
+
+#ifndef _SYS__TYPES_H_
+#define	_SYS__TYPES_H_
+
+#undef  __KERNEL_STRICT_NAMES
+#define __KERNEL_STRICT_NAMES  1
+
+#include <machine/_types.h>
+
+typedef	unsigned long	__cpuid_t;	/* CPU id */
+typedef	__int32_t	__dev_t;	/* device number */
+typedef	__uint32_t	__fixpt_t;	/* fixed point number */
+typedef	__uint32_t	__gid_t;	/* group id */
+typedef	__uint32_t	__id_t;		/* may contain pid, uid or gid */
+typedef __uint32_t	__in_addr_t;	/* base type for internet address */
+typedef __uint16_t	__in_port_t;	/* IP port type */
+typedef	__uint32_t	__ino_t;	/* inode number */
+typedef	long		__key_t;	/* IPC key (for Sys V IPC) */
+typedef	__uint32_t	__mode_t;	/* permissions */
+typedef	__uint32_t	__nlink_t;	/* link count */
+typedef	__int32_t	__pid_t;	/* process id */
+typedef __uint64_t	__rlim_t;	/* resource limit */
+typedef __uint16_t	__sa_family_t;	/* sockaddr address family type */
+typedef	__int32_t	__segsz_t;	/* segment size */
+typedef __uint32_t	__socklen_t;	/* length type for network syscalls */
+typedef	__int32_t	__swblk_t;	/* swap offset */
+typedef	__uint32_t	__uid_t;	/* user id */
+typedef	__uint32_t	__useconds_t;	/* microseconds */
+typedef	__int32_t	__suseconds_t;	/* microseconds (signed) */
+
+/*
+ * mbstate_t is an opaque object to keep conversion state, during multibyte
+ * stream conversions. The content must not be referenced by user programs.
+ */
+typedef union {
+	char __mbstate8[128];
+	__int64_t __mbstateL;			/* for alignment */
+} __mbstate_t;
+
+/* BIONIC: if we're using non-cleaned up user-level kernel headers, 
+ *         this will prevent many type declaration conflicts
+ */
+#define  __KERNEL_STRICT_NAMES  1
+
+#endif /* !_SYS__TYPES_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/atomics.h b/ndk/build/platforms/android-1.5/common/include/sys/atomics.h
new file mode 100644
index 0000000..d3fa145
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/atomics.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_ATOMICS_H
+#define _SYS_ATOMICS_H
+
+#include <sys/cdefs.h>
+#include <sys/time.h>
+
+__BEGIN_DECLS
+
+extern int __atomic_cmpxchg(int old, int _new, volatile int *ptr);
+extern int __atomic_swap(int _new, volatile int *ptr);
+extern int __atomic_dec(volatile int *ptr);
+extern int __atomic_inc(volatile int *ptr);
+
+int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
+int __futex_wake(volatile void *ftx, int count);
+
+__END_DECLS
+
+#endif /* _SYS_ATOMICS_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/cdefs.h b/ndk/build/platforms/android-1.5/common/include/sys/cdefs.h
new file mode 100644
index 0000000..fe7033d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/cdefs.h
@@ -0,0 +1,376 @@
+/*	$NetBSD: cdefs.h,v 1.58 2004/12/11 05:59:00 christos Exp $	*/
+
+/*
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Berkeley Software Design, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)cdefs.h	8.8 (Berkeley) 1/9/95
+ */
+
+#ifndef	_SYS_CDEFS_H_
+#define	_SYS_CDEFS_H_
+
+
+/* our implementation of wchar_t is only 8-bit - die die non-portable code */
+#undef  __WCHAR_TYPE__
+#define __WCHAR_TYPE__  unsigned char
+
+
+/*
+ * Macro to test if we're using a GNU C compiler of a specific vintage
+ * or later, for e.g. features that appeared in a particular version
+ * of GNU C.  Usage:
+ *
+ *	#if __GNUC_PREREQ__(major, minor)
+ *	...cool feature...
+ *	#else
+ *	...delete feature...
+ *	#endif
+ */
+#ifdef __GNUC__
+#define	__GNUC_PREREQ__(x, y)						\
+	((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) ||			\
+	 (__GNUC__ > (x)))
+#else
+#define	__GNUC_PREREQ__(x, y)	0
+#endif
+
+//XXX #include <machine/cdefs.h>
+
+/* BIONIC: simpler definition */
+#define __BSD_VISIBLE   1
+
+#include <sys/cdefs_elf.h>
+
+#if defined(__cplusplus)
+#define	__BEGIN_DECLS		extern "C" {
+#define	__END_DECLS		}
+#define	__static_cast(x,y)	static_cast<x>(y)
+#else
+#define	__BEGIN_DECLS
+#define	__END_DECLS
+#define	__static_cast(x,y)	(x)y
+#endif
+
+/*
+ * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
+ * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
+ * The __CONCAT macro is a bit tricky -- make sure you don't put spaces
+ * in between its arguments.  __CONCAT can also concatenate double-quoted
+ * strings produced by the __STRING macro, but this only works with ANSI C.
+ */
+
+#define	___STRING(x)	__STRING(x)
+#define	___CONCAT(x,y)	__CONCAT(x,y)
+
+#if __STDC__ || defined(__cplusplus)
+#define	__P(protos)	protos		/* full-blown ANSI C */
+#define	__CONCAT(x,y)	x ## y
+#define	__STRING(x)	#x
+
+#define	__const		const		/* define reserved names to standard */
+#define	__signed	signed
+#define	__volatile	volatile
+#if defined(__cplusplus)
+#define	__inline	inline		/* convert to C++ keyword */
+#else
+#if !defined(__GNUC__) && !defined(__lint__)
+#define	__inline			/* delete GCC keyword */
+#endif /* !__GNUC__  && !__lint__ */
+#endif /* !__cplusplus */
+
+#else	/* !(__STDC__ || __cplusplus) */
+#define	__P(protos)	()		/* traditional C preprocessor */
+#define	__CONCAT(x,y)	x/**/y
+#define	__STRING(x)	"x"
+
+#ifndef __GNUC__
+#define	__const				/* delete pseudo-ANSI C keywords */
+#define	__inline
+#define	__signed
+#define	__volatile
+#endif	/* !__GNUC__ */
+
+/*
+ * In non-ANSI C environments, new programs will want ANSI-only C keywords
+ * deleted from the program and old programs will want them left alone.
+ * Programs using the ANSI C keywords const, inline etc. as normal
+ * identifiers should define -DNO_ANSI_KEYWORDS.
+ */
+#ifndef	NO_ANSI_KEYWORDS
+#define	const		__const		/* convert ANSI C keywords */
+#define	inline		__inline
+#define	signed		__signed
+#define	volatile	__volatile
+#endif /* !NO_ANSI_KEYWORDS */
+#endif	/* !(__STDC__ || __cplusplus) */
+
+/*
+ * Used for internal auditing of the NetBSD source tree.
+ */
+#ifdef __AUDIT__
+#define	__aconst	__const
+#else
+#define	__aconst
+#endif
+
+/*
+ * The following macro is used to remove const cast-away warnings
+ * from gcc -Wcast-qual; it should be used with caution because it
+ * can hide valid errors; in particular most valid uses are in
+ * situations where the API requires it, not to cast away string
+ * constants. We don't use *intptr_t on purpose here and we are
+ * explicit about unsigned long so that we don't have additional
+ * dependencies.
+ */
+#define __UNCONST(a)	((void *)(unsigned long)(const void *)(a))
+
+/*
+ * GCC2 provides __extension__ to suppress warnings for various GNU C
+ * language extensions under "-ansi -pedantic".
+ */
+#if !__GNUC_PREREQ__(2, 0)
+#define	__extension__		/* delete __extension__ if non-gcc or gcc1 */
+#endif
+
+/*
+ * GCC1 and some versions of GCC2 declare dead (non-returning) and
+ * pure (no side effects) functions using "volatile" and "const";
+ * unfortunately, these then cause warnings under "-ansi -pedantic".
+ * GCC2 uses a new, peculiar __attribute__((attrs)) style.  All of
+ * these work for GNU C++ (modulo a slight glitch in the C++ grammar
+ * in the distribution version of 2.5.5).
+ */
+#if !__GNUC_PREREQ__(2, 5)
+#define	__attribute__(x)	/* delete __attribute__ if non-gcc or gcc1 */
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+#define	__dead		__volatile
+#define	__pure		__const
+#endif
+#endif
+
+/* Delete pseudo-keywords wherever they are not available or needed. */
+#ifndef __dead
+#define	__dead
+#define	__pure
+#endif
+
+#if __GNUC_PREREQ__(2, 7)
+#define	__unused	__attribute__((__unused__))
+#else
+#define	__unused	/* delete */
+#endif
+
+#if __GNUC_PREREQ__(3, 1)
+#define	__used		__attribute__((__used__))
+#else
+#define	__used		/* delete */
+#endif
+
+#if __GNUC_PREREQ__(2, 7)
+#define	__packed	__attribute__((__packed__))
+#define	__aligned(x)	__attribute__((__aligned__(x)))
+#define	__section(x)	__attribute__((__section__(x)))
+#elif defined(__lint__)
+#define	__packed	/* delete */
+#define	__aligned(x)	/* delete */
+#define	__section(x)	/* delete */
+#else
+#define	__packed	error: no __packed for this compiler
+#define	__aligned(x)	error: no __aligned for this compiler
+#define	__section(x)	error: no __section for this compiler
+#endif
+
+#if !__GNUC_PREREQ__(2, 8)
+#define	__extension__
+#endif
+
+#if __GNUC_PREREQ__(2, 8)
+#define __statement(x)	__extension__(x)
+#elif defined(lint)
+#define __statement(x)	(0)
+#else
+#define __statement(x)	(x)
+#endif
+
+/*
+ * C99 defines the restrict type qualifier keyword, which was made available
+ * in GCC 2.92.
+ */
+#if __STDC_VERSION__ >= 199901L
+#define	__restrict	restrict
+#else
+#if !__GNUC_PREREQ__(2, 92)
+#define	__restrict	/* delete __restrict when not supported */
+#endif
+#endif
+
+/*
+ * C99 defines __func__ predefined identifier, which was made available
+ * in GCC 2.95.
+ */
+#if !(__STDC_VERSION__ >= 199901L)
+#if __GNUC_PREREQ__(2, 6)
+#define	__func__	__PRETTY_FUNCTION__
+#elif __GNUC_PREREQ__(2, 4)
+#define	__func__	__FUNCTION__
+#else
+#define	__func__	""
+#endif
+#endif /* !(__STDC_VERSION__ >= 199901L) */
+
+#if defined(_KERNEL)
+#if defined(NO_KERNEL_RCSIDS)
+#undef __KERNEL_RCSID
+#define	__KERNEL_RCSID(_n, _s)		/* nothing */
+#endif /* NO_KERNEL_RCSIDS */
+#endif /* _KERNEL */
+
+#if !defined(_STANDALONE) && !defined(_KERNEL)
+#ifdef __GNUC__
+#define	__RENAME(x)	___RENAME(x)
+#else
+#ifdef __lint__
+#define	__RENAME(x)	__symbolrename(x)
+#else
+#error "No function renaming possible"
+#endif /* __lint__ */
+#endif /* __GNUC__ */
+#else /* _STANDALONE || _KERNEL */
+#define	__RENAME(x)	no renaming in kernel or standalone environment
+#endif
+
+/*
+ * A barrier to stop the optimizer from moving code or assume live
+ * register values. This is gcc specific, the version is more or less
+ * arbitrary, might work with older compilers.
+ */
+#if __GNUC_PREREQ__(2, 95)
+#define	__insn_barrier()	__asm __volatile("":::"memory")
+#else
+#define	__insn_barrier()	/* */
+#endif
+
+/*
+ * GNU C version 2.96 adds explicit branch prediction so that
+ * the CPU back-end can hint the processor and also so that
+ * code blocks can be reordered such that the predicted path
+ * sees a more linear flow, thus improving cache behavior, etc.
+ *
+ * The following two macros provide us with a way to use this
+ * compiler feature.  Use __predict_true() if you expect the expression
+ * to evaluate to true, and __predict_false() if you expect the
+ * expression to evaluate to false.
+ *
+ * A few notes about usage:
+ *
+ *	* Generally, __predict_false() error condition checks (unless
+ *	  you have some _strong_ reason to do otherwise, in which case
+ *	  document it), and/or __predict_true() `no-error' condition
+ *	  checks, assuming you want to optimize for the no-error case.
+ *
+ *	* Other than that, if you don't know the likelihood of a test
+ *	  succeeding from empirical or other `hard' evidence, don't
+ *	  make predictions.
+ *
+ *	* These are meant to be used in places that are run `a lot'.
+ *	  It is wasteful to make predictions in code that is run
+ *	  seldomly (e.g. at subsystem initialization time) as the
+ *	  basic block reordering that this affects can often generate
+ *	  larger code.
+ */
+#if __GNUC_PREREQ__(2, 96)
+#define	__predict_true(exp)	__builtin_expect((exp) != 0, 1)
+#define	__predict_false(exp)	__builtin_expect((exp) != 0, 0)
+#else
+#define	__predict_true(exp)	(exp)
+#define	__predict_false(exp)	(exp)
+#endif
+
+#if __GNUC_PREREQ__(2, 96)
+#define __noreturn    __attribute__((__noreturn__))
+#define __mallocfunc  __attribute__((malloc))
+#else
+#define __noreturn
+#define __mallocfunc
+#endif
+
+/*
+ * Macros for manipulating "link sets".  Link sets are arrays of pointers
+ * to objects, which are gathered up by the linker.
+ *
+ * Object format-specific code has provided us with the following macros:
+ *
+ *	__link_set_add_text(set, sym)
+ *		Add a reference to the .text symbol `sym' to `set'.
+ *
+ *	__link_set_add_rodata(set, sym)
+ *		Add a reference to the .rodata symbol `sym' to `set'.
+ *
+ *	__link_set_add_data(set, sym)
+ *		Add a reference to the .data symbol `sym' to `set'.
+ *
+ *	__link_set_add_bss(set, sym)
+ *		Add a reference to the .bss symbol `sym' to `set'.
+ *
+ *	__link_set_decl(set, ptype)
+ *		Provide an extern declaration of the set `set', which
+ *		contains an array of the pointer type `ptype'.  This
+ *		macro must be used by any code which wishes to reference
+ *		the elements of a link set.
+ *
+ *	__link_set_start(set)
+ *		This points to the first slot in the link set.
+ *
+ *	__link_set_end(set)
+ *		This points to the (non-existent) slot after the last
+ *		entry in the link set.
+ *
+ *	__link_set_count(set)
+ *		Count the number of entries in link set `set'.
+ *
+ * In addition, we provide the following macros for accessing link sets:
+ *
+ *	__link_set_foreach(pvar, set)
+ *		Iterate over the link set `set'.  Because a link set is
+ *		an array of pointers, pvar must be declared as "type **pvar",
+ *		and the actual entry accessed as "*pvar".
+ *
+ *	__link_set_entry(set, idx)
+ *		Access the link set entry at index `idx' from set `set'.
+ */
+#define	__link_set_foreach(pvar, set)					\
+	for (pvar = __link_set_start(set); pvar < __link_set_end(set); pvar++)
+
+#define	__link_set_entry(set, idx)	(__link_set_begin(set)[idx])
+
+#define  __BIONIC__   1
+
+#endif /* !_SYS_CDEFS_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/cdefs_elf.h b/ndk/build/platforms/android-1.5/common/include/sys/cdefs_elf.h
new file mode 100644
index 0000000..e051b1d
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/cdefs_elf.h
@@ -0,0 +1,152 @@
+/*	$NetBSD: cdefs_elf.h,v 1.22 2005/02/26 22:25:34 perry Exp $	*/
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#ifndef _SYS_CDEFS_ELF_H_
+#define	_SYS_CDEFS_ELF_H_
+
+#ifdef __LEADING_UNDERSCORE
+#define	_C_LABEL(x)	__CONCAT(_,x)
+#define _C_LABEL_STRING(x)	"_"x
+#else
+#define	_C_LABEL(x)	x
+#define _C_LABEL_STRING(x)	x
+#endif
+
+#if __STDC__
+#define	___RENAME(x)	__asm__(___STRING(_C_LABEL(x)))
+#else
+#ifdef __LEADING_UNDERSCORE
+#define	___RENAME(x)	____RENAME(_/**/x)
+#define	____RENAME(x)	__asm__(___STRING(x))
+#else
+#define	___RENAME(x)	__asm__(___STRING(x))
+#endif
+#endif
+
+#define	__indr_reference(sym,alias)	/* nada, since we do weak refs */
+
+#if __STDC__
+#define	__strong_alias(alias,sym)	       				\
+    __asm__(".global " _C_LABEL_STRING(#alias) "\n"			\
+	    _C_LABEL_STRING(#alias) " = " _C_LABEL_STRING(#sym));
+
+#define	__weak_alias(alias,sym)						\
+    __asm__(".weak " _C_LABEL_STRING(#alias) "\n"			\
+	    _C_LABEL_STRING(#alias) " = " _C_LABEL_STRING(#sym));
+#define	__weak_extern(sym)						\
+    __asm__(".weak " _C_LABEL_STRING(#sym));
+#define	__warn_references(sym,msg)					\
+    __asm__(".section .gnu.warning." #sym "\n\t.ascii \"" msg "\"\n\t.text");
+
+#else /* !__STDC__ */
+
+#ifdef __LEADING_UNDERSCORE
+#define __weak_alias(alias,sym) ___weak_alias(_/**/alias,_/**/sym)
+#define	___weak_alias(alias,sym)					\
+    __asm__(".weak alias\nalias = sym");
+#else
+#define	__weak_alias(alias,sym)						\
+    __asm__(".weak alias\nalias = sym");
+#endif
+#ifdef __LEADING_UNDERSCORE
+#define __weak_extern(sym) ___weak_extern(_/**/sym)
+#define	___weak_extern(sym)						\
+    __asm__(".weak sym");
+#else
+#define	__weak_extern(sym)						\
+    __asm__(".weak sym");
+#endif
+#define	__warn_references(sym,msg)					\
+    __asm__(".section .gnu.warning.sym\n\t.ascii msg ; .text");
+
+#endif /* !__STDC__ */
+
+#if __STDC__
+#define	__SECTIONSTRING(_sec, _str)					\
+	__asm__(".section " #_sec "\n\t.asciz \"" _str "\"\n\t.previous")
+#else
+#define	__SECTIONSTRING(_sec, _str)					\
+	__asm__(".section _sec\n\t.asciz _str\n\t.previous")
+#endif
+
+#define	__IDSTRING(_n,_s)		__SECTIONSTRING(.ident,_s)
+
+#define	__RCSID(_s)			__IDSTRING(rcsid,_s)
+#define	__SCCSID(_s)
+#define __SCCSID2(_s)
+#if 0	/* XXX userland __COPYRIGHTs have \ns in them */
+#define	__COPYRIGHT(_s)			__SECTIONSTRING(.copyright,_s)
+#else
+#define	__COPYRIGHT(_s)							\
+	static const char copyright[]					\
+	    __attribute__((__unused__,__section__(".copyright"))) = _s
+#endif
+
+#define	__KERNEL_RCSID(_n, _s)		__RCSID(_s)
+#define	__KERNEL_SCCSID(_n, _s)
+#if 0	/* XXX see above */
+#define	__KERNEL_COPYRIGHT(_n, _s)	__COPYRIGHT(_s)
+#else
+#define	__KERNEL_COPYRIGHT(_n, _s)	__SECTIONSTRING(.copyright, _s)
+#endif
+
+#ifndef __lint__
+#define	__link_set_make_entry(set, sym)					\
+	static void const * const __link_set_##set##_sym_##sym		\
+	    __section("link_set_" #set) __used = &sym
+#define	__link_set_make_entry2(set, sym, n)				\
+	static void const * const __link_set_##set##_sym_##sym##_##n	\
+	    __section("link_set_" #set) __used = &sym[n]
+#else
+#define	__link_set_make_entry(set, sym)					\
+	extern void const * const __link_set_##set##_sym_##sym
+#define	__link_set_make_entry2(set, sym, n)				\
+	extern void const * const __link_set_##set##_sym_##sym##_##n
+#endif /* __lint__ */
+
+#define	__link_set_add_text(set, sym)	__link_set_make_entry(set, sym)
+#define	__link_set_add_rodata(set, sym)	__link_set_make_entry(set, sym)
+#define	__link_set_add_data(set, sym)	__link_set_make_entry(set, sym)
+#define	__link_set_add_bss(set, sym)	__link_set_make_entry(set, sym)
+#define	__link_set_add_text2(set, sym, n)   __link_set_make_entry2(set, sym, n)
+#define	__link_set_add_rodata2(set, sym, n) __link_set_make_entry2(set, sym, n)
+#define	__link_set_add_data2(set, sym, n)   __link_set_make_entry2(set, sym, n)
+#define	__link_set_add_bss2(set, sym, n)    __link_set_make_entry2(set, sym, n)
+
+#define	__link_set_decl(set, ptype)					\
+	extern ptype * const __start_link_set_##set[];			\
+	extern ptype * const __stop_link_set_##set[]			\
+
+#define	__link_set_start(set)	(__start_link_set_##set)
+#define	__link_set_end(set)	(__stop_link_set_##set)
+
+#define	__link_set_count(set)						\
+	(__link_set_end(set) - __link_set_start(set))
+
+#endif /* !_SYS_CDEFS_ELF_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/dirent.h b/ndk/build/platforms/android-1.5/common/include/sys/dirent.h
new file mode 100644
index 0000000..da96f5e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/dirent.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_DIRENT_H_
+#define _SYS_DIRENT_H_
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/* this corresponds to the kernel dirent64 */
+struct dirent {
+  uint64_t          d_ino;
+  int64_t           d_off;
+  unsigned short    d_reclen;
+  unsigned char     d_type;
+  char              d_name[256];
+};
+
+extern int getdents(unsigned int, struct dirent *, unsigned int);
+
+__END_DECLS
+
+#endif /* _SYS_DIRENT_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/endian.h b/ndk/build/platforms/android-1.5/common/include/sys/endian.h
new file mode 100644
index 0000000..00f4839
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/endian.h
@@ -0,0 +1,273 @@
+/*	$OpenBSD: endian.h,v 1.17 2006/01/06 18:53:05 millert Exp $	*/
+
+/*-
+ * Copyright (c) 1997 Niklas Hallqvist.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
+ */
+
+/*
+ * Generic definitions for little- and big-endian systems.  Other endianesses
+ * has to be dealt with in the specific machine/endian.h file for that port.
+ *
+ * This file is meant to be included from a little- or big-endian port's
+ * machine/endian.h after setting _BYTE_ORDER to either 1234 for little endian
+ * or 4321 for big..
+ */
+
+#ifndef _SYS_ENDIAN_H_
+#define _SYS_ENDIAN_H_
+
+#include <sys/cdefs.h>
+#include <machine/_types.h>
+
+#define _LITTLE_ENDIAN	1234
+#define _BIG_ENDIAN	4321
+#define _PDP_ENDIAN	3412
+
+#if __BSD_VISIBLE
+#define LITTLE_ENDIAN	_LITTLE_ENDIAN
+#define BIG_ENDIAN	_BIG_ENDIAN
+#define PDP_ENDIAN	_PDP_ENDIAN
+#define BYTE_ORDER	_BYTE_ORDER
+#endif
+
+#ifdef __GNUC__
+
+#define __swap16gen(x) __statement({					\
+	__uint16_t __swap16gen_x = (x);					\
+									\
+	(__uint16_t)((__swap16gen_x & 0xff) << 8 |			\
+	    (__swap16gen_x & 0xff00) >> 8);				\
+})
+
+#define __swap32gen(x) __statement({					\
+	__uint32_t __swap32gen_x = (x);					\
+									\
+	(__uint32_t)((__swap32gen_x & 0xff) << 24 |			\
+	    (__swap32gen_x & 0xff00) << 8 |				\
+	    (__swap32gen_x & 0xff0000) >> 8 |				\
+	    (__swap32gen_x & 0xff000000) >> 24);			\
+})
+
+#define __swap64gen(x) __statement({					\
+	__uint64_t __swap64gen_x = (x);					\
+									\
+	(__uint64_t)((__swap64gen_x & 0xff) << 56 |			\
+	    (__swap64gen_x & 0xff00ULL) << 40 |				\
+	    (__swap64gen_x & 0xff0000ULL) << 24 |			\
+	    (__swap64gen_x & 0xff000000ULL) << 8 |			\
+	    (__swap64gen_x & 0xff00000000ULL) >> 8 |			\
+	    (__swap64gen_x & 0xff0000000000ULL) >> 24 |			\
+	    (__swap64gen_x & 0xff000000000000ULL) >> 40 |		\
+	    (__swap64gen_x & 0xff00000000000000ULL) >> 56);		\
+})
+
+#else /* __GNUC__ */
+
+/* Note that these macros evaluate their arguments several times.  */
+#define __swap16gen(x)							\
+    (__uint16_t)(((__uint16_t)(x) & 0xff) << 8 | ((__uint16_t)(x) & 0xff00) >> 8)
+
+#define __swap32gen(x)							\
+    (__uint32_t)(((__uint32_t)(x) & 0xff) << 24 |			\
+    ((__uint32_t)(x) & 0xff00) << 8 | ((__uint32_t)(x) & 0xff0000) >> 8 |\
+    ((__uint32_t)(x) & 0xff000000) >> 24)
+
+#define __swap64gen(x)							\
+	(__uint64_t)((((__uint64_t)(x) & 0xff) << 56) |			\
+	    ((__uint64_t)(x) & 0xff00ULL) << 40 |			\
+	    ((__uint64_t)(x) & 0xff0000ULL) << 24 |			\
+	    ((__uint64_t)(x) & 0xff000000ULL) << 8 |			\
+	    ((__uint64_t)(x) & 0xff00000000ULL) >> 8 |			\
+	    ((__uint64_t)(x) & 0xff0000000000ULL) >> 24 |		\
+	    ((__uint64_t)(x) & 0xff000000000000ULL) >> 40 |		\
+	    ((__uint64_t)(x) & 0xff00000000000000ULL) >> 56)
+
+#endif /* __GNUC__ */
+
+/*
+ * Define MD_SWAP if you provide swap{16,32}md functions/macros that are
+ * optimized for your architecture,  These will be used for swap{16,32}
+ * unless the argument is a constant and we are using GCC, where we can
+ * take advantage of the CSE phase much better by using the generic version.
+ */
+#ifdef MD_SWAP
+#if __GNUC__
+
+#define __swap16(x) __statement({					\
+	__uint16_t __swap16_x = (x);					\
+									\
+	__builtin_constant_p(x) ? __swap16gen(__swap16_x) :		\
+	    __swap16md(__swap16_x);					\
+})
+
+#define __swap32(x) __statement({					\
+	__uint32_t __swap32_x = (x);					\
+									\
+	__builtin_constant_p(x) ? __swap32gen(__swap32_x) :		\
+	    __swap32md(__swap32_x);					\
+})
+
+#define __swap64(x) __statement({					\
+	__uint64_t __swap64_x = (x);					\
+									\
+	__builtin_constant_p(x) ? __swap64gen(__swap64_x) :		\
+	    __swap64md(__swap64_x);					\
+})
+
+#endif /* __GNUC__  */
+
+#else /* MD_SWAP */
+#define __swap16 __swap16gen
+#define __swap32 __swap32gen
+#define __swap64 __swap64gen
+#endif /* MD_SWAP */
+
+#define __swap16_multi(v, n) do {						\
+	__size_t __swap16_multi_n = (n);				\
+	__uint16_t *__swap16_multi_v = (v);				\
+									\
+	while (__swap16_multi_n) {					\
+		*__swap16_multi_v = swap16(*__swap16_multi_v);		\
+		__swap16_multi_v++;					\
+		__swap16_multi_n--;					\
+	}								\
+} while (0)
+
+#if __BSD_VISIBLE
+#define swap16 __swap16
+#define swap32 __swap32
+#define swap64 __swap64
+#define swap16_multi __swap16_multi
+
+__BEGIN_DECLS
+__uint64_t	htobe64(__uint64_t);
+__uint32_t	htobe32(__uint32_t);
+__uint16_t	htobe16(__uint16_t);
+__uint64_t	betoh64(__uint64_t);
+__uint32_t	betoh32(__uint32_t);
+__uint16_t	betoh16(__uint16_t);
+
+__uint64_t	htole64(__uint64_t);
+__uint32_t	htole32(__uint32_t);
+__uint16_t	htole16(__uint16_t);
+__uint64_t	letoh64(__uint64_t);
+__uint32_t	letoh32(__uint32_t);
+__uint16_t	letoh16(__uint16_t);
+__END_DECLS
+#endif /* __BSD_VISIBLE */
+
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+
+/* Can be overridden by machine/endian.h before inclusion of this file.  */
+#ifndef _QUAD_HIGHWORD
+#define _QUAD_HIGHWORD 1
+#endif
+#ifndef _QUAD_LOWWORD
+#define _QUAD_LOWWORD 0
+#endif
+
+#if __BSD_VISIBLE
+#define htobe16 __swap16
+#define htobe32 __swap32
+#define htobe64 __swap64
+#define betoh16 __swap16
+#define betoh32 __swap32
+#define betoh64 __swap64
+
+#define htole16(x) (x)
+#define htole32(x) (x)
+#define htole64(x) (x)
+#define letoh16(x) (x)
+#define letoh32(x) (x)
+#define letoh64(x) (x)
+#endif /* __BSD_VISIBLE */
+
+#define htons(x) __swap16(x)
+#define htonl(x) __swap32(x)
+#define ntohs(x) __swap16(x)
+#define ntohl(x) __swap32(x)
+
+/* Bionic additions */
+#define ntohq(x) __swap64(x)
+#define htonq(x) __swap64(x)
+
+#define __LITTLE_ENDIAN_BITFIELD
+
+#endif /* _BYTE_ORDER */
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+
+/* Can be overridden by machine/endian.h before inclusion of this file.  */
+#ifndef _QUAD_HIGHWORD
+#define _QUAD_HIGHWORD 0
+#endif
+#ifndef _QUAD_LOWWORD
+#define _QUAD_LOWWORD 1
+#endif
+
+#if __BSD_VISIBLE
+#define htole16 __swap16
+#define htole32 __swap32
+#define htole64 __swap64
+#define letoh16 __swap16
+#define letoh32 __swap32
+#define letoh64 __swap64
+
+#define htobe16(x) (x)
+#define htobe32(x) (x)
+#define htobe64(x) (x)
+#define betoh16(x) (x)
+#define betoh32(x) (x)
+#define betoh64(x) (x)
+#endif /* __BSD_VISIBLE */
+
+#define htons(x) (x)
+#define htonl(x) (x)
+#define ntohs(x) (x)
+#define ntohl(x) (x)
+
+/* Bionic additions */
+#define ntohq(x) (x)
+#define htonq(x) (x)
+
+#define __BIG_ENDIAN_BITFIELD
+
+#endif /* _BYTE_ORDER */
+
+#if __BSD_VISIBLE
+#define	NTOHL(x) (x) = ntohl((u_int32_t)(x))
+#define	NTOHS(x) (x) = ntohs((u_int16_t)(x))
+#define	HTONL(x) (x) = htonl((u_int32_t)(x))
+#define	HTONS(x) (x) = htons((u_int16_t)(x))
+#endif
+
+
+#define  __BYTE_ORDER       _BYTE_ORDER
+#ifndef  __LITTLE_ENDIAN
+#define  __LITTLE_ENDIAN    _LITTLE_ENDIAN
+#endif
+#ifndef  __BIG_ENDIAN
+#define  __BIG_ENDIAN       _BIG_ENDIAN
+#endif
+
+#endif /* _SYS_ENDIAN_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/epoll.h b/ndk/build/platforms/android-1.5/common/include/sys/epoll.h
new file mode 100644
index 0000000..1478caa
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/epoll.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_EPOLL_H_
+#define _SYS_EPOLL_H_
+
+#define EPOLLIN          0x00000001
+#define EPOLLPRI         0x00000002
+#define EPOLLOUT         0x00000004
+#define EPOLLERR         0x00000008
+#define EPOLLHUP         0x00000010
+#define EPOLLRDNORM      0x00000040
+#define EPOLLRDBAND      0x00000080
+#define EPOLLWRNORM      0x00000100
+#define EPOLLWRBAND      0x00000200
+#define EPOLLMSG         0x00000400
+#define EPOLLET          0x80000000
+
+#define EPOLL_CTL_ADD    1
+#define EPOLL_CTL_DEL    2
+#define EPOLL_CTL_MOD    3
+
+typedef union epoll_data 
+{
+    void *ptr;
+    int fd;
+    unsigned int u32;
+    unsigned long long u64;
+} epoll_data_t;
+
+struct epoll_event 
+{
+    unsigned int events;
+    epoll_data_t data;
+};
+
+int epoll_create(int size);
+int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
+int epoll_wait(int epfd, struct epoll_event *events, int max, int timeout);
+
+#endif  /* _SYS_EPOLL_H_ */
+
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/errno.h b/ndk/build/platforms/android-1.5/common/include/sys/errno.h
new file mode 100644
index 0000000..339f4fc
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/errno.h
@@ -0,0 +1 @@
+#include <errno.h>
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/exec_elf.h b/ndk/build/platforms/android-1.5/common/include/sys/exec_elf.h
new file mode 100644
index 0000000..f72f81e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/exec_elf.h
@@ -0,0 +1,625 @@
+/*	$OpenBSD: exec_elf.h,v 1.41 2006/01/06 18:53:05 millert Exp $	*/
+/*
+ * Copyright (c) 1995, 1996 Erik Theisen.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 THE AUTHOR 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.
+ */
+
+/*
+ * This is the ELF ABI header file
+ * formerly known as "elf_abi.h".
+ */
+
+#ifndef _SYS_EXEC_ELF_H_
+#define _SYS_EXEC_ELF_H_
+
+#include <machine/_types.h>
+#include <machine/exec.h>
+
+typedef __uint8_t	Elf_Byte;
+
+typedef __uint32_t	Elf32_Addr;	/* Unsigned program address */
+typedef __uint32_t	Elf32_Off;	/* Unsigned file offset */
+typedef __int32_t	Elf32_Sword;	/* Signed large integer */
+typedef __uint32_t	Elf32_Word;	/* Unsigned large integer */
+typedef __uint16_t	Elf32_Half;	/* Unsigned medium integer */
+
+typedef __uint64_t	Elf64_Addr;
+typedef __uint64_t	Elf64_Off;
+typedef __int32_t	Elf64_Shalf;
+
+#ifdef __alpha__
+typedef __int64_t	Elf64_Sword;
+typedef __uint64_t	Elf64_Word;
+#else
+typedef __int32_t	Elf64_Sword;
+typedef __uint32_t	Elf64_Word;
+#endif
+
+typedef __int64_t	Elf64_Sxword;
+typedef __uint64_t	Elf64_Xword;
+
+typedef __uint32_t	Elf64_Half;
+typedef __uint16_t	Elf64_Quarter;
+
+/*
+ * e_ident[] identification indexes 
+ * See http://www.caldera.com/developers/gabi/2000-07-17/ch4.eheader.html
+ */
+#define EI_MAG0		0		/* file ID */
+#define EI_MAG1		1		/* file ID */
+#define EI_MAG2		2		/* file ID */
+#define EI_MAG3		3		/* file ID */
+#define EI_CLASS	4		/* file class */
+#define EI_DATA		5		/* data encoding */
+#define EI_VERSION	6		/* ELF header version */
+#define EI_OSABI	7		/* OS/ABI ID */
+#define EI_ABIVERSION	8		/* ABI version */ 
+#define EI_PAD		9		/* start of pad bytes */
+#define EI_NIDENT	16		/* Size of e_ident[] */
+
+/* e_ident[] magic number */
+#define	ELFMAG0		0x7f		/* e_ident[EI_MAG0] */
+#define	ELFMAG1		'E'		/* e_ident[EI_MAG1] */
+#define	ELFMAG2		'L'		/* e_ident[EI_MAG2] */
+#define	ELFMAG3		'F'		/* e_ident[EI_MAG3] */
+#define	ELFMAG		"\177ELF"	/* magic */
+#define	SELFMAG		4		/* size of magic */
+
+/* e_ident[] file class */
+#define	ELFCLASSNONE	0		/* invalid */
+#define	ELFCLASS32	1		/* 32-bit objs */
+#define	ELFCLASS64	2		/* 64-bit objs */
+#define	ELFCLASSNUM	3		/* number of classes */
+
+/* e_ident[] data encoding */
+#define ELFDATANONE	0		/* invalid */
+#define ELFDATA2LSB	1		/* Little-Endian */
+#define ELFDATA2MSB	2		/* Big-Endian */
+#define ELFDATANUM	3		/* number of data encode defines */
+
+/* e_ident[] Operating System/ABI */
+#define ELFOSABI_SYSV		0	/* UNIX System V ABI */
+#define ELFOSABI_HPUX		1	/* HP-UX operating system */
+#define ELFOSABI_NETBSD		2	/* NetBSD */
+#define ELFOSABI_LINUX		3	/* GNU/Linux */
+#define ELFOSABI_HURD		4	/* GNU/Hurd */
+#define ELFOSABI_86OPEN		5	/* 86Open common IA32 ABI */
+#define ELFOSABI_SOLARIS	6	/* Solaris */
+#define ELFOSABI_MONTEREY	7	/* Monterey */
+#define ELFOSABI_IRIX		8	/* IRIX */
+#define ELFOSABI_FREEBSD	9	/* FreeBSD */
+#define ELFOSABI_TRU64		10	/* TRU64 UNIX */
+#define ELFOSABI_MODESTO	11	/* Novell Modesto */
+#define ELFOSABI_OPENBSD	12	/* OpenBSD */
+#define ELFOSABI_ARM		97	/* ARM */
+#define ELFOSABI_STANDALONE	255	/* Standalone (embedded) application */
+
+/* e_ident */
+#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
+                      (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
+                      (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
+                      (ehdr).e_ident[EI_MAG3] == ELFMAG3)
+
+/* ELF Header */
+typedef struct elfhdr {
+	unsigned char	e_ident[EI_NIDENT]; /* ELF Identification */
+	Elf32_Half	e_type;		/* object file type */
+	Elf32_Half	e_machine;	/* machine */
+	Elf32_Word	e_version;	/* object file version */
+	Elf32_Addr	e_entry;	/* virtual entry point */
+	Elf32_Off	e_phoff;	/* program header table offset */
+	Elf32_Off	e_shoff;	/* section header table offset */
+	Elf32_Word	e_flags;	/* processor-specific flags */
+	Elf32_Half	e_ehsize;	/* ELF header size */
+	Elf32_Half	e_phentsize;	/* program header entry size */
+	Elf32_Half	e_phnum;	/* number of program header entries */
+	Elf32_Half	e_shentsize;	/* section header entry size */
+	Elf32_Half	e_shnum;	/* number of section header entries */
+	Elf32_Half	e_shstrndx;	/* section header table's "section 
+					   header string table" entry offset */
+} Elf32_Ehdr;
+
+typedef struct {
+	unsigned char	e_ident[EI_NIDENT];	/* Id bytes */
+	Elf64_Quarter	e_type;			/* file type */
+	Elf64_Quarter	e_machine;		/* machine type */
+	Elf64_Half	e_version;		/* version number */
+	Elf64_Addr	e_entry;		/* entry point */
+	Elf64_Off	e_phoff;		/* Program hdr offset */
+	Elf64_Off	e_shoff;		/* Section hdr offset */
+	Elf64_Half	e_flags;		/* Processor flags */
+	Elf64_Quarter	e_ehsize;		/* sizeof ehdr */
+	Elf64_Quarter	e_phentsize;		/* Program header entry size */
+	Elf64_Quarter	e_phnum;		/* Number of program headers */
+	Elf64_Quarter	e_shentsize;		/* Section header entry size */
+	Elf64_Quarter	e_shnum;		/* Number of section headers */
+	Elf64_Quarter	e_shstrndx;		/* String table index */
+} Elf64_Ehdr;
+
+/* e_type */
+#define ET_NONE		0		/* No file type */
+#define ET_REL		1		/* relocatable file */
+#define ET_EXEC		2		/* executable file */
+#define ET_DYN		3		/* shared object file */
+#define ET_CORE		4		/* core file */
+#define ET_NUM		5		/* number of types */
+#define ET_LOPROC	0xff00		/* reserved range for processor */
+#define ET_HIPROC	0xffff		/*  specific e_type */
+
+/* e_machine */
+#define EM_NONE		0		/* No Machine */
+#define EM_M32		1		/* AT&T WE 32100 */
+#define EM_SPARC	2		/* SPARC */
+#define EM_386		3		/* Intel 80386 */
+#define EM_68K		4		/* Motorola 68000 */
+#define EM_88K		5		/* Motorola 88000 */
+#define EM_486		6		/* Intel 80486 - unused? */
+#define EM_860		7		/* Intel 80860 */
+#define EM_MIPS		8		/* MIPS R3000 Big-Endian only */
+/* 
+ * Don't know if EM_MIPS_RS4_BE,
+ * EM_SPARC64, EM_PARISC,
+ * or EM_PPC are ABI compliant
+ */
+#define EM_MIPS_RS4_BE	10		/* MIPS R4000 Big-Endian */
+#define EM_SPARC64	11		/* SPARC v9 64-bit unoffical */
+#define EM_PARISC	15		/* HPPA */
+#define EM_SPARC32PLUS	18		/* Enhanced instruction set SPARC */
+#define EM_PPC		20		/* PowerPC */
+#define EM_ARM		40		/* Advanced RISC Machines ARM */
+#define EM_ALPHA	41		/* DEC ALPHA */
+#define EM_SPARCV9	43		/* SPARC version 9 */
+#define EM_ALPHA_EXP	0x9026		/* DEC ALPHA */
+#define EM_AMD64	62		/* AMD64 architecture */
+#define EM_VAX		75		/* DEC VAX */
+#define EM_NUM		15		/* number of machine types */
+
+/* Version */
+#define EV_NONE		0		/* Invalid */
+#define EV_CURRENT	1		/* Current */
+#define EV_NUM		2		/* number of versions */
+
+/* Section Header */
+typedef struct {
+	Elf32_Word	sh_name;	/* name - index into section header
+					   string table section */
+	Elf32_Word	sh_type;	/* type */
+	Elf32_Word	sh_flags;	/* flags */
+	Elf32_Addr	sh_addr;	/* address */
+	Elf32_Off	sh_offset;	/* file offset */
+	Elf32_Word	sh_size;	/* section size */
+	Elf32_Word	sh_link;	/* section header table index link */
+	Elf32_Word	sh_info;	/* extra information */
+	Elf32_Word	sh_addralign;	/* address alignment */
+	Elf32_Word	sh_entsize;	/* section entry size */
+} Elf32_Shdr;
+
+typedef struct {
+	Elf64_Half	sh_name;	/* section name */
+	Elf64_Half	sh_type;	/* section type */
+	Elf64_Xword	sh_flags;	/* section flags */
+	Elf64_Addr	sh_addr;	/* virtual address */
+	Elf64_Off	sh_offset;	/* file offset */
+	Elf64_Xword	sh_size;	/* section size */
+	Elf64_Half	sh_link;	/* link to another */
+	Elf64_Half	sh_info;	/* misc info */
+	Elf64_Xword	sh_addralign;	/* memory alignment */
+	Elf64_Xword	sh_entsize;	/* table entry size */
+} Elf64_Shdr;
+
+/* Special Section Indexes */
+#define SHN_UNDEF	0		/* undefined */
+#define SHN_LORESERVE	0xff00		/* lower bounds of reserved indexes */
+#define SHN_LOPROC	0xff00		/* reserved range for processor */
+#define SHN_HIPROC	0xff1f		/*   specific section indexes */
+#define SHN_ABS		0xfff1		/* absolute value */
+#define SHN_COMMON	0xfff2		/* common symbol */
+#define SHN_HIRESERVE	0xffff		/* upper bounds of reserved indexes */
+
+/* sh_type */
+#define SHT_NULL	0		/* inactive */
+#define SHT_PROGBITS	1		/* program defined information */
+#define SHT_SYMTAB	2		/* symbol table section */
+#define SHT_STRTAB	3		/* string table section */
+#define SHT_RELA	4		/* relocation section with addends*/
+#define SHT_HASH	5		/* symbol hash table section */
+#define SHT_DYNAMIC	6		/* dynamic section */
+#define SHT_NOTE	7		/* note section */
+#define SHT_NOBITS	8		/* no space section */
+#define SHT_REL		9		/* relation section without addends */
+#define SHT_SHLIB	10		/* reserved - purpose unknown */
+#define SHT_DYNSYM	11		/* dynamic symbol table section */
+#define SHT_NUM		12		/* number of section types */
+#define SHT_LOPROC	0x70000000	/* reserved range for processor */
+#define SHT_HIPROC	0x7fffffff	/*  specific section header types */
+#define SHT_LOUSER	0x80000000	/* reserved range for application */
+#define SHT_HIUSER	0xffffffff	/*  specific indexes */
+
+/* Section names */
+#define ELF_BSS         ".bss"		/* uninitialized data */
+#define ELF_DATA        ".data"		/* initialized data */
+#define ELF_DEBUG       ".debug"	/* debug */
+#define ELF_DYNAMIC     ".dynamic"	/* dynamic linking information */
+#define ELF_DYNSTR      ".dynstr"	/* dynamic string table */
+#define ELF_DYNSYM      ".dynsym"	/* dynamic symbol table */
+#define ELF_FINI        ".fini"		/* termination code */
+#define ELF_GOT         ".got"		/* global offset table */
+#define ELF_HASH        ".hash"		/* symbol hash table */
+#define ELF_INIT        ".init"		/* initialization code */
+#define ELF_REL_DATA    ".rel.data"	/* relocation data */
+#define ELF_REL_FINI    ".rel.fini"	/* relocation termination code */
+#define ELF_REL_INIT    ".rel.init"	/* relocation initialization code */
+#define ELF_REL_DYN     ".rel.dyn"	/* relocaltion dynamic link info */
+#define ELF_REL_RODATA  ".rel.rodata"	/* relocation read-only data */
+#define ELF_REL_TEXT    ".rel.text"	/* relocation code */
+#define ELF_RODATA      ".rodata"	/* read-only data */
+#define ELF_SHSTRTAB    ".shstrtab"	/* section header string table */
+#define ELF_STRTAB      ".strtab"	/* string table */
+#define ELF_SYMTAB      ".symtab"	/* symbol table */
+#define ELF_TEXT        ".text"		/* code */
+
+
+/* Section Attribute Flags - sh_flags */
+#define SHF_WRITE	0x1		/* Writable */
+#define SHF_ALLOC	0x2		/* occupies memory */
+#define SHF_EXECINSTR	0x4		/* executable */
+#define SHF_MASKPROC	0xf0000000	/* reserved bits for processor */
+					/*  specific section attributes */
+
+/* Symbol Table Entry */
+typedef struct elf32_sym {
+	Elf32_Word	st_name;	/* name - index into string table */
+	Elf32_Addr	st_value;	/* symbol value */
+	Elf32_Word	st_size;	/* symbol size */
+	unsigned char	st_info;	/* type and binding */
+	unsigned char	st_other;	/* 0 - no defined meaning */
+	Elf32_Half	st_shndx;	/* section header index */
+} Elf32_Sym;
+
+typedef struct {
+	Elf64_Half	st_name;	/* Symbol name index in str table */
+	Elf_Byte	st_info;	/* type / binding attrs */
+	Elf_Byte	st_other;	/* unused */
+	Elf64_Quarter	st_shndx;	/* section index of symbol */
+	Elf64_Xword	st_value;	/* value of symbol */
+	Elf64_Xword	st_size;	/* size of symbol */
+} Elf64_Sym;
+
+/* Symbol table index */
+#define STN_UNDEF	0		/* undefined */
+
+/* Extract symbol info - st_info */
+#define ELF32_ST_BIND(x)	((x) >> 4)
+#define ELF32_ST_TYPE(x)	(((unsigned int) x) & 0xf)
+#define ELF32_ST_INFO(b,t)	(((b) << 4) + ((t) & 0xf))
+
+#define ELF64_ST_BIND(x)	((x) >> 4)
+#define ELF64_ST_TYPE(x)	(((unsigned int) x) & 0xf)
+#define ELF64_ST_INFO(b,t)	(((b) << 4) + ((t) & 0xf))
+
+/* Symbol Binding - ELF32_ST_BIND - st_info */
+#define STB_LOCAL	0		/* Local symbol */
+#define STB_GLOBAL	1		/* Global symbol */
+#define STB_WEAK	2		/* like global - lower precedence */
+#define STB_NUM		3		/* number of symbol bindings */
+#define STB_LOPROC	13		/* reserved range for processor */
+#define STB_HIPROC	15		/*  specific symbol bindings */
+
+/* Symbol type - ELF32_ST_TYPE - st_info */
+#define STT_NOTYPE	0		/* not specified */
+#define STT_OBJECT	1		/* data object */
+#define STT_FUNC	2		/* function */
+#define STT_SECTION	3		/* section */
+#define STT_FILE	4		/* file */
+#define STT_NUM		5		/* number of symbol types */
+#define STT_LOPROC	13		/* reserved range for processor */
+#define STT_HIPROC	15		/*  specific symbol types */
+
+/* Relocation entry with implicit addend */
+typedef struct {
+	Elf32_Addr	r_offset;	/* offset of relocation */
+	Elf32_Word	r_info;		/* symbol table index and type */
+} Elf32_Rel;
+
+/* Relocation entry with explicit addend */
+typedef struct {
+	Elf32_Addr	r_offset;	/* offset of relocation */
+	Elf32_Word	r_info;		/* symbol table index and type */
+	Elf32_Sword	r_addend;
+} Elf32_Rela;
+
+/* Extract relocation info - r_info */
+#define ELF32_R_SYM(i)		((i) >> 8)
+#define ELF32_R_TYPE(i)		((unsigned char) (i))
+#define ELF32_R_INFO(s,t) 	(((s) << 8) + (unsigned char)(t))
+
+typedef struct {
+	Elf64_Xword	r_offset;	/* where to do it */
+	Elf64_Xword	r_info;		/* index & type of relocation */
+} Elf64_Rel;
+
+typedef struct {
+	Elf64_Xword	r_offset;	/* where to do it */
+	Elf64_Xword	r_info;		/* index & type of relocation */
+	Elf64_Sxword	r_addend;	/* adjustment value */
+} Elf64_Rela;
+
+#define	ELF64_R_SYM(info)	((info) >> 32)
+#define	ELF64_R_TYPE(info)	((info) & 0xFFFFFFFF)
+#define ELF64_R_INFO(s,t) 	(((s) << 32) + (__uint32_t)(t))
+
+/* Program Header */
+typedef struct {
+	Elf32_Word	p_type;		/* segment type */
+	Elf32_Off	p_offset;	/* segment offset */
+	Elf32_Addr	p_vaddr;	/* virtual address of segment */
+	Elf32_Addr	p_paddr;	/* physical address - ignored? */
+	Elf32_Word	p_filesz;	/* number of bytes in file for seg. */
+	Elf32_Word	p_memsz;	/* number of bytes in mem. for seg. */
+	Elf32_Word	p_flags;	/* flags */
+	Elf32_Word	p_align;	/* memory alignment */
+} Elf32_Phdr;
+
+typedef struct {
+	Elf64_Half	p_type;		/* entry type */
+	Elf64_Half	p_flags;	/* flags */
+	Elf64_Off	p_offset;	/* offset */
+	Elf64_Addr	p_vaddr;	/* virtual address */
+	Elf64_Addr	p_paddr;	/* physical address */
+	Elf64_Xword	p_filesz;	/* file size */
+	Elf64_Xword	p_memsz;	/* memory size */
+	Elf64_Xword	p_align;	/* memory & file alignment */
+} Elf64_Phdr;
+
+/* Segment types - p_type */
+#define PT_NULL		0		/* unused */
+#define PT_LOAD		1		/* loadable segment */
+#define PT_DYNAMIC	2		/* dynamic linking section */
+#define PT_INTERP	3		/* the RTLD */
+#define PT_NOTE		4		/* auxiliary information */
+#define PT_SHLIB	5		/* reserved - purpose undefined */
+#define PT_PHDR		6		/* program header */
+#define PT_NUM		7		/* Number of segment types */
+#define PT_LOOS		0x60000000	/* reserved range for OS */
+#define PT_HIOS		0x6fffffff	/*  specific segment types */
+#define PT_LOPROC	0x70000000	/* reserved range for processor */
+#define PT_HIPROC	0x7fffffff	/*  specific segment types */
+
+/* Segment flags - p_flags */
+#define PF_X		0x1		/* Executable */
+#define PF_W		0x2		/* Writable */
+#define PF_R		0x4		/* Readable */
+#define PF_MASKPROC	0xf0000000	/* reserved bits for processor */
+					/*  specific segment flags */
+
+/* Dynamic structure */
+typedef struct {
+	Elf32_Sword	d_tag;		/* controls meaning of d_val */
+	union {
+		Elf32_Word	d_val;	/* Multiple meanings - see d_tag */
+		Elf32_Addr	d_ptr;	/* program virtual address */
+	} d_un;
+} Elf32_Dyn;
+
+typedef struct {
+	Elf64_Xword	d_tag;		/* controls meaning of d_val */
+	union {
+		Elf64_Addr	d_ptr;
+		Elf64_Xword	d_val;
+	} d_un;
+} Elf64_Dyn;
+
+/* Dynamic Array Tags - d_tag */
+#define DT_NULL		0		/* marks end of _DYNAMIC array */
+#define DT_NEEDED	1		/* string table offset of needed lib */
+#define DT_PLTRELSZ	2		/* size of relocation entries in PLT */
+#define DT_PLTGOT	3		/* address PLT/GOT */
+#define DT_HASH		4		/* address of symbol hash table */
+#define DT_STRTAB	5		/* address of string table */
+#define DT_SYMTAB	6		/* address of symbol table */
+#define DT_RELA		7		/* address of relocation table */
+#define DT_RELASZ	8		/* size of relocation table */
+#define DT_RELAENT	9		/* size of relocation entry */
+#define DT_STRSZ	10		/* size of string table */
+#define DT_SYMENT	11		/* size of symbol table entry */
+#define DT_INIT		12		/* address of initialization func. */
+#define DT_FINI		13		/* address of termination function */
+#define DT_SONAME	14		/* string table offset of shared obj */
+#define DT_RPATH	15		/* string table offset of library
+					   search path */
+#define DT_SYMBOLIC	16		/* start sym search in shared obj. */
+#define DT_REL		17		/* address of rel. tbl. w addends */
+#define DT_RELSZ	18		/* size of DT_REL relocation table */
+#define DT_RELENT	19		/* size of DT_REL relocation entry */
+#define DT_PLTREL	20		/* PLT referenced relocation entry */
+#define DT_DEBUG	21		/* bugger */
+#define DT_TEXTREL	22		/* Allow rel. mod. to unwritable seg */
+#define DT_JMPREL	23		/* add. of PLT's relocation entries */
+#define DT_BIND_NOW	24		/* Bind now regardless of env setting */
+#define DT_NUM		25		/* Number used. */
+#define DT_LOPROC	0x70000000	/* reserved range for processor */
+#define DT_HIPROC	0x7fffffff	/*  specific dynamic array tags */
+	
+/* Standard ELF hashing function */
+unsigned int elf_hash(const unsigned char *name);
+
+/*
+ * Note Definitions
+ */
+typedef struct {
+	Elf32_Word namesz;
+	Elf32_Word descsz;
+	Elf32_Word type;
+} Elf32_Note;
+
+typedef struct {
+	Elf64_Half namesz;
+	Elf64_Half descsz;
+	Elf64_Half type;
+} Elf64_Note;
+
+/*
+ * XXX - these _KERNEL items aren't part of the ABI!
+ */
+#if defined(_KERNEL) || defined(_DYN_LOADER)
+
+#define ELF32_NO_ADDR	((u_long) ~0)	/* Indicates addr. not yet filled in */
+#define ELF_AUX_ENTRIES	8		/* Size of aux array passed to loader */
+
+typedef struct {
+	Elf32_Sword	au_id;				/* 32-bit id */
+	Elf32_Word	au_v;				/* 32-bit value */
+} Aux32Info;
+
+#define ELF64_NO_ADDR	((__uint64_t) ~0)/* Indicates addr. not yet filled in */
+#define ELF64_AUX_ENTRIES	8	/* Size of aux array passed to loader */
+
+typedef struct {
+	Elf64_Shalf	au_id;				/* 32-bit id */
+	Elf64_Xword	au_v;				/* 64-bit id */
+} Aux64Info;
+
+enum AuxID {
+	AUX_null = 0,
+	AUX_ignore = 1,
+	AUX_execfd = 2,
+	AUX_phdr = 3,			/* &phdr[0] */
+	AUX_phent = 4,			/* sizeof(phdr[0]) */
+	AUX_phnum = 5,			/* # phdr entries */
+	AUX_pagesz = 6,			/* PAGESIZE */
+	AUX_base = 7,			/* ld.so base addr */
+	AUX_flags = 8,			/* processor flags */
+	AUX_entry = 9,			/* a.out entry */
+	AUX_sun_uid = 2000,		/* euid */
+	AUX_sun_ruid = 2001,		/* ruid */
+	AUX_sun_gid = 2002,		/* egid */
+	AUX_sun_rgid = 2003		/* rgid */
+};
+
+struct elf_args {
+        u_long  arg_entry;		/* program entry point */
+        u_long  arg_interp;		/* Interpreter load address */
+        u_long  arg_phaddr;		/* program header address */
+        u_long  arg_phentsize;		/* Size of program header */
+        u_long  arg_phnum;		/* Number of program headers */
+        u_long  arg_os;			/* OS tag */
+};
+
+#endif
+
+#if !defined(ELFSIZE) && defined(ARCH_ELFSIZE)
+#define ELFSIZE ARCH_ELFSIZE
+#endif
+
+#if defined(ELFSIZE)
+#define CONCAT(x,y)	__CONCAT(x,y)
+#define ELFNAME(x)	CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x)))
+#define ELFNAME2(x,y)	CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y))))
+#define ELFNAMEEND(x)	CONCAT(x,CONCAT(_elf,ELFSIZE))
+#define ELFDEFNNAME(x)	CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x)))
+#endif
+
+#if defined(ELFSIZE) && (ELFSIZE == 32)
+#define Elf_Ehdr	Elf32_Ehdr
+#define Elf_Phdr	Elf32_Phdr
+#define Elf_Shdr	Elf32_Shdr
+#define Elf_Sym		Elf32_Sym
+#define Elf_Rel		Elf32_Rel
+#define Elf_RelA	Elf32_Rela
+#define Elf_Dyn		Elf32_Dyn
+#define Elf_Half	Elf32_Half
+#define Elf_Word	Elf32_Word
+#define Elf_Sword	Elf32_Sword
+#define Elf_Addr	Elf32_Addr
+#define Elf_Off		Elf32_Off
+#define Elf_Nhdr	Elf32_Nhdr
+#define Elf_Note	Elf32_Note
+
+#define ELF_R_SYM	ELF32_R_SYM
+#define ELF_R_TYPE	ELF32_R_TYPE
+#define ELF_R_INFO	ELF32_R_INFO
+#define ELFCLASS	ELFCLASS32
+
+#define ELF_ST_BIND	ELF32_ST_BIND
+#define ELF_ST_TYPE	ELF32_ST_TYPE
+#define ELF_ST_INFO	ELF32_ST_INFO
+
+#define AuxInfo		Aux32Info
+#elif defined(ELFSIZE) && (ELFSIZE == 64)
+#define Elf_Ehdr	Elf64_Ehdr
+#define Elf_Phdr	Elf64_Phdr
+#define Elf_Shdr	Elf64_Shdr
+#define Elf_Sym		Elf64_Sym
+#define Elf_Rel		Elf64_Rel
+#define Elf_RelA	Elf64_Rela
+#define Elf_Dyn		Elf64_Dyn
+#define Elf_Half	Elf64_Half
+#define Elf_Word	Elf64_Word
+#define Elf_Sword	Elf64_Sword
+#define Elf_Addr	Elf64_Addr
+#define Elf_Off		Elf64_Off
+#define Elf_Nhdr	Elf64_Nhdr
+#define Elf_Note	Elf64_Note
+
+#define ELF_R_SYM	ELF64_R_SYM
+#define ELF_R_TYPE	ELF64_R_TYPE
+#define ELF_R_INFO	ELF64_R_INFO
+#define ELFCLASS	ELFCLASS64
+
+#define ELF_ST_BIND	ELF64_ST_BIND
+#define ELF_ST_TYPE	ELF64_ST_TYPE
+#define ELF_ST_INFO	ELF64_ST_INFO
+
+#define AuxInfo		Aux64Info
+#endif
+
+#ifndef _KERNEL
+extern Elf_Dyn		_DYNAMIC[];
+#endif
+
+#ifdef	_KERNEL
+#ifdef _KERN_DO_ELF64
+int exec_elf64_makecmds(struct proc *, struct exec_package *);
+void *elf64_copyargs(struct exec_package *, struct ps_strings *,
+        void *, void *);
+int exec_elf64_fixup(struct proc *, struct exec_package *);
+char *elf64_check_brand(Elf64_Ehdr *);
+int elf64_os_pt_note(struct proc *, struct exec_package *, Elf64_Ehdr *,
+	char *, size_t, size_t);
+#endif
+#ifdef _KERN_DO_ELF
+int exec_elf32_makecmds(struct proc *, struct exec_package *);
+void *elf32_copyargs(struct exec_package *, struct ps_strings *,
+        void *, void *);
+int exec_elf32_fixup(struct proc *, struct exec_package *);
+char *elf32_check_brand(Elf32_Ehdr *);
+int elf32_os_pt_note(struct proc *, struct exec_package *, Elf32_Ehdr *,
+	char *, size_t, size_t);
+#endif
+
+#endif /* _KERNEL */
+
+#define ELF_TARG_VER	1	/* The ver for which this code is intended */
+
+#endif /* _SYS_EXEC_ELF_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/file.h b/ndk/build/platforms/android-1.5/common/include/sys/file.h
new file mode 100644
index 0000000..06937ff
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/file.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_FILE_H_
+#define _SYS_FILE_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+// ANDROID: needed for flock()
+#include <unistd.h>
+#include <fcntl.h>
+
+#endif /* _SYS_FILE_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/fsuid.h b/ndk/build/platforms/android-1.5/common/include/sys/fsuid.h
new file mode 100644
index 0000000..3257bc0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/fsuid.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_FSUID_H_
+#define _SYS_FSUID_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+extern int setfsuid(uid_t);
+extern int setfsgid(gid_t);
+
+__END_DECLS
+
+#endif /* _SYS_FSUID_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/inotify.h b/ndk/build/platforms/android-1.5/common/include/sys/inotify.h
new file mode 100644
index 0000000..33f9e74
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/inotify.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_INOTIFY_H_
+#define _SYS_INOTIFY_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <linux/inotify.h>
+
+__BEGIN_DECLS
+
+extern int inotify_init(void);
+extern int inotify_add_watch(int, const char *, __u32);
+extern int inotify_rm_watch(int, __u32);
+
+__END_DECLS
+
+#endif /* _SYS_INOTIFY_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/ioctl.h b/ndk/build/platforms/android-1.5/common/include/sys/ioctl.h
new file mode 100644
index 0000000..9f68510
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/ioctl.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_IOCTL_H_
+#define _SYS_IOCTL_H_
+
+#include <sys/cdefs.h>
+#include <linux/ioctl.h>
+#include <asm/ioctls.h>
+#include <asm/termbits.h>
+#include <sys/ioctl_compat.h>
+
+__BEGIN_DECLS
+
+extern int ioctl(int, int, ...);
+
+__END_DECLS
+
+#endif /* _SYS_IOCTL_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/ioctl_compat.h b/ndk/build/platforms/android-1.5/common/include/sys/ioctl_compat.h
new file mode 100644
index 0000000..d79b67a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/ioctl_compat.h
@@ -0,0 +1,168 @@
+/*	$NetBSD: ioctl_compat.h,v 1.15 2005/12/03 17:10:46 christos Exp $	*/
+
+/*
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 THE REGENTS AND CONTRIBUTORS ``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 THE REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)ioctl_compat.h	8.4 (Berkeley) 1/21/94
+ */
+
+#ifndef _SYS_IOCTL_COMPAT_H_
+#define	_SYS_IOCTL_COMPAT_H_
+
+//#include <sys/ttychars.h>
+//#include <sys/ttydev.h>
+
+struct tchars {
+	char	t_intrc;	/* interrupt */
+	char	t_quitc;	/* quit */
+	char	t_startc;	/* start output */
+	char	t_stopc;	/* stop output */
+	char	t_eofc;		/* end-of-file */
+	char	t_brkc;		/* input delimiter (like nl) */
+};
+
+struct ltchars {
+	char	t_suspc;	/* stop process signal */
+	char	t_dsuspc;	/* delayed stop process signal */
+	char	t_rprntc;	/* reprint line */
+	char	t_flushc;	/* flush output (toggles) */
+	char	t_werasc;	/* word erase */
+	char	t_lnextc;	/* literal next character */
+};
+
+/*
+ * Structure for TIOCGETP and TIOCSETP ioctls.
+ */
+#ifndef _SGTTYB_
+#define	_SGTTYB_
+struct sgttyb {
+	char	sg_ispeed;		/* input speed */
+	char	sg_ospeed;		/* output speed */
+	char	sg_erase;		/* erase character */
+	char	sg_kill;		/* kill character */
+	short	sg_flags;		/* mode flags */
+};
+#endif
+
+#ifdef USE_OLD_TTY
+# undef  TIOCGETD
+# define TIOCGETD	_IOR('t', 0, int)	/* get line discipline */
+# undef  TIOCSETD
+# define TIOCSETD	_IOW('t', 1, int)	/* set line discipline */
+#else
+# define OTIOCGETD	_IOR('t', 0, int)	/* get line discipline */
+# define OTIOCSETD	_IOW('t', 1, int)	/* set line discipline */
+#endif
+#define	TIOCHPCL	_IO('t', 2)		/* hang up on last close */
+#define	TIOCGETP	_IOR('t', 8,struct sgttyb)/* get parameters -- gtty */
+#define	TIOCSETP	_IOW('t', 9,struct sgttyb)/* set parameters -- stty */
+#define	TIOCSETN	_IOW('t',10,struct sgttyb)/* as above, but no flushtty*/
+#define	TIOCSETC	_IOW('t',17,struct tchars)/* set special characters */
+#define	TIOCGETC	_IOR('t',18,struct tchars)/* get special characters */
+#if 0
+/* BUG: a bunch of these conflict with #defines in asm/termbits.h */
+#define		TANDEM		0x00000001	/* send stopc on out q full */
+#define		CBREAK		0x00000002	/* half-cooked mode */
+#define		LCASE		0x00000004	/* simulate lower case */
+#define		ECHO		0x00000008	/* enable echoing */
+#define		CRMOD		0x00000010	/* map \r to \r\n on output */
+#define		RAW		0x00000020	/* no i/o processing */
+#define		ODDP		0x00000040	/* get/send odd parity */
+#define		EVENP		0x00000080	/* get/send even parity */
+#define		ANYP		0x000000c0	/* get any parity/send none */
+#define		NLDELAY		0x00000300	/* \n delay */
+#define			NL0	0x00000000
+#define			NL1	0x00000100	/* tty 37 */
+#define			NL2	0x00000200	/* vt05 */
+#define			NL3	0x00000300
+#define		TBDELAY		0x00000c00	/* horizontal tab delay */
+#define			TAB0	0x00000000
+#define			TAB1	0x00000400	/* tty 37 */
+#define			TAB2	0x00000800
+#define		XTABS		0x00000c00	/* expand tabs on output */
+#define		CRDELAY		0x00003000	/* \r delay */
+#define			CR0	0x00000000
+#define			CR1	0x00001000	/* tn 300 */
+#define			CR2	0x00002000	/* tty 37 */
+#define			CR3	0x00003000	/* concept 100 */
+#define		VTDELAY		0x00004000	/* vertical tab delay */
+#define			FF0	0x00000000
+#define			FF1	0x00004000	/* tty 37 */
+#define		BSDELAY		0x00008000	/* \b delay */
+#define			BS0	0x00000000
+#define			BS1	0x00008000
+#define		ALLDELAY	(NLDELAY|TBDELAY|CRDELAY|VTDELAY|BSDELAY)
+#define		CRTBS		0x00010000	/* do backspacing for crt */
+#define		PRTERA		0x00020000	/* \ ... / erase */
+#define		CRTERA		0x00040000	/* " \b " to wipe out char */
+#define		TILDE		0x00080000	/* hazeltine tilde kludge */
+#define		MDMBUF		0x00100000	/* DTR/DCD hardware flow control */
+#define		LITOUT		0x00200000	/* literal output */
+#define		TOSTOP		0x00400000	/* stop background jobs on output */
+#define		FLUSHO		0x00800000	/* output being flushed (state) */
+#define		NOHANG		0x01000000	/* (no-op) was no SIGHUP on carrier drop */
+#define		L001000		0x02000000
+#define		CRTKIL		0x04000000	/* kill line with " \b " */
+#define		PASS8		0x08000000
+#define		CTLECH		0x10000000	/* echo control chars as ^X */
+#define		PENDIN		0x20000000	/* re-echo input buffer at next read */
+#define		DECCTQ		0x40000000	/* only ^Q starts after ^S */
+#define		NOFLSH		0x80000000	/* don't flush output on signal */
+#endif
+#define	TIOCLBIS	_IOW('t', 127, int)	/* bis local mode bits */
+#define	TIOCLBIC	_IOW('t', 126, int)	/* bic local mode bits */
+#define	TIOCLSET	_IOW('t', 125, int)	/* set entire local mode word */
+#define	TIOCLGET	_IOR('t', 124, int)	/* get local modes */
+#define		LCRTBS		(CRTBS>>16)
+#define		LPRTERA		(PRTERA>>16)
+#define		LCRTERA		(CRTERA>>16)
+#define		LTILDE		(TILDE>>16)
+#define		LMDMBUF		(MDMBUF>>16)
+#define		LLITOUT		(LITOUT>>16)
+#define		LTOSTOP		(TOSTOP>>16)
+#define		LFLUSHO		(FLUSHO>>16)
+#define		LNOHANG		(NOHANG>>16)
+#define		LCRTKIL		(CRTKIL>>16)
+#define		LPASS8		(PASS8>>16)
+#define		LCTLECH		(CTLECH>>16)
+#define		LPENDIN		(PENDIN>>16)
+#define		LDECCTQ		(DECCTQ>>16)
+#define		LNOFLSH		(NOFLSH>>16)
+#define	TIOCSLTC	_IOW('t',117,struct ltchars)/* set local special chars*/
+#define	TIOCGLTC	_IOR('t',116,struct ltchars)/* get local special chars*/
+#define OTIOCCONS	_IO('t', 98)	/* for hp300 -- sans int arg */
+#define	OTTYDISC	0
+#define	NETLDISC	1
+#define	NTTYDISC	2
+
+#endif /* !_SYS_IOCTL_COMPAT_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/ipc.h b/ndk/build/platforms/android-1.5/common/include/sys/ipc.h
new file mode 100644
index 0000000..c0ae0ba
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/ipc.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_IPC_H
+#define _SYS_IPC_H
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <linux/ipc.h>
+
+__BEGIN_DECLS
+
+extern key_t  ftok(const char*  path, int  id);
+
+__END_DECLS
+
+#endif /* _SYS_IPC_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/klog.h b/ndk/build/platforms/android-1.5/common/include/sys/klog.h
new file mode 100644
index 0000000..21bb7d9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/klog.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_KLOG_H_
+#define _SYS_KLOG_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+#define KLOG_CLOSE      0
+#define KLOG_OPEN       1
+#define KLOG_READ       2
+#define KLOG_READ_ALL   3
+#define KLOG_READ_CLEAR 4
+#define KLOG_CLEAR      5
+#define KLOG_DISABLE    6
+#define KLOG_ENABLE     7
+#define KLOG_SETLEVEL   8
+#define KLOG_UNREADSIZE 9
+#define KLOG_WRITE      10
+
+extern int klogctl(int, char *, int);
+
+__END_DECLS
+
+#endif /* _SYS_KLOG_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/limits.h b/ndk/build/platforms/android-1.5/common/include/sys/limits.h
new file mode 100644
index 0000000..41d02ff
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/limits.h
@@ -0,0 +1,179 @@
+/* $OpenBSD: limits.h,v 1.6 2005/12/13 00:35:23 millert Exp $ */
+/*
+ * Copyright (c) 2002 Marc Espie.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
+ * ``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 THE OPENBSD
+ * PROJECT OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_LIMITS_H_
+#define _SYS_LIMITS_H_
+
+#include <sys/cdefs.h>
+#include <linux/limits.h>
+
+/* Common definitions for limits.h. */
+
+/*
+ * <machine/internal_types.h> is meant to describe a specific architecture,
+ * but to be a safe include, that doesn't ever define anything that is
+ * user-visible (only typedefs and #define names that stays in the __xxx
+ * namespace).
+ *
+ *   __machine_has_unsigned_chars	(default is signed chars)
+ *   __FLT_xxx/__DBL_xxx		non standard values for floating
+ *   					points limits.
+ */
+#include <machine/internal_types.h>
+
+/* Legacy */
+#include <machine/limits.h>
+
+#define	CHAR_BIT	8		/* number of bits in a char */
+
+#define	SCHAR_MAX	0x7f		/* max value for a signed char */
+#define SCHAR_MIN	(-0x7f-1)	/* min value for a signed char */
+
+#define	UCHAR_MAX	0xffU		/* max value for an unsigned char */
+#ifdef __machine_has_unsigned_chars
+# define CHAR_MIN	0		/* min value for a char */
+# define CHAR_MAX	0xff		/* max value for a char */
+#else
+# define CHAR_MAX	0x7f
+# define CHAR_MIN	(-0x7f-1)
+#endif
+
+#define	USHRT_MAX	0xffffU		/* max value for an unsigned short */
+#define	SHRT_MAX	0x7fff		/* max value for a short */
+#define SHRT_MIN        (-0x7fff-1)     /* min value for a short */
+
+#define	UINT_MAX	0xffffffffU	/* max value for an unsigned int */
+#define	INT_MAX		0x7fffffff	/* max value for an int */
+#define	INT_MIN		(-0x7fffffff-1)	/* min value for an int */
+
+#ifdef __LP64__
+# define ULONG_MAX	0xffffffffffffffffUL
+					/* max value for unsigned long */
+# define LONG_MAX	0x7fffffffffffffffL
+					/* max value for a signed long */
+# define LONG_MIN	(-0x7fffffffffffffffL-1)
+					/* min value for a signed long */
+#else
+# define ULONG_MAX	0xffffffffUL	/* max value for an unsigned long */
+# define LONG_MAX	0x7fffffffL	/* max value for a long */
+# define LONG_MIN	(-0x7fffffffL-1)/* min value for a long */
+#endif
+
+#if __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999
+# define ULLONG_MAX	0xffffffffffffffffULL
+					/* max value for unsigned long long */
+# define LLONG_MAX	0x7fffffffffffffffLL
+					/* max value for a signed long long */
+# define LLONG_MIN	(-0x7fffffffffffffffLL-1)
+					/* min value for a signed long long */
+#endif
+
+#if __BSD_VISIBLE
+# define UID_MAX	UINT_MAX	/* max value for a uid_t */
+# define GID_MAX	UINT_MAX	/* max value for a gid_t */
+#endif
+
+
+#ifdef __LP64__
+# define LONG_BIT	64
+#else
+# define LONG_BIT	32
+#endif
+
+/* float.h defines these as well */
+# if !defined(DBL_DIG)
+#  if defined(__DBL_DIG)
+#   define DBL_DIG	__DBL_DIG
+#   define DBL_MAX	__DBL_MAX
+#   define DBL_MIN	__DBL_MIN
+
+#   define FLT_DIG	__FLT_DIG
+#   define FLT_MAX	__FLT_MAX
+#   define FLT_MIN	__FLT_MIN
+#  else
+#   define DBL_DIG	15
+#   define DBL_MAX	1.7976931348623157E+308
+#   define DBL_MIN	2.2250738585072014E-308
+
+#   define FLT_DIG	6
+#   define FLT_MAX	3.40282347E+38F
+#   define FLT_MIN	1.17549435E-38F
+#  endif
+# endif
+
+/* Bionic: the following has been optimized out from our processed kernel headers */
+
+#define  CHILD_MAX   999
+#define  OPEN_MAX    256
+
+/* Bionic-specific definitions */
+
+#define  _POSIX_VERSION             200112L   /* Posix C language bindings version */
+#define  _POSIX2_VERSION            -1        /* we don't support Posix command-line tools */
+#define  _POSIX2_C_VERSION          _POSIX_VERSION
+#define  _XOPEN_VERSION             500       /* by Posix definition */
+#define  _XOPEN_XCU_VERSION         -1        /* we don't support command-line utilities */
+
+/* tell what we implement legacy stuff when appropriate */
+#if _POSIX_VERSION > 0
+#define  _XOPEN_XPG2                1
+#define  _XOPEN_XPG3                1
+#define  _XOPEN_XPG4                1
+#define  _XOPEN_UNIX                1
+#endif
+
+#define  _XOPEN_ENH_I18N          -1  /* we don't support internationalization in the C library */
+#define  _XOPEN_CRYPT             -1  /* don't support X/Open Encryption */
+#define  _XOPEN_LEGACY            -1  /* don't claim we support these, we have some of them but not all */
+#define  _XOPEN_REALTIME          -1 /* we don't support all these functions */
+#define  _XOPEN_REALTIME_THREADS  -1  /* same here */
+
+#define  _POSIX_REALTIME_SIGNALS    -1  /* for now, this is not supported */
+#define  _POSIX_PRIORITY_SCHEDULING  1  /* priority scheduling is a Linux feature */
+#define  _POSIX_TIMERS               1  /* Posix timers are supported */
+#undef   _POSIX_ASYNCHRONOUS_IO         /* aio_ functions are not supported */
+#define  _POSIX_SYNCHRONIZED_IO      1  /* synchronized i/o supported */
+#define  _POSIX_FSYNC                1  /* fdatasync() supported */
+#define  _POSIX_MAPPED_FILES         1  /* mmap-ed files supported */
+
+/* XXX: TODO: complete and check list here */
+
+
+#define  _POSIX_THREADS             1    /* we support threads */
+#define  _POSIX_THREAD_STACKADDR    1    /* we support thread stack address */
+#define  _POSIX_THREAD_STACKSIZE    1    /* we support thread stack size */
+#define  _POSIX_THREAD_PRIO_INHERIT 200112L   /* linux feature */
+#define  _POSIX_THREAD_PRIO_PROTECT 200112L   /* linux feature */
+
+#undef   _POSIX_PROCESS_SHARED           /* we don't support process-shared synchronization */
+#undef   _POSIX_THREAD_SAFE_FUNCTIONS    /* most functions are, but not everything yet */
+#define  _POSIX_CHOWN_RESTRICTED    1    /* yes, chown requires appropriate priviledges */
+#define  _POSIX_NO_TRUNC            1    /* very long pathnames generate an error */
+#define  _POSIX_SAVED_IDS           1    /* saved user ids is a Linux feature */
+#define  _POSIX_JOB_CONTROL         1    /* job control is a Linux feature */
+
+
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/linux-syscalls.h b/ndk/build/platforms/android-1.5/common/include/sys/linux-syscalls.h
new file mode 100644
index 0000000..7772f1e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/linux-syscalls.h
@@ -0,0 +1,223 @@
+/* auto-generated by gensyscalls.py, do not touch */
+#ifndef _BIONIC_LINUX_SYSCALLS_H_
+
+#if !defined __ASM_ARM_UNISTD_H && !defined __ASM_I386_UNISTD_H
+#if defined __arm__ && !defined __ARM_EABI__ && !defined __thumb__
+  #  define __NR_SYSCALL_BASE  0x900000
+  #else
+  #  define  __NR_SYSCALL_BASE  0
+  #endif
+
+#define __NR_exit                         (__NR_SYSCALL_BASE + 1)
+#define __NR_fork                         (__NR_SYSCALL_BASE + 2)
+#define __NR_clone                        (__NR_SYSCALL_BASE + 120)
+#define __NR_execve                       (__NR_SYSCALL_BASE + 11)
+#define __NR_setuid32                     (__NR_SYSCALL_BASE + 213)
+#define __NR_getuid32                     (__NR_SYSCALL_BASE + 199)
+#define __NR_getgid32                     (__NR_SYSCALL_BASE + 200)
+#define __NR_geteuid32                    (__NR_SYSCALL_BASE + 201)
+#define __NR_getegid32                    (__NR_SYSCALL_BASE + 202)
+#define __NR_getresuid32                  (__NR_SYSCALL_BASE + 209)
+#define __NR_getresgid32                  (__NR_SYSCALL_BASE + 211)
+#define __NR_gettid                       (__NR_SYSCALL_BASE + 224)
+#define __NR_getgroups32                  (__NR_SYSCALL_BASE + 205)
+#define __NR_getpgid                      (__NR_SYSCALL_BASE + 132)
+#define __NR_getppid                      (__NR_SYSCALL_BASE + 64)
+#define __NR_setsid                       (__NR_SYSCALL_BASE + 66)
+#define __NR_setgid32                     (__NR_SYSCALL_BASE + 214)
+#define __NR_setreuid32                   (__NR_SYSCALL_BASE + 203)
+#define __NR_setresuid32                  (__NR_SYSCALL_BASE + 208)
+#define __NR_setresgid32                  (__NR_SYSCALL_BASE + 210)
+#define __NR_brk                          (__NR_SYSCALL_BASE + 45)
+#define __NR_ptrace                       (__NR_SYSCALL_BASE + 26)
+#define __NR_getpriority                  (__NR_SYSCALL_BASE + 96)
+#define __NR_setpriority                  (__NR_SYSCALL_BASE + 97)
+#define __NR_setrlimit                    (__NR_SYSCALL_BASE + 75)
+#define __NR_ugetrlimit                   (__NR_SYSCALL_BASE + 191)
+#define __NR_getrusage                    (__NR_SYSCALL_BASE + 77)
+#define __NR_setgroups32                  (__NR_SYSCALL_BASE + 206)
+#define __NR_setpgid                      (__NR_SYSCALL_BASE + 57)
+#define __NR_setregid32                   (__NR_SYSCALL_BASE + 204)
+#define __NR_chroot                       (__NR_SYSCALL_BASE + 61)
+#define __NR_prctl                        (__NR_SYSCALL_BASE + 172)
+#define __NR_capget                       (__NR_SYSCALL_BASE + 184)
+#define __NR_capset                       (__NR_SYSCALL_BASE + 185)
+#define __NR_acct                         (__NR_SYSCALL_BASE + 51)
+#define __NR_read                         (__NR_SYSCALL_BASE + 3)
+#define __NR_write                        (__NR_SYSCALL_BASE + 4)
+#define __NR_pread64                      (__NR_SYSCALL_BASE + 180)
+#define __NR_pwrite64                     (__NR_SYSCALL_BASE + 181)
+#define __NR_open                         (__NR_SYSCALL_BASE + 5)
+#define __NR_close                        (__NR_SYSCALL_BASE + 6)
+#define __NR_lseek                        (__NR_SYSCALL_BASE + 19)
+#define __NR__llseek                      (__NR_SYSCALL_BASE + 140)
+#define __NR_getpid                       (__NR_SYSCALL_BASE + 20)
+#define __NR_mmap2                        (__NR_SYSCALL_BASE + 192)
+#define __NR_munmap                       (__NR_SYSCALL_BASE + 91)
+#define __NR_mremap                       (__NR_SYSCALL_BASE + 163)
+#define __NR_msync                        (__NR_SYSCALL_BASE + 144)
+#define __NR_mprotect                     (__NR_SYSCALL_BASE + 125)
+#define __NR_mlock                        (__NR_SYSCALL_BASE + 150)
+#define __NR_munlock                      (__NR_SYSCALL_BASE + 151)
+#define __NR_ioctl                        (__NR_SYSCALL_BASE + 54)
+#define __NR_readv                        (__NR_SYSCALL_BASE + 145)
+#define __NR_writev                       (__NR_SYSCALL_BASE + 146)
+#define __NR_fcntl                        (__NR_SYSCALL_BASE + 55)
+#define __NR_flock                        (__NR_SYSCALL_BASE + 143)
+#define __NR_fchmod                       (__NR_SYSCALL_BASE + 94)
+#define __NR_dup                          (__NR_SYSCALL_BASE + 41)
+#define __NR_pipe                         (__NR_SYSCALL_BASE + 42)
+#define __NR_dup2                         (__NR_SYSCALL_BASE + 63)
+#define __NR__newselect                   (__NR_SYSCALL_BASE + 142)
+#define __NR_ftruncate                    (__NR_SYSCALL_BASE + 93)
+#define __NR_fsync                        (__NR_SYSCALL_BASE + 118)
+#define __NR_fchown32                     (__NR_SYSCALL_BASE + 207)
+#define __NR_sync                         (__NR_SYSCALL_BASE + 36)
+#define __NR_fcntl64                      (__NR_SYSCALL_BASE + 221)
+#define __NR_sendfile                     (__NR_SYSCALL_BASE + 187)
+#define __NR_link                         (__NR_SYSCALL_BASE + 9)
+#define __NR_unlink                       (__NR_SYSCALL_BASE + 10)
+#define __NR_chdir                        (__NR_SYSCALL_BASE + 12)
+#define __NR_mknod                        (__NR_SYSCALL_BASE + 14)
+#define __NR_chmod                        (__NR_SYSCALL_BASE + 15)
+#define __NR_chown32                      (__NR_SYSCALL_BASE + 212)
+#define __NR_lchown32                     (__NR_SYSCALL_BASE + 198)
+#define __NR_mount                        (__NR_SYSCALL_BASE + 21)
+#define __NR_umount2                      (__NR_SYSCALL_BASE + 52)
+#define __NR_fstat64                      (__NR_SYSCALL_BASE + 197)
+#define __NR_stat64                       (__NR_SYSCALL_BASE + 195)
+#define __NR_lstat64                      (__NR_SYSCALL_BASE + 196)
+#define __NR_mkdir                        (__NR_SYSCALL_BASE + 39)
+#define __NR_readlink                     (__NR_SYSCALL_BASE + 85)
+#define __NR_rmdir                        (__NR_SYSCALL_BASE + 40)
+#define __NR_rename                       (__NR_SYSCALL_BASE + 38)
+#define __NR_getcwd                       (__NR_SYSCALL_BASE + 183)
+#define __NR_access                       (__NR_SYSCALL_BASE + 33)
+#define __NR_symlink                      (__NR_SYSCALL_BASE + 83)
+#define __NR_fchdir                       (__NR_SYSCALL_BASE + 133)
+#define __NR_truncate                     (__NR_SYSCALL_BASE + 92)
+#define __NR_pause                        (__NR_SYSCALL_BASE + 29)
+#define __NR_gettimeofday                 (__NR_SYSCALL_BASE + 78)
+#define __NR_settimeofday                 (__NR_SYSCALL_BASE + 79)
+#define __NR_times                        (__NR_SYSCALL_BASE + 43)
+#define __NR_nanosleep                    (__NR_SYSCALL_BASE + 162)
+#define __NR_getitimer                    (__NR_SYSCALL_BASE + 105)
+#define __NR_setitimer                    (__NR_SYSCALL_BASE + 104)
+#define __NR_sigaction                    (__NR_SYSCALL_BASE + 67)
+#define __NR_sigprocmask                  (__NR_SYSCALL_BASE + 126)
+#define __NR_sigsuspend                   (__NR_SYSCALL_BASE + 72)
+#define __NR_rt_sigaction                 (__NR_SYSCALL_BASE + 174)
+#define __NR_rt_sigprocmask               (__NR_SYSCALL_BASE + 175)
+#define __NR_rt_sigtimedwait              (__NR_SYSCALL_BASE + 177)
+#define __NR_sigpending                   (__NR_SYSCALL_BASE + 73)
+#define __NR_sched_setscheduler           (__NR_SYSCALL_BASE + 156)
+#define __NR_sched_getscheduler           (__NR_SYSCALL_BASE + 157)
+#define __NR_sched_yield                  (__NR_SYSCALL_BASE + 158)
+#define __NR_sched_setparam               (__NR_SYSCALL_BASE + 154)
+#define __NR_sched_getparam               (__NR_SYSCALL_BASE + 155)
+#define __NR_sched_get_priority_max       (__NR_SYSCALL_BASE + 159)
+#define __NR_sched_get_priority_min       (__NR_SYSCALL_BASE + 160)
+#define __NR_sched_rr_get_interval        (__NR_SYSCALL_BASE + 161)
+#define __NR_uname                        (__NR_SYSCALL_BASE + 122)
+#define __NR_wait4                        (__NR_SYSCALL_BASE + 114)
+#define __NR_umask                        (__NR_SYSCALL_BASE + 60)
+#define __NR_reboot                       (__NR_SYSCALL_BASE + 88)
+#define __NR_syslog                       (__NR_SYSCALL_BASE + 103)
+#define __NR_init_module                  (__NR_SYSCALL_BASE + 128)
+#define __NR_delete_module                (__NR_SYSCALL_BASE + 129)
+#define __NR_syslog                       (__NR_SYSCALL_BASE + 103)
+#define __NR_futex                        (__NR_SYSCALL_BASE + 240)
+#define __NR_poll                         (__NR_SYSCALL_BASE + 168)
+
+#ifdef __arm__
+#define __NR_exit_group                   (__NR_SYSCALL_BASE + 248)
+#define __NR_waitid                       (__NR_SYSCALL_BASE + 280)
+#define __NR_vfork                        (__NR_SYSCALL_BASE + 190)
+#define __NR_openat                       (__NR_SYSCALL_BASE + 322)
+#define __NR_madvise                      (__NR_SYSCALL_BASE + 220)
+#define __NR_mincore                      (__NR_SYSCALL_BASE + 219)
+#define __NR_getdents64                   (__NR_SYSCALL_BASE + 217)
+#define __NR_fstatfs64                    (__NR_SYSCALL_BASE + 267)
+#define __NR_fstatat64                    (__NR_SYSCALL_BASE + 327)
+#define __NR_mkdirat                      (__NR_SYSCALL_BASE + 323)
+#define __NR_fchownat                     (__NR_SYSCALL_BASE + 325)
+#define __NR_fchmodat                     (__NR_SYSCALL_BASE + 333)
+#define __NR_renameat                     (__NR_SYSCALL_BASE + 329)
+#define __NR_unlinkat                     (__NR_SYSCALL_BASE + 328)
+#define __NR_statfs64                     (__NR_SYSCALL_BASE + 266)
+#define __NR_clock_gettime                (__NR_SYSCALL_BASE + 263)
+#define __NR_clock_settime                (__NR_SYSCALL_BASE + 262)
+#define __NR_clock_getres                 (__NR_SYSCALL_BASE + 264)
+#define __NR_clock_nanosleep              (__NR_SYSCALL_BASE + 265)
+#define __NR_timer_create                 (__NR_SYSCALL_BASE + 257)
+#define __NR_timer_settime                (__NR_SYSCALL_BASE + 258)
+#define __NR_timer_gettime                (__NR_SYSCALL_BASE + 259)
+#define __NR_timer_getoverrun             (__NR_SYSCALL_BASE + 260)
+#define __NR_timer_delete                 (__NR_SYSCALL_BASE + 261)
+#define __NR_utimes                       (__NR_SYSCALL_BASE + 269)
+#define __NR_socket                       (__NR_SYSCALL_BASE + 281)
+#define __NR_socketpair                   (__NR_SYSCALL_BASE + 288)
+#define __NR_bind                         (__NR_SYSCALL_BASE + 282)
+#define __NR_connect                      (__NR_SYSCALL_BASE + 283)
+#define __NR_listen                       (__NR_SYSCALL_BASE + 284)
+#define __NR_accept                       (__NR_SYSCALL_BASE + 285)
+#define __NR_getsockname                  (__NR_SYSCALL_BASE + 286)
+#define __NR_getpeername                  (__NR_SYSCALL_BASE + 287)
+#define __NR_sendto                       (__NR_SYSCALL_BASE + 290)
+#define __NR_recvfrom                     (__NR_SYSCALL_BASE + 292)
+#define __NR_shutdown                     (__NR_SYSCALL_BASE + 293)
+#define __NR_setsockopt                   (__NR_SYSCALL_BASE + 294)
+#define __NR_getsockopt                   (__NR_SYSCALL_BASE + 295)
+#define __NR_sendmsg                      (__NR_SYSCALL_BASE + 296)
+#define __NR_recvmsg                      (__NR_SYSCALL_BASE + 297)
+#define __NR_epoll_create                 (__NR_SYSCALL_BASE + 250)
+#define __NR_epoll_ctl                    (__NR_SYSCALL_BASE + 251)
+#define __NR_epoll_wait                   (__NR_SYSCALL_BASE + 252)
+#define __NR_inotify_init                 (__NR_SYSCALL_BASE + 316)
+#define __NR_inotify_add_watch            (__NR_SYSCALL_BASE + 317)
+#define __NR_inotify_rm_watch             (__NR_SYSCALL_BASE + 318)
+#define __NR_ARM_set_tls                  (__NR_SYSCALL_BASE + 983045)
+#define __NR_ARM_cacheflush               (__NR_SYSCALL_BASE + 983042)
+#endif
+
+#ifdef __i386__
+#define __NR_exit_group                   (__NR_SYSCALL_BASE + 252)
+#define __NR_waitpid                      (__NR_SYSCALL_BASE + 7)
+#define __NR_waitid                       (__NR_SYSCALL_BASE + 284)
+#define __NR_kill                         (__NR_SYSCALL_BASE + 37)
+#define __NR_tkill                        (__NR_SYSCALL_BASE + 238)
+#define __NR_set_thread_area              (__NR_SYSCALL_BASE + 243)
+#define __NR_openat                       (__NR_SYSCALL_BASE + 295)
+#define __NR_madvise                      (__NR_SYSCALL_BASE + 219)
+#define __NR_mincore                      (__NR_SYSCALL_BASE + 218)
+#define __NR_getdents64                   (__NR_SYSCALL_BASE + 220)
+#define __NR_fstatfs64                    (__NR_SYSCALL_BASE + 269)
+#define __NR_fstatat64                    (__NR_SYSCALL_BASE + 300)
+#define __NR_mkdirat                      (__NR_SYSCALL_BASE + 296)
+#define __NR_fchownat                     (__NR_SYSCALL_BASE + 298)
+#define __NR_fchmodat                     (__NR_SYSCALL_BASE + 306)
+#define __NR_renameat                     (__NR_SYSCALL_BASE + 302)
+#define __NR_unlinkat                     (__NR_SYSCALL_BASE + 301)
+#define __NR_statfs64                     (__NR_SYSCALL_BASE + 268)
+#define __NR_clock_gettime                (__NR_SYSCALL_BASE + 265)
+#define __NR_clock_settime                (__NR_SYSCALL_BASE + 264)
+#define __NR_clock_getres                 (__NR_SYSCALL_BASE + 266)
+#define __NR_clock_nanosleep              (__NR_SYSCALL_BASE + 267)
+#define __NR_timer_create                 (__NR_SYSCALL_BASE + 259)
+#define __NR_timer_settime                (__NR_SYSCALL_BASE + 260)
+#define __NR_timer_gettime                (__NR_SYSCALL_BASE + 261)
+#define __NR_timer_getoverrun             (__NR_SYSCALL_BASE + 262)
+#define __NR_timer_delete                 (__NR_SYSCALL_BASE + 263)
+#define __NR_utimes                       (__NR_SYSCALL_BASE + 271)
+#define __NR_socketcall                   (__NR_SYSCALL_BASE + 102)
+#define __NR_epoll_create                 (__NR_SYSCALL_BASE + 254)
+#define __NR_epoll_ctl                    (__NR_SYSCALL_BASE + 255)
+#define __NR_epoll_wait                   (__NR_SYSCALL_BASE + 256)
+#define __NR_inotify_init                 (__NR_SYSCALL_BASE + 291)
+#define __NR_inotify_add_watch            (__NR_SYSCALL_BASE + 292)
+#define __NR_inotify_rm_watch             (__NR_SYSCALL_BASE + 293)
+#endif
+
+#endif
+
+#endif /* _BIONIC_LINUX_SYSCALLS_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/linux-unistd.h b/ndk/build/platforms/android-1.5/common/include/sys/linux-unistd.h
new file mode 100644
index 0000000..789271e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/linux-unistd.h
@@ -0,0 +1,204 @@
+/* auto-generated by gensyscalls.py, do not touch */
+#ifndef _BIONIC_LINUX_UNISTD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void             _exit (int);
+void             _exit_thread (int);
+pid_t            __fork (void);
+pid_t            _waitpid (pid_t, int*, int, struct rusage*);
+int              waitid (int, pid_t, struct siginfo_t*, int,void*);
+pid_t            __clone (int (*fn)(void*), void *child_stack, int flags, void *arg);
+int              execve (const char*, char* const*, char* const*);
+int              setuid (uid_t);
+uid_t            getuid (void);
+gid_t            getgid (void);
+uid_t            geteuid (void);
+gid_t            getegid (void);
+uid_t            getresuid (void);
+gid_t            getresgid (void);
+pid_t            gettid (void);
+int              getgroups (int, gid_t *);
+pid_t            getpgid (pid_t);
+pid_t            getppid (void);
+pid_t            setsid (void);
+int              setgid (gid_t);
+int              seteuid (uid_t);
+int              setreuid (uid_t, uid_t);
+int              setresuid (uid_t, uid_t, uid_t);
+int              setresgid (gid_t, gid_t, gid_t);
+void*            __brk (void*);
+int              kill (pid_t, int);
+int              tkill (pid_t tid, int sig);
+int              __ptrace (int request, int pid, void* addr, void* data);
+int              __set_thread_area (void*  user_desc);
+int              __getpriority (int, int);
+int              setpriority (int, int, int);
+int              setrlimit (int resource, const struct rlimit *rlp);
+int              getrlimit (int resource, struct rlimit *rlp);
+int              getrusage (int who, struct rusage*  r_usage);
+int              setgroups (int, const gid_t *);
+pid_t            getpgrp (void);
+int              setpgid (pid_t, pid_t);
+pid_t            vfork (void);
+int              setregid (gid_t, gid_t);
+int              chroot (const char *);
+int              prctl (int option, unsigned int arg2, unsigned int arg3, unsigned int arg4, unsigned int arg5);
+int              capget (cap_user_header_t header, cap_user_data_t data);
+int              capset (cap_user_header_t header, const cap_user_data_t data);
+int              acct (const char*  filepath);
+ssize_t          read (int, void*, size_t);
+ssize_t          write (int, const void*, size_t);
+ssize_t          __pread64 (int, void *, size_t, off_t, off_t);
+ssize_t          __pwrite64 (int, void *, size_t, off_t, off_t);
+int              __open (const char*, int, mode_t);
+int              __openat (int, const char*, int, mode_t);
+int              close (int);
+int              creat (const char*, mode_t);
+off_t            lseek (int, off_t, int);
+int              __llseek (int, unsigned long, unsigned long, loff_t*, int);
+pid_t            getpid (void);
+void *           mmap (void *, size_t, int, int, int, long);
+void *           __mmap2 (void*, size_t, int, int, int, long);
+int              munmap (void *, size_t);
+void *           mremap (void *, size_t, size_t, unsigned long);
+int              msync (const void *, size_t, int);
+int              mprotect (const void *, size_t, int);
+int              madvise (const void *, size_t, int);
+int              mlock (const void *addr, size_t len);
+int              munlock (const void *addr, size_t len);
+int              mincore (void*  start, size_t  length, unsigned char*  vec);
+int              __ioctl (int, int, void *);
+int              readv (int, const struct iovec *, int);
+int              writev (int, const struct iovec *, int);
+int              __fcntl (int, int, void*);
+int              flock (int, int);
+int              fchmod (int, mode_t);
+int              dup (int);
+int              pipe (int *);
+int              dup2 (int, int);
+int              select (int, struct fd_set *, struct fd_set *, struct fd_set *, struct timeval *);
+int              ftruncate (int, off_t);
+int              getdents (unsigned int, struct dirent *, unsigned int);
+int              fsync (int);
+int              fchown (int, uid_t, gid_t);
+void             sync (void);
+int              __fcntl64 (int, int, void *);
+int              fstatfs (int, size_t, struct statfs *);
+ssize_t          sendfile (int out_fd, int in_fd, off_t *offset, size_t count);
+int              fstatat (int dirfd, const char *path, struct stat *buf, int flags);
+int              mkdirat (int dirfd, const char *pathname, mode_t mode);
+int              fchownat (int dirfd, const char *path, uid_t owner, gid_t group, int flags);
+int              fchmodat (int dirfd, const char *path, mode_t mode, int flags);
+int              renameat (int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
+int              link (const char*, const char*);
+int              unlink (const char*);
+int              unlinkat (int, const char *, int);
+int              chdir (const char*);
+int              mknod (const char*, mode_t, dev_t);
+int              chmod (const char*,mode_t);
+int              chown (const char *, uid_t, gid_t);
+int              lchown (const char*, uid_t, gid_t);
+int              mount (const char*, const char*, const char*, unsigned long, const void*);
+int              umount (const char*);
+int              umount2 (const char*, int);
+int              fstat (int, struct stat*);
+int              stat (const char *, struct stat *);
+int              lstat (const char *, struct stat *);
+int              mkdir (const char *, mode_t);
+int              readlink (const char *, char *, size_t);
+int              rmdir (const char *);
+int              rename (const char *, const char *);
+int              __getcwd (char * buf, size_t size);
+int              access (const char *, int);
+int              symlink (const char *, const char *);
+int              fchdir (int);
+int              truncate (const char*, off_t);
+int              __statfs64 (const char *, size_t, struct statfs *);
+int              pause (void);
+int              gettimeofday (struct timeval*, struct timezone*);
+int              settimeofday (const struct timeval*, const struct timezone*);
+clock_t          times (struct tms *);
+int              nanosleep (const struct timespec *, struct timespec *);
+int              clock_gettime (clockid_t clk_id, struct timespec *tp);
+int              clock_settime (clockid_t clk_id, const struct timespec *tp);
+int              clock_getres (clockid_t clk_id, struct timespec *res);
+int              clock_nanosleep (const struct timespec *req, struct timespec *rem);
+int              getitimer (int, const struct itimerval *);
+int              setitimer (int, const struct itimerval *, struct itimerval *);
+int              __timer_create (clockid_t clockid, struct sigevent *evp, timer_t *timerid);
+int              __timer_settime (timer_t, int, const struct itimerspec*, struct itimerspec*);
+int              __timer_gettime (timer_t, struct itimerspec*);
+int              __timer_getoverrun (timer_t);
+int              __timer_delete (timer_t);
+int              utimes (const char*, const struct timeval tvp[2]);
+int              sigaction (int, const struct sigaction *, struct sigaction *);
+int              sigprocmask (int, const sigset_t *, sigset_t *);
+int              __sigsuspend (int unused1, int unused2, unsigned mask);
+int              __rt_sigaction (int sig, const struct sigaction *act, struct sigaction *oact, size_t sigsetsize);
+int              __rt_sigprocmask (int  how, const sigset_t *set, sigset_t *oset, size_t sigsetsize);
+int              __rt_sigtimedwait (const sigset_t *set, struct siginfo_t  *info, struct timespec_t  *timeout, size_t  sigset_size);
+int              sigpending (sigset_t *);
+int              socket (int, int, int);
+int              socketpair (int, int, int, int*);
+int              bind (int, struct sockaddr *, int);
+int              connect (int, struct sockaddr *, socklen_t);
+int              listen (int, int);
+int              accept (int, struct sockaddr *, socklen_t *);
+int              getsockname (int, struct sockaddr *, socklen_t *);
+int              getpeername (int, struct sockaddr *, socklen_t *);
+int              sendto (int, const void *, size_t, int, const struct sockaddr *, socklen_t);
+int              recvfrom (int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *);
+int              shutdown (int, int);
+int              setsockopt (int, int, int, const void *, socklen_t);
+int              getsockopt (int, int, int, void *, socklen_t *);
+int              sendmsg (int, const struct msghdr *, unsigned int);
+int              recvmsg (int, struct msghdr *, unsigned int);
+int              socket (int, int, int);
+int              bind (int, struct sockaddr *, int);
+int              connect (int, struct sockaddr *, socklen_t);
+int              listen (int, int);
+int              accept (int, struct sockaddr *, socklen_t *);
+int              getsockname (int, struct sockaddr *, socklen_t *);
+int              getpeername (int, struct sockaddr *, socklen_t *);
+int              socketpair (int, int, int, int*);
+int              sendto (int, const void *, size_t, int, const struct sockaddr *, socklen_t);
+int              recvfrom (int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *);
+int              shutdown (int, int);
+int              setsockopt (int, int, int, const void *, socklen_t);
+int              getsockopt (int, int, int, void *, socklen_t *);
+int              sendmsg (int, const struct msghdr *, unsigned int);
+int              recvmsg (int, struct msghdr *, unsigned int);
+int              sched_setscheduler (pid_t pid, int policy, const struct sched_param *param);
+int              sched_getscheduler (pid_t pid);
+int              sched_yield (void);
+int              sched_setparam (pid_t pid, const struct sched_param *param);
+int              sched_getparam (pid_t pid, struct sched_param *param);
+int              sched_get_priority_max (int policy);
+int              sched_get_priority_min (int policy);
+int              sched_rr_get_interval (pid_t pid, struct timespec *interval);
+int              uname (struct utsname *);
+pid_t            __wait4 (pid_t pid, int *status, int options, struct rusage *rusage);
+mode_t           umask (mode_t);
+int              __reboot (int, int, int, void *);
+int              __syslog (int, char *, int);
+int              init_module (void *, unsigned long, const char *);
+int              delete_module (const char*, unsigned int);
+int              klogctl (int, char *, int);
+int              futex (void *, int, int, void *, void *, int);
+int              epoll_create (int size);
+int              epoll_ctl (int epfd, int op, int fd, struct epoll_event *event);
+int              epoll_wait (int epfd, struct epoll_event *events, int max, int timeout);
+int              inotify_init (void);
+int              inotify_add_watch (int, const char *, unsigned int);
+int              inotify_rm_watch (int, unsigned int);
+int              poll (struct pollfd *, unsigned int, long);
+int              __set_tls (void*);
+int              cacheflush (long start, long end, long flags);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BIONIC_LINUX_UNISTD_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/mman.h b/ndk/build/platforms/android-1.5/common/include/sys/mman.h
new file mode 100644
index 0000000..7a32974
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/mman.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_MMAN_H_
+#define _SYS_MMAN_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <asm/mman.h>
+#include <asm/page.h>
+
+__BEGIN_DECLS
+
+#ifndef MAP_ANON
+#define MAP_ANON  MAP_ANONYMOUS
+#endif
+
+#define MAP_FAILED ((void *)-1)
+
+#define MREMAP_MAYMOVE  1
+#define MREMAP_FIXED    2
+
+extern void*  mmap(void *, size_t, int, int, int, off_t);
+extern int    munmap(void *, size_t);
+extern int    msync(const void *, size_t, int);
+extern int    mprotect(const void *, size_t, int);
+extern void*  mremap(void *, size_t, size_t, unsigned long);
+
+extern int    mlockall(int);
+extern int    munlockall(void);
+extern int    mlock(const void *, size_t);
+extern int    munlock(const void *, size_t);
+extern int    madvise(const void *, size_t, int);
+
+extern int    mlock(const void *addr, size_t len);
+extern int    munlock(const void *addr, size_t len);
+
+extern int    mincore(void*  start, size_t  length, unsigned char*  vec);
+
+__END_DECLS
+
+#endif /* _SYS_MMAN_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/mount.h b/ndk/build/platforms/android-1.5/common/include/sys/mount.h
new file mode 100644
index 0000000..62c4ee2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/mount.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_MOUNT_H
+#define _SYS_MOUNT_H
+
+#include <sys/cdefs.h>
+#include <sys/ioctl.h>
+
+__BEGIN_DECLS
+
+/*
+ * These are the fs-independent mount-flags: up to 32 flags are supported
+ */
+#define MS_RDONLY        1      /* Mount read-only */
+#define MS_NOSUID        2      /* Ignore suid and sgid bits */
+#define MS_NODEV         4      /* Disallow access to device special files */
+#define MS_NOEXEC        8      /* Disallow program execution */
+#define MS_SYNCHRONOUS  16      /* Writes are synced at once */
+#define MS_REMOUNT      32      /* Alter flags of a mounted FS */
+#define MS_MANDLOCK     64      /* Allow mandatory locks on an FS */
+#define MS_DIRSYNC      128     /* Directory modifications are synchronous */
+#define MS_NOATIME      1024    /* Do not update access times. */
+#define MS_NODIRATIME   2048    /* Do not update directory access times */
+#define MS_BIND         4096
+#define MS_MOVE         8192
+#define MS_REC          16384
+#define MS_VERBOSE      32768
+#define MS_POSIXACL     (1<<16) /* VFS does not apply the umask */
+#define MS_ONE_SECOND   (1<<17) /* fs has 1 sec a/m/ctime resolution */
+#define MS_ACTIVE       (1<<30)
+#define MS_NOUSER       (1<<31)
+
+/*
+ * Superblock flags that can be altered by MS_REMOUNT
+ */
+#define MS_RMT_MASK     (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_NOATIME|MS_NODIRATIME)
+
+/*
+ * Old magic mount flag and mask
+ */
+#define MS_MGC_VAL 0xC0ED0000
+#define MS_MGC_MSK 0xffff0000
+
+/*
+ * umount2() flags
+ */
+#define MNT_FORCE	1	/* Forcibly unmount */
+#define MNT_DETACH	2	/* Detach from tree only */
+#define MNT_EXPIRE	4	/* Mark for expiry */
+
+/*
+ * Block device ioctls
+ */
+#define BLKROSET   _IO(0x12, 93) /* Set device read-only (0 = read-write).  */
+#define BLKROGET   _IO(0x12, 94) /* Get read-only status (0 = read_write).  */
+#define BLKRRPART  _IO(0x12, 95) /* Re-read partition table.  */
+#define BLKGETSIZE _IO(0x12, 96) /* Return device size.  */
+#define BLKFLSBUF  _IO(0x12, 97) /* Flush buffer cache.  */
+#define BLKRASET   _IO(0x12, 98) /* Set read ahead for block device.  */
+#define BLKRAGET   _IO(0x12, 99) /* Get current read ahead setting.  */
+
+/*
+ * Prototypes
+ */
+extern int mount(const char *, const char *,
+		   const char *, unsigned long,
+		   const void *);
+extern int umount(const char *);
+extern int umount2(const char *, int);
+extern int pivot_root(const char *, const char *);
+
+__END_DECLS
+
+#endif /* _SYS_MOUNT_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/param.h b/ndk/build/platforms/android-1.5/common/include/sys/param.h
new file mode 100644
index 0000000..3a815cb
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/param.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_PARAM_H_
+#define _SYS_PARAM_H_
+
+#include <limits.h>
+#include <linux/param.h>
+
+#define MAXPATHLEN  PATH_MAX
+#define MAXSYMLINKS 8
+
+#define ALIGNBYTES  3
+#define ALIGN(p)    (((unsigned int)(p) + ALIGNBYTES) &~ ALIGNBYTES)
+
+#endif /* _SYS_PARAM_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/poll.h b/ndk/build/platforms/android-1.5/common/include/sys/poll.h
new file mode 100644
index 0000000..779ec77
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/poll.h
@@ -0,0 +1 @@
+#include <poll.h>
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/prctl.h b/ndk/build/platforms/android-1.5/common/include/sys/prctl.h
new file mode 100644
index 0000000..ce85bf7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/prctl.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_PRCTL_H
+#define _SYS_PRCTL_H
+
+#include <linux/prctl.h>
+
+__BEGIN_DECLS
+
+extern int prctl(int option, unsigned long arg2, unsigned long arg3 , unsigned
+               long arg4, unsigned long arg5);
+
+__END_DECLS
+
+#endif /* _SYS_PRCTL_H */
+
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/ptrace.h b/ndk/build/platforms/android-1.5/common/include/sys/ptrace.h
new file mode 100644
index 0000000..78a057a
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/ptrace.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_PTRACE_H_
+#define _SYS_PTRACE_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+// For all of the defines
+#include <linux/ptrace.h>
+
+__BEGIN_DECLS
+
+#define PTRACE_POKEUSER     PTRACE_POKEUSR
+#define PTRACE_PEEKUSER     PTRACE_PEEKUSR
+
+extern long ptrace(int request, pid_t pid, void *addr, void *data);
+
+__END_DECLS
+
+#endif /* _SYS_PTRACE_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/reboot.h b/ndk/build/platforms/android-1.5/common/include/sys/reboot.h
new file mode 100644
index 0000000..df81139
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/reboot.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_REBOOT_H_
+#define _SYS_REBOOT_H_
+
+#include <sys/cdefs.h>
+#include <linux/reboot.h>
+
+__BEGIN_DECLS
+
+/* use glibc names as well */
+
+#define RB_AUTOBOOT     LINUX_REBOOT_CMD_RESTART
+#define RB_HALT_SYSTEM  LINUX_REBOOT_CMD_HALT
+#define RB_ENABLE_CAD   LINUX_REBOOT_CMD_CAD_ON
+#define RB_DISABLE_CAD  LINUX_REBOOT_CMD_CAD_OFF
+#define RB_POWER_OFF    LINUX_REBOOT_CMD_POWER_OFF
+
+extern int reboot(int  reboot_type);
+extern int __reboot(int, int, int, void *);
+
+__END_DECLS
+
+#endif /* _SYS_REBOOT_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/resource.h b/ndk/build/platforms/android-1.5/common/include/sys/resource.h
new file mode 100644
index 0000000..a7de6f0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/resource.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_RESOURCE_H_
+#define _SYS_RESOURCE_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>     /* MUST be included before linux/resource.h */
+
+/* TRICK AHEAD: <linux/resource.h> defines a getrusage function with
+ *              a non-standard signature. this is surprising because the
+ *              syscall seems to use the standard one instead.
+ *              once again, creative macro usage saves the days
+ */
+#define  getrusage   __kernel_getrusage
+#include <linux/resource.h>
+#undef   getrusage
+
+__BEGIN_DECLS
+
+extern int getpriority(int, int);
+extern int setpriority(int, int, int);
+extern int getrlimit(int resource, struct rlimit *rlp);
+extern int setrlimit(int resource, const struct rlimit *rlp);
+extern int getrusage(int  who, struct rusage*  r_usage);
+
+__END_DECLS
+
+#endif /* _SYS_RESOURCE_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/select.h b/ndk/build/platforms/android-1.5/common/include/sys/select.h
new file mode 100644
index 0000000..52315b9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/select.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_SELECT_H_
+#define _SYS_SELECT_H_
+
+#include <sys/cdefs.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+typedef __kernel_fd_set   fd_set;
+
+extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+
+__END_DECLS
+
+#endif /* _SYS_SELECT_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/sendfile.h b/ndk/build/platforms/android-1.5/common/include/sys/sendfile.h
new file mode 100644
index 0000000..d5aba26
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/sendfile.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_SENDFILE_H_
+#define _SYS_SENDFILE_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+extern ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
+
+__END_DECLS
+
+#endif /* _SYS_SENDFILE_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/socket.h b/ndk/build/platforms/android-1.5/common/include/sys/socket.h
new file mode 100644
index 0000000..208663e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/socket.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_SOCKET_H_
+#define _SYS_SOCKET_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <linux/socket.h>
+
+__BEGIN_DECLS
+
+#define SOCK_STREAM      1
+#define SOCK_DGRAM       2
+#define SOCK_RAW         3
+#define SOCK_RDM         4
+#define SOCK_SEQPACKET   5
+#define SOCK_PACKET      10
+
+#ifdef __i386__
+# define __socketcall extern __attribute__((__cdecl__))
+#else
+# define __socketcall extern
+#endif
+
+/* BIONIC: second argument to shutdown() */
+enum {
+    SHUT_RD = 0,        /* no more receptions */
+#define SHUT_RD         SHUT_RD
+    SHUT_WR,            /* no more transmissions */
+#define SHUT_WR         SHUT_WR
+    SHUT_RDWR           /* no more receptions or transmissions */
+#define SHUT_RDWR       SHUT_RDWR
+};
+
+
+typedef int socklen_t;
+
+__socketcall int socket(int, int, int);
+__socketcall int bind(int, const struct sockaddr *, int);
+__socketcall int connect(int, const struct sockaddr *, socklen_t);
+__socketcall int listen(int, int);
+__socketcall int accept(int, struct sockaddr *, socklen_t *);
+__socketcall int getsockname(int, struct sockaddr *, socklen_t *);
+__socketcall int getpeername(int, struct sockaddr *, socklen_t *);
+__socketcall int socketpair(int, int, int, int *);
+__socketcall int shutdown(int, int);
+__socketcall int setsockopt(int, int, int, const void *, socklen_t);
+__socketcall int getsockopt(int, int, int, void *, socklen_t *);
+__socketcall int sendmsg(int, const struct msghdr *, unsigned int);
+__socketcall int recvmsg(int, struct msghdr *, unsigned int);
+
+extern  ssize_t  send(int, const void *, size_t, unsigned int);
+extern  ssize_t  recv(int, void *, size_t, unsigned int);
+
+__socketcall ssize_t sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t);
+__socketcall ssize_t recvfrom(int, void *, size_t, unsigned int, const struct sockaddr *, socklen_t *);
+
+#undef __socketcall
+
+__END_DECLS
+
+#endif /* _SYS_SOCKET_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/socketcalls.h b/ndk/build/platforms/android-1.5/common/include/sys/socketcalls.h
new file mode 100644
index 0000000..c74f463
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/socketcalls.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_SOCKETCALLS_H_
+#define _SYS_SOCKETCALLS_H_
+
+/* socketcalls by number */
+
+#define SYS_SOCKET      1               /* sys_socket(2)                */
+#define SYS_BIND        2               /* sys_bind(2)                  */
+#define SYS_CONNECT     3               /* sys_connect(2)               */
+#define SYS_LISTEN      4               /* sys_listen(2)                */
+#define SYS_ACCEPT      5               /* sys_accept(2)                */
+#define SYS_GETSOCKNAME 6               /* sys_getsockname(2)           */
+#define SYS_GETPEERNAME 7               /* sys_getpeername(2)           */
+#define SYS_SOCKETPAIR  8               /* sys_socketpair(2)            */
+#define SYS_SEND        9               /* sys_send(2)                  */
+#define SYS_RECV        10              /* sys_recv(2)                  */
+#define SYS_SENDTO      11              /* sys_sendto(2)                */
+#define SYS_RECVFROM    12              /* sys_recvfrom(2)              */
+#define SYS_SHUTDOWN    13              /* sys_shutdown(2)              */
+#define SYS_SETSOCKOPT  14              /* sys_setsockopt(2)            */
+#define SYS_GETSOCKOPT  15              /* sys_getsockopt(2)            */
+#define SYS_SENDMSG     16              /* sys_sendmsg(2)               */
+#define SYS_RECVMSG     17              /* sys_recvmsg(2)               */
+
+#endif /* _SYS_SOCKETCALLS_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/stat.h b/ndk/build/platforms/android-1.5/common/include/sys/stat.h
new file mode 100644
index 0000000..23ab5ae
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/stat.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_STAT_H_
+#define _SYS_STAT_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <linux/stat.h>
+
+#include <endian.h>
+
+__BEGIN_DECLS
+
+/* really matches stat64 in the kernel, hence the padding
+ * Note: The kernel zero's the padded region because glibc might read them
+ * in the hope that the kernel has stretched to using larger sizes.
+ */
+struct stat {
+    unsigned long long  st_dev;
+    unsigned char       __pad0[4];
+
+    unsigned long       __st_ino;
+    unsigned int        st_mode;
+    unsigned int        st_nlink;
+
+    unsigned long       st_uid;
+    unsigned long       st_gid;
+
+    unsigned long long  st_rdev;
+    unsigned char       __pad3[4];
+
+    long long           st_size;
+    unsigned long	st_blksize;
+    unsigned long long  st_blocks;
+
+    unsigned long       st_atime;
+    unsigned long       st_atime_nsec;
+
+    unsigned long       st_mtime;
+    unsigned long       st_mtime_nsec;
+
+    unsigned long       st_ctime;
+    unsigned long       st_ctime_nsec;
+
+    unsigned long long  st_ino;
+};
+
+extern int    chmod(const char *, mode_t);
+extern int    fchmod(int, mode_t);
+extern int    mkdir(const char *, mode_t);
+
+extern int    stat(const char *, struct stat *);
+extern int    fstat(int, struct stat *);
+extern int    lstat(const char *, struct stat *);
+extern int    mknod(const char *, mode_t, dev_t);
+extern mode_t umask(mode_t);
+
+#define  stat64    stat
+#define  fstat64   fstat
+#define  lstat64   lstat
+
+static __inline__ int mkfifo(const char *__p, mode_t __m)
+{
+  return mknod(__p, (__m & ~S_IFMT) | S_IFIFO, (dev_t)0);
+}
+
+extern int  fstatat(int dirfd, const char *path, struct stat *buf, int flags);
+extern int  mkdirat(int dirfd, const char *pathname, mode_t mode);
+extern int fchownat(int dirfd, const char *path, uid_t owner, gid_t group, int flags);
+extern int fchmodat(int dirfd, const char *path, mode_t mode, int flags);
+extern int renameat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath);
+
+__END_DECLS
+
+#endif /* _SYS_STAT_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/statfs.h b/ndk/build/platforms/android-1.5/common/include/sys/statfs.h
new file mode 100644
index 0000000..53b3b5e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/statfs.h
@@ -0,0 +1 @@
+#include <sys/vfs.h>
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/syscall.h b/ndk/build/platforms/android-1.5/common/include/sys/syscall.h
new file mode 100644
index 0000000..7055518
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/syscall.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_SYSCALL_H_
+#define _SYS_SYSCALL_H_
+
+#include <errno.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <asm/unistd.h>
+
+__BEGIN_DECLS
+
+int syscall(int number, ...);
+
+__END_DECLS
+
+#endif /* _SYS_SYSCALL_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/sysconf.h b/ndk/build/platforms/android-1.5/common/include/sys/sysconf.h
new file mode 100644
index 0000000..2fc1b08
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/sysconf.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_SYSCONF_H_
+#define _SYS_SYSCONF_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/* as listed by Posix sysconf() description */
+/* most of these will return -1 and ENOSYS  */
+
+#define _SC_ARG_MAX             0x0000
+#define _SC_BC_BASE_MAX         0x0001
+#define _SC_BC_DIM_MAX          0x0002
+#define _SC_BC_SCALE_MAX        0x0003
+#define _SC_BC_STRING_MAX       0x0004
+#define _SC_CHILD_MAX           0x0005
+#define _SC_CLK_TCK             0x0006
+#define _SC_COLL_WEIGHTS_MAX    0x0007
+#define _SC_EXPR_NEST_MAX       0x0008
+#define _SC_LINE_MAX            0x0009
+#define _SC_NGROUPS_MAX         0x000a
+#define _SC_OPEN_MAX            0x000b
+#define _SC_PASS_MAX            0x000c
+#define _SC_2_C_BIND            0x000d
+#define _SC_2_C_DEV             0x000e
+#define _SC_2_C_VERSION         0x000f
+#define _SC_2_CHAR_TERM         0x0010
+#define _SC_2_FORT_DEV          0x0011
+#define _SC_2_FORT_RUN          0x0012
+#define _SC_2_LOCALEDEF         0x0013
+#define _SC_2_SW_DEV            0x0014
+#define _SC_2_UPE               0x0015
+#define _SC_2_VERSION           0x0016
+#define _SC_JOB_CONTROL         0x0017
+#define _SC_SAVED_IDS           0x0018
+#define _SC_VERSION             0x0019
+#define _SC_RE_DUP_MAX          0x001a
+#define _SC_STREAM_MAX          0x001b
+#define _SC_TZNAME_MAX          0x001c
+#define _SC_XOPEN_CRYPT         0x001d
+#define _SC_XOPEN_ENH_I18N      0x001e
+#define _SC_XOPEN_SHM           0x001f
+#define _SC_XOPEN_VERSION       0x0020
+#define _SC_XOPEN_XCU_VERSION   0x0021
+#define _SC_XOPEN_REALTIME      0x0022
+#define _SC_XOPEN_REALTIME_THREADS  0x0023
+#define _SC_XOPEN_LEGACY        0x0024
+#define _SC_ATEXIT_MAX          0x0025
+#define _SC_IOV_MAX             0x0026
+#define _SC_PAGESIZE            0x0027
+#define _SC_PAGE_SIZE           0x0028
+#define _SC_XOPEN_UNIX          0x0029
+#define _SC_XBS5_ILP32_OFF32    0x002a
+#define _SC_XBS5_ILP32_OFFBIG   0x002b
+#define _SC_XBS5_LP64_OFF64     0x002c
+#define _SC_XBS5_LPBIG_OFFBIG   0x002d
+#define _SC_AIO_LISTIO_MAX      0x002e
+#define _SC_AIO_MAX             0x002f
+#define _SC_AIO_PRIO_DELTA_MAX  0x0030
+#define _SC_DELAYTIMER_MAX      0x0031
+#define _SC_MQ_OPEN_MAX         0x0032
+#define _SC_MQ_PRIO_MAX         0x0033
+#define _SC_RTSIG_MAX           0x0034
+#define _SC_SEM_NSEMS_MAX       0x0035
+#define _SC_SEM_VALUE_MAX       0x0036
+#define _SC_SIGQUEUE_MAX        0x0037
+#define _SC_TIMER_MAX           0x0038
+#define _SC_ASYNCHRONOUS_IO     0x0039
+#define _SC_FSYNC               0x003a
+#define _SC_MAPPED_FILES        0x003b
+#define _SC_MEMLOCK             0x003c
+#define _SC_MEMLOCK_RANGE       0x003d
+#define _SC_MEMORY_PROTECTION   0x003e
+#define _SC_MESSAGE_PASSING     0x003f
+#define _SC_PRIORITIZED_IO      0x0040
+#define _SC_PRIORITY_SCHEDULING 0x0041
+#define _SC_REALTIME_SIGNALS    0x0042
+#define _SC_SEMAPHORES          0x0043
+#define _SC_SHARED_MEMORY_OBJECTS  0x0044
+#define _SC_SYNCHRONIZED_IO     0x0045
+#define _SC_TIMERS              0x0046
+#define _SC_GETGR_R_SIZE_MAX    0x0047
+#define _SC_GETPW_R_SIZE_MAX    0x0048
+#define _SC_LOGIN_NAME_MAX      0x0049
+#define _SC_THREAD_DESTRUCTOR_ITERATIONS  0x004a
+#define _SC_THREAD_KEYS_MAX     0x004b
+#define _SC_THREAD_STACK_MIN    0x004c
+#define _SC_THREAD_THREADS_MAX  0x004d
+#define _SC_TTY_NAME_MAX        0x004e
+
+#define _SC_THREADS                     0x004f
+#define _SC_THREAD_ATTR_STACKADDR       0x0050
+#define _SC_THREAD_ATTR_STACKSIZE       0x0051
+#define _SC_THREAD_PRIORITY_SCHEDULING  0x0052
+#define _SC_THREAD_PRIO_INHERIT         0x0053
+#define _SC_THREAD_PRIO_PROTECT         0x0054
+#define _SC_THREAD_SAFE_FUNCTIONS       0x0055
+
+#define _SC_NPROCESSORS_CONF            0x0060
+#define _SC_NPROCESSORS_ONLN            0x0061
+#define _SC_PHYS_PAGES                  0x0062
+#define _SC_AVPHYS_PAGES                0x0063
+
+extern int sysconf (int  name);
+
+__END_DECLS
+
+#endif /* _SYS_SYSCONF_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/sysinfo.h b/ndk/build/platforms/android-1.5/common/include/sys/sysinfo.h
new file mode 100644
index 0000000..c7e46e6
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/sysinfo.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_SYSINFO_H_
+#define _SYS_SYSINFO_H_
+
+#include <sys/cdefs.h>
+#include <linux/kernel.h>
+
+__BEGIN_DECLS
+
+extern int sysinfo (struct sysinfo *info);
+
+__END_DECLS
+
+#endif /* _SYS_SYSINFO_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/syslimits.h b/ndk/build/platforms/android-1.5/common/include/sys/syslimits.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/syslimits.h
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/sysmacros.h b/ndk/build/platforms/android-1.5/common/include/sys/sysmacros.h
new file mode 100644
index 0000000..6f053a8
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/sysmacros.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_SYSMACROS_H_
+#define _SYS_SYSMACROS_H_
+
+/* some rogue code includes this file directly :-( */
+#ifndef _SYS_TYPES_H_
+# include <sys/types.h>
+#endif
+
+static __inline__ int major(dev_t _dev)
+{
+  return (_dev >> 8) & 0xfff;
+}
+
+static __inline__ int minor(dev_t _dev)
+{
+  return (_dev & 0xff) | ((_dev >> 12) & 0xfff00);
+}
+
+static __inline__ dev_t makedev(int __ma, int __mi)
+{
+  return ((__ma & 0xfff) << 8) | (__mi & 0xff) | ((__mi & 0xfff00) << 12);
+}
+
+#endif /* _SYS_SYSMACROS_H_ */
+
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/system_properties.h b/ndk/build/platforms/android-1.5/common/include/sys/system_properties.h
new file mode 100644
index 0000000..2eb00cd
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/system_properties.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+
+#ifndef _INCLUDE_SYS_SYSTEM_PROPERTIES_H
+#define _INCLUDE_SYS_SYSTEM_PROPERTIES_H
+
+typedef struct prop_info prop_info;
+
+#define PROP_NAME_MAX   32
+#define PROP_VALUE_MAX  92
+
+/* Look up a system property by name, copying its value and a
+** \0 terminator to the provided pointer.  The total bytes
+** copied will be no greater than PROP_VALUE_MAX.  Returns
+** the string length of the value.  A property that is not
+** defined is identical to a property with a length 0 value.
+*/
+int __system_property_get(const char *name, char *value);
+
+/* Return a pointer to the system property named name, if it
+** exists, or NULL if there is no such property.  Use 
+** __system_property_read() to obtain the string value from
+** the returned prop_info pointer.
+**
+** It is safe to cache the prop_info pointer to avoid future
+** lookups.  These returned pointers will remain valid for
+** the lifetime of the system.
+*/
+const prop_info *__system_property_find(const char *name);
+
+/* Read the value of a system property.  Returns the length
+** of the value.  Copies the value and \0 terminator into
+** the provided value pointer.  Total length (including
+** terminator) will be no greater that PROP_VALUE_MAX.
+**
+** If name is nonzero, up to PROP_NAME_MAX bytes will be
+** copied into the provided name pointer.  The name will
+** be \0 terminated.
+*/
+int __system_property_read(const prop_info *pi, char *name, char *value);
+
+/* Return a prop_info for the nth system property, or NULL if 
+** there is no nth property.  Use __system_property_read() to
+** read the value of this property.
+**
+** This method is for inspecting and debugging the property 
+** system.  Please use __system_property_find() instead.
+**
+** Order of results may change from call to call.  This is
+** not a bug.
+*/ 
+const prop_info *__system_property_find_nth(unsigned n);
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/time.h b/ndk/build/platforms/android-1.5/common/include/sys/time.h
new file mode 100644
index 0000000..1f010d4
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/time.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_TIME_H_
+#define _SYS_TIME_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <linux/time.h>
+
+__BEGIN_DECLS
+
+extern int gettimeofday(struct timeval *, struct timezone *);
+extern int settimeofday(const struct timeval *, const struct timezone *);
+
+extern int getitimer(int, struct itimerval *);
+extern int setitimer(int, const struct itimerval *, struct itimerval *);
+
+extern int utimes(const char *, const struct timeval *);
+
+#define timerclear(a)   \
+        ((a)->tv_sec = (a)->tv_usec = 0)
+
+#define timerisset(a)    \
+        ((a)->tv_sec != 0 || (a)->tv_usec != 0)
+
+#define timercmp(a, b, op)               \
+        ((a)->tv_sec == (b)->tv_sec      \
+        ? (a)->tv_usec op (b)->tv_usec   \
+        : (a)->tv_sec op (b)->tv_sec)
+
+#define timeradd(a, b, res)                           \
+    do {                                              \
+        (res)->tv_sec  = (a)->tv_sec  + (b)->tv_sec;  \
+        (res)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
+        if ((res)->tv_usec >= 1000000) {              \
+            (res)->tv_usec -= 1000000;                \
+            (res)->tv_sec  += 1;                      \
+        }                                             \
+    } while (0)
+
+#define timersub(a, b, res)                           \
+    do {                                              \
+        (res)->tv_sec  = (a)->tv_sec  - (b)->tv_sec;  \
+        (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+        if ((res)->tv_usec < 0) {                     \
+            (res)->tv_usec += 1000000;                \
+            (res)->tv_sec  -= 1;                      \
+        }                                             \
+    } while (0)
+
+__END_DECLS
+
+#endif /* _SYS_TIME_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/timeb.h b/ndk/build/platforms/android-1.5/common/include/sys/timeb.h
new file mode 100644
index 0000000..f2cc39c
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/timeb.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_TIMEB_H
+#define _SYS_TIMEB_H
+
+#include <sys/time.h>
+
+__BEGIN_DECLS
+
+struct timeb {
+    time_t          time;
+    unsigned short  millitm;
+    short           timezone;
+    short           dstflag;
+};
+
+extern int  ftime(struct timeb*  timebuf);
+
+__END_DECLS
+
+#endif /* _SYS_TIMEB_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/times.h b/ndk/build/platforms/android-1.5/common/include/sys/times.h
new file mode 100644
index 0000000..1b9b8b2
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/times.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_TIMES_H_
+#define _SYS_TIMES_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <linux/times.h>
+
+__BEGIN_DECLS
+
+extern clock_t times(struct tms *);
+
+__END_DECLS
+
+#endif /* _SYS_TIMES_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/ttychars.h b/ndk/build/platforms/android-1.5/common/include/sys/ttychars.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/ttychars.h
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/ttydev.h b/ndk/build/platforms/android-1.5/common/include/sys/ttydev.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/ttydev.h
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/types.h b/ndk/build/platforms/android-1.5/common/include/sys/types.h
new file mode 100644
index 0000000..b071ee9
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/types.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_TYPES_H_
+#define _SYS_TYPES_H_
+
+#define __need_size_t
+#define __need_ptrdiff_t
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+#include <linux/posix_types.h>
+#include <asm/types.h>
+#include <linux/types.h>
+#include <machine/kernel.h>
+
+typedef __u32    __kernel_dev_t;
+
+/* be careful with __kernel_gid_t and __kernel_uid_t
+ * these are defined as 16-bit for legacy reason, but
+ * the kernel uses 32-bits instead.
+ *
+ * 32-bit valuea are required for Android, so use
+ * __kernel_uid32_t and __kernel_gid32_t
+ */
+
+typedef __kernel_blkcnt_t    blkcnt_t;
+typedef __kernel_blksize_t   blksize_t;
+typedef __kernel_clock_t     clock_t;
+typedef __kernel_clockid_t   clockid_t;
+typedef __kernel_dev_t       dev_t;
+typedef __kernel_fsblkcnt_t  fsblkcnt_t;
+typedef __kernel_fsfilcnt_t  fsfilcnt_t;
+typedef __kernel_gid32_t     gid_t;
+typedef __kernel_id_t        id_t;
+typedef __kernel_ino_t       ino_t;
+typedef __kernel_key_t       key_t;
+typedef __kernel_mode_t      mode_t;
+typedef __kernel_nlink_t	 nlink_t;
+#define _OFF_T_DEFINED_
+typedef __kernel_off_t       off_t;
+typedef __kernel_loff_t      loff_t;
+typedef loff_t               off64_t;  /* GLibc-specific */
+
+typedef __kernel_pid_t		 pid_t;
+
+/* while POSIX wants these in <sys/types.h>, we
+ * declare then in <pthread.h> instead */
+#if 0
+typedef  .... pthread_attr_t;
+typedef  .... pthread_cond_t;
+typedef  .... pthread_condattr_t;
+typedef  .... pthread_key_t;
+typedef  .... pthread_mutex_t;
+typedef  .... pthread_once_t;
+typedef  .... pthread_rwlock_t;
+typedef  .... pthread_rwlock_attr_t;
+typedef  .... pthread_t;
+#endif
+
+#ifndef _SIZE_T_DEFINED_
+#define _SIZE_T_DEFINED_
+typedef unsigned int  size_t;
+#endif
+
+/* size_t is defined by the GCC-specific <stddef.h> */
+#ifndef _SSIZE_T_DEFINED_
+#define _SSIZE_T_DEFINED_
+typedef long int  ssize_t;
+#endif
+
+typedef __kernel_suseconds_t  suseconds_t;
+typedef __kernel_time_t       time_t;
+typedef __kernel_uid32_t        uid_t;
+typedef signed long           useconds_t;
+
+typedef __kernel_daddr_t	daddr_t;
+typedef __kernel_timer_t	timer_t;
+typedef __kernel_mqd_t		mqd_t;
+
+typedef __kernel_caddr_t    caddr_t;
+typedef unsigned int        uint_t;
+typedef unsigned int        uint;
+
+/* for some applications */
+#include <sys/sysmacros.h>
+
+#ifdef __BSD_VISIBLE
+typedef	unsigned char	u_char;
+typedef	unsigned short	u_short;
+typedef	unsigned int	u_int;
+typedef	unsigned long	u_long;
+
+typedef uint32_t       u_int32_t;
+typedef uint16_t       u_int16_t;
+typedef uint8_t        u_int8_t;
+typedef uint64_t       u_int64_t;
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/uio.h b/ndk/build/platforms/android-1.5/common/include/sys/uio.h
new file mode 100644
index 0000000..0251716
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/uio.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_UIO_H_
+#define _SYS_UIO_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <linux/uio.h>
+
+__BEGIN_DECLS
+
+int readv(int, const struct iovec *, int);
+int writev(int, const struct iovec *, int);
+
+__END_DECLS
+
+#endif /* _SYS_UIO_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/un.h b/ndk/build/platforms/android-1.5/common/include/sys/un.h
new file mode 100644
index 0000000..973861f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/un.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_UN_H_
+#define _SYS_UN_H_
+
+#include <linux/un.h>
+
+#endif /* _SYS_UN_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/utime.h b/ndk/build/platforms/android-1.5/common/include/sys/utime.h
new file mode 100644
index 0000000..9f8810e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/utime.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_UTIME_H_
+#define _SYS_UTIME_H_
+
+#include <linux/utime.h>
+
+#endif /* _SYS_UTIME_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/utsname.h b/ndk/build/platforms/android-1.5/common/include/sys/utsname.h
new file mode 100644
index 0000000..d54a994
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/utsname.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_UTSNAME_H_
+#define _SYS_UTSNAME_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+#define SYS_NMLN 65
+
+struct utsname {
+    char  sysname   [SYS_NMLN];
+    char  nodename  [SYS_NMLN];
+    char  release   [SYS_NMLN];
+    char  version   [SYS_NMLN];
+    char  machine   [SYS_NMLN];
+    char  domainname[SYS_NMLN];
+};
+
+extern int uname(struct utsname *);
+
+__END_DECLS
+
+#endif /* _SYS_UTSNAME_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/vfs.h b/ndk/build/platforms/android-1.5/common/include/sys/vfs.h
new file mode 100644
index 0000000..4adaf5f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/vfs.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_VFS_H_
+#define _SYS_VFS_H_
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+__BEGIN_DECLS
+
+/* note: this corresponds to the kernel's statfs64 type */
+struct statfs {
+    uint32_t        f_type;
+    uint32_t        f_bsize;
+    uint64_t        f_blocks;
+    uint64_t        f_bfree;
+    uint64_t        f_bavail;
+    uint64_t        f_files;
+    uint64_t        f_ffree;
+    __kernel_fsid_t f_fsid;
+    uint32_t        f_namelen;
+    uint32_t        f_frsize;
+    uint32_t        f_spare[5];
+};
+
+#define  ADFS_SUPER_MAGIC      0xadf5
+#define  AFFS_SUPER_MAGIC      0xADFF
+#define  BEFS_SUPER_MAGIC      0x42465331
+#define  BFS_MAGIC             0x1BADFACE
+#define  CIFS_MAGIC_NUMBER     0xFF534D42
+#define  CODA_SUPER_MAGIC      0x73757245
+#define  COH_SUPER_MAGIC       0x012FF7B7
+#define  CRAMFS_MAGIC          0x28cd3d45
+#define  DEVFS_SUPER_MAGIC     0x1373
+#define  EFS_SUPER_MAGIC       0x00414A53
+#define  EXT_SUPER_MAGIC       0x137D
+#define  EXT2_OLD_SUPER_MAGIC  0xEF51
+#define  EXT2_SUPER_MAGIC      0xEF53
+#define  EXT3_SUPER_MAGIC      0xEF53
+#define  HFS_SUPER_MAGIC       0x4244
+#define  HPFS_SUPER_MAGIC      0xF995E849
+#define  HUGETLBFS_MAGIC       0x958458f6
+#define  ISOFS_SUPER_MAGIC     0x9660
+#define  JFFS2_SUPER_MAGIC     0x72b6
+#define  JFS_SUPER_MAGIC       0x3153464a
+#define  MINIX_SUPER_MAGIC     0x137F /* orig. minix */
+#define  MINIX_SUPER_MAGIC2    0x138F /* 30 char minix */
+#define  MINIX2_SUPER_MAGIC    0x2468 /* minix V2 */
+#define  MINIX2_SUPER_MAGIC2   0x2478 /* minix V2, 30 char names */
+#define  MSDOS_SUPER_MAGIC     0x4d44
+#define  NCP_SUPER_MAGIC       0x564c
+#define  NFS_SUPER_MAGIC       0x6969
+#define  NTFS_SB_MAGIC         0x5346544e
+#define  OPENPROM_SUPER_MAGIC  0x9fa1
+#define  PROC_SUPER_MAGIC      0x9fa0
+#define  QNX4_SUPER_MAGIC      0x002f
+#define  REISERFS_SUPER_MAGIC  0x52654973
+#define  ROMFS_MAGIC           0x7275
+#define  SMB_SUPER_MAGIC       0x517B
+#define  SYSV2_SUPER_MAGIC     0x012FF7B6
+#define  SYSV4_SUPER_MAGIC     0x012FF7B5
+#define  TMPFS_MAGIC           0x01021994
+#define  UDF_SUPER_MAGIC       0x15013346
+#define  UFS_MAGIC             0x00011954
+#define  USBDEVICE_SUPER_MAGIC 0x9fa2
+#define  VXFS_SUPER_MAGIC      0xa501FCF5
+#define  XENIX_SUPER_MAGIC     0x012FF7B4
+#define  XFS_SUPER_MAGIC       0x58465342
+#define  _XIAFS_SUPER_MAGIC    0x012FD16D
+
+extern int statfs(const char *, struct statfs *);
+extern int fstatfs(int, struct statfs *);
+
+__END_DECLS
+
+#endif /* _SYS_VFS_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/vt.h b/ndk/build/platforms/android-1.5/common/include/sys/vt.h
new file mode 100644
index 0000000..b37a869
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/vt.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#include <linux/vt.h>
diff --git a/ndk/build/platforms/android-1.5/common/include/sys/wait.h b/ndk/build/platforms/android-1.5/common/include/sys/wait.h
new file mode 100644
index 0000000..8ba1837
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/sys/wait.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYS_WAIT_H_
+#define _SYS_WAIT_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <linux/wait.h>
+
+__BEGIN_DECLS
+
+#define WEXITSTATUS(s)  (((s) & 0xff00) >> 8)
+#define WCOREDUMP(s)    ((s) & 0x80)
+#define WTERMSIG(s)     ((s) & 0x7f)
+#define WSTOPSIG(s)     WEXITSTATUS(s)
+
+#define WIFEXITED(s)    (WTERMSIG(s) == 0)
+#define WIFSTOPPED(s)   (WTERMSIG(s) == 0x7f)
+#define WIFSIGNALED(s)  (WTERMSIG((s)+1) >= 2)
+
+extern pid_t  wait(int *);
+extern pid_t  waitpid(pid_t, int *, int);
+extern pid_t  wait3(int *, int, struct rusage *);
+extern pid_t  wait4(pid_t, int *, int, struct rusage *);
+
+__END_DECLS
+
+#endif /* _SYS_WAIT_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/syslog.h b/ndk/build/platforms/android-1.5/common/include/syslog.h
new file mode 100644
index 0000000..d35bc79
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/syslog.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _SYSLOG_H
+#define _SYSLOG_H
+
+#include <stdio.h>
+#include <sys/cdefs.h>
+#include <stdarg.h>
+
+__BEGIN_DECLS
+
+/* Alert levels */
+#define LOG_EMERG	0
+#define LOG_ALERT	1
+#define LOG_CRIT	2
+#define LOG_ERR		3
+#define LOG_WARNING	4
+#define LOG_NOTICE	5
+#define LOG_INFO	6
+#define LOG_DEBUG	7
+
+#define LOG_PRIMASK	7
+#define LOG_PRI(x)	((x) & LOG_PRIMASK)
+
+
+/* Facilities; not actually used */
+#define LOG_KERN	0000
+#define LOG_USER	0010
+#define LOG_MAIL	0020
+#define LOG_DAEMON	0030
+#define LOG_AUTH	0040
+#define LOG_SYSLOG	0050
+#define LOG_LPR		0060
+#define LOG_NEWS	0070
+#define LOG_UUCP	0100
+#define LOG_CRON	0110
+#define LOG_AUTHPRIV	0120
+#define LOG_FTP		0130
+#define LOG_LOCAL0	0200
+#define LOG_LOCAL1	0210
+#define LOG_LOCAL2	0220
+#define LOG_LOCAL3	0230
+#define LOG_LOCAL4	0240
+#define LOG_LOCAL5	0250
+#define LOG_LOCAL6	0260
+#define LOG_LOCAL7	0270
+
+#define LOG_FACMASK	01770
+#define LOG_FAC(x)	(((x) >> 3) & (LOG_FACMASK >> 3))
+
+#define	LOG_MASK(pri)	(1 << (pri))		/* mask for one priority */
+#define	LOG_UPTO(pri)	((1 << ((pri)+1)) - 1)	/* all priorities through pri */
+
+/* openlog() flags; only LOG_PID and LOG_PERROR supported */
+#define        LOG_PID         0x01    /* include pid with message */
+#define        LOG_CONS        0x02    /* write to console on logger error */
+#define        LOG_ODELAY      0x04    /* delay connection until syslog() */
+#define        LOG_NDELAY      0x08    /* open connection immediately */
+#define        LOG_NOWAIT      0x10    /* wait for child processes (unused on linux) */
+#define        LOG_PERROR      0x20    /* additional logging to stderr */
+
+/* BIONIC: the following definitions are from OpenBSD's sys/syslog.h
+ */
+struct syslog_data {
+	int	log_file;
+        int	connected;
+        int	opened;
+        int	log_stat;
+        const char 	*log_tag;
+        int 	log_fac;
+        int 	log_mask;
+};
+
+#define SYSLOG_DATA_INIT {-1, 0, 0, 0, (const char *)0, LOG_USER, 0xff}
+
+#define _PATH_LOG  "/dev/kmsg"
+
+extern void	closelog(void);
+extern void	openlog(const char *, int, int);
+extern int	setlogmask(int);
+extern void	syslog(int, const char *, ...);
+extern void	vsyslog(int, const char *, va_list);
+extern void	closelog_r(struct syslog_data *);
+extern void	openlog_r(const char *, int, int, struct syslog_data *);
+extern int	setlogmask_r(int, struct syslog_data *);
+extern void	syslog_r(int, struct syslog_data *, const char *, ...);
+extern void	vsyslog_r(int, struct syslog_data *, const char *, va_list);
+
+__END_DECLS
+
+#endif /* _SYSLOG_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/termios.h b/ndk/build/platforms/android-1.5/common/include/termios.h
new file mode 100644
index 0000000..ad19089
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/termios.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _TERMIOS_H_
+#define _TERMIOS_H_
+
+#include <sys/cdefs.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <stdint.h>
+#include <linux/termios.h>
+
+__BEGIN_DECLS
+
+/* Redefine these to match their ioctl number */
+#undef  TCSANOW
+#define TCSANOW    TCSETS
+
+#undef  TCSADRAIN
+#define TCSADRAIN  TCSETSW
+
+#undef  TCSAFLUSH
+#define TCSAFLUSH  TCSETSF
+
+static __inline__ int tcgetattr(int fd, struct termios *s)
+{
+    return ioctl(fd, TCGETS, s);
+}
+
+static __inline__ int tcsetattr(int fd, int __opt, const struct termios *s)
+{
+    return ioctl(fd, __opt, (void *)s);
+}
+
+static __inline__ int tcflow(int fd, int action)
+{
+    return ioctl(fd, TCXONC, (void *)(intptr_t)action);
+}
+
+static __inline__ int tcflush(int fd, int __queue)
+{
+    return ioctl(fd, TCFLSH, (void *)(intptr_t)__queue);
+}
+
+static __inline__ pid_t tcgetsid(int fd)
+{
+    pid_t _pid;
+    return ioctl(fd, TIOCGSID, &_pid) ? (pid_t)-1 : _pid;
+}
+
+static __inline__ int tcsendbreak(int fd, int __duration)
+{
+    return ioctl(fd, TCSBRKP, (void *)(uintptr_t)__duration);
+}
+
+static __inline__ speed_t cfgetospeed(const struct termios *s)
+{
+    return (speed_t)(s->c_cflag & CBAUD);
+}
+
+static __inline__ int cfsetospeed(struct termios *s, speed_t  speed)
+{
+    s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);
+    return 0;
+}
+
+static __inline__ speed_t cfgetispeed(const struct termios *s)
+{
+    return (speed_t)(s->c_cflag & CBAUD);
+}
+
+static __inline__ int cfsetispeed(struct termios *s, speed_t  speed)
+{
+    s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD);
+  return 0;
+}
+
+static __inline__ void cfmakeraw(struct termios *s)
+{
+    s->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
+    s->c_oflag &= ~OPOST;
+    s->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+    s->c_cflag &= ~(CSIZE|PARENB);
+    s->c_cflag |= CS8;
+}
+
+__END_DECLS
+
+#endif /* _TERMIOS_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/thread_db.h b/ndk/build/platforms/android-1.5/common/include/thread_db.h
new file mode 100644
index 0000000..9c76d40
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/thread_db.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ */
+
+#ifndef _LIBTHREAD_DB__THREAD_DB_H
+#define _LIBTHREAD_DB__THREAD_DB_H
+
+#include <pthread.h>
+#include <signal.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+
+#define TD_THR_ANY_USER_FLAGS       0xffffffff
+#define TD_THR_LOWEST_PRIORITY      -20
+#define TD_SIGNO_MASK               NULL
+
+/* td_err_e values */
+enum {
+    TD_OK,
+    TD_ERR,
+    TD_NOTHR,
+    TD_NOSV,
+    TD_NOLWP,
+    TD_BADPH,
+    TD_BADTH,
+    TD_BADSH,
+    TD_BADTA,
+    TD_BADKEY,
+    TD_NOMSG,
+    TD_NOFPREGS,
+    TD_NOLIBTHREAD,
+    TD_NOEVENT,
+    TD_NOCAPAB,
+    TD_DBERR,
+    TD_NOAPLIC,
+    TD_NOTSD,
+    TD_MALLOC,
+    TD_PARTIALREG,
+    TD_NOXREGS,
+    TD_VERSION
+};
+
+/*
+ * td_event_e values 
+ * NOTE: There is a max of 32 events
+ */
+enum {
+    TD_CREATE,
+    TD_DEATH
+};
+
+/* td_thr_state_e values */
+enum {
+    TD_THR_ANY_STATE,
+    TD_THR_UNKNOWN,
+    TD_THR_SLEEP,
+    TD_THR_ZOMBIE
+};
+
+typedef int32_t td_err_e;
+typedef uint32_t td_event_e;
+typedef uint32_t td_notify_e;
+typedef uint32_t td_thr_state_e;
+typedef pthread_t thread_t;
+
+typedef struct
+{
+    pid_t pid;
+} td_thragent_t;
+
+typedef struct
+{
+    pid_t pid;
+    pid_t tid;
+} td_thrhandle_t;
+
+typedef struct
+{
+    td_event_e event;
+    td_thrhandle_t const * th_p;
+    union {
+        void * data;
+    } msg;
+} td_event_msg_t;
+
+typedef struct
+{
+    uint32_t events;
+} td_thr_events_t;
+
+typedef struct
+{
+    union {
+        void * bptaddr;
+    } u;
+} td_notify_t;
+
+typedef struct
+{
+    td_thr_state_e ti_state;
+    thread_t ti_tid; // pthread's id for the thread
+    int32_t ti_lid; // the kernel's id for the thread
+} td_thrinfo_t;
+
+
+#define td_event_emptyset(set) \
+    (set)->events = 0
+
+#define td_event_fillset(set) \
+    (set)->events = 0xffffffff
+
+#define td_event_addset(set, n) \
+    (set)->events |= (1 << n)
+
+
+typedef int td_thr_iter_f(td_thrhandle_t const *, void *);
+
+
+struct ps_prochandle;
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+extern td_err_e td_ta_new(struct ps_prochandle const * proc_handle, td_thragent_t ** thread_agent);
+
+extern td_err_e td_ta_set_event(td_thragent_t const * agent, td_thr_events_t * event);
+
+extern td_err_e td_ta_event_addr(td_thragent_t const * agent, td_event_e event, td_notify_t * notify);
+
+extern td_err_e td_ta_event_getmsg(td_thragent_t const * agent, td_event_msg_t * event);
+
+extern td_err_e td_ta_thr_iter(td_thragent_t const * agent, td_thr_iter_f * func, void * cookie,
+                               td_thr_state_e state, int32_t prio, sigset_t * sigmask, uint32_t user_flags);
+
+extern char const ** td_symbol_list(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/time.h b/ndk/build/platforms/android-1.5/common/include/time.h
new file mode 100644
index 0000000..35c2358
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/time.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _TIME_H_
+#define _TIME_H_
+
+#include <sys/cdefs.h>
+#include <sys/time.h>
+
+#define __ARCH_SI_UID_T __kernel_uid32_t
+#include <asm/siginfo.h>
+#undef __ARCH_SI_UID_T
+
+__BEGIN_DECLS
+
+extern time_t   time(time_t *);
+extern int      nanosleep(const struct timespec *, struct timespec *);
+
+extern char *strtotimeval(const char *str, struct timeval *tv);
+
+struct tm {
+   int     tm_sec;         /* seconds */
+   int     tm_min;         /* minutes */
+   int     tm_hour;        /* hours */
+   int     tm_mday;        /* day of the month */
+   int     tm_mon;         /* month */
+   int     tm_year;        /* year */
+   int     tm_wday;        /* day of the week */
+   int     tm_yday;        /* day in the year */
+   int     tm_isdst;       /* daylight saving time */
+
+   long int tm_gmtoff;     /* Seconds east of UTC.  */
+   const char *tm_zone;    /* Timezone abbreviation.  */
+
+};
+
+/* defining TM_ZONE indicates that we have a "timezone abbreviation" field in
+ * struct tm, the value should be the field name
+ */
+#define   TM_ZONE   tm_zone
+
+extern char* asctime(const struct tm* a);
+extern char* asctime_r(const struct tm* a, char* buf);
+
+/* Return the difference between TIME1 and TIME0.  */
+extern double difftime (time_t __time1, time_t __time0);
+extern time_t mktime (struct tm *a);
+
+extern struct tm*  localtime(const time_t *t);
+extern struct tm*  localtime_r(const time_t *timep, struct tm *result);
+
+extern struct tm*  gmtime(const time_t *timep);
+extern struct tm*  gmtime_r(const time_t *timep, struct tm *result);
+
+extern char*       strptime(const char *buf, const char *fmt, struct tm *tm);
+extern size_t      strftime(char *s, size_t max, const char *format, const struct tm *tm);
+
+extern char *ctime(const time_t *timep);
+extern char *ctime_r(const time_t *timep, char *buf);
+
+/* global includes */
+extern char*     tzname[];
+extern int       daylight;
+extern long int  timezone;
+
+#define CLOCKS_PER_SEC     1000000
+
+extern clock_t   clock();
+
+/* BIONIC: extra linux clock goodies */
+extern int clock_getres(int, struct timespec *);
+extern int clock_gettime(int, struct timespec *);
+
+#define CLOCK_REALTIME             0
+#define CLOCK_MONOTONIC            1
+#define CLOCK_PROCESS_CPUTIME_ID   2
+#define CLOCK_THREAD_CPUTIME_ID    3
+#define CLOCK_REALTIME_HR          4
+#define CLOCK_MONOTONIC_HR         5
+
+extern int  timer_create(int, struct sigevent*, timer_t*);
+extern int  timer_delete(timer_t);
+extern int  timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue);
+extern int  timer_gettime(timer_t timerid, struct itimerspec *value);
+extern int  timer_getoverrun(timer_t  timerid);
+
+__END_DECLS
+
+#endif /* _TIME_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/time64.h b/ndk/build/platforms/android-1.5/common/include/time64.h
new file mode 100644
index 0000000..9da4bc7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/time64.h
@@ -0,0 +1,54 @@
+/*
+
+Copyright (c) 2007-2008  Michael G Schwern
+
+This software originally derived from Paul Sheer's pivotal_gmtime_r.c.
+
+The MIT License:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+Origin: http://code.google.com/p/y2038
+Modified for Bionic by the Android Open Source Project
+
+*/
+#ifndef TIME64_H
+#define TIME64_H
+
+#include <time.h>
+#include <stdint.h>
+
+typedef int64_t  time64_t;
+
+struct tm *gmtime64_r (const time64_t *, struct tm *);
+struct tm *localtime64_r (const time64_t *, struct tm *);
+struct tm *gmtime64 (const time64_t *);
+struct tm *localtime64 (const time64_t *);
+
+char *asctime64 (const struct tm *);
+char *asctime64_r (const struct tm *, char *);
+
+char *ctime64 (const time64_t*);
+char *ctime64_r (const time64_t*, char*);
+
+time64_t timegm64 (const struct tm *);
+time64_t mktime64 (const struct tm *);
+time64_t timelocal64 (const struct tm *);
+
+#endif /* TIME64_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/typeinfo b/ndk/build/platforms/android-1.5/common/include/typeinfo
new file mode 100644
index 0000000..8a51a54
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/typeinfo
@@ -0,0 +1,28 @@
+#ifndef _TYPEINFO_HEADER_GAURD
+#define _TYPEINFO_HEADER_GAURD
+
+
+namespace std {
+    class type_info;
+    class bad_cast;
+    class bad_typeid;
+};
+
+
+class type_info {
+public:
+    type_info();
+    virtual ~type_info();
+
+    char const * name() const;
+
+    bool operator==(type_info const & right) const;
+    bool operator!=(type_info const & right) const;
+    bool before(type_info const & right) const;
+
+private:
+    type_info(type_info const & right);
+    type_info & operator=(type_info const & right);
+};
+
+#endif
diff --git a/ndk/build/platforms/android-1.5/common/include/unistd.h b/ndk/build/platforms/android-1.5/common/include/unistd.h
new file mode 100644
index 0000000..1ada37e
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/unistd.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _UNISTD_H_
+#define _UNISTD_H_
+
+#include <stddef.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#include <sys/sysconf.h>
+#include <linux/capability.h>
+#include <pathconf.h>
+
+__BEGIN_DECLS
+
+/* Standard file descriptor numbers. */
+#define STDIN_FILENO	0
+#define STDOUT_FILENO	1
+#define STDERR_FILENO	2
+
+/* Values for whence in fseek and lseek */
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+extern char **environ;
+extern __noreturn void _exit(int);
+
+extern pid_t  fork(void);
+extern pid_t  vfork(void);
+extern pid_t  getpid(void);
+extern pid_t  gettid(void);
+extern pid_t  getpgid(pid_t);
+extern int    setpgid(pid_t, pid_t);
+extern pid_t  getppid(void);
+extern pid_t  getpgrp(void);
+extern int    setpgrp(void);
+extern pid_t  setsid(void);
+extern pid_t  getsid(pid_t);
+
+extern int execv(const char *, char * const *);
+extern int execvp(const char *, char * const *);
+extern int execve(const char *, char * const *, char * const *);
+extern int execvpe(const char *, char * const *, char * const *);
+extern int execl(const char *, const char *, ...);
+extern int execlp(const char *, const char *, ...);
+extern int execle(const char *, const char *, ...);
+extern int execlpe(const char *, const char *, ...);
+extern int capget(cap_user_header_t hdrp, cap_user_data_t datap);
+extern int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
+extern int prctl(int  option,  unsigned long arg2, unsigned long arg3,
+                 unsigned long arg4, unsigned long arg5);
+
+extern int nice(int);
+
+extern int setuid(uid_t);
+extern uid_t getuid(void);
+extern int seteuid(uid_t);
+extern uid_t geteuid(void);
+extern int setgid(gid_t);
+extern gid_t getgid(void);
+extern int setegid(gid_t);
+extern gid_t getegid(void);
+extern int getgroups(int, gid_t *);
+extern int setgroups(size_t, const gid_t *);
+extern int setreuid(uid_t, uid_t);
+extern int setregid(gid_t, gid_t);
+extern int setresuid(uid_t, uid_t, uid_t);
+extern int setresgid(gid_t, gid_t, gid_t);
+extern int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
+extern int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
+extern int getfsuid(uid_t);
+extern int setfsuid(uid_t);
+extern int issetugid(void);
+extern char* getlogin(void);
+extern int getlogin_r(char* name, size_t namesize);
+
+
+/* Macros for access() */
+#define R_OK  4  /* Read */
+#define W_OK  2  /* Write */
+#define X_OK  1  /* Execute */
+#define F_OK  0  /* Existence */
+
+extern int access(const char *, int);
+extern int link(const char *, const char *);
+extern int unlink(const char *);
+extern int chdir(const char *);
+extern int fchdir(int);
+extern int rmdir(const char *);
+extern int pipe(int *);
+extern int chroot(const char *);
+extern int symlink(const char *, const char *);
+extern int readlink(const char *, char *, size_t);
+extern int chown(const char *, uid_t, gid_t);
+extern int fchown(int, uid_t, gid_t);
+extern int lchown(const char *, uid_t, gid_t);
+extern char *getcwd(char *, size_t);
+
+extern int sync(void);
+
+extern int close(int);
+extern off_t lseek(int, off_t, int);
+extern loff_t lseek64(int, loff_t, int);
+
+extern ssize_t read(int, void *, size_t);
+extern ssize_t write(int, const void *, size_t);
+extern ssize_t pread(int, void *, size_t, off_t);
+extern ssize_t pwrite(int, void *, size_t, off_t);
+
+extern int dup(int);
+extern int dup2(int, int);
+extern int fcntl(int, int, ...);
+extern int ioctl(int, int, ...);
+extern int flock(int, int);
+extern int fsync(int);
+extern int fdatasync(int);
+extern int ftruncate(int, off_t);
+
+extern int pause(void);
+extern unsigned int alarm(unsigned int);
+extern unsigned int sleep(unsigned int);
+extern void usleep(unsigned long);
+
+extern int gethostname(char *, size_t);
+extern int sethostname(const char *, size_t);
+extern int getdomainname(char *, size_t);
+extern int setdomainname(const char *, size_t);
+
+extern int getdtablesize(void);
+
+extern void *__brk(void *);
+extern int brk(void *);
+extern void *sbrk(ptrdiff_t);
+
+extern int getopt(int, char * const *, const char *);
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+extern int isatty(int);
+
+extern int  acct(const char*  filepath);
+
+static __inline__ int getpagesize(void) {
+  extern unsigned int __page_size;
+  return __page_size;
+}
+static __inline__ int __getpageshift(void) {
+  extern unsigned int __page_shift;
+  return __page_shift;
+}
+
+extern int sysconf(int  name);
+
+extern int daemon(int, int);
+
+/* A special syscall that is only available on the ARM, not x86 function. */
+extern int cacheflush(long start, long end, long flags);
+
+extern pid_t tcgetpgrp(int fd);
+extern int   tcsetpgrp(int fd, pid_t _pid);
+
+__END_DECLS
+
+#endif /* _UNISTD_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/util.h b/ndk/build/platforms/android-1.5/common/include/util.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/util.h
diff --git a/ndk/build/platforms/android-1.5/common/include/utility b/ndk/build/platforms/android-1.5/common/include/utility
new file mode 100644
index 0000000..12044a7
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/utility
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _CPP_UTILITY
+#define _CPP_UTILITY
+
+#pragma GCC system_header
+
+#define  __STL_BEGIN_NAMESPACE  namespace std {
+#define  __STL_END_NAMESPACE    }
+
+#include <stl_pair.h>
+
+#endif /* _CPP_UTILITY */
diff --git a/ndk/build/platforms/android-1.5/common/include/utime.h b/ndk/build/platforms/android-1.5/common/include/utime.h
new file mode 100644
index 0000000..fa7cd2f
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/utime.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _UTIME_H_
+#define _UTIME_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <linux/utime.h>
+
+__BEGIN_DECLS
+
+extern int  utime(const char *, const struct utimbuf *);
+
+__END_DECLS
+
+#endif /* _UTIME_H_ */
+
diff --git a/ndk/build/platforms/android-1.5/common/include/utmp.h b/ndk/build/platforms/android-1.5/common/include/utmp.h
new file mode 100644
index 0000000..e362b40
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/utmp.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _UTMP_H_
+#define _UTMP_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <time.h>
+
+#define _PATH_UTMP      "/var/run/utmp"
+#define _PATH_WTMP      "/var/log/wtmp"
+#define _PATH_LASTLOG   "/var/log/lastlog"
+
+#define	UT_NAMESIZE	8
+#define	UT_LINESIZE	8
+#define	UT_HOSTSIZE	16
+
+#define USER_PROCESS 7
+
+struct lastlog
+{
+    time_t ll_time;
+    char ll_line[UT_LINESIZE];
+    char ll_host[UT_HOSTSIZE];
+};
+
+struct exit_status
+{
+    short int e_termination;
+    short int e_exit;
+};
+
+
+struct utmp
+{
+    short int ut_type;
+    pid_t ut_pid;
+    char ut_line[UT_LINESIZE];
+    char ut_id[4];
+    char ut_user[UT_NAMESIZE];
+    char ut_host[UT_HOSTSIZE];
+
+    struct exit_status ut_exit;
+
+    long int ut_session;
+    struct timeval ut_tv;
+
+    int32_t ut_addr_v6[4];
+    char unsed[20];
+};
+
+
+#define ut_name ut_user
+#define ut_time ut_tv.tv_sec
+#define ut_addr ut_addr_v6[0]
+
+__BEGIN_DECLS
+
+int utmpname(const char*);
+void setutent();
+struct utmp* getutent();
+
+__END_DECLS
+
+#endif // _UTMP_H_
diff --git a/ndk/build/platforms/android-1.5/common/include/wchar.h b/ndk/build/platforms/android-1.5/common/include/wchar.h
new file mode 100644
index 0000000..e2feb60
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/wchar.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "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 THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ */
+#ifndef _WCHAR_H_
+#define _WCHAR_H_
+
+#include <sys/cdefs.h>
+#include <stdio.h>
+
+/* wchar_t is required in stdlib.h according to POSIX */
+#define __need___wchar_t
+#include <stddef.h>
+
+#include <stdarg.h>
+#include <time.h>
+#include <malloc.h>
+
+#include <stddef.h>
+
+/* IMPORTANT: Any code that relies on wide character support is essentially
+ *            non-portable and/or broken. the only reason this header exist
+ *            is because I'm really a nice guy. However, I'm not nice enough
+ *            to provide you with a real implementation. instead wchar_t == char
+ *            and all wc functions are stubs to their "normal" equivalent...
+ */
+
+__BEGIN_DECLS
+
+typedef int                     wint_t;
+typedef struct { int  dummy; }  mbstate_t;
+
+typedef enum {
+    WC_TYPE_INVALID = 0,
+    WC_TYPE_ALNUM,
+    WC_TYPE_ALPHA,
+    WC_TYPE_BLANK,
+    WC_TYPE_CNTRL,
+    WC_TYPE_DIGIT,
+    WC_TYPE_GRAPH,
+    WC_TYPE_LOWER,
+    WC_TYPE_PRINT,
+    WC_TYPE_PUNCT,
+    WC_TYPE_SPACE,
+    WC_TYPE_UPPER,
+    WC_TYPE_XDIGIT,
+    WC_TYPE_MAX
+} wctype_t;
+
+#define  WCHAR_MAX   255
+#define  WCHAR_MIN   0
+#define  WEOF        (-1)
+
+extern wint_t            btowc(int);
+extern int               fwprintf(FILE *, const wchar_t *, ...);
+extern int               fwscanf(FILE *, const wchar_t *, ...);
+extern int               iswalnum(wint_t);
+extern int               iswalpha(wint_t);
+extern int               iswcntrl(wint_t);
+extern int               iswdigit(wint_t);
+extern int               iswgraph(wint_t);
+extern int               iswlower(wint_t);
+extern int               iswprint(wint_t);
+extern int               iswpunct(wint_t);
+extern int               iswspace(wint_t);
+extern int               iswupper(wint_t);
+extern int               iswxdigit(wint_t);
+extern int               iswctype(wint_t, wctype_t);
+extern wint_t            fgetwc(FILE *);
+extern wchar_t          *fgetws(wchar_t *, int, FILE *);
+extern wint_t            fputwc(wchar_t, FILE *);
+extern int               fputws(const wchar_t *, FILE *);
+extern int               fwide(FILE *, int);
+extern wint_t            getwc(FILE *);
+extern wint_t            getwchar(void);
+extern int               mbsinit(const mbstate_t *);
+extern size_t            mbrlen(const char *, size_t, mbstate_t *);
+extern size_t            mbrtowc(wchar_t *, const char *, size_t, mbstate_t *);
+extern size_t            mbsrtowcs(wchar_t *, const char **, size_t, mbstate_t *);
+extern wint_t            putwc(wchar_t, FILE *);
+extern wint_t            putwchar(wchar_t);
+extern int               swprintf(wchar_t *, size_t, const wchar_t *, ...);
+extern int               swscanf(const wchar_t *, const wchar_t *, ...);
+extern wint_t            towlower(wint_t);
+extern wint_t            towupper(wint_t);
+extern wint_t            ungetwc(wint_t, FILE *);
+extern int               vfwprintf(FILE *, const wchar_t *, va_list);
+extern int               vwprintf(const wchar_t *, va_list);
+extern int               vswprintf(wchar_t *, size_t, const wchar_t *, va_list);
+extern size_t            wcrtomb(char *, wchar_t, mbstate_t *);
+extern wchar_t          *wcscat(wchar_t *, const wchar_t *);
+extern wchar_t          *wcschr(const wchar_t *, wchar_t);
+extern int               wcscmp(const wchar_t *, const wchar_t *);
+extern int               wcscoll(const wchar_t *, const wchar_t *);
+extern wchar_t          *wcscpy(wchar_t *, const wchar_t *);
+extern size_t            wcscspn(const wchar_t *, const wchar_t *);
+extern size_t            wcsftime(wchar_t *, size_t, const wchar_t *, const struct tm *);
+extern size_t            wcslen(const wchar_t *);
+extern wchar_t          *wcsncat(wchar_t *, const wchar_t *, size_t);
+extern int               wcsncmp(const wchar_t *, const wchar_t *, size_t);
+extern wchar_t          *wcsncpy(wchar_t *, const wchar_t *, size_t);
+extern wchar_t          *wcspbrk(const wchar_t *, const wchar_t *);
+extern wchar_t          *wcsrchr(const wchar_t *, wchar_t);
+extern size_t            wcsrtombs(char *, const wchar_t **, size_t, mbstate_t *);
+extern size_t            wcsspn(const wchar_t *, const wchar_t *);
+extern wchar_t          *wcsstr(const wchar_t *, const wchar_t *);
+extern double            wcstod(const wchar_t *, wchar_t **);
+extern wchar_t          *wcstok(wchar_t *, const wchar_t *, wchar_t **);
+extern long int          wcstol(const wchar_t *, wchar_t **, int);
+extern unsigned long int wcstoul(const wchar_t *, wchar_t **, int);
+extern wchar_t          *wcswcs(const wchar_t *, const wchar_t *);
+extern int               wcswidth(const wchar_t *, size_t);
+extern size_t            wcsxfrm(wchar_t *, const wchar_t *, size_t);
+extern int               wctob(wint_t);
+extern wctype_t          wctype(const char *);
+extern int               wcwidth(wchar_t);
+extern wchar_t          *wmemchr(const wchar_t *, wchar_t, size_t);
+extern int               wmemcmp(const wchar_t *, const wchar_t *, size_t);
+extern wchar_t          *wmemcpy(wchar_t *, const wchar_t *, size_t);
+extern wchar_t          *wmemmove(wchar_t *, const wchar_t *, size_t);
+extern wchar_t          *wmemset(wchar_t *, wchar_t, size_t);
+extern int               wprintf(const wchar_t *, ...);
+extern int               wscanf(const wchar_t *, ...);
+
+/* No really supported.  These are just for making libstdc++-v3 happy.  */
+typedef void *wctrans_t;
+extern wint_t		 towctrans(wint_t, wctrans_t);
+extern wctrans_t	 wctrans (const char *);
+
+__END_DECLS
+
+#endif /* _WCHAR_H_ */
diff --git a/ndk/build/platforms/android-1.5/common/include/wctype.h b/ndk/build/platforms/android-1.5/common/include/wctype.h
new file mode 100644
index 0000000..b5f18a0
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/wctype.h
@@ -0,0 +1 @@
+#include <wchar.h>
diff --git a/ndk/build/platforms/android-1.5/common/include/zconf.h b/ndk/build/platforms/android-1.5/common/include/zconf.h
new file mode 100644
index 0000000..03a9431
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/zconf.h
@@ -0,0 +1,332 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+#  define deflateInit_          z_deflateInit_
+#  define deflate               z_deflate
+#  define deflateEnd            z_deflateEnd
+#  define inflateInit_          z_inflateInit_
+#  define inflate               z_inflate
+#  define inflateEnd            z_inflateEnd
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateCopy           z_deflateCopy
+#  define deflateReset          z_deflateReset
+#  define deflateParams         z_deflateParams
+#  define deflateBound          z_deflateBound
+#  define deflatePrime          z_deflatePrime
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateCopy           z_inflateCopy
+#  define inflateReset          z_inflateReset
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define compress              z_compress
+#  define compress2             z_compress2
+#  define compressBound         z_compressBound
+#  define uncompress            z_uncompress
+#  define adler32               z_adler32
+#  define crc32                 z_crc32
+#  define get_crc_table         z_get_crc_table
+#  define zError                z_zError
+
+#  define alloc_func            z_alloc_func
+#  define free_func             z_free_func
+#  define in_func               z_in_func
+#  define out_func              z_out_func
+#  define Byte                  z_Byte
+#  define uInt                  z_uInt
+#  define uLong                 z_uLong
+#  define Bytef                 z_Bytef
+#  define charf                 z_charf
+#  define intf                  z_intf
+#  define uIntf                 z_uIntf
+#  define uLongf                z_uLongf
+#  define voidpf                z_voidpf
+#  define voidp                 z_voidp
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if 0           /* HAVE_UNISTD_H -- this line is updated by ./configure */
+#  include <sys/types.h> /* for off_t */
+#  include <unistd.h>    /* for SEEK_* and off_t */
+#  ifdef VMS
+#    include <unixio.h>   /* for off_t */
+#  endif
+#  define z_off_t off_t
+#endif
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if defined(__OS400__)
+#  define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+#  define NO_vsnprintf
+#  ifdef FAR
+#    undef FAR
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+#   pragma map(deflateInit_,"DEIN")
+#   pragma map(deflateInit2_,"DEIN2")
+#   pragma map(deflateEnd,"DEEND")
+#   pragma map(deflateBound,"DEBND")
+#   pragma map(inflateInit_,"ININ")
+#   pragma map(inflateInit2_,"ININ2")
+#   pragma map(inflateEnd,"INEND")
+#   pragma map(inflateSync,"INSY")
+#   pragma map(inflateSetDictionary,"INSEDI")
+#   pragma map(compressBound,"CMBND")
+#   pragma map(inflate_table,"INTABL")
+#   pragma map(inflate_fast,"INFA")
+#   pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/ndk/build/platforms/android-1.5/common/include/zlib.h b/ndk/build/platforms/android-1.5/common/include/zlib.h
new file mode 100644
index 0000000..0228179
--- /dev/null
+++ b/ndk/build/platforms/android-1.5/common/include/zlib.h
@@ -0,0 +1,1357 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.2.3, July 18th, 2005
+
+  Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.3"
+#define ZLIB_VERNUM 0x1230
+
+/*
+     The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed
+  data.  This version of the library supports only one compression method
+  (deflation) but other algorithms will be added later and will have the same
+  stream interface.
+
+     Compression can be done in a single step if the buffers are large
+  enough (for example if an input file is mmap'ed), or can be done by
+  repeated calls of the compression function.  In the latter case, the
+  application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+     The compressed data format used by default by the in-memory functions is
+  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+  around a deflate stream, which is itself documented in RFC 1951.
+
+     The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio using the functions that start
+  with "gz".  The gzip format is different from the zlib format.  gzip is a
+  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+     This library can optionally read and write gzip streams in memory as well.
+
+     The zlib format was designed to be compact and fast for use in memory
+  and on communications channels.  The gzip format was designed for single-
+  file compression on file systems, has a larger header than zlib to maintain
+  directory information, and uses a different, slower check method than zlib.
+
+     The library does not install any signal handler. The decoder checks
+  the consistency of the compressed data, so the library should never
+  crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    Bytef    *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: binary or text */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+     gzip header information passed to and from zlib routines.  See RFC 1952
+  for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+    int     text;       /* true if compressed data believed to be text */
+    uLong   time;       /* modification time */
+    int     xflags;     /* extra flags (not used when writing a gzip file) */
+    int     os;         /* operating system */
+    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */
+    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */
+    uInt    extra_max;  /* space at extra (only when reading header) */
+    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */
+    uInt    name_max;   /* space at name (only when reading header) */
+    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */
+    uInt    comm_max;   /* space at comment (only when reading header) */
+    int     hcrc;       /* true if there was or will be a header crc */
+    int     done;       /* true when done reading gzip header (not used
+                           when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+   The application must update next_in and avail_in when avail_in has
+   dropped to zero. It must update next_out and avail_out when avail_out
+   has dropped to zero. The application must initialize zalloc, zfree and
+   opaque before calling the init function. All other fields are set by the
+   compression library and must not be updated by the application.
+
+   The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree. This can be useful for custom
+   memory management. The compression library attaches no meaning to the
+   opaque value.
+
+   zalloc must return Z_NULL if there is not enough memory for the object.
+   If zlib is used in a multi-threaded application, zalloc and zfree must be
+   thread safe.
+
+   On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this
+   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+   pointers returned by zalloc for objects of exactly 65536 bytes *must*
+   have their offset normalized to zero. The default allocation function
+   provided by this library ensures this (see zutil.c). To reduce memory
+   requirements and avoid any allocation of 64K objects, at the expense of
+   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+   The fields total_in and total_out can be used for statistics or
+   progress reports. After compression, total_in holds the total size of
+   the uncompressed data and may be saved for use in the decompressor
+   (particularly if the decompressor wants to decompress everything in
+   a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+#define Z_BLOCK         5
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_RLE                 3
+#define Z_FIXED               4
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_TEXT     1
+#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+                        /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is
+   not compatible with the zlib.h header file used by the application.
+   This check is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression. The fields
+   zalloc, zfree and opaque must be initialized before by the caller.
+   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+   use default allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at
+   all (the input data is simply copied a block at a time).
+   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+   compression (currently equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).
+   msg is set to null if there is no error message.  deflateInit does not
+   perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+    deflate compresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may introduce some
+  output latency (reading input without producing any output) except when
+  forced to flush.
+
+    The detailed semantics are as follows. deflate performs one or both of the
+  following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly. This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary (in interactive applications).
+    Some output may be provided even if flush is not set.
+
+  Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating avail_in or avail_out accordingly; avail_out
+  should never be zero before the call. The application can consume the
+  compressed output when it wants, for example when the output buffer is full
+  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+  and with zero avail_out, it must be called again after making room in the
+  output buffer because there might be more output pending.
+
+    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+  decide how much data to accumualte before producing output, in order to
+  maximize compression.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+  flushed to the output buffer and the output is aligned on a byte boundary, so
+  that the decompressor can get all input data available so far. (In particular
+  avail_in is zero after the call if enough output space has been provided
+  before the call.)  Flushing may degrade compression for some compression
+  algorithms and so it should be used only when necessary.
+
+    If flush is set to Z_FULL_FLUSH, all output is flushed as with
+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+  restart from this point if previous compressed data has been damaged or if
+  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+  compression.
+
+    If deflate returns with avail_out == 0, this function must be called again
+  with the same value of the flush parameter and more output space (updated
+  avail_out), until the flush is complete (deflate returns with non-zero
+  avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+  avail_out is greater than six to avoid repeated flush markers due to
+  avail_out == 0 on return.
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there
+  was enough output space; if deflate returns with Z_OK, this function must be
+  called again with Z_FINISH and more output space (updated avail_out) but no
+  more input data, until it returns with Z_STREAM_END or an error. After
+  deflate has returned Z_STREAM_END, the only possible operations on the
+  stream are deflateReset or deflateEnd.
+
+    Z_FINISH can be used immediately after deflateInit if all the compression
+  is to be done in a single step. In this case, avail_out must be at least
+  the value returned by deflateBound (see below). If deflate does not return
+  Z_STREAM_END, then it must be called again as described above.
+
+    deflate() sets strm->adler to the adler32 checksum of all input read
+  so far (that is, total_in bytes).
+
+    deflate() may update strm->data_type if it can make a good guess about
+  the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
+  binary. This field is only for information purposes and does not affect
+  the compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+  (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+  fatal, and deflate() can be called again with more input and more output
+  space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded). In the error case,
+   msg may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression. The fields
+   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+   value depends on the compression method), inflateInit determines the
+   compression method from the zlib header and allocates all data structures
+   accordingly; otherwise the allocation will be deferred to the first call of
+   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+   use default allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller.  msg is set to null if there is no error
+   message. inflateInit does not perform any decompression apart from reading
+   the zlib header if present: this will be done by inflate().  (So next_in and
+   avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+    inflate decompresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+  The detailed semantics are as follows. inflate performs one or both of the
+  following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing
+    will resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there
+    is no more input data or no more space in the output buffer (see below
+    about the flush parameter).
+
+  Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating the next_* and avail_* values accordingly.
+  The application can consume the uncompressed output when it wants, for
+  example when the output buffer is full (avail_out == 0), or after each
+  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+  must be called again after making room in the output buffer because there
+  might be more output pending.
+
+    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
+  Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
+  output as possible to the output buffer. Z_BLOCK requests that inflate() stop
+  if and when it gets to the next deflate block boundary. When decoding the
+  zlib or gzip format, this will cause inflate() to return immediately after
+  the header and before the first block. When doing a raw inflate, inflate()
+  will go ahead and process the first block, and will return when it gets to
+  the end of that block, or when it runs out of data.
+
+    The Z_BLOCK option assists in appending to or combining deflate streams.
+  Also to assist in this, on return inflate() will set strm->data_type to the
+  number of unused bits in the last byte taken from strm->next_in, plus 64
+  if inflate() is currently decoding the last block in the deflate stream,
+  plus 128 if inflate() returned immediately after decoding an end-of-block
+  code or decoding the complete header up to just before the first byte of the
+  deflate stream. The end-of-block will not be indicated until all of the
+  uncompressed data from that block has been written to strm->next_out.  The
+  number of unused bits may in general be greater than seven, except when
+  bit 7 of data_type is set, in which case the number of unused bits will be
+  less than eight.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error. However if all decompression is to be performed in a single step
+  (a single call of inflate), the parameter flush should be set to
+  Z_FINISH. In this case all pending input is processed and all pending
+  output is flushed; avail_out must be large enough to hold all the
+  uncompressed data. (The size of the uncompressed data may have been saved
+  by the compressor for this purpose.) The next operation on this stream must
+  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+  is never required, but can be used to inform inflate that a faster approach
+  may be used for the single inflate() call.
+
+     In this implementation, inflate() always flushes as much output as
+  possible to the output buffer, and always uses the faster approach on the
+  first call. So the only effect of the flush parameter in this implementation
+  is on the return value of inflate(), as noted below, or when it returns early
+  because Z_BLOCK is used.
+
+     If a preset dictionary is needed after this call (see inflateSetDictionary
+  below), inflate sets strm->adler to the adler32 checksum of the dictionary
+  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+  strm->adler to the adler32 checksum of all output produced so far (that is,
+  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+  below. At the end of the stream, inflate() checks that its computed adler32
+  checksum is equal to that saved by the compressor and returns Z_STREAM_END
+  only if the checksum is correct.
+
+    inflate() will decompress and check either zlib-wrapped or gzip-wrapped
+  deflate data.  The header type is detected automatically.  Any information
+  contained in the gzip header is not retained, so applications that need that
+  information should instead use raw inflate, see inflateInit2() below, or
+  inflateBack() and perform their own processing of the gzip header and
+  trailer.
+
+    inflate() returns Z_OK if some progress has been made (more input processed
+  or more output produced), Z_STREAM_END if the end of the compressed data has
+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+  corrupted (input stream not conforming to the zlib format or incorrect check
+  value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+  if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
+  Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+  output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+  inflate() can be called again with more input and more output space to
+  continue decompressing. If Z_DATA_ERROR is returned, the application may then
+  call inflateSync() to look for a good compression block if a partial recovery
+  of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent. In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                     int  level,
+                                     int  method,
+                                     int  windowBits,
+                                     int  memLevel,
+                                     int  strategy));
+
+     This is another version of deflateInit with more compression options. The
+   fields next_in, zalloc, zfree and opaque must be initialized before by
+   the caller.
+
+     The method parameter is the compression method. It must be Z_DEFLATED in
+   this version of the library.
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer). It should be in the range 8..15 for this
+   version of the library. Larger values of this parameter result in better
+   compression at the expense of memory usage. The default value is 15 if
+   deflateInit is used instead.
+
+     windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+   determines the window size. deflate() will then generate raw deflate data
+   with no zlib header or trailer, and will not compute an adler32 check value.
+
+     windowBits can also be greater than 15 for optional gzip encoding. Add
+   16 to windowBits to write a simple gzip header and trailer around the
+   compressed data instead of a zlib wrapper. The gzip header will have no
+   file name, no extra data, no comment, no modification time (set to zero),
+   no header crc, and the operating system will be set to 255 (unknown).  If a
+   gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state. memLevel=1 uses minimum memory but
+   is slow and reduces compression ratio; memLevel=9 uses maximum memory
+   for optimal speed. The default value is 8. See zconf.h for total memory
+   usage as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm. Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match), or Z_RLE to limit match distances to one (run-length
+   encoding). Filtered data consists mostly of small values with a somewhat
+   random distribution. In this case, the compression algorithm is tuned to
+   compress them better. The effect of Z_FILTERED is to force more Huffman
+   coding and less string matching; it is somewhat intermediate between
+   Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
+   Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
+   parameter only affects the compression ratio but not the correctness of the
+   compressed output even if it is not set appropriately.  Z_FIXED prevents the
+   use of dynamic Huffman codes, allowing for a simpler decoder for special
+   applications.
+
+      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+   method). msg is set to null if there is no error message.  deflateInit2 does
+   not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the compression dictionary from the given byte sequence
+   without producing any compressed output. This function must be called
+   immediately after deflateInit, deflateInit2 or deflateReset, before any
+   call of deflate. The compressor and decompressor must use exactly the same
+   dictionary (see inflateSetDictionary).
+
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary. Using a
+   dictionary is most useful when the data to be compressed is short and can be
+   predicted with good accuracy; the data can then be compressed better than
+   with the default empty dictionary.
+
+     Depending on the size of the compression data structures selected by
+   deflateInit or deflateInit2, a part of the dictionary may in effect be
+   discarded, for example if the dictionary is larger than the window size in
+   deflate or deflate2. Thus the strings most likely to be useful should be
+   put at the end of the dictionary, not at the front. In addition, the
+   current implementation of deflate will use at most the window size minus
+   262 bytes of the provided dictionary.
+
+     Upon return of this function, strm->adler is set to the adler32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor. (The adler32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.) If a raw deflate was requested, then the
+   adler32 value is not computed and strm->adler is not set.
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent (for example if deflate has already been called for this stream
+   or if the compression method is bsort). deflateSetDictionary does not
+   perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter. The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and
+   can consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being NULL). msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit,
+   but does not free and reallocate all the internal compression state.
+   The stream will keep the same compression level and any other attributes
+   that may have been set by deflateInit2.
+
+      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+                                      int level,
+                                      int strategy));
+/*
+     Dynamically update the compression level and compression strategy.  The
+   interpretation of level and strategy is as in deflateInit2.  This can be
+   used to switch between compression and straight copy of the input data, or
+   to switch to a different kind of input data requiring a different
+   strategy. If the compression level is changed, the input available so far
+   is compressed with the old level (and may be flushed); the new level will
+   take effect only at the next call of deflate().
+
+     Before the call of deflateParams, the stream state must be set as for
+   a call of deflate(), since the currently available input may have to
+   be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+   if strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+                                    int good_length,
+                                    int max_lazy,
+                                    int nice_length,
+                                    int max_chain));
+/*
+     Fine tune deflate's internal compression parameters.  This should only be
+   used by someone who understands the algorithm used by zlib's deflate for
+   searching for the best matching string, and even then only by the most
+   fanatic optimizer trying to squeeze out the last compressed bit for their
+   specific input data.  Read the deflate.c source code for the meaning of the
+   max_lazy, good_length, nice_length, and max_chain parameters.
+
+     deflateTune() can be called after deflateInit() or deflateInit2(), and
+   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+                                       uLong sourceLen));
+/*
+     deflateBound() returns an upper bound on the compressed size after
+   deflation of sourceLen bytes.  It must be called after deflateInit()
+   or deflateInit2().  This would be used to allocate an output buffer
+   for deflation in a single pass, and so would be called before deflate().
+*/
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     deflatePrime() inserts bits in the deflate output stream.  The intent
+  is that this function is used to start off the deflate output with the
+  bits leftover from a previous deflate stream when appending to it.  As such,
+  this function can only be used for raw deflate, and must be used before the
+  first deflate() call after a deflateInit2() or deflateReset().  bits must be
+  less than or equal to 16, and that many of the least significant bits of
+  value will be inserted in the output.
+
+      deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+      deflateSetHeader() provides gzip header information for when a gzip
+   stream is requested by deflateInit2().  deflateSetHeader() may be called
+   after deflateInit2() or deflateReset() and before the first call of
+   deflate().  The text, time, os, extra field, name, and comment information
+   in the provided gz_header structure are written to the gzip header (xflag is
+   ignored -- the extra flags are set according to the compression level).  The
+   caller must assure that, if not Z_NULL, name and comment are terminated with
+   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+   available there.  If hcrc is true, a gzip header crc is included.  Note that
+   the current versions of the command-line version of gzip (up through version
+   1.3.x) do not support header crc's, and will report that it is a "multi-part
+   gzip file" and give up.
+
+      If deflateSetHeader is not used, the default gzip header has text false,
+   the time set to zero, and os set to 255, with no extra, name, or comment
+   fields.  The gzip header is returned to the default state by deflateReset().
+
+      deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+                                     int  windowBits));
+
+     This is another version of inflateInit with an extra parameter. The
+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+   before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library. The default value is 15 if inflateInit is used
+   instead. windowBits must be greater than or equal to the windowBits value
+   provided to deflateInit2() while compressing, or it must be equal to 15 if
+   deflateInit2() was not used. If a compressed stream with a larger window
+   size is given as input, inflate() will return with the error code
+   Z_DATA_ERROR instead of trying to allocate a larger window.
+
+     windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+   determines the window size. inflate() will then process raw deflate data,
+   not looking for a zlib or gzip header, not generating a check value, and not
+   looking for any check values for comparison at the end of the stream. This
+   is for use with other formats that use the deflate compressed data format
+   such as zip.  Those formats provide their own check values. If a custom
+   format is developed using the raw deflate format for compressed data, it is
+   recommended that a check value such as an adler32 or a crc32 be applied to
+   the uncompressed data as is done in the zlib, gzip, and zip formats.  For
+   most applications, the zlib format should be used as is. Note that comments
+   above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+     windowBits can also be greater than 15 for optional gzip decoding. Add
+   32 to windowBits to enable zlib and gzip decoding with automatic header
+   detection, or add 16 to decode only the gzip format (the zlib format will
+   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is
+   a crc32 instead of an adler32.
+
+     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
+   is set to null if there is no error message.  inflateInit2 does not perform
+   any decompression apart from reading the zlib header if present: this will
+   be done by inflate(). (So next_in and avail_in may be modified, but next_out
+   and avail_out are unchanged.)
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the decompression dictionary from the given uncompressed byte
+   sequence. This function must be called immediately after a call of inflate,
+   if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+   can be determined from the adler32 value returned by that call of inflate.
+   The compressor and decompressor must use exactly the same dictionary (see
+   deflateSetDictionary).  For raw inflate, this function can be called
+   immediately after inflateInit2() or inflateReset() and before any call of
+   inflate() to set the dictionary.  The application must insure that the
+   dictionary that was used for compression is provided.
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect adler32 value). inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+    Skips invalid compressed data until a full flush point (see above the
+  description of deflate with Z_FULL_FLUSH) can be found, or until all
+  available input is skipped. No output is provided.
+
+    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+  case, the application may save the current current value of total_in which
+  indicates where valid compressed data was found. In the error case, the
+  application may repeatedly call inflateSync, providing more input each time,
+  until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when randomly accessing a large stream.  The
+   first pass through the stream can periodically record the inflate state,
+   allowing restarting inflate at those points when randomly accessing the
+   stream.
+
+     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being NULL). msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.
+   The stream will keep attributes that may have been set by inflateInit2.
+
+      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     This function inserts bits in the inflate input stream.  The intent is
+  that this function is used to start inflating at a bit position in the
+  middle of a byte.  The provided bits will be used before any bytes are used
+  from next_in.  This function should only be used with raw inflate, and
+  should be used before the first inflate() call after inflateInit2() or
+  inflateReset().  bits must be less than or equal to 16, and that many of the
+  least significant bits of value will be inserted in the input.
+
+      inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+      inflateGetHeader() requests that gzip header information be stored in the
+   provided gz_header structure.  inflateGetHeader() may be called after
+   inflateInit2() or inflateReset(), and before the first call of inflate().
+   As inflate() processes the gzip stream, head->done is zero until the header
+   is completed, at which time head->done is set to one.  If a zlib stream is
+   being decoded, then head->done is set to -1 to indicate that there will be
+   no gzip header information forthcoming.  Note that Z_BLOCK can be used to
+   force inflate() to return immediately after header processing is complete
+   and before any actual data is decompressed.
+
+      The text, time, xflags, and os fields are filled in with the gzip header
+   contents.  hcrc is set to true if there is a header CRC.  (The header CRC
+   was valid if done is set to one.)  If extra is not Z_NULL, then extra_max
+   contains the maximum number of bytes to write to extra.  Once done is true,
+   extra_len contains the actual extra field length, and extra contains the
+   extra field, or that field truncated if extra_max is less than extra_len.
+   If name is not Z_NULL, then up to name_max characters are written there,
+   terminated with a zero unless the length is greater than name_max.  If
+   comment is not Z_NULL, then up to comm_max characters are written there,
+   terminated with a zero unless the length is greater than comm_max.  When
+   any of extra, name, or comment are not Z_NULL and the respective field is
+   not present in the header, then that field is set to Z_NULL to signal its
+   absence.  This allows the use of deflateSetHeader() with the returned
+   structure to duplicate the header.  However if those fields are set to
+   allocated memory, then the application will need to save those pointers
+   elsewhere so that they can be eventually freed.
+
+      If inflateGetHeader is not used, then the header information is simply
+   discarded.  The header is always checked for validity, including the header
+   CRC if present.  inflateReset() will reset the process to discard the header
+   information.  The application would need to call inflateGetHeader() again to
+   retrieve the header from the next gzip stream.
+
+      inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+                                        unsigned char FAR *window));
+
+     Initialize the internal stream state for decompression using inflateBack()
+   calls.  The fields zalloc, zfree and opaque in strm must be initialized
+   before the call.  If zalloc and zfree are Z_NULL, then the default library-
+   derived memory allocation routines are used.  windowBits is the base two
+   logarithm of the window size, in the range 8..15.  window is a caller
+   supplied buffer of that size.  Except for special applications where it is
+   assured that deflate was used with small window sizes, windowBits must be 15
+   and a 32K byte window must be supplied to be able to decompress general
+   deflate streams.
+
+     See inflateBack() for the usage of these routines.
+
+     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+   the paramaters are invalid, Z_MEM_ERROR if the internal state could not
+   be allocated, or Z_VERSION_ERROR if the version of the library does not
+   match the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+                                    in_func in, void FAR *in_desc,
+                                    out_func out, void FAR *out_desc));
+/*
+     inflateBack() does a raw inflate with a single call using a call-back
+   interface for input and output.  This is more efficient than inflate() for
+   file i/o applications in that it avoids copying between the output and the
+   sliding window by simply making the window itself the output buffer.  This
+   function trusts the application to not change the output buffer passed by
+   the output function, at least until inflateBack() returns.
+
+     inflateBackInit() must be called first to allocate the internal state
+   and to initialize the state with the user-provided window buffer.
+   inflateBack() may then be used multiple times to inflate a complete, raw
+   deflate stream with each call.  inflateBackEnd() is then called to free
+   the allocated state.
+
+     A raw deflate stream is one with no zlib or gzip header or trailer.
+   This routine would normally be used in a utility that reads zip or gzip
+   files and writes out uncompressed files.  The utility would decode the
+   header and process the trailer on its own, hence this routine expects
+   only the raw deflate stream to decompress.  This is different from the
+   normal behavior of inflate(), which expects either a zlib or gzip header and
+   trailer around the deflate stream.
+
+     inflateBack() uses two subroutines supplied by the caller that are then
+   called by inflateBack() for input and output.  inflateBack() calls those
+   routines until it reads a complete deflate stream and writes out all of the
+   uncompressed data, or until it encounters an error.  The function's
+   parameters and return types are defined above in the in_func and out_func
+   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the
+   number of bytes of provided input, and a pointer to that input in buf.  If
+   there is no input available, in() must return zero--buf is ignored in that
+   case--and inflateBack() will return a buffer error.  inflateBack() will call
+   out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].  out()
+   should return zero on success, or non-zero on failure.  If out() returns
+   non-zero, inflateBack() will return with an error.  Neither in() nor out()
+   are permitted to change the contents of the window provided to
+   inflateBackInit(), which is also the buffer that out() uses to write from.
+   The length written by out() will be at most the window size.  Any non-zero
+   amount of input may be provided by in().
+
+     For convenience, inflateBack() can be provided input on the first call by
+   setting strm->next_in and strm->avail_in.  If that input is exhausted, then
+   in() will be called.  Therefore strm->next_in must be initialized before
+   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called
+   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in
+   must also be initialized, and then if strm->avail_in is not zero, input will
+   initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+     The in_desc and out_desc parameters of inflateBack() is passed as the
+   first parameter of in() and out() respectively when they are called.  These
+   descriptors can be optionally used to pass any information that the caller-
+   supplied in() and out() functions need to do their job.
+
+     On return, inflateBack() will set strm->next_in and strm->avail_in to
+   pass back any unused input that was provided by the last in() call.  The
+   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+   if in() or out() returned an error, Z_DATA_ERROR if there was a format
+   error in the deflate stream (in which case strm->msg is set to indicate the
+   nature of the error), or Z_STREAM_ERROR if the stream was not properly
+   initialized.  In the case of Z_BUF_ERROR, an input or output error can be
+   distinguished using strm->next_in which will be Z_NULL only if in() returned
+   an error.  If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
+   out() returning non-zero.  (in() will always be called before out(), so
+   strm->next_in is assured to be defined if out() returns non-zero.)  Note
+   that inflateBack() cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+     All memory allocated by inflateBackInit() is freed.
+
+     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+   state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+     1.0: size of uInt
+     3.2: size of uLong
+     5.4: size of voidpf (pointer)
+     7.6: size of z_off_t
+
+    Compiler, assembler, and debug options:
+     8: DEBUG
+     9: ASMV or ASMINF -- use ASM code
+     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+     11: 0 (reserved)
+
+    One-time table building (smaller code, but not thread-safe if true):
+     12: BUILDFIXED -- build static block decoding tables when needed
+     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+     14,15: 0 (reserved)
+
+    Library content (indicates missing functionality):
+     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+                          deflate code when not needed)
+     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+                    and decode gzip streams (to avoid linking crc code)
+     18-19: 0 (reserved)
+
+    Operation variations (changes in library functionality):
+     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+     21: FASTEST -- deflate algorithm with only one, lowest compression level
+     22,23: 0 (reserved)
+
+    The sprintf variant used by gzprintf (zero is best):
+     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+     26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+    Remainder:
+     27-31: 0 (reserved)
+ */
+
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the
+   basic stream-oriented functions. To simplify the interface, some
+   default options are assumed (compression level and memory usage,
+   standard memory allocation functions). The source code of these
+   utility functions can easily be modified if you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
+                                 const Bytef *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be at least the value returned
+   by compressBound(sourceLen). Upon exit, destLen is the actual size of the
+   compressed buffer.
+     This function can be used to compress a whole file at once if the
+   input file is mmap'ed.
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
+                                  const Bytef *source, uLong sourceLen,
+                                  int level));
+/*
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least the value returned by
+   compressBound(sourceLen). Upon exit, destLen is the actual size of the
+   compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+     compressBound() returns an upper bound on the compressed size after
+   compress() or compress2() on sourceLen bytes.  It would be used before
+   a compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+                                   const Bytef *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+*/
+
+
+typedef voidp gzFile;
+
+ZEXTERN gzFile ZEXPORT gzopen  OF((const char *path, const char *mode));
+/*
+     Opens a gzip (.gz) file for reading or writing. The mode parameter
+   is as in fopen ("rb" or "wb") but can also include a compression level
+   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+   Huffman only compression as in "wb1h", or 'R' for run-length encoding
+   as in "wb1R". (See the description of deflateInit2 for more information
+   about the strategy parameter.)
+
+     gzopen can be used to read a file which is not in gzip format; in this
+   case gzread will directly read from the file without decompression.
+
+     gzopen returns NULL if the file could not be opened or if there was
+   insufficient memory to allocate the (de)compression state; errno
+   can be checked to distinguish the two cases (if errno is zero, the
+   zlib error is Z_MEM_ERROR).  */
+
+ZEXTERN gzFile ZEXPORT gzdopen  OF((int fd, const char *mode));
+/*
+     gzdopen() associates a gzFile with the file descriptor fd.  File
+   descriptors are obtained from calls like open, dup, creat, pipe or
+   fileno (in the file has been previously opened with fopen).
+   The mode parameter is as in gzopen.
+     The next call of gzclose on the returned gzFile will also close the
+   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+     gzdopen returns NULL if there was insufficient memory to allocate
+   the (de)compression state.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+     Dynamically update the compression level or strategy. See the description
+   of deflateInit2 for the meaning of these parameters.
+     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+   opened for writing.
+*/
+
+ZEXTERN int ZEXPORT    gzread  OF((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.
+   If the input file was not in gzip format, gzread copies the given number
+   of bytes into the buffer.
+     gzread returns the number of uncompressed bytes actually read (0 for
+   end of file, -1 for error). */
+
+ZEXTERN int ZEXPORT    gzwrite OF((gzFile file,
+                                   voidpc buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes actually written
+   (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA   gzprintf OF((gzFile file, const char *format, ...));
+/*
+     Converts, formats, and writes the args to the compressed file under
+   control of the format string, as in fprintf. gzprintf returns the number of
+   uncompressed bytes actually written (0 in case of error).  The number of
+   uncompressed bytes written is limited to 4095. The caller should assure that
+   this limit is not exceeded. If it is exceeded, then gzprintf() will return
+   return an error (0) with nothing written. In this case, there may also be a
+   buffer overflow with unpredictable consequences, which is possible only if
+   zlib was compiled with the insecure functions sprintf() or vsprintf()
+   because the secure snprintf() or vsnprintf() functions were not available.
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+      Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+      gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+      Reads bytes from the compressed file until len-1 characters are read, or
+   a newline character is read and transferred to buf, or an end-of-file
+   condition is encountered.  The string is then terminated with a null
+   character.
+      gzgets returns buf, or Z_NULL in case of error.
+*/
+
+ZEXTERN int ZEXPORT    gzputc OF((gzFile file, int c));
+/*
+      Writes c, converted to an unsigned char, into the compressed file.
+   gzputc returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT    gzgetc OF((gzFile file));
+/*
+      Reads one byte from the compressed file. gzgetc returns this byte
+   or -1 in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT    gzungetc OF((int c, gzFile file));
+/*
+      Push one character back onto the stream to be read again later.
+   Only one character of push-back is allowed.  gzungetc() returns the
+   character pushed, or -1 on failure.  gzungetc() will fail if a
+   character has been pushed but not read yet, or if c is -1. The pushed
+   character will be discarded if the stream is repositioned with gzseek()
+   or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT    gzflush OF((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file. The parameter
+   flush is as in the deflate() function. The return value is the zlib
+   error number (see function gzerror below). gzflush returns Z_OK if
+   the flush parameter is Z_FINISH and all output could be flushed.
+     gzflush should be called only when strictly necessary because it can
+   degrade compression.
+*/
+
+ZEXTERN z_off_t ZEXPORT    gzseek OF((gzFile file,
+                                      z_off_t offset, int whence));
+/*
+      Sets the starting position for the next gzread or gzwrite on the
+   given compressed file. The offset represents a number of bytes in the
+   uncompressed data stream. The whence parameter is defined as in lseek(2);
+   the value SEEK_END is not supported.
+     If the file is opened for reading, this function is emulated but can be
+   extremely slow. If the file is opened for writing, only forward seeks are
+   supported; gzseek then compresses a sequence of zeroes up to the new
+   starting position.
+
+      gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error, in
+   particular if the file is opened for writing and the new starting position
+   would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
+/*
+     Rewinds the given file. This function is supported only for reading.
+
+   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
+/*
+     Returns the starting position for the next gzread or gzwrite on the
+   given compressed file. This position represents a number of bytes in the
+   uncompressed data stream.
+
+   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+     Returns 1 when EOF has previously been detected reading the given
+   input stream, otherwise zero.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+     Returns 1 if file is being read directly without decompression, otherwise
+   zero.
+*/
+
+ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file
+   and deallocates all the (de)compression state. The return value is the zlib
+   error number (see function gzerror below).
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the
+   given compressed file. errnum is set to zlib error number. If an
+   error occurred in the file system and not in the compression library,
+   errnum is set to Z_ERRNO and the application may consult errno
+   to get the exact error code.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+     Clears the error and end-of-file flags for file. This is analogous to the
+   clearerr() function in stdio. This is useful for continuing to read a gzip
+   file that is being written concurrently.
+*/
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the
+   compression library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum. If buf is NULL, this function returns
+   the required initial value for the checksum.
+   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster. Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+                                          z_off_t len2));
+/*
+     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
+   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of
+   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+*/
+
+ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running CRC-32 with the bytes buf[0..len-1] and return the
+   updated CRC-32. If buf is NULL, this function returns the required initial
+   value for the for the crc. Pre- and post-conditioning (one's complement) is
+   performed within this function so it shouldn't be done by the application.
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+/*
+     Combine two CRC-32 check values into one.  For two sequences of bytes,
+   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32
+   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+   len2.
+*/
+
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                      int windowBits, int memLevel,
+                                      int strategy, const char *version,
+                                      int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+                                         unsigned char FAR *window,
+                                         const char *version,
+                                         int stream_size));
+#define deflateInit(strm, level) \
+        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+        inflateBackInit_((strm), (windowBits), (window), \
+        ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+    struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char   * ZEXPORT zError           OF((int));
+ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/ndk/build/toolchains/archive/toolchain/sources.txt b/ndk/build/toolchains/archive/toolchain/sources.txt
new file mode 100644
index 0000000..c59d51a
--- /dev/null
+++ b/ndk/build/toolchains/archive/toolchain/sources.txt
@@ -0,0 +1,3 @@
+android-ndk-toolchain-20090323.tar.bz2
+d56abac4df36271ae0c961d21d0847db
+http://android.git.kernel.org/pub/android-ndk-toolchain-20090323.tar.bz2
diff --git a/ndk/build/toolchains/arm-eabi-4.2.1/config.mk b/ndk/build/toolchains/arm-eabi-4.2.1/config.mk
new file mode 100644
index 0000000..1b5cf02
--- /dev/null
+++ b/ndk/build/toolchains/arm-eabi-4.2.1/config.mk
@@ -0,0 +1,19 @@
+# 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.
+#
+
+# config file for the arm-eabi-4.2.1 toolchain for the Android NDK
+# the real meat is in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ABIS := arm
diff --git a/ndk/build/toolchains/arm-eabi-4.2.1/setup.mk b/ndk/build/toolchains/arm-eabi-4.2.1/setup.mk
new file mode 100644
index 0000000..4c10c07
--- /dev/null
+++ b/ndk/build/toolchains/arm-eabi-4.2.1/setup.mk
@@ -0,0 +1,122 @@
+# 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 prepare the NDK to build with the arm-eabi-4.2.1
+# toolchain any number of source files
+#
+# its purpose is to define (or re-define) templates used to build
+# various sources into target object files, libraries or executables.
+#
+# Note that this file may end up being parsed several times in future
+# revisions of the NDK.
+#
+
+TOOLCHAIN_NAME   := arm-eabi-4.2.1
+TOOLCHAIN_PREFIX := $(HOST_PREBUILT)/$(TOOLCHAIN_NAME)/bin/arm-eabi-
+
+TARGET_CFLAGS.common := \
+    -I$(SYSROOT)/usr/include \
+    -march=armv5te -mtune=xscale \
+    -msoft-float -fpic \
+    -mthumb-interwork \
+    -ffunction-sections \
+    -funwind-tables \
+    -fstack-protector \
+    -fno-short-enums \
+    -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ \
+    -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ \
+
+
+TARGET_arm_release_CFLAGS :=  -O2 \
+                              -fomit-frame-pointer \
+                              -fstrict-aliasing    \
+                              -funswitch-loops     \
+                              -finline-limit=300
+
+TARGET_thumb_release_CFLAGS := -mthumb \
+                               -Os \
+                               -fomit-frame-pointer \
+                               -fno-strict-aliasing \
+                               -finline-limit=64
+
+# When building for debug, compile everything as arm.
+TARGET_arm_debug_CFLAGS := $(TARGET_arm_release_CFLAGS) \
+                           -fno-omit-frame-pointer \
+                           -fno-strict-aliasing
+
+TARGET_thumb_debug_CFLAGS := $(TARGET_thumb_release_CFLAGS) \
+                             -marm \
+                             -fno-omit-frame-pointer
+
+TARGET_CC       := $(TOOLCHAIN_PREFIX)gcc
+TARGET_CFLAGS   := $(TARGET_CFLAGS.common)
+
+
+TARGET_CXX      := $(TOOLCHAIN_PREFIX)g++
+TARGET_CXXFLAGS := $(TARGET_CFLAGS.common) -fno-exceptions -fno-rtti
+
+TARGET_LD      := $(TOOLCHAIN_PREFIX)ld
+TARGET_LDFLAGS :=
+
+TARGET_AR      := $(TOOLCHAIN_PREFIX)ar
+TARGET_ARFLAGS := crs
+
+TARGET_LIBGCC := $(shell $(TARGET_CC) -mthumb-interwork -print-libgcc-file-name)
+TARGET_LDLIBS := -Wl,-rpath-link=$(SYSROOT)/usr/lib $(TARGET_LIBGCC)
+
+# These flags are used to ensure that a binary doesn't reference undefined
+# flags.
+TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
+
+# The ABI-specific sub-directory that the SDK tools recognize for
+# this toolchain's generated binaries
+TARGET_ABI_SUBDIR := armeabi
+
+define cmd-build-shared-library
+$(TARGET_CC) \
+    -nostdlib -Wl,-soname,$(notdir $@) \
+    -Wl,-shared,-Bsymbolic \
+    $(PRIVATE_OBJECTS) \
+    -Wl,--whole-archive \
+    $(PRIVATE_WHOLE_STATIC_LIBRARIES) \
+    -Wl,--no-whole-archive \
+    $(PRIVATE_STATIC_LIBRARIES) \
+    $(PRIVATE_SHARED_LIBRARIES) \
+    $(PRIVATE_LDFLAGS) \
+    $(PRIVATE_LDLIBS) \
+    -o $@
+endef
+
+define cmd-build-executable
+$(TARGET_CC) \
+    -nostdlib -Bdynamic \
+    -Wl,-dynamic-linker,/system/bin/linker \
+    -Wl,--gc-sections \
+    -Wl,-z,nocopyreloc \
+    $(PRIVATE_SHARED_LIBRARIES) \
+    $(TARGET_CRTBEGIN_DYNAMIC_O) \
+    $(PRIVATE_OBJECTS) \
+    $(PRIVATE_STATIC_LIBRARIES) \
+    $(PRIVATE_LDFLAGS) \
+    $(PRIVATE_LDLIBS) \
+    $(TARGET_CRTEND_O) \
+    -o $@
+endef
+
+define cmd-build-static-library
+$(TARGET_AR) $(TARGET_ARFLAGS) $@ $(PRIVATE_OBJECTS)
+endef
+
+cmd-strip = $(TOOLCHAIN_PREFIX)strip --strip-debug $1
diff --git a/ndk/build/tools/build-ndk-sysroot.sh b/ndk/build/tools/build-ndk-sysroot.sh
new file mode 100755
index 0000000..7a79e92
--- /dev/null
+++ b/ndk/build/tools/build-ndk-sysroot.sh
@@ -0,0 +1,280 @@
+#!/bin/sh
+#
+# 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.
+#
+# build-ndk-sysroot.sh
+#
+# collect files from an Android tree to assemble a sysroot suitable for
+# building a standable toolchain.
+#
+# after that, you may use build/tools/package-ndk-sysroot.sh to package
+# the resulting files for distribution.
+#
+# NOTE: this is different from the Android toolchain original build-sysroot.sh
+#       script because we place target files differently.
+#
+# WARNING: For now, only a single target ABI/Architecture us supported
+#
+
+source `dirname $0`/../core/ndk-common.sh
+
+# PLATFORM is the name of the current Android system platform
+PLATFORM=android-1.5
+
+# ABI is the target ABI name for the NDK
+ABI=arm
+
+# ARCH is the target ABI name in the Android sources
+ARCH=arm
+
+OPTION_HELP=no
+OPTION_BUILD_OUT=
+OPTION_PLATFORM=
+OPTION_PACKAGE=no
+for opt do
+  optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
+  case "$opt" in
+  --help|-h|-\?) OPTION_HELP=yes
+  ;;
+  --verbose)
+    if [ "$VERBOSE" = "yes" ] ; then
+        VERBOSE2=yes
+    else
+        VERBOSE=yes
+    fi
+    ;;
+  --platform=*)
+    OPTION_PLATFORM=$optarg
+    ;;
+  --build-out=*)
+    OPTION_BUILD_OUT=$optarg
+    ;;
+  --package)
+    OPTION_PACKAGE=yes
+    ;;
+  *)
+    echo "unknown option '$opt', use --help"
+    exit 1
+  esac
+done
+
+if [ $OPTION_HELP = "yes" ] ; then
+    echo "Collect files from an Android build tree and assembles a sysroot"
+    echo "suitable for building a standalone toolchain or be used by the"
+    echo "Android NDK."
+    echo ""
+    echo "options:"
+    echo ""
+    echo "  --help             print this message"
+    echo "  --verbose          enable verbose messages"
+    echo "  --platform=<name>  generate sysroot for platform <name> (default is $PLATFORM)"
+    echo "  --build-out=<path> set Android build out directory"
+    echo "  --package          generate sysroot package tarball"
+    echo ""
+    exit 0
+fi
+
+if [ -n "$OPTION_PLATFORM" ] ; then
+    PLATFORM=$OPTION_PLATFORM
+fi
+
+# Get the root of the NDK from the current program location
+NDK_ROOT=`dirname $0`
+NDK_ROOT=`dirname $NDK_ROOT`
+NDK_ROOT=`dirname $NDK_ROOT`
+
+# Get the Android out directory
+if [ -z "$OPTION_BUILD_OUT" ] ; then
+    if [ -z "$ANDROID_PRODUCT_OUT" ] ; then
+        echo "ANDROID_PRODUCT_OUT is not defined in your environment. Aborting"
+        exit 1
+    fi
+    if [ ! -d $ANDROID_PRODUCT_OUT ] ; then
+        echo "ANDROID_PRODUCT_OUT does not point to a valid directory. Aborting"
+        exit 1
+    fi
+else
+    ANDROID_PRODUCT_OUT=$OPTION_BUILD_OUT
+    if [ ! -d $ANDROID_PRODUCT_OUT ] ; then
+        echo "The build out path is not a valid directory: $OPTION_BUILD_OUT"
+        exit 1
+    fi
+fi
+
+PRODUCT_DIR=$ANDROID_PRODUCT_OUT
+SYSROOT=$NDK_ROOT/build/platforms/$PLATFORM/arch-$ABI
+COMMON_ROOT=$NDK_ROOT/build/platforms/$PLATFORM/common
+
+# clean up everything in existing sysroot
+rm -rf $SYSROOT
+mkdir -p $SYSROOT
+
+rm -rf $COMMON_ROOT
+mkdir -p $COMMON_ROOT
+
+LIB_ROOT=$SYSROOT/usr/lib
+INCLUDE_ROOT=$SYSROOT/usr/include
+
+install_file ()
+{
+    mkdir -p $2/`dirname $1`
+    cp -fp $1 $2/$1
+}
+
+install_helper ()
+{
+  (cd $1 && find . -type f | while read ff; do install_file $ff $2; done)
+}
+
+TOP=$PRODUCT_DIR/../../../..
+
+# CRT objects that need to be copied
+CRT_OBJS_DIR=$PRODUCT_DIR/obj/lib
+CRT_OBJS="$CRT_OBJS_DIR/crtbegin_static.o \
+$CRT_OBJS_DIR/crtbegin_dynamic.o \
+$CRT_OBJS_DIR/crtend_android.o"
+
+# static libraries that need to be copied.
+STATIC_LIBS_DIR=$PRODUCT_DIR/obj/STATIC_LIBRARIES
+STATIC_LIBS="$STATIC_LIBS_DIR/libc_intermediates/libc.a \
+$STATIC_LIBS_DIR/libm_intermediates/libm.a \
+$STATIC_LIBS_DIR/libstdc++_intermediates/libstdc++.a
+$STATIC_LIBS_DIR/libthread_db_intermediates/libthread_db.a"
+
+# dynamic libraries that need to be copied.
+DYNAMIC_LIBS_DIR=$PRODUCT_DIR/symbols/system/lib
+DYNAMIC_LIBS="$DYNAMIC_LIBS_DIR/libdl.so \
+$DYNAMIC_LIBS_DIR/libc.so \
+$DYNAMIC_LIBS_DIR/libm.so \
+$DYNAMIC_LIBS_DIR/libstdc++.so \
+$DYNAMIC_LIBS_DIR/libthread_db.so"
+
+# Copy all CRT objects and libraries
+rm -rf $LIB_ROOT
+mkdir -p $LIB_ROOT
+cp -f $CRT_OBJS $STATIC_LIBS $DYNAMIC_LIBS $LIB_ROOT
+
+# Check $TOP/bionic to see if this is new source layout.
+if [ -d $TOP/bionic ] ;then
+  BIONIC_ROOT=$TOP/bionic
+  LIBC_ROOT=$BIONIC_ROOT/libc
+else
+  BIONIC_ROOT=$TOP/system
+  LIBC_ROOT=$BIONIC_ROOT/bionic
+fi
+
+# Copy headers.  This need to be done in the reverse order of inclusion
+# in case there are different headers with the same name.
+ARCH_INCLUDE=$SYSROOT/usr/include
+rm -rf $ARCH_INCLUDE
+mkdir -p $ARCH_INCLUDE
+
+COMMON_INCLUDE=$COMMON_ROOT/include
+rm -rf $COMMON_INCLUDE
+mkdir -p $COMMON_INCLUDE
+
+# Install a common header and create the appropriate arch-specific
+# directory for it.
+#
+# $1: source directory
+# $2: header path, relative to source directory
+#
+common_header ()
+{
+    echo "Copy: $COMMON_INCLUDE/$2"
+    mkdir -p `dirname $COMMON_INCLUDE/$2`
+    install $1/$2 $COMMON_INCLUDE/$2
+    # just to be safe
+    chmod a-x $COMMON_INCLUDE/$2
+
+    # the link prefix, used to point to common/
+    # from arch-$ARCH/usr/
+    link_prefix=../../common/include
+
+    # we need to count the number of directory separators in $2
+    # for each one of them, we're going to prepend ../ to the
+    # link prefix
+    for item in `echo $2 | tr '/' ' '`; do
+        link_prefix=../$link_prefix
+    done
+
+    echo "Link: $ARCH_INCLUDE/$2"
+    mkdir -p `dirname $ARCH_INCLUDE/$2`
+    ln -s $link_prefix/$2 $ARCH_INCLUDE/$2
+}
+
+common_headers ()
+{
+    srcs=`cd $1 && find . -type f`
+    # remove leading ./
+    srcs=`echo $srcs | sed -e "s%\./%%g"`
+
+    for src in $srcs; do
+        common_header $1 $src
+    done
+}
+
+arch_header ()
+{
+    echo "Copy: $ARCH_INCLUDE/$2"
+    mkdir -p `dirname $ARCH_INCLUDE/$2`
+    install $1/$2 $ARCH_INCLUDE/$2
+    # just to be safe
+    chmod a-x $ARCH_INCLUDE/$2
+}
+
+arch_headers ()
+{
+    srcs=`cd $1 && find . -type f`
+    # remove leading ./
+    srcs=`echo $srcs | sed -e "s%\./%%g"`
+
+    for src in $srcs; do
+        arch_header $1 $src
+    done
+}
+
+# ZLib headers
+common_header  $TOP/external/zlib zlib.h
+common_header  $TOP/external/zlib zconf.h
+
+# Jni header
+common_header  $TOP/dalvik/libnativehelper/include/nativehelper jni.h
+
+# libthread_db headers, not sure if this is needed for the NDK
+common_headers $BIONIC_ROOT/libthread_db/include
+
+# for libm, just copy math.h and fenv.h
+common_header $BIONIC_ROOT/libm/include math.h
+arch_header   $BIONIC_ROOT/libm/include $ARCH/fenv.h
+
+# our tiny C++ standard library
+common_headers $BIONIC_ROOT/libstdc++/include
+
+# C library kernel headers
+common_headers $LIBC_ROOT/kernel/common
+arch_headers   $LIBC_ROOT/kernel/arch-arm
+
+# C library headers
+common_headers $LIBC_ROOT/include
+arch_headers   $LIBC_ROOT/arch-$ARCH/include
+
+# Do we need to package the result
+if [ $OPTION_PACKAGE = yes ] ; then
+    DATE=`date +%Y%m%d`
+    PKGFILE=/tmp/android-ndk-sysroot-$DATE.tar.bz2
+    tar cjf $PKGFILE build/platforms/$PLATFORM
+    echo "Packaged in $PKGFILE"
+fi
diff --git a/ndk/build/tools/build-toolchain.sh b/ndk/build/tools/build-toolchain.sh
new file mode 100755
index 0000000..42f7276
--- /dev/null
+++ b/ndk/build/tools/build-toolchain.sh
@@ -0,0 +1,494 @@
+#!/bin/sh
+#
+# 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 shell script is used to rebuild the Android NDK's prebuilt binaries.
+#
+#  The source tarballs must be located in $ANDROID_NDK_ROOT/build/archive
+#  They will be located in $ANDROID_NDK_ROOT/build/toolchain after compilation
+#
+
+# include common function and variable definitions
+source `dirname $0`/../core/ndk-common.sh
+
+# number of jobs to run in parallel when running make
+JOBS=$HOST_NUM_CPUS
+
+TOOLCHAIN_NAME=arm-eabi-4.2.1
+PLATFORM=android-1.5
+ABI=arm
+
+OPTION_HELP=no
+OPTION_PLATFORM=
+OPTION_FORCE_32=no
+OPTION_REBUILD=no
+
+VERBOSE=no
+for opt do
+  optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
+  case "$opt" in
+  --help|-h|-\?) OPTION_HELP=yes
+  ;;
+  --verbose)
+    if [ "$VERBOSE" = "yes" ] ; then
+        VERBOSE2=yes
+    else
+        VERBOSE=yes
+    fi
+    ;;
+  --toolchain=*)
+    TOOLCHAIN_NAME=$optarg
+    ;;
+  --platform=*)
+    PLATFORM=$optarg
+    ;;
+  --abi=*)
+    ABI=$optarg
+    ;;
+  --force-download)
+    OPTION_FORCE_DOWNLOAD=yes
+    OPTION_FORCE_BUILD=yes
+    ;;
+  --force-build)
+    OPTION_FORCE_BUILD=yes
+    ;;
+  --verbose)
+    VERBOSE=yes
+    ;;
+  *)
+    echo "unknown option '$opt', use --help"
+    exit 1
+  esac
+done
+
+if [ $OPTION_HELP = "yes" ] ; then
+    echo "Rebuild the prebuilt binaries for the Android NDK toolchain."
+    echo ""
+    echo "options:"
+    echo ""
+    echo "  --help             print this message"
+    echo "  --toolchain=<name> toolchain name (default is $TOOLCHAIN_NAME)"
+    echo "  --platform=<name>  generate toolchain from platform <name> (default is $PLATFORM)"
+    echo "  --abi=<name>       generate toolchain from abi <name> (default is $ABI)"
+    echo "  --build-out=<path> set Android build out directory"
+    echo "  --force-download   force a download and unpacking of the toolchain sources"
+    echo "  --force-build      force a rebuild of the sources"
+    echo ""
+    exit 0
+fi
+
+# Force generation of 32-bit binaries on 64-bit systems
+case $HOST_TAG in
+    *-x86_64)
+        HOST_CFLAGS="$HOST_CFLAGS -m32"
+        HOST_LDFLAGS="$HOST_LDFLAGS -m32"
+        force_32bit_binaries  # to modify HOST_TAG and others
+        ;;
+esac
+
+TMPLOG=/tmp/android-toolchain-build-$$.log
+rm -rf $TMPLOG
+
+if [ $VERBOSE = yes ] ; then
+    run ()
+    {
+        echo "##### NEW COMMAND"
+        echo $@
+        $@ 2>&1 | tee $TMPLOG
+    }
+else
+    echo "To follow build long, please use in another terminal: tail -F $TMPLOG"
+    run ()
+    {
+        echo "##### NEW COMMAND" >> $TMPLOG
+        echo "$@" >> $TMPLOG
+        $@ 1>$TMPLOG 2>&1
+    }
+fi
+
+ANDROID_NDK_ROOT=`cd $ANDROID_NDK_ROOT && pwd`
+ANDROID_NDK_ARCHIVE=$ANDROID_NDK_ROOT/build/toolchains/archive
+ANDROID_PLATFORMS_ROOT=$ANDROID_NDK_ROOT/build/platforms
+
+# where all generated files will be placed
+OUT=$ANDROID_NDK_ROOT/out/$TOOLCHAIN_NAME
+PACKAGE_OUT=$OUT/packages
+TIMESTAMP_OUT=$OUT/timestamps
+
+# where the sysroot is located
+ANDROID_SYSROOT=$ANDROID_NDK_ROOT/build/platforms/$PLATFORM/arch-$ABI
+
+# where the toolchain binaries will be placed
+ANDROID_TOOLCHAIN_OUT=$OUT/toolchain
+ANDROID_TOOLCHAIN_SRC=$ANDROID_TOOLCHAIN_OUT/src
+ANDROID_TOOLCHAIN_BUILD=$ANDROID_TOOLCHAIN_OUT/build
+
+# where the gdbserver binaries will be placed
+ANDROID_GDBSERVER_OUT=$OUT/gdbserver
+ANDROID_GDBSERVER_BUILD=$ANDROID_GDBSERVER_OUT/build
+ANDROID_GDBSERVER_DEST=$ANDROID_SYSROOT/usr/bin
+
+# Let's check that we have a working md5sum here
+A_MD5=`echo "A" | md5sum | cut -d' ' -f1`
+if [ "$A_MD5" != "bf072e9119077b4e76437a93986787ef" ] ; then
+    echo "Please install md5sum on this machine"
+    exit 2
+fi
+
+# And wget too
+WGET=`which wget`
+CURL=`which curl`
+SCP=`which scp`
+
+# download a file with either 'curl', 'wget' or 'scp'
+# $1: source
+# $2: target
+download_file ()
+{
+    # is this HTTP, HTTPS or FTP ?
+    echo $1 | grep -q -e "^\(http\|https\):.*"
+    if [ $? = 0 ] ; then
+        if [ -n "$WGET" ] ; then
+            $WGET -O $2 $1 
+        elif [ -n "$CURL" ] ; then
+            $CURL -o $2 $1
+        else
+            echo "Please install wget or curl on this machine"
+            exit 1
+        fi
+        return
+    fi
+
+    # is this SSH ?
+    echo $1 | grep -q -e "^ssh:.*"
+    if [ $? = 0 ] ; then
+        if [ -n "$SCP" ] ; then
+            scp_src=`echo $1 | sed -e s%ssh://%%g`
+            $SCP $scp_src $2
+        else
+            echo "Please install scp on this machine"
+            exit 1
+        fi
+        return
+    fi
+
+    echo $1 | grep -q -e "^/.*"
+    if [ $? = 0 ] ; then
+        cp -f $1 $2
+    fi
+}
+
+TOOLCHAIN_SRC=$ANDROID_TOOLCHAIN_SRC
+TOOLCHAIN_BUILD=$ANDROID_TOOLCHAIN_BUILD
+TOOLCHAIN_PREFIX=$ANDROID_NDK_ROOT/build/prebuilt/$HOST_TAG/$TOOLCHAIN_NAME
+
+GDBSERVER_BUILD=$ANDROID_GDBSERVER_BUILD
+
+timestamp_check ()
+{
+    [ -f $TIMESTAMP_OUT/$1/timestamp-$2 ]
+}
+
+timestamp_set ()
+{
+    mkdir -p $TIMESTAMP_OUT/$1
+    touch $TIMESTAMP_OUT/$1/timestamp-$2
+}
+
+timestamp_clear ()
+{
+    rm -f $TIMESTAMP_OUT/$1/timestamp-*
+}
+
+timestamp_force ()
+{
+    rm -f $TIMESTAMP_OUT/$1/timestamp-$2
+}
+
+# this function will be used to download and verify a toolchain
+# package 
+# $1: directory name under build/archive  (e.g. 'android-toolchain')
+#
+download_package ()
+{
+    WORKSPACE=$ANDROID_NDK_ARCHIVE/$1
+    if [ ! -d $WORKSPACE ] ; then
+        echo "No directory named $1 under $ANDROID_NDK_ARCHIVE"
+        exit 2
+    fi
+    SOURCES=$WORKSPACE/sources.txt
+    if [ ! -f $SOURCES ] ; then
+        echo "Missing sources.txt in $WORKSPACE"
+        exit 2
+    fi
+    # First line must be file name
+    PKGNAME=`cat $SOURCES | sed 1q`
+    # Second line must be md5sum
+    PKGSUM=`cat $SOURCES | sed 1d | sed 1q`
+    if [ -z "$PKGNAME" -o -z "$PKGSUM" ] ; then
+        echo "Corrupted file: $SOURCES"
+        exit 2
+    fi
+
+    # Try to download the package if it is not there
+    # the Third line of sources.txt, and all others behind
+    # must be wget urls or something.
+    PACKAGE_TARBALL=$PACKAGE_OUT/$PKGNAME
+    if [ ! -f $PACKAGE_TARBALL ] ; then
+        cat $SOURCES | sed 1,2d | while read src; do
+            echo $src | grep -q -e "^/.*"
+            if [ $? = 0 ] ; then
+                if [ -f $src ] ; then
+                    echo "Copy    : $PKGNAME"
+                    echo "          from `dirname $src`"
+                    echo "          into $PACKAGE_TARBALL"
+                    run cp -f $src $PACKAGE_TARBALL
+                    if [ $? = 0 ] ; then
+                        break
+                    fi
+                    echo "Copy    : Problem copying from $src"
+                else
+                    echo "Copy    : Can't find $src (skipping)"
+                fi
+                continue
+            fi
+            echo $src | grep -q -e "^\(http\|https\|ftp\|ssh\):.*"
+            if [ $? = 0 ] ; then
+                echo "Download: $PKGNAME"
+                echo "          from $src"
+                echo "          into $PACKAGE_TARBALL"
+                download_file $src $PACKAGE_TARBALL
+                if [ $? = 0 ] ; then
+                    break
+                fi
+                continue
+            else
+                "Copy    : Unknown method in $src"
+            fi
+        done
+        if [ ! -f $PACKAGE_TARBALL ] ; then
+            echo "ERROR: Could not copy or download $PKGNAME !"
+            echo "Your probably need to edit $WORKSPACE/sources.txt"
+            exit 1
+        fi
+    fi
+
+    if ! timestamp_check $1 verify ; then
+        SUM=`md5sum $PACKAGE_TARBALL | cut -d " " -f 1`
+        if [ "$SUM" != "$PKGSUM" ] ; then
+            echo "ERROR: Invalid MD5 Sum for $PACKAGE_TARBALL"
+            echo "    Expected $PKGSUM"
+            echo "    Computed $SUM"
+            echo "You might want to use the --force-download option."
+            exit 2
+        fi
+
+        echo "Verified: $PACKAGE_TARBALL"
+        timestamp_set   $1 verify
+        timestamp_force $1 unpack
+    fi
+    eval PKG_$1=$PACKAGE_TARBALL
+}
+
+# Unpack a given package in a target location
+# $1: package name
+# $2: target directory
+#
+unpack_package ()
+{
+    WORKSPACE=$ANDROID_NDK_ARCHIVE/$1
+    SRCDIR=$2
+    SRCPKG=`var_value PKG_$1`
+    if ! timestamp_check $1 unpack; then
+        echo "Unpack  : $1 sources"
+        echo "          from $SRCPKG"
+        echo "          into $SRCDIR"
+        rm -rf $SRCDIR
+        mkdir -p $SRCDIR
+        TARFLAGS=xjf
+        if [ $VERBOSE = yes ]; then
+          TARFLAGS="v$TARFLAGS"
+        fi
+        run tar $TARFLAGS $SRCPKG -C $SRCDIR
+        if [ $? != 0 ] ; then
+            echo "ERROR: Could not unpack $1, See $TMPLOG"
+            exit 1
+        fi
+        timestamp_set   $1 unpack
+        timestamp_force $1 configure
+    fi
+}
+
+if [ $OPTION_FORCE_DOWNLOAD ] ; then
+    rm -rf $PACKAGE_OUT $ANDROID_TOOLCHAIN_SRC
+    timestamp_force toolchain unpack
+    timestamp_force toolchain verify
+fi
+
+if [ $OPTION_FORCE_BUILD ] ; then
+    rm -rf $ANDROID_TOOLCHAIN_BUILD
+    timestamp_clear toolchain
+    timestamp_clear gdbserver
+fi
+
+# checks, we need more checks..
+mkdir -p $PACKAGE_OUT
+if [ $? != 0 ] ; then
+    echo "Can't create download/archive directory for toolchain tarballs"
+    exit 2
+fi
+
+download_package toolchain
+unpack_package   toolchain $ANDROID_TOOLCHAIN_SRC
+
+# remove all info files from the unpacked toolchain sources
+# they create countless little problems during the build
+# if you don't have exactly the configuration expected by
+# the scripts.
+#
+find $ANDROID_TOOLCHAIN_SRC -type f -a -name "*.info" -print0 | xargs -0 rm -f
+
+# configure the toolchain
+if ! timestamp_check toolchain configure; then
+    echo "Configure: toolchain build"
+    mkdir -p $TOOLCHAIN_BUILD &&
+    cd $TOOLCHAIN_BUILD &&
+    export CFLAGS="$HOST_CFLAGS" &&
+    export LDFLAGS="$HOST_LDFLAGS" && run \
+    $TOOLCHAIN_SRC/configure --target=arm-eabi \
+                             --disable-nls \
+                             --prefix=$TOOLCHAIN_PREFIX \
+                             --with-sysroot=$ANDROID_SYSROOT
+
+    if [ $? != 0 ] ; then
+        echo "Error while trying to configure toolchain build. See $TMPLOG"
+        exit 1
+    fi
+    timestamp_set   toolchain configure
+    timestamp_force toolchain build
+fi
+
+# build the toolchain
+if ! timestamp_check toolchain build ; then
+    echo "Building : toolchain [this can take a long time]."
+    cd $TOOLCHAIN_BUILD &&
+    export CFLAGS="$HOST_CFLAGS" &&
+    export LDFLAGS="$HOST_LDFLAGS" &&
+    run make -j$JOBS
+    if [ $? != 0 ] ; then
+        echo "Error while building toolchain. See $TMPLOG"
+        exit 1
+    fi
+    timestamp_set   toolchain build
+    timestamp_force toolchain install
+fi
+
+# install the toolchain to its final location
+if ! timestamp_check toolchain install ; then
+    echo "Install  : toolchain binaries."
+    cd $TOOLCHAIN_BUILD &&
+    run make install
+    if [ $? != 0 ] ; then
+        echo "Error while installing toolchain. See $TMPLOG"
+        exit 1
+    fi
+    # don't forget to copy the GPL and LGPL license files
+    cp -f $TOOLCHAIN_SRC/COPYING $TOOLCHAIN_SRC/COPYING.LIB $TOOLCHAIN_PREFIX
+    # remove some unneeded files
+    rm -f $TOOLCHAIN_PREFIX/bin/*-gccbug
+    rm -rf $TOOLCHAIN_PREFIX/man $TOOLCHAIN_PREFIX/info
+    # strip binaries to reduce final package size
+    strip $TOOLCHAIN_PREFIX/bin/*
+    strip $TOOLCHAIN_PREFIX/arm-eabi/bin/*
+    strip $TOOLCHAIN_PREFIX/libexec/gcc/*/*/cc1
+    strip $TOOLCHAIN_PREFIX/libexec/gcc/*/*/cc1plus
+    strip $TOOLCHAIN_PREFIX/libexec/gcc/*/*/collect2
+    timestamp_set   toolchain install
+    timestamp_force gdbserver configure
+fi
+
+# configure the gdbserver build now
+if ! timestamp_check gdbserver configure; then
+    echo "Configure: gdbserver build."
+    mkdir -p $GDBSERVER_BUILD
+    cd $GDBSERVER_BUILD &&
+    CFLAGS="-g -O2 -static -mandroid -I$ANDROID_SYSROOT/usr/include" \
+    LDFLAGS= \
+    CC="$TOOLCHAIN_PREFIX/bin/arm-eabi-gcc" \
+    run $TOOLCHAIN_SRC/gdb-6.6/gdb/gdbserver/configure \
+    --host=arm-eabi-linux \
+    --with-sysroot=$ANDROID_SYSROOT
+    if [ $? != 0 ] ; then
+        echo "Could not configure gdbserver build. See $TMPLOG"
+        exit 1
+    fi
+    timestamp_set   gdbserver configure
+    timestamp_force gdbserver build
+fi
+
+# build gdbserver
+if ! timestamp_check gdbserver build; then
+    echo "Building : gdbserver."
+    cd $GDBSERVER_BUILD &&
+    run make -j$JOBS
+    if [ $? != 0 ] ; then
+        echo "Could not build gdbserver. See $TMPLOG"
+        exit 1
+    fi
+    timestamp_set   gdbserver build
+    timestamp_force gdbserver install
+fi
+
+# install gdbserver
+#
+# note that we install it in the toolchain bin directory
+# not in $SYSROOT/usr/bin
+#
+if ! timestamp_check gdbserver install; then
+    echo "Install  : gdbserver."
+    DEST=$TOOLCHAIN_PREFIX/bin
+    mkdir -p $DEST &&
+    $TOOLCHAIN_PREFIX/bin/arm-eabi-strip $GDBSERVER_BUILD/gdbserver &&
+    run cp -f $GDBSERVER_BUILD/gdbserver $DEST/gdbserver
+    if [ $? != 0 ] ; then
+        echo "Could not install gdbserver. See $TMPLOG"
+        exit 1
+    fi
+    timestamp_set   gdbserver install
+    timestamp_force package toolchain
+fi
+
+# package the toolchain
+TOOLCHAIN_TARBALL=/tmp/prebuilt-$TOOLCHAIN_NAME-$HOST_TAG.tar.bz2
+if ! timestamp_check package toolchain; then
+    echo "Package  : $HOST_ARCH toolchain binaries"
+    echo "           into $TOOLCHAIN_TARBALL"
+    cd $ANDROID_NDK_ROOT &&
+    TARFLAGS="cjf"
+    if [ $VERBOSE = yes ] ; then
+      TARFLAGS="v$TARFLAGS"
+    fi
+    run tar $TARFLAGS $TOOLCHAIN_TARBALL build/prebuilt/$HOST_TAG/$TOOLCHAIN_NAME
+    if [ $? != 0 ] ; then
+        echo "ERROR: Cannot package prebuilt toolchain binaries. See $TMPLOG"
+        exit 1
+    fi
+    timestamp_set package toolchain
+else
+    echo "prebuilt toolchain is in $TOOLCHAIN_TARBALL"
+fi
+
+echo "Done."
+rm -f $TMPLOG
diff --git a/ndk/build/tools/make-release.sh b/ndk/build/tools/make-release.sh
new file mode 100755
index 0000000..a599124
--- /dev/null
+++ b/ndk/build/tools/make-release.sh
@@ -0,0 +1,168 @@
+#!/bin/sh
+#
+# This script is used to build complete Android NDK release packages
+# from the git repository and a set of prebuilt cross-toolchain tarballs
+#
+
+# location of the root ndk directory. we assume this script is under build/tools
+NDK_ROOT_DIR=`dirname $0`/../..
+NDK_ROOT_DIR=`cd $NDK_ROOT_DIR && pwd`
+
+# the release name
+RELEASE=1.5_r1
+
+# the package prefix
+PREFIX=android-ndk
+
+# the directory containing the prebuilt toolchain tarballs
+PREBUILT_DIR=
+
+# the prefix of prebuilt toolchain tarballs in $PREBUILT_DIR
+PREBUILT_PREFIX=android-ndk-prebuilt-20090323
+
+# the list of supported host development systems
+PREBUILT_SYSTEMS="linux-x86 darwin-x86 windows"
+
+
+OPTION_HELP=no
+
+for opt do
+  optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
+  case "$opt" in
+  --help|-h|-\?) OPTION_HELP=yes
+  ;;
+  --verbose)
+    if [ "$VERBOSE" = "yes" ] ; then
+        VERBOSE2=yes
+    else
+        VERBOSE=yes
+    fi
+  ;;
+  --release=*) RELEASE=$optarg
+  ;;
+  --prefix=*) PREFIX=$optarg
+  ;;
+  --prebuilt-prefix=*) PREBUILT_PREFIX=$optarg
+  ;;
+  --prebuilt-path=*) PREBUILT_DIR=$optarg
+  ;;
+  --systems=*) PREBUILT_SYSTEMS=$optarg
+  ;;
+  *)
+    echo "unknown option '$opt', use --help"
+    exit 1
+  esac
+done
+
+if [ $OPTION_HELP = yes ] ; then
+    echo "Usage: make-release.sh [options]"
+    echo ""
+    echo "Package a new set of release packages for the Android NDK."
+    echo "You will need to specify the path of a directory containing"
+    echo "prebuilt toolchain tarballs with the --prebuilt-path option."
+    echo ""
+    echo "Options: [defaults in brackets after descriptions]"
+    echo ""
+    echo "  --help                    Print this help message"
+    echo "  --prefix=PREFIX           Package prefix name [$PREFIX]"
+    echo "  --release=NAME            Specify release name [$RELEASE]"
+    echo "  --systems=SYSTEMS         List of host system packages [$PREBUILT_SYSTEMS]"
+    echo "  --prebuilt-path=PATH      Location of prebuilt binary tarballs [$PREBUILT_DIR]"
+    echo "  --prebuilt-prefix=PREFIX  Prefix of prebuilt binary tarballs [$PREBUILT_PREFIX]"
+    echo ""
+    exit 1
+fi
+
+# Check the prebuilt path
+#
+if [ -z "$PREBUILT_DIR" ] ; then
+    echo "ERROR: You must use --prebuilt-path=PATH to specify the path of prebuilt binary tarballs."
+    exit 1
+fi
+
+if [ ! -d "$PREBUILT_DIR" ] ; then
+    echo "ERROR: the --prebuilt-path argument is not a directory path: $PREBUILT_DIR"
+    exit 1
+fi
+
+# Check the systems
+#
+if [ -z "$PREBUILT_SYSTEMS" ] ; then
+    echo "ERROR: Your systems list is empty, use --system=LIST to specify a different one."
+    exit 1
+fi
+
+if [ -z "$PREBUILT_PREFIX" ] ; then
+    echo "ERROR: Your prebuilt prefix is empty; use --prebuilt-prefix=PREFIX."
+    exit 1
+fi
+
+for SYS in $PREBUILT_SYSTEMS; do
+    if [ ! -f $PREBUILT_DIR/$PREBUILT_PREFIX-$SYS.tar.bz2 ] ; then
+        echo "ERROR: It seems there is no prebuilt binary tarball for the '$SYS' system"
+        echo "Please check the content of $PREBUILT_DIR for a file named $PREBUILT_PREFIX-$SYS.tar.bz2."
+        exit 1
+    fi
+done
+
+# the list of git files to copy into the archives
+GIT_FILES=`cd $NDK_ROOT_DIR && git ls-files`
+
+# temporary directory used for packaging
+TMPDIR=/tmp/ndk-release
+
+RELEASE_PREFIX=$PREFIX-$RELEASE
+
+rm -rf $TMPDIR && mkdir -p $TMPDIR
+
+# first create the reference ndk directory from the git reference
+echo "Creating reference from git files"
+REFERENCE=$TMPDIR/reference &&
+mkdir -p $REFERENCE &&
+(for ff in $GIT_FILES; do
+  mkdir -p $REFERENCE/`dirname $ff` && cp -pf $NDK_ROOT_DIR/$ff $REFERENCE/$ff;
+done) &&
+rm -f $REFERENCE/Android.mk
+if [ $? != 0 ] ; then
+    echo "Could not create git reference. Aborting."
+    exit 2
+fi
+
+# now, for each system, create a preview package
+#
+for SYSTEM in $PREBUILT_SYSTEMS; do
+    echo "Preparing package for system $SYSTEM."
+    BIN_RELEASE=$RELEASE_PREFIX-$SYSTEM
+    PREBUILT=$PREBUILT_DIR/$PREBUILT_PREFIX-$SYSTEM
+    DSTDIR=$TMPDIR/$RELEASE_PREFIX
+    rm -rf $DSTDIR && mkdir -p $DSTDIR &&
+    cp -rp $REFERENCE/* $DSTDIR
+    if [ $? != 0 ] ; then
+        echo "Could not copy reference. Aborting."
+        exit 2
+    fi
+
+    echo "Unpacking $PREBUILT.tar.bz2"
+    (cd $DSTDIR && tar xjf $PREBUILT.tar.bz2) 2>/dev/null 1>&2
+    if [ $? != 0 ] ; then
+        echo "Could not unpack prebuilt for system $SYSTEM. Aborting."
+        exit 1
+    fi
+
+    ARCHIVE=$BIN_RELEASE.zip
+    echo "Creating $ARCHIVE"
+    (cd $TMPDIR && zip -9qr $ARCHIVE $RELEASE_PREFIX && rm -rf $DSTDIR) 2>/dev/null 1>&2
+    if [ $? != 0 ] ; then
+        echo "Could not create zip archive. Aborting."
+        exit 1
+    fi
+
+    chmod a+r $TMPDIR/$ARCHIVE
+done
+
+echo "Cleaning up."
+rm -rf $TMPDIR/reference
+
+echo "Done, please see packages in $TMPDIR:"
+ls -l $TMPDIR
+
diff --git a/ndk/docs/ANDROID-MK.TXT b/ndk/docs/ANDROID-MK.TXT
new file mode 100644
index 0000000..9ba5388
--- /dev/null
+++ b/ndk/docs/ANDROID-MK.TXT
@@ -0,0 +1,374 @@
+Android.mk file syntax specification
+
+Introduction:
+-------------
+
+This document describes the syntax of Android.mk build file
+written to describe your C and C++ source files to the Android
+NDK. To understand what follows, it is assumed that you have
+read the docs/OVERVIEW.TXT file that explains their role and
+usage.
+
+Overview:
+---------
+
+An Android.mk file is written to describe your sources to the
+build system. More specifically:
+
+- The file is really a tiny GNU Makefile fragment that will be
+  parsed one or more times by the build system. As such, you
+  should try to minimize the variables you declare there and
+  do not assume that anything is not defined during parsing.
+
+- The file syntax is designed to allow you to group your
+  sources into 'modules'. A module is one of the following:
+
+    - a static library
+    - a shared library
+
+  Only shared libraries will be installed/copied to your
+  application package. Static libraries can be used to generate
+  shared libraries though.
+
+  You can define one or more modules in each Android.mk file,
+  and you can use the same source file in several modules.
+
+- The build system handles many details for you. For example, you
+  don't need to list header files or explicit dependencies between
+  generated files in your Android.mk. The NDK build system will
+  compute these automatically for you.
+
+  This also means that, when updating to newer releases of the NDK,
+  you should be able to benefit from new toolchain/platform support
+  without having to touch your Android.mk files.
+
+Note that the syntax is *very* close to the one used in Android.mk files
+distributed with the full open-source Android platform sources. While
+the build system implementation that uses them is different, this is
+an intentional design decision made to allow reuse of 'external' libraries'
+source code easier for application developers.
+
+Simple example:
+---------------
+
+Before describing the syntax in details, let's consider a simple
+"hello world" example, i.e. the following files:
+
+    sources/helloworld/helloworld.c
+    sources/helloworld/Android.mk
+
+Where 'helloworld.c' is the source of a simple JNI shared library
+that implements a native method that returns the "hello world"
+string.
+
+The corresponding Android.mk file will look like this:
+
+   ---------- cut here ------------------
+   LOCAL_PATH := $(call my-dir)
+
+   include $(CLEAR_VARS)
+
+   LOCAL_MODULE    := helloworld
+   LOCAL_SRC_FILES := helloworld.c
+
+   include $(BUILD_SHARED_LIBRARY)
+   ---------- cut here ------------------
+
+Now, let's explain these lines:
+
+  LOCAL_PATH := $(call my-dir)
+
+An Android.mk file must begin with the definition of the LOCAL_PATH variable.
+It is used to locate source files in the development tree. In this example,
+the macro function 'my-dir', provided by the build system, is used to return
+the path of the current directory (i.e. the directory containing the
+Android.mk file itself).
+
+  include $(CLEAR_VARS)
+
+The CLEAR_VARS variable is provided by the build system and points to a
+special GNU Makefile that will clear many LOCAL_XXX variables for you
+(e.g. LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, etc...),
+with the exception of LOCAL_PATH. This is needed because all build
+control files are parsed in a single GNU Make execution context where
+all variables are global.
+
+  LOCAL_MODULE := helloworld
+
+The LOCAL_MODULE variable must be defined to identify each module you
+describe in your Android.mk. The name must be *unique* and not contain
+any spaces. Note that the build system will automatically add proper
+prefix and suffix to the corresponding generated file. In other words,
+a shared library module named 'foo' will generate 'libfoo.so'.
+
+IMPORTANT NOTE:
+If you name your module 'libfoo', the build system will not
+add another 'lib' prefix and will generate libfoo.so as well.
+This is to support Android.mk files that originate from the
+Android platform sources, would you need to use these.
+
+  LOCAL_SRC_FILES := helloworld.c
+
+The LOCAL_SRC_FILES variables must contain a list of C and/or C++ source
+files that will be built and assemble into a module. Note that you should
+not list header and included files here, because the build system will
+compute dependencies automatically for you; just list the source files
+that will be passed directly to a compiler, and you should be good.
+
+Note that the default extension for C++ source files is '.cpp'. It is
+however possible to specify a different one by defining the variable
+LOCAL_DEFAULT_CPP_EXTENSION. Don't forget the initial dot (i.e. '.cxx'
+will work, but not 'cxx').
+
+  include $(BUILD_SHARED_LIBRARY)
+
+The BUILD_SHARED_LIBRARY is a variable provided by the build system that
+points to a GNU Makefile script that is in charge of collecting all the
+information you defined in LOCAL_XXX variables since the latest
+'include $(CLEAR_VARS)' and determine what to build, and how to do it
+exactly. There is also BUILD_STATIC_LIBRARY to generate a static library.
+
+There are more complex examples under sources/samples, with commented
+Android.mk files that you can look at.
+
+Reference:
+----------
+
+This is the list of variables you should either rely on or define in
+an Android.mk. You can define other variables for your own usage, but
+the NDK build system reserves the following variable names:
+
+- names that begin with LOCAL_  (e.g. LOCAL_MODULE)
+- names that begin with PRIVATE_, NDK_ or APP_  (used internally)
+- lower-case names (used internally, e.g. 'my-dir')
+
+If you need to define your own convenience variables in an Android.mk
+file, we recommend using the MY_ prefix, for a trivial example:
+
+   ---------- cut here ------------------
+    MY_SOURCES := foo.c
+    ifneq ($(MY_CONFIG_BAR),)
+      MY_SOURCES += bar.c
+    endif
+
+    LOCAL_SRC_FILES += $(MY_SOURCES)
+   ---------- cut here ------------------
+
+So, here we go:
+
+
+NDK-provided variables:
+- - - - - - - - - - - -
+
+These GNU Make variables are defined by the build system before
+your Android.mk file is parsed. Note that under certain circumstances
+the NDK might parse your Android.mk several times, each with different
+definition for some of these variables.
+
+CLEAR_VARS
+    Points to a build script that undefines nearly all LOCAL_XXX variables
+    listed in the "Module-description" section below. You must include
+    the script before starting a new module, e.g.:
+
+      include $(CLEAR_VARS)
+
+BUILD_SHARED_LIBRARY
+    Points to a build script that collects all the information about the
+    module you provided in LOCAL_XXX variables and determines how to build
+    a target shared library from the sources you listed. Note that you
+    must have LOCAL_MODULE and LOCAL_SRC_FILES defined, at a minimum before
+    including this file. Example usage:
+
+      include $(BUILD_SHARED_LIBRARY)
+
+    note that this will generate a file named lib$(LOCAL_MODULE).so
+
+BUILD_STATIC_LIBRARY
+    A variant of BUILD_SHARED_LIBRARY that is used to build a target static
+    library instead. Static libraries are not copied into your
+    project/packages but can be used to build shared libraries (see
+    LOCAL_STATIC_LIBRARIES and LOCAL_STATIC_WHOLE_LIBRARIES described below).
+    Example usage:
+
+      include $(BUILD_STATIC_LIBRARY)
+
+    Note that this will generate a file named lib$(LOCAL_MODULE).a
+
+TARGET_ARCH
+    Name of the target CPU architecture as it is specified by the
+    full Android open-source build. This is 'arm' for any ARM-compatible
+    build, independent of the CPU architecture revision.
+
+TARGET_PLATFORM
+    Name of the target Android platform when this Android.mk is parsed.
+    For now, only 'android-1.5' is supported.
+
+TARGET_ARCH_ABI
+    Name of the target CPU+ABI when this Android.mk is parsed.
+    For now, only 'arm' is supported, which really means the following:
+
+       ARMv5TE or higher CPU, with 'softfloat' floating point support
+
+    Other target ABIs will be introduced in future releases of the NDK
+    and will have a different name. Note that all ARM-based ABIs will
+    have 'TARGET_ARCH' defined to 'arm', but may have different
+    'TARGET_ARCH_ABI'
+
+TARGET_ABI
+    The concatenation of target platform and abi, it really is defined
+    as $(TARGET_PLATFORM)-$(TARGET_ARCH_ABI) and is useful when you want
+    to test against a specific target system image for a real device.
+
+    By default, this will be 'android-1.5-arm'
+
+
+NDK-provided function macros:
+- - - - - - - - - - - - - - -
+
+The following are GNU Make 'function' macros, and must be evaluated
+by using '$(call <function>)'. They return textual information.
+
+my-dir
+    Returns the path of the current Android.mk's directory, relative
+    to the top of the NDK build system. This is useful to define
+    LOCAL_PATH at the start of your Android.mk as with:
+
+        LOCAL_PATH := $(call my-dir)
+
+all-subdir-makefiles
+    Returns a list of Android.mk located in all sub-directories of
+    the current 'my-dir' path. For example, consider the following
+    hierarchy:
+
+        sources/foo/Android.mk
+        sources/foo/lib1/Android.mk
+        sources/foo/lib2/Android.mk
+
+    If sources/foo/Android.mk contains the single line:
+
+        include $(call all-subdir-makefiles)
+
+    Then it will include automatically sources/foo/lib1/Android.mk and
+    sources/foo/lib2/Android.mk
+
+    This function can be used to provide deep-nested source directory
+    hierarchies to the build system. Note that by default, the NDK
+    will only look for files in sources/*/Android.mk
+
+this-makefile
+    Returns the path of the current Makefile (i.e. where the function
+    is called).
+
+parent-makefile
+    Returns the path of the parent Makefile in the inclusion tree,
+    i.e. the path of the Makefile that included the current one.
+
+grand-parent-makefile
+    Guess what...
+
+
+Module-description variables:
+- - - - - - - - - - - - - - -
+
+The following variables are used to describe your module to the build
+system. You should define some of them between an 'include $(CLEAR_VARS)'
+and an 'include $(BUILD_XXXXX)'. As written previously, $(CLEAR_VARS) is
+a script that will undefine/clear all of these variables, unless explicitely
+noted in their description.
+
+LOCAL_PATH
+    This variable is used to give the path of the current file.
+    You MUST define it at the start of your Android.mk, which can
+    be done with:
+
+      LOCAL_PATH := $(call my-dir)
+
+    This variable is *not* cleared by $(CLEAR_VARS) so only one
+    definition per Android.mk is needed (in case you define several
+    modules in a single file).
+
+LOCAL_MODULE
+    This is the name of your module. It must be unique among all
+    module names, and shall not contain any space. You MUST define
+    it before including any $(BUILD_XXXX) script.
+
+    The module name determines the name of generated files, e.g.
+    lib<foo>.so for a shared library module named <foo>. However
+    you should only refer to other modules with their 'normal'
+    name (e.g. <foo>) in your NDK build files (either Android.mk
+    or Application.mk)
+
+LOCAL_SRC_FILES
+    This is a list of source files that will be built for your module.
+    Only list the files that will be passed to a compiler, since the
+    build system automatically computes dependencies for you.
+
+    Note that source files names are all relative to LOCAL_PATH and
+    you can use path components, e.g.:
+
+      LOCAL_SRC_FILES := foo.c \
+                         toto/bar.c
+
+    NOTE: Always use Unix-style forward slashes (/) in build files.
+          Windows-style back-slashes will not be handled properly.
+
+LOCAL_CPP_EXTENSION
+    This is an optional variable that can be defined to indicate
+    the file extension of C++ source files. The default is '.cpp'
+    but you can change it. For example:
+
+        LOCAL_CPP_EXTENSION := .cxx
+
+LOCAL_CFLAGS
+    An optional set of compiler flags that will be passed when building
+    C source files (*not* C++ sources).
+
+    This can be useful to specify an additionnal include path
+    (relative to the top of the NDK directory), macro definitions
+    or compile options.
+
+    IMPORTANT: Try not to change the optimization/debugging level in
+               your Android.mk, this can be handled automatically for
+               you by specifying the appropriate information in
+               your Application.mk, and will let the NDK generate
+               useful data files used during debugging.
+
+LOCAL_CXXFLAGS
+    Same as LOCAL_CFLAGS for C++ source files
+
+LOCAL_CPPFLAGS
+    Same as LOCAL_CFLAGS but used for both C and C++ source files
+
+LOCAL_STATIC_LIBRARIES
+    The list of static libraries modules (built with BUILD_STATIC_LIBRARY)
+    that should be linked to this module. This only makes sense in
+    shared library modules. 
+
+LOCAL_SHARED_LIBRARIES
+    The list of shared libraries *modules* this module depends on at runtime.
+    This is necessary at link time and to embed the corresponding information
+    in the generated file.
+
+    Note that this does not append the listed modules to the build graph,
+    i.e. you should still add them to your application's required modules
+    in your Application.mk
+
+LOCAL_LDLIBS
+    The list of additional linker flags to be used when building your
+    module. This is useful to pass the name of specific system libraries
+    with the "-l" prefix. For example, the following will tell the linker
+    to generate a module that links to /system/lib/libz.so at load time:
+
+      LOCAL_LDLIBS := -lz
+
+    See docs/STABLE-APIS.TXT for the list of exposed system libraries you
+    can linked against with this NDK release.
+
+LOCAL_ALLOW_UNDEFINED_SYMBOLS
+    By default, any undefined reference encountered when trying to build
+    a shared library will result in an "undefined symbol" error. This is a
+    great help to catch bugs in your source code.
+
+    However, if for some reason you need to disable this check, set this
+    variable to 'true'. Note that the corresponding shared library may fail
+    to load at runtime.
diff --git a/ndk/docs/APPLICATION-MK.TXT b/ndk/docs/APPLICATION-MK.TXT
new file mode 100644
index 0000000..6f84da9
--- /dev/null
+++ b/ndk/docs/APPLICATION-MK.TXT
@@ -0,0 +1,104 @@
+Application.mk file syntax specification
+
+Introduction:
+-------------
+
+This document describes the syntax of Application.mk build files
+written to describe the native modules required by your Android
+application. To understand what follows, it is assumed that you have
+read the docs/OVERVIEW.TXT file that explains their role and
+usage.
+
+Readers of this document should have read docs/OVERVIEW.TXT and
+docs/ANDROID-MK.TXT
+
+
+Overview:
+---------
+
+The purpose of Application.mk is to describe which native
+'modules' (i.e. static/shared libraries) are needed by your
+application.
+
+Each Application.mk must be placed under a sub-directory of
+the top-level apps directory, e.g.:
+
+   $NDK/apps/<myapp>/Application.mk
+
+Where <myapp> is a short name used to describe your 'application'
+to the NDK build system (this name doesn't go into your generated
+shared libraries or your final packages).
+
+The Application.mk is really a tiny GNU Makefile fragment that must
+define a few variables:
+
+APP_MODULES
+    This variable is mandatory and lists all the native modules
+    (described through Android.mk files) that your application
+    requires.
+
+    This must be a space-separated list of module names as they
+    appear in the LOCAL_MODULE definitions of Android.mk files
+
+APP_PROJECT_PATH
+    This variable is mandatory and should give the *absolute*
+    path to your Application's project root directory. This is used
+    to copy/install stripped versions of the generated JNI shared
+    libraries to a specific location known to the APK-generating tools.
+
+APP_OPTIM
+    This optional variable can be defined to either 'release' or
+    'debug'. This is used to alter the optimization level when
+    building your application's modules.
+
+    A 'release' mode is the default, and will generate highly
+    optimized binaries. The 'debug' mode will generate un-optimized
+    binaries which are much easier to debug.
+
+    Note that it is possible to debug both 'release' and 'debug'
+    binaries, but the 'release' builds tend to provide less information
+    during debugging sessions: some variables are optimized out and
+    can't be inspected, code re-ordering can make stepping through
+    the code difficult, stack traces may not be reliable, etc...
+
+APP_CFLAGS
+    A set of C compiler flags passed when compiling any C source code
+    of any of the modules. This can be used to change the build of a given
+    module depending on the application that needs it, instead of modifying
+    the Android.mk file itself.
+
+    IMPORTANT WARNING: +++++++++++++++++++++++++++++++++++++++++++++++++++
+    +
+    + All paths in these flags should be relative to the top-level NDK
+    + directory. For example, if you have the following setup:
+    +
+    +    sources/foo/Android.mk
+    +    sources/bar/Android.mk
+    +
+    + To specify in foo/Android.mk that you want to add the path to the
+    + 'bar' sources during compilation, you should use:
+    +
+    +   APP_CFLAGS += -Isources/bar
+    +
+    + Or alternatively:
+    +
+    +   APP_CFLAGS += -I$(LOCAL_PATH)/../bar
+    +
+    + Using '-I../bar' will *NOT* work since it will be equivalent to
+    + '-I$NDK_ROOT/../bar' instead.
+    +
+    +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+APP_CXXFLAGS
+    Same as APP_CFLAGS for C++ sources.
+
+APP_CPPFLAGS
+    Same as APP_CFLAGS but will be passed to both C and C++ sources
+
+A trivial Application.mk file would be:
+
+-------------- cut here -------------------------
+APP_MODULES      := <list of modules>
+APP_PROJECT_PATH := <path to project>
+-------------- cut here -------------------------
+
diff --git a/ndk/docs/CHANGES.TXT b/ndk/docs/CHANGES.TXT
new file mode 100644
index 0000000..c65c821
--- /dev/null
+++ b/ndk/docs/CHANGES.TXT
@@ -0,0 +1,4 @@
+Android NDK ChangeLog:
+
+-------------------------------------------------------------------------------
+android-1.5_r1 released.
diff --git a/ndk/docs/HOWTO.TXT b/ndk/docs/HOWTO.TXT
new file mode 100644
index 0000000..d2fa95f
--- /dev/null
+++ b/ndk/docs/HOWTO.TXT
@@ -0,0 +1,98 @@
+Android NDK How-To:
+===================
+
+A collection of tips and tricks for NDK users
+
+
+How to force the display of build commands:
+-------------------------------------------
+
+Do "make APP=<yourapp> V=1" and actual build commands will be
+displayed. This can be used to verify that things are compiled
+as you expect them to, and check for bugs in the NDK build system.
+
+(The V=1 trick comes from the Linux kernel build system)
+
+
+
+How to force a rebuild of all your sources:
+-------------------------------------------
+
+Use GNU Make's "-B" option, as in:
+
+   make APP=<yourapp> -B
+
+
+How to store your native sources in under your project's path:
+--------------------------------------------------------------
+
+It is often more convenient to store your native sources at a
+different location than $NDK_ROOT/sources. For example, you would
+typically place them under the same directory than your other project
+files, to keep everything under source control, etc...
+
+The NDK build system needs to access the sources from $NDK_ROOT/sources
+and your Application.mk from $NDK_ROOT/apps/<name>. This is essentially
+to keep its implementation sane and simple, and to ensure that certain
+features, like automatic dependency management, work reliably.
+
+You can however use simple symlinks to redirect paths to your project's
+storage location. For example:
+
+   $NDK_ROOT/sources/<foo>  ---->  $PROJECT_PATH/jni/<foo>
+   $NDK_ROOT/apps/<foo>     ---->  $PROJECT_PATH/jni/<foo>
+
+Where $PROJECT_PATH/jni/<foo> contains both an Android.mk and an
+Application.mk. Note that things like $(call my-dir) will always evaluate
+to the NDK paths (i.e. $NDK_ROOT/sources/<foo>) at build time.
+
+Windows users: The NDK is only supported on Cygwin, which implements
+symbolic links through the "ln -s" command, as in:
+
+    ln -s  <target>  <link>
+
+
+How to properly add include directories to your module declaration:
+-------------------------------------------------------------------
+
+If you define several modules, it is common to need to include one
+module's header while compiling another one. For example, consider
+the following example:
+
+  $NDK_ROOT/sources/foo/
+    Android.mk
+    foo.h
+    foo.c
+
+  $NDK_ROOT/sources/bar/
+    Android.mk
+    bar.c
+
+Where the 'bar.c' uses '#include <foo.h>'. You will need to add the
+path to the 'foo' module in bar/Android.mk to build it properly.
+
+One is tempted to use the following:
+
+  LOCAL_CPPFLAGS := -I../foo
+
+However this will not work because all compilation happens from the
+root NDK directory (i.e. $NDK_ROOT), and include files must be relative
+to it. The above line really translates to:
+
+  LOCAL_CPPFLAGS := -I$(NDK_ROOT)/../foo
+
+Which adds a non-existing directory to the C include path. The correct
+line is instead:
+
+  LOCAL_CPPFLAGS := -Isources/foo
+
+Or even better:
+
+  LOCAL_CPPFLAGS := $(LOCAL_PATH)/../foo
+
+Which uses a path relative to $(LOCAL_PATH), in the case where you would
+need to move 'foo' and 'bar' to a deeper level in the 'sources' hierarchy.
+
+
+
+
diff --git a/ndk/docs/INSTALL.TXT b/ndk/docs/INSTALL.TXT
new file mode 100644
index 0000000..f7f474e
--- /dev/null
+++ b/ndk/docs/INSTALL.TXT
@@ -0,0 +1,57 @@
+Android NDK Installation
+
+Introduction:
+-------------
+
+Please read docs/OVERVIEW.TXT to understand what the Android NDK is and is not.
+This file gives instructions on how to properly setup your NDK.
+
+
+I. Requirements:
+----------------
+
+The Android NDK currently requires a Linux, OS X or Windows host operating system.
+Windows users will need to install Cygwin (http://www.cygwin.com) to use it. Note
+that running the NDK under MSys has not been tested.
+
+You will need to have the Android SDK and its dependencies installed. The NDK
+cannot generate final application packages (.apk files), only the shared library
+files that can go into them.
+
+
+IMPORTANT:
+    The Android NDK can only be used to target system images using
+    the Cupcake (1.5) or later releases of the platform.
+
+    This is due to subtle toolchain and ABI related changed that make
+    it incompatible with 1.0 and 1.1 system images.
+
+The NDK also requires GNU Make 3.81 or later being available on your development
+system. Earlier versions of GNU Make might work but have not been tested.
+
+You can check this by running 'make -v' from the command-line. The output
+should look like:
+
+    GNU Make 3.81
+    Copyright (C) 2006  Free Software Foundation, Inc.
+    ...
+
+On certain systems, GNU Make might be available through a different command like
+'gmake' or 'gnumake'. For these systems, replace 'make' by the appropriate command
+when invoking the NDK build system as described in the documentation.
+
+On Windows, you will need to install a recent release of Cygwin to use the NDK.
+See http://www.cygwin.com for instructions.
+
+
+II. Preparing your installation prebuilt cross-toolchain binaries:
+-----------------------------------------------
+
+After installing and unarchiving the NDK, you will need to run the following
+command from the root folder:
+
+  build/host-setup.sh
+
+This will test your setup and make sure the NDK can work properly.
+
+
diff --git a/ndk/docs/LICENSES.TXT b/ndk/docs/LICENSES.TXT
new file mode 100644
index 0000000..0192dbf
--- /dev/null
+++ b/ndk/docs/LICENSES.TXT
@@ -0,0 +1,10 @@
+The content of the Android NDK is covered by various open-source licenses.
+See the copyright disclaimers in each respective file for details.
+
+Note that the public Android NDK release packages also contain prebuilt binaries
+for the compiler, linker, archiver, etc... The source code for the toolchain is
+available at http://android.git.kernel.org/pub
+
+The prebuilt binaries are covered by either the GNU General Public License (GPL),
+or the GNU Lesser General Public License (LGPL). For details, see the files
+COPYING and COPYING.LIB under 'build/prebuilt/<system>/<toolchain>'
diff --git a/ndk/docs/OVERVIEW.TXT b/ndk/docs/OVERVIEW.TXT
new file mode 100644
index 0000000..903c23b
--- /dev/null
+++ b/ndk/docs/OVERVIEW.TXT
@@ -0,0 +1,288 @@
+Android NDK Overview
+
+Introduction:
+
+The Android NDK is a set of tools that allows Android application developers
+to embed native machine code compiled from C and/or C++ source files into
+their application packages.
+
+IMPORTANT:
+  The Android NDK can only be used to target Android system images
+  running Cupcake (a.k.a 1.5) or later versions of the platform.
+
+  1.0 and 1.1 system images are specifically *not* supported due to
+  subtle ABI and toolchain changes that happened for the 1.5 release.
+
+
+I. Android NDK Goals:
+---------------------
+
+The Android VM allows your application's source code to call methods
+implemented in native code through the JNI. In a nutshell, this means that:
+
+  - Your application's source code will declare one or more methods
+    with the 'native' keyword to indicate that they are implemented through
+    native code. E.g.:
+
+      native byte[]  loadFile(String  filePath);
+
+  - You must provide a native shared library that contains the
+    implementation of these methods, which will be packaged into your
+    application's .apk. This library must be named according to standard
+    Unix conventions as lib<something>.so, and shall contain a standard JNI
+    entry point (more on this later). For example:
+
+      libFileLoader.so
+
+  - Your application must explicitely load the library. For example, to load
+    it at application startup, simply add the following to its source code:
+
+      static {
+        System.loadLibrary("FileLoader");
+      }
+
+    Note that you should not use the 'lib' prefix and '.so' suffix here.
+
+
+The Android NDK is a complement to the Android SDK that helps you to:
+
+  - generate JNI-compatible shared libraries that can run on the Android
+    1.5 platform (and later) running on ARM CPUs.
+
+  - copy the generated shared libraries to a proper location of your
+    application project path, so they will be automatically added to your
+    final (and signed) .apks
+
+  - in later revisions of the NDK, we intend to provide tools that help
+    debug your native code through a remote gdb connection and as much
+    source/symbol information as possible.
+
+Moreover, the Android NDK provides:
+
+  - a set of cross-toolchains (compilers, linkers, etc..) that can
+    generate native ARM binaries on Linux, OS X and Windows (with Cygwin)
+
+  - a set of system headers corresponding to the list of stable native APIs
+    supported by the Android platform. This corresponds to definitions that
+    are guaranteed to be supported in all later releases of the platform.
+
+    IMPORTANT: 
+    Keep in mind that most of the native system libraries in Android system
+    images are not frozen and might changed drastically, or even deleted,
+    in later updates and releases of the platform.
+
+  - a build system that allow developers to only write very short build files
+    to describe which sources need to be compiled, and how. The build system
+    deals with all the hairy toolchain/platform/CPU/ABI specifics. Moreover,
+    later updates of the NDK can add support for more toolchains, platforms,
+    system interfaces without requiring changes in the developer's build
+    files (more on this later).
+
+
+II. Android NDK Non-Goals:
+--------------------------
+
+The NDK is *not* a good way to write generic native code that runs on Android
+devices. In particular, your applications should still be written in the Java
+programming language, handle Android system events appropriately to avoid the
+"Application Not Responding" dialog or deal with the Android application
+life-cycle.
+
+Note however that is is possible to write a sophisticated application in
+native code with a small "application wrapper" used to start/stop it
+appropriately.
+
+A good understanding of JNI is highly recommended, since many operations
+in this environment require specific actions from the developers, that are
+not necessarily common in typical native code. These include:
+
+  - not being able to directly access the content of VM objects through
+    direct native pointers. E.g. you cannot safely get a pointer to a
+    String object's 16-bit char array to iterate over it in a loop.
+
+  - requiring explicit reference management when the native code wants to
+    keep handles to VM objects between JNI calls.
+
+
+The NDK only provides system headers for a very limited set of native
+APIs and libraries supported by the Android platform. While a typical
+Android system image includes many native shared libraries, these should
+be considered an implementation detail that might change drastically between
+updates and releases of the platform.
+
+If an Android system library is not explicitely supported by the NDK
+headers, then applications should not depend on it being available, or
+they risk breaking after the next over-the-air system update on various
+devices.
+
+Selected system libraries will gradually be added to the set of stable NDK
+APIs.
+
+
+III. NDK development in practice:
+---------------------------------
+
+Here's a very rough overview of how you can develop native code with the
+Android NDK:
+
+  1/ Run build/host-setup.sh to configure the NDK
+
+  2/ Place your sources under sources/<mysrc>/...
+
+  3/ Write sources/<mysrc>/Android.mk to describe your sources
+     to the NDK build system
+
+  4/ Write apps/<myapp>/Application.mk to describe your application
+     and the native sources it needs to the NDK build system
+
+  5/ Build your native code by running "make APP=<myapp>"
+     in the top-level NDK directory.
+
+The last step will copy, in case of success, the stripped shared libraries
+your application needs to your application's root project directory. You
+will then need to generate your final .apk through the usual means.
+
+Now, for a few more details:
+
+
+III.1/ Configuring the NDK:
+- - - - - - - - - - - - - -
+
+After installing the NDK as described in docs/INSTALL.TXT, you should call
+the 'build/host-setup.sh' script to configure your NDK.
+
+This script is used to probe your host system and verify a few pre-requisites.
+It will then generate a configuration file (e.g. out/host/config-host.mk) that
+is later used during NDK builds.
+
+In some cases, this might instruct you to download an archive containing
+prebuilt toolchain binaries for your development platform, the unzip it
+to the NDK root directory. The message should contain enough information
+to let you do that.
+
+If you forget this step, trying to build with the NDK will generate an
+error message telling you what to do.
+
+
+III.2/ Placing C and C++ sources:
+- - - - - - - - - - - - - - - - -
+
+The NDK build system expects your sources to be visible under the top-level
+'sources' directory. You should first create a directory like:
+
+    $NDK/sources/<mysrc>/
+
+You are pretty free to organize the content of 'sources' as you want,
+the directory names and structure here will not influence the final
+generated application packages, so you don't have to use pseudo-unique
+names like com.<mycompany>.<myproject> as is the case for application
+package names.
+
+For the record, the NDK comes with a 'sources/samples' directory which
+itself contains several subdirectories for various sample modules.
+
+Note that C and C++ sources are supported. The default C++ file extensions
+supported by the NDK is '.cpp', but other extensions can be handled as well
+(see docs/ANDROID-MK.TXT for details).
+
+It is possible to store your sources in a different location, as long as
+you create $NDK/sources/<mysrc> as a symbolic link. For proper operation, the
+NDK build system must be able to 'see' your source files and build scripts
+from $NDK/sources.
+
+
+III.3/ Writing an Android.mk build script:
+- - - - - - - - - - - - - - - - - - - - - -
+
+An Android.mk file is a small build script that you write to describe your
+sources to the NDK build system. Their syntax is described in details in
+the file docs/ANDROID-MK.TXT.
+
+In a nutshell, the NDK groups your sources into "modules", where each module
+can be one of the following:
+
+  - a static library
+  - a shared library
+
+You can define several modules in a single Android.mk, or you can write
+several Android.mk files, each one defining a single module.
+
+All Android.mk files are parsed by the build system before any build occurs.
+Note also that a single Android.mk might be parsed several times by the build
+system so don't assume that certain variables are not defined in them.
+
+By default, the NDK will look for all files that match the following:
+
+   $NDK/sources/*/Android.mk
+
+If you want to define Android.mk files in sub-directories, you should
+include them explicitely in your top-level Android.mk. There is even
+a helper function to do that, i.e. use:
+
+   include $(call all-subdir-makefiles)
+
+This will include all Android.mk files in sub-directories of the current
+build file's path.
+
+
+III.4/ Writing an Application.mk build file:
+- - - - - - - - - - - - - - - - - - - - - - -
+
+While an Android.mk file describes your modules to the build system, you
+need to write an Application.mk file to describe your application and the
+modules it requires. This file must be located in:
+
+  $NDK/apps/<myapp>/Application.mk
+
+Where <myapp> is a short descriptive name for your application that will
+be used to invoke the NDK build (and not go into final APKs). The file is
+used to provide the following to the NDK build:
+
+  - The location of your Android application's project path
+
+  - The list of NDK modules that is required by your application.
+    This should really be a list of 'shared library' modules.
+
+  - Optional information, like whether you want a release or debug
+    build, specific C or C++ compiler flags and others.
+
+  - Planned: the list of specific platforms/CPUs you want to explicitely
+    target (currently only one is supported).
+
+The syntax of an Application.mk file is very simple and is described in
+docs/APPLICATION-MK.TXT
+
+You can define several Application.mk corresponding to different builds
+of the same application, for example:
+
+  $NDK/apps/release/Application.mk
+  $NDK/apps/debug/Application.mk
+
+
+III.5/ Invoke the NDK build system:
+- - - - - - - - - - - - - - - - - -
+
+On the command-line, go to the top-level NDK directory, then invoke the
+build system with:
+
+   make APP=<myapp>
+
+Where 'make' refers to GNU Make, and <myapp> is the name of one of the
+subdirectories of '$NDK/apps/'
+
+This will try to build all modules with relevant options, the final
+shared libraries listed by your Application.mk and, in case of success,
+will copy stripped versions of the shared libraries to your application's
+project path. (Note that unstripped versions are kept for debugging
+purposes, there is no need to copy unstripped binaries to a device).
+
+
+
+IV. Debugging support:
+- - - - - - - - - - - -
+
+Debugging your native code with this initial release of the NDK is still
+very rough.
+
+Note that we plan to make this much easier in a later NDK release, all of
+this without changing your sources, Android.mk and Application.mk files.
diff --git a/ndk/docs/STABLE-APIS.TXT b/ndk/docs/STABLE-APIS.TXT
new file mode 100644
index 0000000..743d657
--- /dev/null
+++ b/ndk/docs/STABLE-APIS.TXT
@@ -0,0 +1,113 @@
+Android NDK Stable APIs:
+========================
+
+This is the list of stable APIs/ABIs exposed by the Android NDK.
+
+I. Purpose:
+-----------
+
+Each API corresponds to a set of headers files, and a shared library file
+that contains the corresponding implementation, and which must be linked
+against by your native code.
+
+For example, to use system library "Foo", you would include a header
+like <foo.h> in your code, then tell the build system that your native
+module needs to link to /system/lib/libfoo.so at load-time by adding
+the following line to your Android.mk file:
+
+  LOCAL_LDLIBS := -lfoo
+
+Note that the build system automatically links the C library, the Math
+library and the C++ support library to your native code, there is no
+need to list them in a LOCAL_LDLIBS line.
+
+
+
+II. Android 1.5 Stable Native APIs:
+-----------------------------------
+
+All the APIs listed below are available for developing native code that
+runs on Android 1.5 system images and above.
+
+The C Library:
+--------------
+
+The C library headers, as they are defined on Android 1.5 are available
+through their standard names (<stdlib.h>, <stdio.h>, etc...). If one header
+is not there at build time, it's because its implementation is not available
+on a 1.5 system image.
+
+The build system automatically links your native modules to the C library,
+you don't need to add it to LOCAL_LDLIBS.
+
+Note that the Android C library includes support for pthread (<pthread.h>),
+so "LOCAL_LIBS := -lpthread" is not needed. The same is true for real-time
+extensions (-lrt on typical Linux distributions).
+
+
+** VERY IMPORTANT NOTE: ******************************************************
+*
+*  The kernel-specific headers in <linux/...> and <asm/...> are not considered
+*  stable at this point. Avoid including them directly because some of them
+*  are likely to change in future releases of the platform. This is especially
+*  true for anything related to specific hardware definitions.
+*
+******************************************************************************
+
+
+The Math Library:
+-----------------
+
+<math.h> is available, and the math library is automatically linked to your
+native modules at build time, so there is no need to list "-lm" through
+LOCAL_LDLIBS.
+
+
+
+C++ Library:
+------------
+
+An *extremely* minimal C++ support API is available. For Android 1.5, this is
+currently limited to the following headers:
+
+   <cstddef>
+   <new>
+   <utility>
+   <stl_pair.h>
+
+They may not contain all definitions required by the standard. Notably, support
+for C++ exceptions and RTTI is not available with Android 1.5 system images.
+
+The C++ support library (-lstdc++) is automatically linked to your native
+modules too, so there is no need to list it through LOCAL_LDLIBS
+
+
+
+Android-specific Log Support:
+-----------------------------
+
+<android/log.h> contains various definitions that can be used to send log messages
+to the kernel from your native code. Please have a look at its content in
+(build/platforms/android-1.5/common/include/android/log.h), which contain many
+informative comments on how to use it.
+
+You should be able to write helpful wrapper macros for your own usage to
+access this facility.
+
+If you use it, your native module should link to /system/lib/liblog.so with:
+
+  LOCAL_LDLIBS := -llog
+
+
+
+ZLib Compression Library:
+-------------------------
+
+<zlib.h> and <zconf.h> are available and can be used to use the ZLib compression
+library available on Android 1.5 system images. Documentation for it is available
+on the ZLib page: http://www.zlib.net/manual.html
+
+If you use it, your native module should link to /system/lib/libz.so with:
+
+  LOCAL_LDLIBS := -lz
+
diff --git a/ndk/docs/SYSTEM-ISSUES.TXT b/ndk/docs/SYSTEM-ISSUES.TXT
new file mode 100644
index 0000000..17ee4e8
--- /dev/null
+++ b/ndk/docs/SYSTEM-ISSUES.TXT
@@ -0,0 +1,113 @@
+Android System Image Issues
+===========================
+
+This document contains a list of known issues in existing Android
+system images that NDK developers should be aware of.
+
+I. Android 1.5 System Issues:
+-----------------------------
+
+The following issues correspond to the official Android 1.5
+system images:
+
+
+No standard C++ library support:
+--------------------------------
+
+The Android 1.5 system does not use any C++ standard library, and does
+not provide one to applicative native code. Instead, a very limited set
+of headers are provided (see docs/STABLE-APIS.TXT) which correspond to
+the C++ support code used to build the Android platform.
+
+It is possible to hack existing C++ STL implementations to work on top
+of this, but this is not supported yet. We recommend trying with uSTL
+and STLport at this point if you really need this.
+
+
+No support for C++ exceptions and RTTI:
+---------------------------------------
+
+The Android 1.5 system image lacks several features necessary to reliably
+implement C++ exceptions and RTTI. C++ code that depends on these features
+will simply not link or run appropriately on Android 1.5
+
+
+C Library limitations:
+----------------------
+
+The C library doesn't try to implement every feature under the sun.
+Most notably, pthread cancellation is not supported. A detailed overview
+of the C library and its design is available in docs/system/libc/OVERVIEW.TXT
+
+
+No SysV IPCs in C library:
+--------------------------
+
+Unix System V Inter-Process Communication APIs (e.g. semget()) are
+intentionally not available from the C library, to avoid denial-of-service
+issues. See docs/system/libc/SYSV-IPC.TXT for details.
+
+
+C Library bug: getservbyname() returns port number in incorrect order:
+----------------------------------------------------------------------
+
+The Android 1.5 C library function getservbyname() returns the port number
+corresponding to a given network service in incorrect order. The function
+stores its result in a 'struct servent' structure, and the port number in
+its 's_port' field.
+
+The standard mandates that this value is stored in network order (and thus
+should be converted to host order through ntohs()). However, the 1.5
+implementation is buggy and returns the number.
+
+This bug will be fixed in future releases of the platform, and applications
+should not depend on the wrong behaviour in the future. Avoid using this
+function if possible; if this is not possible, try to use a small wrapper
+like the following one:
+
+static struct servent*
+my_getservbyname(const char*  name, const char*  proto)
+{
+    static int       has_bug = -1;
+    struct servent*  ret;
+
+    if (has_bug < 0) {
+        ret = getservbyname("http",NULL);
+        has_bug = (ret == NULL || ret->s_port == 80);
+    }
+
+    ret = getservbyname(name, proto);
+    if (has_bug)
+        ret->s_port = htons(ret->s_port);
+}
+
+(the returned struct servent is thread-local and can be modified by the
+ caller. It will be over-written on the next call to the function though).
+
+
+Dynamic Linker limitations:
+---------------------------
+
+The Android dynamic linker in 1.5 has many important limitations:
+
+- No support for LD_LIBRARY_PATH, LD_PRELOAD, RTLD_LOCAL and many
+  other options.
+
+- Static C++ constructors in executables are called twice due to a bug
+  in the C library initialization sequence. However, static C++
+  constructors in shared libraries are only called once.
+
+- Static destructors are never called at the moment, either at program
+  exit, or when dlclose() is called.
+
+- dlerror() reporting is very limited and only provides a few generic
+  error messages that make it difficult to know why a dynamic load/link
+  operation failed. Most of the time, the culprit is a missing symbol.
+
+- A bug prevents one application shared library from depending on another
+  one. For example, if you build both libfoo.so and libbar.so for your
+  application, and list libfoo.so as a dependency for libbar.so in
+  bar/Android.mk (with LOCAL_SHARED_LIBRARIES := foo), then loading
+  libbar.so will always fail, even if you have already loaded libfoo.so
+  in your process.
+
diff --git a/ndk/docs/system/libc/OVERVIEW.TXT b/ndk/docs/system/libc/OVERVIEW.TXT
new file mode 100644
index 0000000..4c153b1
--- /dev/null
+++ b/ndk/docs/system/libc/OVERVIEW.TXT
@@ -0,0 +1,388 @@
+Bionic C Library Overview:
+==========================
+
+Introduction:
+
+Core Philosophy:
+
+  The core idea behind Bionic's design is: KEEP IT REALLY SIMPLE.
+
+  This implies that the C library should only provide lightweight wrappers
+  around kernel facilities and not try to be too smart to deal with edge cases.
+
+  The name "Bionic" comes from the fact that it is part-BSD and part-Linux:
+  its source code consists in a mix of BSD C library pieces with custom
+  Linux-specific bits used to deal with threads, processes, signals and a few
+  others things.
+
+  All original BSD pieces carry the BSD copyright disclaimer. Bionic-specific 
+  bits carry the Android Open Source Project copyright disclaimer. And
+  everything is released under the BSD license.
+
+Architectures:
+
+  Bionic currently supports the ARM and x86 instruction sets. In theory, it
+  should be possible to support more, but this may require a little work (e.g.
+  adding system call IDs to SYSCALLS.TXT, described below, or modifying the
+  dynamic linker).
+
+  The ARM-specific code is under arch-arm/ and the x86-specific one is under
+  arch-x86/
+
+  Note that the x86 version is only meant to run on an x86 Android device. We
+  make absolutely no claim that you could build and use Bionic on a stock x86
+  Linux distribution (though that would be cool, so patches are welcomed :-))
+
+Syscall stubs:
+
+  Each system call function is implemented by a tiny assembler source fragment
+  (called a "syscall stub"), which is generated automatically by
+  tools/gensyscalls.py which reads the SYSCALLS.TXT file for input.
+
+  SYSCALLS.TXT contains the list of all syscall stubs to generate, along with
+  the corresponding syscall numeric identifier (which may differ between ARM
+  and x86), and its signature
+
+  If you modify this file, you may want to use tools/checksyscalls.py which
+  checks its content against official Linux kernel header files, and will
+  report errors when invalid syscall ids are used.
+
+  Sometimes, the C library function is really a wrapper that calls the
+  corresponding syscall with another name. For example, the exit() function
+  is provided by the C library and calls the _exit() syscall stub.
+
+  See SYSCALLS.TXT for documentation and details.
+
+
+time_t:
+
+  time_t is 32-bit as defined by the kernel on 32-bit CPUs. A 64-bit version
+  would be preferrable to avoid the Y2038 bug, but the kernel maintainers
+  consider that this is not needed at the moment.
+
+  Instead, Bionic provides a <time64.h> header that defines a time64_t type,
+  and related functions like mktime64(), localtime64(), etc...
+
+
+Timezone management:
+
+  The name of the current timezone is taken from the TZ environment variable,
+  if defined. Otherwise, the system property named 'persist.sys.timezone' is
+  checked instead.
+
+  The zoneinfo timezone database and index files are located under directory
+  /system/usr/share/zoneinfo, instead of the more Posix-compliant path of
+  /usr/share/zoneinfo
+
+
+off_t:
+
+  For similar reasons, off_t is 32-bit. We define loff_t as the 64-bit variant
+  due to BSD inheritance, but off64_t should be available as a typedef to ease
+  porting of current Linux-specific code.
+
+
+Linux kernel headers:
+
+  Bionic comes with its own set of "clean" Linux kernel headers to allow
+  user-space code to use kernel-specific declarations (e.g. IOCTLs, structure
+  declarations, constants, etc...). They are located in:
+
+     ./kernel/common,
+     ./kernel/arch-arm
+     ./kernel/arch-x86
+
+  These headers have been generated by a tool (kernel/tools/update-all.py) to
+  only include the public definitions from the original Linux kernel headers.
+
+  If you want to know why and how this is done, read kernel/README.TXT to get
+  all the (gory) details.
+
+
+PThread implementation:
+
+   Bionic's C library comes with its own pthread implementation bundled in.
+   This is different from other historical C libraries which:
+
+    - place it in an external library (-lpthread)
+    - play linker tricks with weak symbols at dynamic link time
+
+   The support for real-time features (a.k.a. -lrt) is also bundled in the
+   C library.
+
+   The implementation is based on futexes and strives to provide *very* short
+   code paths for common operations. Notable features are the following:
+
+      - pthread_mutex_t, pthread_cond_t are only 4 bytes each.
+
+      - Normal, recursive and error-check mutexes are supported, and the code
+        path is heavily optimized for the normal case, which is used most of
+        the time.
+
+      - Process-shared mutexes and condition variables are not supported.
+        Their implementation requires far more complexity and was absolutely
+        not needed for Android (which uses other inter-process synchronization
+        capabilities).
+
+        Note that they could be added in the future without breaking the ABI
+        by specifying more sophisticated code paths (which may make the common
+        paths slightly slower though).
+
+      - There is currently no support for read/write locks, priority-ceiling in
+        mutexes and other more advanced features. Again, the main idea being
+        that this was not needed for Android at all but could be added in the
+        future.
+
+pthread_cancel():
+
+   pthread_cancel() will *not* be supported in Bionic, because doing this would
+   involve making the C library significantly bigger for very little benefit.
+
+   Consider that:
+
+     - A proper implementation must insert pthread cancellation checks in a lot
+       of different places of the C library. And conformance is very difficult
+       to test properly.
+
+     - A proper implementation must also clean up resources, like releasing
+       memory, or unlocking mutexes, properly if the cancellation happens in a
+       complex function (e.g. inside gethostbyname() or fprintf() + complex
+       formatting rules). This tends to slow down the path of many functions.
+
+     - pthread cancellation cannot stop all threads: e.g. it can't do anything
+       against an infinite loop
+
+     - pthread cancellation itself has short-comings and isn't very portable
+       (see http://advogato.org/person/slamb/diary.html?start=49 for example).
+
+   All of this is contrary to the Bionic design goals. If your code depends on
+   thread cancellation, please consider alternatives.
+
+   Note however that Bionic does implement pthread_cleanup_push() and
+   pthread_cleanup_pop(), which can be used to handle cleanups that happen when
+   a thread voluntarily exits through pthread_exit() or returning from its
+   main function.
+
+
+pthread_once():
+
+  Do not call fork() within a callback provided to pthread_once(). Doing this
+  may result in a deadlock in the child process the next time it calls
+  pthread_once().
+
+  Also, you can't throw a C++ Exception from the callback (see C++ Exception
+  Support below).
+
+  The current implementation of pthread_once() lacks the necessary support of
+  multi-core-safe double-checked-locking (read and write barriers).
+
+
+Thread-specific data
+
+  The thread-specific storage only provides for a bit less than 64
+  pthread_key_t objects to each process. The implementation provides 64 real
+  slots but also uses about 5 of them (exact number may depend on
+  implementation) for its own use (e.g. two slots are pre-allocated by the C
+  library to speed-up the Android OpenGL sub-system).
+
+  Note that Posix mandates a minimum of 128 slots, but we do not claim to be
+  Posix-compliant.
+
+  Except for the main thread, the TLS area is stored at the top of the stack.
+  See comments in bionic/libc/bionic/pthread.c for details.
+
+  At the moment, thread-local storage defined through the __thread compiler
+  keyword is not supported by the Bionic C library and dynamic linker.
+
+
+Multi-core support
+
+  At the moment, Bionic does not provide or use read/write memory barriers.
+  This means that using it on certain multi-core systems might not be
+  supported, depending on its exact CPU architecture.
+
+
+Android-specific features:
+
+  Bionic provides a small number of Android-specific features to its clients:
+
+  - access to system properties:
+
+       Android provides a simple shared value/key space to all processes on the
+       system. It stores a liberal number of 'properties', each of them being a
+       simple size-limited string that can be associated to a size-limited
+       string value.
+
+       The header <sys/system_properties.h> can be used to read system
+       properties and also defines the maximum size of keys and values.
+
+   - Android-specific user/group management:
+
+       There is no /etc/passwd or /etc/groups in Android. By design, it is
+       meant to be used by a single handset user. On the other hand, Android
+       uses the Linux user/group management features extensively to secure
+       process permissions, like access to various filesystem directories.
+
+       In the Android scheme, each installed application gets its own
+       uid_t/gid_t starting from 10000; lower numerical ids are reserved for
+       system daemons.
+
+       getpwnam() recognizes some hard-coded subsystems names (e.g. "radio")
+       and will translate them to their low-user-id values. It also recognizes
+       "app_1234" as the synthetic name of the application that was installed
+       with uid 10000 + 1234, which is 11234. getgrnam() works similarly
+
+       getgrouplist() will always return a single group for any user name,
+       which is the one passed as an input parameter.
+
+       getgrgid() will similarly only return a structure that contains a
+       single-element members list, corresponding to the user with the same
+       numerical value than the group.
+
+       See bionic/libc/bionic/stubs.c for more details.
+
+    - getservent()
+
+       There is no /etc/services on Android. Instead the C library embeds a
+       constant list of services in its executable, which is parsed on demand
+       by the various functions that depend on it. See
+       bionic/libc/netbsd/net/getservent.c and
+       bionic/libc/netbsd/net/services.h
+
+       The list of services defined internally might change liberally in the
+       future. This feature is mostly historically and is very rarely used.
+
+       The getservent() returns thread-local data. getservbyport() and
+       getservbyname() are also implemented in a similar fashion.
+
+     - getprotoent()
+
+       There is no /etc/protocol on Android. Bionic does not currently
+       implement getprotoent() and related functions. If added, it will
+       likely be done in a way similar to getservent()
+
+DNS resolver:
+
+  Bionic uses a NetBSD-derived resolver library which has been modified in
+  the following ways:
+
+     - don't implement the name-server-switch feature (a.k.a. <nsswitch.h>)
+
+     - read /system/etc/resolv.conf instead of /etc/resolv.conf
+
+     - read the list of servers from system properties. the code looks for
+       'net.dns1', 'net.dns2', etc.. Each property should contain the IP
+       address of a DNS server.
+
+       these properties are set/modified by other parts of the Android system
+       (e.g. the dhcpd daemon).
+
+       the implementation also supports per-process DNS server list, using the
+       properties 'net.dns1.<pid>', 'net.dns2.<pid>', etc... Where <pid> stands
+       for the numerical ID of the current process.
+
+     - when performing a query, use a properly randomized Query ID (instead of
+       a incremented one), for increased security.
+
+     - when performing a query, bind the local client socket to a random port
+       for increased security.
+
+     - get rid of *many* unfortunate thread-safety issues in the original code
+
+  Bionic does *not* expose implementation details of its DNS resolver; the
+  content of <arpa/nameser.h> is intentionally blank. The resolver
+  implementation might change completely in the future.
+
+
+PThread Real-Time Timers:
+
+  timer_create(), timer_gettime(), timer_settime() and timer_getoverrun() are
+  supported.
+
+  Bionic also now supports SIGEV_THREAD real-time timers (see timer_create()).
+  The implementation simply uses a single thread per timer, unlike GLibc which
+  uses complex heuristics to try to use the less threads possible when several
+  timers with compatible properties are used.
+
+  This means that if your code uses a lot of SIGEV_THREAD timers, your program
+  may consume a lot of memory. However, if your program needs many of these
+  timers, it'd better handle timeout events directly instead.
+
+  Other timers (e.g. SIGEV_SIGNAL) are handled by the kernel and use much less
+  system resources.
+
+
+Binary Compatibility:
+
+  Bionic is *not* in any way binary-compatible with the GNU C Library, ucLibc
+  or any known Linux C library. This means several things:
+
+  - You cannot expect to build something against the GNU C Library headers and
+    have it dynamically link properly to Bionic later.
+
+  - You should *really* use the Android toolchain to build your program against
+    Bionic. The toolchain deals with many important details that are crucial
+    to get something working properly.
+
+  Failure to do so will usually result in the inability to run or link your
+  program, or even runtime crashes. Several random web pages on the Internet
+  describe how you can succesfully write a "hello-world" program with the
+  ARM GNU toolchain. These examples usually work by chance, if anything else,
+  and you should not follow these instructions unless you want to waste a lot
+  of your time in the process.
+
+  Note however that you *can* generate a binary that is built against the
+  GNU C Library headers and then statically linked to it. The corresponding
+  executable should be able to run (if it doesn't use dlopen()/dlsym())
+
+
+Dynamic Linker:
+
+  Bionic comes with its own dynamic linker (just like ld.so on Linux really
+  comes from GLibc). This linker does not support all the relocations
+  generated by other GCC ARM toolchains.
+
+
+C++ Exceptions Support:
+
+  At the moment, Bionic doesn't support C++ exceptions, what this really means
+  is the following:
+
+    - If pthread_once() is called with a C++ callback that throws an exception,
+      then the C library will keep the corresponding pthread_once_t mutex
+      locked. Any further call to pthread_once() will result in a deadlock.
+
+      A proper implementation should be able to register a C++ exception
+      cleanup handler before the callback to properly unlock the
+      pthread_once_t. Unfortunately this requires tricky assembly code that
+      is highly dependent on the compiler.
+
+      This feature is not planned to be supported anytime soon.
+
+    - The same problem may arise if you throw an exception within a callback
+      called from the C library. Fortunately, these cases are very rare in the
+      real-world, but any callback you provide to the C library should *not*
+      throw an exception.
+
+    - Bionic lacks a few support functions to have exception support work
+      properly.
+
+System V IPCs:
+
+  Bionic intentionally does not provide support for System-V IPCs mechanisms,
+  like the ones provided by semget(), shmget(), msgget(). The reason for this
+  is to avoid denial-of-service. For a detailed rationale about this, please
+  read the file docs/SYSV-IPCS.TXT.
+
+Include Paths:
+
+  The Android build system should automatically provide the necessary include
+  paths required to build against the C library headers. However, if you want
+  to do that yourself, you will need to add:
+
+      libc/arch-$ARCH/include
+      libc/include
+      libc/kernel/common
+      libc/kernel/arch-$ARCH
+
+  to your C include path.
diff --git a/ndk/docs/system/libc/SYSV-IPC.TXT b/ndk/docs/system/libc/SYSV-IPC.TXT
new file mode 100644
index 0000000..5a3eef0
--- /dev/null
+++ b/ndk/docs/system/libc/SYSV-IPC.TXT
@@ -0,0 +1,103 @@
+Android does not support System V IPCs, i.e. the facilities provided by the
+following standard Posix headers:
+
+  <sys/sem.h>   /* SysV semaphores */
+  <sys/shm.h>   /* SysV shared memory segments */
+  <sys/msg.h>   /* SysV message queues */
+  <sys/ipc.h>   /* General IPC definitions */
+
+The reason for this is due to the fact that, by design, they lead to global
+kernel resource leakage.
+
+For example, there is no way to automatically release a SysV semaphore
+allocated in the kernel when:
+
+- a buggy or malicious process exits
+- a non-buggy and non-malicious process crashes or is explicitely killed.
+
+Killing processes automatically to make room for new ones is an
+important part of Android's application lifecycle implementation. This means
+that, even assuming only non-buggy and non-malicious code, it is very likely
+that over time, the kernel global tables used to implement SysV IPCs will fill
+up.
+
+At that point, strange failures are likely to occur and prevent programs that
+use them to run properly until the next reboot of the system.
+
+And we can't ignore potential malicious applications. As a proof of concept
+here is a simple exploit that you can run on a standard Linux box today:
+
+--------------- cut here ------------------------
+#include <sys/sem.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#define  NUM_SEMAPHORES  32
+#define  MAX_FAILS       10
+
+int  main(void)
+{
+    int   counter = 0;
+    int   fails   = 0;
+
+    if (counter == IPC_PRIVATE)
+        counter++;
+
+    printf( "%d (NUM_SEMAPHORES=%d)\n", counter, NUM_SEMAPHORES);
+
+    for (;;) {
+        int  ret = fork();
+        int  status;
+
+        if (ret < 0) {
+            perror("fork:");
+            break;
+        }
+        if (ret == 0) {
+            /* in the child */
+            ret = semget( (key_t)counter, NUM_SEMAPHORES, IPC_CREAT );
+            if (ret < 0) {
+                return errno;
+            }
+            return 0;
+        }
+        else {
+            /* in the parent */
+            ret = wait(&status);
+            if (ret < 0) {
+                perror("waitpid:");
+                break;
+            }
+            if (status != 0) {
+                status = WEXITSTATUS(status);
+                fprintf(stderr, "child %d FAIL at counter=%d: %d\n", ret,
+                                counter, status);
+                if (++fails >= MAX_FAILS)
+                    break;
+            }
+        }
+
+        counter++;
+        if ((counter % 1000) == 0) {
+            printf("%d\n", counter);
+        }
+        if (counter == IPC_PRIVATE)
+            counter++;
+    }
+    return 0;
+}
+--------------- cut here ------------------------
+
+If you run it on a typical Linux distribution today, you'll discover that it
+will quickly fill up the kernel's table of unique key_t values, and that
+strange things will happen in some parts of the system, but not all.
+
+(You can use the "ipcs -u" command to get a summary describing the kernel
+ tables and their allocations)
+
+For example, in our experience, anything program launched after that that
+calls strerror() will simply crash. The USB sub-system starts spoutting weird
+errors to the system console, etc...
diff --git a/ndk/out/.gitignore b/ndk/out/.gitignore
new file mode 100644
index 0000000..ef2875b
--- /dev/null
+++ b/ndk/out/.gitignore
@@ -0,0 +1,2 @@
+# Ignore all generated files here
+*
diff --git a/ndk/sources/samples/Android.mk b/ndk/sources/samples/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/ndk/sources/samples/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/ndk/sources/samples/hello-jni/Android.mk b/ndk/sources/samples/hello-jni/Android.mk
new file mode 100644
index 0000000..6ccf381
--- /dev/null
+++ b/ndk/sources/samples/hello-jni/Android.mk
@@ -0,0 +1,22 @@
+# 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_MODULE    := hello-jni
+LOCAL_SRC_FILES := hello-jni.c
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/ndk/sources/samples/hello-jni/hello-jni.c b/ndk/sources/samples/hello-jni/hello-jni.c
new file mode 100644
index 0000000..632ac17
--- /dev/null
+++ b/ndk/sources/samples/hello-jni/hello-jni.c
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ *
+ */
+#include <string.h>
+#include <jni.h>
+
+/* This is a trivial JNI example where we use a native method
+ * to return a new VM String. See the corresponding Java source
+ * file located at:
+ *
+ *   apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java
+ */
+jstring
+Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
+                                                  jobject thiz )
+{
+    return (*env)->NewStringUTF(env, "Hello from JNI !");
+}
diff --git a/ndk/sources/samples/two-libs/Android.mk b/ndk/sources/samples/two-libs/Android.mk
new file mode 100644
index 0000000..eb3f018
--- /dev/null
+++ b/ndk/sources/samples/two-libs/Android.mk
@@ -0,0 +1,41 @@
+# 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 purpose of this sample is to demonstrate how one can
+# generate two distinct shared libraries and have them both
+# uploaded in
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+# first lib, which will be built statically
+#
+include $(CLEAR_VARS)
+
+LOCAL_MODULE    := libtwolib-first
+LOCAL_SRC_FILES := first.c
+
+include $(BUILD_STATIC_LIBRARY)
+
+# second lib, which will depend on and include the first one
+#
+include $(CLEAR_VARS)
+
+LOCAL_MODULE    := libtwolib-second
+LOCAL_SRC_FILES := second.c
+
+LOCAL_STATIC_LIBRARIES := libtwolib-first
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/ndk/sources/samples/two-libs/first.c b/ndk/sources/samples/two-libs/first.c
new file mode 100644
index 0000000..419d9bd
--- /dev/null
+++ b/ndk/sources/samples/two-libs/first.c
@@ -0,0 +1,6 @@
+#include "first.h"
+
+int  first(int  x, int  y)
+{
+    return x + y;
+}
diff --git a/ndk/sources/samples/two-libs/first.h b/ndk/sources/samples/two-libs/first.h
new file mode 100644
index 0000000..6116a38
--- /dev/null
+++ b/ndk/sources/samples/two-libs/first.h
@@ -0,0 +1,6 @@
+#ifndef FIRST_H
+#define FIRST_H
+
+extern int first(int  x, int  y);
+
+#endif /* FIRST_H */
diff --git a/ndk/sources/samples/two-libs/second.c b/ndk/sources/samples/two-libs/second.c
new file mode 100644
index 0000000..c44d184
--- /dev/null
+++ b/ndk/sources/samples/two-libs/second.c
@@ -0,0 +1,11 @@
+#include "first.h"
+#include <jni.h>
+
+jint
+Java_com_example_twolibs_TwoLibs_add( JNIEnv*  env,
+                                      jobject  this,
+                                      jint     x,
+                                      jint     y )
+{
+    return first(x, y);
+}
diff --git a/pdk/docs/guide/index.jd b/pdk/docs/guide/index.jd
index b59615f..acce1f7 100644
--- a/pdk/docs/guide/index.jd
+++ b/pdk/docs/guide/index.jd
@@ -3,9 +3,9 @@
 @jd:body
 
 
-<p>The Open Handset Distribution (OHD) is a isoftware distribution  for mobile devices, often referred to as Android, developed by members of the <a href="http://www.openhandsetalliance.com">Open Handset Alliance</a>. &nbsp;Android includes an operating system, middleware, and key applications typically required for mobile devices.</p>
+<p>The Open Handset Distribution (OHD) is a software distribution for mobile devices, often referred to as Android, developed by members of the <a href="http://www.openhandsetalliance.com">Open Handset Alliance</a>. &nbsp;Android includes an operating system, middleware, and key applications typically required for mobile devices.</p>
   
-<p>This porting guide describes the steps necessary to port Android to a new mobile device. &nbsp;Android is designed as a highly-portable, hardware-independent platform based on Linux, and porting the platform to new devices requires little more than porting the Linux kernel and developing the Linux drivers necessary for your device.</p>
+<p>This platform development kit describes the steps necessary to port Android to a new mobile device. &nbsp;Android is designed as a highly-portable, hardware-independent platform based on Linux, and porting the platform to new devices requires little more than porting the Linux kernel and developing the Linux drivers necessary for your device.</p>
   
 <p>The current version of this guide describes bringing Android up to "PDA-level" functionality; functionality sufficient to support non-multimedia apps that run on unconnected mobile devices through the standard user interface devices such as keypad and display. &nbsp;Future versions of this guide will cover complete telephony, multi-media and peripheral integration to create a complete mobile device.</p>
 
diff --git a/pdk/docs/guide/pdk_toc.cs b/pdk/docs/guide/pdk_toc.cs
index 5944ce3..a37e516 100644
--- a/pdk/docs/guide/pdk_toc.cs
+++ b/pdk/docs/guide/pdk_toc.cs
@@ -63,6 +63,14 @@
       <li><a href="<?cs var:toroot ?>guide/stk.html">SIM Toolkit Application (STK)</a></li>
     </ul>
   </li>
+
+  <li class="toggle-list">
+    <div><a href="javascript:nothing()">Misc</a></div>
+    <ul>
+      <li><a href="<?cs var:toroot ?>guide/lights.html">LEDs</a></li>
+    </ul>
+  </li>
+
 </ul>
 </li>
 
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index a53718e..d353d31 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -1104,6 +1104,13 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".view.Animation3" android:label="Views/Animation/Interpolators">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".view.LayoutAnimation1" android:label="Views/Layout Animation/1. Grid Fade">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/samples/ApiDemos/res/layout/animation_3.xml b/samples/ApiDemos/res/layout/animation_3.xml
new file mode 100644
index 0000000..4d1474c
--- /dev/null
+++ b/samples/ApiDemos/res/layout/animation_3.xml
@@ -0,0 +1,44 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:padding="10dip"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:clipToPadding="false">
+
+    <TextView
+        android:id="@+id/target"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="26sp"
+        android:text="@string/animation_3_text"/>
+
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="20dip"
+        android:layout_marginBottom="5dip"
+        android:text="@string/animation_2_instructions" />
+
+    <Spinner
+        android:id="@+id/spinner"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content" />
+
+</LinearLayout>
+
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index 0cafe14..29bbcec 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -476,6 +476,7 @@
     <string name="animation_2_text_3">a chance to be better.</string>
     <string name="animation_2_text_4">— Albert Camus</string>
     <string name="animation_2_instructions">Select an animation:</string>
+    <string name="animation_3_text">Interpolators</string>
     <string name="autocomplete_1_instructions">Type in the text field for auto-completion.</string>
     <string name="autocomplete_1_country">Country:</string>
     <string name="autocomplete_1_focus">Give me Focus</string>
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/StaticTriangleRenderer.java b/samples/ApiDemos/src/com/example/android/apis/graphics/StaticTriangleRenderer.java
new file mode 100644
index 0000000..c492e3f
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/StaticTriangleRenderer.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.graphics;
+
+import static android.opengl.GLES10.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+import android.opengl.GLUtils;
+import android.os.SystemClock;
+
+import com.example.android.apis.R;
+
+/**
+ * A GLSurfaceView.Renderer that uses the Android-specific
+ * android.opengl.GLESXXX static OpenGL ES APIs. The static APIs
+ * expose more of the OpenGL ES features than the
+ * javax.microedition.khronos.opengles APIs, and also
+ * provide a programming model that is closer to the C OpenGL ES APIs, which
+ * may make it easier to reuse code and documentation written for the
+ * C OpenGL ES APIs.
+ *
+ */
+public class StaticTriangleRenderer implements GLSurfaceView.Renderer{
+
+    public StaticTriangleRenderer(Context context) {
+        mContext = context;
+        mTriangle = new Triangle();
+    }
+
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+        /*
+         * By default, OpenGL enables features that improve quality
+         * but reduce performance. One might want to tweak that
+         * especially on software renderer.
+         */
+        glDisable(GL_DITHER);
+
+        /*
+         * Some one-time OpenGL initialization can be made here
+         * probably based on features of this particular context
+         */
+        glHint(GL_PERSPECTIVE_CORRECTION_HINT,
+                GL_FASTEST);
+
+        glClearColor(.5f, .5f, .5f, 1);
+        glShadeModel(GL_SMOOTH);
+        glEnable(GL_DEPTH_TEST);
+        glEnable(GL_TEXTURE_2D);
+
+        /*
+         * Create our texture. This has to be done each time the
+         * surface is created.
+         */
+
+        int[] textures = new int[1];
+        glGenTextures(1, textures, 0);
+
+        mTextureID = textures[0];
+        glBindTexture(GL_TEXTURE_2D, mTextureID);
+
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+                GL_NEAREST);
+        glTexParameterf(GL_TEXTURE_2D,
+                GL_TEXTURE_MAG_FILTER,
+                GL_LINEAR);
+
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+                GL_CLAMP_TO_EDGE);
+        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+                GL_CLAMP_TO_EDGE);
+
+        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
+                GL_REPLACE);
+
+        InputStream is = mContext.getResources()
+                .openRawResource(R.drawable.robot);
+        Bitmap bitmap;
+        try {
+            bitmap = BitmapFactory.decodeStream(is);
+        } finally {
+            try {
+                is.close();
+            } catch(IOException e) {
+                // Ignore.
+            }
+        }
+
+        GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
+        bitmap.recycle();
+    }
+
+    public void onDrawFrame(GL10 gl) {
+        /*
+         * By default, OpenGL enables features that improve quality
+         * but reduce performance. One might want to tweak that
+         * especially on software renderer.
+         */
+        glDisable(GL_DITHER);
+
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
+                GL_MODULATE);
+
+        /*
+         * Usually, the first thing one might want to do is to clear
+         * the screen. The most efficient way of doing this is to use
+         * glClear().
+         */
+
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+        /*
+         * Now we're ready to draw some 3D objects
+         */
+
+        glMatrixMode(GL_MODELVIEW);
+        glLoadIdentity();
+
+        GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+
+        glEnableClientState(GL_VERTEX_ARRAY);
+        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+        glActiveTexture(GL_TEXTURE0);
+        glBindTexture(GL_TEXTURE_2D, mTextureID);
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
+                GL_REPEAT);
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
+                GL_REPEAT);
+
+        long time = SystemClock.uptimeMillis() % 4000L;
+        float angle = 0.090f * ((int) time);
+
+        glRotatef(angle, 0, 0, 1.0f);
+
+        mTriangle.draw(gl);
+    }
+
+    public void onSurfaceChanged(GL10 gl, int w, int h) {
+        glViewport(0, 0, w, h);
+
+        /*
+        * Set our projection matrix. This doesn't have to be done
+        * each time we draw, but usually a new projection needs to
+        * be set when the viewport is resized.
+        */
+
+        float ratio = (float) w / h;
+        glMatrixMode(GL_PROJECTION);
+        glLoadIdentity();
+        glFrustumf(-ratio, ratio, -1, 1, 3, 7);
+    }
+
+    private Context mContext;
+    private Triangle mTriangle;
+    private int mTextureID;
+
+    static class Triangle {
+        public Triangle() {
+
+            // Buffers to be passed to gl*Pointer() functions
+            // must be direct, i.e., they must be placed on the
+            // native heap where the garbage collector cannot
+            // move them.
+            //
+            // Buffers with multi-byte datatypes (e.g., short, int, float)
+            // must have their byte order set to native order
+
+            ByteBuffer vbb = ByteBuffer.allocateDirect(VERTS * 3 * 4);
+            vbb.order(ByteOrder.nativeOrder());
+            mFVertexBuffer = vbb.asFloatBuffer();
+
+            ByteBuffer tbb = ByteBuffer.allocateDirect(VERTS * 2 * 4);
+            tbb.order(ByteOrder.nativeOrder());
+            mTexBuffer = tbb.asFloatBuffer();
+
+            ByteBuffer ibb = ByteBuffer.allocateDirect(VERTS * 2);
+            ibb.order(ByteOrder.nativeOrder());
+            mIndexBuffer = ibb.asShortBuffer();
+
+            // A unit-sided equilateral triangle centered on the origin.
+            float[] coords = {
+                    // X, Y, Z
+                    -0.5f, -0.25f, 0,
+                     0.5f, -0.25f, 0,
+                     0.0f,  0.559016994f, 0
+            };
+
+            for (int i = 0; i < VERTS; i++) {
+                for(int j = 0; j < 3; j++) {
+                    mFVertexBuffer.put(coords[i*3+j] * 2.0f);
+                }
+            }
+
+            for (int i = 0; i < VERTS; i++) {
+                for(int j = 0; j < 2; j++) {
+                    mTexBuffer.put(coords[i*3+j] * 2.0f + 0.5f);
+                }
+            }
+
+            for(int i = 0; i < VERTS; i++) {
+                mIndexBuffer.put((short) i);
+            }
+
+            mFVertexBuffer.position(0);
+            mTexBuffer.position(0);
+            mIndexBuffer.position(0);
+        }
+
+        public void draw(GL10 gl) {
+            glFrontFace(GL_CCW);
+            glVertexPointer(3, GL_FLOAT, 0, mFVertexBuffer);
+            glEnable(GL_TEXTURE_2D);
+            glTexCoordPointer(2, GL_FLOAT, 0, mTexBuffer);
+            glDrawElements(GL_TRIANGLE_STRIP, VERTS,
+                    GL_UNSIGNED_SHORT, mIndexBuffer);
+        }
+
+        private final static int VERTS = 3;
+
+        private FloatBuffer mFVertexBuffer;
+        private FloatBuffer mTexBuffer;
+        private ShortBuffer mIndexBuffer;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java
index e5b06f4..7d7cd4a 100644
--- a/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TriangleActivity.java
@@ -27,7 +27,7 @@
         super.onCreate(savedInstanceState);
         mGLView = new GLSurfaceView(this);
         mGLView.setEGLConfigChooser(false);
-        mGLView.setRenderer(new TriangleRenderer(this));
+        mGLView.setRenderer(new StaticTriangleRenderer(this));
         setContentView(mGLView);
     }
 
diff --git a/samples/ApiDemos/src/com/example/android/apis/media/MediaPlayerDemo_Video.java b/samples/ApiDemos/src/com/example/android/apis/media/MediaPlayerDemo_Video.java
index fd3c486..601c5a3 100644
--- a/samples/ApiDemos/src/com/example/android/apis/media/MediaPlayerDemo_Video.java
+++ b/samples/ApiDemos/src/com/example/android/apis/media/MediaPlayerDemo_Video.java
@@ -9,6 +9,8 @@
 import android.media.MediaPlayer;
 import android.media.MediaPlayer.OnBufferingUpdateListener;
 import android.media.MediaPlayer.OnCompletionListener;
+import android.media.MediaPlayer.OnPreparedListener;
+import android.media.MediaPlayer.OnVideoSizeChangedListener;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.SurfaceHolder;
@@ -21,7 +23,7 @@
 
 public class MediaPlayerDemo_Video extends Activity implements
         OnBufferingUpdateListener, OnCompletionListener,
-        MediaPlayer.OnPreparedListener, SurfaceHolder.Callback {
+        OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback {
 
     private static final String TAG = "MediaPlayerDemo";
     private int mVideoWidth;
@@ -37,6 +39,8 @@
     private static final int RESOURCES_AUDIO = 3;
     private static final int LOCAL_VIDEO = 4;
     private static final int STREAM_VIDEO = 5;
+    private boolean mIsVideoSizeKnown = false;
+    private boolean mIsVideoReadyToBePlayed = false;
 
     /**
      * 
@@ -54,6 +58,7 @@
     }
 
     private void playVideo(Integer Media) {
+        doCleanUp();
         try {
 
             switch (Media) {
@@ -109,6 +114,7 @@
             mMediaPlayer.setOnBufferingUpdateListener(this);
             mMediaPlayer.setOnCompletionListener(this);
             mMediaPlayer.setOnPreparedListener(this);
+            mMediaPlayer.setOnVideoSizeChangedListener(this);
             mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
 
 
@@ -126,15 +132,26 @@
         Log.d(TAG, "onCompletion called");
     }
 
+    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
+        Log.v(TAG, "onVideoSizeChanged called");
+        if (width == 0 || height == 0) {
+            Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
+            return;
+        }
+        mIsVideoSizeKnown = true;
+        mVideoWidth = width;
+        mVideoHeight = height;
+        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
+            startVideoPlayback();
+        }
+    }
+
     public void onPrepared(MediaPlayer mediaplayer) {
         Log.d(TAG, "onPrepared called");
-        mVideoWidth = mMediaPlayer.getVideoWidth();
-        mVideoHeight = mMediaPlayer.getVideoHeight();
-        if (mVideoWidth != 0 && mVideoHeight != 0) {
-            holder.setFixedSize(mVideoWidth, mVideoHeight);
-            mMediaPlayer.start();
+        mIsVideoReadyToBePlayed = true;
+        if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
+            startVideoPlayback();
         }
-
     }
 
     public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
@@ -148,7 +165,6 @@
 
 
     public void surfaceCreated(SurfaceHolder holder) {
-        // TODO Auto-generated method stub
         Log.d(TAG, "surfaceCreated called");
         playVideo(extras.getInt(MEDIA));
 
@@ -156,14 +172,36 @@
     }
 
     @Override
+    protected void onPause() {
+        super.onPause();
+        releaseMediaPlayer();
+        doCleanUp();
+    }
+
+    @Override
     protected void onDestroy() {
         super.onDestroy();
-        // TODO Auto-generated method stub
+        releaseMediaPlayer();
+        doCleanUp();
+    }
+
+    private void releaseMediaPlayer() {
         if (mMediaPlayer != null) {
             mMediaPlayer.release();
             mMediaPlayer = null;
         }
-
     }
 
+    private void doCleanUp() {
+        mVideoWidth = 0;
+        mVideoHeight = 0;
+        mIsVideoReadyToBePlayed = false;
+        mIsVideoSizeKnown = false;
+    }
+
+    private void startVideoPlayback() {
+        Log.v(TAG, "startVideoPlayback");
+        holder.setFixedSize(mVideoWidth, mVideoHeight);
+        mMediaPlayer.start();
+    }
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Animation3.java b/samples/ApiDemos/src/com/example/android/apis/view/Animation3.java
new file mode 100644
index 0000000..11fc9ed
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Animation3.java
@@ -0,0 +1,101 @@
+/*
+ * 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.example.android.apis.view;
+
+// Need the following import to get access to the app resources, since this
+// class is in a sub-package.
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Animation;
+import android.view.animation.TranslateAnimation;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Spinner;
+
+public class Animation3 extends Activity implements AdapterView.OnItemSelectedListener {
+    private static final String[] INTERPOLATORS = {
+            "Accelerate", "Decelerate", "Accelerate/Decelerate",
+            "Anticipate", "Overshoot", "Anticipate/Overshoot",
+            "Bounce"
+    };
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.animation_3);
+
+        Spinner s = (Spinner) findViewById(R.id.spinner);
+        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+                android.R.layout.simple_spinner_item, INTERPOLATORS);
+        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        s.setAdapter(adapter);
+        s.setOnItemSelectedListener(this);
+    }
+
+    public void onItemSelected(AdapterView parent, View v, int position, long id) {
+        final View target = findViewById(R.id.target);
+        final View targetParent = (View) target.getParent();
+
+        Animation a = new TranslateAnimation(0.0f,
+                targetParent.getWidth() - target.getWidth() - targetParent.getPaddingLeft() -
+                targetParent.getPaddingRight(), 0.0f, 0.0f);
+        a.setDuration(1000);
+        a.setStartOffset(300);
+        a.setRepeatMode(Animation.RESTART);
+        a.setRepeatCount(Animation.INFINITE);
+
+        switch (position) {
+            case 0:
+                a.setInterpolator(AnimationUtils.loadInterpolator(this,
+                        android.R.anim.accelerate_interpolator));
+                break;
+            case 1:
+                a.setInterpolator(AnimationUtils.loadInterpolator(this,
+                        android.R.anim.decelerate_interpolator));
+                break;
+            case 2:
+                a.setInterpolator(AnimationUtils.loadInterpolator(this,
+                        android.R.anim.accelerate_decelerate_interpolator));
+                break;
+            case 3:
+                a.setInterpolator(AnimationUtils.loadInterpolator(this,
+                        android.R.anim.anticipate_interpolator));
+                break;
+            case 4:
+                a.setInterpolator(AnimationUtils.loadInterpolator(this,
+                        android.R.anim.overshoot_interpolator));
+                break;
+            case 5:
+                a.setInterpolator(AnimationUtils.loadInterpolator(this,
+                        android.R.anim.anticipate_overshoot_interpolator));
+                break;
+            case 6:
+                a.setInterpolator(AnimationUtils.loadInterpolator(this,
+                        android.R.anim.bounce_interpolator));
+                break;
+        }
+
+        target.startAnimation(a);
+    }
+
+    public void onNothingSelected(AdapterView parent) {
+    }
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar4.java b/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar4.java
index ee396b3..86188f2 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar4.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar4.java
@@ -26,7 +26,7 @@
 
 
 /**
- * Demonstrates how to use an indetermiate progress indicator in the window's title bar.
+ * Demonstrates how to use an indeterminate progress indicator in the window's title bar.
  */
 public class ProgressBar4 extends Activity {
     private boolean mToggleIndeterminate = false;
diff --git a/samples/PlatformLibrary/Android.mk b/samples/PlatformLibrary/Android.mk
deleted file mode 100644
index afb54a2..0000000
--- a/samples/PlatformLibrary/Android.mk
+++ /dev/null
@@ -1,58 +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.
-#
-
-# This makefile shows how to build your own shared library that can be
-# shipped on the system of a phone, and included additional examples of
-# including JNI code with the library and writing client applications against it.
-
-LOCAL_PATH := $(call my-dir)
-
-# the library
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := samples
-
-# This is the target being built.
-LOCAL_MODULE:= com.example.android.platform_library
-
-# Only compile source java files for the platform library.
-LOCAL_SRC_FILES := $(call all-java-files-under, java)
-
-include $(BUILD_JAVA_LIBRARY)
-
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := com.example.android.platform_library.xml
-
-LOCAL_MODULE_TAGS := samples
-
-LOCAL_MODULE_CLASS := ETC
-
-# This will install the file in /system/etc/permissions
-#
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions
-
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-
-include $(BUILD_PREBUILT)
-
-# ============================================================
-
-# Also build all of the sub-targets under this one: the library's
-# associated JNI code, and a sample client of the library.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/PlatformLibrary/README.txt b/samples/PlatformLibrary/README.txt
deleted file mode 100644
index 5ce9d2f..0000000
--- a/samples/PlatformLibrary/README.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-Platform Library Example
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-
-This directory contains a full example of writing your own Android platform
-shared library, without changing the Android framework.  It also shows how to
-write JNI code for incorporating native code into the library, and a client
-application that uses the library.
-
-This example is ONLY for people working with the open source platform to
-create a system image that will be delivered on a device which will include
-a custom library as shown here.  It can not be used to create a third party
-shared library, which is not currently supported in Android.
-
-To declare your library to the framework, you must place a file with a .xml
-extension in the /system/etc/permissions directory with the following contents:
-
-<?xml version="1.0" encoding="utf-8"?>
-<permissions>
-    <library name="com.example.android.platform_library"
-            file="/system/framework/com.example.android.platform_library.jar"/>
-</permissions>
-
-There are three major parts of this example, supplying three distinct
-build targets and corresponding build outputs:
-
-
-com.example.android.platform_library
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The top-level Android.mk defines the rules to build the shared library itself,
-whose target is "com.example.android.platform_library".  The code for this
-library lives under java/.
-
-Note that the product for this library is a raw .jar file, NOT a .apk, which
-means there is no manifest or resources associated with the library.
-Unfortunately this means that if you need any resources for the library, such
-as drawables or layout files, you will need to add these to the core framework
-resources under frameworks/base/res.  Please make sure when doing this that
-you do not make any of these resources public, they should not become part of
-the Android API.  In the future we will allow shared libraries to have their
-own resources.
-
-Other than that, the library is very straight-forward, and you can write
-basically whatever code you want.  You can also put code in other Java
-namespaces -- the namespace given in the <library> tag above is just the
-public unique name by which clients will link to your library, but once this
-link happens all of the Java namespaces in that library will be available
-to the client.
-
-
-libplatform_library_jni
-~~~~~~~~~~~~~~~~~~~~~~~
-
-This is an optional example of how to write JNI code associated with a
-shared library.  This code lives under jni/.  The jni/Android.mk file defines
-the rules for building the final .so in which the code lives.  This example
-provides everything needed to hook up the native code with the Java library
-and call through to it, plus a very simple JNI call.
-
-
-PlatformLibraryClient
-~~~~~~~~~~~~~~~~~~~~~
-
-This shows an example of how you can write client applications for your new
-shared library.  This code lives under client/.  Note that the example is
-simply a regular Android .apk, like all of the other .apks created by the
-build system.  The only two special things needed to use your library are:
-
-- A LOCAL_JAVA_LIBRARIES line in the Android.mk to have the build system link
-against your shared library.
-
-- A <uses-library> line in the AndroidManifest.xml to have the runtime load
-your library into the application.
diff --git a/samples/PlatformLibrary/client/Android.mk b/samples/PlatformLibrary/client/Android.mk
deleted file mode 100644
index cfd5493..0000000
--- a/samples/PlatformLibrary/client/Android.mk
+++ /dev/null
@@ -1,37 +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.
-#
-
-# This makefile is an example of writing an application that will link against
-# a custom shared library included with an Android system.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := samples
-
-# This is the target being built.
-LOCAL_PACKAGE_NAME := PlatformLibraryClient
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-# Link against the current Android SDK.
-LOCAL_SDK_VERSION := current
-
-# Also link against our own custom library.
-LOCAL_JAVA_LIBRARIES := com.example.android.platform_library
-
-include $(BUILD_PACKAGE)
diff --git a/samples/PlatformLibrary/client/AndroidManifest.xml b/samples/PlatformLibrary/client/AndroidManifest.xml
deleted file mode 100644
index be0d9a1..0000000
--- a/samples/PlatformLibrary/client/AndroidManifest.xml
+++ /dev/null
@@ -1,36 +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.
--->
-
-<!-- This is an example of writing a client application for a custom
-     platform library. -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.example.android.platform_library.client">
-    
-    <application android:label="Platform Lib Client">
-    
-        <!-- This tells the system about the custom library used by the
-             application, so that it can be properly loaded and linked
-             to the app when the app is initialized. -->
-        <uses-library android:name="com.example.android.platform_library" />
-        
-        <activity android:name="Client">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN"/>
-                <category android:name="android.intent.category.LAUNCHER"/>
-            </intent-filter>
-        </activity>
-    </application>
-</manifest>
diff --git a/samples/PlatformLibrary/client/src/com/example/android/platform_library/client/Client.java b/samples/PlatformLibrary/client/src/com/example/android/platform_library/client/Client.java
deleted file mode 100644
index 8722c72..0000000
--- a/samples/PlatformLibrary/client/src/com/example/android/platform_library/client/Client.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.example.android.platform_library.client;
-
-import com.example.android.platform_library.PlatformLibrary;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.widget.TextView;
-
-/**
- * Use a custom platform library.
- */
-public class Client extends Activity {
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // Call an API on the library.
-        PlatformLibrary pl = new PlatformLibrary();
-        int res = pl.getInt(false);
-        
-        // We'll just make our own view to show the result.
-        TextView tv = new TextView(this);
-        tv.setText("Got from lib: " + res);
-        setContentView(tv);
-    }
-}
-
diff --git a/samples/PlatformLibrary/com.example.android.platform_library.xml b/samples/PlatformLibrary/com.example.android.platform_library.xml
deleted file mode 100644
index b9491d8..0000000
--- a/samples/PlatformLibrary/com.example.android.platform_library.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<permissions>
-    <library name="com.example.android.platform_library"
-            file="/system/framework/com.example.android.platform_library.jar"/>
-</permissions>
diff --git a/samples/PlatformLibrary/java/com/example/android/platform_library/PlatformLibrary.java b/samples/PlatformLibrary/java/com/example/android/platform_library/PlatformLibrary.java
deleted file mode 100644
index 68154ec..0000000
--- a/samples/PlatformLibrary/java/com/example/android/platform_library/PlatformLibrary.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.example.android.platform_library;
-
-import android.util.Config;
-import android.util.Log;
-
-public final class PlatformLibrary {    
-    static {
-        /*
-         * Load the library.  If it's already loaded, this does nothing.
-         */
-        System.loadLibrary("platform_library_jni");
-    }
-
-    private int mJniInt = -1;
-
-    public PlatformLibrary() {}
-
-    /*
-     * Test native methods.
-     */
-    public int getInt(boolean bad) {
-        /* this alters mJniInt */
-        int result = getJniInt(bad);
-
-        /* reverse a string, for no very good reason */
-        String reverse = reverseString("Android!");
-
-        Log.i("PlatformLibrary", "getInt: " + result + ", '" + reverse + "'");
-
-        return mJniInt;
-    }
-
-    /*
-     * Simple method, called from native code.
-     */
-    private static void yodel(String msg) {
-        Log.d("PlatformLibrary", "yodel: " + msg);
-    }
-
-    /*
-     * Trivial native method call.  If "bad" is true, this will throw an
-     * exception.
-     */
-    native private int getJniInt(boolean bad);
-
-    /*
-     * Native method that returns a new string that is the reverse of
-     * the original.  This also calls yodel().
-     */
-    native private static String reverseString(String str);
-}
diff --git a/samples/PlatformLibrary/jni/Android.mk b/samples/PlatformLibrary/jni/Android.mk
deleted file mode 100644
index 1bdefa1..0000000
--- a/samples/PlatformLibrary/jni/Android.mk
+++ /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.
-#
-
-# This makefile supplies the rules for building a library of JNI code for
-# use by our example platform shared library.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := samples
-
-# This is the target being built.
-LOCAL_MODULE:= libplatform_library_jni
-
-# All of the source files that we will compile.
-LOCAL_SRC_FILES:= \
-	PlatformLibrary.cpp
-
-# All of the shared libraries we link against.
-LOCAL_SHARED_LIBRARIES := \
-	libandroid_runtime \
-	libnativehelper \
-	libcutils \
-	libutils
-
-# No static libraries.
-LOCAL_STATIC_LIBRARIES :=
-
-# Also need the JNI headers.
-LOCAL_C_INCLUDES += \
-	$(JNI_H_INCLUDE)
-
-# No specia compiler flags.
-LOCAL_CFLAGS +=
-
-# Don't prelink this library.  For more efficient code, you may want
-# to add this library to the prelink map and set this to true.
-LOCAL_PRELINK_MODULE := false
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/samples/PlatformLibrary/jni/PlatformLibrary.cpp b/samples/PlatformLibrary/jni/PlatformLibrary.cpp
deleted file mode 100644
index ad60002..0000000
--- a/samples/PlatformLibrary/jni/PlatformLibrary.cpp
+++ /dev/null
@@ -1,273 +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.
- */
-
-#define LOG_TAG "PlatformLibrary"
-#include "utils/Log.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <assert.h>
-
-#include "jni.h"
-
-
-// ----------------------------------------------------------------------------
-
-/*
- * Field/method IDs and class object references.
- *
- * You should not need to store the JNIEnv pointer in here.  It is
- * thread-specific and will be passed back in on every call.
- */
-static struct {
-    jclass      platformLibraryClass;
-    jfieldID    jniInt;
-    jmethodID   yodel;
-} gCachedState;
-
-// ----------------------------------------------------------------------------
-
-/*
- * Helper function to throw an arbitrary exception.
- *
- * Takes the exception class name, a format string, and one optional integer
- * argument (useful for including an error code, perhaps from errno).
- */
-static void throwException(JNIEnv* env, const char* ex, const char* fmt,
-    int data) {
-
-    if (jclass cls = env->FindClass(ex)) {
-        if (fmt != NULL) {
-            char msg[1000];
-            snprintf(msg, sizeof(msg), fmt, data);
-            env->ThrowNew(cls, msg);
-        } else {
-            env->ThrowNew(cls, NULL);
-        }
-
-        /*
-         * This is usually not necessary -- local references are released
-         * automatically when the native code returns to the VM.  It's
-         * required if the code doesn't actually return, e.g. it's sitting
-         * in a native event loop.
-         */
-        env->DeleteLocalRef(cls);
-    }
-}
-
-/*
- * Trivial sample method.
- *
- * If "bad" is true, this throws an exception.  Otherwise, this sets the
- * "mJniInt" field to 42 and returns 24.
- */
-static jint PlatformLibrary_getJniInt(JNIEnv* env, jobject thiz, jboolean bad) {
-    if (bad) {
-        throwException(env, "java/lang/IllegalStateException",
-                "you are bad", 0);
-        return 0;       /* return value will be ignored */
-    }
-    env->SetIntField(thiz, gCachedState.jniInt, 42);
-    return (jint)24;
-}
-
-/*
- * A more complex sample method.
- *
- * This takes a String as an argument, and returns a new String with
- * characters in reverse order.  The new string is passed to another method.
- * This demonstrates basic String manipulation functions and method
- * invocation.
- *
- * This method is declared "static", so there's no "this" pointer; instead,
- * we get a pointer to the class object.
- */
-static jstring PlatformLibrary_reverseString(JNIEnv* env, jclass clazz,
-    jstring str) {
-
-    if (str == NULL) {
-        throwException(env, "java/lang/NullPointerException", NULL, 0);
-        return NULL;
-    }
-
-    /*
-     * Get a pointer to the string's UTF-16 character data.  The data
-     * may be a copy or a pointer to the original.  Since String data
-     * is immutable, we're not allowed to touch it.
-     */
-    const jchar* strChars = env->GetStringChars(str, NULL);
-    if (strChars == NULL) {
-        /* something went wrong */
-        LOGW("Couldn't get string chars\n");
-        return NULL;
-    }
-    jsize strLength = env->GetStringLength(str);
-
-    /*
-     * Write a progress message to the log.  Log messages are UTF-8, so
-     * we want to convert the string to show it.
-     */
-    const char* printable = env->GetStringUTFChars(str, NULL);
-    if (printable != NULL) {
-        LOGD("Reversing string '%s'\n", printable);
-        env->ReleaseStringUTFChars(str, printable);
-    }
-
-    /*
-     * Copy the characters to temporary storage, reversing as we go.
-     */
-    jchar tempChars[strLength];
-    for (int i = 0; i < strLength; i++) {
-        tempChars[i] = strChars[strLength -1 -i];
-    }
-
-    /*
-     * Release the original String.  That way, if something fails later on,
-     * we don't have to worry about this leading to a memory leak.
-     */
-    env->ReleaseStringChars(str, strChars);
-    strChars = NULL;            /* this pointer no longer valid */
-
-    /*
-     * Create a new String with the chars.
-     */
-    jstring result = env->NewString(tempChars, strLength);
-    if (result == NULL) {
-        LOGE("NewString failed\n");
-        return NULL;
-    }
-
-    /*
-     * Now let's do something with it.  We already have the methodID for
-     * "yodel", so we can invoke it directly.  It's in our class, so we
-     * can use the Class object reference that was passed in.
-     */
-    env->CallStaticVoidMethod(clazz, gCachedState.yodel, result);
-
-    return result;
-}
-
-
-// ----------------------------------------------------------------------------
-
-/*
- * Array of methods.
- *
- * Each entry has three fields: the name of the method, the method
- * signature, and a pointer to the native implementation.
- */
-static const JNINativeMethod gMethods[] = {
-    { "getJniInt",          "(Z)I",
-                        (void*)PlatformLibrary_getJniInt },
-    { "reverseString",      "(Ljava/lang/String;)Ljava/lang/String;",
-                        (void*)PlatformLibrary_reverseString },
-};
-
-/*
- * Do some (slow-ish) lookups now and save the results.
- *
- * Returns 0 on success.
- */
-static int cacheIds(JNIEnv* env, jclass clazz) {
-    /*
-     * Save the class in case we want to use it later.  Because this is a
-     * reference to the Class object, we need to convert it to a JNI global
-     * reference.
-     */
-    gCachedState.platformLibraryClass = (jclass) env->NewGlobalRef(clazz);
-    if (clazz == NULL) {
-        LOGE("Can't create new global ref\n");
-        return -1;
-    }
-
-    /*
-     * Cache field and method IDs.  IDs are not references, which means we
-     * don't need to call NewGlobalRef on them.
-     */
-    gCachedState.jniInt = env->GetFieldID(clazz, "mJniInt", "I");
-    if (gCachedState.jniInt == NULL) {
-        LOGE("Can't find PlatformLibrary.mJniInt\n");
-        return -1;
-    }
-
-    gCachedState.yodel = env->GetStaticMethodID(clazz, "yodel",
-        "(Ljava/lang/String;)V");
-    if (gCachedState.yodel == NULL) {
-        LOGE("Can't find PlatformLibrary.yodel\n");
-        return -1;
-    }
-
-    return 0;
-}
-
-/*
- * Explicitly register all methods for our class.
- *
- * While we're at it, cache some class references and method/field IDs.
- *
- * Returns 0 on success.
- */
-static int registerMethods(JNIEnv* env) {
-    static const char* const kClassName =
-        "com/example/android/platform_library/PlatformLibrary";
-    jclass clazz;
-
-    /* look up the class */
-    clazz = env->FindClass(kClassName);
-    if (clazz == NULL) {
-        LOGE("Can't find class %s\n", kClassName);
-        return -1;
-    }
-
-    /* register all the methods */
-    if (env->RegisterNatives(clazz, gMethods,
-            sizeof(gMethods) / sizeof(gMethods[0])) != JNI_OK)
-    {
-        LOGE("Failed registering methods for %s\n", kClassName);
-        return -1;
-    }
-
-    /* fill out the rest of the ID cache */
-    return cacheIds(env, clazz);
-}
-
-// ----------------------------------------------------------------------------
-
-/*
- * This is called by the VM when the shared library is first loaded.
- */
-jint JNI_OnLoad(JavaVM* vm, void* reserved) {
-    JNIEnv* env = NULL;
-    jint result = -1;
-
-    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
-        LOGE("ERROR: GetEnv failed\n");
-        goto bail;
-    }
-    assert(env != NULL);
-
-    if (registerMethods(env) != 0) {
-        LOGE("ERROR: PlatformLibrary native registration failed\n");
-        goto bail;
-    }
-
-    /* success -- return valid version number */
-    result = JNI_VERSION_1_4;
-
-bail:
-    return result;
-}
diff --git a/simulator/wrapsim/Android.mk b/simulator/wrapsim/Android.mk
index ca9a592..0b7890d 100644
--- a/simulator/wrapsim/Android.mk
+++ b/simulator/wrapsim/Android.mk
@@ -22,7 +22,8 @@
 	Init.c \
 	Intercept.c \
 	Log.c \
-	SimMgr.c
+	SimMgr.c \
+	SysPower.c
 
 LOCAL_C_INCLUDES += prebuilt/common/esd
 
diff --git a/simulator/wrapsim/FakeDev.c b/simulator/wrapsim/FakeDev.c
index 3e223d3..7d2494e 100644
--- a/simulator/wrapsim/FakeDev.c
+++ b/simulator/wrapsim/FakeDev.c
@@ -67,6 +67,9 @@
     { "/dev/input/*",           NULL },
     { "/dev/log/*",             wsOpenDevLog },
     { "/sys/class/power_supply/*", wsOpenDevPower },
+    { "/sys/power/state",       wsOpenSysPower },
+    { "/sys/power/wake_lock",   wsOpenSysPower },
+    { "/sys/power/wake_unlock", wsOpenSysPower },
     { "/sys/devices/platform/android-vibrator/enable",  wsOpenDevVibrator },
     { "/sys/qemu_trace/*",      NULL },
     { NULL,                     NULL }
diff --git a/simulator/wrapsim/FakeDev.h b/simulator/wrapsim/FakeDev.h
index eacbbf5..4781cfc 100644
--- a/simulator/wrapsim/FakeDev.h
+++ b/simulator/wrapsim/FakeDev.h
@@ -108,6 +108,7 @@
 FakeDev* wsOpenDevFb(const char* pathName, int flags);
 FakeDev* wsOpenDevLog(const char* pathName, int flags);
 FakeDev* wsOpenDevPower(const char* pathName, int flags);
+FakeDev* wsOpenSysPower(const char* pathName, int flags);
 FakeDev* wsOpenDevVibrator(const char* pathName, int flags);
 
 /*
diff --git a/simulator/wrapsim/Intercept.c b/simulator/wrapsim/Intercept.c
index 29b0e00..49d77ee 100644
--- a/simulator/wrapsim/Intercept.c
+++ b/simulator/wrapsim/Intercept.c
@@ -127,6 +127,7 @@
      */
     if (origPath[0] != '/')
         goto skip_rewrite;
+    while (origPath[1] == '/') origPath++; // some apps like to use paths like '//data/data/....'
     if (memcmp(origPath+1, "system", 6) == 0 &&
         (origPath[7] == '/' || origPath[7] == '\0'))
             goto do_rewrite;
diff --git a/simulator/wrapsim/SysPower.c b/simulator/wrapsim/SysPower.c
new file mode 100644
index 0000000..fa7ae0a
--- /dev/null
+++ b/simulator/wrapsim/SysPower.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2009 The Android Open Source Project
+ *
+ * Magic entries in /sys/power/.
+ */
+#include "Common.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+/*
+ * Map filename to device index.
+ *
+ * [ not using DeviceIndex -- would be useful if we need to return something
+ * other than a static string ]
+ */
+static const struct {
+    const char*     name;
+    //DeviceIndex     idx;
+    const char*     data;
+} gDeviceMap[] = {
+    { "state",
+        "mem\n" },
+    { "wake_lock",
+        "\n" },
+    { "wake_unlock",
+        "KeyEvents PowerManagerService radio-interface\n" },
+};
+
+/*
+ * Power driver state.
+ *
+ * Right now we just ignore everything written.
+ */
+typedef struct PowerState {
+    int         which;
+} PowerState;
+
+
+/*
+ * Figure out who we are, based on "pathName".
+ */
+static void configureInitialState(const char* pathName, PowerState* powerState)
+{
+    const char* cp = pathName + strlen("/sys/power/");
+    int i;
+
+    powerState->which = -1;
+    for (i = 0; i < (int) (sizeof(gDeviceMap) / sizeof(gDeviceMap[0])); i++) {
+        if (strcmp(cp, gDeviceMap[i].name) == 0) {
+            powerState->which = i;
+            break;
+        }
+    }
+
+    if (powerState->which == -1) {
+        wsLog("Warning: access to unknown power device '%s'\n", pathName);
+        return;
+    }
+}
+
+/*
+ * Free up the state structure.
+ */
+static void freeState(PowerState* powerState)
+{
+    free(powerState);
+}
+
+/*
+ * Read data from the device.
+ *
+ * We don't try to keep track of how much was read -- existing clients just
+ * try to read into a large buffer.
+ */
+static ssize_t readPower(FakeDev* dev, int fd, void* buf, size_t count)
+{
+    PowerState* state = (PowerState*) dev->state;
+    int dataLen;
+
+    wsLog("%s: read %d\n", dev->debugName, count);
+
+    if (state->which < 0 ||
+        state->which >= (int) (sizeof(gDeviceMap)/sizeof(gDeviceMap[0])))
+    {
+        return 0;
+    }
+
+    const char* data = gDeviceMap[state->which].data;
+    size_t strLen = strlen(data);
+
+    while(strLen == 0)
+        sleep(10); // block forever
+
+    ssize_t copyCount = (strLen < count) ? strLen : count;
+    memcpy(buf, data, copyCount);
+    return copyCount;
+}
+
+/*
+ * Ignore the request.
+ */
+static ssize_t writePower(FakeDev* dev, int fd, const void* buf, size_t count)
+{
+    wsLog("%s: write %d bytes\n", dev->debugName, count);
+    return count;
+}
+
+/*
+ * Free up our state before closing down the fake descriptor.
+ */
+static int closePower(FakeDev* dev, int fd)
+{
+    freeState((PowerState*)dev->state);
+    dev->state = NULL;
+    return 0;
+}
+
+/*
+ * Open a power device.
+ */
+FakeDev* wsOpenSysPower(const char* pathName, int flags)
+{
+    FakeDev* newDev = wsCreateFakeDev(pathName);
+    if (newDev != NULL) {
+        newDev->read = readPower;
+        newDev->write = writePower;
+        newDev->ioctl = NULL;
+        newDev->close = closePower;
+
+        PowerState* powerState = calloc(1, sizeof(PowerState));
+
+        configureInitialState(pathName, powerState);
+        newDev->state = powerState;
+    }
+
+    return newDev;
+}
+
diff --git a/testrunner/.gitignore b/testrunner/.gitignore
new file mode 100644
index 0000000..0d20b64
--- /dev/null
+++ b/testrunner/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/testrunner/adb_interface.py b/testrunner/adb_interface.py
index ad1b2c9..b1e3757 100755
--- a/testrunner/adb_interface.py
+++ b/testrunner/adb_interface.py
@@ -64,7 +64,7 @@
       string output of command
 
     Raises:
-      WaitForResponseTimedOutError if device does not respond to command
+      WaitForResponseTimedOutError if device does not respond to command within time
     """
     adb_cmd = "adb %s %s" % (self._target_arg, command_string)
     logger.SilentLog("about to run %s" % adb_cmd)
@@ -157,8 +157,9 @@
     separated into its package and runner components.
     """
     instrumentation_path = "%s/%s" % (package_name, runner_name)
-    return self.StartInstrumentation(self, instrumentation_path, timeout_time,
-                                     no_window_animation, instrumentation_args)
+    return self.StartInstrumentation(instrumentation_path, timeout_time=timeout_time,
+                                     no_window_animation=no_window_animation,
+                                     instrumentation_args=instrumentation_args)
 
   def StartInstrumentation(
       self, instrumentation_path, timeout_time=60*10, no_window_animation=False,
@@ -203,7 +204,7 @@
         instrumentation_path, no_window_animation=no_window_animation,
         profile=profile, raw_mode=True,
         instrumentation_args=instrumentation_args)
-
+    logger.Log(command_string)
     (test_results, inst_finished_bundle) = (
         am_instrument_parser.ParseAmInstrumentOutput(
             self.SendShellCommand(command_string, timeout_time=timeout_time,
@@ -217,7 +218,7 @@
       short_msg_result = "no error message"
       if "shortMsg" in inst_finished_bundle:
         short_msg_result = inst_finished_bundle["shortMsg"]
-        logger.Log(short_msg_result)
+        logger.Log("Error! Test run failed: %s" % short_msg_result)
       raise errors.InstrumentationError(short_msg_result)
 
     if "INSTRUMENTATION_ABORTED" in inst_finished_bundle:
@@ -327,32 +328,30 @@
       
     Raises:
       WaitForResponseTimedOutError if package manager does not respond
+      AbortError if unrecoverable error occurred
     """
-    output = self.SendCommand("sync", retry_count=retry_count)
+    output = ""
+    error = None
+    try:
+      output = self.SendCommand("sync", retry_count=retry_count)
+    except errors.AbortError, e:
+      error = e
+      output = e.msg
     if "Read-only file system" in output:
       logger.SilentLog(output) 
       logger.Log("Remounting read-only filesystem")
       self.SendCommand("remount")
       output = self.SendCommand("sync", retry_count=retry_count)
-    if "No space left on device" in output:
+    elif "No space left on device" in output:
       logger.SilentLog(output) 
       logger.Log("Restarting device runtime")
       self.SendShellCommand("stop", retry_count=retry_count)
       output = self.SendCommand("sync", retry_count=retry_count)
       self.SendShellCommand("start", retry_count=retry_count)
-
+    elif error is not None:
+      # exception occurred that cannot be recovered from
+      raise error
     logger.SilentLog(output)
     self.WaitForDevicePm()
     return output
-  
-  def IsDevicePresent(self):
-    """Check if targeted device is present.
 
-    Returns:
-      True if device is present, False otherwise.
-    """
-    output = self.SendShellCommand("ls", retry_count=0)
-    if output.startswith("error:"):
-      return False
-    else:
-      return True
diff --git a/testrunner/android_build.py b/testrunner/android_build.py
index ca43ece..976f2bb 100644
--- a/testrunner/android_build.py
+++ b/testrunner/android_build.py
@@ -3,22 +3,24 @@
 #
 # 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 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
 #
-#     http://www.apache.org/licenses/LICENSE-2.0 
+#     http://www.apache.org/licenses/LICENSE-2.0
 #
-# Unless required by applicable law or agreed to in writing, software 
-# distributed under the License is distributed on an "AS IS" BASIS, 
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-# See the License for the specific language governing permissions and 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
 # limitations under the License.
 
 """Contains utility functions for interacting with the Android build system."""
 
 # Python imports
 import os
+import re
+import subprocess
 
 # local imports
 import errors
@@ -38,8 +40,96 @@
     AbortError: if Android build root could not be found.
   """
   # TODO: does this need to be reimplemented to be like gettop() in envsetup.sh
-  root_path = os.getenv('ANDROID_BUILD_TOP')
+  root_path = os.getenv("ANDROID_BUILD_TOP")
   if root_path is None:
-    logger.Log('Error: ANDROID_BUILD_TOP not defined. Please run envsetup.sh')
+    logger.Log("Error: ANDROID_BUILD_TOP not defined. Please run envsetup.sh")
     raise errors.AbortError
   return root_path
+
+
+def GetHostOsArch():
+  """Identify the host os and arch.
+
+  Returns:
+    The triple (HOST_OS, HOST_ARCH, HOST_OS-HOST_ARCH).
+
+  Raises:
+    AbortError: If the os and/or arch could not be found.
+  """
+  command = ("CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core "
+             "make --no-print-directory -C \"%s\" -f build/core/config.mk "
+             "dumpvar-report_config") % GetTop()
+
+  # Use the shell b/c we set some env variables before the make command.
+  config = subprocess.Popen(command, stdout=subprocess.PIPE,
+                            shell=True).communicate()[0]
+  host_os = re.search("HOST_OS=(\w+)", config).group(1)
+  host_arch = re.search("HOST_ARCH=(\w+)", config).group(1)
+  if not (host_os and host_arch):
+    logger.Log("Error: Could not get host's OS and/or ARCH")
+    raise errors.AbortError
+  return (host_os, host_arch, "%s-%s" % (host_os, host_arch))
+
+
+def GetHostBin():
+  """Compute the full pathname to the host binary directory.
+
+  Typically $ANDROID_BUILD_TOP/out/host/linux-x86/bin.
+
+  Assumes build environment has been properly configured by envsetup &
+  lunch/choosecombo.
+
+  Returns:
+    The absolute file path of the Android host binary directory.
+
+  Raises:
+    AbortError: if Android host binary directory could not be found.
+  """
+  (_, _, os_arch) = GetHostOsArch()
+  path = os.path.join(GetTop(), "out", "host", os_arch, "bin")
+  if not os.path.exists(path):
+    logger.Log("Error: Host bin path could not be found %s" % path)
+    raise errors.AbortError
+  return path
+
+
+def GetProductOut():
+  """Returns the full pathname to the target/product directory.
+
+  Typically the value of the env variable $ANDROID_PRODUCT_OUT.
+
+  Assumes build environment has been properly configured by envsetup &
+  lunch/choosecombo.
+
+  Returns:
+    The absolute file path of the Android product directory.
+
+  Raises:
+    AbortError: if Android product directory could not be found.
+  """
+  path = os.getenv("ANDROID_PRODUCT_OUT")
+  if path is None:
+    logger.Log("Error: ANDROID_PRODUCT_OUT not defined. Please run envsetup.sh")
+    raise errors.AbortError
+  return path
+
+
+def GetTargetSystemBin():
+  """Returns the full pathname to the target/product system/bin directory.
+
+  Typically the value of the env variable $ANDROID_PRODUCT_OUT/system/bin
+
+  Assumes build environment has been properly configured by envsetup &
+  lunch/choosecombo.
+
+  Returns:
+    The absolute file path of the Android target system bin directory.
+
+  Raises:
+    AbortError: if Android target system bin directory could not be found.
+  """
+  path = os.path.join(GetProductOut(), "system", "bin")
+  if not os.path.exists(path):
+    logger.Log("Error: Target system bin path could not be found")
+    raise errors.AbortError
+  return path
diff --git a/testrunner/coverage.py b/testrunner/coverage.py
index 39a2ceb..c80eea0 100755
--- a/testrunner/coverage.py
+++ b/testrunner/coverage.py
@@ -44,16 +44,15 @@
     # path to EMMA host jar, relative to Android build root
   _EMMA_JAR = os.path.join(_EMMA_BUILD_PATH, "lib", "emma.jar")
   _TEST_COVERAGE_EXT = "ec"
-  # default device-side path to code coverage results file
-  _DEVICE_COVERAGE_PATH = "/sdcard/coverage.ec"
   # root path of generated coverage report files, relative to Android build root
   _COVERAGE_REPORT_PATH = os.path.join("out", "emma")
+  _TARGET_DEF_FILE = "coverage_targets.xml"
   _CORE_TARGET_PATH = os.path.join("development", "testrunner",
-                                   "coverage_targets.xml")
+                                   _TARGET_DEF_FILE)
   # vendor glob file path patterns to tests, relative to android
   # build root
   _VENDOR_TARGET_PATH = os.path.join("vendor", "*", "tests", "testinfo",
-                                     "coverage_targets.xml")
+                                     _TARGET_DEF_FILE)
 
   # path to root of target build intermediates
   _TARGET_INTERMEDIATES_BASE_PATH = os.path.join("out", "target", "common",
@@ -93,7 +92,7 @@
       return False
 
   def ExtractReport(self, test_suite,
-                    device_coverage_path=_DEVICE_COVERAGE_PATH,
+                    device_coverage_path,
                     output_path=None):
     """Extract runtime coverage data and generate code coverage report.
 
@@ -122,8 +121,14 @@
       report_path = os.path.join(output_path,
                                  test_suite.GetName())
       target = self._targets_manifest.GetTarget(test_suite.GetTargetName())
-      return self._GenerateReport(report_path, coverage_local_path, [target],
-                                  do_src=True)
+      if target is None:
+        msg = ["Error: test %s references undefined target %s."
+                % (test_suite.GetName(), test_suite.GetTargetName())]
+        msg.append(" Ensure target is defined in %s" % self._TARGET_DEF_FILE)
+        logger.Log("".join(msg))
+      else:
+        return self._GenerateReport(report_path, coverage_local_path, [target],
+                                    do_src=True)
     return None
 
   def _GenerateReport(self, report_path, coverage_file_path, targets,
diff --git a/testrunner/errors.py b/testrunner/errors.py
index 6d606ec..e240899 100755
--- a/testrunner/errors.py
+++ b/testrunner/errors.py
@@ -34,6 +34,9 @@
   """Generic exception that indicates a fatal error has occurred and program
   execution should be aborted."""
 
+  def __init__(self, msg="AbortError"):
+    self.msg = msg
+
 
 class ParseError(Exception):
   """Raised when xml data to parse has unrecognized format."""
diff --git a/testrunner/run_command.py b/testrunner/run_command.py
index 6b72b77..ead80f1 100755
--- a/testrunner/run_command.py
+++ b/testrunner/run_command.py
@@ -3,37 +3,38 @@
 #
 # 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 
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
 #
-#     http://www.apache.org/licenses/LICENSE-2.0 
+#     http://www.apache.org/licenses/LICENSE-2.0
 #
-# Unless required by applicable law or agreed to in writing, software 
-# distributed under the License is distributed on an "AS IS" BASIS, 
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-# See the License for the specific language governing permissions and 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
 # limitations under the License.
 
 # System imports
 import os
 import signal
 import subprocess
-import time
 import threading
+import time
 
 # local imports
-import logger
+import android_build
 import errors
+import logger
 
 _abort_on_error = False
 
 def SetAbortOnError(abort=True):
-  """Sets behavior of RunCommand to throw AbortError if command process returns 
+  """Sets behavior of RunCommand to throw AbortError if command process returns
   a negative error code"""
   global _abort_on_error
   _abort_on_error = abort
-  
+
 def RunCommand(cmd, timeout_time=None, retry_count=3, return_output=True):
   """Spawns a subprocess to run the given shell command, and checks for
   timeout_time. If return_output is True, the output of the command is returned
@@ -42,7 +43,7 @@
   result = None
   while True:
     try:
-      result = RunOnce(cmd, timeout_time=timeout_time, 
+      result = RunOnce(cmd, timeout_time=timeout_time,
                        return_output=return_output)
     except errors.WaitForResponseTimedOutError:
       if retry_count == 0:
@@ -57,15 +58,16 @@
   start_time = time.time()
   so = []
   pid = []
-  global _abort_on_error
+  global _abort_on_error, error_occurred
   error_occurred = False
-  
+
   def Run():
+    global error_occurred
     if return_output:
       output_dest = subprocess.PIPE
     else:
       # None means direct to stdout
-      output_dest = None  
+      output_dest = None
     pipe = subprocess.Popen(
         cmd,
         executable='/bin/bash',
@@ -82,10 +84,10 @@
       logger.Log(e)
       so.append("ERROR")
       error_occurred = True
-    if pipe.returncode < 0:
-      logger.SilentLog("Error: %s was terminated by signal %d" %(cmd, 
+    if pipe.returncode != 0:
+      logger.SilentLog("Error: %s returned %d error code" %(cmd,
           pipe.returncode))
-      error_occurred = True  
+      error_occurred = True
 
   t = threading.Thread(target=Run)
   t.start()
@@ -110,8 +112,53 @@
       time.sleep(0.1)
 
   t.join()
-
+  output = "".join(so)
   if _abort_on_error and error_occurred:
-    raise errors.AbortError
-  
+    raise errors.AbortError(msg=output)
+
   return "".join(so)
+
+
+def RunHostCommand(binary, valgrind=False):
+  """Run a command on the host (opt using valgrind).
+
+  Runs the host binary and returns the exit code.
+  If successfull, the output (stdout and stderr) are discarded,
+  but printed in case of error.
+  The command can be run under valgrind in which case all the
+  output are always discarded.
+
+  Args:
+    binary: basename of the file to be run. It is expected to be under
+            out/host/<os>-<arch>/bin.
+    valgrind: If True the command will be run under valgrind.
+
+  Returns:
+    The command exit code (int)
+  """
+  full_path = os.path.join(android_build.GetHostBin(), binary)
+  if not valgrind:
+    subproc = subprocess.Popen(full_path, stdout=subprocess.PIPE,
+                               stderr=subprocess.STDOUT)
+    subproc.wait()
+    if subproc.returncode != 0:         # In case of error print the output
+      print subproc.communicate()[0]
+    return subproc.returncode
+  else:
+    # Need the full path to valgrind to avoid other versions on the system.
+    subproc = subprocess.Popen(["/usr/bin/valgrind", "-q", full_path],
+                               stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+    subproc.wait()
+    return subproc.returncode
+
+
+def HasValgrind():
+  """Check that /usr/bin/valgrind exists.
+
+  We look for the fullpath to avoid picking up 'alternative' valgrind
+  on the system.
+
+  Returns:
+    True if a system valgrind was found.
+  """
+  return os.path.exists("/usr/bin/valgrind")
diff --git a/testrunner/runtest.py b/testrunner/runtest.py
index 243da77..046eb7c 100755
--- a/testrunner/runtest.py
+++ b/testrunner/runtest.py
@@ -23,6 +23,7 @@
 import glob
 import optparse
 import os
+import re
 from sets import Set
 import sys
 
@@ -43,7 +44,7 @@
 
   # file path to android core platform tests, relative to android build root
   # TODO move these test data files to another directory
-  _CORE_TEST_PATH = os.path.join("development", "testrunner", 
+  _CORE_TEST_PATH = os.path.join("development", "testrunner",
                                  _TEST_FILE_NAME)
 
   # vendor glob file path patterns to tests, relative to android
@@ -58,7 +59,8 @@
 
   def __init__(self):
     # disable logging of timestamp
-    logger.SetTimestampLogging(False)  
+    self._root_path = android_build.GetTop()
+    logger.SetTimestampLogging(False)
 
   def _ProcessOptions(self):
     """Processes command-line options."""
@@ -93,6 +95,10 @@
                       help="Restrict test to a specific class")
     parser.add_option("-m", "--test-method", dest="test_method",
                       help="Restrict test to a specific method")
+    parser.add_option("-p", "--test-package", dest="test_package",
+                      help="Restrict test to a specific java package")
+    parser.add_option("-z", "--size", dest="test_size",
+                      help="Restrict test to a specific test size")
     parser.add_option("-u", "--user-tests-file", dest="user_tests_file",
                       metavar="FILE", default=user_test_default,
                       help="Alternate source of user test definitions")
@@ -106,6 +112,9 @@
                       default=False, action="store_true",
                       help="Run all tests defined as part of the continuous "
                       "test set")
+    parser.add_option("--timeout", dest="timeout",
+                      default=300, help="Set a timeout limit (in sec) for "
+                      "running native tests on a device (default: 300 secs)")
 
     group = optparse.OptionGroup(
         parser, "Targets", "Use these options to direct tests to a specific "
@@ -137,8 +146,6 @@
     if self._options.verbose:
       logger.SetVerbose(True)
 
-    self._root_path = android_build.GetTop()
-
     self._known_tests = self._ReadTests()
 
     self._coverage_gen = coverage.CoverageGenerator(
@@ -172,22 +179,30 @@
     """Prints out set of defined tests."""
     print "The following tests are currently defined:"
     for test in self._known_tests:
-      print test.GetName()
+      print "%-15s %s" % (test.GetName(), test.GetDescription())
 
   def _DoBuild(self):
     logger.SilentLog("Building tests...")
     target_set = Set()
+    extra_args_set = Set()
     for test_suite in self._GetTestsToRun():
-      self._AddBuildTarget(test_suite.GetBuildPath(), target_set)
+      self._AddBuildTarget(test_suite, target_set, extra_args_set)
 
     if target_set:
       if self._options.coverage:
         self._coverage_gen.EnableCoverageBuild()
-        self._AddBuildTarget(self._coverage_gen.GetEmmaBuildPath(), target_set)
+        self._AddBuildTargetPath(self._coverage_gen.GetEmmaBuildPath(),
+                                 target_set)
       target_build_string = " ".join(list(target_set))
-      logger.Log("mmm %s" % target_build_string)
-      cmd = 'ONE_SHOT_MAKEFILE="%s" make -C "%s" files' %  (target_build_string,
-                                                            self._root_path)
+      extra_args_string = " ".join(list(extra_args_set))
+      # log the user-friendly equivalent make command, so developers can
+      # replicate this step
+      logger.Log("mmm %s %s" % (target_build_string, extra_args_string))
+      # mmm cannot be used from python, so perform a similiar operation using
+      # ONE_SHOT_MAKEFILE
+      cmd = 'ONE_SHOT_MAKEFILE="%s" make -C "%s" files %s' % (
+          target_build_string, self._root_path, extra_args_string)
+
       if self._options.preview:
         # in preview mode, just display to the user what command would have been
         # run
@@ -197,11 +212,18 @@
         logger.Log("Syncing to device...")
         self._adb.Sync()
 
-  def _AddBuildTarget(self, build_dir, target_set):
+  def _AddBuildTarget(self, test_suite, target_set, extra_args_set):
+    build_dir = test_suite.GetBuildPath()
+    if self._AddBuildTargetPath(build_dir, target_set):
+      extra_args_set.add(test_suite.GetExtraMakeArgs())
+
+  def _AddBuildTargetPath(self, build_dir, target_set):
     if build_dir is not None:
       build_file_path = os.path.join(build_dir, "Android.mk")
       if os.path.isfile(os.path.join(self._root_path, build_file_path)):
         target_set.add(build_file_path)
+        return True
+    return False
 
   def _GetTestsToRun(self):
     """Get a list of TestSuite objects to run, based on command line args."""
@@ -230,13 +252,19 @@
 
     test_class = test_suite.GetClassName()
     if self._options.test_class is not None:
-      test_class = self._options.test_class
+      test_class = self._options.test_class.lstrip()
+      if test_class.startswith("."):
+        test_class = test_suite.GetPackageName() + test_class
     if self._options.test_method is not None:
       test_class = "%s#%s" % (test_class, self._options.test_method)
 
     instrumentation_args = {}
     if test_class is not None:
       instrumentation_args["class"] = test_class
+    if self._options.test_package:
+      instrumentation_args["package"] = self._options.test_package
+    if self._options.test_size:
+      instrumentation_args["size"] = self._options.test_size
     if self._options.wait_for_debugger:
       instrumentation_args["debug"] = "true"
     if self._options.suite_assign_mode:
@@ -250,16 +278,164 @@
           raw_mode=self._options.raw_mode,
           instrumentation_args=instrumentation_args)
       logger.Log(adb_cmd)
+    elif self._options.coverage:
+      # need to parse test output to determine path to coverage file
+      logger.Log("Running in coverage mode, suppressing test output")
+      try:
+        (test_results, status_map) = self._adb.StartInstrumentationForPackage(
+          package_name=test_suite.GetPackageName(),
+          runner_name=test_suite.GetRunnerName(),
+          timeout_time=60*60,
+          instrumentation_args=instrumentation_args)
+      except errors.InstrumentationError, errors.DeviceUnresponsiveError:
+        return
+      self._PrintTestResults(test_results)
+      device_coverage_path = status_map.get("coverageFilePath", None)
+      if device_coverage_path is None:
+        logger.Log("Error: could not find coverage data on device")
+        return
+      coverage_file = self._coverage_gen.ExtractReport(test_suite, device_coverage_path)
+      if coverage_file is not None:
+        logger.Log("Coverage report generated at %s" % coverage_file)
     else:
       self._adb.StartInstrumentationNoResults(
           package_name=test_suite.GetPackageName(),
           runner_name=test_suite.GetRunnerName(),
           raw_mode=self._options.raw_mode,
           instrumentation_args=instrumentation_args)
-      if self._options.coverage and test_suite.GetTargetName() is not None:
-        coverage_file = self._coverage_gen.ExtractReport(test_suite)
-        if coverage_file is not None:
-          logger.Log("Coverage report generated at %s" % coverage_file)
+
+  def _PrintTestResults(self, test_results):
+    """Prints a summary of test result data to stdout.
+
+    Args:
+      test_results: a list of am_instrument_parser.TestResult
+    """
+    total_count = 0
+    error_count = 0
+    fail_count = 0
+    for test_result in test_results:
+      if test_result.GetStatusCode() == -1: # error
+        logger.Log("Error in %s: %s" % (test_result.GetTestName(),
+                                        test_result.GetFailureReason()))
+        error_count+=1
+      elif test_result.GetStatusCode() == -2: # failure
+        logger.Log("Failure in %s: %s" % (test_result.GetTestName(),
+                                          test_result.GetFailureReason()))
+        fail_count+=1
+      total_count+=1
+    logger.Log("Tests run: %d, Failures: %d, Errors: %d" %
+               (total_count, fail_count, error_count))
+
+  def _CollectTestSources(self, test_list, dirname, files):
+    """For each directory, find tests source file and add them to the list.
+
+    Test files must match one of the following pattern:
+      - test_*.[cc|cpp]
+      - *_test.[cc|cpp]
+      - *_unittest.[cc|cpp]
+
+    This method is a callback for os.path.walk.
+
+    Args:
+      test_list: Where new tests should be inserted.
+      dirname: Current directory.
+      files: List of files in the current directory.
+    """
+    for f in files:
+      (name, ext) = os.path.splitext(f)
+      if ext == ".cc" or ext == ".cpp":
+        if re.search("_test$|_test_$|_unittest$|_unittest_$|^test_", name):
+          logger.SilentLog("Found %s" % f)
+          test_list.append(str(os.path.join(dirname, f)))
+
+  def _FilterOutMissing(self, path, sources):
+    """Filter out from the sources list missing tests.
+
+    Sometimes some test source are not built for the target, i.e there
+    is no binary corresponding to the source file. We need to filter
+    these out.
+
+    Args:
+      path: Where the binaries should be.
+      sources: List of tests source path.
+    Returns:
+      A list of test binaries built from the sources.
+    """
+    binaries = []
+    for f in sources:
+      binary = os.path.basename(f)
+      binary = os.path.splitext(binary)[0]
+      full_path = os.path.join(path, binary)
+      if os.path.exists(full_path):
+        binaries.append(binary)
+    return binaries
+
+  def _RunNativeTest(self, test_suite):
+    """Run the provided *native* test suite.
+
+    The test_suite must contain a build path where the native test
+    files are. Subdirectories are automatically scanned as well.
+
+    Each test's name must have a .cc or .cpp extension and match one
+    of the following patterns:
+      - test_*
+      - *_test.[cc|cpp]
+      - *_unittest.[cc|cpp]
+    A successful test must return 0. Any other value will be considered
+    as an error.
+
+    Args:
+      test_suite: TestSuite to run
+    """
+    # find all test files, convert unicode names to ascii, take the basename
+    # and drop the .cc/.cpp  extension.
+    source_list = []
+    build_path = test_suite.GetBuildPath()
+    os.path.walk(build_path, self._CollectTestSources, source_list)
+    logger.SilentLog("Tests source %s" % source_list)
+
+    # Host tests are under out/host/<os>-<arch>/bin.
+    host_list = self._FilterOutMissing(android_build.GetHostBin(), source_list)
+    logger.SilentLog("Host tests %s" % host_list)
+
+    # Target tests are under $ANDROID_PRODUCT_OUT/system/bin.
+    target_list = self._FilterOutMissing(android_build.GetTargetSystemBin(),
+                                         source_list)
+    logger.SilentLog("Target tests %s" % target_list)
+
+    # Run on the host
+    logger.Log("\nRunning on host")
+    for f in host_list:
+      if run_command.RunHostCommand(f) != 0:
+        logger.Log("%s... failed" % f)
+      else:
+        if run_command.HasValgrind():
+          if run_command.RunHostCommand(f, valgrind=True) == 0:
+            logger.Log("%s... ok\t\t[valgrind: ok]" % f)
+          else:
+            logger.Log("%s... ok\t\t[valgrind: failed]" % f)
+        else:
+          logger.Log("%s... ok\t\t[valgrind: missing]" % f)
+
+    # Run on the device
+    logger.Log("\nRunning on target")
+    for f in target_list:
+      full_path = os.path.join(os.sep, "system", "bin", f)
+
+      # Single quotes are needed to prevent the shell splitting it.
+      output = self._adb.SendShellCommand("'%s 2>&1;echo -n exit code:$?'" %
+                                          full_path,
+                                          int(self._options.timeout))
+      success = output.endswith("exit code:0")
+      logger.Log("%s... %s" % (f, success and "ok" or "failed"))
+      # Print the captured output when the test failed.
+      if not success or self._options.verbose:
+        pos = output.rfind("exit code")
+        output = output[0:pos]
+        logger.Log(output)
+
+      # Cleanup
+      self._adb.SendShellCommand("rm %s" % full_path)
 
   def RunTests(self):
     """Main entry method - executes the tests according to command line args."""
@@ -270,18 +446,18 @@
         self._DumpTests()
         return
 
-      if not self._adb.IsDevicePresent():
-        logger.Log("Error: specified device cannot be found")
-        return
-
       if not self._options.skip_build:
         self._DoBuild()
 
       for test_suite in self._GetTestsToRun():
-        self._RunTest(test_suite)
+        if test_suite.IsNative():
+          self._RunNativeTest(test_suite)
+        else:
+          self._RunTest(test_suite)
     except KeyboardInterrupt:
       logger.Log("Exiting...")
-    except errors.AbortError:
+    except errors.AbortError, e:
+      logger.Log(e.msg)
       logger.SilentLog("Exiting due to AbortError...")
     except errors.WaitForResponseTimedOutError:
       logger.Log("Timed out waiting for response")
diff --git a/testrunner/test_defs.py b/testrunner/test_defs.py
index 949ad6e..2cdcfa8 100644
--- a/testrunner/test_defs.py
+++ b/testrunner/test_defs.py
@@ -38,7 +38,14 @@
        [class=""]
        [coverage_target=""]
        [build_path=""]
-       [continuous]
+       [continuous=false]
+       [description=""]
+      />
+     <test-native
+       name=""
+       build_path=""
+       [continuous=false]
+       [description=""]
       />
      <test  ...
    </test-definitions>
@@ -48,13 +55,17 @@
 
   # tag/attribute constants
   _TEST_TAG_NAME = "test"
+  _TEST_NATIVE_TAG_NAME = "test-native"
 
   def __init__(self):
     # dictionary of test name to tests
     self._testname_map = {}
 
   def __iter__(self):
-    return iter(self._testname_map.values())
+    ordered_list = []
+    for k in sorted(self._testname_map):
+      ordered_list.append(self._testname_map[k])
+    return iter(ordered_list)
 
   def Parse(self, file_path):
     """Parse the test suite data from from given file path.
@@ -87,6 +98,12 @@
       test = self._ParseTestSuite(suite_element)
       self._AddTest(test)
 
+    suite_elements = doc.getElementsByTagName(self._TEST_NATIVE_TAG_NAME)
+
+    for suite_element in suite_elements:
+      test = self._ParseNativeTestSuite(suite_element)
+      self._AddTest(test)
+
   def _ParseTestSuite(self, suite_element):
     """Parse the suite element.
     
@@ -96,6 +113,17 @@
     test = TestSuite(suite_element)
     return test
 
+  def _ParseNativeTestSuite(self, suite_element):
+    """Parse the native test element.
+
+    Returns:
+      a TestSuite object, populated with parsed data
+    Raises:
+      ParseError if some required attribute is missing.
+    """
+    test = TestSuite(suite_element, native=True)
+    return test
+
   def _AddTest(self, test):
     """Adds a test to this TestManifest.
     
@@ -129,13 +157,28 @@
   _TARGET_ATTR = "coverage_target"
   _BUILD_ATTR = "build_path"
   _CONTINUOUS_ATTR = "continuous"
+  _DESCRIPTION_ATTR = "description"
+  _EXTRA_MAKE_ARGS_ATTR = "extra_make_args"
 
   _DEFAULT_RUNNER = "android.test.InstrumentationTestRunner"
 
-  def __init__(self, suite_element):
-    """Populates this instance's data from given suite xml element."""
+  def __init__(self, suite_element, native=False):
+    """Populates this instance's data from given suite xml element.
+    Raises:
+      ParseError if some required attribute is missing.
+    """
+    self._native = native
     self._name = suite_element.getAttribute(self._NAME_ATTR)
-    self._package = suite_element.getAttribute(self._PKG_ATTR)
+
+    if self._native:
+      # For native runs, _BUILD_ATTR is required
+      if not suite_element.hasAttribute(self._BUILD_ATTR):
+        logger.Log("Error: %s is missing required build_path attribute" %
+                   self._name)
+        raise errors.ParseError
+    else:
+      self._package = suite_element.getAttribute(self._PKG_ATTR)
+
     if suite_element.hasAttribute(self._RUNNER_ATTR):
       self._runner = suite_element.getAttribute(self._RUNNER_ATTR)
     else:
@@ -156,6 +199,15 @@
       self._continuous = suite_element.getAttribute(self._CONTINUOUS_ATTR)
     else:
       self._continuous = False
+    if suite_element.hasAttribute(self._DESCRIPTION_ATTR):
+      self._description = suite_element.getAttribute(self._DESCRIPTION_ATTR)
+    else:
+      self._description = ""
+    if suite_element.hasAttribute(self._EXTRA_MAKE_ARGS_ATTR):
+      self._extra_make_args = suite_element.getAttribute(
+          self._EXTRA_MAKE_ARGS_ATTR)
+    else:
+      self._extra_make_args = ""
 
   def GetName(self):
     return self._name
@@ -184,6 +236,18 @@
     """Returns true if test is flagged as being part of the continuous tests"""  
     return self._continuous
 
+  def IsNative(self):
+    """Returns true if test is a native one."""
+    return self._native
+
+  def GetDescription(self):
+    """Returns a description if available, an empty string otherwise."""
+    return self._description
+
+  def GetExtraMakeArgs(self):
+    """Returns the extra make args if available, an empty string otherwise."""
+    return self._extra_make_args
+
 def Parse(file_path):
   """Parses out a TestDefinitions from given path to xml file.
 
diff --git a/testrunner/test_defs.xml b/testrunner/test_defs.xml
index 87159fd..4121f7b 100644
--- a/testrunner/test_defs.xml
+++ b/testrunner/test_defs.xml
@@ -4,9 +4,9 @@
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-  
+
           http://www.apache.org/licenses/LICENSE-2.0
-  
+
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,38 +14,78 @@
      limitations under the License.
 -->
 
-<!-- 
+<!--
 This file contains standard test definitions for the Android platform
-          
-Tests are defined by <test> tags with the following attributes
 
-name package [class runner build_path coverage_target continuous]
+Java tests are defined by <test> tags and native ones (C/C++) are defined by
+<test-native> tags.
 
-Where:
-name: Self-descriptive name used to uniquely identify the test
-build_path: File system path, relative to Android build root, to this package's
-   Android.mk file. If omitted, build/sync step for this test will be skipped
-package: Android application package that contains the tests
-class: Optional. Fully qualified Java test class to run. 
-runner: Fully qualified InstrumentationTestRunner to execute. If omitted, 
-   will default to android.test.InstrumentationTestRunner
-coverage_target: Build name of Android package this test targets - these targets
-   are defined in the coverage_targets.xml file.  Used as basis for code
-   coverage metrics. If omitted, code coverage will not be supported for this
-   test
-continuous: Optional boolean. Default is false. Set to true if tests are known
-   to be reliable, and should be included in a continuous test system. false if
-   they are under development.
+JAVA/application tests:
+=======================
+  The java <test> element has the following attributes
 
-These attributes map to the following commands:  
-(if class is defined)
-    adb shell am instrument -w <package>/<runner>
-(else)
-    adb shell am instrument -w -e class <class> <package>/<runner>
+  name package [class runner build_path coverage_target continuous description]
 
+  Where:
+  name: Self-descriptive name used to uniquely identify the test
+  build_path: File system path, relative to Android build root, to this
+    package's Android.mk file. If omitted, build/sync step for this test will
+    be skipped.
+  package: Android application package that contains the tests
+  class: Optional. Fully qualified Java test class to run.
+  runner: Fully qualified InstrumentationTestRunner to execute. If omitted,
+     will default to android.test.InstrumentationTestRunner.
+  coverage_target: Build name of Android package this test targets - these
+    targets are defined in the coverage_targets.xml file.  Used as basis for
+    code coverage metrics. If omitted, code coverage will not be supported for
+    this test.
+  continuous: Optional boolean. Default is false. Set to true if tests are known
+    to be reliable, and should be included in a continuous test system. false if
+    they are under development.
+
+  description: Optional string. Default is empty. Short description (typically
+     less than 60 characters) about this test.
+
+  These attributes map to the following commands:
+  (if class is defined)
+      adb shell am instrument -w <package>/<runner>
+  (else)
+      adb shell am instrument -w -e class <class> <package>/<runner>
+
+Native tests:
+=============
+  The <test-native> element has the following attributes
+
+  name build_path [continuous description extra_make_args]
+
+  Where:
+  name: Self-descriptive name used to uniquely identify the test
+  build_path: File system path, relative to Android build root, to this
+     package's Android.mk file. By convention the name of a test should match:
+      - test_*.[cc|cpp]
+      - *_test.[cc|cpp]
+      - *_unittest.[cc|cpp]
+
+  continuous: Optional boolean. Default is false. Set to true if tests are known
+     to be reliable, and should be included in a continuous test system.
+     false if they are under development.
+  description: Optional string. Default is empty. Short description (typically
+     less than 60 characters) about this test.
+  extra_make_args: Optional string. Default is empty. Some test module require
+     extra make arguments to build. This string is append to the make command.
+
+  These attributes map to the following commands:
+    make <build_path>/Android.mk <extra_make_args>
+    adb sync
+    for test_prog in <tests built>; do
+      adb shell "/system/bin/${test_prog} >/dev/null 2>&1;echo \$?"
+      adb shell "rm /system/bin/${test_prog}"
+    done
 -->
 
-<test-definitions version="1">
+<test-definitions xmlns="http://schemas.android.com/testrunner/test_defs/1.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://schemas.android.com/testrunner/test_defs/1.0 test_defs.xsd">
 
 <!-- system-wide tests -->
 <test name="framework"
@@ -80,7 +120,7 @@
     package="android.core"
     class="android.core.JavaTests"
     coverage_target="framework" />
-    
+
 <test name="apidemos"
     build_path="development/samples/ApiDemos"
     package="com.example.android.apis.tests"
@@ -151,10 +191,17 @@
     coverage_target="CalendarProvider"
     continuous="true" />
 
+<test name="camerastress"
+    build_path="packages/apps/Camera"
+    package="com.android.camera.tests"
+    class="com.android.camera.StressTests"
+    coverage_target="Camera" />
+
 <test name="camera"
-    build_path="packages/apps/Camera/tests"
-    package="com.android.cameratests"
-    runner="CameraInstrumentationTestRunner"
+    build_path="packages/apps/Camera"
+    package="com.android.camera.tests"
+    class="com.android.camera.UnitTests"
+    continuous="true"
     coverage_target="Camera" />
 
 <test name="contactsprov"
@@ -180,13 +227,33 @@
     runner=".MediaFrameworkTestRunner"
     coverage_target="framework"
     continuous="true" />
-    
+
+<test name="mediaapitest"
+    build_path="frameworks/base/media/tests/MediaFrameworkTest"
+    package="com.android.mediaframeworktest"
+    class="com.android.mediaframeworktest.functional.MediaPlayerApiTest"
+    runner=".MediaFrameworkTestRunner"
+    coverage_target="framework" />
+
+<test name="mediarecordertest"
+    build_path="frameworks/base/media/tests/MediaFrameworkTest"
+    package="com.android.mediaframeworktest"
+    class="com.android.mediaframeworktest.functional.MediaRecorderTest"
+    runner=".MediaFrameworkTestRunner"
+    coverage_target="framework" />
+
+<test name="mediastresstest"
+    build_path="frameworks/base/media/tests/MediaFrameworkTest"
+    package="com.android.mediaframeworktest"
+    runner=".MediaRecorderStressTestRunner"
+    coverage_target="framework" />
+
 <test name="mediaunit"
     build_path="frameworks/base/media/tests/MediaFrameworkTest"
     package="com.android.mediaframeworktest"
     runner=".MediaFrameworkUnitTestRunner"
     coverage_target="framework" />
-    
+
 <test name="musicplayer"
     build_path="packages/apps/Music"
     package="com.android.music.tests"
@@ -222,4 +289,17 @@
     coverage_target="Settings" />
 -->
 
+<!--  native tests  -->
+<test-native name="libstdcpp"
+    build_path="system/extras/tests/bionic/libstdc++"
+    description="Bionic libstdc++."
+    extra_make_args="BIONIC_TESTS=1" />
+
+<!-- pending patch 820
+<test-native name="gtest"
+    build_path="external/gtest"
+    description="Google test."
+    extra_make_args="GTEST_TESTS=1" />
+-->
+
 </test-definitions>
diff --git a/testrunner/test_defs.xsd b/testrunner/test_defs.xsd
new file mode 100644
index 0000000..5387a28
--- /dev/null
+++ b/testrunner/test_defs.xsd
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+        targetNamespace="http://schemas.android.com/testrunner/test_defs/1.0"
+        xmlns="http://schemas.android.com/testrunner/test_defs/1.0"
+        elementFormDefault="qualified">
+
+    <xs:element name="test-definitions">
+        <xs:complexType>
+            <xs:sequence>
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:element name="test" type="javaTestType"/>
+                    <xs:element name="test-native" type="nativeTestType"/>
+                </xs:choice>
+            </xs:sequence>
+        </xs:complexType>
+    </xs:element>
+
+    <xs:complexType name="javaTestType">
+        <xs:attribute name="name" type="xs:string" use="required"/>
+        <xs:attribute name="package" type="xs:string" use="required"/>
+        <xs:attribute name="build_path" type="xs:string" use="optional"/>
+        <xs:attribute name="class" type="xs:string" use="optional"/>
+        <xs:attribute name="runner" type="xs:string" use="optional"
+                      default="android.test.InstrumentationTestRunner"/>
+        <xs:attribute name="coverage_target" type="xs:string" use="optional"/>
+        <xs:attribute name="continuous" type="xs:boolean" use="optional" default="false"/>
+    </xs:complexType>
+
+    <xs:complexType name="nativeTestType">
+        <xs:attribute name="name" type="xs:string" use="required"/>
+        <xs:attribute name="build_path" type="xs:string" use="required"/>
+        <xs:attribute name="extra_make_args" type="xs:string" use="optional"/>
+        <xs:attribute name="description" type="xs:string" use="optional"/>
+        <xs:attribute name="continuous" type="xs:boolean" use="optional" default="false"/>
+    </xs:complexType>
+</xs:schema>
diff --git a/tools/androidprefs/.gitignore b/tools/androidprefs/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/tools/androidprefs/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/tools/anttasks/.gitignore b/tools/anttasks/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/tools/anttasks/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/tools/anttasks/src/com/android/ant/AaptExecLoopTask.java b/tools/anttasks/src/com/android/ant/AaptExecLoopTask.java
index 6444e4d..ef74fe7 100644
--- a/tools/anttasks/src/com/android/ant/AaptExecLoopTask.java
+++ b/tools/anttasks/src/com/android/ant/AaptExecLoopTask.java
@@ -16,9 +16,9 @@
 
 package com.android.ant;
 
-import com.android.sdklib.project.ApkConfigurationHelper;
-import com.android.sdklib.project.ProjectProperties;
-import com.android.sdklib.project.ProjectProperties.PropertyType;
+import com.android.sdklib.internal.project.ApkConfigurationHelper;
+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;
diff --git a/tools/anttasks/src/com/android/ant/ApkBuilderTask.java b/tools/anttasks/src/com/android/ant/ApkBuilderTask.java
index 22729ec..3758b82 100644
--- a/tools/anttasks/src/com/android/ant/ApkBuilderTask.java
+++ b/tools/anttasks/src/com/android/ant/ApkBuilderTask.java
@@ -18,9 +18,9 @@
 
 import com.android.apkbuilder.ApkBuilder;
 import com.android.apkbuilder.ApkBuilder.ApkFile;
-import com.android.sdklib.project.ApkConfigurationHelper;
-import com.android.sdklib.project.ProjectProperties;
-import com.android.sdklib.project.ProjectProperties.PropertyType;
+import com.android.sdklib.internal.project.ApkConfigurationHelper;
+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;
diff --git a/tools/anttasks/src/com/android/ant/SetupTask.java b/tools/anttasks/src/com/android/ant/SetupTask.java
index d425a2f..60f8c7e 100644
--- a/tools/anttasks/src/com/android/ant/SetupTask.java
+++ b/tools/anttasks/src/com/android/ant/SetupTask.java
@@ -20,7 +20,7 @@
 import com.android.sdklib.ISdkLog;
 import com.android.sdklib.SdkManager;
 import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
-import com.android.sdklib.project.ProjectProperties;
+import com.android.sdklib.internal.project.ProjectProperties;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Project;
diff --git a/tools/apkbuilder/.gitignore b/tools/apkbuilder/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/tools/apkbuilder/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/tools/ddms/.gitignore b/tools/ddms/.gitignore
new file mode 100644
index 0000000..6d833a0
--- /dev/null
+++ b/tools/ddms/.gitignore
@@ -0,0 +1,4 @@
+app/bin
+libs/ddmlib/bin
+libs/ddmuilib/bin
+
diff --git a/tools/ddms/app/etc/ddms b/tools/ddms/app/etc/ddms
index d809cfc..c63930b 100755
--- a/tools/ddms/app/etc/ddms
+++ b/tools/ddms/app/etc/ddms
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 # Copyright 2005-2007, The Android Open Source Project
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -67,6 +67,29 @@
     os_opts="-XstartOnFirstThread"
     #because Java 1.6 is 64 bits only and SWT doesn't support this, we force the usage of java 1.5
     java_cmd="/System/Library/Frameworks/JavaVM.framework/Versions/1.5/Commands/java"
+elif [[ `uname -s` = 'Linux' ]]; then
+    # We need a 32-bit Java on Linux, because our JNI libraries are 32-bit.
+    java_cmd=`which java`
+
+    if [ -x "$java_cmd" ]; then
+        if [[ ! `file -L "$java_cmd"` =~ "ELF 32-bit LSB executable" ]]; then
+            java_cmd=""
+        fi
+    fi
+
+    if [ ! -x "$java_cmd" ]; then
+        # The default JVM is not suitable.
+        # See if we can find a particular known-good JVM
+        java_cmd="/usr/lib/jvm/ia32-java-6-sun/jre/bin/java"
+        if [ ! -x "$java_cmd" ]; then
+            PREFIX=`basename "$prog"`
+            echo "$PREFIX: The default Java VM is not an ELF 32-bit LSB executable."
+            echo "$PREFIX: Please do one of the following:"
+            echo "$PREFIX: 1) Arrange for the default Java VM to be an ELF 32-bit LSB executable."
+            echo "$PREFIX: 2) Install the ia32-sun-java6-bin package."
+            exit 1
+        fi
+    fi
 else
     os_opts=
     java_cmd="java"
diff --git a/tools/ddms/app/src/com/android/ddms/DebugPortProvider.java b/tools/ddms/app/src/com/android/ddms/DebugPortProvider.java
index 89cc190..76a86b7 100644
--- a/tools/ddms/app/src/com/android/ddms/DebugPortProvider.java
+++ b/tools/ddms/app/src/com/android/ddms/DebugPortProvider.java
@@ -16,7 +16,7 @@
 
 package com.android.ddms;
 
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
 
 import org.eclipse.jface.preference.IPreferenceStore;
@@ -53,15 +53,15 @@
 
     /**
          * Returns a static debug port for the specified application running on the
-         * specified {@link Device}.
+         * 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(Device, String)
+     * @see IDebugPortProvider#getPort(IDevice, String)
      */
-    public int getPort(Device device, String appName) {
+    public int getPort(IDevice device, String appName) {
         if (mMap != null) {
             Map<String, Integer> deviceMap = mMap.get(device.getSerialNumber());
             if (deviceMap != null) {
@@ -107,7 +107,7 @@
                 if (entry.length == 3) {
                     deviceName = entry[2];
                 } else {
-                    deviceName = Device.FIRST_EMULATOR_SN;
+                    deviceName = IDevice.FIRST_EMULATOR_SN;
                 }
 
                 // get the device map
diff --git a/tools/ddms/app/src/com/android/ddms/DeviceCommandDialog.java b/tools/ddms/app/src/com/android/ddms/DeviceCommandDialog.java
index 2a1342e..befb994 100644
--- a/tools/ddms/app/src/com/android/ddms/DeviceCommandDialog.java
+++ b/tools/ddms/app/src/com/android/ddms/DeviceCommandDialog.java
@@ -17,7 +17,7 @@
 
 package com.android.ddms;
 
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.IShellOutputReceiver;
 import com.android.ddmlib.Log;
 
@@ -96,7 +96,7 @@
      * Prepare and display the dialog.
      * @param currentDevice
      */
-    public void open(Device currentDevice) {
+    public void open(IDevice currentDevice) {
         Shell parent = getParent();
         Shell shell = new Shell(parent, getStyle());
         shell.setText("Remote Command");
@@ -219,13 +219,13 @@
         private String mCommand;
         private Text mText;
         private int mResult;
-        private Device mDevice;
+        private IDevice mDevice;
 
         /**
          * Constructor; pass in the text widget that will receive the output.
          * @param device
          */
-        public Gatherer(Shell shell, Device device, String command, Text text) {
+        public Gatherer(Shell shell, IDevice device, String command, Text text) {
             mShell = shell;
             mDevice = device;
             mCommand = command;
@@ -307,7 +307,7 @@
      * We have to run the command in a thread so that the UI continues
      * to work.
      */
-    private void executeCommand(Shell shell, Device device) {
+    private void executeCommand(Shell shell, IDevice device) {
         Gatherer gath = new Gatherer(shell, device, commandString(), mText);
         gath.start();
     }
diff --git a/tools/ddms/app/src/com/android/ddms/Main.java b/tools/ddms/app/src/com/android/ddms/Main.java
index d63b884..d545ed9 100644
--- a/tools/ddms/app/src/com/android/ddms/Main.java
+++ b/tools/ddms/app/src/com/android/ddms/Main.java
@@ -78,7 +78,7 @@
         // 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]);
+            SdkStatsService.ping(args[1], args[2], null);
             return;
         } else if (args.length > 0) {
             Log.e("ddms", "Unknown argument: " + args[0]);
@@ -86,7 +86,7 @@
         }
 
         // ddms itself is wanted: send a ping for ourselves
-        SdkStatsService.ping("ddms", VERSION);  //$NON-NLS-1$
+        SdkStatsService.ping("ddms", VERSION, null);  //$NON-NLS-1$
 
         DebugPortManager.setProvider(DebugPortProvider.getInstance());
 
diff --git a/tools/ddms/app/src/com/android/ddms/StaticPortEditDialog.java b/tools/ddms/app/src/com/android/ddms/StaticPortEditDialog.java
index 6330126..b224967 100644
--- a/tools/ddms/app/src/com/android/ddms/StaticPortEditDialog.java
+++ b/tools/ddms/app/src/com/android/ddms/StaticPortEditDialog.java
@@ -16,7 +16,7 @@
 
 package com.android.ddms;
 
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.ModifyEvent;
@@ -75,7 +75,7 @@
     public StaticPortEditDialog(Shell parent, ArrayList<Integer> ports) {
         super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
         mPorts = ports;
-        mDeviceSn = Device.FIRST_EMULATOR_SN;
+        mDeviceSn = IDevice.FIRST_EMULATOR_SN;
     }
 
     /**
diff --git a/tools/ddms/app/src/com/android/ddms/UIThread.java b/tools/ddms/app/src/com/android/ddms/UIThread.java
index ff89e2c..86cab20 100644
--- a/tools/ddms/app/src/com/android/ddms/UIThread.java
+++ b/tools/ddms/app/src/com/android/ddms/UIThread.java
@@ -18,7 +18,7 @@
 
 import com.android.ddmlib.AndroidDebugBridge;
 import com.android.ddmlib.Client;
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.Log.ILogOutput;
 import com.android.ddmlib.Log.LogLevel;
@@ -90,7 +90,7 @@
 /**
  * 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 Device} / {@link Client} selection changes.
+ * when {@link IDevice} / {@link Client} selection changes.
  */
 public class UIThread implements IUiSelectionListener {
     /*
@@ -153,7 +153,7 @@
     // the table we show in the left-hand pane
     private DevicePanel mDevicePanel;
 
-    private Device mCurrentDevice = null;
+    private IDevice mCurrentDevice = null;
     private Client mCurrentClient = null;
 
     // status line at the bottom of the app window
@@ -166,7 +166,7 @@
     private ToolItem mTBCauseGc;
 
     private ImageLoader mDdmsImageLoader;
-    private ImageLoader mDdmuiLibImageLoader; 
+    private ImageLoader mDdmuiLibImageLoader;
 
     private final class FilterStorage implements ILogFilterStorageManager {
 
@@ -238,7 +238,7 @@
     private Shell mExplorerShell = null;
 
     private EmulatorControlPanel mEmulatorPanel;
-    
+
     private EventLogPanel mEventLogPanel;
 
     private class TableFocusListener implements ITableFocusListener {
@@ -333,7 +333,7 @@
         // 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));
@@ -883,7 +883,7 @@
                 p.setTableFocusListener(mTableListener);
             }
         }
-        
+
         mStatusLine.setText("");
     }
 
@@ -892,7 +892,7 @@
      */
     private void createDevicePanelToolBar(ToolBar toolBar) {
         Display display = toolBar.getDisplay();
-        
+
         // add "show thread updates" button
         mTBShowThreadUpdates = new ToolItem(toolBar, SWT.CHECK);
         mTBShowThreadUpdates.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
@@ -949,7 +949,7 @@
                 mDevicePanel.killSelectedClient();
             }
         });
-        
+
         new ToolItem(toolBar, SWT.SEPARATOR);
 
         // add "cause GC" button
@@ -1130,7 +1130,7 @@
 
         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));
@@ -1239,12 +1239,12 @@
         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));
@@ -1260,7 +1260,7 @@
         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);
@@ -1283,7 +1283,7 @@
 
         // create the event log panel
         mEventLogPanel = new EventLogPanel(mDdmuiLibImageLoader);
-        
+
         // set the external actions
         mEventLogPanel.setActions(optionsAction, clearAction, saveAction, loadAction,
                 importBugAction);
@@ -1450,13 +1450,13 @@
     }
 
     /**
-     * Sent when a new {@link Device} and {@link Client} are selected.
+     * 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(Device selectedDevice, Client selectedClient) {
+    public void selectionChanged(IDevice selectedDevice, Client selectedClient) {
         if (mCurrentDevice != selectedDevice) {
             mCurrentDevice = selectedDevice;
             for (TablePanel panel : mPanels) {
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java
index 42022fe..5f0f271 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java
@@ -29,7 +29,7 @@
 /**
  * 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. 
+ * 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.
  */
@@ -272,14 +272,14 @@
         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: "
@@ -287,7 +287,7 @@
                 adbChan.close();
                 return null;
             }
-    
+
             reply = new byte[16];
             if (read(adbChan, reply) == false) {
                 Log.w("ddms", "got partial reply from ADB fb:");
@@ -297,19 +297,19 @@
             }
             ByteBuffer buf = ByteBuffer.wrap(reply);
             buf.order(ByteOrder.LITTLE_ENDIAN);
-    
+
             imageParams.bpp = buf.getInt();
             imageParams.size = buf.getInt();
             imageParams.width = buf.getInt();
             imageParams.height = buf.getInt();
-    
+
             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");
@@ -416,34 +416,34 @@
     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;
@@ -465,7 +465,7 @@
             }
         }
     }
-    
+
     /**
      * Creates a port forwarding between a local and a remote port.
      * @param adbSockAddr the socket address to connect to adb
@@ -473,7 +473,7 @@
      * @param localPort the local port to forward
      * @param remotePort the remote port.
      * @return <code>true</code> if success.
-     * @throws IOException 
+     * @throws IOException
      */
     public static boolean createForward(InetSocketAddress adbSockAddr, Device device, int localPort,
             int remotePort) throws IOException {
@@ -482,15 +482,15 @@
         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.serialNumber, localPort, remotePort));
-    
+                    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);
@@ -500,7 +500,7 @@
                 adbChan.close();
             }
         }
-        
+
         return true;
     }
 
@@ -520,15 +520,15 @@
         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.serialNumber, localPort, remotePort));
-    
+                    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);
@@ -563,7 +563,7 @@
         }
         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).
@@ -572,7 +572,7 @@
      *      mode for timeouts to work
      * @param data the buffer to store the read data into.
      * @return "true" if all data was read.
-     * @throws IOException 
+     * @throws IOException
      */
     static boolean read(SocketChannel chan, byte[] data) {
        try {
@@ -581,7 +581,7 @@
            Log.d("ddms", "readAll: IOException: " + e.getMessage());
            return false;
        }
-       
+
        return true;
     }
 
@@ -597,7 +597,7 @@
      * @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 
+     * @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);
@@ -653,7 +653,7 @@
      * @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 
+     * @throws IOException
      */
     static void write(SocketChannel chan, byte[] data, int length, int timeout)
             throws IOException {
@@ -697,7 +697,7 @@
         // 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.serialNumber; //$NON-NLS-1$
+            String msg = "host:transport:" + device.getSerialNumber(); //$NON-NLS-1$
             byte[] device_query = formAdbRequest(msg);
 
             if (write(adbChan, device_query) == false)
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java
index 795bf88..9d6294a 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java
@@ -37,7 +37,7 @@
  * <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
@@ -48,7 +48,7 @@
 
     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$
 
@@ -107,7 +107,7 @@
 
     /**
      * Classes which implement this interface provide methods that deal
-     * with {@link Device} addition, deletion, and changes.
+     * with {@link IDevice} addition, deletion, and changes.
      */
     public interface IDeviceChangeListener {
         /**
@@ -116,7 +116,7 @@
          * This is sent from a non UI thread.
          * @param device the new device.
          */
-        public void deviceConnected(Device device);
+        public void deviceConnected(IDevice device);
 
         /**
          * Sent when the a device is connected to the {@link AndroidDebugBridge}.
@@ -124,7 +124,7 @@
          * This is sent from a non UI thread.
          * @param device the new device.
          */
-        public void deviceDisconnected(Device device);
+        public void deviceDisconnected(IDevice device);
 
         /**
          * Sent when a device data changed, or when clients are started/terminated on the device.
@@ -132,10 +132,10 @@
          * 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 Device#CHANGE_BUILD_INFO}, {@link Device#CHANGE_STATE},
-         * {@link Device#CHANGE_CLIENT_LIST}
+         * values: {@link IDevice#CHANGE_BUILD_INFO}, {@link IDevice#CHANGE_STATE},
+         * {@link IDevice#CHANGE_CLIENT_LIST}
          */
-        public void deviceChanged(Device device, int changeMask);
+        public void deviceChanged(IDevice device, int changeMask);
     }
 
     /**
@@ -194,6 +194,7 @@
         HandleThread.register(monitorThread);
         HandleHeap.register(monitorThread);
         HandleWait.register(monitorThread);
+        HandleProfiling.register(monitorThread);
     }
 
     /**
@@ -211,15 +212,15 @@
             monitorThread.quit();
         }
     }
-    
+
     /**
      * Returns whether the ddmlib is setup to support monitoring and interacting with
-     * {@link Client}s running on the {@link Device}s.
+     * {@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
@@ -324,6 +325,7 @@
 
     /**
      * 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)}.
      */
@@ -389,7 +391,7 @@
     }
 
     /**
-     * Adds the listener to the collection of listeners who will be notified when a {@link Device}
+     * 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.
@@ -404,7 +406,7 @@
 
     /**
      * Removes the listener from the collection of listeners who will be notified when a
-     * {@link Device} is connected, disconnected, or when its properties or its {@link Client}
+     * {@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.
      */
@@ -444,30 +446,30 @@
      * Returns the devices.
      * @see #hasInitialDeviceList()
      */
-    public Device[] getDevices() {
+    public IDevice[] getDevices() {
         synchronized (sLock) {
             if (mDeviceMonitor != null) {
                 return mDeviceMonitor.getDevices();
             }
         }
 
-        return new Device[0];
+        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 Device} list has been
+     * 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 Device} objects is to create a 
+     * <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;
     }
 
@@ -514,7 +516,7 @@
         }
         return -1;
     }
-    
+
     /**
      * Creates a new bridge.
      * @param osLocation the location of the command line tool
@@ -528,7 +530,7 @@
 
         checkAdbVersion();
     }
-    
+
     /**
      * Creates a new bridge not linked to any particular adb executable.
      */
@@ -590,7 +592,7 @@
                 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$
@@ -608,7 +610,7 @@
      * <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).
      */
@@ -665,7 +667,7 @@
     }
 
    /**
-     * Kills the debug bridge.
+     * Kills the debug bridge, and the adb host server.
      * @return true if success
      */
     boolean stop() {
@@ -717,19 +719,19 @@
     }
 
     /**
-     * Notify the listener of a new {@link Device}.
+     * 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 Device} as well as
+     * 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 Device} which is also inside a synchronized block, should first synchronize on
+     * {@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>Device</code>.
+     * @param device the new <code>IDevice</code>.
      * @see #getLock()
      */
-    void deviceConnected(Device device) {
+    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.
@@ -739,7 +741,7 @@
             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
@@ -753,19 +755,19 @@
     }
 
     /**
-     * Notify the listener of a disconnected {@link Device}.
+     * 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 Device} as well as
+     * 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 Device} which is also inside a synchronized block, should first synchronize on
+     * {@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>Device</code>.
+     * @param device the disconnected <code>IDevice</code>.
      * @see #getLock()
      */
-    void deviceDisconnected(Device device) {
+    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.
@@ -775,7 +777,7 @@
             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
@@ -789,19 +791,19 @@
     }
 
     /**
-     * Notify the listener of a modified {@link Device}.
+     * 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 Device} as well as
+     * 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 Device} which is also inside a synchronized block, should first synchronize on
+     * {@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>Device</code>.
+     * @param device the modified <code>IDevice</code>.
      * @see #getLock()
      */
-    void deviceChanged(Device device, int changeMask) {
+    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.
@@ -811,7 +813,7 @@
             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
@@ -828,11 +830,11 @@
      * 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 Device} as well as
+     * 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 Device} which is also inside a synchronized block, should first synchronize on
+     * {@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>
@@ -847,7 +849,7 @@
         synchronized (sLock) {
             listenersCopy = sClientListeners.toArray(
                     new IClientChangeListener[sClientListeners.size()]);
-            
+
         }
 
         // Notify the listeners
@@ -961,7 +963,7 @@
      * @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. 
+     * @param waitforReaders if true, this will wait for the reader threads.
      * @return the process return code.
      * @throws InterruptedException
      */
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ChunkHandler.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ChunkHandler.java
index 441b024..74fa318 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ChunkHandler.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ChunkHandler.java
@@ -199,7 +199,7 @@
     protected static Client checkDebuggerPortForAppName(Client client, String appName) {
         IDebugPortProvider provider = DebugPortManager.getProvider();
         if (provider != null) {
-            Device device = client.getDevice();
+            Device device = client.getDeviceImpl();
             int newPort = provider.getPort(device, appName);
 
             if (newPort != IDebugPortProvider.NO_STATIC_PORT &&
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java
index 866d578..64fbef6 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java
@@ -133,7 +133,7 @@
         mConnState = ST_INIT;
 
         mClientData = new ClientData(pid);
-        
+
         mThreadUpdateEnabled = DdmPreferences.getInitialThreadUpdate();
         mHeapUpdateEnabled = DdmPreferences.getInitialHeapUpdate();
     }
@@ -147,9 +147,15 @@
     }
 
     /**
-     * Returns the {@link Device} on which this Client is running.
+     * Returns the {@link IDevice} on which this Client is running.
      */
-    public Device getDevice() {
+    public IDevice getDevice() {
+        return mDevice;
+    }
+
+    /** Returns the {@link Device} on which this Client is running.
+     */
+    Device getDeviceImpl() {
         return mDevice;
     }
 
@@ -238,7 +244,7 @@
 
         update(CHANGE_THREAD_MODE);
     }
-    
+
     /**
      * Returns whether the thread update is enabled.
      */
@@ -268,7 +274,7 @@
     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.
@@ -320,7 +326,7 @@
 
         return false;
     }
-    
+
     /**
      * Enables or disables the Allocation tracker for this client.
      * <p/>If enabled, the VM will start tracking allocation informations. A call to
@@ -336,7 +342,7 @@
             Log.e("ddmlib", e);
         }
     }
-    
+
     /**
      * Sends a request to the VM to send the enable status of the allocation tracking.
      * This is asynchronous.
@@ -350,9 +356,9 @@
             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>
@@ -457,7 +463,7 @@
         }
 
         mConnState = ST_AWAIT_SHAKE;
-        
+
         return true;
     }
 
@@ -638,7 +644,7 @@
              */
             Log.e("ddms", "Receiving data in state = " + mConnState);
         }
-        
+
         return null;
     }
 
@@ -753,7 +759,7 @@
 
         mDevice.removeClient(this, notify);
     }
-    
+
     /**
      * Returns whether this {@link Client} has a valid connection to the application VM.
      */
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DebugPortManager.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DebugPortManager.java
index 9392127..defdc0e 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DebugPortManager.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DebugPortManager.java
@@ -19,12 +19,12 @@
 import com.android.ddmlib.Device;
 
 /**
- * Centralized point to provide a {@link IDebugPortProvider} to ddmlib. 
- * 
+ * 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 
+ * 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.
@@ -48,7 +48,7 @@
          * @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(Device device, String appName);
+        public int getPort(IDevice device, String appName);
     }
 
     private static IDebugPortProvider sProvider = null;
@@ -63,7 +63,7 @@
     }
 
     /**
-     * Returns the 
+     * Returns the
      * @return
      */
     static IDebugPortProvider getProvider() {
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
index 0e7f0bb..d9d1275 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
@@ -16,7 +16,6 @@
 
 package com.android.ddmlib;
 
-import com.android.ddmlib.Client;
 import com.android.ddmlib.log.LogReceiver;
 
 import java.io.IOException;
@@ -30,50 +29,20 @@
 
 /**
  * A Device. It can be a physical device or an emulator.
- *
- * TODO: make this class package-protected, and shift all callers to use IDevice
  */
-public final class Device implements IDevice {
-    /**
-     * 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;
-        }
-    }
+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 */
-    String serialNumber = null;
+    private String mSerialNumber = null;
 
     /** Name of the AVD */
-    String mAvdName = null;
+    private String mAvdName = null;
 
     /** State of the device. */
-    DeviceState state = null;
+    private DeviceState mState = null;
 
     /** Device properties. */
     private final Map<String, String> mProperties = new HashMap<String, String>();
@@ -91,22 +60,42 @@
      * @see com.android.ddmlib.IDevice#getSerialNumber()
      */
     public String getSerialNumber() {
-        return serialNumber;
+        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 state;
+        return mState;
     }
 
+    /**
+     * Changes the state of the device.
+     */
+    void setState(DeviceState state) {
+        mState = state;
+    }
+
+
     /*
      * (non-Javadoc)
      * @see com.android.ddmlib.IDevice#getProperties()
@@ -134,7 +123,7 @@
 
     @Override
     public String toString() {
-        return serialNumber;
+        return mSerialNumber;
     }
 
     /*
@@ -142,7 +131,7 @@
      * @see com.android.ddmlib.IDevice#isOnline()
      */
     public boolean isOnline() {
-        return state == DeviceState.ONLINE;
+        return mState == DeviceState.ONLINE;
     }
 
     /*
@@ -150,7 +139,7 @@
      * @see com.android.ddmlib.IDevice#isEmulator()
      */
     public boolean isEmulator() {
-        return serialNumber.matches(RE_EMULATOR_SN);
+        return mSerialNumber.matches(RE_EMULATOR_SN);
     }
 
     /*
@@ -158,7 +147,7 @@
      * @see com.android.ddmlib.IDevice#isOffline()
      */
     public boolean isOffline() {
-        return state == DeviceState.OFFLINE;
+        return mState == DeviceState.OFFLINE;
     }
 
     /*
@@ -166,7 +155,7 @@
      * @see com.android.ddmlib.IDevice#isBootLoader()
      */
     public boolean isBootLoader() {
-        return state == DeviceState.BOOTLOADER;
+        return mState == DeviceState.BOOTLOADER;
     }
 
     /*
@@ -208,7 +197,7 @@
      * (non-Javadoc)
      * @see com.android.ddmlib.IDevice#getSyncService()
      */
-    public SyncService getSyncService() {
+    public SyncService getSyncService() throws IOException {
         SyncService syncService = new SyncService(AndroidDebugBridge.sSocketAddr, this);
         if (syncService.openSync()) {
             return syncService;
@@ -305,8 +294,10 @@
     }
 
 
-    Device(DeviceMonitor monitor) {
+    Device(DeviceMonitor monitor, String serialNumber, DeviceState deviceState) {
         mMonitor = monitor;
+        mSerialNumber = serialNumber;
+        mState = deviceState;
     }
 
     DeviceMonitor getMonitor() {
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DeviceMonitor.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DeviceMonitor.java
index f9d0fa0..3382067 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DeviceMonitor.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DeviceMonitor.java
@@ -18,7 +18,7 @@
 
 import com.android.ddmlib.AdbHelper.AdbResponse;
 import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
-import com.android.ddmlib.Device.DeviceState;
+import com.android.ddmlib.IDevice.DeviceState;
 
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
@@ -112,11 +112,11 @@
     boolean isMonitoring() {
         return mMonitoring;
     }
-    
+
     int getConnectionAttemptCount() {
         return mConnectionAttempt;
     }
-    
+
     int getRestartAttemptCount() {
         return mRestartAttemptCount;
     }
@@ -129,7 +129,7 @@
             return mDevices.toArray(new Device[mDevices.size()]);
         }
     }
-    
+
     boolean hasInitialDeviceList() {
         return mInitialDeviceListDone;
     }
@@ -184,11 +184,11 @@
                 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;
                     }
@@ -278,20 +278,19 @@
      */
     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);
-                    device.serialNumber = param[0];
-                    device.state = DeviceState.getState(param[1]);
+                    Device device = new Device(this, param[0] /*serialnumber*/,
+                            DeviceState.getState(param[1]));
 
                     //add the device to the list
                     list.add(device);
@@ -319,24 +318,24 @@
                 // * 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.serialNumber.equals(device.serialNumber)) {
+                        if (newDevice.getSerialNumber().equals(device.getSerialNumber())) {
                             foundMatch = true;
-    
+
                             // update the state if needed.
-                            if (device.state != newDevice.state) {
-                                device.state = newDevice.state;
+                            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()) {
@@ -344,7 +343,7 @@
                                         if (startMonitoringDevice(device) == false) {
                                             Log.e("DeviceMonitor",
                                                     "Failed to start monitoring "
-                                                    + device.serialNumber);
+                                                    + device.getSerialNumber());
                                         }
                                     }
 
@@ -353,13 +352,13 @@
                                     }
                                 }
                             }
-    
+
                             // 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.
@@ -370,21 +369,21 @@
                         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);
@@ -398,7 +397,7 @@
     private void removeDevice(Device device) {
         device.clearClientList();
         mDevices.remove(device);
-        
+
         SocketChannel channel = device.getClientMonitoringSocket();
         if (channel != null) {
             try {
@@ -419,12 +418,12 @@
             // 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.mAvdName = console.getAvdName();
+                    device.setAvdName(console.getAvdName());
                 }
             }
         } catch (IOException e) {
@@ -510,7 +509,7 @@
                         MonitorThread monitorThread = MonitorThread.getInstance();
 
                         for (Client client : clients) {
-                            Device device = client.getDevice();
+                            Device device = client.getDeviceImpl();
                             int pid = client.getClientData().getPid();
 
                             monitorThread.dropClient(client, false /* notify */);
@@ -623,10 +622,10 @@
             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));
@@ -662,7 +661,7 @@
                     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) {
@@ -671,7 +670,7 @@
                                 break;
                             }
                         }
-        
+
                         if (match != null) {
                             pidList.remove(match);
                             c++; // move on to the next client.
@@ -705,7 +704,7 @@
      * @return
      */
     private void openClient(Device device, int pid, int port, MonitorThread monitorThread) {
-        
+
         SocketChannel clientSocket;
         try {
             clientSocket = AdbHelper.createPassThroughConnection(
@@ -721,7 +720,7 @@
                     "Failed to connect to client '" + pid + "': " + ioe.getMessage());
             return ;
         }
-        
+
         createClient(device, pid, clientSocket, port, monitorThread);
     }
 
@@ -748,12 +747,13 @@
                 if (AndroidDebugBridge.getClientSupport()) {
                     client.listenForDebugger(debuggerPort);
                 }
-                client.requestAllocationStatus();
             } catch (IOException ioe) {
                 client.getClientData().setDebuggerConnectionStatus(ClientData.DEBUGGER_ERROR);
                 Log.e("ddms", "Can't bind to local " + debuggerPort + " for debugger");
                 // oh well
             }
+
+            client.requestAllocationStatus();
         } else {
             Log.e("ddms", "Handshake with " + client + " failed!");
             /*
@@ -813,7 +813,7 @@
             }
         }
     }
-    
+
     /**
      * Reads the length of the next message from a socket.
      * @param socket The {@link SocketChannel} to read from.
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/EmulatorConsole.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/EmulatorConsole.java
index f3986ed..75347c6 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/EmulatorConsole.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/EmulatorConsole.java
@@ -41,7 +41,7 @@
  * 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> 
+ * <b>This API will change in the near future.</b>
  */
 public final class EmulatorConsole {
 
@@ -65,7 +65,7 @@
     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 = 
+    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$
@@ -202,9 +202,9 @@
      * @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(Device d) {
+    public static synchronized EmulatorConsole getConsole(IDevice d) {
         // we need to make sure that the device is an emulator
-        Matcher m = sEmulatorRegexp.matcher(d.serialNumber);
+        Matcher m = sEmulatorRegexp.matcher(d.getSerialNumber());
         if (m.matches()) {
             // get the port number. This is the console port.
             int port;
@@ -308,7 +308,7 @@
             RemoveConsole(mPort);
         }
     }
-    
+
     public synchronized String getAvdName() {
         if (sendCommand(COMMAND_AVD_NAME)) {
             String[] result = readLines();
@@ -323,7 +323,7 @@
                 }
             }
         }
-        
+
         return null;
     }
 
@@ -517,18 +517,18 @@
         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);
@@ -537,15 +537,15 @@
         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);
     }
 
@@ -617,7 +617,7 @@
             ByteBuffer buf = ByteBuffer.wrap(mBuffer, 0, mBuffer.length);
             int numWaits = 0;
             boolean stop = false;
-            
+
             while (buf.position() != buf.limit() && stop == false) {
                 int count;
 
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHeap.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHeap.java
index 5752b86..5111638 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHeap.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHeap.java
@@ -32,6 +32,7 @@
     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");
@@ -98,6 +99,8 @@
             client.update(Client.CHANGE_HEAP_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);
             client.update(Client.CHANGE_HEAP_ALLOCATION_STATUS);
@@ -221,6 +224,44 @@
     }
 
     /**
+     * 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);
+    }
+
+    /*
+     * Handle notification of completion of a HeaP DUmp.
+     */
+    private void handleHPDU(Client client, ByteBuffer data) {
+        byte result;
+
+        result = data.get();
+
+        if (result == 0) {
+            Log.i("ddm-heap", "Heap dump request has finished");
+            // TODO: stuff
+        } else {
+            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)
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java
index 5ba5aeb..fb9697c 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java
@@ -20,11 +20,12 @@
 import java.nio.ByteBuffer;
 
 /**
- * Handle the "hello" chunk (HELO).
+ * 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();
 
@@ -65,6 +66,8 @@
         if (type == CHUNK_HELO) {
             assert isReply;
             handleHELO(client, data);
+        } else if (type == CHUNK_FEAT) {
+            handleFEAT(client, data);
         } else {
             handleUnknownChunk(client, type, data, isReply, msgId);
         }
@@ -126,5 +129,37 @@
             + " 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);
+
+            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/HandleProfiling.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java
new file mode 100644
index 0000000..e8e8103
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java
@@ -0,0 +1,163 @@
+/*
+ * 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 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");
+
+    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 {
+            handleUnknownChunk(client, type, data, isReply, msgId);
+        }
+    }
+
+    /**
+     * Send a MPRS (Method PRofiling Start) request to the client.
+     *
+     * @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 should be zero
+     */
+    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);
+    }
+
+    /**
+     * 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;
+
+        result = data.get();
+
+        if (result == 0) {
+            Log.i("ddm-prof", "Method profiling has finished");
+        } else {
+            Log.w("ddm-prof", "Method profiling has failed (check device log)");
+        }
+
+        // TODO: stuff
+    }
+
+    /**
+     * 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) {
+            Log.i("ddm-prof", "Method profiling is not running");
+        } else {
+            Log.i("ddm-prof", "Method profiling is running");
+        }
+    }
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
index 5dbce92..3a2bd55 100755
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
@@ -16,7 +16,6 @@
 
 package com.android.ddmlib;
 
-import com.android.ddmlib.Device.DeviceState;
 import com.android.ddmlib.log.LogReceiver;
 
 import java.io.IOException;
@@ -41,6 +40,35 @@
     public static final int CHANGE_BUILD_INFO = 0x0004;
 
     /**
+     * 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();
@@ -118,9 +146,11 @@
 
     /**
      * 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.
+     * @return <code>null</code> if the SyncService couldn't be created. This can happen if abd
+     * 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();
+    public SyncService getSyncService() throws IOException;
 
     /**
      * Returns a {@link FileListingService} for this device.
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MonitorThread.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MonitorThread.java
index 79eb5bb..3089c2e 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MonitorThread.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MonitorThread.java
@@ -103,7 +103,7 @@
 
 
     /**
-     * Sets or changes the port number for "debug selected". 
+     * Sets or changes the port number for "debug selected".
      */
     synchronized void setDebugSelectedPort(int port) throws IllegalStateException {
         if (mInstance == null) {
@@ -206,7 +206,7 @@
         }
 
         while (!mQuit) {
-            
+
             try {
                 /*
                  * sync with new registrations: we wait until addClient is done before going through
@@ -215,7 +215,7 @@
                  */
                 synchronized (mClientList) {
                 }
-    
+
                 // (re-)open the "debug selected" port, if it's not opened yet or
                 // if the port changed.
                 try {
@@ -234,7 +234,7 @@
                     Log.e("ddms", ioe);
                     mNewDebugSelectedPort = mDebugSelectedPort; // no retry
                 }
-    
+
                 int count;
                 try {
                     count = mSelector.select();
@@ -244,20 +244,20 @@
                 } 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);
@@ -300,7 +300,7 @@
      */
     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.");
@@ -423,7 +423,7 @@
      * @param notify
      */
     synchronized void dropClient(Client client, boolean notify) {
-        if (mInstance == null) { 
+        if (mInstance == null) {
             return;
         }
 
@@ -551,13 +551,13 @@
 
                 // we should drop the client, but also attempt to reopen it.
                 // This is done by the DeviceMonitor.
-                client.getDevice().getMonitor().addClientToDropAndReopen(client,
+                client.getDeviceImpl().getMonitor().addClientToDropAndReopen(client,
                         IDebugPortProvider.NO_STATIC_PORT);
             } else {
                 Log.i("ddms", " (recycling client connection as well)");
                 // we should drop the client, but also attempt to reopen it.
                 // This is done by the DeviceMonitor.
-                client.getDevice().getMonitor().addClientToDropAndReopen(client,
+                client.getDeviceImpl().getMonitor().addClientToDropAndReopen(client,
                         IDebugPortProvider.NO_STATIC_PORT);
             }
         }
@@ -644,7 +644,7 @@
             }
         }
     }
-    
+
     /*
      * Broadcast an event to all message handlers.
      */
@@ -719,7 +719,7 @@
             }
 
             mDebugSelectedChan.register(mSelector, SelectionKey.OP_ACCEPT, this);
-            
+
             return true;
         } catch (java.net.BindException e) {
             displayDebugSelectedBindError(mNewDebugSelectedPort);
@@ -727,7 +727,7 @@
             // do not attempt to reopen it.
             mDebugSelectedChan = null;
             mNewDebugSelectedPort = -1;
-            
+
             return false;
         }
     }
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java
index 44df000..c1d1d3b 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java
@@ -209,9 +209,11 @@
 
     /**
      * Opens the sync connection. This must be called before any calls to push[File] / pull[File].
-     * @return true if the connection opened, false otherwise.
+     * @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() {
+    boolean openSync() throws IOException {
         try {
             mChannel = SocketChannel.open(mAddress);
             mChannel.configureBlocking(false);
@@ -236,13 +238,15 @@
             if (mChannel != null) {
                 try {
                     mChannel.close();
-                } catch (IOException e1) {
-                    // we do nothing, since we'll return false just below
+                } catch (IOException e2) {
+                    // we want to throw the original exception, so we ignore this one.
                 }
                 mChannel = null;
-                return false;
             }
+
+            throw e;
         }
+
         return true;
     }
 
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
index 85e99c1..0b2ce69 100644
--- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventLogParser.java
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventLogParser.java
@@ -16,7 +16,7 @@
 
 package com.android.ddmlib.log;
 
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.MultiLineReceiver;
 import com.android.ddmlib.log.EventContainer.EventValueType;
@@ -55,7 +55,7 @@
     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(
@@ -67,9 +67,9 @@
             "(\\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[]>(); 
+        new TreeMap<Integer, EventValueDescription[]>();
 
     public EventLogParser() {
     }
@@ -82,7 +82,7 @@
      * @param device The device.
      * @return <code>true</code> if success, <code>false</code> if failure or cancellation.
      */
-    public boolean init(Device device) {
+    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$
@@ -103,7 +103,7 @@
 
         return true;
     }
-    
+
     /**
      * Inits the parser with the content of a tag file.
      * @param tagFileContent the lines of a tag file.
@@ -115,7 +115,7 @@
         }
         return true;
     }
-    
+
     /**
      * Inits the parser with a specified event-log-tags file.
      * @param filePath
@@ -124,7 +124,7 @@
     public boolean init(String filePath)  {
         try {
             BufferedReader reader = new BufferedReader(new FileReader(filePath));
-            
+
             String line = null;
             do {
                 line = reader.readLine();
@@ -132,13 +132,13 @@
                     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
@@ -154,7 +154,7 @@
                     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.
@@ -163,12 +163,12 @@
                         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);
                             }
@@ -189,12 +189,12 @@
             }
         }
     }
-    
+
     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()) {
@@ -208,15 +208,15 @@
                         // 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));
@@ -233,15 +233,15 @@
                     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;
@@ -251,7 +251,7 @@
 
         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));
@@ -275,10 +275,10 @@
         } 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>
@@ -289,7 +289,7 @@
         if (textLogLine.length() == 0) {
             return null;
         }
-        
+
         // parse the header first
         Matcher m = TEXT_LOG_LINE.matcher(textLogLine);
         if (m.matches()) {
@@ -300,7 +300,7 @@
                 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);
@@ -308,7 +308,7 @@
                 int nsec = milliseconds * 1000000;
 
                 String tag = m.group(7);
-                
+
                 // get the numerical tag value
                 int tagValue = -1;
                 Set<Entry<Integer, String>> tagSet = mTagMap.entrySet();
@@ -318,18 +318,18 @@
                         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) {
@@ -337,20 +337,20 @@
                 } 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;
     }
@@ -370,7 +370,7 @@
 
         if (eventData.length - dataOffset < 1)
             return -1;
-        
+
         int offset = dataOffset;
 
         int type = eventData[offset++];
@@ -385,7 +385,7 @@
                     return -1;
                 ival = ArrayHelper.swap32bitFromArray(eventData, offset);
                 offset += 4;
-                
+
                 list.add(new Integer(ival));
             }
             break;
@@ -396,7 +396,7 @@
                     return -1;
                 lval = ArrayHelper.swap64bitFromArray(eventData, offset);
                 offset += 8;
-                
+
                 list.add(new Long(lval));
             }
             break;
@@ -410,7 +410,7 @@
 
                 if (eventData.length - offset < strLen)
                     return -1;
-                
+
                 // get the string
                 try {
                     String str = new String(eventData, offset, strLen, "UTF-8"); //$NON-NLS-1$
@@ -434,7 +434,7 @@
                     if (result == -1) {
                         return result;
                     }
-                    
+
                     offset += result;
                 }
 
@@ -446,59 +446,59 @@
                     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; 
+                    objects[i] = obj;
                 }
-                
+
                 return objects;
             }
         }
-        
+
         return null;
     }
 
-    
+
     private Object getObjectFromString(String value, EventValueType type) {
         try {
             switch (type) {
@@ -512,14 +512,14 @@
         } catch (NumberFormatException e) {
             // do nothing, we'll return null.
         }
-        
+
         return null;
     }
 
     /**
-     * Recreates the event-log-tags at the specified file path. 
+     * Recreates the event-log-tags at the specified file path.
      * @param filePath the file path to write the file.
-     * @throws IOException 
+     * @throws IOException
      */
     public void saveTags(String filePath) throws IOException {
         File destFile = new File(filePath);
@@ -527,16 +527,16 @@
         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();
@@ -557,12 +557,12 @@
                         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);
             }
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
index 864e219..04b42cc 100644
--- 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
@@ -22,7 +22,6 @@
 import com.android.ddmlib.IShellOutputReceiver;
 import com.android.ddmlib.RawImage;
 import com.android.ddmlib.SyncService;
-import com.android.ddmlib.Device.DeviceState;
 import com.android.ddmlib.log.LogReceiver;
 
 import java.io.IOException;
@@ -100,7 +99,7 @@
         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, 
+        assertStringsEquals(String.format("am instrument -w -r -e %s %s %s/%s", extraArgName,
                 extraArgValue, TEST_PACKAGE, TEST_RUNNER), mMockDevice.getLastShellCommand());
     }
 
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DevicePanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DevicePanel.java
index 81b757e..d9d6fa1 100644
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DevicePanel.java
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DevicePanel.java
@@ -20,11 +20,11 @@
 import com.android.ddmlib.Client;
 import com.android.ddmlib.ClientData;
 import com.android.ddmlib.DdmPreferences;
-import com.android.ddmlib.Device;
+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.Device.DeviceState;
+import com.android.ddmlib.IDevice.DeviceState;
 
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.viewers.ILabelProviderListener;
@@ -69,16 +69,16 @@
     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$
 
-    private Device mCurrentDevice;
+    private IDevice mCurrentDevice;
     private Client mCurrentClient;
-    
+
     private Tree mTree;
     private TreeViewer mTreeViewer;
 
@@ -92,8 +92,8 @@
     private Image mDebugErrorImage;
 
     private final ArrayList<IUiSelectionListener> mListeners = new ArrayList<IUiSelectionListener>();
-    
-    private final ArrayList<Device> mDevicesToExpand = new ArrayList<Device>();
+
+    private final ArrayList<IDevice> mDevicesToExpand = new ArrayList<IDevice>();
 
     private IImageLoader mLoader;
 
@@ -102,13 +102,13 @@
     /**
      * A Content provider for the {@link TreeViewer}.
      * <p/>
-     * The input is a {@link AndroidDebugBridge}. First level elements are {@link Device} objects,
+     * 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 Device) {
-                return ((Device)parentElement).getClients();
+            if (parentElement instanceof IDevice) {
+                return ((IDevice)parentElement).getClients();
             }
             return new Object[0];
         }
@@ -121,8 +121,8 @@
         }
 
         public boolean hasChildren(Object element) {
-            if (element instanceof Device) {
-                return ((Device)element).hasClients();
+            if (element instanceof IDevice) {
+                return ((IDevice)element).hasClients();
             }
 
             // Clients never have children.
@@ -147,13 +147,13 @@
 
     /**
      * A Label Provider for the {@link TreeViewer} in {@link DevicePanel}. It provides
-     * labels and images for {@link Device} and {@link Client} objects.
+     * 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 Device) {
-                Device device = (Device)element;
+            if (columnIndex == DEVICE_COL_SERIAL && element instanceof IDevice) {
+                IDevice device = (IDevice)element;
                 if (device.isEmulator()) {
                     return mEmulatorImage;
                 }
@@ -192,17 +192,17 @@
         }
 
         public String getColumnText(Object element, int columnIndex) {
-            if (element instanceof Device) {
-                Device device = (Device)element;
+            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(Device.PROP_BUILD_VERSION);
+                        String version = device.getProperty(IDevice.PROP_BUILD_VERSION);
                         if (version != null) {
-                            String debuggable = device.getProperty(Device.PROP_DEBUGGABLE);
+                            String debuggable = device.getProperty(IDevice.PROP_DEBUGGABLE);
                             if (device.isEmulator()) {
                                 String avdName = device.getAvdName();
                                 if (avdName == null) {
@@ -279,15 +279,15 @@
 
     /**
      * Classes which implement this interface provide methods that deals
-     * with {@link Device} and {@link Client} selection changes coming from the ui.
+     * with {@link IDevice} and {@link Client} selection changes coming from the ui.
      */
     public interface IUiSelectionListener {
         /**
-         * Sent when a new {@link Device} and {@link Client} are selected.
+         * 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(Device selectedDevice, Client selectedClient);
+        public void selectionChanged(IDevice selectedDevice, Client selectedClient);
     }
 
     /**
@@ -359,7 +359,7 @@
 
         return mTree;
     }
-    
+
     /**
      * Sets the focus to the proper control inside the panel.
      */
@@ -371,7 +371,7 @@
     @Override
     protected void postCreation() {
         // ask for notification of changes in AndroidDebugBridge (a new one is created when
-        // adb is restarted from a different location), Device and Client objects.
+        // adb is restarted from a different location), IDevice and Client objects.
         AndroidDebugBridge.addDebugBridgeChangeListener(this);
         AndroidDebugBridge.addDeviceChangeListener(this);
         AndroidDebugBridge.addClientChangeListener(this);
@@ -391,10 +391,10 @@
     }
 
     /**
-     * Returns the selected {@link Device}. If a {@link Client} is selected, it returns the
-     * Device object containing the client.
+     * Returns the selected {@link IDevice}. If a {@link Client} is selected, it returns the
+     * IDevice object containing the client.
      */
-    public Device getSelectedDevice() {
+    public IDevice getSelectedDevice() {
         return mCurrentDevice;
     }
 
@@ -404,7 +404,7 @@
     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);
@@ -413,7 +413,7 @@
             client.kill();
         }
     }
-    
+
     /**
      * Forces a GC on the selected {@link Client}.
      */
@@ -422,13 +422,13 @@
             mCurrentClient.executeGarbageCollector();
         }
     }
-    
+
     public void setEnabledHeapOnSelectedClient(boolean enable) {
         if (mCurrentClient != null) {
             mCurrentClient.setHeapUpdateEnabled(enable);
         }
     }
-    
+
     public void setEnabledThreadOnSelectedClient(boolean enable) {
         if (mCurrentClient != null) {
             mCurrentClient.setThreadUpdateEnabled(enable);
@@ -476,9 +476,9 @@
      * This is sent from a non UI thread.
      * @param device the new device.
      *
-     * @see IDeviceChangeListener#deviceConnected(Device)
+     * @see IDeviceChangeListener#deviceConnected(IDevice)
      */
-    public void deviceConnected(Device device) {
+    public void deviceConnected(IDevice device) {
         exec(new Runnable() {
             public void run() {
                 if (mTree.isDisposed() == false) {
@@ -511,11 +511,11 @@
      * This is sent from a non UI thread.
      * @param device the new device.
      *
-     * @see IDeviceChangeListener#deviceDisconnected(Device)
+     * @see IDeviceChangeListener#deviceDisconnected(IDevice)
      */
-    public void deviceDisconnected(Device device) {
+    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);
@@ -529,9 +529,9 @@
      * @param device the device that was updated.
      * @param changeMask the mask indicating what changed.
      *
-     * @see IDeviceChangeListener#deviceChanged(Device)
+     * @see IDeviceChangeListener#deviceChanged(IDevice)
      */
-    public void deviceChanged(final Device device, int changeMask) {
+    public void deviceChanged(final IDevice device, int changeMask) {
         boolean expand = false;
         synchronized (mDevicesToExpand) {
             int index = mDevicesToExpand.indexOf(device);
@@ -540,7 +540,7 @@
                 expand = true;
             }
         }
-        
+
         final boolean finalExpand = expand;
 
         exec(new Runnable() {
@@ -549,22 +549,22 @@
                     // 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.
-                    
-                    Device selectedDevice = getSelectedDevice();
+
+                    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);
                     }
@@ -606,7 +606,7 @@
                         // 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.
-                        Device device = client.getDevice();
+                        IDevice device = client.getDevice();
                         if (mTreeViewer.getExpandedState(device) == false) {
                             mTreeViewer.setExpandedState(device, true);
                         }
@@ -615,11 +615,11 @@
                         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);
                     }
@@ -676,7 +676,7 @@
      * Returns a display string representing the state of the device.
      * @param d the device
      */
-    private static String getStateString(Device d) {
+    private static String getStateString(IDevice d) {
         DeviceState deviceState = d.getState();
         if (deviceState == DeviceState.ONLINE) {
             return "Online";
@@ -704,32 +704,32 @@
             AndroidDebugBridge.removeClientChangeListener(this);
         }
     }
-    
+
     private void notifyListeners() {
         // get the selection
         TreeItem[] items = mTree.getSelection();
 
         Client client = null;
-        Device device = 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 Device) {
-                device = (Device)object;
+            } else if (object instanceof IDevice) {
+                device = (IDevice)object;
             }
         }
 
         notifyListeners(device, client);
     }
-    
-    private void notifyListeners(Device selectedDevice, Client selectedClient) {
+
+    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.
@@ -740,5 +740,5 @@
             }
         }
     }
-    
+
 }
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/EmulatorControlPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/EmulatorControlPanel.java
index 5583760..4410d3a 100644
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/EmulatorControlPanel.java
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/EmulatorControlPanel.java
@@ -16,7 +16,7 @@
 
 package com.android.ddmuilib;
 
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.EmulatorConsole;
 import com.android.ddmlib.EmulatorConsole.GsmMode;
 import com.android.ddmlib.EmulatorConsole.GsmStatus;
@@ -75,7 +75,7 @@
     // 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";
 
 
@@ -106,7 +106,7 @@
         "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$
@@ -149,7 +149,7 @@
     private Button mCancelButton;
 
     private TabFolder mLocationFolders;
-    
+
     private Button mDecimalButton;
     private Button mSexagesimalButton;
     private CoordinateControls mLongitudeControls;
@@ -177,7 +177,7 @@
     private int mPlayDirection = 1;
     private int mSpeed;
     private int mSpeedIndex;
-    
+
     private final SelectionAdapter mDirectionButtonAdapter = new SelectionAdapter() {
         @Override
         public void widgetSelected(SelectionEvent e) {
@@ -188,7 +188,7 @@
                 b.setSelection(true);
                 return;
             }
-            
+
             // now handle selection change.
             if (b == mGpxForwardButton || b == mKmlForwardButton) {
                 mGpxBackwardButton.setSelection(false);
@@ -196,7 +196,7 @@
                 mKmlBackwardButton.setSelection(false);
                 mKmlForwardButton.setSelection(true);
                 mPlayDirection = 1;
-                
+
             } else {
                 mGpxBackwardButton.setSelection(true);
                 mGpxForwardButton.setSelection(false);
@@ -206,27 +206,27 @@
             }
         }
     };
-    
+
     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;
     }
@@ -274,11 +274,11 @@
                 scollingParent.setMinSize(top.computeSize(r.width, SWT.DEFAULT));
             }
         });
-        
+
         createRadioControls(top);
 
         createCallControls(top);
-        
+
         createLocationControls(top);
 
         doEnable(false);
@@ -379,7 +379,7 @@
         Label l = new Label(g1, SWT.NONE);
         l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
     }
-    
+
     /**
      * Create Voice/SMS call/hang up controls
      * @param top
@@ -517,7 +517,7 @@
             }
         });
     }
-    
+
     /**
      * Create Location controls.
      * @param top
@@ -526,15 +526,15 @@
         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$
@@ -544,7 +544,7 @@
         item = new TabItem(mLocationFolders, SWT.NONE);
         item.setText("GPX");
         item.setControl(gpxLocationComp);
-        
+
         createGpxLocationControl(gpxLocationComp);
 
         Composite kmlLocationComp = new Composite(mLocationFolders, SWT.NONE);
@@ -552,7 +552,7 @@
         item = new TabItem(mLocationFolders, SWT.NONE);
         item.setText("KML");
         item.setControl(kmlLocationComp);
-        
+
         createKmlLocationControl(kmlLocationComp);
     }
 
@@ -572,63 +572,63 @@
         // 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("\"");
 
@@ -647,7 +647,7 @@
                 content.layout();
             }
         });
-        
+
         Button sendButton = new Button(manualLocationComp, SWT.PUSH);
         sendButton.setText("Send");
         sendButton.addSelectionListener(new SelectionAdapter() {
@@ -659,7 +659,7 @@
                 }
             }
         });
-        
+
         mLongitudeControls.setValue(DEFAULT_LONGITUDE);
         mLatitudeControls.setValue(DEFAULT_LATITUDE);
     }
@@ -681,7 +681,7 @@
         gd.heightHint = 100;
         mGpxWayPointTable.setHeaderVisible(true);
         mGpxWayPointTable.setLinesVisible(true);
-        
+
         TableHelper.createTableColumn(mGpxWayPointTable, "Name", SWT.LEFT,
                 "Some Name",
                 PREFS_WAYPOINT_COL_NAME, store);
@@ -701,7 +701,7 @@
         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();
@@ -710,7 +710,7 @@
                     Object selectedObject = structuredSelection.getFirstElement();
                     if (selectedObject instanceof WayPoint) {
                         WayPoint wayPoint = (WayPoint)selectedObject;
-                        
+
                         if (mEmulatorConsole != null && mPlayingTrack == false) {
                             processCommandResult(mEmulatorConsole.sendLocation(
                                     wayPoint.getLongitude(), wayPoint.getLatitude(),
@@ -748,7 +748,7 @@
         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();
@@ -757,19 +757,19 @@
                     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;
                     }
                 }
@@ -780,7 +780,7 @@
                 mGpxSpeedButton.setEnabled(false);
             }
         });
-        
+
         mGpxUploadButton.addSelectionListener(new SelectionAdapter() {
             @Override
             public void widgetSelected(SelectionEvent e) {
@@ -799,7 +799,7 @@
                 }
             }
         });
-        
+
         mGpxPlayControls = new Composite(gpxLocationComp, SWT.NONE);
         GridLayout gl;
         mGpxPlayControls.setLayout(gl = new GridLayout(5, false));
@@ -828,14 +828,14 @@
                        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);
@@ -852,7 +852,7 @@
 
         mGpxSpeedButton.setText(String.format(SPEED_FORMAT, mSpeed));
         mGpxSpeedButton.addSelectionListener(mSpeedButtonAdapter);
-        
+
         mPlayGpxButton.setEnabled(false);
         mGpxBackwardButton.setEnabled(false);
         mGpxForwardButton.setEnabled(false);
@@ -877,7 +877,7 @@
         gd.heightHint = 200;
         mKmlWayPointTable.setHeaderVisible(true);
         mKmlWayPointTable.setLinesVisible(true);
-        
+
         TableHelper.createTableColumn(mKmlWayPointTable, "Name", SWT.LEFT,
                 "Some Name",
                 PREFS_WAYPOINT_COL_NAME, store);
@@ -911,7 +911,7 @@
                     KmlParser parser = new KmlParser(fileName);
                     if (parser.parse()) {
                         kmlWayPointViewer.setInput(parser.getWayPoints());
-                        
+
                         mPlayKmlButton.setEnabled(true);
                         mKmlBackwardButton.setEnabled(true);
                         mKmlForwardButton.setEnabled(true);
@@ -920,7 +920,7 @@
                 }
             }
         });
-        
+
         kmlWayPointViewer.addSelectionChangedListener(new ISelectionChangedListener() {
             public void selectionChanged(SelectionChangedEvent event) {
                 ISelection selection = event.getSelection();
@@ -929,7 +929,7 @@
                     Object selectedObject = structuredSelection.getFirstElement();
                     if (selectedObject instanceof WayPoint) {
                         WayPoint wayPoint = (WayPoint)selectedObject;
-                        
+
                         if (mEmulatorConsole != null && mPlayingTrack == false) {
                             processCommandResult(mEmulatorConsole.sendLocation(
                                     wayPoint.getLongitude(), wayPoint.getLatitude(),
@@ -939,9 +939,9 @@
                 }
             }
         });
-        
-        
-        
+
+
+
         mKmlPlayControls = new Composite(kmlLocationComp, SWT.NONE);
         GridLayout gl;
         mKmlPlayControls.setLayout(gl = new GridLayout(5, false));
@@ -965,14 +965,14 @@
                        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);
@@ -989,7 +989,7 @@
 
         mKmlSpeedButton.setText(String.format(SPEED_FORMAT, mSpeed));
         mKmlSpeedButton.addSelectionListener(mSpeedButtonAdapter);
-        
+
         mPlayKmlButton.setEnabled(false);
         mKmlBackwardButton.setEnabled(false);
         mKmlForwardButton.setEnabled(false);
@@ -1039,7 +1039,7 @@
      * Callback on device selection change.
      * @param device the new selected device
      */
-    public void handleNewDevice(Device device) {
+    public void handleNewDevice(IDevice device) {
         if (mParent.isDisposed()) {
             return;
         }
@@ -1061,7 +1061,7 @@
                         // get the gsm status
                         gsm = mEmulatorConsole.getGsmStatus();
                         netstatus = mEmulatorConsole.getNetworkStatus();
-                        
+
                         if (gsm == null || netstatus == null) {
                             mEmulatorConsole = null;
                         }
@@ -1073,7 +1073,7 @@
                     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) {
@@ -1109,7 +1109,7 @@
             synchronized (this) {
                 enable = mEmulatorConsole != null;
             }
-            
+
             enable(enable);
         }
     }
@@ -1240,10 +1240,10 @@
             } catch (SWTException e) {
                 // we're quitting, just ignore
             }
-            
+
             return false;
         }
-        
+
         return true;
     }
 
@@ -1264,13 +1264,13 @@
                     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;
@@ -1299,7 +1299,7 @@
                                 if (delta < 0) {
                                     delta = -delta;
                                 }
-                                
+
                                 long startTime = System.currentTimeMillis();
 
                                 try {
@@ -1308,7 +1308,7 @@
                                     if (mPlayingTrack == false) {
                                         return;
                                     }
-                                    
+
                                     // we got interrupted, lets make sure we can play
                                     do {
                                         long waited = System.currentTimeMillis() - startTime;
@@ -1351,7 +1351,7 @@
             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.
@@ -1365,13 +1365,13 @@
                 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;
@@ -1399,7 +1399,7 @@
                                 if (delta < 0) {
                                     delta = -delta;
                                 }
-                                
+
                                 long startTime = System.currentTimeMillis();
 
                                 try {
@@ -1408,7 +1408,7 @@
                                     if (mPlayingTrack == false) {
                                         return;
                                     }
-                                    
+
                                     // we got interrupted, lets make sure we can play
                                     do {
                                         long waited = System.currentTimeMillis() - startTime;
@@ -1449,6 +1449,6 @@
             };
 
             mPlayingThread.start();
-        }        
+        }
     }
 }
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java
index dad54dc..b9bb10c 100644
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java
@@ -16,7 +16,7 @@
 
 package com.android.ddmuilib;
 
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.RawImage;
 
@@ -47,7 +47,7 @@
     private Label mBusyLabel;
     private Label mImageLabel;
     private Button mSave;
-    private Device mDevice;
+    private IDevice mDevice;
 
 
     /**
@@ -66,9 +66,9 @@
 
     /**
      * Prepare and display the dialog.
-     * @param device The {@link Device} from which to get the screenshot.
+     * @param device The {@link IDevice} from which to get the screenshot.
      */
-    public void open(Device device) {
+    public void open(IDevice device) {
         mDevice = device;
 
         Shell parent = getParent();
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SelectionDependentPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SelectionDependentPanel.java
index 4b5fe56..e6d2211 100644
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SelectionDependentPanel.java
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SelectionDependentPanel.java
@@ -17,20 +17,20 @@
 package com.android.ddmuilib;
 
 import com.android.ddmlib.Client;
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 
 /**
  * A Panel that requires {@link Device}/{@link Client} selection notifications.
  */
 public abstract class SelectionDependentPanel extends Panel {
-    private Device mCurrentDevice = null;
+    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 Device getCurrentDevice() {
+    protected final IDevice getCurrentDevice() {
         return mCurrentDevice;
     }
 
@@ -46,7 +46,7 @@
      * Sent when a new device is selected.
      * @param selectedDevice the selected device.
      */
-    public final void deviceSelected(Device selectedDevice) {
+    public final void deviceSelected(IDevice selectedDevice) {
         if (selectedDevice != mCurrentDevice) {
             mCurrentDevice = selectedDevice;
             deviceSelected();
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
index ba0f555..4652b31 100644
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java
@@ -16,7 +16,7 @@
 
 package com.android.ddmuilib.explorer;
 
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.FileListingService;
 import com.android.ddmlib.IShellOutputReceiver;
 import com.android.ddmlib.SyncService;
@@ -99,7 +99,7 @@
     private Image mPackageImage;
     private Image mOtherImage;
 
-    private Device mCurrentDevice;
+    private IDevice mCurrentDevice;
 
     private String mDefaultSave;
 
@@ -374,13 +374,13 @@
 
             }
         }.start();
-        
+
         return mTree;
     }
-    
+
     @Override
     protected void postCreation() {
-        
+
     }
 
     /**
@@ -418,61 +418,67 @@
         }
 
         // download the files
-        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;
-            }
+        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;
-            }
+                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;
+                // 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);
+                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);
+                    // 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;
+                            // 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) {
+
                             }
-                            // get the return code from the process
-                            p.waitFor();
-                        } catch (IOException e) {
-                        } catch (InterruptedException e) {
-
                         }
-                    }
-                }.start();
+                    }.start();
 
-            } catch (IOException e) {
+                } catch (IOException e) {
+                }
             }
+        } catch (IOException e) {
+            DdmConsole.printErrorToConsole(String.format(
+                    "Failed to pull %1$s: %2$s", keyEntry.getName(), e.getMessage()));
+            return;
         }
     }
 
@@ -625,7 +631,7 @@
     /**
      * Sets the new device to explorer
      */
-    public void switchDevice(final Device device) {
+    public void switchDevice(final IDevice device) {
         if (device != mCurrentDevice) {
             mCurrentDevice = device;
             // now we change the input. but we need to do that in the
@@ -667,21 +673,21 @@
      * @param localDirector the local directory in which to save the files.
      */
     private void pullSelection(TreeItem[] items, final String localDirectory) {
-        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);
+        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()]);
+                final FileEntry[] entryArray = entries.toArray(
+                        new FileEntry[entries.size()]);
 
-            // get a progressdialog
-            try {
+                // get a progressdialog
                 new ProgressMonitorDialog(mParent.getShell()).run(true, true,
                         new IRunnableWithProgress() {
                     public void run(IProgressMonitor monitor)
@@ -699,13 +705,10 @@
                         sync.close();
                     }
                 });
-            } catch (InvocationTargetException e) {
-                DdmConsole.printErrorToConsole( "Failed to pull selection");
-                DdmConsole.printErrorToConsole(e.getMessage());
-            } catch (InterruptedException e) {
-                DdmConsole.printErrorToConsole("Failed to pull selection");
-                DdmConsole.printErrorToConsole(e.getMessage());
             }
+        } catch (Exception e) {
+            DdmConsole.printErrorToConsole( "Failed to pull selection");
+            DdmConsole.printErrorToConsole(e.getMessage());
         }
     }
 
@@ -715,9 +718,9 @@
      * @param local the destination filepath
      */
     private void pullFile(final FileEntry remote, final String local) {
-        final SyncService sync = mCurrentDevice.getSyncService();
-        if (sync != null) {
-            try {
+        try {
+            final SyncService sync = mCurrentDevice.getSyncService();
+            if (sync != null) {
                 new ProgressMonitorDialog(mParent.getShell()).run(true, true,
                         new IRunnableWithProgress() {
                     public void run(IProgressMonitor monitor)
@@ -734,13 +737,10 @@
                         sync.close();
                     }
                 });
-            } catch (InvocationTargetException e) {
-                DdmConsole.printErrorToConsole( "Failed to pull selection");
-                DdmConsole.printErrorToConsole(e.getMessage());
-            } catch (InterruptedException e) {
-                DdmConsole.printErrorToConsole("Failed to pull selection");
-                DdmConsole.printErrorToConsole(e.getMessage());
             }
+        } catch (Exception e) {
+            DdmConsole.printErrorToConsole( "Failed to pull selection");
+            DdmConsole.printErrorToConsole(e.getMessage());
         }
     }
 
@@ -750,9 +750,9 @@
      * @param remoteDirectory
      */
     private void pushFiles(final String[] localFiles, final FileEntry remoteDirectory) {
-        final SyncService sync = mCurrentDevice.getSyncService();
-        if (sync != null) {
-            try {
+        try {
+            final SyncService sync = mCurrentDevice.getSyncService();
+            if (sync != null) {
                 new ProgressMonitorDialog(mParent.getShell()).run(true, true,
                         new IRunnableWithProgress() {
                     public void run(IProgressMonitor monitor)
@@ -769,14 +769,10 @@
                         sync.close();
                     }
                 });
-            } catch (InvocationTargetException e) {
-                DdmConsole.printErrorToConsole("Failed to push the items");
-                DdmConsole.printErrorToConsole(e.getMessage());
-            } catch (InterruptedException e) {
-                DdmConsole.printErrorToConsole("Failed to push the items");
-                DdmConsole.printErrorToConsole(e.getMessage());
             }
-            return;
+        } catch (Exception e) {
+            DdmConsole.printErrorToConsole("Failed to push the items");
+            DdmConsole.printErrorToConsole(e.getMessage());
         }
     }
 
@@ -786,9 +782,9 @@
      * @param remoteDirectory the remote destination directory on the device
      */
     private void pushFile(final String local, final String remoteDirectory) {
-        final SyncService sync = mCurrentDevice.getSyncService();
-        if (sync != null) {
-            try {
+        try {
+            final SyncService sync = mCurrentDevice.getSyncService();
+            if (sync != null) {
                 new ProgressMonitorDialog(mParent.getShell()).run(true, true,
                         new IRunnableWithProgress() {
                     public void run(IProgressMonitor monitor)
@@ -812,14 +808,10 @@
                         sync.close();
                     }
                 });
-            } catch (InvocationTargetException e) {
-                DdmConsole.printErrorToConsole("Failed to push the item(s).");
-                DdmConsole.printErrorToConsole(e.getMessage());
-            } catch (InterruptedException e) {
-                DdmConsole.printErrorToConsole("Failed to push the item(s).");
-                DdmConsole.printErrorToConsole(e.getMessage());
             }
-            return;
+        } catch (Exception e) {
+            DdmConsole.printErrorToConsole("Failed to push the item(s).");
+            DdmConsole.printErrorToConsole(e.getMessage());
         }
     }
 
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
index 2621c6a..11138d1 100644
--- 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
@@ -17,7 +17,7 @@
 package com.android.ddmuilib.log.event;
 
 import com.android.ddmlib.Client;
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.Log.LogLevel;
 import com.android.ddmlib.log.EventContainer;
@@ -80,7 +80,7 @@
 
     private IImageLoader mImageLoader;
 
-    private Device mCurrentLoggedDevice;
+    private IDevice mCurrentLoggedDevice;
     private String mCurrentLogFile;
     private LogReceiver mCurrentLogReceiver;
     private EventLogParser mCurrentEventLogParser;
@@ -94,7 +94,7 @@
     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>();
 
@@ -107,7 +107,7 @@
     private ICommonAction mSaveAction;
     private ICommonAction mLoadAction;
     private ICommonAction mImportAction;
-    
+
     /** file containing the current log raw data. */
     private File mTempFile = null;
 
@@ -209,10 +209,10 @@
                     // get the new EventDisplay list
                     mEventDisplays.clear();
                     mEventDisplays.addAll(dialog.getEventDisplays());
-                    
+
                     // since the list of EventDisplay changed, we store it.
                     saveEventDisplays();
-                    
+
                     rebuildUi();
                 }
             }
@@ -220,7 +220,7 @@
             Log.e("EventLog", e); //$NON-NLS-1$
         }
     }
-    
+
     /**
      * Clears the log.
      * <p/>
@@ -240,7 +240,7 @@
             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.
@@ -254,16 +254,16 @@
             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);
@@ -293,16 +293,16 @@
 
         }
     }
-    
+
     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());
@@ -324,7 +324,7 @@
     public void deviceSelected() {
         startEventLog(getCurrentDevice());
     }
-    
+
     /*
      * (non-Javadoc)
      * @see com.android.ddmlib.AndroidDebugBridge.IClientChangeListener#clientChanged(com.android.ddmlib.Client, int)
@@ -359,7 +359,7 @@
         // 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);
@@ -383,7 +383,7 @@
 
         // create the ui
         createDisplayUi();
-        
+
         return mBottomParentPanel;
     }
 
@@ -402,12 +402,12 @@
     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 Device device) {
+    private void startEventLog(final IDevice device) {
         if (device == mCurrentLoggedDevice) {
             return;
         }
@@ -448,10 +448,10 @@
                             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");
 
@@ -464,7 +464,7 @@
             }.start();
         }
     }
-    
+
     private void startEventLogFromFiles(final String fileName) {
         // if we have a logcat already running
         if (mCurrentLogReceiver != null) {
@@ -475,7 +475,7 @@
 
         // create a new output receiver
         mCurrentLogReceiver = new LogReceiver(this);
-        
+
         mSaveAction.setEnabled(false);
 
         // start the logcat in a different thread
@@ -493,10 +493,10 @@
                             return;
                         }
                     }
-                    
+
                     // update the event display with the new parser.
                     updateEventDisplays();
-                    
+
                     runLocalEventLogService(fileName, mCurrentLogReceiver);
                 } catch (Exception e) {
                     Log.e("EventLog", e);
@@ -516,7 +516,7 @@
 
         // create a new output receiver
         mCurrentLogReceiver = new LogReceiver(this);
-        
+
         mSaveAction.setEnabled(false);
 
         // start the logcat in a different thread
@@ -531,10 +531,10 @@
                             return;
                         }
                     }
-                    
+
                     // update the event display with the new parser.
                     updateEventDisplays();
-                    
+
                     runLocalEventLogService(log, mCurrentLogReceiver);
                 } catch (Exception e) {
                     Log.e("EventLog", e);
@@ -563,7 +563,7 @@
 
             resetUI(inUiThread);
         }
-        
+
         if (mTempFile != null) {
             mTempFile.delete();
             mTempFile = null;
@@ -593,7 +593,7 @@
             }
         }
     }
-    
+
     private void resetUiFromUiThread() {
         synchronized(mLock) {
             for (EventDisplay eventDisplay : mEventDisplays) {
@@ -618,11 +618,11 @@
         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) {
@@ -631,7 +631,7 @@
                 rd.width = displayWidth;
                 c.setLayoutData(rd);
             }
-            
+
             Table table = eventDisplay.getTable();
             if (table != null) {
                 addTableToFocusListener(table);
@@ -642,7 +642,7 @@
         mBottomParentPanel.setMinSize(mBottomPanel.computeSize(SWT.DEFAULT, SWT.DEFAULT));
         mBottomParentPanel.layout();
     }
-    
+
     /**
      * Rebuild the display ui.
      */
@@ -652,26 +652,26 @@
             // 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));
@@ -682,7 +682,7 @@
     /**
      * 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) 
+     * @see LogReceiver.ILogListener#newEntry(LogEntry)
      */
     @WorkerThread
     public void newEntry(LogEntry entry) {
@@ -695,24 +695,24 @@
             }
         }
     }
-    
+
     @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;
@@ -737,7 +737,7 @@
                 }
             });
         } catch (SWTException e) {
-            // if the ui is disposed, do nothing 
+            // if the ui is disposed, do nothing
         }
     }
 
@@ -766,7 +766,7 @@
         for (EventDisplay eventDisplay : mEventDisplays) {
             eventDisplay.startMultiEventDisplay();
         }
-        
+
         // display the new events
         EventContainer event = null;
         boolean need_to_reloop = false;
@@ -803,7 +803,7 @@
         for (EventDisplay eventDisplay : mEventDisplays) {
             eventDisplay.endMultiEventDisplay();
         }
-        
+
         // if needed, ask the UI thread to re-run this method.
         if (need_to_reloop) {
             scheduleUIEventHandler();
@@ -816,10 +816,10 @@
     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) {
@@ -834,10 +834,10 @@
      */
     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) {
@@ -846,7 +846,7 @@
                 } else {
                     first = false;
                 }
-                
+
                 sb.append(storage);
             }
         }
@@ -870,7 +870,7 @@
                         for (EventDisplay eventDisplay : mEventDisplays) {
                             eventDisplay.setNewLogParser(mCurrentEventLogParser);
                         }
-                        
+
                         mOptionsAction.setEnabled(true);
                         mClearAction.setEnabled(true);
                         if (mCurrentLogFile == null) {
@@ -897,21 +897,21 @@
      * 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 
+     * @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) {
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
index bd8b75c..154e2fa 100644
--- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java
@@ -16,7 +16,7 @@
 
 package com.android.ddmuilib.logcat;
 
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.MultiLineReceiver;
 import com.android.ddmlib.Log.LogLevel;
@@ -163,13 +163,13 @@
     private int mFilterMode = FILTER_NONE;
 
     /** Device currently running logcat */
-    private Device mCurrentLoggedDevice = null;
+    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;
@@ -183,7 +183,7 @@
      * 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
@@ -481,7 +481,7 @@
      * Starts a new logcat and set mCurrentLogCat as the current receiver.
      * @param device the device to connect logcat to.
      */
-    public void startLogCat(final Device device) {
+    public void startLogCat(final IDevice device) {
         if (device == mCurrentLoggedDevice) {
             return;
         }
@@ -491,7 +491,7 @@
             stopLogCat(false);
             mCurrentLoggedDevice = null;
         }
-        
+
         resetUI(false);
 
         if (device != null) {
@@ -696,7 +696,7 @@
         synchronized (mBuffer) {
             FileDialog dlg = new FileDialog(mParent.getShell(), SWT.SAVE);
             String fileName;
-    
+
             dlg.setText("Save log...");
             dlg.setFileName("log.txt");
             String defaultPath = mDefaultLogSave;
@@ -710,7 +710,7 @@
             dlg.setFilterExtensions(new String[] {
                 "*.txt"
             });
-    
+
             fileName = dlg.open();
             if (fileName != null) {
                 mDefaultLogSave = dlg.getFilterPath();
@@ -928,7 +928,7 @@
             t.setLinesVisible(false);
 
             if (mGlobalListener != null) {
-            	addTableToFocusListener(t);
+                addTableToFocusListener(t);
             }
 
             // create a controllistener that will handle the resizing of all the
@@ -1064,7 +1064,7 @@
     }
 
     /**
-     * Process new Log lines coming from {@link LogCatOuputReceiver}. 
+     * Process new Log lines coming from {@link LogCatOuputReceiver}.
      * @param lines the new lines
      */
     protected void processLogLines(String[] lines) {
@@ -1074,10 +1074,10 @@
         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.
@@ -1087,7 +1087,7 @@
                     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);
@@ -1097,7 +1097,7 @@
                         // 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
@@ -1109,34 +1109,34 @@
                             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() {
@@ -1165,7 +1165,7 @@
                             f.flush();
                         }
                     }
-    
+
                     if (mDefaultFilter != null) {
                         mDefaultFilter.flush();
                     }
@@ -1209,7 +1209,7 @@
             // increment the next usable slot index
             mBufferEnd = (mBufferEnd + 1) % STRING_BUFFER_LENGTH;
         }
-        
+
         LogMessage oldMessage = null;
 
         // record the message that was there before
@@ -1381,7 +1381,7 @@
             initDefaultFilter();
             return;
         }
-        
+
         filter.clear();
 
         if (mBufferStart != -1) {
@@ -1482,13 +1482,13 @@
             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;
@@ -1511,12 +1511,12 @@
                     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);
@@ -1526,7 +1526,7 @@
                     }
                     f.setTempKeywordFiltering(keywordsArray);
                 }
-    
+
                 if (mDefaultFilter != null) {
                     if (tempPid != -1) {
                         mDefaultFilter.setTempPidFiltering(tempPid);
@@ -1535,10 +1535,10 @@
                         mDefaultFilter.setTempTagFiltering(tempTag);
                     }
                     mDefaultFilter.setTempKeywordFiltering(keywordsArray);
-    
+
                 }
             }
-    
+
             initFilter(mCurrentFilter);
         }
     }
diff --git a/tools/dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java b/tools/dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java
index 6c528e1..695573c 100644
--- a/tools/dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java
+++ b/tools/dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java
@@ -17,7 +17,7 @@
 package com.android.dumpeventlog;
 
 import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.Log.ILogOutput;
 import com.android.ddmlib.Log.LogLevel;
@@ -30,7 +30,7 @@
 import java.io.IOException;
 
 /**
- * Connects to a device using ddmlib and dumps its event log as long as the device is connected. 
+ * Connects to a device using ddmlib and dumps its event log as long as the device is connected.
  */
 public class DumpEventLog {
 
@@ -74,7 +74,7 @@
             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) {
@@ -85,13 +85,13 @@
                 // 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.
@@ -103,7 +103,7 @@
                 } catch (InterruptedException e) {
                     // pass
                 }
-                
+
                 // let's not wait > 10 sec.
                 if (count > 100) {
                     System.err.println("Timeout getting device list!");
@@ -112,9 +112,9 @@
             }
 
             // now get the devices
-            Device[] devices = bridge.getDevices();
-            
-            for (Device device : devices) {
+            IDevice[] devices = bridge.getDevices();
+
+            for (IDevice device : devices) {
                 if (device.getSerialNumber().equals(args[0])) {
                     try {
                         grabLogFrom(device, args[1]);
@@ -126,20 +126,20 @@
                     return;
                 }
             }
-            
+
             System.err.println("Could not find " + args[0]);
         } finally {
             AndroidDebugBridge.terminate();
         }
     }
 
-    private static void grabLogFrom(Device device, String filePath) throws IOException {
+    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/changes.txt b/tools/eclipse/changes.txt
index 02d9075..ecb1f15 100644
--- a/tools/eclipse/changes.txt
+++ b/tools/eclipse/changes.txt
@@ -1,4 +1,15 @@
-0.9.0 (work in progress)
+0.9.2:
+- New wizard to create Android JUnit Test Projects.
+
+
+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.
diff --git a/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml b/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml
index e7cffea..3f8342e 100644
--- a/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml
+++ b/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="com.android.ide.eclipse.adt"
       label="Android Development Tools"
-      version="0.9.0.qualifier"
+      version="0.9.1.qualifier"
       provider-name="The Android Open Source Project"
       plugin="com.android.ide.eclipse.adt">
 
@@ -15,7 +15,7 @@
    </copyright>
 
    <license url="http://www.eclipse.org/org/documents/epl-v10.php">
-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
+      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 EPL.  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
 
@@ -140,6 +140,10 @@
       <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
diff --git a/tools/eclipse/features/com.android.ide.eclipse.ddms/feature.xml b/tools/eclipse/features/com.android.ide.eclipse.ddms/feature.xml
index 00805e4..ae3944b 100644
--- a/tools/eclipse/features/com.android.ide.eclipse.ddms/feature.xml
+++ b/tools/eclipse/features/com.android.ide.eclipse.ddms/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="com.android.ide.eclipse.ddms"
       label="Android DDMS"
-      version="0.9.0.qualifier"
+      version="0.9.1.qualifier"
       provider-name="The Android Open Source Project">
 
    <description>
diff --git a/tools/eclipse/features/com.android.ide.eclipse.tests/feature.xml b/tools/eclipse/features/com.android.ide.eclipse.tests/feature.xml
index 2a3a74f..b88f071 100644
--- a/tools/eclipse/features/com.android.ide.eclipse.tests/feature.xml
+++ b/tools/eclipse/features/com.android.ide.eclipse.tests/feature.xml
@@ -2,7 +2,7 @@
 <feature
       id="com.android.ide.eclipse.tests"
       label="ADT Tests"
-      version="0.9.0.qualifier"
+      version="0.9.1.qualifier"
       provider-name="The Android Open Source Project">
 
    <copyright>
diff --git a/tools/eclipse/plugins/.gitignore b/tools/eclipse/plugins/.gitignore
new file mode 100644
index 0000000..2842bb1
--- /dev/null
+++ b/tools/eclipse/plugins/.gitignore
@@ -0,0 +1,52 @@
+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.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/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/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
+
diff --git a/tools/eclipse/plugins/README.txt b/tools/eclipse/plugins/README.txt
deleted file mode 100644
index 184d731..0000000
--- a/tools/eclipse/plugins/README.txt
+++ /dev/null
@@ -1,114 +0,0 @@
-Compiling and deploying the Android Development Toolkit (ADT) feature.
-
-The ADT feature is composed of four plugins:
-- com.android.ide.eclipse.adt:
-    The ADT plugin, which provides support for compiling and debugging android
-    applications.
-- com.android.ide.eclipse.common:
-    A common plugin providing utility services to the other plugins.
-- com.android.ide.eclipse.editors:
-    A plugin providing optional XML editors.
-- com.android.ide.eclipse.ddms:
-    A plugin version of the tool DDMS
-
-Because the DDMS plugin source code is not yet released, compiling the
-ADT/Common/Editors plugins requires to install the DDMS plugin in eclipse.
-
-Basic requirements:
-- Eclipse 3.3 or 3.4 with JDT and PDE.
-- DDMS plugin installed and running.
-
-
---------------------------
-1- Install the DDMS plugin
---------------------------
-
-The easiest way to setup the DDMS plugin in your Eclipse environment is to
-install the ADT features (see SDK documentation for details) and then remove
-the following features and plugins:
-
-- <eclipse-directory>/features/com.android.ide.eclipse.adt_x.x.x.jar
-- <eclipse-directory>/plugins/com.android.ide.eclipse.adt_x.x.x.jar
-- <eclipse-directory>/plugins/com.android.ide.eclipse.common_x.x.x.jar
-- <eclipse-directory>/plugins/com.android.ide.eclipse.editors_x.x.x.jar
-
-This will leave you with only the DDMS plugin installed in your Eclipse
-distribution.
-
-
--------------------------------------
-2- Setting up the ADT/Common project
--------------------------------------
-
-- Download the ADT/Common/Editors source.
-
-- From the SDK, copy the following jars:
-   * androidprefs.jar    => com.android.ide.eclipse.adt folder.
-   * jarutils.jar        => com.android.ide.eclipse.adt folder.
-   * ping.jar            => com.android.ide.eclipse.common folder.
-   * androidprefs.jar    => com.android.ide.eclipse.common folder.
-
-- Create a java project from existing source for both the ADT plugin and the
-  common plugin.
-
-- In the Package Explorer, right click the projects and choose
-     PDE Tools > Convert Projects to Plug-in Project...
-
-- Select your projects in the dialog box and click OK.
-
-- In the Package Explorer, for ADT and common, right click the jar files mentioned above
-  and choose Build Path > Add to Build Path
-
-At this point the projects will compile.
-
-To launch the projects, open the Run/Debug Dialog and create an "Eclipse
-Application" launch configuration.
-
-Additionnaly, another feature containing the Android Editors Plugin
-(com.android.ide.eclipse.editors) is available.
-
-- Make sure the common project is present in your workspace as the Editors
-  plugin depends on this plugin. Alternatively, you can have the offical ADT
-  feature installed in your Eclipse distribution.
-- Create a java project from existing source for the Editors project.
-- In the Package Explorer, right click the project and choose
-     PDE Tools > Convert Projects to Plug-in Project...
-- Select your project in the dialog box and click OK.
-
-Create an "Eclipse Application" launch configuration to test the plugin.
-
--------------------------------------
-3- Setting up the Editors project
--------------------------------------
-
-The "editors" plugin is optional. You can use ADT to develop Android
-applications without the XML editor support. When this plugin is present, it
-offers several customized form-based XML editors and one graphical layout
-editor.
-
-At the time of this release (Android 0.9 SDK), some of the supporting libraries
-still need some cleanup and are currently only provided as JAR files.
-
-- Download the ADT/Common/Editors source.
-
-- From the source archives, copy the following jars:
-   * ninepatch.jar       => com.android.ide.eclipse.editors folder.
-   * layoutlib_utils.jar => com.android.ide.eclipse.editors folder.
-   * layoutlib_api.jar   => com.android.ide.eclipse.editors folder.
-
-- From http://kxml.sourceforge.net/ download:
-   * kXML2-2.3.0.jar     => com.android.ide.eclipse.editors folder.
-
-- Create a java project from existing source for both the editors plugin.
-
-- In the Package Explorer, right click the project and choose
-     PDE Tools > Convert Projects to Plug-in Project...
-
-- Select your project in the dialog box and click OK.
-
-- In the Package Explorer for editors, right click the jar files mentioned
-  above and choose Build Path > Add to Build Path
-
-To launch the projects, reuse the "Eclipse Application" launch configuration
-created for ADT.
-
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/.classpath b/tools/eclipse/plugins/com.android.ide.eclipse.adt/.classpath
index a24fc87..9898b97 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/.classpath
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/.classpath
@@ -5,7 +5,7 @@
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="lib" path="jarutils.jar"/>
 	<classpathentry kind="lib" path="androidprefs.jar"/>
-	<classpathentry kind="lib" path="sdkstats.jar"/>
+	<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"/>
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
index 8092f3a..09ecc63 100644
--- 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
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Android Development Toolkit
 Bundle-SymbolicName: com.android.ide.eclipse.adt;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.9.1.qualifier
 Bundle-ClassPath: .,
  jarutils.jar,
  androidprefs.jar,
@@ -47,39 +47,35 @@
  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.build;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.launch;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.project;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.project.internal;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.sdk;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.wizards.newproject;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.adt.ui;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.common;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.common.project;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.common.resources;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.descriptors;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.layout;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.layout.descriptors;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.layout.parts;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.layout.uimodel;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.manifest;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.manifest.descriptors;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.manifest.model;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.manifest.pages;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.menu;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.menu.descriptors;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.resources;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.resources.configurations;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.resources.descriptors;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.resources.explorer;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.resources.manager;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.resources.manager.files;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.resources.uimodel;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.ui;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.ui.tree;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.uimodel;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.xml;x-friends:="com.android.ide.eclipse.tests",
- com.android.ide.eclipse.editors.xml.descriptors;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.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.project;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.newproject;x-friends:="com.android.ide.eclipse.tests"
 
 
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
new file mode 100755
index 0000000..7dbbbb6
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/avd_manager.png
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
index 19cd509..dc2c612 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
@@ -47,7 +47,7 @@
          point="org.eclipse.core.resources.builders">
       <builder
             hasNature="true">
-         <run class="com.android.ide.eclipse.adt.build.ResourceManagerBuilder"/>
+         <run class="com.android.ide.eclipse.adt.internal.build.ResourceManagerBuilder"/>
       </builder>
    </extension>
    <extension
@@ -56,7 +56,7 @@
          point="org.eclipse.core.resources.builders">
       <builder
             hasNature="true">
-         <run class="com.android.ide.eclipse.adt.build.PreCompilerBuilder"/>
+         <run class="com.android.ide.eclipse.adt.internal.build.PreCompilerBuilder"/>
       </builder>
    </extension>
    <extension
@@ -65,7 +65,7 @@
          point="org.eclipse.core.resources.builders">
       <builder
             hasNature="true">
-         <run class="com.android.ide.eclipse.adt.build.ApkBuilder"/>
+         <run class="com.android.ide.eclipse.adt.internal.build.ApkBuilder"/>
       </builder>
    </extension>
    <extension
@@ -73,7 +73,7 @@
          name="AndroidNature"
          point="org.eclipse.core.resources.natures">
       <runtime>
-         <run class="com.android.ide.eclipse.adt.project.AndroidNature"/>
+         <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"/>
@@ -87,10 +87,10 @@
       <wizard
             canFinishEarly="false"
             category="com.android.ide.eclipse.wizards.category"
-            class="com.android.ide.eclipse.adt.wizards.newproject.NewProjectWizard"
+            class="com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizard"
             finalPerspective="org.eclipse.jdt.ui.JavaPerspective"
             hasPages="true"
-            icon="icons/android.png"
+            icon="icons/new_adt_project.png"
             id="com.android.ide.eclipse.adt.project.NewProjectWizard"
             name="Android Project"
             preferredPerspectives="org.eclipse.jdt.ui.JavaPerspective"
@@ -98,10 +98,22 @@
       <wizard
             canFinishEarly="false"
             category="com.android.ide.eclipse.wizards.category"
-            class="com.android.ide.eclipse.adt.wizards.newxmlfile.NewXmlFileWizard"
+            class="com.android.ide.eclipse.adt.internal.wizards.newproject.NewTestProjectWizard"
             finalPerspective="org.eclipse.jdt.ui.JavaPerspective"
             hasPages="true"
-            icon="icons/android.png"
+            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"
@@ -111,7 +123,7 @@
    <extension
          point="org.eclipse.debug.core.launchConfigurationTypes">
       <launchConfigurationType
-            delegate="com.android.ide.eclipse.adt.launch.LaunchConfigDelegate"
+            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"
@@ -132,7 +144,7 @@
    <extension
          point="org.eclipse.debug.ui.launchConfigurationTabGroups">
       <launchConfigurationTabGroup
-            class="com.android.ide.eclipse.adt.launch.LaunchConfigTabGroup"
+            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"/>
@@ -141,7 +153,7 @@
          point="org.eclipse.debug.ui.launchShortcuts">
       <shortcut
             category="com.android.ide.eclipse.adt.launch.LaunchConfigType"
-            class="com.android.ide.eclipse.adt.launch.LaunchShortcut"
+            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"
@@ -197,7 +209,7 @@
             </not>
          </visibility>
          <action
-               class="com.android.ide.eclipse.adt.project.ConvertToAndroidAction"
+               class="com.android.ide.eclipse.adt.internal.actions.ConvertToAndroidAction"
                enablesFor="1"
                id="com.android.ide.eclipse.adt.ConvertToAndroidAction"
                label="Convert To Android Project"
@@ -220,26 +232,37 @@
                value="com.android.ide.eclipse.adt.AndroidNature">
          </filter>
          <action
-               class="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileWizardAction"
+               class="com.android.ide.eclipse.adt.internal.wizards.actions.NewXmlFileAction"
                enablesFor="1"
-               id="com.android.ide.eclipse.adt.project.NewXmlFileWizardAction"
+               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">
+               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.project.ExportAction"
+               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.project.ExportWizardAction"
+               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.project.FixProjectAction"
+               class="com.android.ide.eclipse.adt.internal.actions.FixProjectAction"
                enablesFor="1"
                id="com.android.ide.eclipse.adt.project.FixProjectAction"
                label="Fix Project Properties"
@@ -250,29 +273,29 @@
    <extension
          point="org.eclipse.ui.preferencePages">
       <page
-            class="com.android.ide.eclipse.adt.preferences.AndroidPreferencePage"
+            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.preferences.BuildPreferencePage"
+            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.preferences.LaunchPreferencePage"
+            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.common.preferences.UsagePreferencePage"
+            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.preferences.PreferenceInitializer"/>
+      <initializer class="com.android.ide.eclipse.adt.internal.preferences.PreferenceInitializer"/>
    </extension>
    <extension
          id="com.android.ide.eclipse.adt.adtProblem"
@@ -312,11 +335,11 @@
    <extension
          point="org.eclipse.jdt.core.classpathContainerInitializer">
       <classpathContainerInitializer
-            class="com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer"
+            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.project.internal.AndroidClasspathContainerInitializer"
+            class="com.android.ide.eclipse.adt.internal.project.AndroidClasspathContainerInitializer"
             id="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK">
       </classpathContainerInitializer>
    </extension>
@@ -328,7 +351,7 @@
       </category>
       <wizard
             category="com.android.ide.eclipse.wizards.category"
-            class="com.android.ide.eclipse.adt.project.export.ExportWizard"
+            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">
@@ -365,7 +388,7 @@
          point="org.eclipse.ui.decorators">
       <decorator
             adaptable="true"
-            class="com.android.ide.eclipse.adt.project.FolderDecorator"
+            class="com.android.ide.eclipse.adt.internal.project.FolderDecorator"
             id="com.android.ide.eclipse.adt.project.FolderDecorator"
             label="Android Decorator"
             lightweight="true"
@@ -377,7 +400,7 @@
    <extension
          point="org.eclipse.ui.editors">
       <editor
-            class="com.android.ide.eclipse.editors.manifest.ManifestEditor"
+            class="com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor"
             default="true"
             filenames="AndroidManifest.xml"
             icon="icons/android.png"
@@ -385,7 +408,7 @@
             name="Android Manifest Editor">
       </editor>
       <editor
-            class="com.android.ide.eclipse.editors.resources.ResourcesEditor"
+            class="com.android.ide.eclipse.adt.internal.editors.resources.ResourcesEditor"
             default="false"
             extensions="xml"
             icon="icons/android.png"
@@ -393,16 +416,16 @@
             name="Android Resource Editor">
       </editor>
       <editor
-            class="com.android.ide.eclipse.editors.layout.LayoutEditor"
+            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.editors.layout.MatchingStrategy"
+            matchingStrategy="com.android.ide.eclipse.adt.internal.editors.layout.MatchingStrategy"
             name="Android Layout Editor">
       </editor>
       <editor
-            class="com.android.ide.eclipse.editors.menu.MenuEditor"
+            class="com.android.ide.eclipse.adt.internal.editors.menu.MenuEditor"
             default="false"
             extensions="xml"
             icon="icons/android.png"
@@ -410,7 +433,7 @@
             name="Android Menu Editor">
       </editor>
       <editor
-            class="com.android.ide.eclipse.editors.xml.XmlEditor"
+            class="com.android.ide.eclipse.adt.internal.editors.xml.XmlEditor"
             default="false"
             extensions="xml"
             icon="icons/android.png"
@@ -423,7 +446,7 @@
       <view
             allowMultiple="false"
             category="com.android.ide.eclipse.ddms.views.category"
-            class="com.android.ide.eclipse.editors.resources.explorer.ResourceExplorerView"
+            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">
@@ -432,23 +455,23 @@
    <extension
          point="org.eclipse.wst.sse.ui.editorConfiguration">
       <sourceViewerConfiguration
-            class="com.android.ide.eclipse.editors.manifest.ManifestSourceViewerConfig"
+            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.editors.resources.ResourcesSourceViewerConfig"
+            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.editors.layout.LayoutSourceViewerConfig"
+            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.editors.menu.MenuSourceViewerConfig"
+            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.editors.xml.XmlSourceViewerConfig"
+            class="com.android.ide.eclipse.adt.internal.editors.xml.XmlSourceViewerConfig"
             target="com.android.ide.eclipse.editors.xml.XmlEditor">
       </sourceViewerConfiguration>
    </extension>
@@ -456,7 +479,7 @@
          point="org.eclipse.ui.propertyPages">
       <page
             adaptable="true"
-            class="com.android.ide.eclipse.adt.project.properties.AndroidPropertyPage"
+            class="com.android.ide.eclipse.adt.internal.properties.AndroidPropertyPage"
             id="com.android.ide.eclipse.adt.project.properties.AndroidPropertyPage"
             name="Android"
             nameFilter="*"
@@ -475,7 +498,7 @@
             label="Android Wizards"
             visible="true">
          <action
-               class="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction"
+               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"
@@ -484,7 +507,16 @@
                tooltip="Opens a wizard to help create a new Android XML file">
          </action>
          <action
-               class="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"
+               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"
@@ -498,9 +530,9 @@
             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. 
+              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"
@@ -518,14 +550,14 @@
             <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> 
+         <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.refactorings.extractstring.ExtractStringAction"
+               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..."
@@ -538,11 +570,27 @@
                label="Refactor">
          </menu>
       </actionSet>
+      <actionSet
+            description="Android AVD Manager"
+            id="adt.actionSet.avdManager"
+            label="Android 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 AVD Manager"
+               menubarPath="Window/additions"
+               style="push"
+               toolbarPath="android_project"
+               tooltip="Opens the Android Virtual Device (AVD) Manager">
+         </action>
+      </actionSet>
    </extension>
    <extension
          point="org.eclipse.debug.core.launchDelegates">
        <launchDelegate
-             delegate="com.android.ide.eclipse.adt.launch.JUnitLaunchConfigDelegate"
+             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"
@@ -553,7 +601,7 @@
    <extension
          point="org.eclipse.debug.core.launchConfigurationTypes">
       <launchConfigurationType
-            delegate="com.android.ide.eclipse.adt.launch.junit.AndroidJUnitLaunchConfigDelegate"
+            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"
@@ -573,7 +621,7 @@
    <extension
          point="org.eclipse.debug.ui.launchConfigurationTabGroups">
       <launchConfigurationTabGroup
-            class="com.android.ide.eclipse.adt.launch.junit.AndroidJUnitTabGroup"
+            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"/>
@@ -581,7 +629,7 @@
    <extension
          point="org.eclipse.debug.ui.launchShortcuts">
       <shortcut
-            class="com.android.ide.eclipse.adt.launch.junit.AndroidJUnitLaunchShortcut"
+            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"
@@ -622,7 +670,7 @@
    <extension
          point="org.eclipse.ltk.core.refactoring.refactoringContributions">
       <contribution
-            class="com.android.ide.eclipse.adt.refactorings.extractstring.ExtractStringContribution"
+            class="com.android.ide.eclipse.adt.internal.refactorings.extractstring.ExtractStringContribution"
             id="com.android.ide.eclipse.adt.refactoring.extract.string">
       </contribution>
    </extension>
@@ -632,7 +680,7 @@
             properties="isTest,canLaunchAsJUnit"
             namespace="com.android.ide.eclipse.adt"
             type="org.eclipse.core.runtime.IAdaptable"
-            class="com.android.ide.eclipse.adt.launch.junit.AndroidJUnitPropertyTester"
+            class="com.android.ide.eclipse.adt.internal.launch.junit.AndroidJUnitPropertyTester"
             id="com.android.ide.eclipse.adt.AndroidJUnitPropertyTester">
       </propertyTester>
    </extension>
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
index 7304e5e..d3175ce 100644
--- 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
@@ -16,7 +16,7 @@
 
 package com.android.ide.eclipse.adt;
 
-import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer;
+import com.android.ide.eclipse.adt.internal.project.AndroidClasspathContainerInitializer;
 
 
 /**
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
index b5cee81..0ac3bb9 100644
--- 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
@@ -20,37 +20,36 @@
 import com.android.ddmuilib.StackTracePanel.ISourceRevealer;
 import com.android.ddmuilib.console.DdmConsole;
 import com.android.ddmuilib.console.IDdmConsole;
-import com.android.ide.eclipse.adt.launch.AndroidLaunchController;
-import com.android.ide.eclipse.adt.preferences.BuildPreferencePage;
-import com.android.ide.eclipse.adt.project.ProjectHelper;
-import com.android.ide.eclipse.adt.project.export.ExportWizard;
-import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer;
-import com.android.ide.eclipse.adt.sdk.AndroidTargetParser;
-import com.android.ide.eclipse.adt.sdk.LoadStatus;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
-import com.android.ide.eclipse.adt.ui.EclipseUiHelper;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.SdkStatsHelper;
-import com.android.ide.eclipse.common.StreamHelper;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-import com.android.ide.eclipse.common.project.ExportHelper;
-import com.android.ide.eclipse.common.project.ExportHelper.IExportCallback;
+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.ide.eclipse.editors.IconFactory;
-import com.android.ide.eclipse.editors.layout.LayoutEditor;
-import com.android.ide.eclipse.editors.menu.MenuEditor;
-import com.android.ide.eclipse.editors.resources.ResourcesEditor;
-import com.android.ide.eclipse.editors.resources.manager.ProjectResources;
-import com.android.ide.eclipse.editors.resources.manager.ResourceFolder;
-import com.android.ide.eclipse.editors.resources.manager.ResourceFolderType;
-import com.android.ide.eclipse.editors.resources.manager.ResourceManager;
-import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor;
-import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IFileListener;
-import com.android.ide.eclipse.editors.xml.XmlEditor;
 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;
@@ -110,6 +109,7 @@
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Calendar;
 import java.util.List;
 
 /**
@@ -118,7 +118,7 @@
 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$
@@ -132,7 +132,7 @@
     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;
 
@@ -162,7 +162,7 @@
 
     /** 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.
@@ -172,7 +172,7 @@
     /** 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>();
@@ -204,7 +204,7 @@
         @Override
         public void println(String message) {
             // write the date/project tag first.
-            String tag = StreamHelper.getMessageTag(mProject != null ? mProject.getName() : null);
+            String tag = getMessageTag(mProject != null ? mProject.getName() : null);
 
             print(tag);
             if (mPrefix != null) {
@@ -312,7 +312,7 @@
                     // get the SDK location and build id.
                     if (checkSdkLocationAndId()) {
                         // if sdk if valid, reparse it
-                        
+
                         // add all the opened Android projects to the list of projects to be updated
                         // after the SDK is reloaded
                         synchronized (getSdkLockObject()) {
@@ -320,7 +320,7 @@
                             IJavaProject[] androidProjects = BaseProjectHelper.getAndroidProjects();
                             mPostLoadProjectsToResolve.addAll(Arrays.asList(androidProjects));
                         }
-    
+
                         // parse the SDK resources at the new location
                         parseSdkContent();
                     }
@@ -341,7 +341,7 @@
 
         // check the location of SDK
         final boolean isSdkLocationValid = checkSdkLocationAndId();
-        
+
         mBuildVerbosity = BuildPreferencePage.getBuildLevel(
                 mStore.getString(PREFS_BUILD_VERBOSITY));
 
@@ -356,7 +356,7 @@
         // 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 
+                // search for an android project matching the process name
                 IProject project = ProjectHelper.findAndroidProjectByAppName(appName);
                 if (project != null) {
                     AndroidLaunchController.debugRunningApp(project, port);
@@ -366,7 +366,7 @@
                 }
             }
         });
-        
+
         StackTracePanel.setSourceRevealer(new ISourceRevealer() {
             public void reveal(String applicationName, String className, int line) {
                 IProject project = ProjectHelper.findAndroidProjectByAppName(applicationName);
@@ -375,12 +375,12 @@
                 }
             }
         });
-        
+
         // 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(),
@@ -388,7 +388,7 @@
                 dialog.open();
             }
         });
-        
+
         // initialize editors
         startEditors();
 
@@ -400,16 +400,16 @@
            @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); 
+        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*/);
@@ -417,15 +417,15 @@
 
     /*
      * (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;
@@ -525,7 +525,7 @@
         if (sPlugin != null) {
             return sPlugin.mBuildVerbosity;
         }
-        
+
         return 0;
     }
 
@@ -537,7 +537,7 @@
      * @return the image descriptor
      */
     public static ImageDescriptor getImageDescriptor(String path) {
-    	return imageDescriptorFromPlugin(PLUGIN_ID, path);
+        return imageDescriptorFromPlugin(PLUGIN_ID, path);
     }
 
     /**
@@ -555,7 +555,7 @@
                 return null;
             }
         }
-        
+
         // attempt to get a file to one of the template.
         try {
             URL url = bundle.getEntry(AndroidConstants.WS_SEP + filepath);
@@ -683,10 +683,10 @@
         });
         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}.
@@ -704,7 +704,7 @@
      * 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
@@ -715,13 +715,13 @@
         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
@@ -733,7 +733,7 @@
             String message = String.format(format, args);
             Status status = new Status(IStatus.ERROR, PLUGIN_ID, message, exception);
             getDefault().getLog().log(status);
-            StreamHelper.printToStream(sPlugin.mAndroidConsoleErrorStream, tag, message);
+            printToStream(sPlugin.mAndroidConsoleErrorStream, tag, message);
             showAndroidConsole();
         }
     }
@@ -745,8 +745,8 @@
      */
     public static synchronized void printErrorToConsole(String tag, Object... objects) {
         if (sPlugin != null) {
-            StreamHelper.printToStream(sPlugin.mAndroidConsoleErrorStream, tag, objects);
-    
+            printToStream(sPlugin.mAndroidConsoleErrorStream, tag, objects);
+
             showAndroidConsole();
         }
     }
@@ -783,7 +783,7 @@
         if (sPlugin != null) {
             if (level <= sPlugin.mBuildVerbosity) {
                 String tag = project != null ? project.getName() : null;
-                StreamHelper.printToStream(sPlugin.mAndroidConsoleStream, tag, objects);
+                printToStream(sPlugin.mAndroidConsoleStream, tag, objects);
             }
         }
     }
@@ -795,7 +795,7 @@
      */
     public static synchronized void printToConsole(String tag, Object... objects) {
         if (sPlugin != null) {
-            StreamHelper.printToStream(sPlugin.mAndroidConsoleStream, tag, objects);
+            printToStream(sPlugin.mAndroidConsoleStream, tag, objects);
         }
     }
 
@@ -813,7 +813,7 @@
     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());
@@ -832,7 +832,7 @@
         if (sPlugin != null) {
             return new AndroidPrintStream(project, prefix, sPlugin.mAndroidConsoleStream);
         }
-        
+
         return null;
     }
 
@@ -849,10 +849,10 @@
         if (sPlugin != null) {
             return new AndroidPrintStream(project, prefix, sPlugin.mAndroidConsoleErrorStream);
         }
-        
+
         return null;
     }
-    
+
     /**
      * Returns whether the Sdk has been loaded.
      */
@@ -861,7 +861,7 @@
             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.
@@ -869,7 +869,7 @@
     public final Object getSdkLockObject() {
         return mPostLoadProjectsToResolve;
     }
-    
+
     /**
      * Sets the given {@link IJavaProject} to have its target resolved again once the SDK finishes
      * to load.
@@ -879,14 +879,14 @@
             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 
+        // only lock on
         synchronized (getSdkLockObject()) {
             mPostLoadProjectsToCheck.add(javaProject);
         }
@@ -983,14 +983,8 @@
             @Override
             protected IStatus run(IProgressMonitor monitor) {
                 try {
+                    pingUsageServer(); //$NON-NLS-1$
 
-                    // get the version of the plugin
-                    String versionString = (String) getBundle().getHeaders().get(
-                            Constants.BUNDLE_VERSION);
-                    Version version = new Version(versionString);
-                    
-                    SdkStatsHelper.pingUsageServer("adt", version); //$NON-NLS-1$
-                    
                     return Status.OK_STATUS;
                 } catch (Throwable t) {
                     log(t, "pingUsageServer failed"); //$NON-NLS-1$
@@ -1001,7 +995,7 @@
         };
         return job;
     }
-    
+
     /**
      * Parses the SDK resources.
      */
@@ -1018,18 +1012,18 @@
                         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);
-                        
+
                         int n = sdk.getTargets().length;
                         if (n > 0) {
                             int w = 60 / n;
@@ -1050,7 +1044,7 @@
                             mSdkIsLoaded = LoadStatus.LOADED;
 
                             progress.setTaskName("Check Projects");
-                            
+
                             ArrayList<IJavaProject> list = new ArrayList<IJavaProject>();
                             for (IJavaProject javaProject : mPostLoadProjectsToResolve) {
                                 if (javaProject.getProject().isOpen()) {
@@ -1066,24 +1060,24 @@
                             // 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 =
@@ -1115,34 +1109,18 @@
         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();
-        
-        // get the stream to write in the android console.
-        MessageConsole androidConsole = AdtPlugin.getDefault().getAndroidConsole();
-        mAndroidConsoleStream = androidConsole.newMessageStream();
-
-        mAndroidConsoleErrorStream = androidConsole.newMessageStream();
-        mRed = new Color(getDisplay(), 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.
-        getDisplay().asyncExec(new Runnable() {
-            public void run() {
-                mAndroidConsoleErrorStream.setColor(mRed);
-            }
-        });
 
         // Add a resource listener to handle compiled resources.
         IWorkspace ws = ResourcesPlugin.getWorkspace();
@@ -1160,19 +1138,19 @@
 
     /**
      * The <code>AbstractUIPlugin</code> implementation of this <code>Plugin</code>
-     * method saves this plug-in's preference and dialog stores and shuts down 
+     * 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);
@@ -1182,7 +1160,7 @@
 
     /**
      * Returns an Image for the small Android logo.
-     * 
+     *
      * Callers should not dispose it.
      */
     public static Image getAndroidLogo() {
@@ -1191,13 +1169,13 @@
 
     /**
      * Returns an {@link ImageDescriptor} for the small Android logo.
-     * 
+     *
      * Callers should not dispose it.
      */
     public static ImageDescriptor getAndroidLogoDesc() {
         return sAndroidLogoDesc;
     }
-    
+
     /**
      * Returns the ResourceMonitor object.
      */
@@ -1207,23 +1185,23 @@
 
     /**
      * 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) {
@@ -1233,7 +1211,7 @@
                     // 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); 
+                        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().
@@ -1252,7 +1230,7 @@
 
                             ResourceFolder resFolder = resources.getResourceFolder(
                                 (IFolder)file.getParent());
-                        
+
                             if (resFolder != null) {
                                 if (kind == IResourceDelta.ADDED) {
                                     resourceAdded(file, resFolder.getType());
@@ -1320,7 +1298,7 @@
                                 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",
@@ -1332,7 +1310,7 @@
                                             XmlEditor.ID,
                                             true, /* activate */
                                             IWorkbenchPage.MATCH_NONE);
-                                
+
                                     if (newEditor != null) {
                                         page.closeEditor(oldEditor, true /* save */);
                                     }
@@ -1385,8 +1363,60 @@
             }
         });
     }
-    
+
     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$
+    }
+
+    /**
+     * 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
new file mode 100644
index 0000000..4464daa
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AndroidConstants.java
@@ -0,0 +1,220 @@
+/*
+ * 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_ADB = SdkConstants.FN_ADB;
+
+    public final static String FN_EMULATOR = SdkConstants.FN_EMULATOR;
+
+    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
index a638810..33046dc 100644
--- 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
@@ -16,6 +16,10 @@
 
     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;
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/VersionCheck.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/VersionCheck.java
deleted file mode 100644
index 6d85af3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/VersionCheck.java
+++ /dev/null
@@ -1,115 +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.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>
- *
- */
-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/build/ApkBuilder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java
deleted file mode 100644
index 47ea3e7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java
+++ /dev/null
@@ -1,1158 +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.build;
-
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.project.ApkInstallManager;
-import com.android.ide.eclipse.adt.project.ProjectHelper;
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-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 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();
-
-        // Top level check to make sure the build can move forward.
-        abortOnBadSetup(project);
-
-        // get the list of referenced projects.
-        IProject[] 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 extra configs for the project.
-        // The map contains (name, filter) where 'name' is a name to be used in the apk filename,
-        // and filter is the resource filter to be used in the aapt -c parameters to restrict
-        // which resource configurations to package in the apk.
-        Map<String, String> configs = Sdk.getCurrent().getProjectApkConfigs(project);
-
-        // 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 (configs != null) {
-                    Set<Entry<String, String>> entrySet = configs.entrySet();
-                    
-                    for (Entry<String, String> entry : entrySet) {
-                        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 (configs != null) {
-                // if the full apk is present, we check the filtered apk as well
-                Set<Entry<String, String>> entrySet = configs.entrySet();
-                
-                for (Entry<String, String> entry : entrySet) {
-                    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 (configs != null) {
-                Set<Entry<String, String>> entrySet = configs.entrySet();
-                for (Entry<String, String> entry : entrySet) {
-                    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 (configs != null) {
-                        Set<Entry<String, String>> entrySet = configs.entrySet();
-                        for (Entry<String, String> entry : entrySet) {
-                            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 (configs != null) {
-                String resPathFormat = osBinPath + File.separator +
-                        AndroidConstants.FN_RESOURCES_S_AP_;
-
-                Set<Entry<String, String>> entrySet = configs.entrySet();
-                for (Entry<String, String> entry : entrySet) {
-                    // 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!");
-        }
-        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;
-        } 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.
-            if (path.getFileExtension().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) {
-            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);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkDeltaVisitor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkDeltaVisitor.java
deleted file mode 100644
index 5d6793a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.build;
-
-import com.android.ide.eclipse.adt.build.BaseBuilder.BaseDeltaVisitor;
-import com.android.ide.eclipse.common.AndroidConstants;
-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/build/BaseBuilder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/BaseBuilder.java
deleted file mode 100644
index c3d5ba6..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.build;
-
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.project.ProjectHelper;
-import com.android.ide.eclipse.adt.sdk.LoadStatus;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-import com.android.ide.eclipse.common.project.XmlErrorHandler;
-import com.android.ide.eclipse.common.project.XmlErrorHandler.XmlErrorListener;
-
-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 final 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/build/DexWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/DexWrapper.java
deleted file mode 100644
index 65ad4f5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/DexWrapper.java
+++ /dev/null
@@ -1,168 +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.build;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-
-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/build/Messages.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/Messages.java
deleted file mode 100644
index 0100049..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/Messages.java
+++ /dev/null
@@ -1,137 +0,0 @@
-
-package com.android.ide.eclipse.adt.build;
-
-import org.eclipse.osgi.util.NLS;
-
-public class Messages extends NLS {
-    private static final String BUNDLE_NAME = "com.android.ide.eclipse.adt.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/build/PreCompilerBuilder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java
deleted file mode 100644
index df023b8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java
+++ /dev/null
@@ -1,986 +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.build;
-
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.project.FixLaunchConfig;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-import com.android.ide.eclipse.common.project.XmlErrorHandler.BasicXmlErrorListener;
-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.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;
-            int minSdkVersion = AndroidManifestParser.INVALID_MIN_SDK;
-    
-            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.printBuildToConsole(AdtConstants.BUILD_VERBOSE, 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);
-            }
-    
-            // 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 != AndroidManifestParser.INVALID_MIN_SDK &&
-                    minSdkVersion < projectTarget.getApiVersionNumber()) {
-                // check it against the target api level
-                String msg = String.format(
-                        "Manifest min SDK version (%1$d) is lower than project target API level (%2$d)",
-                        minSdkVersion, projectTarget.getApiVersionNumber());
-                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
-                BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
-                        IMarker.SEVERITY_WARNING);
-            }
-
-            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);
-            }
-            
-            // 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.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.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/build/PreCompilerDeltaVisitor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java
deleted file mode 100644
index 0a48299..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.build;
-
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.build.BaseBuilder.BaseDeltaVisitor;
-import com.android.ide.eclipse.adt.build.PreCompilerBuilder.AidlData;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-import com.android.ide.eclipse.common.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 int mMinSdkVersion = AndroidManifestParser.INVALID_MIN_SDK;
-
-    // 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 {@link AndroidManifestParser#INVALID_MIN_SDK} 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 {@link AndroidManifestParser#INVALID_MIN_SDK}.
-     */
-    public int 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/build/ResourceManagerBuilder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ResourceManagerBuilder.java
deleted file mode 100644
index b1f9ec1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.build;
-
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.project.ProjectHelper;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-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/VersionCheck.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/VersionCheck.java
new file mode 100644
index 0000000..6199ef9
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/VersionCheck.java
@@ -0,0 +1,117 @@
+/*
+ * 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
new file mode 100644
index 0000000..cfbc93d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/ConvertToAndroidAction.java
@@ -0,0 +1,154 @@
+/*
+ * 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
new file mode 100644
index 0000000..cb4f7e7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/FixProjectAction.java
@@ -0,0 +1,139 @@
+/*
+ * 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
new file mode 100644
index 0000000..b49ee6e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkBuilder.java
@@ -0,0 +1,1214 @@
+/*
+ * 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 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 extra configs for the project.
+            // The map contains (name, filter) where 'name' is a name to be used in the apk filename,
+            // and filter is the resource filter to be used in the aapt -c parameters to restrict
+            // which resource configurations to package in the apk.
+            Map<String, String> configs = Sdk.getCurrent().getProjectApkConfigs(project);
+
+            // 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 (configs != null) {
+                        Set<Entry<String, String>> entrySet = configs.entrySet();
+
+                        for (Entry<String, String> entry : entrySet) {
+                            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 (configs != null) {
+                    // if the full apk is present, we check the filtered apk as well
+                    Set<Entry<String, String>> entrySet = configs.entrySet();
+
+                    for (Entry<String, String> entry : entrySet) {
+                        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 (configs != null) {
+                    Set<Entry<String, String>> entrySet = configs.entrySet();
+                    for (Entry<String, String> entry : entrySet) {
+                        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 (configs != null) {
+                            Set<Entry<String, String>> entrySet = configs.entrySet();
+                            for (Entry<String, String> entry : entrySet) {
+                                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 (configs != null) {
+                    String resPathFormat = osBinPath + File.separator +
+                            AndroidConstants.FN_RESOURCES_S_AP_;
+
+                    Set<Entry<String, String>> entrySet = configs.entrySet();
+                    for (Entry<String, String> entry : entrySet) {
+                        // 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
new file mode 100644
index 0000000..2cebd91
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ApkDeltaVisitor.java
@@ -0,0 +1,280 @@
+/*
+ * 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
new file mode 100644
index 0000000..1512d4b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/BaseBuilder.java
@@ -0,0 +1,941 @@
+/*
+ * 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
new file mode 100644
index 0000000..c1698da
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/Messages.java
@@ -0,0 +1,137 @@
+
+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
new file mode 100644
index 0000000..711708f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerBuilder.java
@@ -0,0 +1,985 @@
+/*
+ * 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.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.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;
+            int minSdkVersion = AndroidManifestParser.INVALID_MIN_SDK;
+    
+            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);
+            }
+    
+            // 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 != AndroidManifestParser.INVALID_MIN_SDK &&
+                    minSdkVersion < projectTarget.getApiVersionNumber()) {
+                // check it against the target api level
+                String msg = String.format(
+                        "Manifest min SDK version (%1$d) is lower than project target API level (%2$d)",
+                        minSdkVersion, projectTarget.getApiVersionNumber());
+                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
+                BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
+                        IMarker.SEVERITY_WARNING);
+            }
+
+            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);
+            }
+            
+            // 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.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.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
new file mode 100644
index 0000000..38ff480
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/PreCompilerDeltaVisitor.java
@@ -0,0 +1,540 @@
+/*
+ * 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 int mMinSdkVersion = AndroidManifestParser.INVALID_MIN_SDK;
+
+    // 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 {@link AndroidManifestParser#INVALID_MIN_SDK} 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 {@link AndroidManifestParser#INVALID_MIN_SDK}.
+     */
+    public int 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
new file mode 100644
index 0000000..a277e87
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/ResourceManagerBuilder.java
@@ -0,0 +1,214 @@
+/*
+ * 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/build/build_messages.properties b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/build_messages.properties
similarity index 100%
rename from tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/build_messages.properties
rename to tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/build_messages.properties
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
new file mode 100644
index 0000000..725c6a8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidContentAssist.java
@@ -0,0 +1,807 @@
+/*
+ * 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 choice 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 of 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("",
+                            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
new file mode 100644
index 0000000..94d7d48
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidEditor.java
@@ -0,0 +1,828 @@
+/*
+ * 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.
+     *  
+     * @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
new file mode 100644
index 0000000..3b41252
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/AndroidSourceViewerConfig.java
@@ -0,0 +1,116 @@
+/*
+ * 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
new file mode 100644
index 0000000..e48b321
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/FirstElementParser.java
@@ -0,0 +1,164 @@
+/*
+ * 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
new file mode 100644
index 0000000..c57734b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/IconFactory.java
@@ -0,0 +1,255 @@
+/*
+ * 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
new file mode 100644
index 0000000..db8a2f1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/AttributeDescriptor.java
@@ -0,0 +1,104 @@
+/*
+ * 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
new file mode 100644
index 0000000..da03441
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/AttributeDescriptorLabelProvider.java
@@ -0,0 +1,81 @@
+/*
+ * 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
new file mode 100644
index 0000000..14dd432
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/BooleanAttributeDescriptor.java
@@ -0,0 +1,33 @@
+/*
+ * 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
new file mode 100644
index 0000000..aebf60a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/DescriptorsUtils.java
@@ -0,0 +1,845 @@
+/*
+ * 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.getUiRoot(),
+                new Object[] { ui_node.getDescriptor().getXmlLocalName(), null, null, null });
+        if (widget_id != null) {
+            ui_node.setAttributeValue(LayoutConstants.ATTR_ID, "@+id/" + widget_id, //$NON-NLS-1$
+                    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".
+     *  
+     * @param uiNode The UI node that gives the prefix to match.
+     * @return A suitable generated id
+     */
+    public static String getFreeWidgetId(UiElementNode uiNode) {
+        return getFreeWidgetId(uiNode.getUiRoot(),
+                new Object[] { uiNode.getDescriptor().getXmlLocalName(), 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
new file mode 100644
index 0000000..1509d94
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/DocumentDescriptor.java
@@ -0,0 +1,57 @@
+/*
+ * 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
new file mode 100644
index 0000000..9135241
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/ElementDescriptor.java
@@ -0,0 +1,331 @@
+/*
+ * 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
new file mode 100644
index 0000000..4974e6e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/EnumAttributeDescriptor.java
@@ -0,0 +1,41 @@
+/*
+ * 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
new file mode 100644
index 0000000..15a90c7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/FlagAttributeDescriptor.java
@@ -0,0 +1,85 @@
+/*
+ * 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
new file mode 100644
index 0000000..860ed39
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/IDescriptorProvider.java
@@ -0,0 +1,24 @@
+/*
+ * 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
new file mode 100644
index 0000000..bb22e45
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/ListAttributeDescriptor.java
@@ -0,0 +1,71 @@
+/*
+ * 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
new file mode 100644
index 0000000..c6aecd2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/ReferenceAttributeDescriptor.java
@@ -0,0 +1,84 @@
+/*
+ * 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 {
+
+    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;
+    }
+    
+    
+    /**
+     * @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
new file mode 100644
index 0000000..080877b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/SeparatorAttributeDescriptor.java
@@ -0,0 +1,45 @@
+/*
+ * 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
new file mode 100644
index 0000000..37eca88
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/TextAttributeDescriptor.java
@@ -0,0 +1,137 @@
+/*
+ * 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
new file mode 100644
index 0000000..381827d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/TextValueDescriptor.java
@@ -0,0 +1,48 @@
+/*
+ * 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
new file mode 100644
index 0000000..8f6efaf
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/descriptors/XmlnsAttributeDescriptor.java
@@ -0,0 +1,81 @@
+/*
+ * 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/AbstractGraphicalLayoutEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/AbstractGraphicalLayoutEditor.java
new file mode 100644
index 0000000..e8ccdab
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/AbstractGraphicalLayoutEditor.java
@@ -0,0 +1,106 @@
+/*
+ * 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.LayoutReloadMonitor.ILayoutReloadListener;
+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.DefaultEditDomain;
+import org.eclipse.gef.ui.parts.GraphicalEditorWithPalette;
+import org.eclipse.gef.ui.parts.SelectionSynchronizer;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.ui.IWorkbenchPart;
+
+/**
+ * Abstract GraphicalLayoutEditor.
+ */
+/*package*/ abstract class AbstractGraphicalLayoutEditor extends GraphicalEditorWithPalette
+    implements IWorkbenchPart, ILayoutReloadListener {
+
+    /**
+     * 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.
+     * <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();
+    }
+
+    abstract void reloadPalette();
+
+    abstract void recomputeLayout();
+
+    abstract UiDocumentNode getModel();
+
+    abstract LayoutEditor getLayoutEditor();
+
+    abstract Clipboard getClipboard();
+
+}
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
new file mode 100644
index 0000000..a44f1f3
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/BasePullParser.java
@@ -0,0 +1,219 @@
+/*
+ * 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/GraphicalLayoutEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/GraphicalLayoutEditor.java
new file mode 100644
index 0000000..c940b9f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/GraphicalLayoutEditor.java
@@ -0,0 +1,2436 @@
+/*
+ * 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.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.ResourceType;
+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.ScreenDimensionQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
+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.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.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.ide.eclipse.adt.internal.ui.ConfigurationSelector.DensityVerifier;
+import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.DimensionVerifier;
+import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.LanguageRegionVerifier;
+import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.MobileCodeVerifier;
+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.IStyleResourceValue;
+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.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.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.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.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 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.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 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
+ */
+public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor
+        implements ILayoutReloadListener {
+    
+    private final static String THEME_SEPARATOR = "----------"; //$NON-NLS-1$
+
+    /** 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 PaletteRoot mPaletteRoot;
+
+    private Text mCountry;
+    private Text mNetwork;
+    private Combo mLanguage;
+    private Combo mRegion;
+    private Combo mOrientation;
+    private Text mDensity;
+    private Combo mTouch;
+    private Combo mKeyboard;
+    private Combo mTextInput;
+    private Combo mNavigation;
+    private Text mSize1;
+    private Text mSize2;
+    private Combo mThemeCombo;
+    private Button mCreateButton;
+
+    private Label mCountryIcon;
+    private Label mNetworkIcon;
+    private Label mLanguageIcon;
+    private Label mRegionIcon;
+    private Label mOrientationIcon;
+    private Label mDensityIcon;
+    private Label mTouchIcon;
+    private Label mKeyboardIcon;
+    private Label mTextInputIcon;
+    private Label mNavigationIcon;
+    private Label mSizeIcon;
+
+    private Label mCurrentLayoutLabel;
+
+    private Image mWarningImage;
+    private Image mMatchImage;
+    private Image mErrorImage;
+
+    /** The {@link FolderConfiguration} representing the state of the UI controls */
+    private FolderConfiguration mCurrentConfig = new FolderConfiguration();
+    /** 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 int mPlatformThemeCount = 0;
+    private boolean mDisableUpdates = 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;
+            
+            updateUIFromResources();
+
+            mThemeCombo.getParent().layout();
+
+            // 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() {
+            updateUIFromResources();
+            mThemeCombo.getParent().layout();
+        }
+    };
+
+    public GraphicalLayoutEditor(LayoutEditor layoutEditor) {
+        mLayoutEditor = layoutEditor;
+        setEditDomain(new DefaultEditDomain(this));
+        setPartName("Layout");
+
+        IconFactory factory = IconFactory.getInstance();
+        mWarningImage = factory.getIcon("warning"); //$NON-NLS-1$
+        mMatchImage = factory.getIcon("match"); //$NON-NLS-1$
+        mErrorImage = factory.getIcon("error"); //$NON-NLS-1$
+
+        AdtPlugin.getDefault().addTargetListener(mTargetListener);
+    }
+
+    // ------------------------------------
+    // Methods overridden from base classes
+    //------------------------------------
+
+    @Override
+    public void createPartControl(Composite parent) {
+        mParent = parent;
+        GridLayout gl;
+        GridData gd;
+
+        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
+        int cols = 10;
+
+        Composite topParent = new Composite(parent, SWT.NONE);
+        topParent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        topParent.setLayout(gl = new GridLayout(cols, false));
+
+        new Label(topParent, SWT.NONE).setText("MCC");
+        mCountryIcon = createControlComposite(topParent, true /* grab_horizontal */);
+        mCountry = new Text(mCountryIcon.getParent(), SWT.BORDER);
+        mCountry.setLayoutData(new GridData(
+                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
+        mCountry.addVerifyListener(new MobileCodeVerifier());
+        mCountry.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetDefaultSelected(SelectionEvent e) {
+                onCountryCodeChange();
+            }
+        });
+        mCountry.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                onCountryCodeChange();
+            }
+        });
+
+        new Label(topParent, SWT.NONE).setText("MNC");
+        mNetworkIcon = createControlComposite(topParent, true /* grab_horizontal */);
+        mNetwork = new Text(mNetworkIcon.getParent(), SWT.BORDER);
+        mNetwork.setLayoutData(new GridData(
+                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
+        mNetwork.addVerifyListener(new MobileCodeVerifier());
+        mNetwork.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetDefaultSelected(SelectionEvent e) {
+                onNetworkCodeChange();
+            }
+        });
+        mNetwork.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                onNetworkCodeChange();
+            }
+        });
+
+        new Label(topParent, SWT.NONE).setText("Lang");
+        mLanguageIcon = createControlComposite(topParent, true /* grab_horizontal */);
+        mLanguage = new Combo(mLanguageIcon.getParent(), SWT.DROP_DOWN);
+        mLanguage.setLayoutData(new GridData(
+                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_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(topParent, SWT.NONE).setText("Region");
+        mRegionIcon = createControlComposite(topParent, true /* grab_horizontal */);
+        mRegion = new Combo(mRegionIcon.getParent(), SWT.DROP_DOWN);
+        mRegion.setLayoutData(new GridData(
+                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_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(topParent, SWT.NONE).setText("Orient");
+        mOrientationIcon = createControlComposite(topParent, true /* grab_horizontal */);
+        mOrientation = new Combo(mOrientationIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY);
+        ScreenOrientation[] soValues = ScreenOrientation.values();
+        mOrientation.add("(Default)");
+        for (ScreenOrientation value : soValues) {
+            mOrientation.add(value.getDisplayValue());
+        }
+        mOrientation.select(0);
+        mOrientation.setLayoutData(new GridData(
+                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
+        mOrientation.addSelectionListener(new SelectionAdapter() {
+           @Override
+            public void widgetSelected(SelectionEvent e) {
+               onOrientationChange();
+            }
+        });
+
+        new Label(topParent, SWT.NONE).setText("Density");
+        mDensityIcon = createControlComposite(topParent, true /* grab_horizontal */);
+        mDensity = new Text(mDensityIcon.getParent(), SWT.BORDER);
+        mDensity.setLayoutData(new GridData(
+                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
+        mDensity.addVerifyListener(new DensityVerifier());
+        mDensity.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetDefaultSelected(SelectionEvent e) {
+                onDensityChange();
+            }
+        });
+        mDensity.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                onDensityChange();
+            }
+        });
+
+        new Label(topParent, SWT.NONE).setText("Touch");
+        mTouchIcon = createControlComposite(topParent, true /* grab_horizontal */);
+        mTouch = new Combo(mTouchIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY);
+        TouchScreenType[] tstValues = TouchScreenType.values();
+        mTouch.add("(Default)");
+        for (TouchScreenType value : tstValues) {
+            mTouch.add(value.getDisplayValue());
+        }
+        mTouch.select(0);
+        mTouch.setLayoutData(new GridData(
+                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
+        mTouch.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                onTouchChange();
+            }
+        });
+
+        new Label(topParent, SWT.NONE).setText("Keybrd");
+        mKeyboardIcon = createControlComposite(topParent, true /* grab_horizontal */);
+        mKeyboard = new Combo(mKeyboardIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY);
+        KeyboardState[] ksValues = KeyboardState.values();
+        mKeyboard.add("(Default)");
+        for (KeyboardState value : ksValues) {
+            mKeyboard.add(value.getDisplayValue());
+        }
+        mKeyboard.select(0);
+        mKeyboard.setLayoutData(new GridData(
+                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
+        mKeyboard.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                onKeyboardChange();
+            }
+        });
+
+        new Label(topParent, SWT.NONE).setText("Input");
+        mTextInputIcon = createControlComposite(topParent, true /* grab_horizontal */);
+        mTextInput = new Combo(mTextInputIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY);
+        TextInputMethod[] timValues = TextInputMethod.values();
+        mTextInput.add("(Default)");
+        for (TextInputMethod value : timValues) {
+            mTextInput.add(value.getDisplayValue());
+        }
+        mTextInput.select(0);
+        mTextInput.setLayoutData(new GridData(
+                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
+        mTextInput.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                onTextInputChange();
+            }
+        });
+
+        new Label(topParent, SWT.NONE).setText("Nav");
+        mNavigationIcon = createControlComposite(topParent, true /* grab_horizontal */);
+        mNavigation = new Combo(mNavigationIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY);
+        NavigationMethod[] nValues = NavigationMethod.values();
+        mNavigation.add("(Default)");
+        for (NavigationMethod value : nValues) {
+            mNavigation.add(value.getDisplayValue());
+        }
+        mNavigation.select(0);
+        mNavigation.setLayoutData(new GridData(
+                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
+        mNavigation.addSelectionListener(new SelectionAdapter() {
+            @Override
+             public void widgetSelected(SelectionEvent e) {
+                onNavigationChange();
+            } 
+        });
+
+        Composite labelParent = new Composite(topParent, SWT.NONE);
+        labelParent.setLayout(gl = new GridLayout(8, 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;
+
+        new Label(labelParent, SWT.NONE).setText("Size");
+        mSizeIcon = createControlComposite(labelParent, false);
+        Composite sizeParent = new Composite(mSizeIcon.getParent(), SWT.NONE);
+        sizeParent.setLayout(gl = new GridLayout(3, false));
+        gl.marginWidth = gl.marginHeight = 0;
+        gl.horizontalSpacing = 0;
+
+        mSize1 = new Text(sizeParent, SWT.BORDER);
+        mSize1.setLayoutData(gd = new GridData());
+        gd.widthHint = 30;
+        new Label(sizeParent, SWT.NONE).setText("x");
+        mSize2 = new Text(sizeParent, SWT.BORDER);
+        mSize2.setLayoutData(gd = new GridData());
+        gd.widthHint = 30;
+
+        DimensionVerifier verifier = new DimensionVerifier();
+        mSize1.addVerifyListener(verifier);
+        mSize2.addVerifyListener(verifier);
+
+        SelectionListener sl = new SelectionListener() {
+            public void widgetDefaultSelected(SelectionEvent e) {
+                onSizeChange();
+            }
+            public void widgetSelected(SelectionEvent e) {
+                onSizeChange();
+            }
+        };
+
+        mSize1.addSelectionListener(sl);
+        mSize2.addSelectionListener(sl);
+        
+        ModifyListener sizeModifyListener = new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                onSizeChange();
+            }
+        };
+
+        mSize1.addModifyListener(sizeModifyListener);
+        mSize2.addModifyListener(sizeModifyListener);
+
+        // first separator
+        Label separator = new Label(labelParent, SWT.SEPARATOR | SWT.VERTICAL);
+        separator.setLayoutData(gd = new GridData(
+                GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
+        gd.heightHint = 0;
+
+        mThemeCombo = new Combo(labelParent, 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(labelParent, SWT.SEPARATOR | SWT.VERTICAL);
+        separator.setLayoutData(gd = new GridData(
+                GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
+        gd.heightHint = 0;
+
+        mCreateButton = new Button(labelParent, SWT.PUSH | SWT.FLAT);
+        mCreateButton.setText("Create...");
+        mCreateButton.setEnabled(false);
+        mCreateButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                LayoutCreatorDialog dialog = new LayoutCreatorDialog(mCreateButton.getShell(),
+                        mEditedFile.getName(), mCurrentConfig);
+                if (dialog.open() == Dialog.OK) {
+                    final FolderConfiguration config = new FolderConfiguration();
+                    dialog.getConfiguration(config);
+                    
+                    createAlternateLayout(config);
+                }
+            }
+        });
+
+        // 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();
+    }
+
+    /* (non-Javadoc)
+     * Creates the palette root.
+     */
+    @Override
+    protected PaletteRoot getPaletteRoot() {
+        mPaletteRoot = PaletteFactory.createPaletteRoot(mPaletteRoot,
+                mLayoutEditor.getTargetData()); 
+        return mPaletteRoot;
+    }
+
+    @Override
+    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();
+
+            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.
+     */
+    @Override
+    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
+    //--------------
+
+    @Override
+    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.
+     */
+    @Override
+    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
+        mCreateButton.setEnabled(mEditedConfig.equals(mCurrentConfig) == false);
+    }
+    
+    public Rectangle getBounds() {
+        ScreenOrientation orientation = null;
+        if (mOrientation.getSelectionIndex() == 0) {
+            orientation = ScreenOrientation.PORTRAIT;
+        } else {
+            orientation = ScreenOrientation.getByIndex(
+                    mOrientation.getSelectionIndex() - 1);
+        }
+
+        int s1, s2;
+
+        // get the size from the UI controls. If it fails, revert to default values.
+        try {
+            s1 = Integer.parseInt(mSize1.getText().trim());
+        } catch (NumberFormatException e) {
+            s1 = 480;
+        }
+
+        try {
+            s2 = Integer.parseInt(mSize2.getText().trim());
+        } catch (NumberFormatException e) {
+            s2 = 320;
+        }
+
+        // make sure s1 is bigger than s2
+        if (s1 < s2) {
+            int tmp = s1;
+            s1 = s2;
+            s2 = tmp;
+        }
+
+        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);
+        }
+    }
+    
+    /**
+     * 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(mCurrentConfig);
+                }
+                
+                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
+                int themeIndex = mThemeCombo.getSelectionIndex();
+                if (themeIndex != -1) {
+                    String theme = mThemeCombo.getItem(themeIndex);
+
+                    // Render a single object as described by the ViewElementDescriptor.
+                    WidgetPullParser parser = new WidgetPullParser(descriptor);
+                    ILayoutResult result = computeLayout(bridge, parser,
+                            null /* projectKey */,
+                            300 /* width */, 300 /* height */, 160 /*density*/,
+                            160.f /*xdpi*/, 160.f /*ydpi*/, theme,
+                            themeIndex >= mPlatformThemeCount /*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}.
+     */
+    @Override
+    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
+     */
+    @Override
+    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) {
+        mDisableUpdates = true; // we do not want to trigger onXXXChange when setting new values in the widgets.
+
+        mEditedConfig = config;
+        mConfiguredFrameworkRes = mConfiguredProjectRes = null;
+
+        mCountryIcon.setImage(mMatchImage);
+        CountryCodeQualifier countryQualifier = config.getCountryCodeQualifier();
+        if (countryQualifier != null) {
+            mCountry.setText(String.format("%1$d", countryQualifier.getCode()));
+            mCurrentConfig.setCountryCodeQualifier(countryQualifier);
+        } else if (force) {
+            mCountry.setText(""); //$NON-NLS-1$
+            mCurrentConfig.setCountryCodeQualifier(null);
+        } else if (mCountry.getText().length() > 0) {
+            mCountryIcon.setImage(mWarningImage);
+        }
+
+        mNetworkIcon.setImage(mMatchImage);
+        NetworkCodeQualifier networkQualifier = config.getNetworkCodeQualifier();
+        if (networkQualifier != null) {
+            mNetwork.setText(String.format("%1$d", networkQualifier.getCode()));
+            mCurrentConfig.setNetworkCodeQualifier(networkQualifier);
+        } else if (force) {
+            mNetwork.setText(""); //$NON-NLS-1$
+            mCurrentConfig.setNetworkCodeQualifier(null);
+        } else if (mNetwork.getText().length() > 0) {
+            mNetworkIcon.setImage(mWarningImage);
+        }
+
+        mLanguageIcon.setImage(mMatchImage);
+        LanguageQualifier languageQualifier = config.getLanguageQualifier();
+        if (languageQualifier != null) {
+            mLanguage.setText(languageQualifier.getValue());
+            mCurrentConfig.setLanguageQualifier(languageQualifier);
+        } else if (force) {
+            mLanguage.setText(""); //$NON-NLS-1$
+            mCurrentConfig.setLanguageQualifier(null);
+        } else if (mLanguage.getText().length() > 0) {
+            mLanguageIcon.setImage(mWarningImage);
+        }
+
+        mRegionIcon.setImage(mMatchImage);
+        RegionQualifier regionQualifier = config.getRegionQualifier();
+        if (regionQualifier != null) {
+            mRegion.setText(regionQualifier.getValue());
+            mCurrentConfig.setRegionQualifier(regionQualifier);
+        } else if (force) {
+            mRegion.setText(""); //$NON-NLS-1$
+            mCurrentConfig.setRegionQualifier(null);
+        } else if (mRegion.getText().length() > 0) {
+            mRegionIcon.setImage(mWarningImage);
+        }
+
+        mOrientationIcon.setImage(mMatchImage);
+        ScreenOrientationQualifier orientationQualifier = config.getScreenOrientationQualifier();
+        if (orientationQualifier != null) {
+            mOrientation.select(
+                    ScreenOrientation.getIndex(orientationQualifier.getValue()) + 1);
+            mCurrentConfig.setScreenOrientationQualifier(orientationQualifier);
+        } else if (force) {
+            mOrientation.select(0);
+            mCurrentConfig.setScreenOrientationQualifier(null);
+        } else if (mOrientation.getSelectionIndex() != 0) {
+            mOrientationIcon.setImage(mWarningImage);
+        }
+
+        mDensityIcon.setImage(mMatchImage);
+        PixelDensityQualifier densityQualifier = config.getPixelDensityQualifier();
+        if (densityQualifier != null) {
+            mDensity.setText(String.format("%1$d", densityQualifier.getValue()));
+            mCurrentConfig.setPixelDensityQualifier(densityQualifier);
+        } else if (force) {
+            mDensity.setText(""); //$NON-NLS-1$
+            mCurrentConfig.setPixelDensityQualifier(null);
+        } else if (mDensity.getText().length() > 0) {
+            mDensityIcon.setImage(mWarningImage);
+        }
+
+        mTouchIcon.setImage(mMatchImage);
+        TouchScreenQualifier touchQualifier = config.getTouchTypeQualifier();
+        if (touchQualifier != null) {
+            mTouch.select(TouchScreenType.getIndex(touchQualifier.getValue()) + 1);
+            mCurrentConfig.setTouchTypeQualifier(touchQualifier);
+        } else if (force) {
+            mTouch.select(0);
+            mCurrentConfig.setTouchTypeQualifier(null);
+        } else if (mTouch.getSelectionIndex() != 0) {
+            mTouchIcon.setImage(mWarningImage);
+        }
+
+        mKeyboardIcon.setImage(mMatchImage);
+        KeyboardStateQualifier keyboardQualifier = config.getKeyboardStateQualifier();
+        if (keyboardQualifier != null) {
+            mKeyboard.select(KeyboardState.getIndex(keyboardQualifier.getValue()) + 1);
+            mCurrentConfig.setKeyboardStateQualifier(keyboardQualifier);
+        } else if (force) {
+            mKeyboard.select(0);
+            mCurrentConfig.setKeyboardStateQualifier(null);
+        } else if (mKeyboard.getSelectionIndex() != 0) {
+            mKeyboardIcon.setImage(mWarningImage);
+        }
+
+        mTextInputIcon.setImage(mMatchImage);
+        TextInputMethodQualifier inputQualifier = config.getTextInputMethodQualifier();
+        if (inputQualifier != null) {
+            mTextInput.select(TextInputMethod.getIndex(inputQualifier.getValue()) + 1);
+            mCurrentConfig.setTextInputMethodQualifier(inputQualifier);
+        } else if (force) {
+            mTextInput.select(0);
+            mCurrentConfig.setTextInputMethodQualifier(null);
+        } else if (mTextInput.getSelectionIndex() != 0) {
+            mTextInputIcon.setImage(mWarningImage);
+        }
+
+        mNavigationIcon.setImage(mMatchImage);
+        NavigationMethodQualifier navigationQualifiter = config.getNavigationMethodQualifier();
+        if (navigationQualifiter != null) {
+            mNavigation.select(
+                    NavigationMethod.getIndex(navigationQualifiter.getValue()) + 1);
+            mCurrentConfig.setNavigationMethodQualifier(navigationQualifiter);
+        } else if (force) {
+            mNavigation.select(0);
+            mCurrentConfig.setNavigationMethodQualifier(null);
+        } else if (mNavigation.getSelectionIndex() != 0) {
+            mNavigationIcon.setImage(mWarningImage);
+        }
+
+        mSizeIcon.setImage(mMatchImage);
+        ScreenDimensionQualifier sizeQualifier = config.getScreenDimensionQualifier();
+        if (sizeQualifier != null) {
+            mSize1.setText(String.format("%1$d", sizeQualifier.getValue1()));
+            mSize2.setText(String.format("%1$d", sizeQualifier.getValue2()));
+            mCurrentConfig.setScreenDimensionQualifier(sizeQualifier);
+        } else if (force) {
+            mSize1.setText(""); //$NON-NLS-1$
+            mSize2.setText(""); //$NON-NLS-1$
+            mCurrentConfig.setScreenDimensionQualifier(null);
+        } else if (mSize1.getText().length() > 0 && mSize2.getText().length() > 0) {
+            mSizeIcon.setImage(mWarningImage);
+        }
+
+        // update the string showing the folder name
+        String current = config.toDisplayString();
+        mCurrentLayoutLabel.setText(current != null ? current : "(Default)");
+        
+        mDisableUpdates = false;
+    }
+    
+    /**
+     * Displays an error icon in front of all the non-null qualifiers.
+     */
+    void displayConfigError() {
+        mCountryIcon.setImage(mMatchImage);
+        CountryCodeQualifier countryQualifier = mCurrentConfig.getCountryCodeQualifier();
+        if (countryQualifier != null) {
+            mCountryIcon.setImage(mErrorImage);
+        }
+        
+        mNetworkIcon.setImage(mMatchImage);
+        NetworkCodeQualifier networkQualifier = mCurrentConfig.getNetworkCodeQualifier();
+        if (networkQualifier != null) {
+            mNetworkIcon.setImage(mErrorImage);
+        }
+        
+        mLanguageIcon.setImage(mMatchImage);
+        LanguageQualifier languageQualifier = mCurrentConfig.getLanguageQualifier();
+        if (languageQualifier != null) {
+            mLanguageIcon.setImage(mErrorImage);
+        }
+        
+        mRegionIcon.setImage(mMatchImage);
+        RegionQualifier regionQualifier = mCurrentConfig.getRegionQualifier();
+        if (regionQualifier != null) {
+            mRegionIcon.setImage(mErrorImage);
+        }
+        
+        mOrientationIcon.setImage(mMatchImage);
+        ScreenOrientationQualifier orientationQualifier =
+            mCurrentConfig.getScreenOrientationQualifier();
+        if (orientationQualifier != null) {
+            mOrientationIcon.setImage(mErrorImage);
+        }
+        
+        mDensityIcon.setImage(mMatchImage);
+        PixelDensityQualifier densityQualifier = mCurrentConfig.getPixelDensityQualifier();
+        if (densityQualifier != null) {
+            mDensityIcon.setImage(mErrorImage);
+        }
+        
+        mTouchIcon.setImage(mMatchImage);
+        TouchScreenQualifier touchQualifier = mCurrentConfig.getTouchTypeQualifier();
+        if (touchQualifier != null) {
+            mTouchIcon.setImage(mErrorImage);
+        }
+        
+        mKeyboardIcon.setImage(mMatchImage);
+        KeyboardStateQualifier keyboardQualifier = mCurrentConfig.getKeyboardStateQualifier();
+        if (keyboardQualifier != null) {
+            mKeyboardIcon.setImage(mErrorImage);
+        }
+
+        mTextInputIcon.setImage(mMatchImage);
+        TextInputMethodQualifier inputQualifier = mCurrentConfig.getTextInputMethodQualifier();
+        if (inputQualifier != null) {
+            mTextInputIcon.setImage(mErrorImage);
+        }
+        
+        mNavigationIcon.setImage(mMatchImage);
+        NavigationMethodQualifier navigationQualifiter =
+            mCurrentConfig.getNavigationMethodQualifier();
+        if (navigationQualifiter != null) {
+            mNavigationIcon.setImage(mErrorImage);
+        }
+        
+        mSizeIcon.setImage(mMatchImage);
+        ScreenDimensionQualifier sizeQualifier = mCurrentConfig.getScreenDimensionQualifier();
+        if (sizeQualifier != null) {
+            mSizeIcon.setImage(mErrorImage);
+        }
+        
+        // update the string showing the folder name
+        String current = mCurrentConfig.toDisplayString();
+        mCurrentLayoutLabel.setText(current != null ? current : "(Default)");
+    }
+
+    @Override
+    UiDocumentNode getModel() {
+        return mLayoutEditor.getUiRootNode();
+    }
+    
+    @Override
+    void reloadPalette() {
+        PaletteFactory.createPaletteRoot(mPaletteRoot, mLayoutEditor.getTargetData());
+    }
+
+    private void onCountryCodeChange() {
+        // because mCountry triggers onCountryCodeChange at each modification, calling setText()
+        // will trigger notifications, and we don't want that.
+        if (mDisableUpdates == true) {
+            return;
+        }
+
+        // update the current config
+        String value = mCountry.getText();
+
+        // empty string, means no qualifier.
+        if (value.length() == 0) {
+            mCurrentConfig.setCountryCodeQualifier(null);
+        } else {
+            try {
+                CountryCodeQualifier qualifier = CountryCodeQualifier.getQualifier(
+                        CountryCodeQualifier.getFolderSegment(Integer.parseInt(value)));
+                if (qualifier != null) {
+                    mCurrentConfig.setCountryCodeQualifier(qualifier);
+                } else {
+                    // Failure! Looks like the value is wrong (for instance a one letter string).
+                    // We do nothing in this case.
+                    mCountryIcon.setImage(mErrorImage);
+                    return;
+                }
+            } catch (NumberFormatException e) {
+                // Looks like the code is not a number. This should not happen since the text
+                // field has a VerifyListener that prevents it.
+                mCurrentConfig.setCountryCodeQualifier(null);
+                mCountryIcon.setImage(mErrorImage);
+            }
+        }
+
+        // look for a file to open/create
+        onConfigurationChange();
+    }
+
+    private void onNetworkCodeChange() {
+        // because mNetwork triggers onNetworkCodeChange at each modification, calling setText()
+        // will trigger notifications, and we don't want that.
+        if (mDisableUpdates == true) {
+            return;
+        }
+
+        // update the current config
+        String value = mNetwork.getText();
+
+        // empty string, means no qualifier.
+        if (value.length() == 0) {
+            mCurrentConfig.setNetworkCodeQualifier(null);
+        } else {
+            try {
+                NetworkCodeQualifier qualifier = NetworkCodeQualifier.getQualifier(
+                        NetworkCodeQualifier.getFolderSegment(Integer.parseInt(value)));
+                if (qualifier != null) {
+                    mCurrentConfig.setNetworkCodeQualifier(qualifier);
+                } else {
+                    // Failure! Looks like the value is wrong (for instance a one letter string).
+                    // We do nothing in this case.
+                    mNetworkIcon.setImage(mErrorImage);
+                    return;
+                }
+            } catch (NumberFormatException e) {
+                // Looks like the code is not a number. This should not happen since the text
+                // field has a VerifyListener that prevents it.
+                mCurrentConfig.setNetworkCodeQualifier(null);
+                mNetworkIcon.setImage(mErrorImage);
+            }
+        }
+
+        // look for a file to open/create
+        onConfigurationChange();
+    }
+
+    /**
+     * Call back for language combo selection
+     */
+    private void onLanguageChange() {
+        // 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;
+        }
+
+        // update the current config
+        String value = mLanguage.getText();
+
+        updateRegionUi(null /* projectResources */, null /* frameworkResources */);
+
+        // empty string, means no qualifier.
+        if (value.length() == 0) {
+            mCurrentConfig.setLanguageQualifier(null);
+        } else {
+            LanguageQualifier qualifier = null;
+            String segment = LanguageQualifier.getFolderSegment(value);
+            if (segment != null) {
+                qualifier = LanguageQualifier.getQualifier(segment);
+            }
+
+            if (qualifier != null) {
+                mCurrentConfig.setLanguageQualifier(qualifier);
+            } else {
+                // Failure! Looks like the value is wrong (for instance a one letter string).
+                mCurrentConfig.setLanguageQualifier(null);
+                mLanguageIcon.setImage(mErrorImage);
+            }
+        }
+
+        // look for a file to open/create
+        onConfigurationChange();
+    }
+
+    private void onRegionChange() {
+        // because mRegion triggers onRegionChange at each modification, the filling
+        // of the combo with data will trigger notifications, and we don't want that.
+        if (mDisableUpdates == true) {
+            return;
+        }
+
+        // update the current config
+        String value = mRegion.getText();
+
+        // empty string, means no qualifier.
+        if (value.length() == 0) {
+            mCurrentConfig.setRegionQualifier(null);
+        } else {
+            RegionQualifier qualifier = null;
+            String segment = RegionQualifier.getFolderSegment(value);
+            if (segment != null) {
+                qualifier = RegionQualifier.getQualifier(segment);
+            }
+
+            if (qualifier != null) {
+                mCurrentConfig.setRegionQualifier(qualifier);
+            } else {
+                // Failure! Looks like the value is wrong (for instance a one letter string).
+                mCurrentConfig.setRegionQualifier(null);
+                mRegionIcon.setImage(mErrorImage);
+            }
+        }
+
+        // look for a file to open/create
+        onConfigurationChange();
+    }
+
+    private void onOrientationChange() {
+        // update the current config
+        int index = mOrientation.getSelectionIndex();
+        if (index != 0) {
+            mCurrentConfig.setScreenOrientationQualifier(new ScreenOrientationQualifier(
+                ScreenOrientation.getByIndex(index-1)));
+        } else {
+            mCurrentConfig.setScreenOrientationQualifier(null);
+        }
+
+        // look for a file to open/create
+        onConfigurationChange();
+    }
+
+    private void onDensityChange() {
+        // because mDensity triggers onDensityChange at each modification, calling setText()
+        // will trigger notifications, and we don't want that.
+        if (mDisableUpdates == true) {
+            return;
+        }
+
+        // update the current config
+        String value = mDensity.getText();
+
+        // empty string, means no qualifier.
+        if (value.length() == 0) {
+            mCurrentConfig.setPixelDensityQualifier(null);
+        } else {
+            try {
+                PixelDensityQualifier qualifier = PixelDensityQualifier.getQualifier(
+                        PixelDensityQualifier.getFolderSegment(Integer.parseInt(value)));
+                if (qualifier != null) {
+                    mCurrentConfig.setPixelDensityQualifier(qualifier);
+                } else {
+                    // Failure! Looks like the value is wrong (for instance a one letter string).
+                    // We do nothing in this case.
+                    return;
+                }
+            } catch (NumberFormatException e) {
+                // Looks like the code is not a number. This should not happen since the text
+                // field has a VerifyListener that prevents it.
+                // We do nothing in this case.
+                mDensityIcon.setImage(mErrorImage);
+                return;
+            }
+        }
+
+        // look for a file to open/create
+        onConfigurationChange();
+    }
+
+    private void onTouchChange() {
+        // update the current config
+        int index = mTouch.getSelectionIndex();
+        if (index != 0) {
+            mCurrentConfig.setTouchTypeQualifier(new TouchScreenQualifier(
+                TouchScreenType.getByIndex(index-1)));
+        } else {
+            mCurrentConfig.setTouchTypeQualifier(null);
+        }
+
+        // look for a file to open/create
+        onConfigurationChange();
+    }
+
+    private void onKeyboardChange() {
+        // update the current config
+        int index = mKeyboard.getSelectionIndex();
+        if (index != 0) {
+            mCurrentConfig.setKeyboardStateQualifier(new KeyboardStateQualifier(
+                KeyboardState.getByIndex(index-1)));
+        } else {
+            mCurrentConfig.setKeyboardStateQualifier(null);
+        }
+
+        // look for a file to open/create
+        onConfigurationChange();
+    }
+
+    private void onTextInputChange() {
+        // update the current config
+        int index = mTextInput.getSelectionIndex();
+        if (index != 0) {
+            mCurrentConfig.setTextInputMethodQualifier(new TextInputMethodQualifier(
+                TextInputMethod.getByIndex(index-1)));
+        } else {
+            mCurrentConfig.setTextInputMethodQualifier(null);
+        }
+
+        // look for a file to open/create
+        onConfigurationChange();
+    }
+
+    private void onNavigationChange() {
+        // update the current config
+        int index = mNavigation.getSelectionIndex();
+        if (index != 0) {
+            mCurrentConfig.setNavigationMethodQualifier(new NavigationMethodQualifier(
+                NavigationMethod.getByIndex(index-1)));
+        } else {
+            mCurrentConfig.setNavigationMethodQualifier(null);
+        }
+
+        // look for a file to open/create
+        onConfigurationChange();
+    }
+
+    private void onSizeChange() {
+        // because mSize1 and mSize2 trigger onSizeChange at each modification, calling setText()
+        // will trigger notifications, and we don't want that.
+        if (mDisableUpdates == true) {
+            return;
+        }
+
+        // update the current config
+        String size1 = mSize1.getText();
+        String size2 = mSize2.getText();
+
+        // if only one of the strings is empty, do nothing
+        if ((size1.length() == 0) ^ (size2.length() == 0)) {
+            mSizeIcon.setImage(mErrorImage);
+            return;
+        } else if (size1.length() == 0 && size2.length() == 0) {
+            // both sizes are empty: remove the qualifier.
+            mCurrentConfig.setScreenDimensionQualifier(null);
+        } else {
+            ScreenDimensionQualifier qualifier = ScreenDimensionQualifier.getQualifier(size1,
+                    size2);
+
+            if (qualifier != null) {
+                mCurrentConfig.setScreenDimensionQualifier(qualifier);
+            } else {
+                // Failure! Looks like the value is wrong.
+                // we do nothing in this case.
+                return;
+            }
+        }
+
+        // look for a file to open/create
+        onConfigurationChange();
+    }
+
+
+    /**
+     * Looks for a file matching the new {@link FolderConfiguration} and attempts to open it.
+     * <p/>If there is no match, notify the user.
+     */
+    private 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,
+                                              mCurrentConfig);
+        }
+
+        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
+            mCreateButton.setEnabled(mEditedConfig.equals(mCurrentConfig) == false);
+
+            // Even though the layout doesn't change, the config changed, and referenced
+            // resources need to be updated.
+            recomputeLayout();
+        } else {
+            // update the configuration icons with the new edited config.
+            displayConfigError();
+            
+            // enable the Create button
+            mCreateButton.setEnabled(true);
+
+            // display the error.
+            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.",
+                    mCurrentConfig.toDisplayString(),
+                    mCurrentConfig.getFolderName(ResourceFolderType.LAYOUT),
+                    mEditedFile.getName());
+            showErrorInEditor(message);
+        }
+    }
+
+    private void onThemeChange() {
+        int themeIndex = mThemeCombo.getSelectionIndex();
+        if (themeIndex != -1) {
+            String theme = mThemeCombo.getItem(themeIndex);
+            
+            if (theme.equals(THEME_SEPARATOR)) {
+                mThemeCombo.select(0);
+            }
+
+            recomputeLayout();
+        }
+    }
+
+    /**
+     * Creates a composite with no margin/spacing, and puts a {@link Label} in it with the matching
+     * icon.
+     * @param parent the parent to receive the composite
+     * @return the created {@link Label} object.
+     */
+    private Label createControlComposite(Composite parent, boolean grab) {
+        GridLayout gl;
+
+        Composite composite = new Composite(parent, SWT.NONE);
+        composite.setLayout(gl = new GridLayout(2, false));
+        gl.marginHeight = gl.marginWidth = 0;
+        gl.horizontalSpacing = 0;
+        if (grab) {
+            composite.setLayoutData(
+                    new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
+        }
+
+        // create the label
+        Label icon = new Label(composite, SWT.NONE);
+        icon.setImage(mMatchImage);
+
+        return icon;
+    }
+
+    /**
+     * Recomputes the layout with the help of layoutlib.
+     */
+    @Override
+    @SuppressWarnings("deprecation")
+    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.
+                    if (mConfiguredProjectRes == null) {
+                        // make sure they are loaded
+                        projectRes.loadAll();
+    
+                        // get the project resource values based on the current config
+                        mConfiguredProjectRes = projectRes.getConfiguredResources(mCurrentConfig);
+                    }
+    
+                    // get the framework resources
+                    Map<String, Map<String, IResourceValue>> frameworkResources =
+                        getConfiguredFrameworkResources();
+    
+                    if (mConfiguredProjectRes != 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
+                        int themeIndex = mThemeCombo.getSelectionIndex();
+                        if (themeIndex != -1) {
+                            String theme = mThemeCombo.getItem(themeIndex);
+                            
+                            // Compute the layout
+                            UiElementPullParser parser = new UiElementPullParser(getModel());
+                            Rectangle rect = getBounds();
+                            boolean isProjectTheme = themeIndex >= mPlatformThemeCount;
+
+                            // FIXME pass the density/dpi from somewhere (resource config or skin).
+                            ILayoutResult result = computeLayout(bridge, parser,
+                                    iProject /* projectKey */,
+                                    rect.width, rect.height, 160, 160.f, 160.f, 
+                                    theme, isProjectTheme,
+                                    mConfiguredProjectRes, 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.
+     */
+    @Override
+    void activated() {
+        if (mNeedsRecompute || mNeedsXmlReload) {
+            recomputeLayout();
+        }
+    }
+
+    /**
+     * Responds to a page change that made the Graphical editor page the deactivated page
+     */
+    @Override
+    void deactivated() {
+        // nothing to be done here for now.
+    }
+
+    /**
+     * Updates the UI from values in the resources, such as languages, regions, themes, etc...
+     * This must be called from the UI thread.
+     */
+    private void updateUIFromResources() {
+
+        ResourceManager manager = ResourceManager.getInstance();
+
+        ProjectResources frameworkProject = getFrameworkResources();
+
+        mDisableUpdates = true;
+        
+        // Reset stuff
+        int selection = mThemeCombo.getSelectionIndex();
+        mThemeCombo.removeAll();
+        mPlatformThemeCount = 0;
+        mLanguage.removeAll();
+        
+        Set<String> languages = new HashSet<String>();
+        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 =
+                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 languages from the framework.
+            Set<String> frameworkLanguages = frameworkProject.getLanguages();
+            if (frameworkLanguages != null) {
+                languages.addAll(frameworkLanguages);
+            }
+        }
+        
+        // now get the themes and languages from the project.
+        ProjectResources project = null;
+        if (mEditedFile != null) {
+            project = manager.getProjectResources(mEditedFile.getProject());
+
+            // 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 
+                if (mConfiguredProjectRes == null) {
+                    // make sure they are loaded
+                    project.loadAll();
+
+                    // get the project resource values based on the current config
+                    mConfiguredProjectRes = project.getConfiguredResources(mCurrentConfig);
+                }
+                
+                if (mConfiguredProjectRes != null) {
+                    // get the styles.
+                    Map<String, IResourceValue> styleMap = mConfiguredProjectRes.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.
+                Set<String> projectLanguages = project.getLanguages();
+                if (projectLanguages != null) {
+                    languages.addAll(projectLanguages);
+                }
+            }
+        }
+
+        // add the languages to the Combo
+        for (String language : languages) {
+            mLanguage.add(language);
+        }
+        
+        mDisableUpdates = false;
+
+        // and update the Region UI based on the current language
+        updateRegionUi(project, frameworkProject);
+
+        // 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);
+        }
+    }
+
+    /**
+     * 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 (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;
+    }
+
+    /**
+     * Update the Region UI widget based on the current language selection
+     * @param projectResources the project resources or {@code null}.
+     * @param frameworkResources the framework resource or {@code null}
+     */
+    private void updateRegionUi(ProjectResources projectResources,
+            ProjectResources frameworkResources) {
+        if (projectResources == null && mEditedFile != null) {
+            projectResources = ResourceManager.getInstance().getProjectResources(
+                    mEditedFile.getProject());
+        }
+
+        if (frameworkResources == null) {
+            frameworkResources = getFrameworkResources();
+        }
+
+        String currentLanguage = mLanguage.getText();
+
+        Set<String> set = null;
+
+        if (projectResources != null) {
+            set = projectResources.getRegions(currentLanguage);
+        }
+
+        if (frameworkResources != null) {
+            if (set != null) {
+                Set<String> set2 = frameworkResources.getRegions(currentLanguage);
+                set.addAll(set2);
+            } else {
+                set = frameworkResources.getRegions(currentLanguage);
+            }
+        }
+
+        if (set != null) {
+            mDisableUpdates = true;
+
+            mRegion.removeAll();
+            for (String region : set) {
+                mRegion.add(region);
+            }
+
+            mDisableUpdates = false;
+        }
+    }
+    
+    private 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");
+            }
+
+            // get the framework resource values based on the current config
+            mConfiguredFrameworkRes = frameworkRes.getConfiguredResources(mCurrentConfig);
+        }
+        
+        return mConfiguredFrameworkRes;
+    }
+
+    /**
+     * Creates a new layout file from the specificed {@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);
+                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() {
+                            mCurrentConfig.set(config);
+                            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();
+    }
+    
+    /**
+     * Returns a {@link ProjectResources} for the framework resources.
+     * @return the framework resources or null if not found.
+     */
+    private 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;
+    }
+    
+    /**
+     * Computes a layout by calling the correct computeLayout method of ILayoutBridge based on
+     * the implementation API level.
+     */
+    @SuppressWarnings("deprecation")
+    private ILayoutResult computeLayout(LayoutBridge bridge,
+            IXmlPullParser layoutDescription, Object projectKey,
+            int screenWidth, int screenHeight, 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 >= 3) {
+            // newer api with boolean for separation of project/framework theme,
+            // and 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,
+                    mConfiguredProjectRes, frameworkResources, mProjectCallback,
+                    mLogger);
+        } 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,
+                    mConfiguredProjectRes, frameworkResources, mProjectCallback,
+                    mLogger);
+        }
+    }
+}
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
new file mode 100644
index 0000000..b36c985
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutConstants.java
@@ -0,0 +1,65 @@
+/*
+ * 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
new file mode 100644
index 0000000..4b313f6
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutContentAssist.java
@@ -0,0 +1,33 @@
+/*
+ * 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/LayoutCreatorDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutCreatorDialog.java
new file mode 100644
index 0000000..5cd527c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutCreatorDialog.java
@@ -0,0 +1,140 @@
+/*
+ * 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.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 org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TrayDialog;
+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.Label;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Dialog to choose a non existing {@link FolderConfiguration}.
+ */
+class LayoutCreatorDialog extends TrayDialog {
+
+    private ConfigurationSelector mSelector;
+    private Composite mStatusComposite;
+    private Label mStatusLabel; 
+    private Label mStatusImage;
+
+    private final FolderConfiguration mConfig = new FolderConfiguration();
+    private final String mFileName;
+
+    /**
+     * Creates a dialog, and init the UI from a {@link FolderConfiguration}.
+     * @param parentShell the parent {@link Shell}.
+     * @param config The starting configuration.
+     */
+    LayoutCreatorDialog(Shell parentShell, String fileName, FolderConfiguration config) {
+        super(parentShell);
+
+        mFileName = fileName;        
+        // FIXME: add some data to know what configurations already exist. 
+        mConfig.set(config);
+    }
+
+    @Override
+    protected Control createDialogArea(Composite parent) {
+        Composite top = new Composite(parent, SWT.NONE);
+        top.setLayoutData(new GridData());
+        top.setLayout(new GridLayout(1, false));
+
+        new Label(top, SWT.NONE).setText(
+                String.format("Configuration for the alternate version of %1$s", mFileName));
+        
+        mSelector = new ConfigurationSelector(top);
+        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(top, 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();
+
+        return top;
+    }
+    
+    public void getConfiguration(FolderConfiguration config) {
+        config.set(mConfig);
+    }
+    
+    /**
+     * resets the status label to show the file that will be created.
+     */
+    private void resetStatus() {
+        mStatusLabel.setText(String.format("New File: res/%1$s/%2$s",
+                mConfig.getFolderName(ResourceFolderType.LAYOUT), mFileName));
+    }
+}
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
new file mode 100644
index 0000000..6226b7b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutEditor.java
@@ -0,0 +1,419 @@
+/*
+ * 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 AbstractGraphicalLayoutEditor 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) {
+                if (mGraphicalEditor == null) {
+                    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) {
+                mOutline = new UiContentOutlinePage(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.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
new file mode 100644
index 0000000..d9e81f5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutReloadMonitor.java
@@ -0,0 +1,214 @@
+/*
+ * 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.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}.
+     * @param project
+     * @param listener
+     */
+    public void removeListener(IProject project, ILayoutReloadListener listener) {
+        synchronized (mListenerMap) {
+            List<ILayoutReloadListener> list = mListenerMap.get(project);
+            if (list != null) {
+                list.remove(listener);
+            }
+        }
+    }
+
+    /*
+     * (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
new file mode 100644
index 0000000..bf9f97f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/LayoutSourceViewerConfig.java
@@ -0,0 +1,30 @@
+/*
+ * 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
new file mode 100644
index 0000000..a6a19a6
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/MatchingStrategy.java
@@ -0,0 +1,64 @@
+/*
+ * 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/PaletteFactory.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/PaletteFactory.java
new file mode 100644
index 0000000..950be13
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/PaletteFactory.java
@@ -0,0 +1,93 @@
+/*
+ * 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}.
+ */
+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
new file mode 100644
index 0000000..742e3d7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/ProjectCallback.java
@@ -0,0 +1,166 @@
+/*
+ * 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
new file mode 100644
index 0000000..62abd5f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiContentOutlinePage.java
@@ -0,0 +1,615 @@
+/*
+ * 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}.
+ */
+class UiContentOutlinePage extends ContentOutlinePage {
+
+    private AbstractGraphicalLayoutEditor mEditor;
+    
+    private Action mAddAction;
+    private Action mDeleteAction;
+    private Action mUpAction;
+    private Action mDownAction;
+    
+    private UiOutlineActions mUiActions = new UiOutlineActions();
+
+    public UiContentOutlinePage(AbstractGraphicalLayoutEditor 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 GraphicalLayoutEditor}.
+     * <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
new file mode 100644
index 0000000..3443272
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiElementPullParser.java
@@ -0,0 +1,244 @@
+/*
+ * 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
new file mode 100644
index 0000000..33d2ed4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/UiPropertySheetPage.java
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+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
new file mode 100644
index 0000000..50d259f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/WidgetPullParser.java
@@ -0,0 +1,143 @@
+/*
+ * 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/descriptors/CustomViewDescriptorService.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java
new file mode 100644
index 0000000..b765abd
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/CustomViewDescriptorService.java
@@ -0,0 +1,284 @@
+/*
+ * 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
new file mode 100644
index 0000000..b855587
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/LayoutDescriptors.java
@@ -0,0 +1,324 @@
+/*
+ * 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
new file mode 100644
index 0000000..1ae9231
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/descriptors/ViewElementDescriptor.java
@@ -0,0 +1,139 @@
+/*
+ * 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
new file mode 100644
index 0000000..327b53c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/DropFeedback.java
@@ -0,0 +1,763 @@
+/*
+ * 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.
+ */
+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
new file mode 100644
index 0000000..0795b90
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/ElementCreateCommand.java
@@ -0,0 +1,98 @@
+/*
+ * 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.
+ */
+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
new file mode 100644
index 0000000..2d82058
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/ElementFigure.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+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
new file mode 100644
index 0000000..4e5527f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/LayoutFigure.java
@@ -0,0 +1,151 @@
+/*
+ * 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.
+ */
+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
new file mode 100644
index 0000000..d12856c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiDocumentEditPart.java
@@ -0,0 +1,212 @@
+/*
+ * 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. 
+ */
+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
new file mode 100644
index 0000000..57db255
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiDocumentTreeEditPart.java
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+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
new file mode 100644
index 0000000..94590c5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementEditPart.java
@@ -0,0 +1,345 @@
+/*
+ * 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}.
+ */
+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
new file mode 100644
index 0000000..459919a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementTreeEditPart.java
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+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
new file mode 100644
index 0000000..4c9eeb8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementTreeEditPartFactory.java
@@ -0,0 +1,47 @@
+/*
+ * 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. 
+ */
+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
new file mode 100644
index 0000000..8fe4702
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiElementsEditPartFactory.java
@@ -0,0 +1,55 @@
+/*
+ * 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}.
+ */
+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
new file mode 100644
index 0000000..2fe0a59
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiLayoutEditPart.java
@@ -0,0 +1,115 @@
+/*
+ * 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. 
+ */
+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
new file mode 100644
index 0000000..09fdc86
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiLayoutTreeEditPart.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+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
new file mode 100644
index 0000000..e8a1b83
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiViewEditPart.java
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+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
new file mode 100644
index 0000000..b505ec0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/parts/UiViewTreeEditPart.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+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
new file mode 100644
index 0000000..0d3f339
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/uimodel/UiViewElementNode.java
@@ -0,0 +1,130 @@
+/*
+ * 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
new file mode 100644
index 0000000..349048f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestContentAssist.java
@@ -0,0 +1,33 @@
+/*
+ * 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
new file mode 100644
index 0000000..2a26a92
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditor.java
@@ -0,0 +1,388 @@
+/*
+ * 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.project.AndroidXPathFactory;
+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 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
new file mode 100644
index 0000000..8beca30
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestEditorContributor.java
@@ -0,0 +1,100 @@
+/*
+ * 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
new file mode 100644
index 0000000..04f75eb
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/ManifestSourceViewerConfig.java
@@ -0,0 +1,30 @@
+/*
+ * 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
new file mode 100644
index 0000000..2667871
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/AndroidManifestDescriptors.java
@@ -0,0 +1,578 @@
+/*
+ * 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
new file mode 100644
index 0000000..5dfc684
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ApplicationAttributeDescriptor.java
@@ -0,0 +1,45 @@
+/*
+ * 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
new file mode 100644
index 0000000..1137dcf
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ClassAttributeDescriptor.java
@@ -0,0 +1,101 @@
+/*
+ * 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
new file mode 100644
index 0000000..7c02850
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ManifestElementDescriptor.java
@@ -0,0 +1,96 @@
+/*
+ * 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
new file mode 100755
index 0000000..2ed86bb1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ManifestPkgAttrDescriptor.java
@@ -0,0 +1,41 @@
+/*
+ * 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
new file mode 100644
index 0000000..2de32e5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PackageAttributeDescriptor.java
@@ -0,0 +1,41 @@
+/*
+ * 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
new file mode 100644
index 0000000..e10e0e7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostActivityCreationAction.java
@@ -0,0 +1,88 @@
+/*
+ * 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
new file mode 100644
index 0000000..d16a7d6
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/PostReceiverCreationAction.java
@@ -0,0 +1,88 @@
+/*
+ * 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
new file mode 100644
index 0000000..4241f14
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/descriptors/ThemeAttributeDescriptor.java
@@ -0,0 +1,42 @@
+/*
+ * 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
new file mode 100644
index 0000000..3119b70
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiClassAttributeNode.java
@@ -0,0 +1,689 @@
+/*
+ * 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.AndroidManifestParser;
+import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
+
+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 = AndroidManifestParser.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
new file mode 100644
index 0000000..62b6d9d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestElementNode.java
@@ -0,0 +1,92 @@
+/*
+ * 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.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() {
+        if (getXmlNode() != null &&
+                getXmlNode() instanceof Element &&
+                getXmlNode().hasAttributes()) {
+
+            AndroidManifestDescriptors manifestDescriptors =
+                    getAndroidTarget().getManifestDescriptors();
+            
+            // 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
new file mode 100755
index 0000000..5687ece
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiManifestPkgAttrNode.java
@@ -0,0 +1,338 @@
+/*
+ * 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
new file mode 100644
index 0000000..d345d32
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiPackageAttributeNode.java
@@ -0,0 +1,319 @@
+/*
+ * 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
new file mode 100644
index 0000000..c9f82dd
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationAttributesPart.java
@@ -0,0 +1,174 @@
+/*
+ * 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
new file mode 100644
index 0000000..3862a1e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationPage.java
@@ -0,0 +1,126 @@
+/*
+ * 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
new file mode 100644
index 0000000..76a0442
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/ApplicationToggle.java
@@ -0,0 +1,313 @@
+/*
+ * 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
new file mode 100644
index 0000000..41063d5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/InstrumentationPage.java
@@ -0,0 +1,92 @@
+/*
+ * 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
new file mode 100644
index 0000000..ec947c5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewExportPart.java
@@ -0,0 +1,87 @@
+/*
+ * 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
new file mode 100644
index 0000000..98f2f9c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewInfoPart.java
@@ -0,0 +1,87 @@
+/*
+ * 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
new file mode 100644
index 0000000..daf0885
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewLinksPart.java
@@ -0,0 +1,125 @@
+/*
+ * 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
new file mode 100644
index 0000000..24b8014
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/OverviewPage.java
@@ -0,0 +1,157 @@
+/*
+ * 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
new file mode 100644
index 0000000..8f3e7ff
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/manifest/pages/PermissionPage.java
@@ -0,0 +1,101 @@
+/*
+ * 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
new file mode 100644
index 0000000..59068e9
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuContentAssist.java
@@ -0,0 +1,33 @@
+/*
+ * 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
new file mode 100644
index 0000000..11cd1c6
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuEditor.java
@@ -0,0 +1,184 @@
+/*
+ * 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.project.AndroidXPathFactory;
+import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
+
+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
new file mode 100644
index 0000000..a2489a9
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuSourceViewerConfig.java
@@ -0,0 +1,30 @@
+/*
+ * 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
new file mode 100644
index 0000000..c324802
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/MenuTreePage.java
@@ -0,0 +1,62 @@
+/*
+ * 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
new file mode 100644
index 0000000..a4763f7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/menu/descriptors/MenuDescriptors.java
@@ -0,0 +1,196 @@
+/*
+ * 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
new file mode 100644
index 0000000..d8b497f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesContentAssist.java
@@ -0,0 +1,33 @@
+/*
+ * 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
new file mode 100644
index 0000000..221fdff
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesEditor.java
@@ -0,0 +1,164 @@
+/*
+ * 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.ide.eclipse.adt.internal.project.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
new file mode 100644
index 0000000..a0294b1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesSourceViewerConfig.java
@@ -0,0 +1,30 @@
+/*
+ * 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
new file mode 100644
index 0000000..eac593a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/ResourcesTreePage.java
@@ -0,0 +1,85 @@
+/*
+ * 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
new file mode 100644
index 0000000..d9be9ca
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ColorValueDescriptor.java
@@ -0,0 +1,41 @@
+/*
+ * 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
new file mode 100644
index 0000000..143bf8f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ItemElementDescriptor.java
@@ -0,0 +1,55 @@
+/*
+ * 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
new file mode 100644
index 0000000..8fa8a94
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/descriptors/ResourcesDescriptors.java
@@ -0,0 +1,283 @@
+/*
+ * 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
new file mode 100644
index 0000000..e788e0b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/uimodel/UiColorValueNode.java
@@ -0,0 +1,80 @@
+/*
+ * 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
new file mode 100644
index 0000000..1bb0f58
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/resources/uimodel/UiItemElementNode.java
@@ -0,0 +1,58 @@
+/*
+ * 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
new file mode 100644
index 0000000..0a600f7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/EditableDialogCellEditor.java
@@ -0,0 +1,458 @@
+/*
+ * 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
new file mode 100644
index 0000000..a70cf90
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/ErrorImageComposite.java
@@ -0,0 +1,47 @@
+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
new file mode 100644
index 0000000..2a1bc36
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/FlagValueCellEditor.java
@@ -0,0 +1,58 @@
+/*
+ * 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
new file mode 100644
index 0000000..0c780a8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/ListValueCellEditor.java
@@ -0,0 +1,76 @@
+/*
+ * 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
new file mode 100644
index 0000000..8efe294
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/ResourceValueCellEditor.java
@@ -0,0 +1,59 @@
+/*
+ * 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
new file mode 100644
index 0000000..69c21e6
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/SectionHelper.java
@@ -0,0 +1,348 @@
+/*
+ * 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
new file mode 100644
index 0000000..3750c34
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/TextValueCellEditor.java
@@ -0,0 +1,43 @@
+/*
+ * 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
new file mode 100644
index 0000000..1ad9525
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/UiElementPart.java
@@ -0,0 +1,283 @@
+/*
+ * 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
new file mode 100644
index 0000000..e04256c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/CopyCutAction.java
@@ -0,0 +1,220 @@
+/*
+ * 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
new file mode 100644
index 0000000..067d145
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/ICommitXml.java
@@ -0,0 +1,28 @@
+/*
+ * 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
new file mode 100644
index 0000000..6fdb7aa
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/NewItemSelectionDialog.java
@@ -0,0 +1,402 @@
+/*
+ * 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
new file mode 100644
index 0000000..4de52c4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/PasteAction.java
@@ -0,0 +1,124 @@
+/*
+ * 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
new file mode 100644
index 0000000..da6db1a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiActions.java
@@ -0,0 +1,385 @@
+/*
+ * 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
new file mode 100644
index 0000000..a8c3870
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiElementDetail.java
@@ -0,0 +1,486 @@
+/*
+ * 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
new file mode 100644
index 0000000..71ef9c0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiModelTreeContentProvider.java
@@ -0,0 +1,114 @@
+/*
+ * 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
new file mode 100644
index 0000000..46b0a6b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiModelTreeLabelProvider.java
@@ -0,0 +1,100 @@
+/*
+ * 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
new file mode 100644
index 0000000..a0546c1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/ui/tree/UiTreeBlock.java
@@ -0,0 +1,894 @@
+/*
+ * 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.
+        Action action;
+        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
new file mode 100644
index 0000000..dd908ad
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/IUiSettableAttributeNode.java
@@ -0,0 +1,32 @@
+/*
+ * 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
new file mode 100644
index 0000000..a4f1f74
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/IUiUpdateListener.java
@@ -0,0 +1,47 @@
+/*
+ * 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
new file mode 100644
index 0000000..8910839
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiAbstractTextAttributeNode.java
@@ -0,0 +1,119 @@
+/*
+ * 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
new file mode 100644
index 0000000..596cfe3
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiAttributeNode.java
@@ -0,0 +1,159 @@
+/*
+ * 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
new file mode 100644
index 0000000..beac5e1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiDocumentNode.java
@@ -0,0 +1,135 @@
+/*
+ * 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
new file mode 100644
index 0000000..0ff4dfc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiElementNode.java
@@ -0,0 +1,1500 @@
+/*
+ * 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.
+     * 
+     * @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);
+        invokeUiUpdateListeners(UiUpdateState.DELETED);
+        if (ui_node.getDescriptor().isMandatory()) {
+            // We can't remove a mandatory node, we just clear its content.
+
+            // A mandatory node with no XML means it doesn't really exist, so it can't be
+            // deleted.
+            boolean xml_exists = (ui_node.getXmlNode() != null); 
+
+            ui_node.clearContent();
+            return xml_exists;
+        } else {
+            mUiChildren.remove(ui_index);
+            return true;
+        }
+    }
+
+    /**
+     * 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 updates 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.
+     */
+    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
new file mode 100644
index 0000000..eb9903f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiFlagAttributeNode.java
@@ -0,0 +1,310 @@
+/*
+ * 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
new file mode 100644
index 0000000..3354b76
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiListAttributeNode.java
@@ -0,0 +1,202 @@
+/*
+ * 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
new file mode 100644
index 0000000..be2384c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiResourceAttributeNode.java
@@ -0,0 +1,275 @@
+/*
+ * 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
new file mode 100644
index 0000000..3d20062
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiSeparatorAttributeNode.java
@@ -0,0 +1,146 @@
+/*
+ * 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
new file mode 100644
index 0000000..40496ab
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiTextAttributeNode.java
@@ -0,0 +1,194 @@
+/*
+ * 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
new file mode 100644
index 0000000..33fa9fc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/uimodel/UiTextValueNode.java
@@ -0,0 +1,118 @@
+/*
+ * 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
new file mode 100644
index 0000000..cd0b259
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlContentAssist.java
@@ -0,0 +1,33 @@
+/*
+ * 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
new file mode 100644
index 0000000..0129048
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlEditor.java
@@ -0,0 +1,202 @@
+/*
+ * 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) {
+            AndroidTargetData data = Sdk.getCurrent().getTargetData(target);
+        
+            FirstElementParser.Result result = FirstElementParser.parse(
+                    file.getLocation().toOSString(),
+                    SdkConstants.NS_RESOURCES);
+            
+            if (result != 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
new file mode 100644
index 0000000..62f43ef
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlSourceViewerConfig.java
@@ -0,0 +1,30 @@
+/*
+ * 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
new file mode 100644
index 0000000..14b4662
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/XmlTreePage.java
@@ -0,0 +1,62 @@
+/*
+ * 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
new file mode 100644
index 0000000..d393bee
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/xml/descriptors/XmlDescriptors.java
@@ -0,0 +1,364 @@
+/*
+ * 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
new file mode 100644
index 0000000..c79a25b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AMReceiver.java
@@ -0,0 +1,160 @@
+/*
+ * 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
new file mode 100644
index 0000000..09f01ec
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/ActivityLaunchAction.java
@@ -0,0 +1,97 @@
+/*
+ * 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
new file mode 100644
index 0000000..8e2c133
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunch.java
@@ -0,0 +1,57 @@
+/*
+ * 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
new file mode 100644
index 0000000..2b02c59
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchConfiguration.java
@@ -0,0 +1,159 @@
+/*
+ * 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
new file mode 100644
index 0000000..5992fab
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/AndroidLaunchController.java
@@ -0,0 +1,1688 @@
+/*
+ * 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.MultiLineReceiver;
+import com.android.ddmlib.SyncService;
+import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
+import com.android.ddmlib.AndroidDebugBridge.IDebugBridgeChangeListener;
+import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
+import com.android.ddmlib.SyncService.SyncResult;
+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.IAndroidTarget;
+import com.android.sdklib.SdkManager;
+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;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 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();
+
+
+
+    /**
+     * 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 mSuccess = null;
+
+        public InstallReceiver() {
+        }
+
+        @Override
+        public void processNewLines(String[] lines) {
+            for (String line : lines) {
+                if (line.length() > 0) {
+                    if (line.startsWith(SUCCESS_OUTPUT)) {
+                        mSuccess = null;
+                    } else {
+                        Matcher m = FAILURE_PATTERN.matcher(line);
+                        if (m.matches()) {
+                            mSuccess = m.group(1);
+                        }
+                    }
+                }
+            }
+        }
+
+        public boolean isCancelled() {
+            return false;
+        }
+
+        public String getSuccess() {
+            return mSuccess;
+        }
+    }
+
+
+    /** 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
+     * {@link AndroidManifestParser#INVALID_MIN_SDK} 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, int 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();
+        } 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
+                        String apiString = d.getProperty(SdkManager.PROP_VERSION_SDK);
+                        try {
+                            int apiNumber = Integer.parseInt(apiString);
+                            if (apiNumber >= projectTarget.getApiVersionNumber()) {
+                                // device is compatible with project
+                                compatibleRunningAvds.put(d, null);
+                                continue;
+                            }
+                        } catch (NumberFormatException e) {
+                            // do nothing, we'll consider it a non compatible device below.
+                        }
+                    }
+                    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())) {
+                if (defaultAvd == null ||
+                        avd.getTarget().getApiVersionNumber() <
+                            defaultAvd.getTarget().getApiVersionNumber()) {
+                    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 deviceApiVersionName = device.getProperty(IDevice.PROP_BUILD_VERSION);
+            String value = device.getProperty(IDevice.PROP_BUILD_VERSION_NUMBER);
+            int deviceApiVersionNumber = AndroidManifestParser.INVALID_MIN_SDK;
+            try {
+                deviceApiVersionNumber = Integer.parseInt(value);
+            } catch (NumberFormatException e) {
+                // pass, we'll keep the deviceVersionNumber value at 0.
+            }
+
+            if (launchInfo.getRequiredApiVersionNumber() == AndroidManifestParser.INVALID_MIN_SDK) {
+                // warn the 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 (deviceApiVersionName == null ||
+                        deviceApiVersionNumber == AndroidManifestParser.INVALID_MIN_SDK) {
+                    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)", deviceApiVersionNumber,
+                            deviceApiVersionName));
+                }
+            } else { // app requires a specific API level
+                if (deviceApiVersionName == null ||
+                        deviceApiVersionNumber == AndroidManifestParser.INVALID_MIN_SDK) {
+                    AdtPlugin.printToConsole(launchInfo.getProject(),
+                            "WARNING: Unknown device API version!");
+                } else if (deviceApiVersionNumber < launchInfo.getRequiredApiVersionNumber()) {
+                    String msg = String.format(
+                            "ERROR: Application requires API version %1$d. Device API version is %2$d (Android %3$s).",
+                            launchInfo.getRequiredApiVersionNumber(), deviceApiVersionNumber,
+                            deviceApiVersionName);
+                    AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg);
+
+                    // abort the launch
+                    return false;
+                }
+            }
+
+            // 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) {
+        try {
+            SyncService sync = device.getSyncService();
+            if (sync != null) {
+                IPath path = launchInfo.getPackageFile().getLocation();
+                String message = String.format("Uploading %1$s onto device '%2$s'",
+                        path.lastSegment(), device.getSerialNumber());
+                AdtPlugin.printToConsole(launchInfo.getProject(), message);
+
+                String osLocalPath = path.toOSString();
+                String apkName = launchInfo.getPackageFile().getName();
+                String remotePath = "/data/local/tmp/" + apkName; //$NON-NLS-1$
+
+                SyncResult result = sync.pushFile(osLocalPath, remotePath,
+                        SyncService.getNullProgressMonitor());
+
+                if (result.getCode() != SyncService.RESULT_OK) {
+                    String msg = String.format("Failed to upload %1$s on '%2$s': %3$s",
+                            apkName, device.getSerialNumber(), result.getMessage());
+                    AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg);
+                    return false;
+                }
+
+                // Now that the package is uploaded, we can install it properly.
+                // This will check that there isn't another apk declaring the same package, or
+                // that another install used a different key.
+                boolean installResult =  installPackage(launchInfo, remotePath, device);
+
+                // now we delete the app we sync'ed
+                try {
+                    device.executeShellCommand("rm " + remotePath, new MultiLineReceiver() { //$NON-NLS-1$
+                        @Override
+                        public void processNewLines(String[] lines) {
+                            // pass
+                        }
+                        public boolean isCancelled() {
+                            return false;
+                        }
+                    });
+                } catch (IOException e) {
+                    AdtPlugin.printErrorToConsole(launchInfo.getProject(), String.format(
+                            "Failed to delete temporary package: %1$s", e.getMessage()));
+                    return false;
+                }
+
+                // if the installation succeeded, we register it.
+                if (installResult) {
+                    ApkInstallManager.getInstance().registerInstallation(
+                            launchInfo.getProject(), device);
+                }
+
+                return installResult;
+            } else {
+                String msg = String.format(
+                        "Failed to upload %1$s on device '%2$s': Unable to open sync connection!",
+                        launchInfo.getPackageFile().getName(), device.getSerialNumber());
+                AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg);
+            }
+        } catch (IOException e) {
+            String msg = String.format(
+                    "Failed to upload %1$s on device '%2$s': Unable to open sync connection!",
+                    launchInfo.getPackageFile().getName(), device.getSerialNumber());
+            AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg, e.getMessage());
+        }
+
+        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 that was pushed to a temporary location on the device.
+     * @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 {
+            String result = doInstall(launchInfo, remotePath, device, false /* 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) {
+            // do nothing, we'll return false
+        }
+
+        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$
+            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 {
+        InstallReceiver receiver = new InstallReceiver();
+        try {
+            device.executeShellCommand("pm uninstall " + launchInfo.getPackageName(), //$NON-NLS-1$
+                    receiver);
+        } 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;
+        }
+
+        return receiver.getSuccess();
+    }
+
+    /**
+     * 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 {
+        InstallReceiver receiver = new InstallReceiver();
+        try {
+            String cmd = String.format(
+                    reinstall ? "pm install -r \"%1$s\"" : "pm install \"%1$s\"", //$NON-NLS-1$ //$NON-NLS-2$
+                    remotePath); //$NON-NLS-1$ //$NON-NLS-2$
+            device.executeShellCommand(cmd, receiver);
+        } catch (IOException e) {
+            String msg = String.format(
+                    "Failed to install %1$s on device '%2$s': %3$s",
+                    launchInfo.getPackageFile().getName(), device.getSerialNumber(),
+                    e.getMessage());
+            AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg);
+            throw e;
+        }
+
+        return receiver.getSuccess();
+    }
+
+    /**
+     * 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_INTEREST}, {@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() == ClientData.DEBUGGER_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_INTEREST) == Client.CHANGE_DEBUGGER_INTEREST) {
+            ClientData clientData = client.getClientData();
+            String applicationName = client.getClientData().getClientDescription();
+            if (clientData.getDebuggerConnectionStatus() == ClientData.DEBUGGER_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 ouput 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
new file mode 100644
index 0000000..aaa8e89
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/DelayedLaunchInfo.java
@@ -0,0 +1,245 @@
+/*
+ * 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.project.AndroidManifestParser;
+
+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 ApiVersionNumber by the app. {@link AndroidManifestParser#INVALID_MIN_SDK} means
+     * no requirements */
+    private final int 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.
+     * {@link AndroidManifestParser#INVALID_MIN_SDK} 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, 
+            int 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 int 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
new file mode 100644
index 0000000..a403f5a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/DeviceChooserDialog.java
@@ -0,0 +1,769 @@
+/*
+ * 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.adt.internal.wizards.actions.AvdManagerAction;
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.internal.avd.AvdManager;
+import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
+import com.android.sdkuilib.AvdSelector;
+import com.android.sdkuilib.AvdSelector.SelectionMode;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.preference.IPreferenceStore;
+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;
+
+import java.util.ArrayList;
+
+/**
+ * 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 final static String PREFS_COL_SERIAL = "deviceChooser.serial"; //$NON-NLS-1$
+    private final static String PREFS_COL_STATE  = "deviceChooser.state"; //$NON-NLS-1$
+    private final static String PREFS_COL_AVD     = "deviceChooser.avd"; //$NON-NLS-1$
+    private final static String PREFS_COL_TARGET = "deviceChooser.target"; //$NON-NLS-1$
+    private final static String PREFS_COL_DEBUG  = "deviceChooser.debug"; //$NON-NLS-1$
+
+    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 AvdInfo[] mFullAvdList;
+
+    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 api level of the device
+                            try {
+                                String apiValue = device.getProperty(
+                                        IDevice.PROP_BUILD_VERSION_NUMBER);
+                                if (apiValue != null) {
+                                    int api = Integer.parseInt(apiValue);
+                                    if (api >= mProjectTarget.getApiVersionNumber()) {
+                                        // if the project is compiling against an add-on, the optional
+                                        // API may be missing from the device.
+                                        return mProjectTarget.isPlatform() ?
+                                                mMatchImage : mWarningImage;
+                                    } else {
+                                        return mNoMatchImage;
+                                    }
+                                } else {
+                                    return mWarningImage;
+                                }
+                            } catch (NumberFormatException e) {
+                                // lets consider the device non compatible
+                                return mNoMatchImage;
+                            }
+                        } 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();
+
+        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);
+
+        IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore();
+        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$
+                PREFS_COL_SERIAL, store);
+
+        TableHelper.createTableColumn(mDeviceTable, "AVD Name",
+                SWT.LEFT, "engineering", //$NON-NLS-1$
+                PREFS_COL_AVD, store);
+
+        TableHelper.createTableColumn(mDeviceTable, "Target",
+                SWT.LEFT, "AAA+Android 9.9.9", //$NON-NLS-1$
+                PREFS_COL_TARGET, store);
+
+        TableHelper.createTableColumn(mDeviceTable, "Debug",
+                SWT.LEFT, "Debug", //$NON-NLS-1$
+                PREFS_COL_DEBUG, store);
+
+        TableHelper.createTableColumn(mDeviceTable, "State",
+                SWT.LEFT, "bootloader", //$NON-NLS-1$
+                PREFS_COL_STATE, 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,
+                getNonRunningAvds(false /*reloadAvds*/),
+                mProjectTarget,
+                new AvdSelector.IExtraAction() {
+                    public void run() {
+                        AvdManagerAction action = new AvdManagerAction();
+                        action.run(null);
+                        refillAvdList(true /*reloadAvds*/);
+                    }
+
+                    public boolean isEnabled() {
+                        return true;
+                    }
+
+                    public String label() {
+                        return "AVD Manager...";
+                    }
+                },
+                SelectionMode.CHECK);
+        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();
+    }
+
+    /**
+     * Returns the list of {@link AvdInfo} that are not already running in an emulator.
+     */
+    private AvdInfo[] getNonRunningAvds(boolean reloadAvds) {
+        ArrayList<AvdInfo> list = new ArrayList<AvdInfo>();
+
+        // get the full list of Android Virtual Devices
+        if (reloadAvds || mFullAvdList == null) {
+            AvdManager avdManager = mSdk.getAvdManager();
+            if (avdManager != null) {
+                mFullAvdList = avdManager.getValidAvds();
+            }
+        }
+
+        // loop through all the Avd and put the one that are not running in the list.
+        if (mFullAvdList != null) {
+            IDevice[] devices = AndroidDebugBridge.getBridge().getDevices();
+            avdLoop: for (AvdInfo info : mFullAvdList) {
+                for (IDevice d : devices) {
+                    if (info.getName().equals(d.getAvdName())) {
+                        continue avdLoop;
+                    }
+                }
+                list.add(info);
+            }
+        }
+
+        return list.toArray(new AvdInfo[list.size()]);
+    }
+
+    /**
+     * Refills the AVD list keeping the current selection.
+     */
+    private void refillAvdList(boolean reloadAvds) {
+        AvdInfo[] array = getNonRunningAvds(reloadAvds);
+
+        // save the current selection
+        AvdInfo selected = mPreferredAvdSelector.getSelected();
+
+        // disable selection change.
+        mDisableAvdSelectionChange = true;
+
+        // set the new list in the selector
+        mPreferredAvdSelector.setAvds(array, mProjectTarget);
+
+        // 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
new file mode 100644
index 0000000..096d72a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/EmptyLaunchAction.java
@@ -0,0 +1,38 @@
+/*
+ * 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
new file mode 100644
index 0000000..1bba718
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/EmulatorConfigTab.java
@@ -0,0 +1,495 @@
+/*
+ * 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.adt.internal.wizards.actions.AvdManagerAction;
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.prefs.AndroidLocation.AndroidLocationException;
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.internal.avd.AvdManager;
+import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
+import com.android.sdkuilib.AvdSelector;
+import com.android.sdkuilib.AvdSelector.SelectionMode;
+
+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();
+        } 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:");
+        mPreferredAvdSelector = new AvdSelector(offsetComp,
+                null /*avds*/,
+                new AvdSelector.IExtraAction() {
+                    public void run() {
+                        AvdManagerAction action = new AvdManagerAction();
+                        action.run(null);
+                        updateAvdList(null);
+                    }
+
+                    public boolean isEnabled() {
+                        return true;
+                    }
+
+                    public String label() {
+                        return "AVD Manager...";
+                    }
+                },
+                SelectionMode.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();
+        }
+
+        AvdInfo[] avds = null;
+        // no project? we don't want to display any "compatible" AVDs.
+        if (avdManager != null && mProjectTarget != null) {
+            avds = avdManager.getValidAvds();
+        }
+
+        mPreferredAvdSelector.setAvds(avds, mProjectTarget);
+    }
+
+    /* (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
new file mode 100644
index 0000000..1383f8c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/IAndroidLaunchAction.java
@@ -0,0 +1,42 @@
+/*
+ * 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
new file mode 100644
index 0000000..6a5c009
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/ILaunchController.java
@@ -0,0 +1,40 @@
+/*
+ * 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
new file mode 100644
index 0000000..cbfcb24
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/JUnitLaunchConfigDelegate.java
@@ -0,0 +1,155 @@
+/*
+ * 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
new file mode 100644
index 0000000..66762e9
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchConfigDelegate.java
@@ -0,0 +1,421 @@
+/*
+ * 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
new file mode 100644
index 0000000..e1496eb
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchConfigTabGroup.java
@@ -0,0 +1,40 @@
+/*
+ * 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
new file mode 100644
index 0000000..1235f9d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/LaunchShortcut.java
@@ -0,0 +1,87 @@
+/*
+ * 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
new file mode 100644
index 0000000..2b57f30
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/MainLaunchConfigTab.java
@@ -0,0 +1,488 @@
+/*
+ * 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
new file mode 100644
index 0000000..523db3e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchAction.java
@@ -0,0 +1,263 @@
+/*
+ * 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
new file mode 100755
index 0000000..3872bc8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigDelegate.java
@@ -0,0 +1,232 @@
+/*
+ * 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
new file mode 100644
index 0000000..8f162a6
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchConfigurationTab.java
@@ -0,0 +1,997 @@
+/*
+ * 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
new file mode 100755
index 0000000..b94ced8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitLaunchShortcut.java
@@ -0,0 +1,56 @@
+/*
+ * 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
new file mode 100644
index 0000000..b45cc41
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitPropertyTester.java
@@ -0,0 +1,130 @@
+/*
+ * 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
new file mode 100644
index 0000000..0555dea
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/AndroidJUnitTabGroup.java
@@ -0,0 +1,42 @@
+/*
+ * 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
new file mode 100644
index 0000000..856b20b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/InstrumentationRunnerValidator.java
@@ -0,0 +1,150 @@
+/*
+ * 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
new file mode 100644
index 0000000..eea999e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/AndroidJUnitLaunchInfo.java
@@ -0,0 +1,135 @@
+/*
+ * 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
new file mode 100644
index 0000000..8477ca8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/AndroidTestReference.java
@@ -0,0 +1,63 @@
+/*
+ * 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
new file mode 100755
index 0000000..e2afc40
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/RemoteAdtTestRunner.java
@@ -0,0 +1,228 @@
+/*
+ * 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
new file mode 100644
index 0000000..1164956
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/TestCaseReference.java
@@ -0,0 +1,75 @@
+/*
+ * 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
new file mode 100644
index 0000000..b64ede3
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/TestCollector.java
@@ -0,0 +1,124 @@
+/*
+ * 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
new file mode 100644
index 0000000..9bf1e8d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/launch/junit/runtime/TestSuiteReference.java
@@ -0,0 +1,78 @@
+/*
+ * 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
new file mode 100644
index 0000000..f6969f8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/AndroidPreferencePage.java
@@ -0,0 +1,222 @@
+/*
+ * 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.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
new file mode 100644
index 0000000..7adfc23
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/BuildPreferencePage.java
@@ -0,0 +1,217 @@
+/*
+ * 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
new file mode 100644
index 0000000..df30eb5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/LaunchPreferencePage.java
@@ -0,0 +1,51 @@
+/*
+ * 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
new file mode 100644
index 0000000..1474102
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/Messages.java
@@ -0,0 +1,43 @@
+
+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
new file mode 100644
index 0000000..4617e96
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/PreferenceInitializer.java
@@ -0,0 +1,57 @@
+/*
+ * 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
new file mode 100644
index 0000000..acdfefd
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/UsagePreferencePage.java
@@ -0,0 +1,123 @@
+/*
+ * 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/preferences/messages.properties b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/messages.properties
similarity index 100%
rename from tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/messages.properties
rename to tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/preferences/messages.properties
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
new file mode 100644
index 0000000..bbef6b9
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainer.java
@@ -0,0 +1,60 @@
+/*
+ * 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
new file mode 100644
index 0000000..44956bc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidClasspathContainerInitializer.java
@@ -0,0 +1,644 @@
+/*
+ * 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
new file mode 100644
index 0000000..3deea23
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidManifestParser.java
@@ -0,0 +1,1031 @@
+/*
+ * 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 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 String ATTRIBUTE_PACKAGE = "package"; //$NON-NLS-1$
+    private final static String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
+    private final static String ATTRIBUTE_PROCESS = "process"; //$NON-NLS-$
+    private final static String ATTRIBUTE_DEBUGGABLE = "debuggable"; //$NON-NLS-$
+    private final static String ATTRIBUTE_MIN_SDK_VERSION = "minSdkVersion"; //$NON-NLS-$
+    private final static String ATTRIBUTE_TARGET_PACKAGE = "targetPackage"; //$NON-NLS-1$
+    private final static String ATTRIBUTE_EXPORTED = "exported"; //$NON-NLS-1$
+    private final static String NODE_MANIFEST = "manifest"; //$NON-NLS-1$
+    private final static String NODE_APPLICATION = "application"; //$NON-NLS-1$
+    private final static String NODE_ACTIVITY = "activity"; //$NON-NLS-1$
+    private final static String NODE_SERVICE = "service"; //$NON-NLS-1$
+    private final static String NODE_RECEIVER = "receiver"; //$NON-NLS-1$
+    private final static String NODE_PROVIDER = "provider"; //$NON-NLS-1$
+    private final static String NODE_INTENT = "intent-filter"; //$NON-NLS-1$
+    private final static String NODE_ACTION = "action"; //$NON-NLS-1$
+    private final static String NODE_CATEGORY = "category"; //$NON-NLS-1$
+    private final static String NODE_USES_SDK = "uses-sdk"; //$NON-NLS-1$
+    private final static String NODE_INSTRUMENTATION = "instrumentation"; //$NON-NLS-1$
+    private final static String NODE_USES_LIBRARY = "uses-library"; //$NON-NLS-1$
+
+    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$
+
+    public final static int INVALID_MIN_SDK = -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 {@link AndroidManifestParser#INVALID_MIN_SDK}
+         * the attribute was not present. */
+        private int mApiLevelRequirement = INVALID_MIN_SDK;
+        /** 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
+         * {@link AndroidManifestParser#INVALID_MIN_SDK} if it's not set.
+         */
+        int 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 (NODE_MANIFEST.equals(localName)) {
+                                // lets get the package name.
+                                mPackage = getAttributeValue(attributes, ATTRIBUTE_PACKAGE,
+                                        false /* hasNamespace */);
+                                mValidLevel++;
+                            }
+                            break;
+                        case LEVEL_APPLICATION:
+                            if (NODE_APPLICATION.equals(localName)) {
+                                value = getAttributeValue(attributes, ATTRIBUTE_PROCESS,
+                                        true /* hasNamespace */);
+                                if (value != null) {
+                                    addProcessName(value);
+                                }
+
+                                value = getAttributeValue(attributes, ATTRIBUTE_DEBUGGABLE,
+                                        true /* hasNamespace*/);
+                                if (value != null) {
+                                    mDebuggable = Boolean.parseBoolean(value);
+                                }
+
+                                mValidLevel++;
+                            } else if (NODE_USES_SDK.equals(localName)) {
+                                value = getAttributeValue(attributes, ATTRIBUTE_MIN_SDK_VERSION,
+                                        true /* hasNamespace */);
+
+                                if (value != null) {
+                                    try {
+                                        mApiLevelRequirement = Integer.parseInt(value);
+                                    } catch (NumberFormatException e) {
+                                        handleError(e, -1 /* lineNumber */);
+                                    }
+                                }
+                            } else if (NODE_INSTRUMENTATION.equals(localName)) {
+                                processInstrumentationNode(attributes);
+                            }
+                            break;
+                        case LEVEL_ACTIVITY:
+                            if (NODE_ACTIVITY.equals(localName)) {
+                                processActivityNode(attributes);
+                                mValidLevel++;
+                            } else if (NODE_SERVICE.equals(localName)) {
+                                processNode(attributes, AndroidConstants.CLASS_SERVICE);
+                                mValidLevel++;
+                            } else if (NODE_RECEIVER.equals(localName)) {
+                                processNode(attributes, AndroidConstants.CLASS_BROADCASTRECEIVER);
+                                mValidLevel++;
+                            } else if (NODE_PROVIDER.equals(localName)) {
+                                processNode(attributes, AndroidConstants.CLASS_CONTENTPROVIDER);
+                                mValidLevel++;
+                            } else if (NODE_USES_LIBRARY.equals(localName)) {
+                                value = getAttributeValue(attributes, 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 && NODE_INTENT.equals(localName)) {
+                                mCurrentActivity.resetIntentFilter();
+                                mValidLevel++;
+                            }
+                            break;
+                        case LEVEL_CATEGORY:
+                            if (mCurrentActivity != null) {
+                                if (NODE_ACTION.equals(localName)) {
+                                    // get the name attribute
+                                    String action = getAttributeValue(attributes, ATTRIBUTE_NAME,
+                                            true /* hasNamespace */);
+                                    if (action != null) {
+                                        mCurrentActivity.setHasAction(true);
+                                        mCurrentActivity.setHasMainAction(
+                                                ACTION_MAIN.equals(action));
+                                    }
+                                } else if (NODE_CATEGORY.equals(localName)) {
+                                    String category = getAttributeValue(attributes, 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, ATTRIBUTE_NAME,
+                    true /* hasNamespace */);
+            if (activityName != null) {
+                activityName = combinePackageAndClassName(mPackage, activityName);
+
+                // get the exported flag.
+                String exportedStr = getAttributeValue(attributes, 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, 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, ATTRIBUTE_NAME,
+                    true /* hasNamespace */);
+            if (serviceName != null) {
+                serviceName = combinePackageAndClassName(mPackage, serviceName);
+
+                if (mMarkErrors) {
+                    checkClass(serviceName, superClassName, false /* testVisibility */);
+                }
+            }
+
+            String processName = getAttributeValue(attributes, 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, ATTRIBUTE_NAME,
+                    true /* hasNamespace */);
+            if (instrumentationName != null) {
+                String instrClassName = combinePackageAndClassName(mPackage, instrumentationName);
+                String targetPackage = getAttributeValue(attributes, 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 int 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 {@link #INVALID_MIN_SDK}
+     * if it's not set.
+     */
+    public int 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 0 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,
+            int 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;
+    }
+
+    /**
+     * 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;
+        }
+    }
+
+    /**
+     * 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
new file mode 100644
index 0000000..70097ae
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidNature.java
@@ -0,0 +1,291 @@
+/*
+ * 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/AndroidXPathFactory.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidXPathFactory.java
new file mode 100644
index 0000000..9326cb7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/AndroidXPathFactory.java
@@ -0,0 +1,89 @@
+/*
+ * 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.sdklib.SdkConstants;
+
+import java.util.Iterator;
+
+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 namespace.
+ */
+public class AndroidXPathFactory {
+    public final static String DEFAULT_NS_PREFIX = "android"; //$NON-NLS-1$
+
+    private final static XPathFactory sFactory = XPathFactory.newInstance();
+    
+    /** Namespace context for Android resource XML files. */
+    private static class AndroidNamespaceContext implements NamespaceContext {
+        private String mAndroidPrefix;
+
+        /**
+         * Construct the context with the prefix associated with the android namespace.
+         * @param androidPrefix the Prefix
+         */
+        public AndroidNamespaceContext(String androidPrefix) {
+            mAndroidPrefix = androidPrefix;
+        }
+
+        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) {
+            // This isn't necessary for our use.
+            assert false;
+            return null;
+        }
+
+        public Iterator<?> getPrefixes(String namespaceURI) {
+            // This isn't necessary for our use.
+            assert false;
+            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() {
+        return newXPath(DEFAULT_NS_PREFIX);
+    }
+}
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
new file mode 100644
index 0000000..f7556c0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ApkInstallManager.java
@@ -0,0 +1,206 @@
+/*
+ * 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
new file mode 100644
index 0000000..ff6cd04
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/BaseProjectHelper.java
@@ -0,0 +1,452 @@
+/*
+ * 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
new file mode 100644
index 0000000..2cdf3be
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ExportHelper.java
@@ -0,0 +1,188 @@
+/*
+ * 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.openInformation(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.openInformation(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.openInformation(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
+                    }
+                }
+            }
+        } else {
+            MessageDialog.openInformation(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
new file mode 100644
index 0000000..e311bfb
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/FixLaunchConfig.java
@@ -0,0 +1,156 @@
+/*
+ * 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
new file mode 100644
index 0000000..5f4e22e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/FolderDecorator.java
@@ -0,0 +1,107 @@
+/*
+ * 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
new file mode 100644
index 0000000..e6cac8a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectChooserHelper.java
@@ -0,0 +1,129 @@
+/*
+ * 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
new file mode 100644
index 0000000..49a75dc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/ProjectHelper.java
@@ -0,0 +1,768 @@
+/*
+ * 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
new file mode 100644
index 0000000..fe73d49
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/XmlErrorHandler.java
@@ -0,0 +1,132 @@
+/*
+ * 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
new file mode 100644
index 0000000..f6f5f67
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/properties/AndroidPropertyPage.java
@@ -0,0 +1,123 @@
+/*
+ * 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.sdkuilib.ApkConfigWidget;
+import com.android.sdkuilib.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;
+
+import java.util.Map;
+
+/**
+ * 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;
+    private ApkConfigWidget mApkConfigWidget;
+
+    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);
+
+        l = new Label(top, SWT.SEPARATOR | SWT.HORIZONTAL);
+        l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        l = new Label(top, SWT.NONE);
+        l.setText("Project APK Configurations");
+
+        mApkConfigWidget = new ApkConfigWidget(top);
+
+        // 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);
+            }
+            
+            // get the apk configurations
+            Map<String, String> configs = currentSdk.getProjectApkConfigs(mProject);
+            mApkConfigWidget.fillTable(configs);
+        }
+
+        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) {
+            currentSdk.setProject(mProject, mSelector.getSelected(),
+                    mApkConfigWidget.getApkConfigs());
+        }
+        
+        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
new file mode 100644
index 0000000..668cff3
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringAction.java
@@ -0,0 +1,170 @@
+/*
+ * 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 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) {
+                mFile = getSelectedFile();
+            }
+        }
+
+        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, 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 {@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() {
+        IWorkbenchWindow wwin = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+        if (wwin != null) {
+            IWorkbenchPage page = wwin.getActivePage();
+            if (page != null) {
+                IEditorPart editor = page.getActiveEditor();
+                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
new file mode 100644
index 0000000..14fd506
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringContribution.java
@@ -0,0 +1,53 @@
+/*
+ * 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
new file mode 100644
index 0000000..190736a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringDescriptor.java
@@ -0,0 +1,71 @@
+/*
+ * 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
new file mode 100644
index 0000000..d264afc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringInputPage.java
@@ -0,0 +1,505 @@
+/*
+ * 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.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.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;
+
+    /** Test field where the user enters the new ID to be generated or replaced with. */ 
+    private Text mStringIdField;
+    /** 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();
+        
+        final Text stringValueField = new Text(group, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+        stringValueField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        stringValueField.setText(selectedString != null ? selectedString : "");  //$NON-NLS-1$
+        
+        ref.setNewStringValue(stringValueField.getText());
+
+        stringValueField.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                if (validatePage()) {
+                    ref.setNewStringValue(stringValueField.getText());
+                }
+            }
+        });
+
+        
+        // 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.");
+        }
+
+        mStringIdField = new Text(group, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
+        mStringIdField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mStringIdField.setText(guessId(selectedString));
+
+        ref.setNewStringId(mStringIdField.getText().trim());
+
+        mStringIdField.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                if (validatePage()) {
+                    ref.setNewStringId(mStringIdField.getText().trim());
+                }
+            }
+        });
+    }
+
+    /**
+     * 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);
+        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)}.
+     * 
+     * @return True if the page has been positively validated. It may still have warnings.
+     */
+    private boolean validatePage() {
+        boolean success = true;
+
+        // Analyze fatal errors.
+        
+        String text = mStringIdField.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;
+                }
+            }
+        }
+
+        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);
+
+            ExtractStringRefactoring ref = getOurRefactoring();
+
+            ref.setTargetFile(resFile);
+            sLastResFilePath.put(mProject.getFullPath().toPortableString(), resFile);
+
+            if (mXmlHelper.isResIdDuplicate(mProject, resFile, text)) {
+                String msg = String.format("There's already a string item called '%1$s' in %2$s.",
+                        text, resFile);
+                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);
+            }
+        }
+
+        setPageComplete(success);
+        return success;
+    }
+
+    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));
+            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
+            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;
+                    }
+                }
+            }
+
+            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
new file mode 100644
index 0000000..0cccbd2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringRefactoring.java
@@ -0,0 +1,988 @@
+/*
+ * 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.project.AndroidManifestParser;
+
+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.ASTVisitor;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.Name;
+import org.eclipse.jdt.core.dom.QualifiedName;
+import org.eclipse.jdt.core.dom.SimpleName;
+import org.eclipse.jdt.core.dom.StringLiteral;
+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 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.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> TODO: to support refactoring from an XML file, the action should give the {@link IFile}
+ *      and then here we would have to determine whether it's a suitable Android XML file or a
+ *      suitable Java file.
+ *      TODO: enumerate the exact valid contexts in Android XML files, e.g. attributes in layout
+ *      files or text elements (e.g. <string>foo</string>) for values, etc. 
+ * <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#isResIdDuplicate(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: If the source is an XML file, determine if we need to change an attribute or a
+ *      a text element.
+ * <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;
+    /** The file model being manipulated.
+     * Value is null when not on {@link Mode#EDIT_SOURCE} mode. */
+    private final IFile mFile;
+    /** 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$
+
+    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);
+        } else {
+            mFile = null;
+            mSelectionStart = mSelectionEnd = -1;
+            mTokenString = 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);
+        }
+        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 selection The selection in the source file. Cannot be null or empty.
+     */
+    public ExtractStringRefactoring(IFile file, ITextSelection selection) {
+        mMode = Mode.EDIT_SOURCE;
+        mFile = file;
+        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;
+        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...", 5);
+
+            if (mMode != Mode.EDIT_SOURCE) {
+                monitor.worked(5);
+                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) {
+                // Check this an XML file and get the selection and its context.
+                // TODO
+                status.addFatalError("Selection must be inside a Java source 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.
+     */
+    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 of 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();
+    }
+
+    /**
+     * 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.isResIdDuplicate(mProject, mTargetXmlFileWsPath, mXmlStringId)) {
+                // 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) {
+                // Prepare the change to the Java compilation unit
+                List<Change> 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 have 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 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.getFullPath(), 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.
+            
+            if (changes.size() > 0) {
+                return changes;
+            }
+
+            subMonitor.worked(1);
+
+        } catch (CoreException e) {
+            // ImportRewrite.rewriteImports failed.
+            status.addFatalError(e.getMessage());
+        }
+        return null;
+    }
+
+    public class ReplaceStringsVisitor extends ASTVisitor {
+
+        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;
+        }
+
+        @Override
+        public boolean visit(StringLiteral node) {
+            if (node.getLiteralValue().equals(mOldString)) {
+                
+                Name qualifierName = mAst.newName(mRQualifier + ".string"); //$NON-NLS-1$
+                SimpleName idName = mAst.newSimpleName(mXmlId);
+                QualifiedName newNode = mAst.newQualifiedName(qualifierName, idName);
+                
+                TextEditGroup editGroup = new TextEditGroup("Replace string by ID");                
+                mEditGroups.add(editGroup);
+                mRewriter.replace(node, newNode, editGroup);
+            }
+            return super.visit(node);
+        }
+    }
+
+    /**
+     * 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
new file mode 100644
index 0000000..556dff0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/ExtractStringWizard.java
@@ -0,0 +1,50 @@
+/*
+ * 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/XmlStringFileHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/XmlStringFileHelper.java
new file mode 100644
index 0000000..773dc1c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/refactorings/extractstring/XmlStringFileHelper.java
@@ -0,0 +1,122 @@
+/*
+ * 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.internal.project.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.NodeList;
+import org.xml.sax.InputSource;
+
+import java.util.HashMap;
+import java.util.HashSet;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+
+/**
+ * 
+ */
+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. */
+    private HashMap<String,HashSet<String>> mResIdCache;
+    /** An instance of XPath, created lazily on demand. */
+    private XPath mXPath;
+
+    public XmlStringFileHelper() {
+    }
+    
+    /**
+     * Utility method used by the wizard to check whether the given string ID is already
+     * defined in the XML file which path is given.
+     * 
+     * @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 True if such a string ID is already defined.
+     */
+    public boolean isResIdDuplicate(IProject project, String xmlFileWsPath, String stringId) {
+        // This is going to be called many times on the same file.
+        // Build a cache of the existing IDs for a given file.
+        if (mResIdCache == null) {
+            mResIdCache = new HashMap<String, HashSet<String>>();
+        }
+        HashSet<String> cache = mResIdCache.get(xmlFileWsPath);
+        if (cache == null) {
+            cache = getResIdsForFile(project, xmlFileWsPath);
+            mResIdCache.put(xmlFileWsPath, cache);
+        }
+        
+        return cache.contains(stringId);
+    }
+
+    /**
+     * 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 set of all string IDs defined in the file. The returned set is always non
+     *   null. It is empty if the file does not exist.
+     */
+    private HashSet<String> getResIdsForFile(IProject project, String xmlFileWsPath) {
+        HashSet<String> ids = new HashSet<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/@name";   //$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--) {
+                        String id = list.item(n).getNodeValue();
+                        ids.add(id);
+                    }
+                }
+                
+            } catch (CoreException e1) {
+                // IFile.getContents failed. Ignore.
+            } catch (XPathExpressionException e) {
+                // 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
new file mode 100644
index 0000000..7f576c4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/AttrsXmlParser.java
@@ -0,0 +1,505 @@
+/*
+ * 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
new file mode 100644
index 0000000..bcfa766
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/DeclareStyleableInfo.java
@@ -0,0 +1,186 @@
+/*
+ * 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
new file mode 100644
index 0000000..7ed6836
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/IIdResourceItem.java
@@ -0,0 +1,28 @@
+/*
+ * 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
new file mode 100644
index 0000000..d125dc0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/IResourceRepository.java
@@ -0,0 +1,47 @@
+/*
+ * 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
new file mode 100644
index 0000000..c340ffe
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ResourceItem.java
@@ -0,0 +1,48 @@
+/*
+ * 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
new file mode 100644
index 0000000..008e1fa
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ResourceType.java
@@ -0,0 +1,111 @@
+/*
+ * 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
new file mode 100644
index 0000000..23eb1e4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ViewClassInfo.java
@@ -0,0 +1,159 @@
+/*
+ * 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
new file mode 100644
index 0000000..c624035
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/CountryCodeQualifier.java
@@ -0,0 +1,144 @@
+/*
+ * 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 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 int mCode = DEFAULT_CODE;
+    
+    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();
+            qualifier.mCode = 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 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 toString() {
+        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
new file mode 100644
index 0000000..b589d26
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/FolderConfiguration.java
@@ -0,0 +1,499 @@
+/*
+ * 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;
+
+
+/**
+ * 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_ORIENTATION = 4;
+    private final static int INDEX_PIXEL_DENSITY = 5;
+    private final static int INDEX_TOUCH_TYPE = 6;
+    private final static int INDEX_KEYBOARD_STATE = 7;
+    private final static int INDEX_TEXT_INPUT_METHOD = 8;
+    private final static int INDEX_NAVIGATION_METHOD = 9;
+    private final static int INDEX_SCREEN_DIMENSION = 10;
+    private final static int INDEX_COUNT = 11;
+    
+    /**
+     * Sets the config from the qualifiers of a given <var>config</var>.
+     * @param config
+     */
+    public void set(FolderConfiguration config) {
+        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 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;
+        }
+    }
+    
+    /**
+     * 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;
+            }
+        }
+    }
+    
+    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 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];
+    }
+
+    /**
+     * 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) {
+        StringBuilder result = new StringBuilder(folder.getName());
+        
+        for (ResourceQualifier qualifier : mQualifiers) {
+            if (qualifier != null) {
+                result.append(QUALIFIER_SEP);
+                result.append(qualifier.toString());
+            }
+        }
+        
+        return result.toString();
+    }
+    
+    /**
+     * Returns a string valid for usage in a folder name, or <code>null</code> if the configuration
+     * is default.
+     */
+    @Override
+    public String toString() {
+        StringBuilder result = null;
+        
+        for (ResourceQualifier irq : mQualifiers) {
+            if (irq != null) {
+                if (result == null) {
+                    result = new StringBuilder();
+                } else {
+                    result.append(QUALIFIER_SEP);
+                }
+                result.append(irq.toString());
+            }
+        }
+        
+        if (result != null) {
+            return result.toString();
+        } else {
+            return null;
+        }
+    }
+    
+    /**
+     * 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.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 match the given reference config.
+     * <p/>A match means that:
+     * <ul>
+     * <li>This config does not use any qualifier not used by the reference config</li>
+     * <li>The qualifier used by this config have the same values as the qualifiers of
+     * the reference config.</li>
+     * </ul>
+     * @param referenceConfig The reference configuration to test against.
+     * @return the number of matching qualifiers or -1 if the configurations are not compatible.
+     */
+    public int match(FolderConfiguration referenceConfig) {
+        int matchCount = 0;
+        
+        for (int i = 0 ; i < INDEX_COUNT ; i++) {
+            ResourceQualifier testQualifier = mQualifiers[i];
+            ResourceQualifier referenceQualifier = referenceConfig.mQualifiers[i];
+            
+            // we only care if testQualifier is non null. If it's null, it's a match but
+            // without increasing the matchCount.
+            if (testQualifier != null) {
+                if (referenceQualifier == null) {
+                    return -1;
+                } else if (testQualifier.equals(referenceQualifier) == false) {
+                    return -1;
+                }
+                
+                // the qualifier match, increment the count
+                matchCount++;
+            }
+        }
+        return matchCount;
+    }
+
+    /**
+     * 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_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();
+    }
+
+    /**
+     * 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
new file mode 100644
index 0000000..2acebcc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/KeyboardStateQualifier.java
@@ -0,0 +1,180 @@
+/*
+ * 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 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$
+        
+        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.
+         */
+        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 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 toString() {
+        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
new file mode 100644
index 0000000..799fc06
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/LanguageQualifier.java
@@ -0,0 +1,145 @@
+/*
+ * 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 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 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 toString() {
+        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
new file mode 100644
index 0000000..6315014
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NavigationMethodQualifier.java
@@ -0,0 +1,183 @@
+/*
+ * 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 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.
+         */
+        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();
+            qualifier.mValue = 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 toString() {
+        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
new file mode 100644
index 0000000..c7f7fad
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/NetworkCodeQualifier.java
@@ -0,0 +1,156 @@
+/*
+ * 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 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 int mCode = DEFAULT_CODE;
+    
+    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();
+            qualifier.mCode = 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 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();
+            qualifier.mCode = 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 toString() {
+        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
new file mode 100644
index 0000000..a2c690b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/PixelDensityQualifier.java
@@ -0,0 +1,144 @@
+/*
+ * 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 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 {
+    /** Default pixel density value. This means the property is not set. */
+    private final static int DEFAULT_DENSITY = -1;
+
+    private final static Pattern sPixelDensityPattern = Pattern.compile("^(\\d+)dpi$");//$NON-NLS-1$
+
+    public static final String NAME = "Pixel Density";
+
+    private int mValue = DEFAULT_DENSITY;
+    
+    /**
+     * Creates and returns a qualifier from the given folder segment. If the segment is incorrect,
+     * <code>null</code> is returned.
+     * @param folderSegment the folder segment from which to create a qualifier.
+     * @return a new {@link CountryCodeQualifier} object or <code>null</code>
+     */
+    public static PixelDensityQualifier getQualifier(String folderSegment) {
+        Matcher m = sPixelDensityPattern.matcher(folderSegment);
+        if (m.matches()) {
+            String v = m.group(1);
+
+            int density = -1;
+            try {
+                density = Integer.parseInt(v);
+            } catch (NumberFormatException e) {
+                // looks like the string we extracted wasn't a valid number.
+                return null;
+            }
+            
+            PixelDensityQualifier qualifier = new PixelDensityQualifier();
+            qualifier.mValue = density;
+            
+            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 value the value of the qualifier, as returned by {@link #getValue()}.
+     */
+    public static String getFolderSegment(int value) {
+        if (value != DEFAULT_DENSITY) {
+            return String.format("%1$ddpi", value); //$NON-NLS-1$
+        }
+        
+        return ""; //$NON-NLS-1$
+    }
+
+    public int 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 != DEFAULT_DENSITY;
+    }
+
+    @Override
+    public boolean checkAndSet(String value, FolderConfiguration config) {
+        PixelDensityQualifier qualifier = getQualifier(value);
+        if (qualifier != null) {
+            config.setPixelDensityQualifier(qualifier);
+            return true;
+        }
+        
+        return false;
+    }
+    
+    @Override
+    public boolean equals(Object qualifier) {
+        if (qualifier instanceof PixelDensityQualifier) {
+            return mValue == ((PixelDensityQualifier)qualifier).mValue;
+        }
+        
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return mValue;
+    }
+    
+    /**
+     * Returns the string used to represent this qualifier in the folder name.
+     */
+    @Override
+    public String toString() {
+        return getFolderSegment(mValue);
+    }
+
+    @Override
+    public String getStringValue() {
+        if (mValue != DEFAULT_DENSITY) {
+            return String.format("%1$d dpi", 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/RegionQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/RegionQualifier.java
new file mode 100644
index 0000000..be54f2b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/RegionQualifier.java
@@ -0,0 +1,145 @@
+/*
+ * 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 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 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 toString() {
+        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
new file mode 100644
index 0000000..b644e8f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ResourceQualifier.java
@@ -0,0 +1,86 @@
+/*
+ * 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 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.
+     */
+    @Override
+    public abstract String toString();
+
+    /**
+     * 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
new file mode 100644
index 0000000..e756644
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenDimensionQualifier.java
@@ -0,0 +1,148 @@
+/*
+ * 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 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 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 toString() {
+        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
new file mode 100644
index 0000000..6e1b829
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/ScreenOrientationQualifier.java
@@ -0,0 +1,178 @@
+/*
+ * 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 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.
+         */
+        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 toString() {
+        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/TextInputMethodQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TextInputMethodQualifier.java
new file mode 100644
index 0000000..add45cc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TextInputMethodQualifier.java
@@ -0,0 +1,182 @@
+/*
+ * 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 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.
+         */
+        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 toString() {
+        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
new file mode 100644
index 0000000..1ed7d95
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/configurations/TouchScreenQualifier.java
@@ -0,0 +1,180 @@
+/*
+ * 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 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.
+         */
+        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 toString() {
+        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/manager/CompiledResourcesMonitor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java
new file mode 100644
index 0000000..df716b2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java
@@ -0,0 +1,239 @@
+/*
+ * 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
new file mode 100644
index 0000000..2a998f8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ConfigurableResourceItem.java
@@ -0,0 +1,82 @@
+/*
+ * 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
new file mode 100644
index 0000000..4b45f6e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/FolderTypeRelationship.java
@@ -0,0 +1,164 @@
+/*
+ * 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
new file mode 100644
index 0000000..a3e42c6
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/IdResourceItem.java
@@ -0,0 +1,54 @@
+/*
+ * 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
new file mode 100644
index 0000000..f21b15e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/IntArrayWrapper.java
@@ -0,0 +1,50 @@
+/*
+ * 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
new file mode 100644
index 0000000..7528441
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/MultiResourceFile.java
@@ -0,0 +1,174 @@
+/*
+ * 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
new file mode 100644
index 0000000..3e1259c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectClassLoader.java
@@ -0,0 +1,251 @@
+/*
+ * 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
new file mode 100644
index 0000000..7c382d5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResourceItem.java
@@ -0,0 +1,91 @@
+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
new file mode 100644
index 0000000..e6f81e2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResources.java
@@ -0,0 +1,804 @@
+/*
+ * 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.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.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 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 list of languages used in the resources.
+     */
+    public Set<String> getLanguages() {
+        Set<String> set = new HashSet<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 list of regions used in the resources with the given language.
+     * @param currentLanguage the current language the region must be associated with.
+     */
+    public Set<String> getRegions(String currentLanguage) {
+        Set<String> set = new HashSet<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.
+     */
+    private Resource findMatchingConfiguredResource(List<? extends Resource> resources,
+            FolderConfiguration referenceConfig) {
+        // look for resources with the maximum number of qualifier match.
+        int currentMax = -1;
+        ArrayList<Resource> matchingResources = new ArrayList<Resource>();
+        for (int i = 0 ; i < resources.size(); i++) {
+            Resource res = resources.get(i);
+            
+            int count = res.getConfiguration().match(referenceConfig);
+            if (count > currentMax) {
+                matchingResources.clear();
+                matchingResources.add(res);
+                currentMax = count;
+            } else if (count != -1 && count == currentMax) {
+                matchingResources.add(res);
+            }
+        }
+        
+        // if we have more than one match, we look for the match with the qualifiers with the
+        // highest priority.
+        Resource resMatch = null;
+        if (matchingResources.size() == 1) {
+            resMatch = matchingResources.get(0);
+        } else if (matchingResources.size() > 1) {
+            // More than one resource with the same number of qualifier match.
+            // We loop, looking for the resource with the highest priority qualifiers.
+            ArrayList<Resource> tmpResources = new ArrayList<Resource>();
+            int startIndex = 0;
+            while (matchingResources.size() > 1) {
+                int highest = -1;
+                for (int i = 0 ; i < matchingResources.size() ; i++) {
+                    Resource folder = matchingResources.get(i);
+                 
+                    // get highest priority qualifiers.
+                    int m = folder.getConfiguration().getHighestPriorityQualifier(startIndex);
+
+                    // add to the list if highest.
+                    if (m != -1) {
+                        if (highest == -1 || m == highest) {
+                            tmpResources.add(folder);
+                            highest = m;
+                        } else if (m < highest) { // highest priority == lowest index.
+                            tmpResources.clear();
+                            tmpResources.add(folder);
+                        }
+                    }
+                }
+                
+                // at this point, we have a list with 1+ resources that all have the same highest
+                // priority qualifiers. Go through the list again looking for the next highest
+                // priority qualifier.
+                startIndex = highest + 1;
+                
+                // this should not happen, but it's better to check.
+                if (matchingResources.size() == tmpResources.size() && highest == -1) {
+                    // this means all the resources match with the same qualifiers
+                    // (highest == -1 means we reached the end of the qualifier list)
+                    // In this case, we arbitrarily take the first resource.
+                    matchingResources.clear();
+                    matchingResources.add(tmpResources.get(0));
+                } else {
+                    matchingResources.clear();
+                    matchingResources.addAll(tmpResources);
+                }
+                tmpResources.clear();
+            }
+            
+            // we should have only one match here.
+            resMatch = matchingResources.get(0);
+        }
+
+        return resMatch;
+    }
+
+    /**
+     * 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
new file mode 100644
index 0000000..fd9005b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/Resource.java
@@ -0,0 +1,46 @@
+/*
+ * 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
new file mode 100644
index 0000000..f7fb93f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFile.java
@@ -0,0 +1,100 @@
+/*
+ * 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
new file mode 100644
index 0000000..95a2d90
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFolder.java
@@ -0,0 +1,251 @@
+/*
+ * 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
new file mode 100644
index 0000000..0a56ff5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceFolderType.java
@@ -0,0 +1,73 @@
+/*
+ * 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
new file mode 100644
index 0000000..3cb06fd
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java
@@ -0,0 +1,493 @@
+/*
+ * 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 {
+                File[] files = frameworkRes.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();
+                
+                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;
+    }
+    
+    /**
+     * 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
new file mode 100644
index 0000000..06b23d5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceMonitor.java
@@ -0,0 +1,377 @@
+/*
+ * 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
new file mode 100644
index 0000000..51bd793
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/SingleResourceFile.java
@@ -0,0 +1,145 @@
+/*
+ * 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 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);
+        
+        mValue = new ResourceValue(mType.getName(), getResourceName(mType), file.getOsLocation(),
+                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
new file mode 100644
index 0000000..9de5290
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/FileWrapper.java
@@ -0,0 +1,86 @@
+/*
+ * 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
new file mode 100644
index 0000000..1e96164
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/FolderWrapper.java
@@ -0,0 +1,73 @@
+/*
+ * 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
new file mode 100644
index 0000000..db1de5a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IAbstractFile.java
@@ -0,0 +1,44 @@
+/*
+ * 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
new file mode 100644
index 0000000..8557ae2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IAbstractFolder.java
@@ -0,0 +1,38 @@
+/*
+ * 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
new file mode 100644
index 0000000..76f338a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IAbstractResource.java
@@ -0,0 +1,34 @@
+/*
+ * 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
new file mode 100644
index 0000000..a85d36b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IFileWrapper.java
@@ -0,0 +1,68 @@
+/*
+ * 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
new file mode 100644
index 0000000..a92fecd
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/files/IFolderWrapper.java
@@ -0,0 +1,74 @@
+/*
+ * 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
new file mode 100644
index 0000000..477d14a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidJarLoader.java
@@ -0,0 +1,431 @@
+/*
+ * 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
new file mode 100644
index 0000000..118fb4f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetData.java
@@ -0,0 +1,328 @@
+/*
+ * 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
new file mode 100644
index 0000000..5c468ec
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/AndroidTargetParser.java
@@ -0,0 +1,704 @@
+/*
+ * 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.getApiVersionNumber() >= 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
new file mode 100644
index 0000000..9981b14
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/DexWrapper.java
@@ -0,0 +1,169 @@
+/*
+ * 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
new file mode 100644
index 0000000..91b0082
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/FrameworkResourceRepository.java
@@ -0,0 +1,76 @@
+/*
+ * 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
new file mode 100644
index 0000000..c1cd3a3
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/IAndroidClassLoader.java
@@ -0,0 +1,81 @@
+/*
+ * 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/LayoutParamsParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParser.java
new file mode 100644
index 0000000..5d26acb
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParser.java
@@ -0,0 +1,371 @@
+/*
+ * 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
new file mode 100644
index 0000000..e334d97
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LoadStatus.java
@@ -0,0 +1,24 @@
+/*
+ * 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
new file mode 100644
index 0000000..1f3cdb3
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/Sdk.java
@@ -0,0 +1,492 @@
+/*
+ * 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.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.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.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, Map<String, String>> mProjectApkConfigMap =
+            new HashMap<IProject, Map<String, String>>();
+    private final String mDocBaseUrl;
+
+    /**
+     * 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,
+            Map<String, String> apkConfigMap) {
+        synchronized (mProjectTargetMap) {
+            boolean resolveProject = false;
+            boolean compileProject = false;
+            boolean cleanProject = 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 (apkConfigMap != null) {
+                // save the apk configs in the project persistent property
+                cleanProject = ApkConfigurationHelper.setConfigs(properties, apkConfigMap);
+
+                // put it in a local map for easy access.
+                mProjectApkConfigMap.put(project, apkConfigMap);
+
+                compileProject = true;
+            }
+
+            // 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.
+                IJavaProject javaProject = JavaCore.create(project);
+                AndroidClasspathContainerInitializer.updateProjects(
+                        new IJavaProject[] { javaProject });
+            } else if (compileProject) {
+                // If there was removed configs, we clean instead of build
+                // (to remove the obsolete ap_ and apk file from removed configs).
+                try {
+                    project.build(cleanProject ?
+                                IncrementalProjectBuilder.CLEAN_BUILD :
+                                IncrementalProjectBuilder.FULL_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 (mProjectTargetMap) {
+            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) {
+            Map<String, String> configMap = ApkConfigurationHelper.getConfigs(properties);
+
+            if (configMap != null) {
+                sdkStorage.mProjectApkConfigMap.put(project, configMap);
+            }
+        }
+
+        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 (mTargetDataMap) {
+            return mTargetDataMap.get(target);
+        }
+    }
+
+    /**
+     * Returns the configuration map for a given project.
+     * <p/>The Map key are name to be used in the apk filename, while the values are comma separated
+     * config values. The config value can be passed directly to aapt through the -c option.
+     */
+    public Map<String, String> getProjectApkConfigs(IProject project) {
+        return mProjectApkConfigMap.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;
+    }
+
+    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);
+    }
+
+    /**
+     *  Cleans and unloads the SDK.
+     */
+    private void dispose() {
+        ResourceMonitor.getMonitor().removeProjectListener(this);
+    }
+
+    void setTargetData(IAndroidTarget target, AndroidTargetData data) {
+        synchronized (mTargetDataMap) {
+            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;
+    }
+
+    public void projectClosed(IProject project) {
+        // get the target project
+        synchronized (mProjectTargetMap) {
+            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);
+            mProjectApkConfigMap.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
new file mode 100644
index 0000000..321c236
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/WidgetClassLoader.java
@@ -0,0 +1,334 @@
+/*
+ * 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/ui/ConfigurationSelector.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ConfigurationSelector.java
new file mode 100644
index 0000000..7378d41
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ConfigurationSelector.java
@@ -0,0 +1,1278 @@
+/*
+ * 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.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.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.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.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 Composite mQualifierEditParent;
+    
+    /**
+     * 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;
+    }
+
+    public ConfigurationSelector(Composite parent) {
+        super(parent, SWT.NONE);
+
+        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(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));
+    }
+    
+    /**
+     * 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 static class QualifierContentProvider implements IStructuredContentProvider {
+        
+        private FolderConfiguration mInput;
+
+        public QualifierContentProvider() {
+        }
+
+        public void dispose() {
+            // pass
+        }
+
+        public Object[] getElements(Object inputElement) {
+            return mInput.getQualifiers();
+        }
+
+        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 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 Text mText;
+
+        public PixelDensityEdit(Composite parent) {
+            super(parent, PixelDensityQualifier.NAME);
+            
+            mText = new Text(this, SWT.BORDER);
+            mText.addVerifyListener(new DensityVerifier());
+            mText.addModifyListener(new ModifyListener() {
+                public void modifyText(ModifyEvent e) {
+                    onTextChange();
+                }
+            });
+            mText.addFocusListener(new FocusAdapter() {
+                @Override
+                public void focusLost(FocusEvent e) {
+                    onTextChange();
+                }
+            });
+        }
+        
+        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.setPixelDensityQualifier(new PixelDensityQualifier());
+            } else {
+                try {
+                    PixelDensityQualifier qualifier = PixelDensityQualifier.getQualifier(
+                            PixelDensityQualifier.getFolderSegment(Integer.parseInt(value)));
+                    if (qualifier != null) {
+                        mSelectedConfiguration.setPixelDensityQualifier(qualifier);
+                    } else {
+                        // Failure! Looks like the value is wrong
+                        // (for instance a one letter string).
+                        // We do nothing in this case.
+                        return;
+                    }
+                } 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.
+                    // We do nothing in this case.
+                    return;
+                }
+            }
+   
+            // notify of change
+            onChange(true /* keepSelection */);
+        } 
+
+        @Override
+        public void setQualifier(ResourceQualifier qualifier) {
+            PixelDensityQualifier q = (PixelDensityQualifier)qualifier;
+            
+            mText.setText(Integer.toString(q.getValue()));
+        }
+    }
+
+    /**
+     * 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()));
+        }
+    }
+}
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
new file mode 100644
index 0000000..f0fd231
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/EclipseUiHelper.java
@@ -0,0 +1,64 @@
+/*
+ * 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
new file mode 100755
index 0000000..1aa8c2f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/IUpdateWizardDialog.java
@@ -0,0 +1,30 @@
+/*

+ * 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
new file mode 100644
index 0000000..ba4be6a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ReferenceChooserDialog.java
@@ -0,0 +1,363 @@
+/*
+ * 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
new file mode 100644
index 0000000..e2b910c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceChooser.java
@@ -0,0 +1,293 @@
+/*
+ * 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
new file mode 100644
index 0000000..4442b71
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceContentProvider.java
@@ -0,0 +1,110 @@
+/*
+ * 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
new file mode 100644
index 0000000..23eb1ec
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceExplorerView.java
@@ -0,0 +1,338 @@
+/*
+ * 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
new file mode 100644
index 0000000..a67fda4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/ResourceLabelProvider.java
@@ -0,0 +1,138 @@
+/*
+ * 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
new file mode 100755
index 0000000..22141af
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/ui/WizardDialogEx.java
@@ -0,0 +1,46 @@
+/*

+ * 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
new file mode 100755
index 0000000..61cfa74
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/AvdManagerAction.java
@@ -0,0 +1,34 @@
+/*

+ * 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.avdmanager.AvdManagerWizard;

+

+import org.eclipse.jface.action.IAction;

+import org.eclipse.ui.IWorkbenchWizard;

+

+/**

+ * Delegate for the toolbar/menu action "Android AVD Manager".

+ * It displays the Android AVD Manager.

+ */

+public class AvdManagerAction extends OpenWizardAction {

+

+    @Override

+    protected IWorkbenchWizard instanciateWizard(IAction action) {

+        return new AvdManagerWizard();

+    }

+}

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
new file mode 100644
index 0000000..9093470
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportAction.java
@@ -0,0 +1,65 @@
+/*
+ * 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
new file mode 100644
index 0000000..8165f97
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/ExportWizardAction.java
@@ -0,0 +1,57 @@
+/*
+ * 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
new file mode 100644
index 0000000..6bcc479
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewProjectAction.java
@@ -0,0 +1,36 @@
+/*
+ * 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
new file mode 100755
index 0000000..c8e45ef
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewTestProjectAction.java
@@ -0,0 +1,34 @@
+/*
+ * 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
new file mode 100644
index 0000000..ba349c3
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/NewXmlFileAction.java
@@ -0,0 +1,36 @@
+/*
+ * 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
new file mode 100644
index 0000000..01280cc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/actions/OpenWizardAction.java
@@ -0,0 +1,178 @@
+/*
+ * 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/avdmanager/AvdManagerListPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/avdmanager/AvdManagerListPage.java
new file mode 100755
index 0000000..562e70f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/avdmanager/AvdManagerListPage.java
@@ -0,0 +1,631 @@
+/*
+ * 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.avdmanager;
+
+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.prefs.AndroidLocation;
+import com.android.prefs.AndroidLocation.AndroidLocationException;
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.ISdkLog;
+import com.android.sdklib.internal.avd.AvdManager;
+import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
+import com.android.sdkuilib.AvdSelector;
+import com.android.sdkuilib.AvdSelector.SelectionMode;
+
+import org.eclipse.core.resources.IProject;
+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.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;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.TreeMap;
+
+/**
+ * This is the single page of the {@link AvdManagerWizard} which provides the ability to display
+ * the AVDs and edit them quickly.
+ */
+class AvdManagerListPage extends WizardPage {
+
+    private AvdSelector mAvdSelector;
+    private Button mRefreshButton;
+    private Text mCreateName;
+    private Combo mCreateTargetCombo;
+    private Text mCreateSdCard;
+    private Combo mCreateSkinCombo;
+    private Button mCreateForce;
+    private Button mCreateButton;
+    private HashSet<String> mKnownAvdNames = new HashSet<String>();
+    private TreeMap<String, IAndroidTarget> mCurrentTargets = new TreeMap<String, IAndroidTarget>();
+    private ITargetChangeListener mSdkTargetChangeListener;
+
+    /**
+     * Constructs a new {@link AvdManagerListPage}.
+     * <p/>
+     * Called by {@link AvdManagerWizard#createMainPage()}.
+     */
+    protected AvdManagerListPage(String pageName) {
+        super(pageName);
+        setPageComplete(false);
+    }
+
+    /**
+     * 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(1, false /*makeColumnsEqualWidth*/));
+        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        createAvdGroup(composite);
+        createCreateGroup(composite);
+        registerSdkChangeListener();
+
+        // Show description the first time
+        setErrorMessage(null);
+        setMessage(null);
+        setControl(composite);
+
+        // Update state the first time
+        reloadAvdList();
+        reloadTargetCombo();
+        validatePage();
+    }
+
+    private void registerSdkChangeListener() {
+
+        mSdkTargetChangeListener = new ITargetChangeListener() {
+            public void onProjectTargetChange(IProject changedProject) {
+                // Ignore
+            }
+
+            public void onTargetsLoaded() {
+                // Update the AVD list, since the SDK change will influence the "good" avd list
+                reloadAvdList();
+                // Update the sdk target combo with the new targets
+                reloadTargetCombo();
+                validatePage();
+            }
+        };
+        AdtPlugin.getDefault().addTargetListener(mSdkTargetChangeListener);
+
+    }
+
+    @Override
+    public void dispose() {
+        if (mSdkTargetChangeListener != null) {
+            AdtPlugin.getDefault().removeTargetListener(mSdkTargetChangeListener);
+            mSdkTargetChangeListener = null;
+        }
+
+        super.dispose();
+    }
+
+    // --- UI creation ---
+
+    /**
+     * Creates the AVD selector and refresh & delete buttons.
+     */
+    private void createAvdGroup(Composite parent) {
+        final Composite grid2 = new Composite(parent, SWT.NONE);
+        grid2.setLayout(new GridLayout(2,  false /*makeColumnsEqualWidth*/));
+        grid2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        Label label = new Label(grid2, SWT.NONE);
+        label.setText("List of existing Android Virtual Devices:");
+        label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false));
+
+        mRefreshButton = new Button(grid2, SWT.PUSH);
+        mRefreshButton.setText("Refresh");
+        mRefreshButton.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
+        mRefreshButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                reloadAvdList();
+           }
+        });
+
+        mAvdSelector = new AvdSelector(parent,
+                SelectionMode.SELECT,
+                new AvdSelector.IExtraAction() {
+                    public String label() {
+                        return "Delete AVD...";
+                    }
+
+                    public boolean isEnabled() {
+                        return mAvdSelector != null && mAvdSelector.getSelected() != null;
+                    }
+
+                    public void run() {
+                        onDelete();
+                    }
+            });
+    }
+
+    /**
+     * Creates the "Create" group
+     */
+    private void createCreateGroup(Composite parent) {
+
+        Group grid = new Group(parent, SWT.SHADOW_ETCHED_IN);
+        grid.setLayout(new GridLayout(4,  false /*makeColumnsEqualWidth*/));
+        grid.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        grid.setFont(parent.getFont());
+        grid.setText("Create AVD");
+
+        // first line
+
+        Label label = new Label(grid, SWT.NONE);
+        label.setText("Name");
+
+        mCreateName = new Text(grid, SWT.BORDER);
+        mCreateName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mCreateName.addModifyListener(new CreateNameModifyListener());
+
+        label = new Label(grid, SWT.NONE);
+        label.setText("Target");
+
+        mCreateTargetCombo = new Combo(grid, SWT.READ_ONLY | SWT.DROP_DOWN);
+        mCreateTargetCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mCreateTargetCombo.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                super.widgetSelected(e);
+                reloadSkinCombo();
+                validatePage();
+            }
+        });
+
+        // second line
+
+        label = new Label(grid, SWT.NONE);
+        label.setText("SDCard");
+
+        ValidateListener validateListener = new ValidateListener();
+
+        mCreateSdCard = new Text(grid, SWT.BORDER);
+        mCreateSdCard.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mCreateSdCard.addModifyListener(validateListener);
+
+        label = new Label(grid, SWT.NONE);
+        label.setText("Skin");
+
+        mCreateSkinCombo = new Combo(grid, SWT.READ_ONLY | SWT.DROP_DOWN);
+        mCreateSkinCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        // dummies for alignment
+        label = new Label(grid, SWT.NONE);
+        label = new Label(grid, SWT.NONE);
+
+        mCreateForce = new Button(grid, SWT.CHECK);
+        mCreateForce.setText("Force");
+        mCreateForce.setEnabled(false);
+        mCreateForce.addSelectionListener(validateListener);
+
+        mCreateButton = new Button(grid, SWT.PUSH);
+        mCreateButton.setText("Create AVD");
+        mCreateButton.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
+        mCreateButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                super.widgetSelected(e);
+                onCreate();
+            }
+        });
+    }
+
+    /**
+     * 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 = mCreateName.getText().trim();
+            if (mKnownAvdNames.contains(name)) {
+                mCreateForce.setEnabled(true);
+            } else {
+                mCreateForce.setEnabled(false);
+                mCreateForce.setSelection(false);
+            }
+            validatePage();
+        }
+    }
+
+    private class ValidateListener extends SelectionAdapter implements ModifyListener {
+
+        public void modifyText(ModifyEvent e) {
+            validatePage();
+        }
+
+        @Override
+        public void widgetSelected(SelectionEvent e) {
+            super.widgetSelected(e);
+            validatePage();
+        }
+    }
+
+    private void reloadTargetCombo() {
+
+        String selected = null;
+        int index = mCreateTargetCombo.getSelectionIndex();
+        if (index >= 0) {
+            selected = mCreateTargetCombo.getItem(index);
+        }
+
+        mCurrentTargets.clear();
+        mCreateTargetCombo.removeAll();
+
+        boolean found = false;
+        index = -1;
+
+        Sdk sdk = Sdk.getCurrent();
+        if (sdk != null) {
+            for (IAndroidTarget target : sdk.getTargets()) {
+                String name = String.format("%s - %s",
+                        target.getName(),
+                        target.getApiVersionName());
+                mCurrentTargets.put(name, target);
+                mCreateTargetCombo.add(name);
+                if (!found) {
+                    index++;
+                    found = name.equals(selected);
+                }
+            }
+        }
+
+        mCreateTargetCombo.setEnabled(mCurrentTargets.size() > 0);
+
+        if (found) {
+            mCreateTargetCombo.select(index);
+        }
+
+        reloadSkinCombo();
+    }
+
+    private void reloadSkinCombo() {
+        String selected = null;
+        int index = mCreateSkinCombo.getSelectionIndex();
+        if (index >= 0) {
+            selected = mCreateSkinCombo.getItem(index);
+        }
+
+        mCreateSkinCombo.removeAll();
+        mCreateSkinCombo.setEnabled(false);
+
+        index = mCreateTargetCombo.getSelectionIndex();
+        if (index >= 0) {
+
+            String targetName = mCreateTargetCombo.getItem(index);
+
+            boolean found = false;
+            IAndroidTarget target = mCurrentTargets.get(targetName);
+            if (target != null) {
+                mCreateSkinCombo.add(String.format("Default (%s)", target.getDefaultSkin()));
+
+                index = -1;
+                for (String skin : target.getSkins()) {
+                    mCreateSkinCombo.add(skin);
+                    if (!found) {
+                        index++;
+                        found = skin.equals(selected);
+                    }
+                }
+
+                mCreateSkinCombo.setEnabled(true);
+
+                if (found) {
+                    mCreateSkinCombo.select(index);
+                } else {
+                    mCreateSkinCombo.select(0);  // default
+                }
+            }
+        }
+    }
+
+    /**
+     * Validates the fields, displays errors and warnings.
+     * Enables the finish button if there are no errors.
+     * <p/>
+     * Not really used here yet. Keep as a placeholder.
+     */
+    private void validatePage() {
+        String error = null;
+        String warning = null;
+
+
+        // Validate AVD name
+        String avdName = mCreateName.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. Allowed characters are: %2$s",
+                avdName, AvdManager.CHARS_AVD_NAME);
+        }
+
+        // Validate target
+        if (hasAvdName && error == null && mCreateTargetCombo.getSelectionIndex() < 0) {
+            error = "A target must be selected in order to create an AVD.";
+        }
+
+        // Validate SDCard path or value
+        if (error == null) {
+            String sdName = mCreateSdCard.getText().trim();
+
+            if (sdName.length() > 0 &&
+                    !new File(sdName).isFile() &&
+                    !AvdManager.SDCARD_SIZE_PATTERN.matcher(sdName).matches()) {
+                error = "SD Card must be either a file path or a size such as 128K or 64M.";
+            }
+        }
+
+        // Check for duplicate AVD name
+        if (hasAvdName && error == null) {
+            if (mKnownAvdNames.contains(avdName) && !mCreateForce.getSelection()) {
+                error = String.format(
+                        "The AVD name '%s' is already used. " +
+                        "Check \"Force\" if you really want to create a new AVD with that name and delete the previous one.",
+                        avdName);
+            }
+        }
+
+        // Validate the create button
+        boolean can_create = hasAvdName && error == null;
+        if (can_create) {
+            can_create &= mCreateTargetCombo.getSelectionIndex() >= 0;
+        }
+        mCreateButton.setEnabled(can_create);
+
+        // -- update UI
+        setPageComplete(true);
+        if (error != null) {
+            setMessage(error, WizardPage.ERROR);
+        } else if (warning != null) {
+            setMessage(warning, WizardPage.WARNING);
+        } else {
+            setErrorMessage(null);
+            setMessage(null);
+        }
+    }
+
+    /**
+     * Reloads the AVD list in the AVD selector.
+     * Tries to preserve the selection.
+     */
+    private void reloadAvdList() {
+        AvdInfo selected = mAvdSelector.getSelected();
+
+        AvdManager avdm = getAvdManager();
+        AvdInfo[] avds = null;
+
+        // For the AVD manager to reload the list, in case AVDs where created using the
+        // command line tool.
+        // The AVD manager may not exist yet, typically when loading the SDK.
+        if (avdm != null) {
+            try {
+                avdm.reloadAvds();
+            } catch (AndroidLocationException e) {
+                AdtPlugin.log(e, "AVD Manager reload failed");  //$NON-NLS-1$
+            }
+
+            avds = avdm.getValidAvds();
+        }
+
+        mAvdSelector.setAvds(avds, null /*filter*/);
+
+        // Keep the list of known AVD names to check if they exist quickly. however
+        // use the list of all AVDs, including broken ones (unless we don't know their
+        // name).
+        mKnownAvdNames.clear();
+        if (avdm != null) {
+            for (AvdInfo avd : avdm.getAllAvds()) {
+                String name = avd.getName();
+                if (name != null) {
+                    mKnownAvdNames.add(name);
+                }
+            }
+        }
+
+        mAvdSelector.setSelection(selected);
+    }
+
+    /**
+     * Triggered when the user selects the "delete" button (the extra action in the selector)
+     * Deletes the currently selected AVD, if any.
+     */
+    private void onDelete() {
+        AvdInfo avdInfo = mAvdSelector.getSelected();
+        AvdManager avdm = getAvdManager();
+        if (avdInfo == null || avdm == null) {
+            return;
+        }
+
+        // Confirm you want to delete this AVD
+        if (!AdtPlugin.displayPrompt("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()))) {
+            return;
+        }
+
+        SdkLog log = new SdkLog(String.format("Result of deleting AVD '%s':", avdInfo.getName()));
+
+        boolean success = avdm.deleteAvd(avdInfo, log);
+
+        log.display(success);
+        reloadAvdList();
+    }
+
+    /**
+     * Triggered when the user selects the "create" button.
+     */
+    private void onCreate() {
+        String avdName = mCreateName.getText().trim();
+        String sdName = mCreateSdCard.getText().trim();
+        int targetIndex = mCreateTargetCombo.getSelectionIndex();
+        int skinIndex = mCreateSkinCombo.getSelectionIndex();
+        boolean force = mCreateForce.getSelection();
+        AvdManager avdm = getAvdManager();
+
+        if (avdm == null ||
+                avdName.length() == 0 ||
+                targetIndex < 0) {
+            return;
+        }
+
+        String targetName = mCreateTargetCombo.getItem(targetIndex);
+        IAndroidTarget target = mCurrentTargets.get(targetName);
+        if (target == null) {
+            return;
+        }
+
+        String skinName = null;
+        if (skinIndex > 0) {
+            // index 0 is the default, we don't use it
+            skinName = mCreateSkinCombo.getItem(skinIndex);
+        }
+
+        SdkLog log = new SdkLog(String.format("Result of creating AVD '%s':", avdName));
+
+        File avdFolder;
+        try {
+            avdFolder = new File(
+                    AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD,
+                    avdName + AvdManager.AVD_FOLDER_EXTENSION);
+        } catch (AndroidLocationException e) {
+            AdtPlugin.logAndPrintError(e, null /*tag*/,
+                    "AndroidLocation.getFolder failed");  //$NON-NLS-1$
+            return;
+        }
+
+        ISdkLog oldLog = null;
+        boolean success = false;
+        try {
+            // Temporarily change the AvdManager's logger for ours, since the API no longer
+            // takes a logger argument.
+            // TODO revisit this later. See comments in AvdManager#mSdkLog.
+            oldLog = avdm.setSdkLog(log);
+
+            AvdInfo avdInfo = avdm.createAvd(
+                    avdFolder,
+                    avdName,
+                    target,
+                    skinName,
+                    sdName,
+                    null, // hardwareConfig,
+                    force);
+
+            success = avdInfo != null;
+
+        } finally {
+            avdm.setSdkLog(oldLog);
+        }
+
+        log.display(success);
+
+        if (success) {
+            // clear the name field on success
+            mCreateName.setText("");  //$NON-NLS-1$
+        }
+
+        reloadAvdList();
+    }
+
+    /**
+     * Collects all log from the AVD action and displays it in a dialog.
+     */
+    private class SdkLog implements ISdkLog {
+
+        final ArrayList<String> logMessages = new ArrayList<String>();
+        private final String mMessage;
+
+        public SdkLog(String message) {
+            mMessage = message;
+        }
+
+        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 display(boolean success) {
+            if (logMessages.size() > 0) {
+                StringBuilder sb = new StringBuilder(mMessage + "\n");
+                for (String msg : logMessages) {
+                    sb.append('\n');
+                    sb.append(msg);
+                }
+                if (success) {
+                    AdtPlugin.displayWarning("Android Virtual Devices Manager", sb.toString());
+                } else {
+                    AdtPlugin.displayError("Android Virtual Devices Manager", sb.toString());
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the current AVD Manager or null if none has been created yet.
+     * This can happen when the SDK hasn't finished loading or the manager failed to
+     * parse the AVD directory.
+     */
+    private AvdManager getAvdManager() {
+        Sdk sdk = Sdk.getCurrent();
+        if (sdk != null) {
+            return sdk.getAvdManager();
+        }
+        return null;
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/avdmanager/AvdManagerWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/avdmanager/AvdManagerWizard.java
new file mode 100755
index 0000000..d8f77cc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/avdmanager/AvdManagerWizard.java
@@ -0,0 +1,114 @@
+/*
+ * 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.avdmanager;
+
+import com.android.ide.eclipse.adt.internal.editors.IconFactory;
+import com.android.ide.eclipse.adt.internal.ui.IUpdateWizardDialog;
+import com.android.ide.eclipse.adt.internal.ui.WizardDialogEx;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+
+/**
+ * The "AVD Manager Wizard" provides a quick way to edit AVDs.
+ * <p/>
+ * The wizard has one page, {@link AvdManagerListPage}, used to display and edit the AVDs. 
+ * In fact the whole UI is not really a wizard. It has just been implemented that way
+ * to get something quick out of the door. We'll need to revisit this when we implement
+ * the final standalone AVD Manager UI and this Wizard will go away.
+ */
+public class AvdManagerWizard extends Wizard implements INewWizard, IUpdateWizardDialog {
+
+    private static final String PROJECT_LOGO_LARGE = "android_large"; //$NON-NLS-1$
+    
+    protected static final String MAIN_PAGE_NAME = "avdManagerListPage"; //$NON-NLS-1$
+
+    private AvdManagerListPage mMainPage;
+
+    public void init(IWorkbench workbench, IStructuredSelection selection) {
+        setHelpAvailable(false); // TODO have help
+        setWindowTitle("Android Virtual Devices Manager");
+        setImageDescriptor();
+
+        mMainPage = createMainPage();
+        mMainPage.setTitle("Android Virtual Devices Manager");
+        mMainPage.setDescription("Displays existing Android Virtual Devices. Lets you create new ones or delete existing ones.");
+    }
+    
+    /**
+     * 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 AvdManagerListPage createMainPage() {
+        return new AvdManagerListPage(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 does nothing.
+     *
+     * @return True
+     */
+    @Override
+    public boolean performFinish() {
+        return true;
+    }
+
+    /**
+     * Returns an image descriptor for the wizard logo.
+     */
+    private void setImageDescriptor() {
+        ImageDescriptor desc = IconFactory.getInstance().getImageDescriptor(PROJECT_LOGO_LARGE);
+        setDefaultPageImageDescriptor(desc);
+    }
+
+    /**
+     * Invoked once the dialog frame as been created.
+     * We use it to hide the cancel button, which looks odd here.
+     */
+    public void updateWizardDialog(WizardDialogEx dialog) {
+        Button cancel = dialog.getCancelButtonEx();
+        if (cancel != null) {
+            cancel.setVisible(false);
+        }
+    }
+
+}
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
new file mode 100644
index 0000000..834d5e8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ExportWizard.java
@@ -0,0 +1,570 @@
+/*
+ * 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.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 com.android.jarutils.DebugKeyProvider.KeytoolException;
+
+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.CoreException;
+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.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+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();
+                for (Entry<String, String[]> entry : set) {
+                    String[] defaultApk = entry.getValue();
+                    String srcFilename = defaultApk[APK_FILE_SOURCE];
+                    String destFilename = defaultApk[APK_FILE_DEST];
+
+                    FileOutputStream fos = new FileOutputStream(
+                            new File(mDestinationParentFolder, destFilename));
+                    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();
+                    } finally {
+                        try {
+                            fis.close();
+                        } finally {
+                            fos.close();
+                        }
+                    }
+                }
+                return true;
+            }
+        } catch (FileNotFoundException e) {
+            displayError(e);
+        } catch (NoSuchAlgorithmException e) {
+            displayError(e);
+        } catch (IOException e) {
+            displayError(e);
+        } catch (GeneralSecurityException e) {
+            displayError(e);
+        } catch (KeytoolException e) {
+            displayError(e);
+        } catch (CoreException e) {
+            displayError(e);
+        }
+
+        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(Exception e) {
+        String message = getExceptionMessage(e);
+        displayError(message);
+        
+        AdtPlugin.log(e, "Export Wizard Error");
+    }
+    
+    /**
+     * 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) {
+            Throwable cause = t.getCause();
+            if (cause != null) {
+                return getExceptionMessage(cause);
+            }
+
+            // no more cause and still no message. display the first exception.
+            return t.getClass().getCanonicalName();
+        }
+        
+        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
new file mode 100644
index 0000000..0f630c4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCheckPage.java
@@ -0,0 +1,443 @@
+/*
+ * 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 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;
+    /** The Apk Config map for the current project */
+    private Map<String, String> mApkConfig;
+    private ScrolledComposite mScrolledComposite;
+    
+    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();
+            mApkConfig = Sdk.getCurrent().getProjectApkConfigs(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 (mApkConfig != null && mApkConfig.size() > 0) {
+            // remove the extension.
+            int index = filename.lastIndexOf('.');
+            String base = filename.substring(0, index);
+            String extension = filename.substring(index);
+            
+            Set<Entry<String, String>> set = mApkConfig.entrySet();
+            for (Entry<String, String> entry : set) {
+                apkArray = new String[ExportWizard.APK_COUNT];
+                apkArray[ExportWizard.APK_FILE_SOURCE] = ProjectHelper.getApkFilename(
+                        mWizard.getProject(), entry.getKey());
+                apkArray[ExportWizard.APK_FILE_DEST] = base + "-" + 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
new file mode 100644
index 0000000..2bc72db
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeyCreationPage.java
@@ -0,0 +1,332 @@
+/*
+ * 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
new file mode 100644
index 0000000..131e009
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeySelectionPage.java
@@ -0,0 +1,266 @@
+/*
+ * 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
new file mode 100644
index 0000000..a02b7b0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/KeystoreSelectionPage.java
@@ -0,0 +1,260 @@
+/*
+ * 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
new file mode 100644
index 0000000..4b8cb69
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/export/ProjectCheckPage.java
@@ -0,0 +1,302 @@
+/*
+ * 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
new file mode 100644
index 0000000..cf0dc00
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectCreationPage.java
@@ -0,0 +1,1456 @@
+/*
+ * 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.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.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.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; False means Create From Existing would be
+     * the default.*/
+    private static final boolean INITIAL_CREATE_NEW_PROJECT = true;
+    /** 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 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;
+
+
+    /**
+     * 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 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();
+
+        // 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_NEW_PROJECT);
+
+        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();
+            }
+        });
+    }
+
+    /**
+     * 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 project location, depending on the Use Default Location check box. */
+    private String getProjectLocation() {
+        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();
+        }
+    }
+
+    /**
+     * 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 use_default = mInfo.useDefaultLocation();
+        boolean location_enabled = !is_new_project || !use_default;
+        boolean create_activity = mInfo.isCreateActivity();
+
+        mUseDefaultLocation.setEnabled(is_new_project);
+
+        mLocationLabel.setEnabled(location_enabled);
+        mLocationPathField.setEnabled(location_enabled);
+        mBrowseButton.setEnabled(location_enabled);
+
+        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) {
+        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;
+        }
+
+        try {
+            int version = Integer.parseInt(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.getApiVersionNumber() == version) {
+                return;
+            }
+
+            for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
+                if (target.getApiVersionNumber() == version) {
+                    mSdkTargetSelector.setSelection(target);
+                    break;
+                }
+            }
+        } catch (NumberFormatException e) {
+            // ignore
+        }
+    }
+
+    /**
+     * 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(Integer.toString(target.getApiVersionNumber()));
+            mInternalMinSdkVersionUpdate = false;
+        }
+    }
+
+    /**
+     * 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;
+        int minSdkVersion = AndroidManifestParser.INVALID_MIN_SDK;
+        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;
+                mProjectNameField.setText(activityName);
+                mInternalProjectNameUpdate = false;
+            }
+            if (mApplicationNameField.getText().length() == 0 ||
+                    !mApplicationNameModifiedByUser) {
+                mInternalApplicationNameUpdate = true;
+                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
+        boolean foundTarget = false;
+
+        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);
+            if (target != null) {
+                mSdkTargetSelector.setSelection(target);
+                foundTarget = true;
+            }
+        }
+
+        if (!foundTarget && minSdkVersion != AndroidManifestParser.INVALID_MIN_SDK) {
+            try {
+                for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
+                    if (target.getApiVersionNumber() == minSdkVersion) {
+                        mSdkTargetSelector.setSelection(target);
+                        foundTarget = true;
+                        break;
+                    }
+                }
+            } catch(NumberFormatException e) {
+                // ignore
+            }
+        }
+
+        if (!foundTarget) {
+            for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
+                if (projectLocation.startsWith(target.getLocation())) {
+                    mSdkTargetSelector.setSelection(target);
+                    foundTarget = true;
+                    break;
+                }
+            }
+        }
+
+        if (!foundTarget) {
+            mInternalMinSdkVersionUpdate = true;
+            mMinSdkVersionField.setText(
+                    minSdkVersion == AndroidManifestParser.INVALID_MIN_SDK ? ""  //$NON-NLS-1$
+                            : Integer.toString(minSdkVersion));
+            mInternalMinSdkVersionUpdate = false;
+        }
+    }
+
+    /**
+     * 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 |= validateLocationPath(workspace);
+        }
+        if ((status & MSG_ERROR) == 0) {
+            status |= validateSdkTarget();
+        }
+        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;
+        }
+
+        int version = AndroidManifestParser.INVALID_MIN_SDK;
+        try {
+            // If not empty, it must be a valid integer > 0
+            version = Integer.parseInt(mInfo.getMinSdkVersion());
+        } catch (NumberFormatException e) {
+            // ignore
+        }
+
+        if (version < 1) {
+            return setStatus("Min SDK Version must be an integer > 0.", MSG_ERROR);
+        }
+
+        if (mInfo.getSdkTarget() != null && mInfo.getSdkTarget().getApiVersionNumber() != version) {
+            return setStatus("The API level for the selected SDK target does not match the Min SDK version.",
+                    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
new file mode 100644
index 0000000..d8989c2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewProjectWizard.java
@@ -0,0 +1,1036 @@
+/*
+ * 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.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 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 ICON = "icon.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 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 {
+
+        // 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.
+        addDefaultDirectories(project, RES_DIRECTORY, RES_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, 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, (IAndroidTarget) parameters.get(PARAM_SDK_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 monitor An existing monitor.
+     * @throws CoreException if the method fails to update the project.
+     */
+    private void addIcon(IProject project, IProgressMonitor monitor)
+            throws CoreException {
+        IFile file = project.getFile(RES_DIRECTORY + AndroidConstants.WS_SEP
+                                     + DRAWABLE_DIRECTORY + AndroidConstants.WS_SEP + ICON);
+        if (!file.exists()) {
+            // read the content from the template
+            byte[] buffer = AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON);
+
+            // if valid
+            if (buffer != null) {
+                // Save in the project
+                InputStream stream = new ByteArrayInputStream(buffer);
+                file.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
new file mode 100755
index 0000000..d18c2ff
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectCreationPage.java
@@ -0,0 +1,1349 @@
+/*
+ * 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.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();
+                int 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;
+                    mMinSdkVersionField.setText(
+                            minSdkVersion != AndroidManifestParser.INVALID_MIN_SDK ?
+                                    Integer.toString(minSdkVersion) : "");        //$NON-NLS-1$
+                    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() {
+        try {
+            int version = Integer.parseInt(mInfo.getMinSdkVersion());
+
+            IAndroidTarget curr_target = mInfo.getSdkTarget();
+            if (curr_target != null && curr_target.getApiVersionNumber() == version) {
+                return;
+            }
+
+            for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
+                if (target.getApiVersionNumber() == version) {
+                    mSdkTargetSelector.setSelection(target);
+                    return;
+                }
+            }
+        } catch (NumberFormatException e) {
+            // ignore
+        }
+    }
+
+    /**
+     * 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(Integer.toString(target.getApiVersionNumber()));
+            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;
+        }
+
+        int version = AndroidManifestParser.INVALID_MIN_SDK;
+        try {
+            // If not empty, it must be a valid integer > 0
+            version = Integer.parseInt(mInfo.getMinSdkVersion());
+        } catch (NumberFormatException e) {
+            // ignore
+        }
+
+        if (version < 1) {
+            return setStatus("Min SDK Version must be an integer > 0.", MSG_ERROR);
+        }
+
+        if (mInfo.getSdkTarget() != null && mInfo.getSdkTarget().getApiVersionNumber() != version) {
+            return setStatus("The API level for the selected SDK target does not match the Min SDK version.",
+                    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
new file mode 100755
index 0000000..62bf9c1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newproject/NewTestProjectWizard.java
@@ -0,0 +1,30 @@
+/*
+ * 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
new file mode 100644
index 0000000..8c242c0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileCreationPage.java
@@ -0,0 +1,1231 @@
+/*
+ * 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);
+        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 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());
+        } 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());
+            }
+        }
+
+        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;
+            }
+
+            TypeInfo type = getSelectedType();
+            
+            if (type != null) {
+                mConfigSelector.getConfiguration(mTempConfig);
+                StringBuffer sb = new StringBuffer(RES_FOLDER_ABS);
+                sb.append(mTempConfig.getFolderName(type.getResFolderType()));
+                
+                mInternalWsFolderPathUpdate = true;
+                mWsFolderPathTextField.setText(sb.toString());
+                mInternalWsFolderPathUpdate = false;
+                
+                validatePage();
+            }
+        }
+    }
+
+    /**
+     * 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.getApiVersionNumber();
+        }
+        
+        for (TypeInfo type : sTypes) {
+            type.getWidget().setEnabled(type.getTargetApiLevel() <= currentApiLevel);
+        }
+    }
+
+    /**
+     * 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.getApiVersionNumber();
+            }
+
+            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
new file mode 100644
index 0000000..9f4a518
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java
@@ -0,0 +1,226 @@
+/*
+ * 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/launch/AMReceiver.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/AMReceiver.java
deleted file mode 100644
index 8fdcdf9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/ActivityLaunchAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/ActivityLaunchAction.java
deleted file mode 100644
index 1aa5a9a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/AndroidLaunch.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/AndroidLaunch.java
deleted file mode 100644
index 42927c2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/AndroidLaunchConfiguration.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/AndroidLaunchConfiguration.java
deleted file mode 100644
index b5ea727..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/AndroidLaunchController.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/AndroidLaunchController.java
deleted file mode 100644
index 04393c9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/AndroidLaunchController.java
+++ /dev/null
@@ -1,1640 +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.launch;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Client;
-import com.android.ddmlib.ClientData;
-import com.android.ddmlib.Device;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.MultiLineReceiver;
-import com.android.ddmlib.SyncService;
-import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
-import com.android.ddmlib.AndroidDebugBridge.IDebugBridgeChangeListener;
-import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
-import com.android.ddmlib.SyncService.SyncResult;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.launch.AndroidLaunchConfiguration.TargetMode;
-import com.android.ide.eclipse.adt.launch.DelayedLaunchInfo.InstallRetryMode;
-import com.android.ide.eclipse.adt.launch.DeviceChooserDialog.DeviceChooserResponse;
-import com.android.ide.eclipse.adt.project.ApkInstallManager;
-import com.android.ide.eclipse.adt.project.ProjectHelper;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkManager;
-import com.android.sdklib.avd.AvdManager;
-import com.android.sdklib.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 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;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * 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();
-    
-
-
-    /**
-     * 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 mSuccess = null;
-        
-        public InstallReceiver() {
-        }
-
-        @Override
-        public void processNewLines(String[] lines) {
-            for (String line : lines) {
-                if (line.length() > 0) {
-                    if (line.startsWith(SUCCESS_OUTPUT)) {
-                        mSuccess = null;
-                    } else {
-                        Matcher m = FAILURE_PATTERN.matcher(line);
-                        if (m.matches()) {
-                            mSuccess = m.group(1);
-                        }
-                    }
-                }
-            }
-        }
-
-        public boolean isCancelled() {
-            return false;
-        }
-
-        public String getSuccess() {
-            return mSuccess;
-        }
-    }
-
-
-    /** 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
-     * {@link AndroidManifestParser#INVALID_MIN_SDK} 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, int 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();
-        } 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
-                        String apiString = d.getProperty(SdkManager.PROP_VERSION_SDK);
-                        try {
-                            int apiNumber = Integer.parseInt(apiString);
-                            if (apiNumber >= projectTarget.getApiVersionNumber()) {
-                                // device is compatible with project
-                                compatibleRunningAvds.put(d, null);
-                                continue;
-                            }
-                        } catch (NumberFormatException e) {
-                            // do nothing, we'll consider it a non compatible device below.
-                        }
-                    }
-                    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[] avds = avdManager.getValidAvds();
-                AvdInfo defaultAvd = null;
-                for (AvdInfo avd : avds) {
-                    if (projectTarget.isCompatibleBaseFor(avd.getTarget())) {
-                        if (defaultAvd == null ||
-                                avd.getTarget().getApiVersionNumber() <
-                                    defaultAvd.getTarget().getApiVersionNumber()) {
-                            defaultAvd = avd;
-                        }
-                    }
-                }
-
-                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 {
-                    // FIXME: ask the user if he wants to create a AVD.
-                    // we found no compatible AVD.
-                    AdtPlugin.printErrorToConsole(project, String.format(
-                            "Failed to find an AVD compatible with target '%1$s'. Launch aborted.",
-                            projectTarget.getName()));
-                    stopLaunch(launchInfo);
-                    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);
-                }
-            }
-        });
-    }
-    
-    /**
-     * 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 deviceApiVersionName = device.getProperty(IDevice.PROP_BUILD_VERSION);
-            String value = device.getProperty(IDevice.PROP_BUILD_VERSION_NUMBER);
-            int deviceApiVersionNumber = AndroidManifestParser.INVALID_MIN_SDK;
-            try {
-                deviceApiVersionNumber = Integer.parseInt(value);
-            } catch (NumberFormatException e) {
-                // pass, we'll keep the deviceVersionNumber value at 0.
-            }
-            
-            if (launchInfo.getRequiredApiVersionNumber() == AndroidManifestParser.INVALID_MIN_SDK) {
-                // warn the 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 (deviceApiVersionName == null ||
-                        deviceApiVersionNumber == AndroidManifestParser.INVALID_MIN_SDK) {
-                    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)", deviceApiVersionNumber,
-                            deviceApiVersionName));
-                }
-            } else { // app requires a specific API level
-                if (deviceApiVersionName == null ||
-                        deviceApiVersionNumber == AndroidManifestParser.INVALID_MIN_SDK) {
-                    AdtPlugin.printToConsole(launchInfo.getProject(),
-                            "WARNING: Unknown device API version!");
-                } else if (deviceApiVersionNumber < launchInfo.getRequiredApiVersionNumber()) {
-                    String msg = String.format(
-                            "ERROR: Application requires API version %1$d. Device API version is %2$d (Android %3$s).",
-                            launchInfo.getRequiredApiVersionNumber(), deviceApiVersionNumber,
-                            deviceApiVersionName);
-                    AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg);
-                    
-                    // abort the launch
-                    return false;
-                }
-            }
-
-            // 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) {
-        SyncService sync = device.getSyncService();
-        if (sync != null) {
-            IPath path = launchInfo.getPackageFile().getLocation();
-            String message = String.format("Uploading %1$s onto device '%2$s'",
-                    path.lastSegment(), device.getSerialNumber());
-            AdtPlugin.printToConsole(launchInfo.getProject(), message);
-
-            String osLocalPath = path.toOSString();
-            String apkName = launchInfo.getPackageFile().getName();
-            String remotePath = "/data/local/tmp/" + apkName; //$NON-NLS-1$
-
-            SyncResult result = sync.pushFile(osLocalPath, remotePath,
-                    SyncService.getNullProgressMonitor());
-
-            if (result.getCode() != SyncService.RESULT_OK) {
-                String msg = String.format("Failed to upload %1$s on '%2$s': %3$s",
-                        apkName, device.getSerialNumber(), result.getMessage());
-                AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg);
-                return false;
-            }
-
-            // Now that the package is uploaded, we can install it properly.
-            // This will check that there isn't another apk declaring the same package, or
-            // that another install used a different key.
-            boolean installResult =  installPackage(launchInfo, remotePath, device);
-            
-            // now we delete the app we sync'ed
-            try {
-                device.executeShellCommand("rm " + remotePath, new MultiLineReceiver() { //$NON-NLS-1$
-                    @Override
-                    public void processNewLines(String[] lines) {
-                        // pass
-                    }
-                    public boolean isCancelled() {
-                        return false;
-                    }
-                });
-            } catch (IOException e) {
-                AdtPlugin.printErrorToConsole(launchInfo.getProject(), String.format(
-                        "Failed to delete temporary package: %1$s", e.getMessage()));
-                return false;
-            }
-            
-            // if the installation succeeded, we register it.
-            if (installResult) {
-                ApkInstallManager.getInstance().registerInstallation(
-                        launchInfo.getProject(), device);
-            }
-            
-            return installResult;
-        }
-
-        String msg = String.format(
-                "Failed to upload %1$s on device '%2$s': Unable to open sync connection!",
-                launchInfo.getPackageFile().getName(), device.getSerialNumber());
-        AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg);
-
-        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 that was pushed to a temporary location on the device.
-     * @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 {
-            String result = doInstall(launchInfo, remotePath, device, false /* 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) {
-            // do nothing, we'll return false
-        }
-        
-        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$
-            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 {
-        InstallReceiver receiver = new InstallReceiver();
-        try {
-            device.executeShellCommand("pm uninstall " + launchInfo.getPackageName(), //$NON-NLS-1$
-                    receiver);
-        } 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;
-        }
-        
-        return receiver.getSuccess();
-    }
-
-    /**
-     * 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 {
-        InstallReceiver receiver = new InstallReceiver();
-        try {
-            String cmd = String.format(
-                    reinstall ? "pm install -r \"%1$s\"" : "pm install \"%1$s\"", //$NON-NLS-1$ //$NON-NLS-2$
-                    remotePath); //$NON-NLS-1$ //$NON-NLS-2$
-            device.executeShellCommand(cmd, receiver);
-        } catch (IOException e) {
-            String msg = String.format(
-                    "Failed to install %1$s on device '%2$s': %3$s",
-                    launchInfo.getPackageFile().getName(), device.getSerialNumber(), 
-                    e.getMessage());
-            AdtPlugin.printErrorToConsole(launchInfo.getProject(), msg);
-            throw e;
-        }
-        
-        return receiver.getSuccess();
-    }
-    
-    /**
-     * 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(Device)
-     */
-    public void deviceConnected(Device 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(Device)
-     */
-    @SuppressWarnings("unchecked")
-    public void deviceDisconnected(Device 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(Device, int)
-     */
-    public void deviceChanged(Device 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_INTEREST}, {@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() == ClientData.DEBUGGER_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_INTEREST) == Client.CHANGE_DEBUGGER_INTEREST) {
-            ClientData clientData = client.getClientData();
-            String applicationName = client.getClientData().getClientDescription();
-            if (clientData.getDebuggerConnectionStatus() == ClientData.DEBUGGER_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 ouput 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/launch/DelayedLaunchInfo.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/DelayedLaunchInfo.java
deleted file mode 100644
index f3bd28a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/DelayedLaunchInfo.java
+++ /dev/null
@@ -1,245 +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.launch;
-
-import com.android.ddmlib.IDevice;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-
-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 ApiVersionNumber by the app. {@link AndroidManifestParser#INVALID_MIN_SDK} means
-     * no requirements */
-    private final int 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.
-     * {@link AndroidManifestParser#INVALID_MIN_SDK} 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, 
-            int 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 int 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/launch/DeviceChooserDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/DeviceChooserDialog.java
deleted file mode 100644
index 1bc07fe..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/DeviceChooserDialog.java
+++ /dev/null
@@ -1,742 +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.launch;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Client;
-import com.android.ddmlib.Device;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
-import com.android.ddmlib.Device.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.sdk.Sdk;
-import com.android.ide.eclipse.ddms.DdmsPlugin;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.avd.AvdManager;
-import com.android.sdklib.avd.AvdManager.AvdInfo;
-import com.android.sdkuilib.AvdSelector;
-
-import org.eclipse.jface.dialogs.Dialog;
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.preference.IPreferenceStore;
-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.Shell;
-import org.eclipse.swt.widgets.Table;
-
-import java.util.ArrayList;
-
-/**
- * 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 final static String PREFS_COL_SERIAL = "deviceChooser.serial"; //$NON-NLS-1$
-    private final static String PREFS_COL_STATE  = "deviceChooser.state"; //$NON-NLS-1$
-    private final static String PREFS_COL_AVD     = "deviceChooser.avd"; //$NON-NLS-1$
-    private final static String PREFS_COL_TARGET = "deviceChooser.target"; //$NON-NLS-1$
-    private final static String PREFS_COL_DEBUG  = "deviceChooser.debug"; //$NON-NLS-1$
-
-    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 final AvdInfo[] mFullAvdList;
-
-    private Button mDeviceRadioButton;
-
-    private boolean mDisableAvdSelectionChange = false;
-    
-    /**
-     * Basic Content Provider for a table full of {@link Device} 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 Device} objects.
-     */
-    private class LabelProvider implements ITableLabelProvider {
-
-        public Image getColumnImage(Object element, int columnIndex) {
-            if (element instanceof Device) {
-                Device device = (Device)element;
-                switch (columnIndex) {
-                    case 0:
-                        return device.isEmulator() ? mEmulatorImage : mDeviceImage;
-                        
-                    case 2:
-                        // check for compatibility.
-                        if (device.isEmulator() == false) { // physical device
-                            // get the api level of the device
-                            try {
-                                String apiValue = device.getProperty(
-                                        IDevice.PROP_BUILD_VERSION_NUMBER);
-                                if (apiValue != null) {
-                                    int api = Integer.parseInt(apiValue);
-                                    if (api >= mProjectTarget.getApiVersionNumber()) {
-                                        // if the project is compiling against an add-on, the optional
-                                        // API may be missing from the device.
-                                        return mProjectTarget.isPlatform() ?
-                                                mMatchImage : mWarningImage;
-                                    } else {
-                                        return mNoMatchImage;
-                                    }
-                                } else {
-                                    return mWarningImage;
-                                }
-                            } catch (NumberFormatException e) {
-                                // lets consider the device non compatible
-                                return mNoMatchImage;
-                            }
-                        } 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 Device) {
-                Device device = (Device)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();
-        
-        // get the full list of Android Virtual Devices
-        AvdManager avdManager = mSdk.getAvdManager();
-        if (avdManager != null) {
-            mFullAvdList = avdManager.getValidAvds();
-        } else {
-            mFullAvdList = null;
-        }
-
-        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) {
-        Composite top = new Composite(parent, SWT.NONE);
-        top.setLayout(new GridLayout(1, true));
-
-        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.getFirstSelected());
-                }
-                
-                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);
-
-        IPreferenceStore store = AdtPlugin.getDefault().getPreferenceStore(); 
-        mDeviceTable = new Table(offsetComp, SWT.SINGLE | SWT.FULL_SELECTION);
-        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$
-                PREFS_COL_SERIAL, store);
-
-        TableHelper.createTableColumn(mDeviceTable, "AVD Name",
-                SWT.LEFT, "engineering", //$NON-NLS-1$
-                PREFS_COL_AVD, store);
-
-        TableHelper.createTableColumn(mDeviceTable, "Target",
-                SWT.LEFT, "AAA+Android 9.9.9", //$NON-NLS-1$
-                PREFS_COL_TARGET, store);
-
-        TableHelper.createTableColumn(mDeviceTable, "Debug",
-                SWT.LEFT, "Debug", //$NON-NLS-1$
-                PREFS_COL_DEBUG, store);
-
-        TableHelper.createTableColumn(mDeviceTable, "State",
-                SWT.LEFT, "bootloader", //$NON-NLS-1$
-                PREFS_COL_STATE, 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, getNonRunningAvds(), mProjectTarget);
-        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.getFirstSelected());
-                    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();
-                }
-            }
-        });
-        
-        AndroidDebugBridge.addDeviceChangeListener(this);
-
-        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(Device 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(Device)
-     */
-    public void deviceConnected(Device 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();
-                } 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(Device)
-     */
-    public void deviceDisconnected(Device 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(Device, int)
-     */
-    public void deviceChanged(final Device device, int changeMask) {
-        if ((changeMask & (Device.CHANGE_STATE | Device.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();
-
-                        // 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 Device) {
-                handleSelection((Device)data);
-            } else {
-                handleSelection(null);
-            }
-        }
-    }
-
-    private void handleSelection(Device 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();
-            
-            Device[] devices = bridge.getDevices();
-            
-            for (Device 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();
-    }
-    
-    /**
-     * Returns the list of {@link AvdInfo} that are not already running in an emulator.
-     */
-    private AvdInfo[] getNonRunningAvds() {
-        ArrayList<AvdInfo> list = new ArrayList<AvdInfo>();
-        
-        Device[] devices = AndroidDebugBridge.getBridge().getDevices();
-        
-        // loop through all the Avd and put the one that are not running in the list.
-        avdLoop: for (AvdInfo info : mFullAvdList) {
-            for (Device d : devices) {
-                if (info.getName().equals(d.getAvdName())) {
-                    continue avdLoop;
-                }
-            }
-            list.add(info);
-        }
-        
-        return list.toArray(new AvdInfo[list.size()]);
-    } 
-    
-    /**
-     * Refills the AVD list keeping the current selection.
-     */
-    private void refillAvdList() {
-        AvdInfo[] array = getNonRunningAvds();
-        
-        // save the current selection
-        AvdInfo selected = mPreferredAvdSelector.getFirstSelected();
-        
-        // disable selection change.
-        mDisableAvdSelectionChange = true;
-        
-        // set the new list in the selector
-        mPreferredAvdSelector.setAvds(array, mProjectTarget);
-        
-        // 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/launch/EmptyLaunchAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/EmptyLaunchAction.java
deleted file mode 100644
index 02ae675..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/EmulatorConfigTab.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/EmulatorConfigTab.java
deleted file mode 100644
index bba7126..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/EmulatorConfigTab.java
+++ /dev/null
@@ -1,468 +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.launch;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.launch.AndroidLaunchConfiguration.TargetMode;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-import com.android.ide.eclipse.ddms.DdmsPlugin;
-import com.android.prefs.AndroidLocation.AndroidLocationException;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.avd.AvdManager;
-import com.android.sdklib.avd.AvdManager.AvdInfo;
-import com.android.sdkuilib.AvdSelector;
-
-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;
-
-    /**
-     * 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();
-        } 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:");
-        AvdInfo[] avds = new AvdInfo[0];
-        mPreferredAvdSelector = new AvdSelector(offsetComp, avds);
-        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$
-    }
-
-    /* (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
-        AvdInfo[] avds = null;
-        if (avdManager != null) {
-            avds = avdManager.getValidAvds();
-        }
-
-        IAndroidTarget projectTarget = null;
-        if (project != null) {
-            projectTarget = Sdk.getCurrent().getTarget(project);
-        } else {
-            avds = null; // no project? we don't want to display any "compatible" AVDs.
-        }
-        
-        mPreferredAvdSelector.setAvds(avds, projectTarget);
-
-        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.getFirstSelected();
-        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/launch/IAndroidLaunchAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/IAndroidLaunchAction.java
deleted file mode 100644
index 2f3cb89..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.launch;
-
-import com.android.ddmlib.IDevice;
-import com.android.ide.eclipse.adt.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/launch/ILaunchController.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/ILaunchController.java
deleted file mode 100644
index 2372c2d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/JUnitLaunchConfigDelegate.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/JUnitLaunchConfigDelegate.java
deleted file mode 100644
index 7a74309..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.launch;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.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/launch/LaunchConfigDelegate.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/LaunchConfigDelegate.java
deleted file mode 100644
index 4fa270e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.launch;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.launch.AndroidLaunchConfiguration.TargetMode;
-import com.android.ide.eclipse.adt.project.ProjectHelper;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-import com.android.ide.eclipse.common.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/launch/LaunchConfigTabGroup.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/LaunchConfigTabGroup.java
deleted file mode 100644
index f1dbd26..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/LaunchShortcut.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/LaunchShortcut.java
deleted file mode 100644
index 6b2744c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/MainLaunchConfigTab.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/MainLaunchConfigTab.java
deleted file mode 100644
index f2a30de..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.launch;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-import com.android.ide.eclipse.common.project.ProjectChooserHelper;
-import com.android.ide.eclipse.common.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/launch/junit/AndroidJUnitLaunchAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchAction.java
deleted file mode 100644
index 24ebe21..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.launch.junit;
-
-import com.android.ddmlib.IDevice;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.launch.DelayedLaunchInfo;
-import com.android.ide.eclipse.adt.launch.IAndroidLaunchAction;
-import com.android.ide.eclipse.adt.launch.junit.runtime.AndroidJUnitLaunchInfo;
-import com.android.ide.eclipse.adt.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/launch/junit/AndroidJUnitLaunchConfigDelegate.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchConfigDelegate.java
deleted file mode 100755
index 1906792..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.launch.junit;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.launch.AndroidLaunch;
-import com.android.ide.eclipse.adt.launch.AndroidLaunchConfiguration;
-import com.android.ide.eclipse.adt.launch.AndroidLaunchController;
-import com.android.ide.eclipse.adt.launch.IAndroidLaunchAction;
-import com.android.ide.eclipse.adt.launch.LaunchConfigDelegate;
-import com.android.ide.eclipse.adt.launch.junit.runtime.AndroidJUnitLaunchInfo;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-import com.android.ide.eclipse.common.project.AndroidManifestParser.Instrumentation;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-
-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/launch/junit/AndroidJUnitLaunchConfigurationTab.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchConfigurationTab.java
deleted file mode 100644
index 34e64e3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.launch.junit;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.launch.MainLaunchConfigTab;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-import com.android.ide.eclipse.common.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/launch/junit/AndroidJUnitLaunchShortcut.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitLaunchShortcut.java
deleted file mode 100755
index f06f7eb..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/junit/AndroidJUnitPropertyTester.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitPropertyTester.java
deleted file mode 100644
index eadafee..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/junit/AndroidJUnitTabGroup.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/AndroidJUnitTabGroup.java
deleted file mode 100644
index 3c82f57..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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.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/launch/junit/InstrumentationRunnerValidator.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/InstrumentationRunnerValidator.java
deleted file mode 100644
index 7ebbb09..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.launch.junit;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-import com.android.ide.eclipse.common.project.AndroidManifestParser.Instrumentation;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-
-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/launch/junit/runtime/AndroidJUnitLaunchInfo.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/AndroidJUnitLaunchInfo.java
deleted file mode 100644
index 8ac80ca..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/junit/runtime/AndroidTestReference.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/AndroidTestReference.java
deleted file mode 100644
index 9db3ef0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/junit/runtime/RemoteAdtTestRunner.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/RemoteAdtTestRunner.java
deleted file mode 100755
index 962d761..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/junit/runtime/TestCaseReference.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/TestCaseReference.java
deleted file mode 100644
index 1a0ee9a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/junit/runtime/TestCollector.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/TestCollector.java
deleted file mode 100644
index 2dc13a7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/launch/junit/runtime/TestSuiteReference.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/launch/junit/runtime/TestSuiteReference.java
deleted file mode 100644
index 797f27b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/messages.properties b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/messages.properties
index dfb0eb2..982bd84 100644
--- 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
@@ -13,4 +13,6 @@
 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: 
+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/src/com/android/ide/eclipse/adt/preferences/AndroidPreferencePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/AndroidPreferencePage.java
deleted file mode 100644
index 90ad13a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.preferences;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdkuilib.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/preferences/BuildPreferencePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/BuildPreferencePage.java
deleted file mode 100644
index e64c2f4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/preferences/LaunchPreferencePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/LaunchPreferencePage.java
deleted file mode 100644
index 8fd72c1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/preferences/Messages.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/Messages.java
deleted file mode 100644
index e0197b9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/Messages.java
+++ /dev/null
@@ -1,43 +0,0 @@
-
-package com.android.ide.eclipse.adt.preferences;
-
-import org.eclipse.osgi.util.NLS;
-
-public class Messages extends NLS {
-    private static final String BUNDLE_NAME = "com.android.ide.eclipse.adt.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/preferences/PreferenceInitializer.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/PreferenceInitializer.java
deleted file mode 100644
index 2b1fb66..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/project/AndroidNature.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/AndroidNature.java
deleted file mode 100644
index 9bcadaf..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.project;
-
-import com.android.ide.eclipse.adt.build.ApkBuilder;
-import com.android.ide.eclipse.adt.build.PreCompilerBuilder;
-import com.android.ide.eclipse.adt.build.ResourceManagerBuilder;
-import com.android.ide.eclipse.common.AndroidConstants;
-
-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/project/ApkInstallManager.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/ApkInstallManager.java
deleted file mode 100644
index 172c555..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/ApkInstallManager.java
+++ /dev/null
@@ -1,207 +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.project;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Device;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.AndroidDebugBridge.IDebugBridgeChangeListener;
-import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
-import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor;
-import com.android.ide.eclipse.editors.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(Device 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(Device device, int changeMask) {
-        // nothing to do.
-    }
-
-    /*
-     * Does nothing
-     * (non-Javadoc)
-     * @see com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener#deviceConnected(com.android.ddmlib.Device)
-     */
-    public void deviceConnected(Device 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/project/ConvertToAndroidAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/ConvertToAndroidAction.java
deleted file mode 100644
index ffb2535..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/ConvertToAndroidAction.java
+++ /dev/null
@@ -1,153 +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.project;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.AndroidConstants;
-
-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/project/ExportAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/ExportAction.java
deleted file mode 100644
index 3d7e929..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/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.project;
-
-import com.android.ide.eclipse.common.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/project/ExportWizardAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/ExportWizardAction.java
deleted file mode 100644
index 9ade490..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/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.project;
-
-import com.android.ide.eclipse.adt.project.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/project/FixLaunchConfig.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FixLaunchConfig.java
deleted file mode 100644
index 49bbd81..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.project;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.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/project/FixProjectAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FixProjectAction.java
deleted file mode 100644
index 3043818..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FixProjectAction.java
+++ /dev/null
@@ -1,136 +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.project;
-
-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/project/FolderDecorator.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FolderDecorator.java
deleted file mode 100644
index 59b2b06..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.project;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.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/project/ProjectHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/ProjectHelper.java
deleted file mode 100644
index e091b13..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/ProjectHelper.java
+++ /dev/null
@@ -1,753 +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.project;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-
-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;
-    }
-
-    /**
-     * 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/project/export/ExportWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ExportWizard.java
deleted file mode 100644
index 6ede10d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ExportWizard.java
+++ /dev/null
@@ -1,570 +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.project.export;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.project.ProjectHelper;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-import com.android.jarutils.KeystoreHelper;
-import com.android.jarutils.SignedJarBuilder;
-import com.android.jarutils.DebugKeyProvider.IKeyGenOutput;
-import com.android.jarutils.DebugKeyProvider.KeytoolException;
-
-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.CoreException;
-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.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.security.NoSuchAlgorithmException;
-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();
-                for (Entry<String, String[]> entry : set) {
-                    String[] defaultApk = entry.getValue();
-                    String srcFilename = defaultApk[APK_FILE_SOURCE];
-                    String destFilename = defaultApk[APK_FILE_DEST];
-
-                    FileOutputStream fos = new FileOutputStream(
-                            new File(mDestinationParentFolder, destFilename));
-                    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();
-                    } finally {
-                        try {
-                            fis.close();
-                        } finally {
-                            fos.close();
-                        }
-                    }
-                }
-                return true;
-            }
-        } catch (FileNotFoundException e) {
-            displayError(e);
-        } catch (NoSuchAlgorithmException e) {
-            displayError(e);
-        } catch (IOException e) {
-            displayError(e);
-        } catch (GeneralSecurityException e) {
-            displayError(e);
-        } catch (KeytoolException e) {
-            displayError(e);
-        } catch (CoreException e) {
-            displayError(e);
-        }
-
-        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(Exception e) {
-        String message = getExceptionMessage(e);
-        displayError(message);
-        
-        AdtPlugin.log(e, "Export Wizard Error");
-    }
-    
-    /**
-     * 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) {
-            Throwable cause = t.getCause();
-            if (cause != null) {
-                return getExceptionMessage(cause);
-            }
-
-            // no more cause and still no message. display the first exception.
-            return t.getClass().getCanonicalName();
-        }
-        
-        return message;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/KeyCheckPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/KeyCheckPage.java
deleted file mode 100644
index 7fd76e9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/KeyCheckPage.java
+++ /dev/null
@@ -1,443 +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.project.export;
-
-import com.android.ide.eclipse.adt.project.ProjectHelper;
-import com.android.ide.eclipse.adt.project.export.ExportWizard.ExportWizardPage;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-
-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;
-    /** The Apk Config map for the current project */
-    private Map<String, String> mApkConfig;
-    private ScrolledComposite mScrolledComposite;
-    
-    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();
-            mApkConfig = Sdk.getCurrent().getProjectApkConfigs(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 (mApkConfig != null && mApkConfig.size() > 0) {
-            // remove the extension.
-            int index = filename.lastIndexOf('.');
-            String base = filename.substring(0, index);
-            String extension = filename.substring(index);
-            
-            Set<Entry<String, String>> set = mApkConfig.entrySet();
-            for (Entry<String, String> entry : set) {
-                apkArray = new String[ExportWizard.APK_COUNT];
-                apkArray[ExportWizard.APK_FILE_SOURCE] = ProjectHelper.getApkFilename(
-                        mWizard.getProject(), entry.getKey());
-                apkArray[ExportWizard.APK_FILE_DEST] = base + "-" + 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/project/export/KeyCreationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/KeyCreationPage.java
deleted file mode 100644
index d7365f7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/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.project.export;
-
-import com.android.ide.eclipse.adt.project.ProjectHelper;
-import com.android.ide.eclipse.adt.project.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/project/export/KeySelectionPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/KeySelectionPage.java
deleted file mode 100644
index 2fcd757..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/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.project.export;
-
-import com.android.ide.eclipse.adt.project.ProjectHelper;
-import com.android.ide.eclipse.adt.project.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/project/export/KeystoreSelectionPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/KeystoreSelectionPage.java
deleted file mode 100644
index c5a4d47..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/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.project.export;
-
-import com.android.ide.eclipse.adt.project.ProjectHelper;
-import com.android.ide.eclipse.adt.project.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/project/export/ProjectCheckPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ProjectCheckPage.java
deleted file mode 100644
index 054a072..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/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.project.export;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.project.ProjectHelper;
-import com.android.ide.eclipse.adt.project.export.ExportWizard.ExportWizardPage;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-import com.android.ide.eclipse.common.project.ProjectChooserHelper;
-
-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/project/internal/AndroidClasspathContainer.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainer.java
deleted file mode 100644
index c7cb427..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/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.project.internal;
-
-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/project/internal/AndroidClasspathContainerInitializer.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java
deleted file mode 100644
index b1e79b7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java
+++ /dev/null
@@ -1,646 +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.project.internal;
-
-import com.android.ide.eclipse.adt.AdtConstants;
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.project.ProjectHelper;
-import com.android.ide.eclipse.adt.sdk.LoadStatus;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-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/project/properties/AndroidPropertyPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/properties/AndroidPropertyPage.java
deleted file mode 100644
index c9568b2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/properties/AndroidPropertyPage.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.project.properties;
-
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdkuilib.ApkConfigWidget;
-import com.android.sdkuilib.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;
-
-import java.util.Map;
-
-/**
- * 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;
-    private ApkConfigWidget mApkConfigWidget;
-
-    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);
-
-        l = new Label(top, SWT.SEPARATOR | SWT.HORIZONTAL);
-        l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-
-        l = new Label(top, SWT.NONE);
-        l.setText("Project APK Configurations");
-
-        mApkConfigWidget = new ApkConfigWidget(top);
-
-        // 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);
-            }
-            
-            // get the apk configurations
-            Map<String, String> configs = currentSdk.getProjectApkConfigs(mProject);
-            mApkConfigWidget.fillTable(configs);
-        }
-
-        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) {
-            currentSdk.setProject(mProject, mSelector.getSelected(),
-                    mApkConfigWidget.getApkConfigs());
-        }
-        
-        return true;
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringAction.java
deleted file mode 100644
index 4ef1268..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringAction.java
+++ /dev/null
@@ -1,170 +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.refactorings.extractstring;
-
-import com.android.ide.eclipse.common.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 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) {
-                mFile = getSelectedFile();
-            }
-        }
-
-        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, 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 {@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() {
-        IWorkbenchWindow wwin = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-        if (wwin != null) {
-            IWorkbenchPage page = wwin.getActivePage();
-            if (page != null) {
-                IEditorPart editor = page.getActiveEditor();
-                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/refactorings/extractstring/ExtractStringContribution.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringContribution.java
deleted file mode 100644
index 465e1a3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/refactorings/extractstring/ExtractStringDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringDescriptor.java
deleted file mode 100644
index 6e999e9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/refactorings/extractstring/ExtractStringInputPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringInputPage.java
deleted file mode 100644
index 7303b02..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringInputPage.java
+++ /dev/null
@@ -1,504 +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.refactorings.extractstring;
-
-
-import com.android.ide.eclipse.adt.ui.ConfigurationSelector;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.editors.resources.manager.ResourceFolderType;
-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.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.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;
-
-    /** Test field where the user enters the new ID to be generated or replaced with. */ 
-    private Text mStringIdField;
-    /** 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();
-        
-        final Text stringValueField = new Text(group, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-        stringValueField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        stringValueField.setText(selectedString != null ? selectedString : "");  //$NON-NLS-1$
-        
-        ref.setNewStringValue(stringValueField.getText());
-
-        stringValueField.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                if (validatePage()) {
-                    ref.setNewStringValue(stringValueField.getText());
-                }
-            }
-        });
-
-        
-        // 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.");
-        }
-
-        mStringIdField = new Text(group, SWT.SINGLE | SWT.LEFT | SWT.BORDER);
-        mStringIdField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        mStringIdField.setText(guessId(selectedString));
-
-        ref.setNewStringId(mStringIdField.getText().trim());
-
-        mStringIdField.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                if (validatePage()) {
-                    ref.setNewStringId(mStringIdField.getText().trim());
-                }
-            }
-        });
-    }
-
-    /**
-     * 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);
-        GridData gd = new GridData(2, GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
-        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)}.
-     * 
-     * @return True if the page has been positively validated. It may still have warnings.
-     */
-    private boolean validatePage() {
-        boolean success = true;
-
-        // Analyze fatal errors.
-        
-        String text = mStringIdField.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;
-                }
-            }
-        }
-
-        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);
-
-            ExtractStringRefactoring ref = getOurRefactoring();
-
-            ref.setTargetFile(resFile);
-            sLastResFilePath.put(mProject.getFullPath().toPortableString(), resFile);
-
-            if (mXmlHelper.isResIdDuplicate(mProject, resFile, text)) {
-                String msg = String.format("There's already a string item called '%1$s' in %2$s.",
-                        text, resFile);
-                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);
-            }
-        }
-
-        setPageComplete(success);
-        return success;
-    }
-
-    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));
-            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
-            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;
-                    }
-                }
-            }
-
-            validatePage();
-        }
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringRefactoring.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringRefactoring.java
deleted file mode 100644
index 8a38e52..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringRefactoring.java
+++ /dev/null
@@ -1,988 +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.refactorings.extractstring;
-
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-
-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.ASTVisitor;
-import org.eclipse.jdt.core.dom.CompilationUnit;
-import org.eclipse.jdt.core.dom.Name;
-import org.eclipse.jdt.core.dom.QualifiedName;
-import org.eclipse.jdt.core.dom.SimpleName;
-import org.eclipse.jdt.core.dom.StringLiteral;
-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 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.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> TODO: to support refactoring from an XML file, the action should give the {@link IFile}
- *      and then here we would have to determine whether it's a suitable Android XML file or a
- *      suitable Java file.
- *      TODO: enumerate the exact valid contexts in Android XML files, e.g. attributes in layout
- *      files or text elements (e.g. <string>foo</string>) for values, etc. 
- * <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#isResIdDuplicate(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: If the source is an XML file, determine if we need to change an attribute or a
- *      a text element.
- * <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;
-    /** The file model being manipulated.
-     * Value is null when not on {@link Mode#EDIT_SOURCE} mode. */
-    private final IFile mFile;
-    /** 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$
-
-    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);
-        } else {
-            mFile = null;
-            mSelectionStart = mSelectionEnd = -1;
-            mTokenString = 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);
-        }
-        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 selection The selection in the source file. Cannot be null or empty.
-     */
-    public ExtractStringRefactoring(IFile file, ITextSelection selection) {
-        mMode = Mode.EDIT_SOURCE;
-        mFile = file;
-        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;
-        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...", 5);
-
-            if (mMode != Mode.EDIT_SOURCE) {
-                monitor.worked(5);
-                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) {
-                // Check this an XML file and get the selection and its context.
-                // TODO
-                status.addFatalError("Selection must be inside a Java source 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.
-     */
-    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 of 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();
-    }
-
-    /**
-     * 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.isResIdDuplicate(mProject, mTargetXmlFileWsPath, mXmlStringId)) {
-                // 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) {
-                // Prepare the change to the Java compilation unit
-                List<Change> 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 have 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 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.getFullPath(), 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.
-            
-            if (changes.size() > 0) {
-                return changes;
-            }
-
-            subMonitor.worked(1);
-
-        } catch (CoreException e) {
-            // ImportRewrite.rewriteImports failed.
-            status.addFatalError(e.getMessage());
-        }
-        return null;
-    }
-
-    public class ReplaceStringsVisitor extends ASTVisitor {
-
-        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;
-        }
-
-        @Override
-        public boolean visit(StringLiteral node) {
-            if (node.getLiteralValue().equals(mOldString)) {
-                
-                Name qualifierName = mAst.newName(mRQualifier + ".string"); //$NON-NLS-1$
-                SimpleName idName = mAst.newSimpleName(mXmlId);
-                QualifiedName newNode = mAst.newQualifiedName(qualifierName, idName);
-                
-                TextEditGroup editGroup = new TextEditGroup("Replace string by ID");                
-                mEditGroups.add(editGroup);
-                mRewriter.replace(node, newNode, editGroup);
-            }
-            return super.visit(node);
-        }
-    }
-
-    /**
-     * 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/refactorings/extractstring/ExtractStringWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/ExtractStringWizard.java
deleted file mode 100644
index cfcc546..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/refactorings/extractstring/XmlStringFileHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/XmlStringFileHelper.java
deleted file mode 100644
index 6c8bbdb..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/refactorings/extractstring/XmlStringFileHelper.java
+++ /dev/null
@@ -1,122 +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.refactorings.extractstring;
-
-import com.android.ide.eclipse.common.project.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.NodeList;
-import org.xml.sax.InputSource;
-
-import java.util.HashMap;
-import java.util.HashSet;
-
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-
-/**
- * 
- */
-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. */
-    private HashMap<String,HashSet<String>> mResIdCache;
-    /** An instance of XPath, created lazily on demand. */
-    private XPath mXPath;
-
-    public XmlStringFileHelper() {
-    }
-    
-    /**
-     * Utility method used by the wizard to check whether the given string ID is already
-     * defined in the XML file which path is given.
-     * 
-     * @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 True if such a string ID is already defined.
-     */
-    public boolean isResIdDuplicate(IProject project, String xmlFileWsPath, String stringId) {
-        // This is going to be called many times on the same file.
-        // Build a cache of the existing IDs for a given file.
-        if (mResIdCache == null) {
-            mResIdCache = new HashMap<String, HashSet<String>>();
-        }
-        HashSet<String> cache = mResIdCache.get(xmlFileWsPath);
-        if (cache == null) {
-            cache = getResIdsForFile(project, xmlFileWsPath);
-            mResIdCache.put(xmlFileWsPath, cache);
-        }
-        
-        return cache.contains(stringId);
-    }
-
-    /**
-     * 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 set of all string IDs defined in the file. The returned set is always non
-     *   null. It is empty if the file does not exist.
-     */
-    private HashSet<String> getResIdsForFile(IProject project, String xmlFileWsPath) {
-        HashSet<String> ids = new HashSet<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/@name";   //$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--) {
-                        String id = list.item(n).getNodeValue();
-                        ids.add(id);
-                    }
-                }
-                
-            } catch (CoreException e1) {
-                // IFile.getContents failed. Ignore.
-            } catch (XPathExpressionException e) {
-                // mXPath.evaluate failed. Ignore.
-            }
-        }
-        
-        return ids;
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidJarLoader.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidJarLoader.java
deleted file mode 100644
index 1f6ebf1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.sdk;
-
-import com.android.ide.eclipse.common.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/sdk/AndroidTargetData.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetData.java
deleted file mode 100644
index 34391c2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetData.java
+++ /dev/null
@@ -1,321 +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.sdk;
-
-import com.android.ide.eclipse.adt.build.DexWrapper;
-import com.android.ide.eclipse.common.resources.IResourceRepository;
-import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.editors.layout.descriptors.LayoutDescriptors;
-import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.editors.menu.descriptors.MenuDescriptors;
-import com.android.ide.eclipse.editors.resources.descriptors.ResourcesDescriptors;
-import com.android.ide.eclipse.editors.resources.manager.ProjectResources;
-import com.android.ide.eclipse.editors.xml.descriptors.XmlDescriptors;
-import com.android.layoutlib.api.ILayoutBridge;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
-
-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 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,
-            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(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(IOptionalLibrary[] optionalLibraries) {
-        String[] values;
-        
-        if (optionalLibraries == null) {
-            values = new String[0];
-        } else {
-            values = new String[optionalLibraries.length];
-            for (int i = 0; i < optionalLibraries.length; i++) {
-                values[i] = optionalLibraries[i].getName();
-            }
-        }
-        setValues("(uses-library,android:name)", values);
-    }
-
-    /**
-     * 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/sdk/AndroidTargetParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetParser.java
deleted file mode 100644
index 67eec78..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.sdk;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.build.DexWrapper;
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData.LayoutBridge;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.resources.AttrsXmlParser;
-import com.android.ide.eclipse.common.resources.DeclareStyleableInfo;
-import com.android.ide.eclipse.common.resources.IResourceRepository;
-import com.android.ide.eclipse.common.resources.ResourceItem;
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.common.resources.ViewClassInfo;
-import com.android.ide.eclipse.editors.layout.descriptors.LayoutDescriptors;
-import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.editors.menu.descriptors.MenuDescriptors;
-import com.android.ide.eclipse.editors.resources.manager.ProjectResources;
-import com.android.ide.eclipse.editors.resources.manager.ResourceManager;
-import com.android.ide.eclipse.editors.xml.descriptors.XmlDescriptors;
-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.getApiVersionNumber() >= 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.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/sdk/FrameworkResourceRepository.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/FrameworkResourceRepository.java
deleted file mode 100644
index f4b10df..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.sdk;
-
-import com.android.ide.eclipse.common.resources.IResourceRepository;
-import com.android.ide.eclipse.common.resources.ResourceItem;
-import com.android.ide.eclipse.common.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/sdk/IAndroidClassLoader.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/IAndroidClassLoader.java
deleted file mode 100644
index 35057d1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/sdk/LayoutParamsParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/LayoutParamsParser.java
deleted file mode 100644
index 19ef16c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.sdk;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.IAndroidClassLoader.IClassDescriptor;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.resources.AttrsXmlParser;
-import com.android.ide.eclipse.common.resources.ViewClassInfo;
-import com.android.ide.eclipse.common.resources.ViewClassInfo.LayoutParamsInfo;
-
-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/sdk/LoadStatus.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/LoadStatus.java
deleted file mode 100644
index 6bf0272..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/sdk/Sdk.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java
deleted file mode 100644
index 40b3f76..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java
+++ /dev/null
@@ -1,492 +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.sdk;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer;
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData.LayoutBridge;
-import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor;
-import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener;
-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.avd.AvdManager;
-import com.android.sdklib.project.ApkConfigurationHelper;
-import com.android.sdklib.project.ProjectProperties;
-import com.android.sdklib.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, Map<String, String>> mProjectApkConfigMap =
-        new HashMap<IProject, Map<String, String>>();
-    private final String mDocBaseUrl;
-    
-    /**
-     * 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,
-            Map<String, String> apkConfigMap) {
-        synchronized (mProjectTargetMap) {
-            boolean resolveProject = false;
-            boolean compileProject = false;
-            boolean cleanProject = 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 (apkConfigMap != null) {
-                // save the apk configs in the project persistent property
-                cleanProject = ApkConfigurationHelper.setConfigs(properties, apkConfigMap);
-
-                // put it in a local map for easy access.
-                mProjectApkConfigMap.put(project, apkConfigMap);
-                
-                compileProject = true;
-            }
-
-            // 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.
-                IJavaProject javaProject = JavaCore.create(project);
-                AndroidClasspathContainerInitializer.updateProjects(
-                        new IJavaProject[] { javaProject });
-            } else if (compileProject) {
-                // If there was removed configs, we clean instead of build
-                // (to remove the obsolete ap_ and apk file from removed configs).
-                try {
-                    project.build(cleanProject ?
-                                IncrementalProjectBuilder.CLEAN_BUILD :
-                                IncrementalProjectBuilder.FULL_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 (mProjectTargetMap) {
-            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) {
-            Map<String, String> configMap = ApkConfigurationHelper.getConfigs(properties);
-            
-            if (configMap != null) {
-                sdkStorage.mProjectApkConfigMap.put(project, configMap);
-            }
-        }
-        
-        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 (mTargetDataMap) {
-            return mTargetDataMap.get(target);
-        }
-    }
-    
-    /**
-     * Returns the configuration map for a given project.
-     * <p/>The Map key are name to be used in the apk filename, while the values are comma separated
-     * config values. The config value can be passed directly to aapt through the -c option.
-     */
-    public Map<String, String> getProjectApkConfigs(IProject project) {
-        return mProjectApkConfigMap.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;
-    }
-    
-    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);
-    }
-
-    /**
-     *  Cleans and unloads the SDK.
-     */
-    private void dispose() {
-        ResourceMonitor.getMonitor().removeProjectListener(this);
-    }
-    
-    void setTargetData(IAndroidTarget target, AndroidTargetData data) {
-        synchronized (mTargetDataMap) {
-            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;
-    }
-
-    public void projectClosed(IProject project) {
-        // get the target project
-        synchronized (mProjectTargetMap) {
-            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);
-            mProjectApkConfigMap.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/sdk/WidgetClassLoader.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/WidgetClassLoader.java
deleted file mode 100644
index 0e60f8a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.sdk;
-
-import com.android.ide.eclipse.common.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/ui/ConfigurationSelector.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/ui/ConfigurationSelector.java
deleted file mode 100644
index 651d1e0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/ui/ConfigurationSelector.java
+++ /dev/null
@@ -1,1278 +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.ui;
-
-import com.android.ide.eclipse.editors.resources.configurations.CountryCodeQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.editors.resources.configurations.KeyboardStateQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.LanguageQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.NavigationMethodQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.NetworkCodeQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.PixelDensityQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.RegionQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.ResourceQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.ScreenDimensionQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.ScreenOrientationQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.TextInputMethodQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.TouchScreenQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.KeyboardStateQualifier.KeyboardState;
-import com.android.ide.eclipse.editors.resources.configurations.NavigationMethodQualifier.NavigationMethod;
-import com.android.ide.eclipse.editors.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
-import com.android.ide.eclipse.editors.resources.configurations.TextInputMethodQualifier.TextInputMethod;
-import com.android.ide.eclipse.editors.resources.configurations.TouchScreenQualifier.TouchScreenType;
-import com.android.ide.eclipse.editors.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.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 Composite mQualifierEditParent;
-    
-    /**
-     * 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;
-    }
-
-    public ConfigurationSelector(Composite parent) {
-        super(parent, SWT.NONE);
-
-        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(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));
-    }
-    
-    /**
-     * 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 static class QualifierContentProvider implements IStructuredContentProvider {
-        
-        private FolderConfiguration mInput;
-
-        public QualifierContentProvider() {
-        }
-
-        public void dispose() {
-            // pass
-        }
-
-        public Object[] getElements(Object inputElement) {
-            return mInput.getQualifiers();
-        }
-
-        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 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 Text mText;
-
-        public PixelDensityEdit(Composite parent) {
-            super(parent, PixelDensityQualifier.NAME);
-            
-            mText = new Text(this, SWT.BORDER);
-            mText.addVerifyListener(new DensityVerifier());
-            mText.addModifyListener(new ModifyListener() {
-                public void modifyText(ModifyEvent e) {
-                    onTextChange();
-                }
-            });
-            mText.addFocusListener(new FocusAdapter() {
-                @Override
-                public void focusLost(FocusEvent e) {
-                    onTextChange();
-                }
-            });
-        }
-        
-        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.setPixelDensityQualifier(new PixelDensityQualifier());
-            } else {
-                try {
-                    PixelDensityQualifier qualifier = PixelDensityQualifier.getQualifier(
-                            PixelDensityQualifier.getFolderSegment(Integer.parseInt(value)));
-                    if (qualifier != null) {
-                        mSelectedConfiguration.setPixelDensityQualifier(qualifier);
-                    } else {
-                        // Failure! Looks like the value is wrong
-                        // (for instance a one letter string).
-                        // We do nothing in this case.
-                        return;
-                    }
-                } 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.
-                    // We do nothing in this case.
-                    return;
-                }
-            }
-   
-            // notify of change
-            onChange(true /* keepSelection */);
-        } 
-
-        @Override
-        public void setQualifier(ResourceQualifier qualifier) {
-            PixelDensityQualifier q = (PixelDensityQualifier)qualifier;
-            
-            mText.setText(Integer.toString(q.getValue()));
-        }
-    }
-
-    /**
-     * 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()));
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/ui/EclipseUiHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/ui/EclipseUiHelper.java
deleted file mode 100644
index 55878bf..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/ui/ReferenceChooserDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/ui/ReferenceChooserDialog.java
deleted file mode 100644
index 966c5c8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.ui;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.refactorings.extractstring.ExtractStringRefactoring;
-import com.android.ide.eclipse.adt.refactorings.extractstring.ExtractStringWizard;
-import com.android.ide.eclipse.common.resources.IResourceRepository;
-import com.android.ide.eclipse.common.resources.ResourceItem;
-import com.android.ide.eclipse.common.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/ui/ResourceChooser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/ui/ResourceChooser.java
deleted file mode 100644
index d7eeb04..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.ui;
-
-import com.android.ide.eclipse.adt.refactorings.extractstring.ExtractStringRefactoring;
-import com.android.ide.eclipse.adt.refactorings.extractstring.ExtractStringWizard;
-import com.android.ide.eclipse.common.resources.IResourceRepository;
-import com.android.ide.eclipse.common.resources.ResourceItem;
-import com.android.ide.eclipse.common.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/ui/ResourceContentProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/ui/ResourceContentProvider.java
deleted file mode 100644
index 3792fe3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.ui;
-
-import com.android.ide.eclipse.common.resources.IResourceRepository;
-import com.android.ide.eclipse.common.resources.ResourceItem;
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.resources.manager.ConfigurableResourceItem;
-import com.android.ide.eclipse.editors.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/ui/ResourceLabelProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/ui/ResourceLabelProvider.java
deleted file mode 100644
index f7c2634..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.ui;
-
-import com.android.ide.eclipse.common.resources.IIdResourceItem;
-import com.android.ide.eclipse.common.resources.ResourceItem;
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.resources.manager.ConfigurableResourceItem;
-import com.android.ide.eclipse.editors.resources.manager.IdResourceItem;
-import com.android.ide.eclipse.editors.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/wizards/actions/NewProjectAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewProjectAction.java
deleted file mode 100644
index e0d0d5e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewProjectAction.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.wizards.actions;
-
-import com.android.ide.eclipse.adt.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.
- */
-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/wizards/actions/NewXmlFileAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewXmlFileAction.java
deleted file mode 100644
index d1530d4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewXmlFileAction.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.wizards.actions;
-
-import com.android.ide.eclipse.adt.wizards.newxmlfile.NewXmlFileWizard;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.ui.IWorkbenchWizard;
-
-/**
- * Delegate for the toolbar action "Android Project".
- * 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/wizards/actions/NewXmlFileWizardAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewXmlFileWizardAction.java
deleted file mode 100644
index 20cfc82..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewXmlFileWizardAction.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.wizards.actions;
-
-import com.android.ide.eclipse.adt.wizards.newxmlfile.NewXmlFileWizard;
-
-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 NewXmlFileWizardAction 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 new xml file wizard on the current selection.
-            NewXmlFileWizard wizard = new NewXmlFileWizard();
-            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/wizards/actions/OpenWizardAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/OpenWizardAction.java
deleted file mode 100644
index 4fc9dee..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/OpenWizardAction.java
+++ /dev/null
@@ -1,139 +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.wizards.actions;
-
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.wizard.WizardDialog;
-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.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 {
-
-    /**
-     * 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;
-
-    
-    /* (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()}.
-     * 
-     * @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 = 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 = 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
-        IWorkbenchWizard wizard = instanciateWizard(action);
-        wizard.init(workbench, selectionToPass);
-        
-        // It's not visible yet until a dialog is created and opened
-        Shell parent = window.getShell();
-        WizardDialog dialog = new WizardDialog(parent, wizard);
-        dialog.create();
-        
-        // 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);
-        
-        dialog.open();
-    }
-
-    /**
-     * Called by {@link #run(IAction)} to instantiate the actual wizard.
-     * 
-     * @param action The action parameter from {@link #run(IAction)}.
-     * @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) {
-        // pass
-    }
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectCreationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectCreationPage.java
deleted file mode 100644
index 20aa68b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectCreationPage.java
+++ /dev/null
@@ -1,1372 +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.wizards.newproject;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-import com.android.ide.eclipse.common.project.AndroidManifestParser.Activity;
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.project.ProjectProperties;
-import com.android.sdklib.project.ProjectProperties.PropertyType;
-import com.android.sdkuilib.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.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.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
-    /** 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; False means Create From Existing would be
-     * the default.*/
-    private static final boolean INITIAL_CREATE_NEW_PROJECT = true;
-    /** 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;
-    
-    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 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;
-    protected boolean mInternalProjectNameUpdate;
-    protected boolean mInternalApplicationNameUpdate;
-    private boolean mInternalCreateActivityUpdate;
-    private boolean mInternalActivityNameUpdate;
-    protected boolean mProjectNameModifiedByUser;
-    protected boolean mApplicationNameModifiedByUser;
-    private boolean mInternalMinSdkVersionUpdate;
-    private boolean mMinSdkVersionModifiedByUser;
-
-
-    /**
-     * Creates a new project creation wizard page.
-     *
-     * @param pageName the name of this page
-     */
-    public NewProjectCreationPage(String pageName) {
-        super(pageName);
-        setPageComplete(false);
-    }
-
-    // --- Getters used by NewProjectWizard ---
-
-    /**
-     * 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();
-    }
-
-    /** 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 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();
-    }
-
-    /**
-     * 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();
-        }
-    }
-
-    // --- 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();
-
-        // Show description the first time
-        setErrorMessage(null);
-        setMessage(null);
-        setControl(composite);
-
-        // Validate. This will complain about the first empty field.
-        setPageComplete(validatePage());
-    }
-    
-    @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_BOTH));
-        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_NEW_PROJECT);
-
-        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();
-                setPageComplete(validatePage());
-            }
-        };
-
-        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(4, /* num columns */
-                false /* columns of not equal size */));
-        location_group.setLayoutData(new GridData(GridData.FILL_BOTH));
-        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 */
-                2,     /* 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) {
-                openDirectoryBrowser();
-            }
-        });
-    }
-
-    /**
-     * 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);
-                setPageComplete(validatePage());
-            }
-        });
-    }
-
-    /**
-     * Display a directory browser and update the location path field with the selected path
-     */
-    private void openDirectoryBrowser() {
-
-        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();
-            setPageComplete(validatePage());
-        }
-    }
-
-    /**
-     * 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();
-                setPageComplete(validatePage());
-            }
-        });
-    }
-
-
-    //--- Internal getters & setters ------------------
-
-    /** Returns the location path field value with spaces trimmed. */
-    private String getLocationPathFieldValue() {
-        return mLocationPathField == null ? "" : mLocationPathField.getText().trim();
-    }
-
-    /** Returns the current project location, depending on the Use Default Location check box. */
-    public String getProjectLocation() {
-        if (isNewProject() && 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(getProjectName());
-    }
-
-    // --- UI Callbacks ----
-
-    /**
-     * 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 = isNewProject();
-        boolean use_default = useDefaultLocation();
-        boolean location_enabled = !is_new_project || !use_default;
-        boolean create_activity = isCreateActivity();
-        
-        mUseDefaultLocation.setEnabled(is_new_project);
-
-        mLocationLabel.setEnabled(location_enabled);
-        mLocationPathField.setEnabled(location_enabled);
-        mBrowseButton.setEnabled(location_enabled);
-
-        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) {
-        boolean is_new_project = isNewProject();
-        boolean use_default = 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 = 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(getProjectName()).toString();
-                value = TextProcessor.process(value);
-                if (!mLocationPathField.getText().equals(value)) {
-                    mLocationPathField.setText(value);
-                }
-            }
-            setPageComplete(validatePage());
-            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();
-            setPageComplete(validatePage());
-        }
-    }
-
-    /**
-     * 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 (isNewProject()) {
-            mUserPackageName = getPackageName();
-            setPageComplete(validatePage());
-        }
-    }
-
-    /**
-     * 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 (isNewProject() && !mInternalCreateActivityUpdate) {
-            mUserCreateActivityCheck = isCreateActivity();
-        }
-        setPageComplete(validatePage());
-    }
-
-    /**
-     * 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 (isNewProject() && !mInternalActivityNameUpdate) {
-            mUserActivityName = getActivityName();
-            setPageComplete(validatePage());
-        }
-    }
-
-    /**
-     * 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;
-        }
-
-        try {
-            int version = Integer.parseInt(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 = getSdkTarget();
-            if (curr_target != null && curr_target.getApiVersionNumber() == version) {
-                return;
-            }
-            
-            for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
-                if (target.getApiVersionNumber() == version) {
-                    mSdkTargetSelector.setSelection(target);
-                    break;
-                }
-            }
-        } catch (NumberFormatException e) {
-            // ignore
-        }
-
-        mMinSdkVersionModifiedByUser = true;
-    }
-    
-    /**
-     * Called when an SDK target is modified.
-     * 
-     * If the minSdkVersion field hasn't been modified by the user yet, we change it
-     * to reflect the sdk api level that has just been selected.
-     */
-    private void onSdkTargetModified() {
-        IAndroidTarget target = getSdkTarget();
-        
-        if (target != null && !mMinSdkVersionModifiedByUser) {
-            mInternalMinSdkVersionUpdate = true;
-            mMinSdkVersionField.setText(Integer.toString(target.getApiVersionNumber()));
-            mInternalMinSdkVersionUpdate = false;
-        }
-    }
-
-    /**
-     * 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 (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 (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;
-        int minSdkVersion = AndroidManifestParser.INVALID_MIN_SDK;
-        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;
-                mProjectNameField.setText(activityName);
-                mInternalProjectNameUpdate = false;
-            }
-            if (mApplicationNameField.getText().length() == 0 ||
-                    !mApplicationNameModifiedByUser) {
-                mInternalApplicationNameUpdate = true;
-                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
-        boolean foundTarget = false;
-        
-        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);
-            if (target != null) {
-                mSdkTargetSelector.setSelection(target);
-                foundTarget = true;
-            }
-        }
-
-        if (!foundTarget && minSdkVersion != AndroidManifestParser.INVALID_MIN_SDK) {
-            try {
-                for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
-                    if (target.getApiVersionNumber() == minSdkVersion) {
-                        mSdkTargetSelector.setSelection(target);
-                        foundTarget = true;
-                        break;
-                    }
-                }
-            } catch(NumberFormatException e) {
-                // ignore
-            }
-        }
-        
-        if (!foundTarget) {
-            for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
-                if (projectLocation.startsWith(target.getLocation())) {
-                    mSdkTargetSelector.setSelection(target);
-                    foundTarget = true;
-                    break;
-                }
-            }
-        }
-
-        if (!foundTarget) {
-            mInternalMinSdkVersionUpdate = true;
-            mMinSdkVersionField.setText(
-                    minSdkVersion == AndroidManifestParser.INVALID_MIN_SDK ? "" :
-                        Integer.toString(minSdkVersion)); //$NON-NLS-1$
-            mInternalMinSdkVersionUpdate = false;
-        }
-    }
-
-    /**
-     * 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
-     */
-    protected boolean validatePage() {
-        IWorkspace workspace = ResourcesPlugin.getWorkspace();
-
-        int status = validateProjectField(workspace);
-        if ((status & MSG_ERROR) == 0) {
-            status |= validateLocationPath(workspace);
-        }
-        if ((status & MSG_ERROR) == 0) {
-            status |= validateSdkTarget();
-        }
-        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 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 projectFieldContents = getProjectName();
-        if (projectFieldContents.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(projectFieldContents).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(projectFieldContents, 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);
-        }
-
-        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 (isNewProject()) {
-            if (!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(getProjectName()).toFile();
-                if (dest.exists()) {
-                    return setStatus(String.format("There is already a file or directory named \"%1$s\" in the selected location.",
-                            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 (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 (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 (getMinSdkVersion().length() == 0) {
-            return MSG_NONE;
-        }
-
-        int version = AndroidManifestParser.INVALID_MIN_SDK;
-        try {
-            // If not empty, it must be a valid integer > 0
-            version = Integer.parseInt(getMinSdkVersion());
-        } catch (NumberFormatException e) {
-            // ignore
-        }
-        
-        if (version < 1) {
-            return setStatus("Min SDK Version must be an integer > 0.", MSG_ERROR);
-        }
-                
-        if (getSdkTarget() != null && getSdkTarget().getApiVersionNumber() != version) {
-            return setStatus("The API level for the selected SDK target does not match the Min SDK version.",
-                    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 (!isCreateActivity()) {
-            return MSG_NONE;
-        }
-
-        // Validate activity field
-        String activityFieldContents = 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 = "";
-        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 = 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 (isNewProject() || !isCreateActivity()) {
-            return MSG_NONE;
-        }
-
-        String osTarget = getActivityName();
-        
-        if (osTarget.indexOf('.') == -1) {
-            osTarget = getPackageName() + File.separator + osTarget;
-        } else if (osTarget.indexOf('.') == 0) {
-            osTarget = 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/wizards/newproject/NewProjectWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java
deleted file mode 100644
index af45fa9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java
+++ /dev/null
@@ -1,743 +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.wizards.newproject;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.project.AndroidNature;
-import com.android.ide.eclipse.adt.project.ProjectHelper;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.common.AndroidConstants;
-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.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 {
-
-    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$
-
-    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 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 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_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 ICON = "icon.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 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$
-    
-    protected static final String MAIN_PAGE_NAME = "newAndroidProjectPage"; //$NON-NLS-1$
-
-    private NewProjectCreationPage mMainPage;
-
-    /**
-     * 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();
-
-        mMainPage = createMainPage();
-        mMainPage.setTitle("New Android Project");
-        mMainPage.setDescription("Creates a new Android Project resource.");
-    }
-    
-    /**
-     * 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 NewProjectCreationPage createMainPage() {
-        return new NewProjectCreationPage(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() {
-        if (!createAndroidProject()) {
-            return false;
-        }
-
-        // Open the default Java Perspective
-        OpenJavaPerspectiveAction action = new OpenJavaPerspectiveAction();
-        action.run();
-        return true;
-    }
-
-    // -- 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;
-    }
-
-    /**
-     * Creates the android project.
-     * @return True if the project could be created.
-     */
-    private boolean createAndroidProject() {
-        IWorkspace workspace = ResourcesPlugin.getWorkspace();
-        final IProject project = workspace.getRoot().getProject(mMainPage.getProjectName());
-        final IProjectDescription description = workspace.newProjectDescription(project.getName());
-
-        final Map<String, Object> parameters = new HashMap<String, Object>();
-        parameters.put(PARAM_PROJECT, mMainPage.getProjectName());
-        parameters.put(PARAM_PACKAGE, mMainPage.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, mMainPage.isNewProject());
-        parameters.put(PARAM_SRC_FOLDER, mMainPage.getSourceFolder());
-        parameters.put(PARAM_SDK_TARGET, mMainPage.getSdkTarget());
-        parameters.put(PARAM_MIN_SDK_VERSION, mMainPage.getMinSdkVersion());
-
-        if (mMainPage.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 = mMainPage.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> stringDictionary = new HashMap<String, String>();
-        stringDictionary.put(STRING_APP_NAME, mMainPage.getApplicationName());
-
-        IPath path = mMainPage.getLocationPath();
-        IPath defaultLocation = Platform.getLocation();
-        if (!path.equals(defaultLocation)) {
-            description.setLocation(path);
-        }
-        
-        if (mMainPage.isNewProject() && !mMainPage.useDefaultLocation() &&
-                !validateNewProjectLocationIsEmpty(path)) {
-            return false;
-        }
-
-        // Create a monitored operation to create the actual project
-        WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
-            @Override
-            protected void execute(IProgressMonitor monitor) throws InvocationTargetException {
-                createProjectAsync(project, description, monitor, parameters, stringDictionary);
-            }
-        };
-
-        // Run the operation in a different thread
-        runAsyncOperation(op);
-        return true;
-    }
-
-    /**
-     * 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, sets its nature and adds the required folders
-     * and files to it. This is run asynchronously in a different thread.
-     *
-     * @param project The project to create.
-     * @param description A description of the project.
-     * @param monitor An existing monitor.
-     * @param parameters Template parameters.
-     * @param stringDictionary String definition.
-     * @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(IProject project, IProjectDescription description,
-            IProgressMonitor monitor, Map<String, Object> parameters,
-            Map<String, String> stringDictionary)
-            throws InvocationTargetException {
-        monitor.beginTask("Create Android Project", 100);
-        try {
-            // 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.
-            addDefaultDirectories(project, RES_DIRECTORY, RES_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, stringDictionary, monitor);
-
-                // add the default app icon
-                addIcon(project, monitor);
-
-                // Create the default package components
-                addSampleCode(project, sourceFolders[0], parameters, stringDictionary, monitor);
-
-                // add the string definition file if needed
-                if (stringDictionary.size() > 0) {
-                    addStringDictionaryFile(project, stringDictionary, monitor);
-                }
-
-                // Set output location
-                javaProject.setOutputLocation(project.getFolder(BIN_DIRECTORY).getFullPath(),
-                        monitor);
-            }
-
-            Sdk.getCurrent().setProject(project, (IAndroidTarget) parameters.get(PARAM_SDK_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);
-
-        } catch (CoreException e) {
-            throw new InvocationTargetException(e);
-        } catch (IOException e) {
-            throw new InvocationTargetException(e);
-        } finally {
-            monitor.done();
-        }
-    }
-
-    /**
-     * 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 stringDictionary 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> stringDictionary, 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, "");
-            }
-            
-            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 monitor An existing monitor.
-     * @throws CoreException if the method fails to update the project.
-     */
-    private void addIcon(IProject project, IProgressMonitor monitor)
-            throws CoreException {
-        IFile file = project.getFile(RES_DIRECTORY + AndroidConstants.WS_SEP
-                                     + DRAWABLE_DIRECTORY + AndroidConstants.WS_SEP + ICON);
-        if (!file.exists()) {
-            // read the content from the template
-            byte[] buffer = AdtPlugin.readEmbeddedFile(TEMPLATES_DIRECTORY + ICON);
-
-            // if valid
-            if (buffer != null) {
-                // Save in the project
-                InputStream stream = new ByteArrayInputStream(buffer);
-                file.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 stringDictionary 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> stringDictionary,
-            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) {
-                stringDictionary.put(STRING_HELLO_WORLD, "Hello World, " + activityName + "!");
-            } else {
-                stringDictionary.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/wizards/newxmlfile/NewXmlFileCreationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newxmlfile/NewXmlFileCreationPage.java
deleted file mode 100644
index f850504..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newxmlfile/NewXmlFileCreationPage.java
+++ /dev/null
@@ -1,1231 +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.newxmlfile;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
-import com.android.ide.eclipse.adt.ui.ConfigurationSelector;
-import com.android.ide.eclipse.adt.ui.ConfigurationSelector.ConfigurationState;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.ProjectChooserHelper;
-import com.android.ide.eclipse.editors.descriptors.DocumentDescriptor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.editors.menu.descriptors.MenuDescriptors;
-import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.editors.resources.configurations.ResourceQualifier;
-import com.android.ide.eclipse.editors.resources.descriptors.ResourcesDescriptors;
-import com.android.ide.eclipse.editors.resources.manager.ResourceFolderType;
-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);
-        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 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());
-        } 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());
-            }
-        }
-
-        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;
-            }
-
-            TypeInfo type = getSelectedType();
-            
-            if (type != null) {
-                mConfigSelector.getConfiguration(mTempConfig);
-                StringBuffer sb = new StringBuffer(RES_FOLDER_ABS);
-                sb.append(mTempConfig.getFolderName(type.getResFolderType()));
-                
-                mInternalWsFolderPathUpdate = true;
-                mWsFolderPathTextField.setText(sb.toString());
-                mInternalWsFolderPathUpdate = false;
-                
-                validatePage();
-            }
-        }
-    }
-
-    /**
-     * 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.getApiVersionNumber();
-        }
-        
-        for (TypeInfo type : sTypes) {
-            type.getWidget().setEnabled(type.getTargetApiLevel() <= currentApiLevel);
-        }
-    }
-
-    /**
-     * 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.getApiVersionNumber();
-            }
-
-            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/wizards/newxmlfile/NewXmlFileWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newxmlfile/NewXmlFileWizard.java
deleted file mode 100644
index d7e43cf..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.wizards.newxmlfile;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.wizards.newxmlfile.NewXmlFileCreationPage.TypeInfo;
-import com.android.ide.eclipse.editors.IconFactory;
-
-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/common/AndroidConstants.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java
deleted file mode 100644
index d0d8ae3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java
+++ /dev/null
@@ -1,224 +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.common;
-
-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);
-
-    public final static String FN_ADB =
-        (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) ?
-            "adb.exe" : "adb"; //$NON-NLS-1$ //$NON-NLS-2$
-
-    public final static String FN_EMULATOR =
-        (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) ?
-            "emulator.exe" : "emulator"; //$NON-NLS-1$ //$NON-NLS-2$
-
-    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 + "/" +
-            SdkConstants.FD_DOCS_REFERENCE; //$NON-NLS-1$
-
-    /** 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/common/Messages.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/Messages.java
deleted file mode 100644
index 3f1bde4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/Messages.java
+++ /dev/null
@@ -1,21 +0,0 @@
-
-package com.android.ide.eclipse.common;
-
-import org.eclipse.osgi.util.NLS;
-
-public class Messages extends NLS {
-    private static final String BUNDLE_NAME = "com.android.ide.eclipse.common.messages"; //$NON-NLS-1$
-
-    public static String Console_Data_Project_Tag;
-
-    public static String Console_Date_Tag;
-
-
-    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/common/SdkStatsHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/SdkStatsHelper.java
deleted file mode 100644
index 345c663..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/SdkStatsHelper.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.common;
-
-import com.android.sdkstats.SdkStatsService;
-
-import org.osgi.framework.Version;
-
-/**
- * Helper class to access the ping usage stat server.
- */
-public class SdkStatsHelper {
-
-    /**
-     * Pings the usage start server.
-     * @param pluginName the name of the plugin to appear in the stats
-     * @param pluginVersion the {@link Version} of the plugin.
-     */
-    public static void pingUsageServer(String pluginName, Version pluginVersion) {
-        String versionString = String.format("%1$d.%2$d.%3$d", pluginVersion.getMajor(),
-                pluginVersion.getMinor(), pluginVersion.getMicro());
-
-        SdkStatsService.ping(pluginName, versionString);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/StreamHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/StreamHelper.java
deleted file mode 100644
index 6ccf4f2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/StreamHelper.java
+++ /dev/null
@@ -1,63 +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.common;
-
-import org.eclipse.ui.console.MessageConsoleStream;
-
-import java.util.Calendar;
-
-/**
- * Stream helper class.
- */
-public class StreamHelper {
-
-    /**
-     * 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/common/messages.properties b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/messages.properties
deleted file mode 100644
index dba6edc..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/messages.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-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/src/com/android/ide/eclipse/common/preferences/UsagePreferencePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/preferences/UsagePreferencePage.java
deleted file mode 100644
index 58c2f40..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.common.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/common/project/AndroidManifestParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java
deleted file mode 100644
index 3b5c823..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java
+++ /dev/null
@@ -1,1028 +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.common.project;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.XmlErrorHandler.XmlErrorListener;
-import com.android.sdklib.SdkConstants;
-
-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 String ATTRIBUTE_PACKAGE = "package"; //$NON-NLS-1$
-    private final static String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$
-    private final static String ATTRIBUTE_PROCESS = "process"; //$NON-NLS-$
-    private final static String ATTRIBUTE_DEBUGGABLE = "debuggable"; //$NON-NLS-$
-    private final static String ATTRIBUTE_MIN_SDK_VERSION = "minSdkVersion"; //$NON-NLS-$
-    private final static String ATTRIBUTE_TARGET_PACKAGE = "targetPackage"; //$NON-NLS-1$
-    private final static String ATTRIBUTE_EXPORTED = "exported"; //$NON-NLS-1$
-    private final static String NODE_MANIFEST = "manifest"; //$NON-NLS-1$
-    private final static String NODE_APPLICATION = "application"; //$NON-NLS-1$
-    private final static String NODE_ACTIVITY = "activity"; //$NON-NLS-1$
-    private final static String NODE_SERVICE = "service"; //$NON-NLS-1$
-    private final static String NODE_RECEIVER = "receiver"; //$NON-NLS-1$
-    private final static String NODE_PROVIDER = "provider"; //$NON-NLS-1$
-    private final static String NODE_INTENT = "intent-filter"; //$NON-NLS-1$
-    private final static String NODE_ACTION = "action"; //$NON-NLS-1$
-    private final static String NODE_CATEGORY = "category"; //$NON-NLS-1$
-    private final static String NODE_USES_SDK = "uses-sdk"; //$NON-NLS-1$
-    private final static String NODE_INSTRUMENTATION = "instrumentation"; //$NON-NLS-1$
-    private final static String NODE_USES_LIBRARY = "uses-library"; //$NON-NLS-1$
-
-    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$
-    
-    public final static int INVALID_MIN_SDK = -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 {@link AndroidManifestParser#INVALID_MIN_SDK}
-         * the attribute was not present. */
-        private int mApiLevelRequirement = INVALID_MIN_SDK;
-        /** 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
-         * {@link AndroidManifestParser#INVALID_MIN_SDK} if it's not set. 
-         */
-        int 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 (NODE_MANIFEST.equals(localName)) {
-                                // lets get the package name.
-                                mPackage = getAttributeValue(attributes, ATTRIBUTE_PACKAGE,
-                                        false /* hasNamespace */);
-                                mValidLevel++;
-                            }
-                            break;
-                        case LEVEL_APPLICATION:
-                            if (NODE_APPLICATION.equals(localName)) {
-                                value = getAttributeValue(attributes, ATTRIBUTE_PROCESS,
-                                        true /* hasNamespace */);
-                                if (value != null) {
-                                    addProcessName(value);
-                                }
-                                
-                                value = getAttributeValue(attributes, ATTRIBUTE_DEBUGGABLE,
-                                        true /* hasNamespace*/);
-                                if (value != null) {
-                                    mDebuggable = Boolean.parseBoolean(value);
-                                }
-                                
-                                mValidLevel++;
-                            } else if (NODE_USES_SDK.equals(localName)) {
-                                value = getAttributeValue(attributes, ATTRIBUTE_MIN_SDK_VERSION,
-                                        true /* hasNamespace */);
-                                
-                                try {
-                                    mApiLevelRequirement = Integer.parseInt(value);
-                                } catch (NumberFormatException e) {
-                                    handleError(e, -1 /* lineNumber */);
-                                }
-                            } else if (NODE_INSTRUMENTATION.equals(localName)) {
-                                processInstrumentationNode(attributes);
-                            }    
-                            break;
-                        case LEVEL_ACTIVITY:
-                            if (NODE_ACTIVITY.equals(localName)) {
-                                processActivityNode(attributes);
-                                mValidLevel++;
-                            } else if (NODE_SERVICE.equals(localName)) {
-                                processNode(attributes, AndroidConstants.CLASS_SERVICE);
-                                mValidLevel++;
-                            } else if (NODE_RECEIVER.equals(localName)) {
-                                processNode(attributes, AndroidConstants.CLASS_BROADCASTRECEIVER);
-                                mValidLevel++;
-                            } else if (NODE_PROVIDER.equals(localName)) {
-                                processNode(attributes, AndroidConstants.CLASS_CONTENTPROVIDER);
-                                mValidLevel++;
-                            } else if (NODE_USES_LIBRARY.equals(localName)) {
-                                value = getAttributeValue(attributes, 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 && NODE_INTENT.equals(localName)) {
-                                mCurrentActivity.resetIntentFilter();
-                                mValidLevel++;
-                            }
-                            break;
-                        case LEVEL_CATEGORY:
-                            if (mCurrentActivity != null) {
-                                if (NODE_ACTION.equals(localName)) {
-                                    // get the name attribute
-                                    String action = getAttributeValue(attributes, ATTRIBUTE_NAME,
-                                            true /* hasNamespace */);
-                                    if (action != null) {
-                                        mCurrentActivity.setHasAction(true);
-                                        mCurrentActivity.setHasMainAction(
-                                                ACTION_MAIN.equals(action));
-                                    }
-                                } else if (NODE_CATEGORY.equals(localName)) {
-                                    String category = getAttributeValue(attributes, 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, ATTRIBUTE_NAME,
-                    true /* hasNamespace */);
-            if (activityName != null) {
-                activityName = combinePackageAndClassName(mPackage, activityName);
-                
-                // get the exported flag.
-                String exportedStr = getAttributeValue(attributes, 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, 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, ATTRIBUTE_NAME,
-                    true /* hasNamespace */);
-            if (serviceName != null) {
-                serviceName = combinePackageAndClassName(mPackage, serviceName);
-                
-                if (mMarkErrors) {
-                    checkClass(serviceName, superClassName, false /* testVisibility */);
-                }
-            }
-            
-            String processName = getAttributeValue(attributes, 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, ATTRIBUTE_NAME,
-                    true /* hasNamespace */);
-            if (instrumentationName != null) {
-                String instrClassName = combinePackageAndClassName(mPackage, instrumentationName);
-                String targetPackage = getAttributeValue(attributes, 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 int 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 {
-            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 {@link #INVALID_MIN_SDK}
-     * if it's not set. 
-     */
-    public int 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 0 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,
-            int 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;
-    }
-
-    /**
-     * 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;
-        }
-    }
-
-    /**
-     * 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/common/project/AndroidXPathFactory.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidXPathFactory.java
deleted file mode 100644
index 0f1e255..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidXPathFactory.java
+++ /dev/null
@@ -1,89 +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.common.project;
-
-import com.android.sdklib.SdkConstants;
-
-import java.util.Iterator;
-
-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 namespace.
- */
-public class AndroidXPathFactory {
-    public final static String DEFAULT_NS_PREFIX = "android"; //$NON-NLS-1$
-
-    private final static XPathFactory sFactory = XPathFactory.newInstance();
-    
-    /** Namespace context for Android resource XML files. */
-    private static class AndroidNamespaceContext implements NamespaceContext {
-        private String mAndroidPrefix;
-
-        /**
-         * Construct the context with the prefix associated with the android namespace.
-         * @param androidPrefix the Prefix
-         */
-        public AndroidNamespaceContext(String androidPrefix) {
-            mAndroidPrefix = androidPrefix;
-        }
-
-        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) {
-            // This isn't necessary for our use.
-            assert false;
-            return null;
-        }
-
-        public Iterator<?> getPrefixes(String namespaceURI) {
-            // This isn't necessary for our use.
-            assert false;
-            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() {
-        return newXPath(DEFAULT_NS_PREFIX);
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/BaseProjectHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/BaseProjectHelper.java
deleted file mode 100644
index bd8b444..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.common.project;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.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/common/project/ExportHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/ExportHelper.java
deleted file mode 100644
index 4b169a1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/ExportHelper.java
+++ /dev/null
@@ -1,188 +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.common.project;
-
-import com.android.ide.eclipse.common.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.openInformation(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.openInformation(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.openInformation(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
-                    }
-                }
-            }
-        } else {
-            MessageDialog.openInformation(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/common/project/ProjectChooserHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/ProjectChooserHelper.java
deleted file mode 100644
index b6d4c9a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.common.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/common/project/XmlErrorHandler.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java
deleted file mode 100644
index 1810ad2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java
+++ /dev/null
@@ -1,127 +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.common.project;
-
-import com.android.ide.eclipse.common.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();
-        }
-        
-        if (mFile != null) {
-            if (lineNumber != -1) {
-                BaseProjectHelper.addMarker(mFile,
-                        AndroidConstants.MARKER_XML,
-                        exception.getMessage(),
-                        lineNumber,
-                        IMarker.SEVERITY_ERROR);
-            } else {
-                BaseProjectHelper.addMarker(mFile,
-                        AndroidConstants.MARKER_XML,
-                        exception.getMessage(),
-                        IMarker.SEVERITY_ERROR);
-            }
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/AttrsXmlParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/AttrsXmlParser.java
deleted file mode 100644
index 3875e81..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.common.resources;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo;
-import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo.Format;
-import com.android.ide.eclipse.common.resources.ViewClassInfo.LayoutParamsInfo;
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-
-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/common/resources/DeclareStyleableInfo.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java
deleted file mode 100644
index 7aad7c8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.common.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/common/resources/IIdResourceItem.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/IIdResourceItem.java
deleted file mode 100644
index 38b7e03..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.common.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/common/resources/IPathChangedListener.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/IPathChangedListener.java
deleted file mode 100644
index 53d9077..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/IPathChangedListener.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 com.android.ide.eclipse.common.resources;
-
-/**
- * Classes which implement this interface provide a method that deals with
- * a path change.
- */
-public interface IPathChangedListener {
-    /**
-     * Sent when the location of the android sdk directory changed.
-     * @param osPath The new android sdk directory location.
-     */
-    public void pathChanged(String osPath);
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/IResourceRepository.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/IResourceRepository.java
deleted file mode 100644
index 3819997..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.common.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/common/resources/ResourceItem.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/ResourceItem.java
deleted file mode 100644
index 83527f3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.common.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/common/resources/ResourceType.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/ResourceType.java
deleted file mode 100644
index 60c471e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.common.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/common/resources/ViewClassInfo.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/ViewClassInfo.java
deleted file mode 100644
index 619e3cc..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.common.resources;
-
-import com.android.ide.eclipse.common.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/editors/AndroidContentAssist.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidContentAssist.java
deleted file mode 100644
index 0d0883e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidContentAssist.java
+++ /dev/null
@@ -1,795 +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.editors;
-
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.editors.descriptors.SeparatorAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.TextValueDescriptor;
-import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.editors.uimodel.UiFlagAttributeNode;
-import com.android.sdklib.SdkConstants;
-
-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);
-        }
-
-        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.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 choice 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 of 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("",
-                            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/editors/AndroidEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java
deleted file mode 100644
index c7541e9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java
+++ /dev/null
@@ -1,828 +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.editors;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-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.
-     *  
-     * @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/editors/AndroidSourceViewerConfig.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidSourceViewerConfig.java
deleted file mode 100644
index ab17bef..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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/editors/FirstElementParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/FirstElementParser.java
deleted file mode 100644
index bb0996b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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/editors/IconFactory.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/IconFactory.java
deleted file mode 100644
index 2c24772..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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/editors/descriptors/AttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptor.java
deleted file mode 100644
index e0ec86b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.descriptors;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.IconFactory;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.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/editors/descriptors/AttributeDescriptorLabelProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptorLabelProvider.java
deleted file mode 100644
index 2729565..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.descriptors;
-
-import com.android.ide.eclipse.editors.IconFactory;
-import com.android.ide.eclipse.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/editors/descriptors/BooleanAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/BooleanAttributeDescriptor.java
deleted file mode 100644
index 9ebf5f1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.descriptors;
-
-import com.android.ide.eclipse.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/editors/descriptors/DescriptorsUtils.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java
deleted file mode 100644
index f1d62a1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java
+++ /dev/null
@@ -1,845 +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.editors.descriptors;
-
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo;
-import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo.Format;
-import com.android.ide.eclipse.editors.layout.LayoutConstants;
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-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.getUiRoot(),
-                new Object[] { ui_node.getDescriptor().getXmlLocalName(), null, null, null });
-        if (widget_id != null) {
-            ui_node.setAttributeValue(LayoutConstants.ATTR_ID, "@+id/" + widget_id, //$NON-NLS-1$
-                    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".
-     *  
-     * @param uiNode The UI node that gives the prefix to match.
-     * @return A suitable generated id
-     */
-    public static String getFreeWidgetId(UiElementNode uiNode) {
-        return getFreeWidgetId(uiNode.getUiRoot(),
-                new Object[] { uiNode.getDescriptor().getXmlLocalName(), 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/editors/descriptors/DocumentDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DocumentDescriptor.java
deleted file mode 100644
index 7d296f7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.descriptors;
-
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.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/editors/descriptors/ElementDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ElementDescriptor.java
deleted file mode 100644
index 6a9b7db..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.descriptors;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.IconFactory;
-import com.android.ide.eclipse.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/editors/descriptors/EnumAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/EnumAttributeDescriptor.java
deleted file mode 100644
index cab9883..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.descriptors;
-
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.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/editors/descriptors/FlagAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/FlagAttributeDescriptor.java
deleted file mode 100644
index 903417b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.descriptors;
-
-import com.android.ide.eclipse.editors.ui.FlagValueCellEditor;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.editors.uimodel.UiFlagAttributeNode;
-import com.android.ide.eclipse.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/editors/descriptors/IDescriptorProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/IDescriptorProvider.java
deleted file mode 100644
index 4c115e9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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/editors/descriptors/ListAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ListAttributeDescriptor.java
deleted file mode 100644
index 93969e9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.descriptors;
-
-import com.android.ide.eclipse.editors.ui.ListValueCellEditor;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.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/editors/descriptors/ReferenceAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ReferenceAttributeDescriptor.java
deleted file mode 100644
index 336dfe2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ReferenceAttributeDescriptor.java
+++ /dev/null
@@ -1,84 +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.editors.descriptors;
-
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.ui.ResourceValueCellEditor;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.editors.uimodel.UiResourceAttributeNode;
-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 {
-
-    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;
-    }
-    
-    
-    /**
-     * @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/editors/descriptors/SeparatorAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/SeparatorAttributeDescriptor.java
deleted file mode 100644
index 8fb1c7c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.descriptors;
-
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.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/editors/descriptors/TextAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/TextAttributeDescriptor.java
deleted file mode 100644
index 77fc067..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.descriptors;
-
-import com.android.ide.eclipse.editors.ui.TextValueCellEditor;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.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/editors/descriptors/TextValueDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/TextValueDescriptor.java
deleted file mode 100644
index 2015d71..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.descriptors;
-
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.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/editors/descriptors/XmlnsAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/XmlnsAttributeDescriptor.java
deleted file mode 100644
index ed9c897..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.descriptors;
-
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.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/editors/layout/AbstractGraphicalLayoutEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/AbstractGraphicalLayoutEditor.java
deleted file mode 100644
index 0499867..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/AbstractGraphicalLayoutEditor.java
+++ /dev/null
@@ -1,106 +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.editors.layout;
-
-import com.android.ide.eclipse.editors.layout.LayoutReloadMonitor.ILayoutReloadListener;
-import com.android.ide.eclipse.editors.layout.parts.ElementCreateCommand;
-import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-
-import org.eclipse.gef.DefaultEditDomain;
-import org.eclipse.gef.ui.parts.GraphicalEditorWithPalette;
-import org.eclipse.gef.ui.parts.SelectionSynchronizer;
-import org.eclipse.swt.dnd.Clipboard;
-import org.eclipse.ui.IWorkbenchPart;
-
-/**
- * Abstract GraphicalLayoutEditor.
- */
-/*package*/ abstract class AbstractGraphicalLayoutEditor extends GraphicalEditorWithPalette
-    implements IWorkbenchPart, ILayoutReloadListener {
-
-    /**
-     * 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.
-     * <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();
-    }
-
-    abstract void reloadPalette();
-
-    abstract void recomputeLayout();
-
-    abstract UiDocumentNode getModel();
-
-    abstract LayoutEditor getLayoutEditor();
-
-    abstract Clipboard getClipboard();
-
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/BasePullParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/BasePullParser.java
deleted file mode 100644
index 381539b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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/editors/layout/GraphicalLayoutEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/GraphicalLayoutEditor.java
deleted file mode 100644
index e223820..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/GraphicalLayoutEditor.java
+++ /dev/null
@@ -1,2436 +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.editors.layout;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.sdk.LoadStatus;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData.LayoutBridge;
-import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
-import com.android.ide.eclipse.adt.ui.ConfigurationSelector.DensityVerifier;
-import com.android.ide.eclipse.adt.ui.ConfigurationSelector.DimensionVerifier;
-import com.android.ide.eclipse.adt.ui.ConfigurationSelector.LanguageRegionVerifier;
-import com.android.ide.eclipse.adt.ui.ConfigurationSelector.MobileCodeVerifier;
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.IconFactory;
-import com.android.ide.eclipse.editors.layout.LayoutEditor.UiEditorActions;
-import com.android.ide.eclipse.editors.layout.LayoutReloadMonitor.ILayoutReloadListener;
-import com.android.ide.eclipse.editors.layout.descriptors.ViewElementDescriptor;
-import com.android.ide.eclipse.editors.layout.parts.ElementCreateCommand;
-import com.android.ide.eclipse.editors.layout.parts.UiElementEditPart;
-import com.android.ide.eclipse.editors.layout.parts.UiElementsEditPartFactory;
-import com.android.ide.eclipse.editors.resources.configurations.CountryCodeQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.editors.resources.configurations.KeyboardStateQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.LanguageQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.NavigationMethodQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.NetworkCodeQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.PixelDensityQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.RegionQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.ScreenDimensionQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.ScreenOrientationQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.TextInputMethodQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.TouchScreenQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.KeyboardStateQualifier.KeyboardState;
-import com.android.ide.eclipse.editors.resources.configurations.NavigationMethodQualifier.NavigationMethod;
-import com.android.ide.eclipse.editors.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
-import com.android.ide.eclipse.editors.resources.configurations.TextInputMethodQualifier.TextInputMethod;
-import com.android.ide.eclipse.editors.resources.configurations.TouchScreenQualifier.TouchScreenType;
-import com.android.ide.eclipse.editors.resources.manager.ProjectResources;
-import com.android.ide.eclipse.editors.resources.manager.ResourceFile;
-import com.android.ide.eclipse.editors.resources.manager.ResourceFolderType;
-import com.android.ide.eclipse.editors.resources.manager.ResourceManager;
-import com.android.ide.eclipse.editors.ui.tree.CopyCutAction;
-import com.android.ide.eclipse.editors.ui.tree.PasteAction;
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-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.IStyleResourceValue;
-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.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.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.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.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 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.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * 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
- */
-public class GraphicalLayoutEditor extends AbstractGraphicalLayoutEditor
-        implements ILayoutReloadListener {
-    
-    private final static String THEME_SEPARATOR = "----------"; //$NON-NLS-1$
-
-    /** 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 PaletteRoot mPaletteRoot;
-
-    private Text mCountry;
-    private Text mNetwork;
-    private Combo mLanguage;
-    private Combo mRegion;
-    private Combo mOrientation;
-    private Text mDensity;
-    private Combo mTouch;
-    private Combo mKeyboard;
-    private Combo mTextInput;
-    private Combo mNavigation;
-    private Text mSize1;
-    private Text mSize2;
-    private Combo mThemeCombo;
-    private Button mCreateButton;
-
-    private Label mCountryIcon;
-    private Label mNetworkIcon;
-    private Label mLanguageIcon;
-    private Label mRegionIcon;
-    private Label mOrientationIcon;
-    private Label mDensityIcon;
-    private Label mTouchIcon;
-    private Label mKeyboardIcon;
-    private Label mTextInputIcon;
-    private Label mNavigationIcon;
-    private Label mSizeIcon;
-
-    private Label mCurrentLayoutLabel;
-
-    private Image mWarningImage;
-    private Image mMatchImage;
-    private Image mErrorImage;
-
-    /** The {@link FolderConfiguration} representing the state of the UI controls */
-    private FolderConfiguration mCurrentConfig = new FolderConfiguration();
-    /** 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 int mPlatformThemeCount = 0;
-    private boolean mDisableUpdates = 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;
-            
-            updateUIFromResources();
-
-            mThemeCombo.getParent().layout();
-
-            // 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() {
-            updateUIFromResources();
-            mThemeCombo.getParent().layout();
-        }
-    };
-
-    public GraphicalLayoutEditor(LayoutEditor layoutEditor) {
-        mLayoutEditor = layoutEditor;
-        setEditDomain(new DefaultEditDomain(this));
-        setPartName("Layout");
-
-        IconFactory factory = IconFactory.getInstance();
-        mWarningImage = factory.getIcon("warning"); //$NON-NLS-1$
-        mMatchImage = factory.getIcon("match"); //$NON-NLS-1$
-        mErrorImage = factory.getIcon("error"); //$NON-NLS-1$
-
-        AdtPlugin.getDefault().addTargetListener(mTargetListener);
-    }
-
-    // ------------------------------------
-    // Methods overridden from base classes
-    //------------------------------------
-
-    @Override
-    public void createPartControl(Composite parent) {
-        mParent = parent;
-        GridLayout gl;
-        GridData gd;
-
-        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
-        int cols = 10;
-
-        Composite topParent = new Composite(parent, SWT.NONE);
-        topParent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
-        topParent.setLayout(gl = new GridLayout(cols, false));
-
-        new Label(topParent, SWT.NONE).setText("MCC");
-        mCountryIcon = createControlComposite(topParent, true /* grab_horizontal */);
-        mCountry = new Text(mCountryIcon.getParent(), SWT.BORDER);
-        mCountry.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-        mCountry.addVerifyListener(new MobileCodeVerifier());
-        mCountry.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetDefaultSelected(SelectionEvent e) {
-                onCountryCodeChange();
-            }
-        });
-        mCountry.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                onCountryCodeChange();
-            }
-        });
-
-        new Label(topParent, SWT.NONE).setText("MNC");
-        mNetworkIcon = createControlComposite(topParent, true /* grab_horizontal */);
-        mNetwork = new Text(mNetworkIcon.getParent(), SWT.BORDER);
-        mNetwork.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-        mNetwork.addVerifyListener(new MobileCodeVerifier());
-        mNetwork.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetDefaultSelected(SelectionEvent e) {
-                onNetworkCodeChange();
-            }
-        });
-        mNetwork.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                onNetworkCodeChange();
-            }
-        });
-
-        new Label(topParent, SWT.NONE).setText("Lang");
-        mLanguageIcon = createControlComposite(topParent, true /* grab_horizontal */);
-        mLanguage = new Combo(mLanguageIcon.getParent(), SWT.DROP_DOWN);
-        mLanguage.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_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(topParent, SWT.NONE).setText("Region");
-        mRegionIcon = createControlComposite(topParent, true /* grab_horizontal */);
-        mRegion = new Combo(mRegionIcon.getParent(), SWT.DROP_DOWN);
-        mRegion.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_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(topParent, SWT.NONE).setText("Orient");
-        mOrientationIcon = createControlComposite(topParent, true /* grab_horizontal */);
-        mOrientation = new Combo(mOrientationIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY);
-        ScreenOrientation[] soValues = ScreenOrientation.values();
-        mOrientation.add("(Default)");
-        for (ScreenOrientation value : soValues) {
-            mOrientation.add(value.getDisplayValue());
-        }
-        mOrientation.select(0);
-        mOrientation.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-        mOrientation.addSelectionListener(new SelectionAdapter() {
-           @Override
-            public void widgetSelected(SelectionEvent e) {
-               onOrientationChange();
-            }
-        });
-
-        new Label(topParent, SWT.NONE).setText("Density");
-        mDensityIcon = createControlComposite(topParent, true /* grab_horizontal */);
-        mDensity = new Text(mDensityIcon.getParent(), SWT.BORDER);
-        mDensity.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-        mDensity.addVerifyListener(new DensityVerifier());
-        mDensity.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetDefaultSelected(SelectionEvent e) {
-                onDensityChange();
-            }
-        });
-        mDensity.addModifyListener(new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                onDensityChange();
-            }
-        });
-
-        new Label(topParent, SWT.NONE).setText("Touch");
-        mTouchIcon = createControlComposite(topParent, true /* grab_horizontal */);
-        mTouch = new Combo(mTouchIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY);
-        TouchScreenType[] tstValues = TouchScreenType.values();
-        mTouch.add("(Default)");
-        for (TouchScreenType value : tstValues) {
-            mTouch.add(value.getDisplayValue());
-        }
-        mTouch.select(0);
-        mTouch.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-        mTouch.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onTouchChange();
-            }
-        });
-
-        new Label(topParent, SWT.NONE).setText("Keybrd");
-        mKeyboardIcon = createControlComposite(topParent, true /* grab_horizontal */);
-        mKeyboard = new Combo(mKeyboardIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY);
-        KeyboardState[] ksValues = KeyboardState.values();
-        mKeyboard.add("(Default)");
-        for (KeyboardState value : ksValues) {
-            mKeyboard.add(value.getDisplayValue());
-        }
-        mKeyboard.select(0);
-        mKeyboard.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-        mKeyboard.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onKeyboardChange();
-            }
-        });
-
-        new Label(topParent, SWT.NONE).setText("Input");
-        mTextInputIcon = createControlComposite(topParent, true /* grab_horizontal */);
-        mTextInput = new Combo(mTextInputIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY);
-        TextInputMethod[] timValues = TextInputMethod.values();
-        mTextInput.add("(Default)");
-        for (TextInputMethod value : timValues) {
-            mTextInput.add(value.getDisplayValue());
-        }
-        mTextInput.select(0);
-        mTextInput.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-        mTextInput.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                onTextInputChange();
-            }
-        });
-
-        new Label(topParent, SWT.NONE).setText("Nav");
-        mNavigationIcon = createControlComposite(topParent, true /* grab_horizontal */);
-        mNavigation = new Combo(mNavigationIcon.getParent(), SWT.DROP_DOWN | SWT.READ_ONLY);
-        NavigationMethod[] nValues = NavigationMethod.values();
-        mNavigation.add("(Default)");
-        for (NavigationMethod value : nValues) {
-            mNavigation.add(value.getDisplayValue());
-        }
-        mNavigation.select(0);
-        mNavigation.setLayoutData(new GridData(
-                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-        mNavigation.addSelectionListener(new SelectionAdapter() {
-            @Override
-             public void widgetSelected(SelectionEvent e) {
-                onNavigationChange();
-            } 
-        });
-
-        Composite labelParent = new Composite(topParent, SWT.NONE);
-        labelParent.setLayout(gl = new GridLayout(8, 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;
-
-        new Label(labelParent, SWT.NONE).setText("Size");
-        mSizeIcon = createControlComposite(labelParent, false);
-        Composite sizeParent = new Composite(mSizeIcon.getParent(), SWT.NONE);
-        sizeParent.setLayout(gl = new GridLayout(3, false));
-        gl.marginWidth = gl.marginHeight = 0;
-        gl.horizontalSpacing = 0;
-
-        mSize1 = new Text(sizeParent, SWT.BORDER);
-        mSize1.setLayoutData(gd = new GridData());
-        gd.widthHint = 30;
-        new Label(sizeParent, SWT.NONE).setText("x");
-        mSize2 = new Text(sizeParent, SWT.BORDER);
-        mSize2.setLayoutData(gd = new GridData());
-        gd.widthHint = 30;
-
-        DimensionVerifier verifier = new DimensionVerifier();
-        mSize1.addVerifyListener(verifier);
-        mSize2.addVerifyListener(verifier);
-
-        SelectionListener sl = new SelectionListener() {
-            public void widgetDefaultSelected(SelectionEvent e) {
-                onSizeChange();
-            }
-            public void widgetSelected(SelectionEvent e) {
-                onSizeChange();
-            }
-        };
-
-        mSize1.addSelectionListener(sl);
-        mSize2.addSelectionListener(sl);
-        
-        ModifyListener sizeModifyListener = new ModifyListener() {
-            public void modifyText(ModifyEvent e) {
-                onSizeChange();
-            }
-        };
-
-        mSize1.addModifyListener(sizeModifyListener);
-        mSize2.addModifyListener(sizeModifyListener);
-
-        // first separator
-        Label separator = new Label(labelParent, SWT.SEPARATOR | SWT.VERTICAL);
-        separator.setLayoutData(gd = new GridData(
-                GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
-        gd.heightHint = 0;
-
-        mThemeCombo = new Combo(labelParent, 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(labelParent, SWT.SEPARATOR | SWT.VERTICAL);
-        separator.setLayoutData(gd = new GridData(
-                GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
-        gd.heightHint = 0;
-
-        mCreateButton = new Button(labelParent, SWT.PUSH | SWT.FLAT);
-        mCreateButton.setText("Create...");
-        mCreateButton.setEnabled(false);
-        mCreateButton.addSelectionListener(new SelectionAdapter() {
-            @Override
-            public void widgetSelected(SelectionEvent e) {
-                LayoutCreatorDialog dialog = new LayoutCreatorDialog(mCreateButton.getShell(),
-                        mEditedFile.getName(), mCurrentConfig);
-                if (dialog.open() == Dialog.OK) {
-                    final FolderConfiguration config = new FolderConfiguration();
-                    dialog.getConfiguration(config);
-                    
-                    createAlternateLayout(config);
-                }
-            }
-        });
-
-        // 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();
-    }
-
-    /* (non-Javadoc)
-     * Creates the palette root.
-     */
-    @Override
-    protected PaletteRoot getPaletteRoot() {
-        mPaletteRoot = PaletteFactory.createPaletteRoot(mPaletteRoot,
-                mLayoutEditor.getTargetData()); 
-        return mPaletteRoot;
-    }
-
-    @Override
-    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();
-
-            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.
-     */
-    @Override
-    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
-    //--------------
-
-    @Override
-    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.
-     */
-    @Override
-    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
-        mCreateButton.setEnabled(mEditedConfig.equals(mCurrentConfig) == false);
-    }
-    
-    public Rectangle getBounds() {
-        ScreenOrientation orientation = null;
-        if (mOrientation.getSelectionIndex() == 0) {
-            orientation = ScreenOrientation.PORTRAIT;
-        } else {
-            orientation = ScreenOrientation.getByIndex(
-                    mOrientation.getSelectionIndex() - 1);
-        }
-
-        int s1, s2;
-
-        // get the size from the UI controls. If it fails, revert to default values.
-        try {
-            s1 = Integer.parseInt(mSize1.getText().trim());
-        } catch (NumberFormatException e) {
-            s1 = 480;
-        }
-
-        try {
-            s2 = Integer.parseInt(mSize2.getText().trim());
-        } catch (NumberFormatException e) {
-            s2 = 320;
-        }
-
-        // make sure s1 is bigger than s2
-        if (s1 < s2) {
-            int tmp = s1;
-            s1 = s2;
-            s2 = tmp;
-        }
-
-        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);
-        }
-    }
-    
-    /**
-     * 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(mCurrentConfig);
-                }
-                
-                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
-                int themeIndex = mThemeCombo.getSelectionIndex();
-                if (themeIndex != -1) {
-                    String theme = mThemeCombo.getItem(themeIndex);
-
-                    // Render a single object as described by the ViewElementDescriptor.
-                    WidgetPullParser parser = new WidgetPullParser(descriptor);
-                    ILayoutResult result = computeLayout(bridge, parser,
-                            null /* projectKey */,
-                            300 /* width */, 300 /* height */, 160 /*density*/,
-                            160.f /*xdpi*/, 160.f /*ydpi*/, theme,
-                            themeIndex >= mPlatformThemeCount /*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}.
-     */
-    @Override
-    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
-     */
-    @Override
-    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) {
-        mDisableUpdates = true; // we do not want to trigger onXXXChange when setting new values in the widgets.
-
-        mEditedConfig = config;
-        mConfiguredFrameworkRes = mConfiguredProjectRes = null;
-
-        mCountryIcon.setImage(mMatchImage);
-        CountryCodeQualifier countryQualifier = config.getCountryCodeQualifier();
-        if (countryQualifier != null) {
-            mCountry.setText(String.format("%1$d", countryQualifier.getCode()));
-            mCurrentConfig.setCountryCodeQualifier(countryQualifier);
-        } else if (force) {
-            mCountry.setText(""); //$NON-NLS-1$
-            mCurrentConfig.setCountryCodeQualifier(null);
-        } else if (mCountry.getText().length() > 0) {
-            mCountryIcon.setImage(mWarningImage);
-        }
-
-        mNetworkIcon.setImage(mMatchImage);
-        NetworkCodeQualifier networkQualifier = config.getNetworkCodeQualifier();
-        if (networkQualifier != null) {
-            mNetwork.setText(String.format("%1$d", networkQualifier.getCode()));
-            mCurrentConfig.setNetworkCodeQualifier(networkQualifier);
-        } else if (force) {
-            mNetwork.setText(""); //$NON-NLS-1$
-            mCurrentConfig.setNetworkCodeQualifier(null);
-        } else if (mNetwork.getText().length() > 0) {
-            mNetworkIcon.setImage(mWarningImage);
-        }
-
-        mLanguageIcon.setImage(mMatchImage);
-        LanguageQualifier languageQualifier = config.getLanguageQualifier();
-        if (languageQualifier != null) {
-            mLanguage.setText(languageQualifier.getValue());
-            mCurrentConfig.setLanguageQualifier(languageQualifier);
-        } else if (force) {
-            mLanguage.setText(""); //$NON-NLS-1$
-            mCurrentConfig.setLanguageQualifier(null);
-        } else if (mLanguage.getText().length() > 0) {
-            mLanguageIcon.setImage(mWarningImage);
-        }
-
-        mRegionIcon.setImage(mMatchImage);
-        RegionQualifier regionQualifier = config.getRegionQualifier();
-        if (regionQualifier != null) {
-            mRegion.setText(regionQualifier.getValue());
-            mCurrentConfig.setRegionQualifier(regionQualifier);
-        } else if (force) {
-            mRegion.setText(""); //$NON-NLS-1$
-            mCurrentConfig.setRegionQualifier(null);
-        } else if (mRegion.getText().length() > 0) {
-            mRegionIcon.setImage(mWarningImage);
-        }
-
-        mOrientationIcon.setImage(mMatchImage);
-        ScreenOrientationQualifier orientationQualifier = config.getScreenOrientationQualifier();
-        if (orientationQualifier != null) {
-            mOrientation.select(
-                    ScreenOrientation.getIndex(orientationQualifier.getValue()) + 1);
-            mCurrentConfig.setScreenOrientationQualifier(orientationQualifier);
-        } else if (force) {
-            mOrientation.select(0);
-            mCurrentConfig.setScreenOrientationQualifier(null);
-        } else if (mOrientation.getSelectionIndex() != 0) {
-            mOrientationIcon.setImage(mWarningImage);
-        }
-
-        mDensityIcon.setImage(mMatchImage);
-        PixelDensityQualifier densityQualifier = config.getPixelDensityQualifier();
-        if (densityQualifier != null) {
-            mDensity.setText(String.format("%1$d", densityQualifier.getValue()));
-            mCurrentConfig.setPixelDensityQualifier(densityQualifier);
-        } else if (force) {
-            mDensity.setText(""); //$NON-NLS-1$
-            mCurrentConfig.setPixelDensityQualifier(null);
-        } else if (mDensity.getText().length() > 0) {
-            mDensityIcon.setImage(mWarningImage);
-        }
-
-        mTouchIcon.setImage(mMatchImage);
-        TouchScreenQualifier touchQualifier = config.getTouchTypeQualifier();
-        if (touchQualifier != null) {
-            mTouch.select(TouchScreenType.getIndex(touchQualifier.getValue()) + 1);
-            mCurrentConfig.setTouchTypeQualifier(touchQualifier);
-        } else if (force) {
-            mTouch.select(0);
-            mCurrentConfig.setTouchTypeQualifier(null);
-        } else if (mTouch.getSelectionIndex() != 0) {
-            mTouchIcon.setImage(mWarningImage);
-        }
-
-        mKeyboardIcon.setImage(mMatchImage);
-        KeyboardStateQualifier keyboardQualifier = config.getKeyboardStateQualifier();
-        if (keyboardQualifier != null) {
-            mKeyboard.select(KeyboardState.getIndex(keyboardQualifier.getValue()) + 1);
-            mCurrentConfig.setKeyboardStateQualifier(keyboardQualifier);
-        } else if (force) {
-            mKeyboard.select(0);
-            mCurrentConfig.setKeyboardStateQualifier(null);
-        } else if (mKeyboard.getSelectionIndex() != 0) {
-            mKeyboardIcon.setImage(mWarningImage);
-        }
-
-        mTextInputIcon.setImage(mMatchImage);
-        TextInputMethodQualifier inputQualifier = config.getTextInputMethodQualifier();
-        if (inputQualifier != null) {
-            mTextInput.select(TextInputMethod.getIndex(inputQualifier.getValue()) + 1);
-            mCurrentConfig.setTextInputMethodQualifier(inputQualifier);
-        } else if (force) {
-            mTextInput.select(0);
-            mCurrentConfig.setTextInputMethodQualifier(null);
-        } else if (mTextInput.getSelectionIndex() != 0) {
-            mTextInputIcon.setImage(mWarningImage);
-        }
-
-        mNavigationIcon.setImage(mMatchImage);
-        NavigationMethodQualifier navigationQualifiter = config.getNavigationMethodQualifier();
-        if (navigationQualifiter != null) {
-            mNavigation.select(
-                    NavigationMethod.getIndex(navigationQualifiter.getValue()) + 1);
-            mCurrentConfig.setNavigationMethodQualifier(navigationQualifiter);
-        } else if (force) {
-            mNavigation.select(0);
-            mCurrentConfig.setNavigationMethodQualifier(null);
-        } else if (mNavigation.getSelectionIndex() != 0) {
-            mNavigationIcon.setImage(mWarningImage);
-        }
-
-        mSizeIcon.setImage(mMatchImage);
-        ScreenDimensionQualifier sizeQualifier = config.getScreenDimensionQualifier();
-        if (sizeQualifier != null) {
-            mSize1.setText(String.format("%1$d", sizeQualifier.getValue1()));
-            mSize2.setText(String.format("%1$d", sizeQualifier.getValue2()));
-            mCurrentConfig.setScreenDimensionQualifier(sizeQualifier);
-        } else if (force) {
-            mSize1.setText(""); //$NON-NLS-1$
-            mSize2.setText(""); //$NON-NLS-1$
-            mCurrentConfig.setScreenDimensionQualifier(null);
-        } else if (mSize1.getText().length() > 0 && mSize2.getText().length() > 0) {
-            mSizeIcon.setImage(mWarningImage);
-        }
-
-        // update the string showing the folder name
-        String current = config.toDisplayString();
-        mCurrentLayoutLabel.setText(current != null ? current : "(Default)");
-        
-        mDisableUpdates = false;
-    }
-    
-    /**
-     * Displays an error icon in front of all the non-null qualifiers.
-     */
-    void displayConfigError() {
-        mCountryIcon.setImage(mMatchImage);
-        CountryCodeQualifier countryQualifier = mCurrentConfig.getCountryCodeQualifier();
-        if (countryQualifier != null) {
-            mCountryIcon.setImage(mErrorImage);
-        }
-        
-        mNetworkIcon.setImage(mMatchImage);
-        NetworkCodeQualifier networkQualifier = mCurrentConfig.getNetworkCodeQualifier();
-        if (networkQualifier != null) {
-            mNetworkIcon.setImage(mErrorImage);
-        }
-        
-        mLanguageIcon.setImage(mMatchImage);
-        LanguageQualifier languageQualifier = mCurrentConfig.getLanguageQualifier();
-        if (languageQualifier != null) {
-            mLanguageIcon.setImage(mErrorImage);
-        }
-        
-        mRegionIcon.setImage(mMatchImage);
-        RegionQualifier regionQualifier = mCurrentConfig.getRegionQualifier();
-        if (regionQualifier != null) {
-            mRegionIcon.setImage(mErrorImage);
-        }
-        
-        mOrientationIcon.setImage(mMatchImage);
-        ScreenOrientationQualifier orientationQualifier =
-            mCurrentConfig.getScreenOrientationQualifier();
-        if (orientationQualifier != null) {
-            mOrientationIcon.setImage(mErrorImage);
-        }
-        
-        mDensityIcon.setImage(mMatchImage);
-        PixelDensityQualifier densityQualifier = mCurrentConfig.getPixelDensityQualifier();
-        if (densityQualifier != null) {
-            mDensityIcon.setImage(mErrorImage);
-        }
-        
-        mTouchIcon.setImage(mMatchImage);
-        TouchScreenQualifier touchQualifier = mCurrentConfig.getTouchTypeQualifier();
-        if (touchQualifier != null) {
-            mTouchIcon.setImage(mErrorImage);
-        }
-        
-        mKeyboardIcon.setImage(mMatchImage);
-        KeyboardStateQualifier keyboardQualifier = mCurrentConfig.getKeyboardStateQualifier();
-        if (keyboardQualifier != null) {
-            mKeyboardIcon.setImage(mErrorImage);
-        }
-
-        mTextInputIcon.setImage(mMatchImage);
-        TextInputMethodQualifier inputQualifier = mCurrentConfig.getTextInputMethodQualifier();
-        if (inputQualifier != null) {
-            mTextInputIcon.setImage(mErrorImage);
-        }
-        
-        mNavigationIcon.setImage(mMatchImage);
-        NavigationMethodQualifier navigationQualifiter =
-            mCurrentConfig.getNavigationMethodQualifier();
-        if (navigationQualifiter != null) {
-            mNavigationIcon.setImage(mErrorImage);
-        }
-        
-        mSizeIcon.setImage(mMatchImage);
-        ScreenDimensionQualifier sizeQualifier = mCurrentConfig.getScreenDimensionQualifier();
-        if (sizeQualifier != null) {
-            mSizeIcon.setImage(mErrorImage);
-        }
-        
-        // update the string showing the folder name
-        String current = mCurrentConfig.toDisplayString();
-        mCurrentLayoutLabel.setText(current != null ? current : "(Default)");
-    }
-
-    @Override
-    UiDocumentNode getModel() {
-        return mLayoutEditor.getUiRootNode();
-    }
-    
-    @Override
-    void reloadPalette() {
-        PaletteFactory.createPaletteRoot(mPaletteRoot, mLayoutEditor.getTargetData());
-    }
-
-    private void onCountryCodeChange() {
-        // because mCountry triggers onCountryCodeChange at each modification, calling setText()
-        // will trigger notifications, and we don't want that.
-        if (mDisableUpdates == true) {
-            return;
-        }
-
-        // update the current config
-        String value = mCountry.getText();
-
-        // empty string, means no qualifier.
-        if (value.length() == 0) {
-            mCurrentConfig.setCountryCodeQualifier(null);
-        } else {
-            try {
-                CountryCodeQualifier qualifier = CountryCodeQualifier.getQualifier(
-                        CountryCodeQualifier.getFolderSegment(Integer.parseInt(value)));
-                if (qualifier != null) {
-                    mCurrentConfig.setCountryCodeQualifier(qualifier);
-                } else {
-                    // Failure! Looks like the value is wrong (for instance a one letter string).
-                    // We do nothing in this case.
-                    mCountryIcon.setImage(mErrorImage);
-                    return;
-                }
-            } catch (NumberFormatException e) {
-                // Looks like the code is not a number. This should not happen since the text
-                // field has a VerifyListener that prevents it.
-                mCurrentConfig.setCountryCodeQualifier(null);
-                mCountryIcon.setImage(mErrorImage);
-            }
-        }
-
-        // look for a file to open/create
-        onConfigurationChange();
-    }
-
-    private void onNetworkCodeChange() {
-        // because mNetwork triggers onNetworkCodeChange at each modification, calling setText()
-        // will trigger notifications, and we don't want that.
-        if (mDisableUpdates == true) {
-            return;
-        }
-
-        // update the current config
-        String value = mNetwork.getText();
-
-        // empty string, means no qualifier.
-        if (value.length() == 0) {
-            mCurrentConfig.setNetworkCodeQualifier(null);
-        } else {
-            try {
-                NetworkCodeQualifier qualifier = NetworkCodeQualifier.getQualifier(
-                        NetworkCodeQualifier.getFolderSegment(Integer.parseInt(value)));
-                if (qualifier != null) {
-                    mCurrentConfig.setNetworkCodeQualifier(qualifier);
-                } else {
-                    // Failure! Looks like the value is wrong (for instance a one letter string).
-                    // We do nothing in this case.
-                    mNetworkIcon.setImage(mErrorImage);
-                    return;
-                }
-            } catch (NumberFormatException e) {
-                // Looks like the code is not a number. This should not happen since the text
-                // field has a VerifyListener that prevents it.
-                mCurrentConfig.setNetworkCodeQualifier(null);
-                mNetworkIcon.setImage(mErrorImage);
-            }
-        }
-
-        // look for a file to open/create
-        onConfigurationChange();
-    }
-
-    /**
-     * Call back for language combo selection
-     */
-    private void onLanguageChange() {
-        // 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;
-        }
-
-        // update the current config
-        String value = mLanguage.getText();
-
-        updateRegionUi(null /* projectResources */, null /* frameworkResources */);
-
-        // empty string, means no qualifier.
-        if (value.length() == 0) {
-            mCurrentConfig.setLanguageQualifier(null);
-        } else {
-            LanguageQualifier qualifier = null;
-            String segment = LanguageQualifier.getFolderSegment(value);
-            if (segment != null) {
-                qualifier = LanguageQualifier.getQualifier(segment);
-            }
-
-            if (qualifier != null) {
-                mCurrentConfig.setLanguageQualifier(qualifier);
-            } else {
-                // Failure! Looks like the value is wrong (for instance a one letter string).
-                mCurrentConfig.setLanguageQualifier(null);
-                mLanguageIcon.setImage(mErrorImage);
-            }
-        }
-
-        // look for a file to open/create
-        onConfigurationChange();
-    }
-
-    private void onRegionChange() {
-        // because mRegion triggers onRegionChange at each modification, the filling
-        // of the combo with data will trigger notifications, and we don't want that.
-        if (mDisableUpdates == true) {
-            return;
-        }
-
-        // update the current config
-        String value = mRegion.getText();
-
-        // empty string, means no qualifier.
-        if (value.length() == 0) {
-            mCurrentConfig.setRegionQualifier(null);
-        } else {
-            RegionQualifier qualifier = null;
-            String segment = RegionQualifier.getFolderSegment(value);
-            if (segment != null) {
-                qualifier = RegionQualifier.getQualifier(segment);
-            }
-
-            if (qualifier != null) {
-                mCurrentConfig.setRegionQualifier(qualifier);
-            } else {
-                // Failure! Looks like the value is wrong (for instance a one letter string).
-                mCurrentConfig.setRegionQualifier(null);
-                mRegionIcon.setImage(mErrorImage);
-            }
-        }
-
-        // look for a file to open/create
-        onConfigurationChange();
-    }
-
-    private void onOrientationChange() {
-        // update the current config
-        int index = mOrientation.getSelectionIndex();
-        if (index != 0) {
-            mCurrentConfig.setScreenOrientationQualifier(new ScreenOrientationQualifier(
-                ScreenOrientation.getByIndex(index-1)));
-        } else {
-            mCurrentConfig.setScreenOrientationQualifier(null);
-        }
-
-        // look for a file to open/create
-        onConfigurationChange();
-    }
-
-    private void onDensityChange() {
-        // because mDensity triggers onDensityChange at each modification, calling setText()
-        // will trigger notifications, and we don't want that.
-        if (mDisableUpdates == true) {
-            return;
-        }
-
-        // update the current config
-        String value = mDensity.getText();
-
-        // empty string, means no qualifier.
-        if (value.length() == 0) {
-            mCurrentConfig.setPixelDensityQualifier(null);
-        } else {
-            try {
-                PixelDensityQualifier qualifier = PixelDensityQualifier.getQualifier(
-                        PixelDensityQualifier.getFolderSegment(Integer.parseInt(value)));
-                if (qualifier != null) {
-                    mCurrentConfig.setPixelDensityQualifier(qualifier);
-                } else {
-                    // Failure! Looks like the value is wrong (for instance a one letter string).
-                    // We do nothing in this case.
-                    return;
-                }
-            } catch (NumberFormatException e) {
-                // Looks like the code is not a number. This should not happen since the text
-                // field has a VerifyListener that prevents it.
-                // We do nothing in this case.
-                mDensityIcon.setImage(mErrorImage);
-                return;
-            }
-        }
-
-        // look for a file to open/create
-        onConfigurationChange();
-    }
-
-    private void onTouchChange() {
-        // update the current config
-        int index = mTouch.getSelectionIndex();
-        if (index != 0) {
-            mCurrentConfig.setTouchTypeQualifier(new TouchScreenQualifier(
-                TouchScreenType.getByIndex(index-1)));
-        } else {
-            mCurrentConfig.setTouchTypeQualifier(null);
-        }
-
-        // look for a file to open/create
-        onConfigurationChange();
-    }
-
-    private void onKeyboardChange() {
-        // update the current config
-        int index = mKeyboard.getSelectionIndex();
-        if (index != 0) {
-            mCurrentConfig.setKeyboardStateQualifier(new KeyboardStateQualifier(
-                KeyboardState.getByIndex(index-1)));
-        } else {
-            mCurrentConfig.setKeyboardStateQualifier(null);
-        }
-
-        // look for a file to open/create
-        onConfigurationChange();
-    }
-
-    private void onTextInputChange() {
-        // update the current config
-        int index = mTextInput.getSelectionIndex();
-        if (index != 0) {
-            mCurrentConfig.setTextInputMethodQualifier(new TextInputMethodQualifier(
-                TextInputMethod.getByIndex(index-1)));
-        } else {
-            mCurrentConfig.setTextInputMethodQualifier(null);
-        }
-
-        // look for a file to open/create
-        onConfigurationChange();
-    }
-
-    private void onNavigationChange() {
-        // update the current config
-        int index = mNavigation.getSelectionIndex();
-        if (index != 0) {
-            mCurrentConfig.setNavigationMethodQualifier(new NavigationMethodQualifier(
-                NavigationMethod.getByIndex(index-1)));
-        } else {
-            mCurrentConfig.setNavigationMethodQualifier(null);
-        }
-
-        // look for a file to open/create
-        onConfigurationChange();
-    }
-
-    private void onSizeChange() {
-        // because mSize1 and mSize2 trigger onSizeChange at each modification, calling setText()
-        // will trigger notifications, and we don't want that.
-        if (mDisableUpdates == true) {
-            return;
-        }
-
-        // update the current config
-        String size1 = mSize1.getText();
-        String size2 = mSize2.getText();
-
-        // if only one of the strings is empty, do nothing
-        if ((size1.length() == 0) ^ (size2.length() == 0)) {
-            mSizeIcon.setImage(mErrorImage);
-            return;
-        } else if (size1.length() == 0 && size2.length() == 0) {
-            // both sizes are empty: remove the qualifier.
-            mCurrentConfig.setScreenDimensionQualifier(null);
-        } else {
-            ScreenDimensionQualifier qualifier = ScreenDimensionQualifier.getQualifier(size1,
-                    size2);
-
-            if (qualifier != null) {
-                mCurrentConfig.setScreenDimensionQualifier(qualifier);
-            } else {
-                // Failure! Looks like the value is wrong.
-                // we do nothing in this case.
-                return;
-            }
-        }
-
-        // look for a file to open/create
-        onConfigurationChange();
-    }
-
-
-    /**
-     * Looks for a file matching the new {@link FolderConfiguration} and attempts to open it.
-     * <p/>If there is no match, notify the user.
-     */
-    private 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,
-                                              mCurrentConfig);
-        }
-
-        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
-            mCreateButton.setEnabled(mEditedConfig.equals(mCurrentConfig) == false);
-
-            // Even though the layout doesn't change, the config changed, and referenced
-            // resources need to be updated.
-            recomputeLayout();
-        } else {
-            // update the configuration icons with the new edited config.
-            displayConfigError();
-            
-            // enable the Create button
-            mCreateButton.setEnabled(true);
-
-            // display the error.
-            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.",
-                    mCurrentConfig.toDisplayString(),
-                    mCurrentConfig.getFolderName(ResourceFolderType.LAYOUT),
-                    mEditedFile.getName());
-            showErrorInEditor(message);
-        }
-    }
-
-    private void onThemeChange() {
-        int themeIndex = mThemeCombo.getSelectionIndex();
-        if (themeIndex != -1) {
-            String theme = mThemeCombo.getItem(themeIndex);
-            
-            if (theme.equals(THEME_SEPARATOR)) {
-                mThemeCombo.select(0);
-            }
-
-            recomputeLayout();
-        }
-    }
-
-    /**
-     * Creates a composite with no margin/spacing, and puts a {@link Label} in it with the matching
-     * icon.
-     * @param parent the parent to receive the composite
-     * @return the created {@link Label} object.
-     */
-    private Label createControlComposite(Composite parent, boolean grab) {
-        GridLayout gl;
-
-        Composite composite = new Composite(parent, SWT.NONE);
-        composite.setLayout(gl = new GridLayout(2, false));
-        gl.marginHeight = gl.marginWidth = 0;
-        gl.horizontalSpacing = 0;
-        if (grab) {
-            composite.setLayoutData(
-                    new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
-        }
-
-        // create the label
-        Label icon = new Label(composite, SWT.NONE);
-        icon.setImage(mMatchImage);
-
-        return icon;
-    }
-
-    /**
-     * Recomputes the layout with the help of layoutlib.
-     */
-    @Override
-    @SuppressWarnings("deprecation")
-    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.
-                    if (mConfiguredProjectRes == null) {
-                        // make sure they are loaded
-                        projectRes.loadAll();
-    
-                        // get the project resource values based on the current config
-                        mConfiguredProjectRes = projectRes.getConfiguredResources(mCurrentConfig);
-                    }
-    
-                    // get the framework resources
-                    Map<String, Map<String, IResourceValue>> frameworkResources =
-                        getConfiguredFrameworkResources();
-    
-                    if (mConfiguredProjectRes != 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
-                        int themeIndex = mThemeCombo.getSelectionIndex();
-                        if (themeIndex != -1) {
-                            String theme = mThemeCombo.getItem(themeIndex);
-                            
-                            // Compute the layout
-                            UiElementPullParser parser = new UiElementPullParser(getModel());
-                            Rectangle rect = getBounds();
-                            boolean isProjectTheme = themeIndex >= mPlatformThemeCount;
-
-                            // FIXME pass the density/dpi from somewhere (resource config or skin).
-                            ILayoutResult result = computeLayout(bridge, parser,
-                                    iProject /* projectKey */,
-                                    rect.width, rect.height, 160, 160.f, 160.f, 
-                                    theme, isProjectTheme,
-                                    mConfiguredProjectRes, 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.
-     */
-    @Override
-    void activated() {
-        if (mNeedsRecompute || mNeedsXmlReload) {
-            recomputeLayout();
-        }
-    }
-
-    /**
-     * Responds to a page change that made the Graphical editor page the deactivated page
-     */
-    @Override
-    void deactivated() {
-        // nothing to be done here for now.
-    }
-
-    /**
-     * Updates the UI from values in the resources, such as languages, regions, themes, etc...
-     * This must be called from the UI thread.
-     */
-    private void updateUIFromResources() {
-
-        ResourceManager manager = ResourceManager.getInstance();
-
-        ProjectResources frameworkProject = getFrameworkResources();
-
-        mDisableUpdates = true;
-        
-        // Reset stuff
-        int selection = mThemeCombo.getSelectionIndex();
-        mThemeCombo.removeAll();
-        mPlatformThemeCount = 0;
-        mLanguage.removeAll();
-        
-        Set<String> languages = new HashSet<String>();
-        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 =
-                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 languages from the framework.
-            Set<String> frameworkLanguages = frameworkProject.getLanguages();
-            if (frameworkLanguages != null) {
-                languages.addAll(frameworkLanguages);
-            }
-        }
-        
-        // now get the themes and languages from the project.
-        ProjectResources project = null;
-        if (mEditedFile != null) {
-            project = manager.getProjectResources(mEditedFile.getProject());
-
-            // 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 
-                if (mConfiguredProjectRes == null) {
-                    // make sure they are loaded
-                    project.loadAll();
-
-                    // get the project resource values based on the current config
-                    mConfiguredProjectRes = project.getConfiguredResources(mCurrentConfig);
-                }
-                
-                if (mConfiguredProjectRes != null) {
-                    // get the styles.
-                    Map<String, IResourceValue> styleMap = mConfiguredProjectRes.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.
-                Set<String> projectLanguages = project.getLanguages();
-                if (projectLanguages != null) {
-                    languages.addAll(projectLanguages);
-                }
-            }
-        }
-
-        // add the languages to the Combo
-        for (String language : languages) {
-            mLanguage.add(language);
-        }
-        
-        mDisableUpdates = false;
-
-        // and update the Region UI based on the current language
-        updateRegionUi(project, frameworkProject);
-
-        // 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);
-        }
-    }
-
-    /**
-     * 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 (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;
-    }
-
-    /**
-     * Update the Region UI widget based on the current language selection
-     * @param projectResources the project resources or {@code null}.
-     * @param frameworkResources the framework resource or {@code null}
-     */
-    private void updateRegionUi(ProjectResources projectResources,
-            ProjectResources frameworkResources) {
-        if (projectResources == null && mEditedFile != null) {
-            projectResources = ResourceManager.getInstance().getProjectResources(
-                    mEditedFile.getProject());
-        }
-
-        if (frameworkResources == null) {
-            frameworkResources = getFrameworkResources();
-        }
-
-        String currentLanguage = mLanguage.getText();
-
-        Set<String> set = null;
-
-        if (projectResources != null) {
-            set = projectResources.getRegions(currentLanguage);
-        }
-
-        if (frameworkResources != null) {
-            if (set != null) {
-                Set<String> set2 = frameworkResources.getRegions(currentLanguage);
-                set.addAll(set2);
-            } else {
-                set = frameworkResources.getRegions(currentLanguage);
-            }
-        }
-
-        if (set != null) {
-            mDisableUpdates = true;
-
-            mRegion.removeAll();
-            for (String region : set) {
-                mRegion.add(region);
-            }
-
-            mDisableUpdates = false;
-        }
-    }
-    
-    private 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");
-            }
-
-            // get the framework resource values based on the current config
-            mConfiguredFrameworkRes = frameworkRes.getConfiguredResources(mCurrentConfig);
-        }
-        
-        return mConfiguredFrameworkRes;
-    }
-
-    /**
-     * Creates a new layout file from the specificed {@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);
-                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() {
-                            mCurrentConfig.set(config);
-                            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();
-    }
-    
-    /**
-     * Returns a {@link ProjectResources} for the framework resources.
-     * @return the framework resources or null if not found.
-     */
-    private 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;
-    }
-    
-    /**
-     * Computes a layout by calling the correct computeLayout method of ILayoutBridge based on
-     * the implementation API level.
-     */
-    @SuppressWarnings("deprecation")
-    private ILayoutResult computeLayout(LayoutBridge bridge,
-            IXmlPullParser layoutDescription, Object projectKey,
-            int screenWidth, int screenHeight, 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 >= 3) {
-            // newer api with boolean for separation of project/framework theme,
-            // and 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,
-                    mConfiguredProjectRes, frameworkResources, mProjectCallback,
-                    mLogger);
-        } 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,
-                    mConfiguredProjectRes, frameworkResources, mProjectCallback,
-                    mLogger);
-        }
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutConstants.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutConstants.java
deleted file mode 100644
index d4ec5e1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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/editors/layout/LayoutContentAssist.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutContentAssist.java
deleted file mode 100644
index 9f39495..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.layout;
-
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.editors.AndroidContentAssist;
-
-/**
- * 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/editors/layout/LayoutCreatorDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutCreatorDialog.java
deleted file mode 100644
index 6940238..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutCreatorDialog.java
+++ /dev/null
@@ -1,140 +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.editors.layout;
-
-import com.android.ide.eclipse.adt.ui.ConfigurationSelector;
-import com.android.ide.eclipse.adt.ui.ConfigurationSelector.ConfigurationState;
-import com.android.ide.eclipse.editors.IconFactory;
-import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.editors.resources.configurations.ResourceQualifier;
-import com.android.ide.eclipse.editors.resources.manager.ResourceFolderType;
-
-import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.TrayDialog;
-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.Label;
-import org.eclipse.swt.widgets.Shell;
-
-/**
- * Dialog to choose a non existing {@link FolderConfiguration}.
- */
-class LayoutCreatorDialog extends TrayDialog {
-
-    private ConfigurationSelector mSelector;
-    private Composite mStatusComposite;
-    private Label mStatusLabel; 
-    private Label mStatusImage;
-
-    private final FolderConfiguration mConfig = new FolderConfiguration();
-    private final String mFileName;
-
-    /**
-     * Creates a dialog, and init the UI from a {@link FolderConfiguration}.
-     * @param parentShell the parent {@link Shell}.
-     * @param config The starting configuration.
-     */
-    LayoutCreatorDialog(Shell parentShell, String fileName, FolderConfiguration config) {
-        super(parentShell);
-
-        mFileName = fileName;        
-        // FIXME: add some data to know what configurations already exist. 
-        mConfig.set(config);
-    }
-
-    @Override
-    protected Control createDialogArea(Composite parent) {
-        Composite top = new Composite(parent, SWT.NONE);
-        top.setLayoutData(new GridData());
-        top.setLayout(new GridLayout(1, false));
-
-        new Label(top, SWT.NONE).setText(
-                String.format("Configuration for the alternate version of %1$s", mFileName));
-        
-        mSelector = new ConfigurationSelector(top);
-        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(top, 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();
-
-        return top;
-    }
-    
-    public void getConfiguration(FolderConfiguration config) {
-        config.set(mConfig);
-    }
-    
-    /**
-     * resets the status label to show the file that will be created.
-     */
-    private void resetStatus() {
-        mStatusLabel.setText(String.format("New File: res/%1$s/%2$s",
-                mConfig.getFolderName(ResourceFolderType.LAYOUT), mFileName));
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutEditor.java
deleted file mode 100644
index 7bed7ce..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutEditor.java
+++ /dev/null
@@ -1,419 +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.editors.layout;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.ui.EclipseUiHelper;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.descriptors.DocumentDescriptor;
-import com.android.ide.eclipse.editors.resources.manager.ResourceFolder;
-import com.android.ide.eclipse.editors.resources.manager.ResourceManager;
-import com.android.ide.eclipse.editors.ui.tree.UiActions;
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-
-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 AbstractGraphicalLayoutEditor 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) {
-                if (mGraphicalEditor == null) {
-                    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) {
-                mOutline = new UiContentOutlinePage(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.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/editors/layout/LayoutReloadMonitor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutReloadMonitor.java
deleted file mode 100644
index cf20288..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutReloadMonitor.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.editors.layout;
-
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.editors.resources.manager.ResourceFolder;
-import com.android.ide.eclipse.editors.resources.manager.ResourceFolderType;
-import com.android.ide.eclipse.editors.resources.manager.ResourceManager;
-import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor;
-import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IFileListener;
-import com.android.ide.eclipse.editors.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.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}.
-     * @param project
-     * @param listener
-     */
-    public void removeListener(IProject project, ILayoutReloadListener listener) {
-        synchronized (mListenerMap) {
-            List<ILayoutReloadListener> list = mListenerMap.get(project);
-            if (list != null) {
-                list.remove(listener);
-            }
-        }
-    }
-
-    /*
-     * (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/editors/layout/LayoutSourceViewerConfig.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutSourceViewerConfig.java
deleted file mode 100644
index 1aa1f4c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.layout;
-
-
-import com.android.ide.eclipse.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/editors/layout/MatchingStrategy.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/MatchingStrategy.java
deleted file mode 100644
index bb075c2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.layout;
-
-import com.android.ide.eclipse.editors.resources.manager.ResourceFolder;
-import com.android.ide.eclipse.editors.resources.manager.ResourceFolderType;
-import com.android.ide.eclipse.editors.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/editors/layout/PaletteFactory.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/PaletteFactory.java
deleted file mode 100644
index 94df28f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/PaletteFactory.java
+++ /dev/null
@@ -1,93 +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.editors.layout;
-
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-
-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}.
- */
-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/editors/layout/ProjectCallback.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/ProjectCallback.java
deleted file mode 100644
index 94ad87a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.layout;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-import com.android.ide.eclipse.editors.resources.manager.ProjectClassLoader;
-import com.android.ide.eclipse.editors.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/editors/layout/UiContentOutlinePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/UiContentOutlinePage.java
deleted file mode 100644
index 4e0e35f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/UiContentOutlinePage.java
+++ /dev/null
@@ -1,615 +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.editors.layout;
-
-import com.android.ide.eclipse.adt.ui.EclipseUiHelper;
-import com.android.ide.eclipse.editors.IconFactory;
-import com.android.ide.eclipse.editors.layout.parts.UiDocumentTreeEditPart;
-import com.android.ide.eclipse.editors.layout.parts.UiElementTreeEditPart;
-import com.android.ide.eclipse.editors.layout.parts.UiElementTreeEditPartFactory;
-import com.android.ide.eclipse.editors.layout.parts.UiLayoutTreeEditPart;
-import com.android.ide.eclipse.editors.layout.parts.UiViewTreeEditPart;
-import com.android.ide.eclipse.editors.ui.tree.CopyCutAction;
-import com.android.ide.eclipse.editors.ui.tree.PasteAction;
-import com.android.ide.eclipse.editors.ui.tree.UiActions;
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-
-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}.
- */
-class UiContentOutlinePage extends ContentOutlinePage {
-
-    private AbstractGraphicalLayoutEditor mEditor;
-    
-    private Action mAddAction;
-    private Action mDeleteAction;
-    private Action mUpAction;
-    private Action mDownAction;
-    
-    private UiOutlineActions mUiActions = new UiOutlineActions();
-
-    public UiContentOutlinePage(AbstractGraphicalLayoutEditor 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 GraphicalLayoutEditor}.
-     * <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/editors/layout/UiElementPullParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/UiElementPullParser.java
deleted file mode 100644
index b0e6fdb..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.layout;
-
-import com.android.ide.eclipse.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/editors/layout/UiPropertySheetPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/UiPropertySheetPage.java
deleted file mode 100644
index 8093c90..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/UiPropertySheetPage.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.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.
- */
-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/editors/layout/WidgetPullParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/WidgetPullParser.java
deleted file mode 100644
index e62ab69..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.layout;
-
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.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/editors/layout/descriptors/CustomViewDescriptorService.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/descriptors/CustomViewDescriptorService.java
deleted file mode 100644
index d5ee2ca..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.layout.descriptors;
-
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.common.resources.ViewClassInfo;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-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/editors/layout/descriptors/LayoutDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/descriptors/LayoutDescriptors.java
deleted file mode 100644
index a59ad6f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.layout.descriptors;
-
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.resources.DeclareStyleableInfo;
-import com.android.ide.eclipse.common.resources.ViewClassInfo;
-import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo;
-import com.android.ide.eclipse.common.resources.ViewClassInfo.LayoutParamsInfo;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.editors.descriptors.DocumentDescriptor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.editors.descriptors.SeparatorAttributeDescriptor;
-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/editors/layout/descriptors/ViewElementDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/descriptors/ViewElementDescriptor.java
deleted file mode 100644
index d718ebd..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.layout.descriptors;
-
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.layout.uimodel.UiViewElementNode;
-import com.android.ide.eclipse.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/editors/layout/parts/DropFeedback.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/DropFeedback.java
deleted file mode 100644
index b7d69af..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/DropFeedback.java
+++ /dev/null
@@ -1,763 +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.editors.layout.parts;
-
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.layout.LayoutConstants;
-import com.android.ide.eclipse.editors.layout.LayoutEditor.UiEditorActions;
-import com.android.ide.eclipse.editors.layout.parts.UiLayoutEditPart.HighlightInfo;
-import com.android.ide.eclipse.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.
- */
-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/editors/layout/parts/ElementCreateCommand.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/ElementCreateCommand.java
deleted file mode 100644
index d36d9f7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/ElementCreateCommand.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.editors.layout.parts;
-
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.layout.LayoutEditor;
-import com.android.ide.eclipse.editors.layout.LayoutEditor.UiEditorActions;
-import com.android.ide.eclipse.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.
- */
-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/editors/layout/parts/ElementFigure.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/ElementFigure.java
deleted file mode 100644
index f863037..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/ElementFigure.java
+++ /dev/null
@@ -1,75 +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.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.
- */
-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/editors/layout/parts/LayoutFigure.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/LayoutFigure.java
deleted file mode 100644
index 55ed39b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/LayoutFigure.java
+++ /dev/null
@@ -1,151 +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.editors.layout.parts;
-
-import com.android.ide.eclipse.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.
- */
-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/editors/layout/parts/UiDocumentEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiDocumentEditPart.java
deleted file mode 100644
index 2f7636d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiDocumentEditPart.java
+++ /dev/null
@@ -1,212 +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.editors.layout.parts;
-
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.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. 
- */
-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/editors/layout/parts/UiDocumentTreeEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiDocumentTreeEditPart.java
deleted file mode 100644
index af22afb..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiDocumentTreeEditPart.java
+++ /dev/null
@@ -1,37 +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.editors.layout.parts;
-
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-
-import java.util.List;
-
-/**
- * Implementation of {@link UiElementTreeEditPart} for the document root.
- */
-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/editors/layout/parts/UiElementEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiElementEditPart.java
deleted file mode 100644
index a2e05c7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiElementEditPart.java
+++ /dev/null
@@ -1,345 +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.editors.layout.parts;
-
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.uimodel.IUiUpdateListener;
-import com.android.ide.eclipse.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}.
- */
-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/editors/layout/parts/UiElementTreeEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiElementTreeEditPart.java
deleted file mode 100644
index fd788dd..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiElementTreeEditPart.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.editors.layout.parts;
-
-import com.android.ide.eclipse.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.
- */
-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/editors/layout/parts/UiElementTreeEditPartFactory.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiElementTreeEditPartFactory.java
deleted file mode 100644
index de6c404..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiElementTreeEditPartFactory.java
+++ /dev/null
@@ -1,47 +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.editors.layout.parts;
-
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.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. 
- */
-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/editors/layout/parts/UiElementsEditPartFactory.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiElementsEditPartFactory.java
deleted file mode 100644
index 18dcd9c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiElementsEditPartFactory.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.editors.layout.parts;
-
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.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}.
- */
-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/editors/layout/parts/UiLayoutEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiLayoutEditPart.java
deleted file mode 100644
index 43a70a5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiLayoutEditPart.java
+++ /dev/null
@@ -1,115 +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.editors.layout.parts;
-
-import com.android.ide.eclipse.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. 
- */
-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/editors/layout/parts/UiLayoutTreeEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiLayoutTreeEditPart.java
deleted file mode 100644
index 4359e23..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiLayoutTreeEditPart.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.editors.layout.parts;
-
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-
-import java.util.List;
-
-/**
- * Implementation of {@link UiElementTreeEditPart} for layout objects.
- */
-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/editors/layout/parts/UiViewEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiViewEditPart.java
deleted file mode 100644
index 05329f3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiViewEditPart.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.editors.layout.parts;
-
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-
-import org.eclipse.draw2d.IFigure;
-import org.eclipse.draw2d.XYLayout;
-
-/**
- * Graphical edit part for an {@link UiElementNode} that represents a View.
- */
-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/editors/layout/parts/UiViewTreeEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiViewTreeEditPart.java
deleted file mode 100644
index 62b5e8a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiViewTreeEditPart.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.editors.layout.parts;
-
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-
-/**
- * Implementation of {@link UiElementTreeEditPart} for view objects.
- */
-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/editors/layout/uimodel/UiViewElementNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/uimodel/UiViewElementNode.java
deleted file mode 100644
index 738591a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.layout.uimodel;
-
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.editors.layout.descriptors.ViewElementDescriptor;
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-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/editors/manifest/ManifestContentAssist.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/ManifestContentAssist.java
deleted file mode 100644
index b40e458..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest;
-
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.editors.AndroidContentAssist;
-
-/**
- * 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/editors/manifest/ManifestEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/ManifestEditor.java
deleted file mode 100644
index dc32383..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/ManifestEditor.java
+++ /dev/null
@@ -1,386 +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.editors.manifest;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidXPathFactory;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.editors.manifest.pages.ApplicationPage;
-import com.android.ide.eclipse.editors.manifest.pages.InstrumentationPage;
-import com.android.ide.eclipse.editors.manifest.pages.OverviewPage;
-import com.android.ide.eclipse.editors.manifest.pages.PermissionPage;
-import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor;
-import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IFileListener;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-
-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 {
-    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/editors/manifest/ManifestEditorContributor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/ManifestEditorContributor.java
deleted file mode 100644
index 911faa1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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/editors/manifest/ManifestSourceViewerConfig.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/ManifestSourceViewerConfig.java
deleted file mode 100644
index e33e1ef..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest;
-
-
-import com.android.ide.eclipse.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/editors/manifest/descriptors/AndroidManifestDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java
deleted file mode 100644
index 5d1abab..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.resources.DeclareStyleableInfo;
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.editors.descriptors.ListAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.ReferenceAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
-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", PackageAttributeDescriptor.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/editors/manifest/descriptors/ApplicationAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ApplicationAttributeDescriptor.java
deleted file mode 100644
index 98d0fe8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.editors.manifest.model.UiClassAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.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/editors/manifest/descriptors/ClassAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ClassAttributeDescriptor.java
deleted file mode 100644
index d1a76e0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.editors.manifest.model.UiClassAttributeNode;
-import com.android.ide.eclipse.editors.manifest.model.UiClassAttributeNode.IPostTypeCreationAction;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.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/editors/manifest/descriptors/ManifestElementDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ManifestElementDescriptor.java
deleted file mode 100644
index d89292b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.manifest.model.UiManifestElementNode;
-import com.android.ide.eclipse.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/editors/manifest/descriptors/PackageAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/PackageAttributeDescriptor.java
deleted file mode 100644
index 34c5d0d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.editors.manifest.model.UiPackageAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.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/editors/manifest/descriptors/PostActivityCreationAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/PostActivityCreationAction.java
deleted file mode 100644
index 3442c24..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.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/editors/manifest/descriptors/PostReceiverCreationAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/PostReceiverCreationAction.java
deleted file mode 100644
index 5a8137d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.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/editors/manifest/descriptors/ThemeAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ThemeAttributeDescriptor.java
deleted file mode 100644
index 4219007..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.descriptors;
-
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.editors.uimodel.UiResourceAttributeNode;
-
-/**
- * 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/editors/manifest/model/UiClassAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/model/UiClassAttributeNode.java
deleted file mode 100644
index c872b6f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.model;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-import com.android.ide.eclipse.common.project.BaseProjectHelper;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.editors.ui.SectionHelper;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.editors.uimodel.UiTextAttributeNode;
-
-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 = AndroidManifestParser.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 b 
-     * @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/editors/manifest/model/UiManifestElementNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/model/UiManifestElementNode.java
deleted file mode 100644
index fb8f211..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/model/UiManifestElementNode.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.editors.manifest.model;
-
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.editors.manifest.descriptors.ManifestElementDescriptor;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-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() {
-        if (getXmlNode() != null &&
-                getXmlNode() instanceof Element &&
-                getXmlNode().hasAttributes()) {
-
-            AndroidManifestDescriptors manifestDescriptors =
-                    getAndroidTarget().getManifestDescriptors();
-            
-            // 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/editors/manifest/model/UiPackageAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/model/UiPackageAttributeNode.java
deleted file mode 100644
index 1fe9b75..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.model;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.editors.ui.SectionHelper;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.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/editors/manifest/pages/ApplicationAttributesPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/pages/ApplicationAttributesPart.java
deleted file mode 100644
index 01b0f8f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.editors.ui.UiElementPart;
-import com.android.ide.eclipse.editors.uimodel.IUiUpdateListener;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.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/editors/manifest/pages/ApplicationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/pages/ApplicationPage.java
deleted file mode 100644
index 77527f0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.editors.ui.tree.UiTreeBlock;
-import com.android.ide.eclipse.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/editors/manifest/pages/ApplicationToggle.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/pages/ApplicationToggle.java
deleted file mode 100644
index 139575d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.editors.ui.UiElementPart;
-import com.android.ide.eclipse.editors.uimodel.IUiUpdateListener;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.editors.uimodel.IUiUpdateListener.UiUpdateState;
-
-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/editors/manifest/pages/InstrumentationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/pages/InstrumentationPage.java
deleted file mode 100644
index 86d0dd1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.editors.ui.tree.UiTreeBlock;
-import com.android.ide.eclipse.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/editors/manifest/pages/OverviewExportPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/pages/OverviewExportPart.java
deleted file mode 100644
index 66af84c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.pages;
-
-import com.android.ide.eclipse.common.project.ExportHelper;
-import com.android.ide.eclipse.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.editors.ui.SectionHelper.ManifestSectionPart;
-
-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/editors/manifest/pages/OverviewInfoPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/pages/OverviewInfoPart.java
deleted file mode 100644
index cab7f73..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.pages;
-
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.editors.ui.UiElementPart;
-import com.android.ide.eclipse.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/editors/manifest/pages/OverviewLinksPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/pages/OverviewLinksPart.java
deleted file mode 100644
index d637a8f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.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/editors/manifest/pages/OverviewPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/pages/OverviewPage.java
deleted file mode 100644
index a06cc74..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.editors.ui.tree.UiTreeBlock;
-import com.android.ide.eclipse.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/editors/manifest/pages/PermissionPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/pages/PermissionPage.java
deleted file mode 100644
index 41ba22e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.manifest.pages;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.editors.ui.tree.UiTreeBlock;
-import com.android.ide.eclipse.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/editors/menu/MenuContentAssist.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/menu/MenuContentAssist.java
deleted file mode 100644
index bf76d53..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.menu;
-
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.editors.AndroidContentAssist;
-
-/**
- * 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/editors/menu/MenuEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/menu/MenuEditor.java
deleted file mode 100644
index cff1746..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.menu;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidXPathFactory;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-
-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/editors/menu/MenuSourceViewerConfig.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/menu/MenuSourceViewerConfig.java
deleted file mode 100644
index a5e3b09..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.menu;
-
-
-import com.android.ide.eclipse.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/editors/menu/MenuTreePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/menu/MenuTreePage.java
deleted file mode 100644
index edbfa5e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.menu;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.ui.tree.UiTreeBlock;
-import com.android.ide.eclipse.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/editors/menu/descriptors/MenuDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/menu/descriptors/MenuDescriptors.java
deleted file mode 100644
index 40a8f16..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.menu.descriptors;
-
-import com.android.ide.eclipse.common.resources.DeclareStyleableInfo;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
-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/editors/resources/ResourcesContentAssist.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/ResourcesContentAssist.java
deleted file mode 100644
index c9c8e17..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.resources;
-
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.editors.AndroidContentAssist;
-
-/**
- * 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/editors/resources/ResourcesEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/ResourcesEditor.java
deleted file mode 100644
index 46a9112..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.resources;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidXPathFactory;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.resources.descriptors.ResourcesDescriptors;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-
-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/editors/resources/ResourcesSourceViewerConfig.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/ResourcesSourceViewerConfig.java
deleted file mode 100644
index 1804312..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.resources;
-
-
-import com.android.ide.eclipse.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/editors/resources/ResourcesTreePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/ResourcesTreePage.java
deleted file mode 100644
index 5c1b0e1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.resources;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.resources.manager.ResourceFolder;
-import com.android.ide.eclipse.editors.resources.manager.ResourceManager;
-import com.android.ide.eclipse.editors.ui.tree.UiTreeBlock;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-
-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/editors/resources/configurations/CountryCodeQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/CountryCodeQualifier.java
deleted file mode 100644
index 9a61d17..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/CountryCodeQualifier.java
+++ /dev/null
@@ -1,144 +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.editors.resources.configurations;
-
-import com.android.ide.eclipse.editors.IconFactory;
-
-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 int mCode = DEFAULT_CODE;
-    
-    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();
-            qualifier.mCode = 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 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 toString() {
-        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/editors/resources/configurations/FolderConfiguration.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/FolderConfiguration.java
deleted file mode 100644
index 3c3e11f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/FolderConfiguration.java
+++ /dev/null
@@ -1,499 +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.editors.resources.configurations;
-
-import com.android.ide.eclipse.editors.resources.manager.ResourceFolderType;
-
-
-/**
- * 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_ORIENTATION = 4;
-    private final static int INDEX_PIXEL_DENSITY = 5;
-    private final static int INDEX_TOUCH_TYPE = 6;
-    private final static int INDEX_KEYBOARD_STATE = 7;
-    private final static int INDEX_TEXT_INPUT_METHOD = 8;
-    private final static int INDEX_NAVIGATION_METHOD = 9;
-    private final static int INDEX_SCREEN_DIMENSION = 10;
-    private final static int INDEX_COUNT = 11;
-    
-    /**
-     * Sets the config from the qualifiers of a given <var>config</var>.
-     * @param config
-     */
-    public void set(FolderConfiguration config) {
-        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 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;
-        }
-    }
-    
-    /**
-     * 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;
-            }
-        }
-    }
-    
-    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 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];
-    }
-
-    /**
-     * 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) {
-        StringBuilder result = new StringBuilder(folder.getName());
-        
-        for (ResourceQualifier qualifier : mQualifiers) {
-            if (qualifier != null) {
-                result.append(QUALIFIER_SEP);
-                result.append(qualifier.toString());
-            }
-        }
-        
-        return result.toString();
-    }
-    
-    /**
-     * Returns a string valid for usage in a folder name, or <code>null</code> if the configuration
-     * is default.
-     */
-    @Override
-    public String toString() {
-        StringBuilder result = null;
-        
-        for (ResourceQualifier irq : mQualifiers) {
-            if (irq != null) {
-                if (result == null) {
-                    result = new StringBuilder();
-                } else {
-                    result.append(QUALIFIER_SEP);
-                }
-                result.append(irq.toString());
-            }
-        }
-        
-        if (result != null) {
-            return result.toString();
-        } else {
-            return null;
-        }
-    }
-    
-    /**
-     * 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.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 match the given reference config.
-     * <p/>A match means that:
-     * <ul>
-     * <li>This config does not use any qualifier not used by the reference config</li>
-     * <li>The qualifier used by this config have the same values as the qualifiers of
-     * the reference config.</li>
-     * </ul>
-     * @param referenceConfig The reference configuration to test against.
-     * @return the number of matching qualifiers or -1 if the configurations are not compatible.
-     */
-    public int match(FolderConfiguration referenceConfig) {
-        int matchCount = 0;
-        
-        for (int i = 0 ; i < INDEX_COUNT ; i++) {
-            ResourceQualifier testQualifier = mQualifiers[i];
-            ResourceQualifier referenceQualifier = referenceConfig.mQualifiers[i];
-            
-            // we only care if testQualifier is non null. If it's null, it's a match but
-            // without increasing the matchCount.
-            if (testQualifier != null) {
-                if (referenceQualifier == null) {
-                    return -1;
-                } else if (testQualifier.equals(referenceQualifier) == false) {
-                    return -1;
-                }
-                
-                // the qualifier match, increment the count
-                matchCount++;
-            }
-        }
-        return matchCount;
-    }
-
-    /**
-     * 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_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();
-    }
-
-    /**
-     * 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/editors/resources/configurations/KeyboardStateQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/KeyboardStateQualifier.java
deleted file mode 100644
index ad232ed..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/KeyboardStateQualifier.java
+++ /dev/null
@@ -1,180 +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.editors.resources.configurations;
-
-import com.android.ide.eclipse.editors.IconFactory;
-
-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$
-        
-        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.
-         */
-        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 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 toString() {
-        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/editors/resources/configurations/LanguageQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/LanguageQualifier.java
deleted file mode 100644
index 99c3a43..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/LanguageQualifier.java
+++ /dev/null
@@ -1,145 +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.editors.resources.configurations;
-
-import com.android.ide.eclipse.editors.IconFactory;
-
-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 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 toString() {
-        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/editors/resources/configurations/NavigationMethodQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/NavigationMethodQualifier.java
deleted file mode 100644
index 1a2cf53..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.resources.configurations;
-
-import com.android.ide.eclipse.editors.IconFactory;
-
-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.
-         */
-        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();
-            qualifier.mValue = 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 toString() {
-        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/editors/resources/configurations/NetworkCodeQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/NetworkCodeQualifier.java
deleted file mode 100644
index 7e30901..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/NetworkCodeQualifier.java
+++ /dev/null
@@ -1,156 +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.editors.resources.configurations;
-
-import com.android.ide.eclipse.editors.IconFactory;
-
-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 int mCode = DEFAULT_CODE;
-    
-    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();
-            qualifier.mCode = 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 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();
-            qualifier.mCode = 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 toString() {
-        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/editors/resources/configurations/PixelDensityQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/PixelDensityQualifier.java
deleted file mode 100644
index c47bb83..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/PixelDensityQualifier.java
+++ /dev/null
@@ -1,144 +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.editors.resources.configurations;
-
-import com.android.ide.eclipse.editors.IconFactory;
-
-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 {
-    /** Default pixel density value. This means the property is not set. */
-    private final static int DEFAULT_DENSITY = -1;
-
-    private final static Pattern sPixelDensityPattern = Pattern.compile("^(\\d+)dpi$");//$NON-NLS-1$
-
-    public static final String NAME = "Pixel Density";
-
-    private int mValue = DEFAULT_DENSITY;
-    
-    /**
-     * Creates and returns a qualifier from the given folder segment. If the segment is incorrect,
-     * <code>null</code> is returned.
-     * @param folderSegment the folder segment from which to create a qualifier.
-     * @return a new {@link CountryCodeQualifier} object or <code>null</code>
-     */
-    public static PixelDensityQualifier getQualifier(String folderSegment) {
-        Matcher m = sPixelDensityPattern.matcher(folderSegment);
-        if (m.matches()) {
-            String v = m.group(1);
-
-            int density = -1;
-            try {
-                density = Integer.parseInt(v);
-            } catch (NumberFormatException e) {
-                // looks like the string we extracted wasn't a valid number.
-                return null;
-            }
-            
-            PixelDensityQualifier qualifier = new PixelDensityQualifier();
-            qualifier.mValue = density;
-            
-            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 value the value of the qualifier, as returned by {@link #getValue()}.
-     */
-    public static String getFolderSegment(int value) {
-        if (value != DEFAULT_DENSITY) {
-            return String.format("%1$ddpi", value); //$NON-NLS-1$
-        }
-        
-        return ""; //$NON-NLS-1$
-    }
-
-    public int 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 != DEFAULT_DENSITY;
-    }
-
-    @Override
-    public boolean checkAndSet(String value, FolderConfiguration config) {
-        PixelDensityQualifier qualifier = getQualifier(value);
-        if (qualifier != null) {
-            config.setPixelDensityQualifier(qualifier);
-            return true;
-        }
-        
-        return false;
-    }
-    
-    @Override
-    public boolean equals(Object qualifier) {
-        if (qualifier instanceof PixelDensityQualifier) {
-            return mValue == ((PixelDensityQualifier)qualifier).mValue;
-        }
-        
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return mValue;
-    }
-    
-    /**
-     * Returns the string used to represent this qualifier in the folder name.
-     */
-    @Override
-    public String toString() {
-        return getFolderSegment(mValue);
-    }
-
-    @Override
-    public String getStringValue() {
-        if (mValue != DEFAULT_DENSITY) {
-            return String.format("%1$d dpi", mValue);
-        }
-        
-        return ""; //$NON-NLS-1$
-    }
-}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/RegionQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/RegionQualifier.java
deleted file mode 100644
index dc4d5fa..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/RegionQualifier.java
+++ /dev/null
@@ -1,145 +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.editors.resources.configurations;
-
-import com.android.ide.eclipse.editors.IconFactory;
-
-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 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 toString() {
-        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/editors/resources/configurations/ResourceQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/ResourceQualifier.java
deleted file mode 100644
index 0257afa..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/ResourceQualifier.java
+++ /dev/null
@@ -1,86 +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.editors.resources.configurations;
-
-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.
-     */
-    @Override
-    public abstract String toString();
-
-    /**
-     * 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/editors/resources/configurations/ScreenDimensionQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/ScreenDimensionQualifier.java
deleted file mode 100644
index a2cc789..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/ScreenDimensionQualifier.java
+++ /dev/null
@@ -1,148 +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.editors.resources.configurations;
-
-import com.android.ide.eclipse.editors.IconFactory;
-
-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 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 toString() {
-        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/editors/resources/configurations/ScreenOrientationQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/ScreenOrientationQualifier.java
deleted file mode 100644
index e30930f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/ScreenOrientationQualifier.java
+++ /dev/null
@@ -1,178 +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.editors.resources.configurations;
-
-import com.android.ide.eclipse.editors.IconFactory;
-
-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.
-         */
-        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 toString() {
-        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/editors/resources/configurations/TextInputMethodQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/TextInputMethodQualifier.java
deleted file mode 100644
index de40138..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/TextInputMethodQualifier.java
+++ /dev/null
@@ -1,182 +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.editors.resources.configurations;
-
-import com.android.ide.eclipse.editors.IconFactory;
-
-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.
-         */
-        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 toString() {
-        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/editors/resources/configurations/TouchScreenQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/TouchScreenQualifier.java
deleted file mode 100644
index 2390e2c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/TouchScreenQualifier.java
+++ /dev/null
@@ -1,180 +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.editors.resources.configurations;
-
-import com.android.ide.eclipse.editors.IconFactory;
-
-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.
-         */
-        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 toString() {
-        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/editors/resources/descriptors/ColorValueDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/descriptors/ColorValueDescriptor.java
deleted file mode 100644
index 92288ba..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.resources.descriptors;
-
-import com.android.ide.eclipse.editors.descriptors.TextValueDescriptor;
-import com.android.ide.eclipse.editors.resources.uimodel.UiColorValueNode;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.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/editors/resources/descriptors/ItemElementDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/descriptors/ItemElementDescriptor.java
deleted file mode 100644
index bf83d52..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.resources.descriptors;
-
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.resources.uimodel.UiItemElementNode;
-import com.android.ide.eclipse.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/editors/resources/descriptors/ResourcesDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/descriptors/ResourcesDescriptors.java
deleted file mode 100644
index 1075897..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.resources.descriptors;
-
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.descriptors.FlagAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.editors.descriptors.ListAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.TextValueDescriptor;
-
-
-/**
- * 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/editors/resources/explorer/ResourceExplorerView.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/explorer/ResourceExplorerView.java
deleted file mode 100644
index b61eddc..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/explorer/ResourceExplorerView.java
+++ /dev/null
@@ -1,340 +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.editors.resources.explorer;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.ui.ResourceContentProvider;
-import com.android.ide.eclipse.adt.ui.ResourceLabelProvider;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.editors.resources.manager.ProjectResourceItem;
-import com.android.ide.eclipse.editors.resources.manager.ProjectResources;
-import com.android.ide.eclipse.editors.resources.manager.ResourceFile;
-import com.android.ide.eclipse.editors.resources.manager.ResourceManager;
-import com.android.ide.eclipse.editors.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/editors/resources/manager/CompiledResourcesMonitor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/CompiledResourcesMonitor.java
deleted file mode 100644
index 2d14c06..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/CompiledResourcesMonitor.java
+++ /dev/null
@@ -1,236 +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.editors.resources.manager;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.project.AndroidManifestParser;
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IFileListener;
-import com.android.ide.eclipse.editors.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.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);
-            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/editors/resources/manager/ConfigurableResourceItem.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ConfigurableResourceItem.java
deleted file mode 100644
index 57c17fc..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.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/editors/resources/manager/FolderTypeRelationship.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/FolderTypeRelationship.java
deleted file mode 100644
index a9f80bd..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.resources.manager;
-
-import com.android.ide.eclipse.common.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/editors/resources/manager/IdResourceItem.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/IdResourceItem.java
deleted file mode 100644
index 552aec9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.resources.manager;
-
-import com.android.ide.eclipse.common.resources.IIdResourceItem;
-import com.android.ide.eclipse.common.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/editors/resources/manager/IntArrayWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/IntArrayWrapper.java
deleted file mode 100644
index 25eb112..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.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/editors/resources/manager/MultiResourceFile.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/MultiResourceFile.java
deleted file mode 100644
index 3812791..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.resources.manager;
-
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.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/editors/resources/manager/ProjectClassLoader.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectClassLoader.java
deleted file mode 100644
index 8b6c3c1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.resources.manager;
-
-import com.android.ide.eclipse.common.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/editors/resources/manager/ProjectResourceItem.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectResourceItem.java
deleted file mode 100644
index ba770b2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectResourceItem.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package com.android.ide.eclipse.editors.resources.manager;
-
-import com.android.ide.eclipse.common.resources.ResourceItem;
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.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/editors/resources/manager/ProjectResources.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectResources.java
deleted file mode 100644
index 40e4e3b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectResources.java
+++ /dev/null
@@ -1,804 +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.editors.resources.manager;
-
-import com.android.ide.eclipse.common.resources.IResourceRepository;
-import com.android.ide.eclipse.common.resources.ResourceItem;
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.editors.resources.configurations.LanguageQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.RegionQualifier;
-import com.android.ide.eclipse.editors.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.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * 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 list of languages used in the resources.
-     */
-    public Set<String> getLanguages() {
-        Set<String> set = new HashSet<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 list of regions used in the resources with the given language.
-     * @param currentLanguage the current language the region must be associated with.
-     */
-    public Set<String> getRegions(String currentLanguage) {
-        Set<String> set = new HashSet<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.
-     */
-    private Resource findMatchingConfiguredResource(List<? extends Resource> resources,
-            FolderConfiguration referenceConfig) {
-        // look for resources with the maximum number of qualifier match.
-        int currentMax = -1;
-        ArrayList<Resource> matchingResources = new ArrayList<Resource>();
-        for (int i = 0 ; i < resources.size(); i++) {
-            Resource res = resources.get(i);
-            
-            int count = res.getConfiguration().match(referenceConfig);
-            if (count > currentMax) {
-                matchingResources.clear();
-                matchingResources.add(res);
-                currentMax = count;
-            } else if (count != -1 && count == currentMax) {
-                matchingResources.add(res);
-            }
-        }
-        
-        // if we have more than one match, we look for the match with the qualifiers with the
-        // highest priority.
-        Resource resMatch = null;
-        if (matchingResources.size() == 1) {
-            resMatch = matchingResources.get(0);
-        } else if (matchingResources.size() > 1) {
-            // More than one resource with the same number of qualifier match.
-            // We loop, looking for the resource with the highest priority qualifiers.
-            ArrayList<Resource> tmpResources = new ArrayList<Resource>();
-            int startIndex = 0;
-            while (matchingResources.size() > 1) {
-                int highest = -1;
-                for (int i = 0 ; i < matchingResources.size() ; i++) {
-                    Resource folder = matchingResources.get(i);
-                 
-                    // get highest priority qualifiers.
-                    int m = folder.getConfiguration().getHighestPriorityQualifier(startIndex);
-
-                    // add to the list if highest.
-                    if (m != -1) {
-                        if (highest == -1 || m == highest) {
-                            tmpResources.add(folder);
-                            highest = m;
-                        } else if (m < highest) { // highest priority == lowest index.
-                            tmpResources.clear();
-                            tmpResources.add(folder);
-                        }
-                    }
-                }
-                
-                // at this point, we have a list with 1+ resources that all have the same highest
-                // priority qualifiers. Go through the list again looking for the next highest
-                // priority qualifier.
-                startIndex = highest + 1;
-                
-                // this should not happen, but it's better to check.
-                if (matchingResources.size() == tmpResources.size() && highest == -1) {
-                    // this means all the resources match with the same qualifiers
-                    // (highest == -1 means we reached the end of the qualifier list)
-                    // In this case, we arbitrarily take the first resource.
-                    matchingResources.clear();
-                    matchingResources.add(tmpResources.get(0));
-                } else {
-                    matchingResources.clear();
-                    matchingResources.addAll(tmpResources);
-                }
-                tmpResources.clear();
-            }
-            
-            // we should have only one match here.
-            resMatch = matchingResources.get(0);
-        }
-
-        return resMatch;
-    }
-
-    /**
-     * 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/editors/resources/manager/Resource.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/Resource.java
deleted file mode 100644
index dd8d080..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.resources.manager;
-
-import com.android.ide.eclipse.editors.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/editors/resources/manager/ResourceFile.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFile.java
deleted file mode 100644
index f927a9a..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.resources.manager;
-
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.editors.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/editors/resources/manager/ResourceFolder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolder.java
deleted file mode 100644
index 98f5b39..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.resources.manager;
-
-import com.android.ide.eclipse.common.resources.ResourceItem;
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.editors.resources.manager.files.IAbstractFile;
-import com.android.ide.eclipse.editors.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/editors/resources/manager/ResourceFolderType.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolderType.java
deleted file mode 100644
index 5fc7393..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.resources.manager;
-
-import com.android.ide.eclipse.editors.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/editors/resources/manager/ResourceManager.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceManager.java
deleted file mode 100644
index 6099008..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceManager.java
+++ /dev/null
@@ -1,493 +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.editors.resources.manager;
-
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.editors.resources.configurations.ResourceQualifier;
-import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IFileListener;
-import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IFolderListener;
-import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener;
-import com.android.ide.eclipse.editors.resources.manager.files.FileWrapper;
-import com.android.ide.eclipse.editors.resources.manager.files.FolderWrapper;
-import com.android.ide.eclipse.editors.resources.manager.files.IAbstractFile;
-import com.android.ide.eclipse.editors.resources.manager.files.IAbstractFolder;
-import com.android.ide.eclipse.editors.resources.manager.files.IFileWrapper;
-import com.android.ide.eclipse.editors.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 {
-                File[] files = frameworkRes.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();
-                
-                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;
-    }
-    
-    /**
-     * 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/editors/resources/manager/ResourceMonitor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceMonitor.java
deleted file mode 100644
index 59a72fb..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.resources.manager;
-
-import com.android.ide.eclipse.common.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/editors/resources/manager/SingleResourceFile.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/SingleResourceFile.java
deleted file mode 100644
index 32b1107..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/SingleResourceFile.java
+++ /dev/null
@@ -1,145 +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.editors.resources.manager;
-
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.resources.manager.files.IAbstractFile;
-import com.android.layoutlib.api.IResourceValue;
-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);
-        
-        mValue = new ResourceValue(mType.getName(), getResourceName(mType), file.getOsLocation(),
-                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/editors/resources/manager/files/FileWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FileWrapper.java
deleted file mode 100644
index d99cb13..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.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/editors/resources/manager/files/FolderWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FolderWrapper.java
deleted file mode 100644
index 9ad7460..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.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/editors/resources/manager/files/IAbstractFile.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IAbstractFile.java
deleted file mode 100644
index 7e807f9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.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/editors/resources/manager/files/IAbstractFolder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IAbstractFolder.java
deleted file mode 100644
index b35283d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.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/editors/resources/manager/files/IAbstractResource.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IAbstractResource.java
deleted file mode 100644
index daf243d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.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/editors/resources/manager/files/IFileWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFileWrapper.java
deleted file mode 100644
index f0f5f2d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.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/editors/resources/manager/files/IFolderWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFolderWrapper.java
deleted file mode 100644
index b1fa3ef..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.editors.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/editors/resources/uimodel/UiColorValueNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/uimodel/UiColorValueNode.java
deleted file mode 100644
index 29453e9..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.resources.uimodel;
-
-import com.android.ide.eclipse.editors.descriptors.TextValueDescriptor;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-import com.android.ide.eclipse.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/editors/resources/uimodel/UiItemElementNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/uimodel/UiItemElementNode.java
deleted file mode 100644
index 89649f5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.resources.uimodel;
-
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.editors.resources.descriptors.ItemElementDescriptor;
-import com.android.ide.eclipse.editors.resources.descriptors.ResourcesDescriptors;
-import com.android.ide.eclipse.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/editors/ui/EditableDialogCellEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/EditableDialogCellEditor.java
deleted file mode 100644
index 5fb479f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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/editors/ui/ErrorImageComposite.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/ErrorImageComposite.java
deleted file mode 100644
index d095376..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/ErrorImageComposite.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.android.ide.eclipse.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/editors/ui/FlagValueCellEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/FlagValueCellEditor.java
deleted file mode 100644
index ccae099..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.ui;
-
-import com.android.ide.eclipse.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/editors/ui/ListValueCellEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/ListValueCellEditor.java
deleted file mode 100644
index dc4836d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.ui;
-
-import com.android.ide.eclipse.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/editors/ui/ResourceValueCellEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/ResourceValueCellEditor.java
deleted file mode 100644
index 4fc0ab3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.ui;
-
-import com.android.ide.eclipse.editors.uimodel.UiFlagAttributeNode;
-import com.android.ide.eclipse.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/editors/ui/SectionHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/SectionHelper.java
deleted file mode 100644
index 409e92f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.ui;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.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/editors/ui/TextValueCellEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/TextValueCellEditor.java
deleted file mode 100644
index 2fe5783..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.ui;
-
-import com.android.ide.eclipse.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/editors/ui/UiElementPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/UiElementPart.java
deleted file mode 100644
index 66773bd..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.ui;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.editors.manifest.ManifestEditor;
-import com.android.ide.eclipse.editors.ui.SectionHelper.ManifestSectionPart;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.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/editors/ui/tree/CopyCutAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/CopyCutAction.java
deleted file mode 100644
index 2aad217..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.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/editors/ui/tree/ICommitXml.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/ICommitXml.java
deleted file mode 100644
index 8b6aa0e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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/editors/ui/tree/NewItemSelectionDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/NewItemSelectionDialog.java
deleted file mode 100644
index 36bd148..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.layout.descriptors.ViewElementDescriptor;
-import com.android.ide.eclipse.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/editors/ui/tree/PasteAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/PasteAction.java
deleted file mode 100644
index 8bb4ad2..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.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/editors/ui/tree/UiActions.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/UiActions.java
deleted file mode 100644
index 21180b1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.ui.tree;
-
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.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/editors/ui/tree/UiElementDetail.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/UiElementDetail.java
deleted file mode 100644
index 15c67c3..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.descriptors.SeparatorAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.editors.ui.SectionHelper;
-import com.android.ide.eclipse.editors.ui.SectionHelper.ManifestSectionPart;
-import com.android.ide.eclipse.editors.uimodel.IUiUpdateListener;
-import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-
-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/editors/ui/tree/UiModelTreeContentProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/UiModelTreeContentProvider.java
deleted file mode 100644
index 396b309..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.ui.tree;
-
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.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/editors/ui/tree/UiModelTreeLabelProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/UiModelTreeLabelProvider.java
deleted file mode 100644
index 273a30b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.ui.ErrorImageComposite;
-import com.android.ide.eclipse.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/editors/ui/tree/UiTreeBlock.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/UiTreeBlock.java
deleted file mode 100644
index e1986e5..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/UiTreeBlock.java
+++ /dev/null
@@ -1,894 +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.editors.ui.tree;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.IconFactory;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.ui.SectionHelper;
-import com.android.ide.eclipse.editors.ui.SectionHelper.ManifestSectionPart;
-import com.android.ide.eclipse.editors.uimodel.IUiUpdateListener;
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-import com.android.ide.eclipse.editors.uimodel.UiElementNode;
-
-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.
-        Action action;
-        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/editors/uimodel/IUiSettableAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/IUiSettableAttributeNode.java
deleted file mode 100644
index 7fe44da..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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/editors/uimodel/IUiUpdateListener.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/IUiUpdateListener.java
deleted file mode 100644
index 12cb31b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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/editors/uimodel/UiAbstractTextAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiAbstractTextAttributeNode.java
deleted file mode 100644
index 4a9fbb1..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.uimodel;
-
-import com.android.ide.eclipse.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/editors/uimodel/UiAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiAttributeNode.java
deleted file mode 100644
index cada844..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.uimodel;
-
-import com.android.ide.eclipse.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/editors/uimodel/UiDocumentNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiDocumentNode.java
deleted file mode 100644
index 113738f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.uimodel;
-
-import com.android.ide.eclipse.editors.descriptors.DocumentDescriptor;
-import com.android.ide.eclipse.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/editors/uimodel/UiElementNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiElementNode.java
deleted file mode 100644
index 517284c..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiElementNode.java
+++ /dev/null
@@ -1,1500 +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.editors.uimodel;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.descriptors.SeparatorAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.editors.layout.descriptors.CustomViewDescriptorService;
-import com.android.ide.eclipse.editors.layout.descriptors.LayoutDescriptors;
-import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
-import com.android.ide.eclipse.editors.resources.descriptors.ResourcesDescriptors;
-import com.android.ide.eclipse.editors.uimodel.IUiUpdateListener.UiUpdateState;
-import com.android.ide.eclipse.editors.xml.descriptors.XmlDescriptors;
-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.
-     * 
-     * @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);
-        invokeUiUpdateListeners(UiUpdateState.DELETED);
-        if (ui_node.getDescriptor().isMandatory()) {
-            // We can't remove a mandatory node, we just clear its content.
-
-            // A mandatory node with no XML means it doesn't really exist, so it can't be
-            // deleted.
-            boolean xml_exists = (ui_node.getXmlNode() != null); 
-
-            ui_node.clearContent();
-            return xml_exists;
-        } else {
-            mUiChildren.remove(ui_index);
-            return true;
-        }
-    }
-
-    /**
-     * 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 updates 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.
-     */
-    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/editors/uimodel/UiFlagAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiFlagAttributeNode.java
deleted file mode 100644
index c799518..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.uimodel;
-
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.editors.descriptors.FlagAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.editors.ui.SectionHelper;
-
-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/editors/uimodel/UiListAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiListAttributeNode.java
deleted file mode 100644
index faac013..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.uimodel;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.editors.descriptors.ListAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.editors.ui.SectionHelper;
-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/editors/uimodel/UiResourceAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiResourceAttributeNode.java
deleted file mode 100644
index 284cff4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.uimodel;
-
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.ui.ReferenceChooserDialog;
-import com.android.ide.eclipse.adt.ui.ResourceChooser;
-import com.android.ide.eclipse.common.resources.IResourceRepository;
-import com.android.ide.eclipse.common.resources.ResourceItem;
-import com.android.ide.eclipse.common.resources.ResourceType;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.editors.resources.manager.ResourceManager;
-import com.android.ide.eclipse.editors.ui.SectionHelper;
-
-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/editors/uimodel/UiSeparatorAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiSeparatorAttributeNode.java
deleted file mode 100644
index a6111d4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.uimodel;
-
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.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/editors/uimodel/UiTextAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiTextAttributeNode.java
deleted file mode 100644
index 652debe..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.uimodel;
-
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.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/editors/uimodel/UiTextValueNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiTextValueNode.java
deleted file mode 100644
index 5c1db05..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.uimodel;
-
-import com.android.ide.eclipse.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/editors/xml/XmlContentAssist.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/XmlContentAssist.java
deleted file mode 100644
index f28b523..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.xml;
-
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.editors.AndroidContentAssist;
-
-/**
- * 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/editors/xml/XmlEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/XmlEditor.java
deleted file mode 100644
index d7f6119..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/XmlEditor.java
+++ /dev/null
@@ -1,202 +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.editors.xml;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.adt.sdk.Sdk;
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.editors.AndroidEditor;
-import com.android.ide.eclipse.editors.FirstElementParser;
-import com.android.ide.eclipse.editors.descriptors.DocumentDescriptor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
-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) {
-            AndroidTargetData data = Sdk.getCurrent().getTargetData(target);
-        
-            FirstElementParser.Result result = FirstElementParser.parse(
-                    file.getLocation().toOSString(),
-                    SdkConstants.NS_RESOURCES);
-            
-            if (result != 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/editors/xml/XmlSourceViewerConfig.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/XmlSourceViewerConfig.java
deleted file mode 100644
index d25c812..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.xml;
-
-
-import com.android.ide.eclipse.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/editors/xml/XmlTreePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/XmlTreePage.java
deleted file mode 100644
index 91ce6dd..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.xml;
-
-import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.editors.ui.tree.UiTreeBlock;
-import com.android.ide.eclipse.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/editors/xml/descriptors/XmlDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/descriptors/XmlDescriptors.java
deleted file mode 100644
index 144b7ac..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.xml.descriptors;
-
-import com.android.ide.eclipse.common.AndroidConstants;
-import com.android.ide.eclipse.common.resources.DeclareStyleableInfo;
-import com.android.ide.eclipse.common.resources.ViewClassInfo;
-import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo;
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
-import com.android.ide.eclipse.editors.descriptors.DocumentDescriptor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
-import com.android.ide.eclipse.editors.descriptors.SeparatorAttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
-import com.android.ide.eclipse.editors.layout.descriptors.ViewElementDescriptor;
-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/templates/AndroidManifest.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template
index b43e75f..5d57413 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template
@@ -5,6 +5,8 @@
       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/test_instrumentation.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/test_instrumentation.template
new file mode 100755
index 0000000..c282fbc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/test_instrumentation.template
@@ -0,0 +1 @@
+    <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
new file mode 100755
index 0000000..28ae7a4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/test_uses-library.template
@@ -0,0 +1 @@
+    <uses-library android:name="android.test.runner" />
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
index 09b8085..2488fd1 100644
--- 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
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Dalvik Debug Monitor Service
 Bundle-SymbolicName: com.android.ide.eclipse.ddms;singleton:=true
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.9.1.qualifier
 Bundle-Activator: com.android.ide.eclipse.ddms.DdmsPlugin
 Bundle-Vendor: The Android Open Source Project
 Bundle-Localization: plugin
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
index ccadce6..d559b0f 100644
--- 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
@@ -19,7 +19,7 @@
 import com.android.ddmlib.AndroidDebugBridge;
 import com.android.ddmlib.Client;
 import com.android.ddmlib.DdmPreferences;
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
 import com.android.ddmlib.Log.ILogOutput;
@@ -76,11 +76,11 @@
 
     /** Image loader object */
     private ImageLoader mLoader;
-    
-    private Device mCurrentDevice;
+
+    private IDevice mCurrentDevice;
     private Client mCurrentClient;
     private boolean mListeningToUiSelection = false;
-    
+
     private final ArrayList<ISelectionListener> mListeners = new ArrayList<ISelectionListener>();
 
     private Color mRed;
@@ -93,24 +93,24 @@
     public interface IDebugLauncher {
         public boolean debug(String packageName, int port);
     }
-    
+
     /**
      * Classes which implement this interface provide methods that deals
-     * with {@link Device} and {@link Client} selectionchanges.
+     * 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 Device} is selected.
+         * Sent when a new {@link IDevice} is selected.
          * @param selectedDevice the selected device. If null, no devices are selected.
          */
-        public void selectionChanged(Device selectedDevice);
+        public void selectionChanged(IDevice selectedDevice);
     }
 
     /**
@@ -128,14 +128,14 @@
     @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();
@@ -186,12 +186,12 @@
                     }
                 });
             }
-            
+
         });
 
         // 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() {
@@ -214,7 +214,7 @@
                 }
             }
         });
-        
+
         // read the adb location from the prefs to attempt to start it properly without
         // having to wait for ADT to start
         sAdbLocation = eclipseStore.getString(ADB_LOCATION);
@@ -248,9 +248,9 @@
     @Override
     public void stop(BundleContext context) throws Exception {
         AndroidDebugBridge.removeDeviceChangeListener(this);
-        
+
         AndroidDebugBridge.terminate();
-        
+
         mRed.dispose();
 
         sPlugin = null;
@@ -303,15 +303,15 @@
             }.start();
         }
     }
-    
+
     private synchronized void initDdmlib() {
         if (mDdmlibInitialized == false) {
             // set the preferences.
             PreferenceInitializer.setupPreferences();
-    
+
             // init the lib
             AndroidDebugBridge.init(true /* debugger support */);
-            
+
             mDdmlibInitialized = true;
         }
     }
@@ -342,10 +342,10 @@
     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);
@@ -364,10 +364,10 @@
      * <p/>
      * This is sent from a non UI thread.
      * @param device the new device.
-     * 
-     * @see IDeviceChangeListener#deviceConnected(Device)
+     *
+     * @see IDeviceChangeListener#deviceConnected(IDevice)
      */
-    public void deviceConnected(Device device) {
+    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.
@@ -383,10 +383,10 @@
      * <p/>
      * This is sent from a non UI thread.
      * @param device the new device.
-     * 
-     * @see IDeviceChangeListener#deviceDisconnected(Device)
+     *
+     * @see IDeviceChangeListener#deviceDisconnected(IDevice)
      */
-    public void deviceDisconnected(Device device) {
+    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.
@@ -397,16 +397,16 @@
                 AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
                 if (bridge != null) {
                     // get the device list
-                    Device[] devices = bridge.getDevices();
-                    
+                    IDevice[] devices = bridge.getDevices();
+
                     // check if we still have devices
                     if (devices.length == 0) {
-                        handleDefaultSelection((Device)null);
+                        handleDefaultSelection((IDevice)null);
                     } else {
                         handleDefaultSelection(devices[0]);
                     }
                 } else {
-                    handleDefaultSelection((Device)null);
+                    handleDefaultSelection((IDevice)null);
                 }
             }
         }
@@ -418,15 +418,15 @@
      * 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(Device)
+     *
+     * @see IDeviceChangeListener#deviceChanged(IDevice)
      */
-    public void deviceChanged(Device device, int changeMask) {
+    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) {
@@ -441,7 +441,7 @@
                             break;
                         }
                     }
-                    
+
                     // if we haven't found our client, lets look for a new one
                     if (foundClient == false) {
                         mCurrentClient = null;
@@ -453,11 +453,11 @@
     }
 
     /**
-     * Sent when a new {@link Device} and {@link Client} are selected.
+     * 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(Device selectedDevice, Client selectedClient) {
+    public synchronized void selectionChanged(IDevice selectedDevice, Client selectedClient) {
         if (mCurrentDevice != selectedDevice) {
             mCurrentDevice = selectedDevice;
 
@@ -469,7 +469,7 @@
 
         if (mCurrentClient != selectedClient) {
             mCurrentClient = selectedClient;
-            
+
             // notify of the new default client
             for (ISelectionListener listener : mListeners) {
                 listener.selectionChanged(mCurrentClient);
@@ -478,15 +478,15 @@
     }
 
     /**
-     * Handles a default selection of a {@link Device} and {@link Client}.
+     * Handles a default selection of a {@link IDevice} and {@link Client}.
      * @param device the selected device
      */
-    private void handleDefaultSelection(final Device 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.
@@ -494,13 +494,13 @@
                     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.
@@ -522,16 +522,16 @@
             // 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
@@ -545,7 +545,7 @@
         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
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
index 62a528a..30172f5 100644
--- 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
@@ -20,7 +20,7 @@
 import com.android.ddmlib.Client;
 import com.android.ddmlib.ClientData;
 import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmuilib.DevicePanel;
 import com.android.ddmuilib.ScreenShotDialog;
 import com.android.ddmuilib.DevicePanel.IUiSelectionListener;
@@ -42,7 +42,7 @@
 import org.eclipse.ui.part.ViewPart;
 
 public class DeviceView extends ViewPart implements IUiSelectionListener {
-    
+
     private final static boolean USE_SELECTED_DEBUG_PORT = true;
 
     public static final String ID =
@@ -69,7 +69,7 @@
     public static DeviceView getInstance() {
         return sThis;
     }
-    
+
     /**
      * Sets the {@link IDebugLauncher}.
      * @param debugLauncher
@@ -89,7 +89,7 @@
         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);
@@ -212,7 +212,7 @@
                         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();
@@ -233,7 +233,7 @@
         if (mDebugLauncher == null) {
             mDebugAction.setEnabled(false);
         }
-        
+
         placeActions();
     }
 
@@ -241,13 +241,13 @@
     public void setFocus() {
         mDeviceList.setFocus();
     }
-    
+
     /**
-     * Sent when a new {@link Device} and {@link Client} are selected.
+     * 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(Device selectedDevice, Client selectedClient) {
+    public void selectionChanged(IDevice selectedDevice, Client selectedClient) {
         // update the buttons
         doSelectionChanged(selectedClient);
         doSelectionChanged(selectedDevice);
@@ -264,7 +264,7 @@
             mDebugAction.setEnabled(mDebugLauncher != null);
             mKillAppAction.setEnabled(true);
             mGcAction.setEnabled(true);
-            
+
             mUpdateHeapAction.setEnabled(true);
             mUpdateHeapAction.setChecked(selectedClient.isHeapUpdateEnabled());
 
@@ -278,7 +278,7 @@
                     bridge.setSelectedClient(null);
                 }
             }
-            
+
             mDebugAction.setEnabled(false);
             mKillAppAction.setEnabled(false);
             mGcAction.setEnabled(false);
@@ -288,8 +288,8 @@
             mUpdateThreadAction.setChecked(false);
         }
     }
-    
-    private void doSelectionChanged(Device selectedDevice) {
+
+    private void doSelectionChanged(IDevice selectedDevice) {
         mCaptureAction.setEnabled(selectedDevice != null);
     }
 
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
index 4f0dd2e..e79010c 100644
--- 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
@@ -17,7 +17,7 @@
 package com.android.ide.eclipse.ddms.views;
 
 import com.android.ddmlib.Client;
-import com.android.ddmlib.Device;
+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;
@@ -26,6 +26,7 @@
 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;
@@ -128,7 +129,7 @@
         toolBarManager.add(pushAction);
         toolBarManager.add(new Separator());
         toolBarManager.add(deleteAction);
-        
+
         mExplorer.createPanel(parent);
 
         DdmsPlugin.getDefault().addSelectionListener(this);
@@ -146,20 +147,20 @@
     public void selectionChanged(Client selectedClient) {
         // pass
     }
-    
+
     /**
      * Sent when a new {@link Device} is selected.
      * @param selectedDevice the selected device.
      */
-    public void selectionChanged(Device selectedDevice) {
+    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/SelectionDependentViewPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SelectionDependentViewPart.java
index 48b2689..40dae43 100644
--- 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
@@ -16,12 +16,13 @@
 
 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 com.android.ddmlib.Client;
-import com.android.ddmlib.Device;
-import com.android.ddmuilib.SelectionDependentPanel;
 
+import org.eclipse.swt.graphics.Device;
 import org.eclipse.ui.part.ViewPart;
 
 /**
@@ -29,17 +30,17 @@
  * 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);
@@ -49,20 +50,20 @@
     /**
      * 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(Device selectedDevice) {
+    public final void selectionChanged(IDevice selectedDevice) {
         mPanel.deviceSelected(selectedDevice);
     }
 }
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
index c7f5ba8..22cda71 100644
--- 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
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: Android Plugin Tests
 Bundle-SymbolicName: com.android.ide.eclipse.tests
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 0.9.1.qualifier
 Bundle-Activator: com.android.ide.eclipse.tests.AndroidTestPlugin
 Require-Bundle: org.eclipse.ui,
  org.eclipse.core.runtime,
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
new file mode 100644
index 0000000..f393ebf
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/launch/JUnitLaunchConfigDelegateTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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/launch/JUnitLaunchConfigDelegateTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/launch/JUnitLaunchConfigDelegateTest.java
deleted file mode 100644
index df3745e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/launch/JUnitLaunchConfigDelegateTest.java
+++ /dev/null
@@ -1,110 +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.launch;
-
-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/wizards/newproject/StubSampleProjectCreationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectCreationPage.java
index 42f8df0..75b6d9b 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectCreationPage.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectCreationPage.java
@@ -15,6 +15,12 @@
  */
 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;
+
 import java.io.File;
 
 /**
@@ -26,46 +32,60 @@
     private String mSampleProjectName;
     private String mOsSdkLocation;
 
-    public StubSampleProjectCreationPage(String pageName,
-            String sampleProjectName, String osSdkLocation) {
-        super(pageName);
+    public StubSampleProjectCreationPage(String sampleProjectName, String osSdkLocation) {
+        super();
         this.mSampleProjectName = sampleProjectName;
         this.mOsSdkLocation = osSdkLocation;
     }
 
     @Override
-    public String getProjectName() {
-        return mSampleProjectName;
-    }
+    public IMainInfo getMainInfo() {
+        return new IMainInfo() {
+            public String getProjectName() {
+                return mSampleProjectName;
+            }
 
-    @Override
-    public String getPackageName() {
-        return "com.android.samples";
-    }
+            public String getPackageName() {
+                return "com.android.samples";
+            }
 
-    @Override
-    public String getActivityName() {
-        return mSampleProjectName;
-    }
+            public String getActivityName() {
+                return mSampleProjectName;
+            }
 
-    @Override
-    public String getApplicationName() {
-        return mSampleProjectName;
-    }
+            public String getApplicationName() {
+                return mSampleProjectName;
+            }
 
-    @Override
-    public boolean isNewProject() {
-        return false;
-    }
+            public boolean isNewProject() {
+                return false;
+            }
 
-    @Override
-    public String getProjectLocation() {
-        return mOsSdkLocation + File.separator + "samples" + File.separator + mSampleProjectName;
-    }
+            public String getSourceFolder() {
+                return "src";
+            }
 
-    @Override
-    public String getSourceFolder() {
-        return "src";
-    }
+            public IPath getLocationPath() {
+                return new Path(mOsSdkLocation + File.separator +
+                        "samples" + File.separator +
+                        mSampleProjectName);
+            }
 
+            public String getMinSdkVersion() {
+                return null;
+            }
+
+            public IAndroidTarget getSdkTarget() {
+                return null;
+            }
+
+            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/StubSampleProjectWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectWizard.java
index 40cd636..28c2c7e 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectWizard.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectWizard.java
@@ -15,6 +15,9 @@
  */
 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 org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.wizard.IWizardContainer;
@@ -49,8 +52,7 @@
      */
     @Override
     protected NewProjectCreationPage createMainPage() {
-        return new StubSampleProjectCreationPage(MAIN_PAGE_NAME,
-                mSampleProjectName, mOsSdkLocation);
+        return new StubSampleProjectCreationPage(mSampleProjectName, mOsSdkLocation);
     }
 
     /**
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
index d86d585..6d13737 100644
--- 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
@@ -15,7 +15,7 @@
  */
 package com.android.ide.eclipse.tests;
 
-import com.android.ide.eclipse.common.AndroidConstants;
+import com.android.ide.eclipse.adt.AndroidConstants;
 
 import org.eclipse.core.runtime.FileLocator;
 import org.eclipse.core.runtime.Platform;
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
index 6aaa209..5a413fa 100644
--- 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
@@ -67,8 +67,6 @@
     
     /**
      * Returns true if given class should be added to suite
-     * @param testClass
-     * @return
      */
     protected boolean isTestClass(Class<?> testClass) {
         return TestCase.class.isAssignableFrom(testClass) &&
@@ -78,8 +76,6 @@
     
     /**
      * Returns true if given class has a public constructor
-     * @param testClass
-     * @return
      */
     protected boolean hasPublicConstructor(Class<?> testClass) {
         try {
@@ -94,7 +90,6 @@
      * Load the class given by the plugin aka bundle file path
      * @param filePath - path of class in bundle
      * @param expectedPackage - expected package of class
-     * @return
      * @throws ClassNotFoundException
      */
     protected Class<?> getClass(String filePath, String expectedPackage) throws ClassNotFoundException {
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
index 98817c6..54fcb99 100644
--- 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
@@ -15,7 +15,7 @@
  */
 package com.android.ide.eclipse.tests.functests.sampleProjects;
 
-import com.android.ide.eclipse.adt.project.ProjectHelper;
+import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
 import com.android.ide.eclipse.adt.wizards.newproject.StubSampleProjectWizard;
 import com.android.ide.eclipse.tests.FuncTestCase;
 
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/build/BaseBuilderTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/build/BaseBuilderTest.java
deleted file mode 100644
index 0860e40..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/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.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/build/BaseBuilderTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/build/BaseBuilderTest.java
new file mode 100644
index 0000000..a1d658b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/build/BaseBuilderTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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
new file mode 100644
index 0000000..42bf7ae
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/descriptors/DescriptorsUtilsTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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
new file mode 100644
index 0000000..e234d6b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/layout/UiElementPullParserTest.java
@@ -0,0 +1,241 @@
+/*
+ * 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
new file mode 100644
index 0000000..ac3d8d5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/manifest/model/UiElementNodeTest.java
@@ -0,0 +1,211 @@
+/*
+ * 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
new file mode 100644
index 0000000..cf05b2a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/mock/MockNamedNodeMap.java
@@ -0,0 +1,106 @@
+/*
+ * 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
new file mode 100644
index 0000000..def1993
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/mock/MockNodeList.java
@@ -0,0 +1,60 @@
+/*
+ * 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
new file mode 100644
index 0000000..1ad7543
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/mock/MockXmlNode.java
@@ -0,0 +1,286 @@
+/*
+ * 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
new file mode 100644
index 0000000..e0fe013
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/CountryCodeQualifierTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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
new file mode 100644
index 0000000..4953747
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/KeyboardStateQualifierTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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
new file mode 100644
index 0000000..e4a9312
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/LanguageQualifierTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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
new file mode 100644
index 0000000..8e5d9ec
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/NavigationMethodQualifierTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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
new file mode 100644
index 0000000..7512305
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/NetworkCodeQualifierTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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
new file mode 100644
index 0000000..23107a1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/PixelDensityQualifierTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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 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("123dpi", config));//$NON-NLS-1$
+        assertTrue(config.getPixelDensityQualifier() != null);
+        assertEquals(123, config.getPixelDensityQualifier().getValue());
+        assertEquals("123dpi", 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
new file mode 100644
index 0000000..a70a04b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/RegionQualifierTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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
new file mode 100644
index 0000000..b25fb76
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/ScreenDimensionQualifierTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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
new file mode 100644
index 0000000..15d9686
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/ScreenOrientationQualifierTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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
new file mode 100644
index 0000000..c679295
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/TextInputMethodQualifierTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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
new file mode 100644
index 0000000..b5d7933
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/configurations/TouchScreenQualifierTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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
new file mode 100644
index 0000000..dd82bed
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java
@@ -0,0 +1,259 @@
+/*
+ * 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 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 orientation
+                null, // dpi
+                null, // touch mode
+                null, // keyboard state
+                null, // text input
+                null, // navigation
+                null); // screen size
+        
+        addFolder(mResources, defaultConfig, validMemberList);
+        
+        config1 = getConfiguration(
+                null, // country code
+                null, // network code
+                "en", // language
+                null, // region
+                null, // screen orientation
+                null, // dpi
+                null, // touch mode
+                KeyboardState.EXPOSED.getValue(), // keyboard state
+                null, // text input
+                null, // navigation
+                null); // screen size
+        
+        addFolder(mResources, config1, validMemberList);
+
+        config2 = getConfiguration(
+                null, // country code
+                null, // network code
+                "en", // language
+                null, // region
+                null, // screen orientation
+                null, // dpi
+                null, // touch mode
+                KeyboardState.HIDDEN.getValue(), // keyboard state
+                null, // text input
+                null, // navigation
+                null); // screen size
+        
+        addFolder(mResources, config2, validMemberList);
+
+        config3 = getConfiguration(
+                null, // country code
+                null, // network code
+                "en", // language
+                null, // region
+                ScreenOrientation.LANDSCAPE.getValue(), // screen orientation
+                null, // dpi
+                null, // touch mode
+                null, // keyboard state
+                null, // text input
+                null, // navigation
+                null); // screen size
+        
+        addFolder(mResources, config3, validMemberList);
+
+        config4 = getConfiguration(
+                "mcc310", // country code
+                "mnc435", // network code
+                "en", // language
+                "rUS", // region
+                ScreenOrientation.LANDSCAPE.getValue(), // screen orientation
+                "160dpi", // dpi
+                TouchScreenType.FINGER.getValue(), // touch mode
+                KeyboardState.EXPOSED.getValue(), // keyboard state
+                TextInputMethod.QWERTY.getValue(), // text input
+                NavigationMethod.DPAD.getValue(), // navigation
+                "480x320"); // screen size
+        
+        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
+                ScreenOrientation.LANDSCAPE.getValue(), // screen orientation
+                "160dpi", // dpi
+                TouchScreenType.FINGER.getValue(), // touch mode
+                KeyboardState.EXPOSED.getValue(), // keyboard state
+                TextInputMethod.QWERTY.getValue(), // text input
+                NavigationMethod.DPAD.getValue(), // navigation
+                "480x320"); // screen size
+        
+        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 = "layout";
+        if (config.isDefault() == false) {
+            folderName += "-" + config.toString();
+        }
+        
+        // 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
new file mode 100644
index 0000000..8932a00
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/QualifierListTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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
new file mode 100644
index 0000000..a28aacc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/project/AndroidManifestParserTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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);
+        Activity activity = new AndroidManifestParser.Activity(ACTIVITY_NAME, true);
+        activity.setHasAction(true);
+        activity.setHasLauncherCategory(true);
+        activity.setHasMainAction(true);
+        assertEquals(activity, mManifestTestApp.getActivities()[0]);
+    }
+
+    public void testGetLauncherActivity() {
+        Activity activity = new AndroidManifestParser.Activity(ACTIVITY_NAME, true);
+        activity.setHasAction(true);
+        activity.setHasLauncherCategory(true);
+        activity.setHasMainAction(true);
+        assertEquals(activity, mManifestTestApp.getLauncherActivity()); 
+    }
+    
+    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
new file mode 100644
index 0000000..6080102
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/project/ProjectHelperTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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
new file mode 100644
index 0000000..ac6ebf5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/resources/AttrsXmlParserTest.java
@@ -0,0 +1,135 @@
+/*
+ * 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
new file mode 100644
index 0000000..71c79be
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk/AndroidJarLoaderTest.java
@@ -0,0 +1,165 @@
+/*
+ * 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
new file mode 100644
index 0000000..cf5f194
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/sdk/LayoutParamsParserTest.java
@@ -0,0 +1,187 @@
+/*
+ * 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/adt/project/ProjectHelperTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/project/ProjectHelperTest.java
deleted file mode 100644
index 8c52d81..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/project/ProjectHelperTest.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.adt.project;
-
-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/sdk/AndroidJarLoaderTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/AndroidJarLoaderTest.java
deleted file mode 100644
index 8af7e02..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/AndroidJarLoaderTest.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.sdk;
-
-import com.android.ide.eclipse.adt.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/sdk/LayoutParamsParserTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/LayoutParamsParserTest.java
deleted file mode 100644
index cedf4d4..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/LayoutParamsParserTest.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.sdk;
-
-import com.android.ide.eclipse.adt.sdk.AndroidJarLoader.ClassWrapper;
-import com.android.ide.eclipse.adt.sdk.IAndroidClassLoader.IClassDescriptor;
-import com.android.ide.eclipse.common.resources.AttrsXmlParser;
-import com.android.ide.eclipse.common.resources.ViewClassInfo;
-import com.android.ide.eclipse.common.resources.ViewClassInfo.LayoutParamsInfo;
-
-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/common/project/AndroidManifestParserTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/project/AndroidManifestParserTest.java
deleted file mode 100644
index 2f93e51..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/project/AndroidManifestParserTest.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.common.project;
-
-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);
-        assertEquals(ACTIVITY_NAME, mManifestTestApp.getActivities()[0]); 
-    }
-
-    public void testGetLauncherActivity() {
-        assertEquals(ACTIVITY_NAME, mManifestTestApp.getLauncherActivity()); 
-    }
-
-    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/common/resources/AttrsXmlParserTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/resources/AttrsXmlParserTest.java
deleted file mode 100644
index 8338453..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/resources/AttrsXmlParserTest.java
+++ /dev/null
@@ -1,132 +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.common.resources;
-
-
-import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo;
-import com.android.ide.eclipse.common.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/editors/descriptors/DescriptorsUtilsTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/descriptors/DescriptorsUtilsTest.java
deleted file mode 100644
index 69c3ed8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/descriptors/DescriptorsUtilsTest.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.editors.descriptors;
-
-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/editors/layout/UiElementPullParserTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/layout/UiElementPullParserTest.java
deleted file mode 100644
index b0deda0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/layout/UiElementPullParserTest.java
+++ /dev/null
@@ -1,240 +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.editors.layout;
-
-import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
-import com.android.ide.eclipse.editors.mock.MockXmlNode;
-import com.android.ide.eclipse.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/editors/manifest/model/UiElementNodeTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/manifest/model/UiElementNodeTest.java
deleted file mode 100644
index e75d9ef..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/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.editors.manifest.model;
-
-import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
-import com.android.ide.eclipse.editors.mock.MockXmlNode;
-import com.android.ide.eclipse.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/editors/mock/MockNamedNodeMap.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/mock/MockNamedNodeMap.java
deleted file mode 100644
index b1f089b..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/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.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/editors/mock/MockNodeList.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/mock/MockNodeList.java
deleted file mode 100644
index d766af7..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/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.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/editors/mock/MockXmlNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/mock/MockXmlNode.java
deleted file mode 100644
index 4a9dbbd..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/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.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/editors/resources/configurations/CountryCodeQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/CountryCodeQualifierTest.java
deleted file mode 100644
index bedaa0d..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/CountryCodeQualifierTest.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.editors.resources.configurations;
-
-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/editors/resources/configurations/KeyboardStateQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/KeyboardStateQualifierTest.java
deleted file mode 100644
index e15434e..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/KeyboardStateQualifierTest.java
+++ /dev/null
@@ -1,61 +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.editors.resources.configurations;
-
-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/editors/resources/configurations/LanguageQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/LanguageQualifierTest.java
deleted file mode 100644
index d00972f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/LanguageQualifierTest.java
+++ /dev/null
@@ -1,53 +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.editors.resources.configurations;
-
-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/editors/resources/configurations/NavigationMethodQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/NavigationMethodQualifierTest.java
deleted file mode 100644
index d672f1f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/NavigationMethodQualifierTest.java
+++ /dev/null
@@ -1,69 +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.editors.resources.configurations;
-
-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/editors/resources/configurations/NetworkCodeQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/NetworkCodeQualifierTest.java
deleted file mode 100644
index 4567dff..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/NetworkCodeQualifierTest.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.editors.resources.configurations;
-
-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/editors/resources/configurations/PixelDensityQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/PixelDensityQualifierTest.java
deleted file mode 100644
index 2c4cd2f..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/PixelDensityQualifierTest.java
+++ /dev/null
@@ -1,55 +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.editors.resources.configurations;
-
-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("123dpi", config));//$NON-NLS-1$
-        assertTrue(config.getPixelDensityQualifier() != null);
-        assertEquals(123, config.getPixelDensityQualifier().getValue());
-        assertEquals("123dpi", 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/editors/resources/configurations/RegionQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/RegionQualifierTest.java
deleted file mode 100644
index 8a9e6f8..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/RegionQualifierTest.java
+++ /dev/null
@@ -1,54 +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.editors.resources.configurations;
-
-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/editors/resources/configurations/ScreenDimensionQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/ScreenDimensionQualifierTest.java
deleted file mode 100644
index 681d4e0..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/ScreenDimensionQualifierTest.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.editors.resources.configurations;
-
-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/editors/resources/configurations/ScreenOrientationQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/ScreenOrientationQualifierTest.java
deleted file mode 100644
index 28f9961..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/ScreenOrientationQualifierTest.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.editors.resources.configurations;
-
-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/editors/resources/configurations/TextInputMethodQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TextInputMethodQualifierTest.java
deleted file mode 100644
index 28f7871..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TextInputMethodQualifierTest.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.editors.resources.configurations;
-
-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/editors/resources/configurations/TouchScreenQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TouchScreenQualifierTest.java
deleted file mode 100644
index 9a788ad..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TouchScreenQualifierTest.java
+++ /dev/null
@@ -1,70 +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.editors.resources.configurations;
-
-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/editors/resources/manager/ConfigMatchTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/ConfigMatchTest.java
deleted file mode 100644
index 46e60ba..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/ConfigMatchTest.java
+++ /dev/null
@@ -1,253 +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.editors.resources.manager;
-
-import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.editors.resources.configurations.ResourceQualifier;
-import com.android.ide.eclipse.editors.resources.configurations.KeyboardStateQualifier.KeyboardState;
-import com.android.ide.eclipse.editors.resources.configurations.NavigationMethodQualifier.NavigationMethod;
-import com.android.ide.eclipse.editors.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
-import com.android.ide.eclipse.editors.resources.configurations.TextInputMethodQualifier.TextInputMethod;
-import com.android.ide.eclipse.editors.resources.configurations.TouchScreenQualifier.TouchScreenType;
-import com.android.ide.eclipse.editors.resources.manager.files.IAbstractFolder;
-import com.android.ide.eclipse.editors.resources.manager.files.IFileWrapper;
-import com.android.ide.eclipse.editors.resources.manager.files.IFolderWrapper;
-import com.android.ide.eclipse.mock.FileMock;
-import com.android.ide.eclipse.mock.FolderMock;
-
-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 orientation
-                null, // dpi
-                null, // touch mode
-                null, // keyboard state
-                null, // text input
-                null, // navigation
-                null); // screen size
-        
-        addFolder(mResources, defaultConfig, validMemberList);
-        
-        config1 = getConfiguration(
-                null, // country code
-                null, // network code
-                "en", // language
-                null, // region
-                null, // screen orientation
-                null, // dpi
-                null, // touch mode
-                KeyboardState.EXPOSED.getValue(), // keyboard state
-                null, // text input
-                null, // navigation
-                null); // screen size
-        
-        addFolder(mResources, config1, validMemberList);
-
-        config2 = getConfiguration(
-                null, // country code
-                null, // network code
-                "en", // language
-                null, // region
-                null, // screen orientation
-                null, // dpi
-                null, // touch mode
-                KeyboardState.HIDDEN.getValue(), // keyboard state
-                null, // text input
-                null, // navigation
-                null); // screen size
-        
-        addFolder(mResources, config2, validMemberList);
-
-        config3 = getConfiguration(
-                null, // country code
-                null, // network code
-                "en", // language
-                null, // region
-                ScreenOrientation.LANDSCAPE.getValue(), // screen orientation
-                null, // dpi
-                null, // touch mode
-                null, // keyboard state
-                null, // text input
-                null, // navigation
-                null); // screen size
-        
-        addFolder(mResources, config3, validMemberList);
-
-        config4 = getConfiguration(
-                "mcc310", // country code
-                "mnc435", // network code
-                "en", // language
-                "rUS", // region
-                ScreenOrientation.LANDSCAPE.getValue(), // screen orientation
-                "160dpi", // dpi
-                TouchScreenType.FINGER.getValue(), // touch mode
-                KeyboardState.EXPOSED.getValue(), // keyboard state
-                TextInputMethod.QWERTY.getValue(), // text input
-                NavigationMethod.DPAD.getValue(), // navigation
-                "480x320"); // screen size
-        
-        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
-                ScreenOrientation.LANDSCAPE.getValue(), // screen orientation
-                "160dpi", // dpi
-                TouchScreenType.FINGER.getValue(), // touch mode
-                KeyboardState.EXPOSED.getValue(), // keyboard state
-                TextInputMethod.QWERTY.getValue(), // text input
-                NavigationMethod.DPAD.getValue(), // navigation
-                "480x320"); // screen size
-        
-        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 = "layout";
-        if (config.isDefault() == false) {
-            folderName += "-" + config.toString();
-        }
-        
-        // 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/editors/resources/manager/QualifierListTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/QualifierListTest.java
deleted file mode 100644
index 0920f00..0000000
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/QualifierListTest.java
+++ /dev/null
@@ -1,75 +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.editors.resources.manager;
-
-import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.editors.resources.configurations.ResourceQualifier;
-
-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/sites/external/site.xml b/tools/eclipse/sites/external/site.xml
index 9fca8d2..404abe5 100644
--- a/tools/eclipse/sites/external/site.xml
+++ b/tools/eclipse/sites/external/site.xml
@@ -3,10 +3,10 @@
    <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.0.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.0.qualifier">
+   <feature url="features/com.android.ide.eclipse.adt_0.9.1.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.1.qualifier">
       <category name="developer"/>
    </feature>
-   <feature url="features/com.android.ide.eclipse.ddms_0.9.0.qualifier.jar" id="com.android.ide.eclipse.ddms" version="0.9.0.qualifier">
+   <feature url="features/com.android.ide.eclipse.ddms_0.9.1.qualifier.jar" id="com.android.ide.eclipse.ddms" version="0.9.1.qualifier">
       <category name="developer"/>
    </feature>
    <category-def name="developer" label="Developer Tools">
diff --git a/tools/eclipse/sites/internal/site.xml b/tools/eclipse/sites/internal/site.xml
index 9f2642f..b53af92 100644
--- a/tools/eclipse/sites/internal/site.xml
+++ b/tools/eclipse/sites/internal/site.xml
@@ -3,13 +3,13 @@
    <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.0.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.0.qualifier">
+   <feature url="features/com.android.ide.eclipse.adt_0.9.1.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.1.qualifier">
       <category name="developer"/>
    </feature>
-   <feature url="features/com.android.ide.eclipse.ddms_0.9.0.qualifier.jar" id="com.android.ide.eclipse.ddms" version="0.9.0.qualifier">
+   <feature url="features/com.android.ide.eclipse.ddms_0.9.1.qualifier.jar" id="com.android.ide.eclipse.ddms" version="0.9.1.qualifier">
       <category name="developer"/>
    </feature>
-   <feature url="features/com.android.ide.eclipse.tests_0.9.0.qualifier.jar" id="com.android.ide.eclipse.tests" version="0.9.0.qualifier">
+   <feature url="features/com.android.ide.eclipse.tests_0.9.1.qualifier.jar" id="com.android.ide.eclipse.tests" version="0.9.1.qualifier">
       <category name="test"/>
    </feature>
    <category-def name="developer" label="Application Developer Tools">
diff --git a/tools/eclipse/source_package_readme.txt b/tools/eclipse/source_package_readme.txt
deleted file mode 100644
index 456bae7..0000000
--- a/tools/eclipse/source_package_readme.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-HOW TO PACKAGE THE SOURCE OF THE PLUGINS FOR RELEASE.
-
-Note: this is only useful before we move to the public source repository, after which this will
-be obsolete.
-
-The source archive must contains:
-1/ Source of the EPL plugins that are released.
-2/ Any closed source dependencies that were created by Google.
-3/ The readme file explaining how to build the plugins.
-
-
-1/ PLUGIN SOURCE
-
-The Plugins that are currently released and that are EPL are:
-- Android Developer Tools => com.android.ide.eclipse.adt
-- Common                  => com.android.ide.eclipse.common
-- Android Editors         => com.android.ide.eclipse.editors
-
-All three plugins are located in
-    device/tools/eclipse/plugins/
-
-Before packing them up, it is important to:
-- remove the bin directory if it exists
-- remove any symlinks to jar files from the top level folder of each plugin
-
-2/ PLUGIN DEPENDENCIES
-
-The plugin dependencies are jar files embedded in some of the plugins. Some of those jar files
-are android libraries for which the source code is not yet being released (They will be released
-under the APL).
-
-Those libraries are not part of the SDK, and need to be taken from a engineering build.
-They will be located in
-    device/out/host/<platform>/framework/
-
-The libraries to copy are:
- - layoutlib_api.jar
- - layoutlib_utils.jar
- - ninepatch.jar
-
-They should be placed in a "libs" folder in the source archive.
-
-3/ README
-
-In the source archive, at the top level, needs to be present a file explaining how to compile
-the plugins.
-
-This file is located at:
-    device/tools/eclipse/plugins/README.txt
\ No newline at end of file
diff --git a/tools/eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java b/tools/eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java
index c520784..11444ec 100644
--- a/tools/eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java
+++ b/tools/eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java
@@ -17,7 +17,7 @@
 package com.android.eventanalyzer;
 
 import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.Log.ILogOutput;
 import com.android.ddmlib.Log.LogLevel;
@@ -42,19 +42,19 @@
 import java.util.TreeMap;
 
 /**
- * Connects to a device using ddmlib and analyze its event log. 
+ * 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>>(); 
-    
+    private TreeMap<String, ArrayList<Long>> mLaunchMap = new TreeMap<String, ArrayList<Long>>();
+
     String mInputTextFile = null;
     String mInputBinaryFile = null;
     String mInputDevice = null;
@@ -65,47 +65,47 @@
     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) {
@@ -156,17 +156,17 @@
             } 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 
+     * @throws IOException
      */
     private void parseBinaryLogFile() throws IOException {
         mParser = new EventLogParser();
@@ -183,13 +183,13 @@
                 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);
@@ -230,10 +230,10 @@
     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.
@@ -245,7 +245,7 @@
                 } catch (InterruptedException e) {
                     // pass
                 }
-                
+
                 // let's not wait > 10 sec.
                 if (count > 100) {
                     printAndExit("Timeout getting device list!", true /* terminate*/);
@@ -253,21 +253,21 @@
             }
 
             // now get the devices
-            Device[] devices = bridge.getDevices();
-            
-            for (Device device : 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.
@@ -278,14 +278,14 @@
             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);
@@ -300,18 +300,18 @@
         }
     }
 
-    private void grabLogFrom(Device device) throws IOException {
+    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
@@ -326,23 +326,23 @@
 
             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);
@@ -353,33 +353,33 @@
                         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
@@ -387,7 +387,7 @@
                     total += value.longValue();
                 }
                 builder.append(total / list.size()).append(DATA_SEPARATOR);
-                
+
                 // finally write the data.
                 writer.write(builder.append('\n').toString());
             }
@@ -412,7 +412,7 @@
         // 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
@@ -434,12 +434,12 @@
 
     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);
     }
 
@@ -469,11 +469,11 @@
         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) {
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java
index 850a238..0f60be6 100644
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java
@@ -17,7 +17,7 @@
 package com.android.hierarchyviewer.device;
 
 import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.MultiLineReceiver;
 
@@ -29,8 +29,8 @@
 
 public class DeviceBridge {
     private static AndroidDebugBridge bridge;
-    
-    private static final HashMap<Device, Integer> devicePortMap = new HashMap<Device, Integer>();
+
+    private static final HashMap<IDevice, Integer> devicePortMap = new HashMap<IDevice, Integer>();
     private static int nextLocalPort = Configuration.DEFAULT_SERVER_PORT;
 
     public static void initDebugBridge() {
@@ -57,11 +57,11 @@
         AndroidDebugBridge.removeDeviceChangeListener(listener);
     }
 
-    public static Device[] getDevices() {
+    public static IDevice[] getDevices() {
         return bridge.getDevices();
     }
 
-    public static boolean isViewServerRunning(Device device) {
+    public static boolean isViewServerRunning(IDevice device) {
         initDebugBridge();
         final boolean[] result = new boolean[1];
         try {
@@ -75,11 +75,11 @@
         return result[0];
     }
 
-    public static boolean startViewServer(Device device) {
+    public static boolean startViewServer(IDevice device) {
         return startViewServer(device, Configuration.DEFAULT_SERVER_PORT);
     }
 
-    public static boolean startViewServer(Device device, int port) {
+    public static boolean startViewServer(IDevice device, int port) {
         initDebugBridge();
         final boolean[] result = new boolean[1];
         try {
@@ -93,7 +93,7 @@
         return result[0];
     }
 
-    public static boolean stopViewServer(Device device) {
+    public static boolean stopViewServer(IDevice device) {
         initDebugBridge();
         final boolean[] result = new boolean[1];
         try {
@@ -116,17 +116,17 @@
      * <p/>This starts a port forwarding between a local port and a port on the device.
      * @param device
      */
-    public static void setupDeviceForward(Device device) {
+    public static void setupDeviceForward(IDevice device) {
         synchronized (devicePortMap) {
-            if (device.getState() == Device.DeviceState.ONLINE) {
+            if (device.getState() == IDevice.DeviceState.ONLINE) {
                 int localPort = nextLocalPort++;
                 device.createForward(localPort, Configuration.DEFAULT_SERVER_PORT);
                 devicePortMap.put(device, localPort);
             }
         }
     }
-    
-    public static void removeDeviceForward(Device device) {
+
+    public static void removeDeviceForward(IDevice device) {
         synchronized (devicePortMap) {
             final Integer localPort = devicePortMap.get(device);
             if (localPort != null) {
@@ -135,18 +135,18 @@
             }
         }
     }
-    
-    public static int getDeviceLocalPort(Device 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) {
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/CaptureLoader.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/CaptureLoader.java
index 7cc44bc..c512ac2 100644
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/CaptureLoader.java
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/CaptureLoader.java
@@ -16,7 +16,7 @@
 
 package com.android.hierarchyviewer.scene;
 
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.hierarchyviewer.device.Configuration;
 import com.android.hierarchyviewer.device.Window;
 import com.android.hierarchyviewer.device.DeviceBridge;
@@ -31,16 +31,16 @@
 import javax.imageio.ImageIO;
 
 public class CaptureLoader {
-    public static Image loadCapture(Device device, Window window, String params) {
+    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());
 
@@ -66,7 +66,7 @@
                 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
index 83b9113..b91db79 100644
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ProfilesLoader.java
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ProfilesLoader.java
@@ -16,7 +16,7 @@
 
 package com.android.hierarchyviewer.scene;
 
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.hierarchyviewer.device.Window;
 import com.android.hierarchyviewer.device.DeviceBridge;
 
@@ -29,7 +29,7 @@
 import java.io.InputStreamReader;
 
 public class ProfilesLoader {
-    public static double[] loadProfiles(Device device, Window window, String params) {
+    public static double[] loadProfiles(IDevice device, Window window, String params) {
         Socket socket = null;
         BufferedReader in = null;
         BufferedWriter out = null;
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java
index 1f3e278..6254262 100644
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java
@@ -16,7 +16,7 @@
 
 package com.android.hierarchyviewer.scene;
 
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.hierarchyviewer.device.DeviceBridge;
 import com.android.hierarchyviewer.device.Window;
 
@@ -36,19 +36,19 @@
 
 public class ViewHierarchyLoader {
     @SuppressWarnings("empty-statement")
-    public static ViewHierarchyScene loadScene(Device device, Window window) {
+    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)));
@@ -57,11 +57,11 @@
             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;
@@ -72,7 +72,7 @@
                 if ("DONE.".equalsIgnoreCase(line)) {
                     break;
                 }
-                
+
                 int whitespaceCount = countFrontWhitespace(line);
                 if (lastWhitespaceCount < whitespaceCount) {
                     stack.push(lastNode);
@@ -86,7 +86,7 @@
                 lastWhitespaceCount = whitespaceCount;
                 line = line.trim();
                 int index = line.indexOf(' ');
-                
+
                 lastNode = new ViewNode();
                 lastNode.name = line.substring(0, index);
 
@@ -94,12 +94,12 @@
                 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;
@@ -128,7 +128,7 @@
                 Exceptions.printStackTrace(ex);
             }
         }
-        
+
         System.out.println("==> DONE");
 
         return scene;
@@ -165,7 +165,7 @@
             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);
 
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java
index 2b7efd6..df2a63e 100644
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java
@@ -16,7 +16,7 @@
 
 package com.android.hierarchyviewer.scene;
 
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.hierarchyviewer.device.Window;
 import com.android.hierarchyviewer.device.DeviceBridge;
 
@@ -27,15 +27,15 @@
 import java.net.Socket;
 
 public class ViewManager {
-    public static void invalidate(Device device, Window window, String params) {
+    public static void invalidate(IDevice device, Window window, String params) {
         sendCommand("INVALIDATE", device, window, params);
     }
 
-    public static void requestLayout(Device device, Window window, String params) {
+    public static void requestLayout(IDevice device, Window window, String params) {
         sendCommand("REQUEST_LAYOUT", device, window, params);
     }
 
-    private static void sendCommand(String command, Device device, Window window, String params) {
+    private static void sendCommand(String command, IDevice device, Window window, String params) {
         Socket socket = null;
         BufferedWriter out = null;
 
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/WindowsLoader.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/WindowsLoader.java
index 6c14cb6..ef93707 100644
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/WindowsLoader.java
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/WindowsLoader.java
@@ -16,7 +16,7 @@
 
 package com.android.hierarchyviewer.scene;
 
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.hierarchyviewer.device.DeviceBridge;
 import com.android.hierarchyviewer.device.Window;
 
@@ -30,7 +30,7 @@
 import java.util.ArrayList;
 
 public class WindowsLoader {
-    public static Window[] loadWindows(Device device) {
+    public static Window[] loadWindows(IDevice device) {
         Socket socket = null;
         BufferedReader in = null;
         BufferedWriter out = null;
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java
index e4144b1..7c17c90 100644
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java
@@ -1,6 +1,6 @@
 package com.android.hierarchyviewer.ui;
 
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.RawImage;
 import com.android.hierarchyviewer.util.WorkerThread;
 import com.android.hierarchyviewer.scene.ViewNode;
@@ -51,14 +51,14 @@
 
 class ScreenViewer extends JPanel implements ActionListener {
     private final Workspace workspace;
-    private final Device device;
+    private final IDevice device;
 
     private GetScreenshotTask task;
     private BufferedImage image;
     private int[] scanline;
     private volatile boolean isLoading;
 
-    private BufferedImage overlay;    
+    private BufferedImage overlay;
     private AlphaComposite overlayAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f);
 
     private ScreenViewer.LoupeStatus status;
@@ -73,7 +73,7 @@
 
     private JSlider zoomSlider;
 
-    ScreenViewer(Workspace workspace, Device device, int spacing) {
+    ScreenViewer(Workspace workspace, IDevice device, int spacing) {
         setLayout(new BorderLayout());
         setOpaque(false);
 
@@ -92,7 +92,7 @@
 
         SwingUtilities.invokeLater(new Runnable() {
             public void run() {
-                timer.start();                
+                timer.start();
             }
         });
     }
@@ -463,7 +463,7 @@
                 g.fillRect(0, 0, getWidth(), getHeight());
 
                 g.setColor(Color.WHITE);
-                g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);                
+                g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
             }
         }
     }
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java
index d530c35..1361243 100644
--- a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java
@@ -17,7 +17,7 @@
 package com.android.hierarchyviewer.ui;
 
 import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.hierarchyviewer.device.DeviceBridge;
 import com.android.hierarchyviewer.device.Window;
 import com.android.hierarchyviewer.laf.UnifiedContentBorder;
@@ -147,7 +147,7 @@
     private DevicesTableModel devicesTableModel;
     private WindowsTableModel windowsTableModel;
 
-    private Device currentDevice;
+    private IDevice currentDevice;
     private Window currentWindow = Window.FOCUSED_WINDOW;
 
     private JButton displayNodeButton;
@@ -235,7 +235,7 @@
         }
 
         devicesTableModel = new DevicesTableModel();
-        for (Device device : DeviceBridge.getDevices()) {
+        for (IDevice device : DeviceBridge.getDevices()) {
             DeviceBridge.setupDeviceForward(device);
             devicesTableModel.addDevice(device);
         }
@@ -289,7 +289,7 @@
 
         setVisibleRowCount(profilingTable, 5);
         firstTableScroller.setMinimumSize(profilingTable.getPreferredScrollableViewportSize());
-        
+
         JSplitPane tablesSplitter = new JSplitPane();
         tablesSplitter.setBorder(null);
         tablesSplitter.setOrientation(JSplitPane.VERTICAL_SPLIT);
@@ -522,7 +522,7 @@
         showDevicesMenuItem.setEnabled(false);
         viewMenu.add(showDevicesMenuItem);
 
-        menuBar.add(viewMenu);        
+        menuBar.add(viewMenu);
 
         viewHierarchyMenu.setText("Hierarchy");
 
@@ -855,7 +855,7 @@
     public void showDevicesSelector() {
         if (mainSplitter != null) {
             if (pixelPerfectPanel != null) {
-                screenViewer.start();                
+                screenViewer.start();
             }
             mainPanel.remove(graphViewButton.isSelected() ? mainSplitter : pixelPerfectPanel);
             mainPanel.add(deviceSelector, BorderLayout.CENTER);
@@ -864,7 +864,7 @@
 
             hideStatusBarComponents();
 
-            saveMenuItem.setEnabled(false);            
+            saveMenuItem.setEnabled(false);
             showDevicesMenuItem.setEnabled(false);
             showDevicesButton.setEnabled(false);
             displayNodeButton.setEnabled(false);
@@ -926,7 +926,7 @@
     }
 
     public void cleanupDevices() {
-        for (Device device : devicesTableModel.getDevices()) {
+        for (IDevice device : devicesTableModel.getDevices()) {
             DeviceBridge.removeDeviceForward(device);
         }
     }
@@ -989,7 +989,7 @@
             return null;
         }
         return new CaptureNodeTask();
-    }    
+    }
 
     public SwingWorker<?, ?> startServer() {
         return new StartServerTask();
@@ -1232,7 +1232,7 @@
 
         @Override
         protected void done() {
-            endTask();            
+            endTask();
         }
     }
 
@@ -1293,10 +1293,10 @@
     private class DevicesTableModel extends DefaultTableModel implements
             AndroidDebugBridge.IDeviceChangeListener {
 
-        private ArrayList<Device> devices;
+        private ArrayList<IDevice> devices;
 
         private DevicesTableModel() {
-            devices = new ArrayList<Device>();
+            devices = new ArrayList<IDevice>();
         }
 
         @Override
@@ -1320,7 +1320,7 @@
         }
 
         @WorkerThread
-        public void deviceConnected(final Device device) {
+        public void deviceConnected(final IDevice device) {
             DeviceBridge.setupDeviceForward(device);
 
             SwingUtilities.invokeLater(new Runnable() {
@@ -1331,7 +1331,7 @@
         }
 
         @WorkerThread
-        public void deviceDisconnected(final Device device) {
+        public void deviceDisconnected(final IDevice device) {
             DeviceBridge.removeDeviceForward(device);
 
             SwingUtilities.invokeLater(new Runnable() {
@@ -1341,14 +1341,14 @@
             });
         }
 
-        public void addDevice(Device device) {
+        public void addDevice(IDevice device) {
             if (!devices.contains(device)) {
                 devices.add(device);
                 fireTableDataChanged();
             }
         }
 
-        public void removeDevice(Device device) {
+        public void removeDevice(IDevice device) {
             if (device.equals(currentDevice)) {
                 reset();
             }
@@ -1360,12 +1360,12 @@
         }
 
         @WorkerThread
-        public void deviceChanged(Device device, int changeMask) {
-            if ((changeMask & Device.CHANGE_STATE) != 0 &&
+        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 & Device.CHANGE_CLIENT_LIST) != 0) {
+            } 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();
@@ -1378,12 +1378,12 @@
             return devices == null ? 0 : devices.size();
         }
 
-        public Device getDevice(int index) {
+        public IDevice getDevice(int index) {
             return index < devices.size() ? devices.get(index) : null;
         }
 
-        public Device[] getDevices() {
-            return devices.toArray(new Device[devices.size()]);
+        public IDevice[] getDevices() {
+            return devices.toArray(new IDevice[devices.size()]);
         }
     }
 
@@ -1441,7 +1441,7 @@
 
         public void clear() {
             windows.clear();
-            windows.add(Window.FOCUSED_WINDOW);            
+            windows.add(Window.FOCUSED_WINDOW);
         }
 
         public Window getWindow(int index) {
@@ -1462,7 +1462,7 @@
                 if (currentDevice != null) {
                     if (!DeviceBridge.isViewServerRunning(currentDevice)) {
                         DeviceBridge.startViewServer(currentDevice);
-                        checkForServerOnCurrentDevice();                        
+                        checkForServerOnCurrentDevice();
                     }
                     loadWindows().execute();
                     windowsTableModel.setVisible(true);
diff --git a/tools/jarutils/.gitignore b/tools/jarutils/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/tools/jarutils/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/tools/layoutlib_utils/.gitignore b/tools/layoutlib_utils/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/tools/layoutlib_utils/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java b/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java
index 8a8a677..77a6401 100755
--- a/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java
+++ b/tools/makedict/src/com/android/tools/dict/MakeBinaryDictionary.java
@@ -96,6 +96,7 @@
             parser.parse(new File(filename), new DefaultHandler() {
                 boolean inWord;
                 int freq;
+                StringBuilder wordBuilder = new StringBuilder(48);
 
                 @Override
                 public void startElement(String uri, String localName,
@@ -103,6 +104,7 @@
                     if (qName.equals("w")) {
                         inWord = true;
                         freq = Integer.parseInt(attributes.getValue(0));
+                        wordBuilder.setLength(0);
                     }
                 }
 
@@ -110,18 +112,19 @@
                 public void characters(char[] data, int offset, int length) {
                     // Ignore other whitespace
                     if (!inWord) return;
-                    
-                    // Ignore one letter words
-                    if (length < 2) return;
-                    mWordCount++;
-                    String word = new String(data, offset, length);
-                    addWordTop(word, freq);
+                    wordBuilder.append(data, offset, length);
                 }
 
                 @Override
                 public void endElement(String uri, String localName,
                         String qName) {
-                    if (qName.equals("w")) inWord = false;
+                    if (qName.equals("w")) {
+                        if (wordBuilder.length() > 1) {
+                            addWordTop(wordBuilder.toString(), freq);
+                            mWordCount++;
+                        }
+                        inWord = false;
+                    }
                 }
             });
         } catch (Exception ioe) {
@@ -145,7 +148,6 @@
 
     private void addWordTop(String word, int occur) {
         if (occur > 255) occur = 255;
-
         char firstChar = word.charAt(0);
         int index = indexOf(roots, firstChar);
         if (index == -1) {
diff --git a/tools/mkstubs/.classpath b/tools/mkstubs/.classpath
index a6b4c47..49a6d6c 100644
--- a/tools/mkstubs/.classpath
+++ b/tools/mkstubs/.classpath
@@ -1,9 +1,9 @@
-<?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/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/asm3"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
+<?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/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>

+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>

+	<classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/asm/asm-3.1.jar"/>

+	<classpathentry kind="output" path="bin"/>

+</classpath>

diff --git a/tools/mkstubs/.gitignore b/tools/mkstubs/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/tools/mkstubs/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/tools/mkstubs/.project b/tools/mkstubs/.project
index bef013e..12944f4 100644
--- a/tools/mkstubs/.project
+++ b/tools/mkstubs/.project
@@ -1,18 +1,17 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>MkStubs</name>
-	<comment></comment>
-	<projects>
-		<project>asm3</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>
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>MkStubs</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/runtest b/tools/runtest
deleted file mode 100755
index 6280910..0000000
--- a/tools/runtest
+++ /dev/null
@@ -1,360 +0,0 @@
-#!/bin/bash
-#
-# 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.
-
-# Options and default values
-# TODO: other options ideas:
-#   pass options to am (then remove some of the more specific options)
-# TODO capture more non-error output when not -v
-# TODO read configs from vendor/*, not just from vendor/google
-
-optListTests=0
-optSkipBuild=0
-optPreview=0
-optRawmode=0
-optSuiteAssignmentMode=0
-optAdbTarget=""
-optVerbose=0
-optWaitForDebugger=0
-optTestClass=""
-optTestMethod=""
-optUserTests=${HOME}/.android/runtest.rc
-
-#
-# process command-line options.  You must pass them into this function.
-# TODO error messages on once-only or mutually-exclusive options
-#
-function processOptions() {
-  while getopts "l b n a r d e s: v w c:t:u:" opt ; do  
-    case ${opt} in  
-      l ) optListTests=1 ;;
-      b ) optSkipBuild=1 ;;
-      n ) optPreview=1 ;;
-      r ) optRawMode=1 ;;
-      a ) optSuiteAssignmentMode=1 ;;
-      d ) optAdbTarget="-d" ;;
-      e ) optAdbTarget="-e" ;;
-      s ) optAdbTarget="-s ${OPTARG}" ;;
-      v ) optVerbose=1 ;;
-      w ) optWaitForDebugger=1 ;;
-      c ) optTestClass=${OPTARG} ;;
-      t ) optTestMethod=${OPTARG} ;;
-      u ) optUserTests=${OPTARG} ;;
-      esac
-  done
-}
-
-#
-# Show the command usage and options
-#
-function showUsage() {
-  echo "usage: The $progName script works in two ways.  You can query it for a list" >&2
-  echo "       of tests, or you can launch a test, test case, or test suite." >&2
-  echo "" >&2
-  echo "       $progName -l           # To view the list of tests" >&2
-  echo "" >&2
-  echo "       $progName              # To launch tests" >&2
-  echo "           [-b]                     # Skip build - just launch" >&2
-  echo "           [-n]                     # Do not execute, just preview commands" >&2
-  echo "           [-r]                     # Raw mode (for output to other tools)" >&2
-  echo "           [-a]                     # Suite assignment (for details & usage" >&2
-  echo "                                    #   see InstrumentationTestRunner)" >&2
-  echo "           [-v]                     # Increase verbosity of ${progName}" >&2
-  echo "           [-w]                     # Wait for debugger before launching tests" >&2
-  echo "           [-c test-class]          # Restrict test to a specific class" >&2
-  echo "           [-t test-method]         # Restrict test to a specific method" >&2
-  echo "           [-e | -d | -s ser-num]   # use emulator, device, or serial number" >&2
-  echo "           [-u user-tests-file]     # Alternate source of user definitions" >&2
-  echo "           short-test-name          # (req'd) test configuration to launch" >&2
-}
-
-# The list below are built-in test definitions.  You can also define your own
-# tests by creating a file named "~/.android/runtest.rc" and adding them to that
-# file.  (No array needed, just plain lines of text).
-#
-# Tests are defined by entries with the following format:
-# <short-name> <build-path> <test-package> <test-class>
-#              <testrunner-package> <testrunner-component>
-#
-# These map to the following commands:
-#   (if test-class = "#")
-#      adb shell am instrument -w \
-#        <testrunner-package>/<testrunner-component>
-#   (else)
-#      adb shell am instrument -w \
-#        -e class <test-package>.<test-class> \
-#        <testrunner-package>/<testrunner-component>
-#
-# In order to define the most common cases simply, "#" can be used for some of
-# the fields, with the following default values:
-#   <build-path> = "#":  skip build/sync step
-#   <test-package> = "#": test class is fully qualified with package
-#   <test-class> = "#":  omit "-e class" section
-#   <testrunner-package> = "#":   use same value as test-package
-#   <testrunner-component> = "#":  use "android.test.InstrumentationTestRunner"
-#
-# TODO: fields may be omitted completely if the trailing values are all "#"
-# TODO: this should be a here doc instead of an array
-
-knownTests=(
-  # NAME      BUILD DIR               <test-package> <test-class> <testrunner-package> <testrunner-component>
-
-  # system-wide tests
-  "framework  frameworks/base/tests/FrameworkTest # com.android.frameworktest.AllTests com.android.frameworktest.tests #"
-  "android    frameworks/base/tests/AndroidTests  com.android.unit_tests AndroidTests # #"
-  "smoke      frameworks/base/tests/SmokeTest     com.android.smoketest # com.android.smoketest.tests #"
-  "core       frameworks/base/tests/CoreTests     # android.core.CoreTests android.core #"
-  "libcore    frameworks/base/tests/CoreTests     # android.core.JavaTests android.core #"
-  "apidemos   development/samples/ApiDemos        com.example.android.apis # com.example.android.apis.tests #"
-  "launchperf development/apps/launchperf         com.android.launchperf # # .SimpleActivityLaunchPerformance"
-
-  # targeted framework tests
-  "heap       frameworks/base/tests/AndroidTests  com.android.unit_tests HeapTest # #"
-  "activity   frameworks/base/tests/AndroidTests  com.android.unit_tests activity.ActivityTests # #"
-  "deadlock  tests/Deadlock                       com.android.deadlock # com.android.deadlock.tests #"
-  "syncadapter vendor/google/tests/AbstractGDataSyncAdapterTest # # com.google.android.providers.abstractgdatasyncadaptertests #"
-  "tablemerger frameworks/base/tests/FrameworkTest # android.content.AbstractTableMergerTest com.android.frameworktest.tests #"
-  
-  # selected app tests
-  "browser    packages/apps/Browser            com.android.browser # # .BrowserTestRunner"
-  "browserfunc packages/apps/Browser           com.android.browser # # .BrowserFunctionalTestRunner"
-  "calendar   packages/apps/Calendar/tests     com.android.calendar.tests # # #"
-  "calprov    packages/providers/CalendarProvider   com.android.providers.calendar # com.android.providers.calendar.tests #"
-  "camera     tests/Camera            com.android.cameratests # # CameraInstrumentationTestRunner"
-  "contactsprov packages/providers/GoogleContactsProvider/tests com.android.providers.contacts # com.android.providers.contactstests #"
-  "email      packages/apps/Email              com.android.email # com.android.email.tests #"
-  "emailsmall packages/apps/Email              com.android.email SmallTests com.android.email.tests #"
-  "media      tests/MediaFrameworkTest    com.android.mediaframeworktest # # .MediaFrameworkTestRunner"
-  "mediaunit  tests/MediaFrameworkTest com.android.mediaframeworktest # # .MediaFrameworkUnitTestRunner"
-  "mediaprov  tests/MediaProvider     com.android.mediaprovidertests # # .MediaProviderTestsInstrumentation"
-  "mms        packages/apps/Mms                # # com.android.mms.tests com.android.mms.ui.MMSInstrumentationTestRunner"
-  "mmslaunch  packages/apps/Mms                # # com.android.mms.tests com.android.mms.SmsLaunchPerformance"
-  "phone      tests/Phone             com.android.phonetests # # .PhoneInstrumentationTestRunner"
-  "phonestress tests/Phone            com.android.phonetests # # .PhoneInstrumentationStressTestRunner"
-  "ringtone   tests/RingtoneSettings  com.android.ringtonesettingstests # # .RingtoneSettingsInstrumentationTestRunner"
-)
-
-#
-# Searches for a runtest.rc file in a given directory and, if found, prepends it to
-# the list of known tests.
-#
-function readConfigFile () {
-  rcFile=$1
-  if [[ -f ${rcFile} ]] ; then
-    declare -a lines
-    exec 3<${rcFile} || exit
-    while read curline <&3; do
-      if [[ -z ${curline} || ${curline:0:1} = "#" ]]; then
-        continue
-      fi
-      lines=("${lines[@]}" "${curline}")
-    done
-    exec 3<&-
-
-    # now prepend the user lines (so they can override defaults)
-    knownTests=("${lines[@]}" "${knownTests[@]}")
-  fi
-}
-
-#
-# Searches for a specific test in the knownTests array.  If found, writes out
-# the remaining elements in the definition line (not including the test name).
-#
-function findTest() {
-  count=${#knownTests[@]}
-  index=0
-  while [[ ${index} -lt ${count} ]]
-  do
-    # If the first word in the entry matches the argument...
-    test=(${knownTests[$index]})
-    if [[ ${test[0]} = $1 ]] ; then
-      # Print all but the first word
-      echo ${test[@]:1}
-      return
-    fi
-    let "index = $index + 1"
-  done
-}
-
-#
-# Generate a simple listing of available tests
-#
-function dumpTests() {
-  echo "The following tests are currently defined:"
-  count=${#knownTests[@]}
-  index=0
-  while [[ ${index} -lt ${count} ]]
-  do
-    test=(${knownTests[$index]})
-    echo "  " ${test[0]}
-    let "index = $index + 1"
-  done
-}
-
-#
-# Writes the full pathname of the "top" of the development tree, as set by envsetup & lunch.
-# (based on gettop() from envsetup.sh)
-#
-function gettop {
-  TOPFILE=build/core/envsetup.mk
-  if [[ -n ${TOP} && -f ${TOP}/${TOPFILE} ]] ; then
-    echo ${TOP}
-  else
-    if [[ -f ${TOPFILE} ]] ; then
-      echo ${PWD}
-    else
-      # We redirect cd to /dev/null in case it's aliased to
-      # a command that prints something as a side-effect
-      # (like pushd)
-      HERE=${PWD}
-      T=
-    # while [ \( ! \( -f ${TOPFILE} \) \) -a \( $PWD != "/" \) ]; do
-      while [[ ! -f ${TOPFILE} && ${PWD} != "/" ]] ; do
-        cd .. > /dev/null
-        T=${PWD}
-      done
-      cd ${HERE} > /dev/null
-      if [[ -f ${T}/${TOPFILE} ]]; then
-        echo ${T}
-      fi
-    fi
-  fi
-}
-
-#
-# Captures the "mmm" command from envsetup.sh
-#
-function call_mmm() {
-  TOP=$(gettop)
-  if [[ -n ${TOP} ]] ; then
-    . ${TOP}/build/envsetup.sh
-    mmm ${TOP}/$@
-  fi
-}
-
-# main script
-
-progName=$(basename $0)
-
-if [[ $# -eq 0 ]] ; then
-  showUsage
-  exit 1
-fi
-
-processOptions $@
-shift $((OPTIND-1))
-
-readConfigFile $optUserTests
-# TODO: Read from *any* vendor/*/runtest.rc
-readConfigFile $(gettop)/vendor/google/runtest.rc
-
-# if requested, list all tests and halt
-if [[ ${optListTests} -ne 0 ]] ; then
-  dumpTests
-  exit 0
-fi
-
-testInfo=($(findTest $1))
-if [[ ${#testInfo[@]} -eq 5 ]] ; then
-  # break out test definition elements
-  buildPath=${testInfo[0]}
-  testPackage=${testInfo[1]}
-  testClass=${testInfo[2]}
-  runnerPackage=${testInfo[3]}
-  runnerComponent=${testInfo[4]}
-
-  # replace wildcards with default values
-  if [[ ${testPackage} == "#" ]] ; then
-    testPackage=
-  fi
-  if [[ ${runnerPackage} == "#" ]] ; then
-    runnerPackage=$testPackage
-  fi
-  if [[ ${runnerComponent} == "#" ]] ; then
-    runnerComponent="android.test.InstrumentationTestRunner"
-  fi
-
-  if [[ -n ${optTestClass} ]] ; then
-    testClass=$optTestClass
-  fi
-
-  # build & sync, if requested
-  if [[ ${optSkipBuild} -eq 0 ]] ; then
-    if [[ ${buildPath} != "#" ]] ; then
-      if [[ $optVerbose -ne 0 || ${optPreview} -ne 0 ]] ; then
-        echo mmm ${buildPath} "&&" adb ${optAdbTarget} remount "&&" adb ${optAdbTarget} sync
-      fi
-      if [[ ${optPreview} -eq 0 ]] ; then
-        call_mmm ${buildPath} && adb ${optAdbTarget} remount && adb ${optAdbTarget} sync
-        buildResult=$?
-      else
-        buildResult=0
-      fi
-      if [[ $buildResult -ne 0 ]] ; then
-        exit ${buildResult}
-      fi
-      # finally, sleep a bit.  this is a hack.  it gives the package manager time to
-      # install the package(s) that were just synced.  this causes a reduction in the number
-      # of false failures, but it's not a perfect solution.
-      sleep 2
-    fi
-  fi
-
-  # setup additional clauses for the command
-  classOptions=""
-  if [[ ${testClass} != "#" ]] ; then
-    if [[ -z ${testPackage} ]] ; then
-      classOptions="-e class ${testClass}"
-    else
-      classOptions="-e class ${testPackage}.${testClass}"
-    fi
-    if [[ -n ${optTestMethod} ]] ; then
-      classOptions=${classOptions}#${optTestMethod}
-    fi
-  fi
-  debugOptions=""
-  if [[ ${optWaitForDebugger} -ne 0 ]] ; then
-    debugOptions="-e debug true"
-  fi
-  if [[ ${optSuiteAssignmentMode} -ne 0 ]] ; then
-    debugOptions="-e suiteAssignment true "${debugOptions}
-  fi
-  if [[ ${optRawMode} -ne 0 ]] ; then
-    debugOptions="-r "${debugOptions}
-  fi
-
-  # "prevent" a race condition where we try to run the tests before they're
-  # actually installed
-  sleep 2
-  
-  # now run the command
-  if [[ $optVerbose -ne 0 || ${optPreview} -ne 0 ]] ; then
-    echo adb ${optAdbTarget} shell am instrument -w \
-      ${debugOptions} \
-      ${classOptions} \
-      ${runnerPackage}/${runnerComponent}
-  fi
-  if [[ ${optPreview} -eq 0 ]] ; then
-    adb ${optAdbTarget} shell am instrument -w \
-      ${debugOptions} \
-      ${classOptions} \
-      ${runnerPackage}/${runnerComponent}
-  fi
-  exit 0
-else
-  echo "$progName: unknown test \"$1\"" >&2
-  exit 1
-fi
-
diff --git a/tools/screenshot/src/com/android/screenshot/Screenshot.java b/tools/screenshot/src/com/android/screenshot/Screenshot.java
index 40ceffa..06e1f6b 100644
--- a/tools/screenshot/src/com/android/screenshot/Screenshot.java
+++ b/tools/screenshot/src/com/android/screenshot/Screenshot.java
@@ -17,7 +17,7 @@
 package com.android.screenshot;
 
 import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.Device;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.RawImage;
 import com.android.ddmlib.Log.ILogOutput;
@@ -30,7 +30,7 @@
 import javax.imageio.ImageIO;
 
 /**
- * Connects to a device using ddmlib and dumps its event log as long as the device is connected. 
+ * Connects to a device using ddmlib and dumps its event log as long as the device is connected.
  */
 public class Screenshot {
 
@@ -40,7 +40,7 @@
         String serial = null;
         String filepath = null;
         boolean landscape = false;
-        
+
         if (args.length == 0) {
             printUsageAndQuit();
         }
@@ -69,7 +69,7 @@
                 if (device || emulator) {
                     printAndExit("-s conflicts with -d and -e", false /* terminate */);
                 }
-                
+
                 serial = args[index++];
             } else if ("-l".equals(argument)) {
                 landscape = true;
@@ -83,11 +83,11 @@
                 }
             }
         } 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);
@@ -97,7 +97,7 @@
                 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$
@@ -108,11 +108,11 @@
         }
 
         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.
@@ -124,7 +124,7 @@
                 } catch (InterruptedException e) {
                     // pass
                 }
-                
+
                 // let's not wait > 10 sec.
                 if (count > 100) {
                     System.err.println("Timeout getting device list!");
@@ -133,16 +133,16 @@
             }
 
             // now get the devices
-            Device[] devices = bridge.getDevices();
-            
+            IDevice[] devices = bridge.getDevices();
+
             if (devices.length == 0) {
                 printAndExit("No devices found!", true /* terminate */);
             }
-            
-            Device target = null;
-            
+
+            IDevice target = null;
+
             if (emulator || device) {
-                for (Device d : devices) {
+                for (IDevice d : devices) {
                     // this test works because emulator and device can't both be true at the same
                     // time.
                     if (d.isEmulator() == emulator) {
@@ -159,7 +159,7 @@
                     }
                 }
             } else if (serial != null) {
-                for (Device d : devices) {
+                for (IDevice d : devices) {
                     if (serial.equals(d.getSerialNumber())) {
                         target = d;
                         break;
@@ -172,7 +172,7 @@
                 }
                 target = devices[0];
             }
-            
+
             if (target != null) {
                 try {
                     System.out.println("Taking screenshot from: " + target.getSerialNumber());
@@ -188,11 +188,11 @@
             AndroidDebugBridge.terminate();
         }
     }
-    
+
     /*
      * Grab an image from an ADB-connected device.
      */
-    private static void getDeviceImage(Device device, String filepath, boolean landscape)
+    private static void getDeviceImage(IDevice device, String filepath, boolean landscape)
             throws IOException {
         RawImage rawImage;
 
@@ -209,28 +209,28 @@
             return;
 
         assert rawImage.bpp == 16;
-        
+
         BufferedImage image;
-        
+
         if (landscape) {
             // convert raw data to an Image
             image = new BufferedImage(rawImage.height, rawImage.width,
                     BufferedImage.TYPE_INT_ARGB);
-            
+
             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 >> 0) & 0x01F) << 3;
-                    
+
                     value = 0xFF << 24 | r << 16 | g << 8 | b;
-                    
+
                     image.setRGB(y, rawImage.width - x - 1, value);
                 }
             }
@@ -238,31 +238,31 @@
             // convert raw data to an Image
             image = new BufferedImage(rawImage.width, rawImage.height,
                     BufferedImage.TYPE_INT_ARGB);
-            
+
             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 >> 0) & 0x01F) << 3;
-                    
+
                     value = 0xFF << 24 | r << 16 | g << 8 | b;
-                    
+
                     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");
@@ -273,10 +273,10 @@
         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) {
diff --git a/tools/scripts/android_rules.xml b/tools/scripts/android_rules.xml
index 236327c..1f5daac 100644
--- a/tools/scripts/android_rules.xml
+++ b/tools/scripts/android_rules.xml
@@ -205,7 +205,7 @@
         <echo>Uninstalling ${application-package} from the default emulator...</echo>
         <exec executable="${adb}" failonerror="true">
             <arg value="uninstall" />
-            <arg path="${application-package}" />
+            <arg value="${application-package}" />
         </exec>
     </target>
     
diff --git a/tools/sdkmanager/.gitignore b/tools/sdkmanager/.gitignore
new file mode 100644
index 0000000..48f206a
--- /dev/null
+++ b/tools/sdkmanager/.gitignore
@@ -0,0 +1,4 @@
+app/bin
+libs/sdklib/bin
+libs/sdkuilib/bin
+
diff --git a/tools/sdkmanager/app/.classpath b/tools/sdkmanager/app/.classpath
index cbd9d37..4f2e142 100644
--- a/tools/sdkmanager/app/.classpath
+++ b/tools/sdkmanager/app/.classpath
@@ -1,11 +1,11 @@
-<?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="output" path="bin"/>
-</classpath>
+<?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="output" path="bin"/>

+</classpath>

diff --git a/tools/sdkmanager/app/.project b/tools/sdkmanager/app/.project
index e12c17d..aa82db5 100644
--- a/tools/sdkmanager/app/.project
+++ b/tools/sdkmanager/app/.project
@@ -1,17 +1,19 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>SdkManager</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>
+<?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/src/com/android/sdkmanager/CommandLineProcessor.java b/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java
index c20bfa4..4a3c16c 100644
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java
+++ b/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java
@@ -29,7 +29,7 @@
  * <li>override it.
  * <li>pass an action array to the constructor.
  * <li>define flags for your actions.
- * </ul> 
+ * </ul>
  * <p/>
  * To use, call {@link #parseArgs(String[])} and then
  * call {@link #getValue(String, String, String)}.
@@ -38,17 +38,17 @@
 
     /** 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. */ 
+
+    /** 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. */
@@ -66,7 +66,7 @@
      * </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;
@@ -80,7 +80,7 @@
     private final HashMap<String, Arg> mArguments = new HashMap<String, Arg>();
     /** Logger */
     private final ISdkLog mLog;
-    
+
     public CommandLineProcessor(ISdkLog logger, String[][] actions) {
         mLog = logger;
         mActions = actions;
@@ -95,7 +95,18 @@
                 "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
 
@@ -113,7 +124,7 @@
     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;
@@ -123,9 +134,9 @@
     public String getDirectObject() {
         return mDirectObjectRequested;
     }
-    
+
     //------------------
-    
+
     /**
      * Raw access to parsed parameter values.
      * <p/>
@@ -133,10 +144,10 @@
      * 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. 
+     * 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.
@@ -153,7 +164,7 @@
             Arg arg = mArguments.get(key);
             return arg.getCurrentValue();
         }
-        
+
         Object lastDefault = null;
         for (Arg arg : mArguments.values()) {
             if (arg.getLongArg().equals(longFlagName)) {
@@ -169,7 +180,7 @@
                 }
             }
         }
-        
+
         return lastDefault;
     }
 
@@ -191,7 +202,7 @@
      * 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) {
@@ -209,7 +220,7 @@
                 } 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?
@@ -217,7 +228,7 @@
                         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);
@@ -225,14 +236,14 @@
                         } 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) {
@@ -241,7 +252,7 @@
                                 break;
                             }
                         }
-                        
+
                         // Error if it was not a valid verb
                         if (verb == null) {
                             needsHelp = String.format(
@@ -249,7 +260,7 @@
                                 a);
                             return;
                         }
-    
+
                     } else if (directObject == null) {
                         // Then fill the direct object. Find it.
                         for (String[] actionDesc : mActions) {
@@ -266,20 +277,20 @@
                                 }
                             }
                         }
-                        
+
                         // 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()) {
@@ -287,11 +298,11 @@
                             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.
@@ -302,18 +313,18 @@
                             return;
                         }
                     }
-                    
+
                     if (error != null) {
                         needsHelp = String.format("Invalid usage for flag %1$s: %2$s.", a, error);
                         return;
                     }
                 }
             }
-        
+
             if (needsHelp == null) {
-                if (verb == null) {
+                if (verb == null && !acceptLackOfVerb()) {
                     needsHelp = "Missing verb name.";
-                } else {
+                } else if (verb != null) {
                     if (directObject == null) {
                         // Make sure this verb has an optional direct object
                         for (String[] actionDesc : mActions) {
@@ -323,13 +334,13 @@
                                 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;
@@ -347,7 +358,7 @@
                             }
                         }
                     }
-    
+
                     if (missing != null) {
                         needsHelp  = String.format(
                                 "The %1$s %2$s must be defined for action '%3$s %4$s'",
@@ -367,7 +378,7 @@
             }
         }
     }
-    
+
     /**
      * Finds an {@link Arg} given an action name and a long flag name.
      * @return The {@link Arg} found or null.
@@ -409,23 +420,23 @@
 
     /**
      * Prints the help/usage and exits.
-     * 
-     * @param errorFormat Optional error message to print prior to usage using String.format 
+     *
+     * @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 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,
@@ -433,7 +444,7 @@
         if (errorFormat != null) {
             stderr(errorFormat, args);
         }
-        
+
         /*
          * usage should fit in 80 columns
          *   12345678901234567890123456789012345678901234567890123456789012345678901234567890
@@ -448,14 +459,14 @@
         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$-7s: %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])) {
@@ -468,7 +479,7 @@
                 }
             }
         }
-        
+
         exit();
     }
 
@@ -480,12 +491,12 @@
         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()) {
@@ -504,7 +515,7 @@
                         value = " [Default: " + value + "]";
                     }
                 }
-                
+
                 stdout("  -%1$s %2$-10s %3$s%4$s%5$s",
                         arg.getShortArg(),
                         "--" + arg.getLongArg(),
@@ -514,14 +525,14 @@
                 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.
@@ -558,7 +569,7 @@
                 }
             }
         },
-        
+
         /** Argument value is a String. Default value is a String[]. */
         ENUM {
             @Override
@@ -574,7 +585,7 @@
                         arg.setCurrentValue(extra);
                         return null;
                     }
-                    
+
                     if (desc.length() != 0) {
                         desc.append(", ");
                     }
@@ -584,7 +595,7 @@
                 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
@@ -597,7 +608,7 @@
                 return null;
             }
         };
-        
+
         /**
          * Returns true if this mode requires an extra parameter.
          */
@@ -605,9 +616,9 @@
 
         /**
          * Processes the flag for this argument.
-         * 
+         *
          * @param arg The argument being processed.
-         * @param extra The extra parameter. Null if {@link #needsExtra()} returned false. 
+         * @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);
@@ -618,7 +629,7 @@
      * 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.)  
+     * or a String array (in which case the first item is the current by default.)
      */
     static class Arg {
         /** Verb for that argument. Never null. */
@@ -644,9 +655,9 @@
 
         /**
          * 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 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.
@@ -676,27 +687,27 @@
                 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;
@@ -706,12 +717,12 @@
         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;
@@ -721,26 +732,26 @@
         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.
@@ -756,11 +767,11 @@
             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));
@@ -777,7 +788,7 @@
     /**
      * 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.
      */
@@ -788,7 +799,7 @@
     /**
      * 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.
      */
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
index 35d9bb1..94f3062 100644
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
+++ b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
@@ -23,19 +23,19 @@
 import com.android.sdklib.SdkConstants;
 import com.android.sdklib.SdkManager;
 import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
-import com.android.sdklib.avd.AvdManager;
-import com.android.sdklib.avd.HardwareProperties;
-import com.android.sdklib.avd.AvdManager.AvdInfo;
-import com.android.sdklib.avd.HardwareProperties.HardwareProperty;
-import com.android.sdklib.project.ProjectCreator;
-import com.android.sdklib.project.ProjectCreator.OutputLevel;
+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.ProjectCreator.OutputLevel;
+import com.android.sdkuilib.repository.UpdaterWindow;
 
 import java.io.File;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.regex.Pattern;
 
 /**
  * Main class for the 'android' application.
@@ -47,18 +47,12 @@
     /** 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";
-    
+
     private final static String[] BOOLEAN_YES_REPLIES = new String[] { "yes", "y" };
     private final static String[] BOOLEAN_NO_REPLIES = new String[] { "no", "n" };
 
-    /** Regex used to validate characters that compose an AVD name. */
-    private final static Pattern RE_AVD_NAME = Pattern.compile("[a-zA-Z0-9._-]+");
-    /** List of valid characters for an AVD name. Used for display purposes. */
-    private final static String CHARS_AVD_NAME = "a-z A-Z 0-9 . _ -";
-    
-    
     /** Path to the SDK folder. This is the parent of {@link #TOOLSDIR}. */
-    private String mSdkFolder;
+    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. */
@@ -71,7 +65,7 @@
     public static void main(String[] args) {
         new Main().run(args);
     }
-    
+
     /**
      * Runs the sdk manager app
      */
@@ -130,28 +124,28 @@
             // 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);
-                mSdkFolder = tools.getParent();
+                mOsSdkFolder = tools.getParent();
             } else {
                 try {
                     tools = new File(".").getCanonicalFile();
-                    mSdkFolder = tools.getParent();
+                    mOsSdkFolder = tools.getParent();
                 } catch (IOException e) {
                     // Will print an error below since mSdkFolder is not defined
                 }
             }
         }
 
-        if (mSdkFolder == null) {
+        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.
@@ -177,20 +171,20 @@
      * Does the basic SDK parsing required for all actions
      */
     private void parseSdk() {
-        mSdkManager = SdkManager.createManager(mSdkFolder, mSdkLog);
-        
+        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)) {
@@ -226,13 +220,34 @@
                 SdkCommandLine.OBJECT_PROJECT.equals(directObject)) {
             updateProject();
 
+        } else if (verb == null && directObject == null) {
+            showMainWindow();
+
+        } else if (SdkCommandLine.VERB_UPDATE.equals(verb) &&
+                SdkCommandLine.OBJECT_ADB.equals(directObject)) {
+            updateAdb();
+
         } else {
             mSdkCommandLine.printHelpAndExit(null);
         }
     }
 
     /**
-     * Creates a new Android project based on command-line parameters 
+     * Display the main SdkManager app window
+     */
+    private void showMainWindow() {
+        try {
+            UpdaterWindow window = new UpdaterWindow(
+                    mOsSdkFolder,
+                    false /*userCanChangeSdkRoot*/);
+            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.
@@ -243,8 +258,8 @@
                     SdkConstants.androidCmdName());
         }
         IAndroidTarget target = targets[targetId - 1];
-        
-        ProjectCreator creator = new ProjectCreator(mSdkFolder,
+
+        ProjectCreator creator = new ProjectCreator(mOsSdkFolder,
                 mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
                     mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
                         OutputLevel.NORMAL,
@@ -255,7 +270,7 @@
         String projectName = mSdkCommandLine.getParamName();
         String packageName = mSdkCommandLine.getParamProjectPackage();
         String activityName = mSdkCommandLine.getParamProjectActivity();
-        
+
         if (projectName != null &&
                 !ProjectCreator.RE_PROJECT_NAME.matcher(projectName).matches()) {
             errorAndExit(
@@ -291,7 +306,7 @@
     }
 
     /**
-     * Updates an existing Android project based on command-line parameters 
+     * Updates an existing Android project based on command-line parameters
      */
     private void updateProject() {
         // get the target and try to resolve it.
@@ -305,15 +320,15 @@
             }
             target = targets[targetId - 1];
         }
-        
-        ProjectCreator creator = new ProjectCreator(mSdkFolder,
+
+        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());
@@ -322,12 +337,12 @@
     /**
      * 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()) {
@@ -342,7 +357,7 @@
         // 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",
@@ -374,7 +389,7 @@
                 }
                 mSdkLog.printf("     Based on Android %s (API level %d)\n",
                         target.getApiVersionName(), target.getApiVersionNumber());
-                
+
                 // display the optional libraries.
                 IOptionalLibrary[] libraries = target.getOptionalLibraries();
                 if (libraries != null) {
@@ -390,7 +405,12 @@
 
             // 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++;
         }
     }
@@ -411,7 +431,7 @@
                     first = false;
                 }
                 mSdkLog.printf(skin);
-                
+
                 if (skin.equals(defaultSkin)) {
                     mSdkLog.printf(" (default)");
                 }
@@ -421,7 +441,7 @@
             mSdkLog.printf("no skins.\n");
         }
     }
-    
+
     /**
      * Displays the list of available AVDs.
      */
@@ -451,7 +471,7 @@
                     mSdkLog.printf("          Based on Android %s (API level %d)\n", target
                             .getApiVersionName(), target.getApiVersionNumber());
                 }
-                
+
                 // display some extra values.
                 Map<String, String> properties = info.getProperties();
                 if (properties != null) {
@@ -501,7 +521,7 @@
         // find a matching target
         int targetId = mSdkCommandLine.getParamTargetId();
         IAndroidTarget target = null;
-        
+
         if (targetId >= 1 && targetId <= mSdkManager.getTargets().length) {
             target = mSdkManager.getTargets()[targetId-1]; // target it is 1-based
         } else {
@@ -514,14 +534,14 @@
             AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
 
             String avdName = mSdkCommandLine.getParamName();
-            
-            if (!RE_AVD_NAME.matcher(avdName).matches()) {
+
+            if (!AvdManager.RE_AVD_NAME.matcher(avdName).matches()) {
                 errorAndExit(
                     "AVD name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
-                    avdName, CHARS_AVD_NAME);
+                    avdName, AvdManager.CHARS_AVD_NAME);
                 return;
             }
-            
+
             AvdInfo info = avdManager.getAvd(avdName, false /*validAvdOnly*/);
             if (info != null) {
                 if (removePrevious) {
@@ -556,7 +576,7 @@
             if (removePrevious) {
                 oldAvdInfo = avdManager.getAvd(avdName, false /*validAvdOnly*/);
             }
-            
+
             // Validate skin is either default (empty) or NNNxMMM or a valid skin name.
             String skin = mSdkCommandLine.getParamSkin();
             if (skin != null && skin.length() == 0) {
@@ -572,7 +592,7 @@
                         break;
                     }
                 }
-                
+
                 // Is it NNNxMMM?
                 if (!valid) {
                     valid = AvdManager.NUMERIC_SKIN_SIZE.matcher(skin).matches();
@@ -584,7 +604,7 @@
                     return;
                 }
             }
-            
+
             AvdInfo newAvdInfo = avdManager.createAvd(avdFolder,
                     avdName,
                     target,
@@ -592,19 +612,7 @@
                     mSdkCommandLine.getParamSdCard(),
                     hardwareConfig,
                     removePrevious);
-            
-            if (newAvdInfo != null && 
-                    oldAvdInfo != null &&
-                    !oldAvdInfo.getPath().equals(newAvdInfo.getPath())) {
-                mSdkLog.warning("Removing previous AVD directory at %s", oldAvdInfo.getPath());
-                // Remove the old data directory
-                File dir = new File(oldAvdInfo.getPath());
-                avdManager.recursiveDelete(dir);
-                dir.delete();
-                // Remove old AVD info from manager
-                avdManager.removeAvd(oldAvdInfo);
-            }
-            
+
         } catch (AndroidLocationException e) {
             errorAndExit(e.getMessage());
         }
@@ -619,18 +627,18 @@
             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.
      */
@@ -639,12 +647,12 @@
             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())) {
@@ -665,17 +673,17 @@
                     }
                 } catch (IOException e) {
                     // Fail to resolve canonical path. Fail now since a move operation might fail
-                    // later and be harder to recover from. 
+                    // 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.
@@ -692,12 +700,12 @@
                                      newName + AvdManager.AVD_FOLDER_EXTENSION);
                         paramFolderPath = f.getCanonicalPath();
                     } catch (IOException e) {
-                        // Fail to resolve canonical path. Fail now rather than later. 
+                        // 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) {
@@ -717,7 +725,7 @@
                         "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());
@@ -725,7 +733,7 @@
             errorAndExit(e.getMessage());
         }
     }
-    
+
     /**
      * Updates a broken AVD.
      */
@@ -740,20 +748,38 @@
             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 
+     * @throws IOException
      */
     private Map<String, String> promptForHardware(IAndroidTarget createTarget) 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) {
@@ -764,17 +790,17 @@
             // no custom config.
             return null;
         }
-        
+
         mSdkLog.printf("\n"); // empty line
-        
+
         // get the list of possible hardware properties
-        File hardwareDefs = new File (mSdkFolder + File.separator +
+        File hardwareDefs = new File (mOsSdkFolder + File.separator +
                 SdkConstants.OS_SDK_TOOLS_LIB_FOLDER, SdkConstants.FN_HARDWARE_INI);
         List<HardwareProperty> list = HardwareProperties.parseHardwareDefinitions(hardwareDefs,
                 null /*sdkLog*/);
-        
+
         HashMap<String, String> map = new HashMap<String, String>();
-        
+
         for (int i = 0 ; i < list.size() ;) {
             HardwareProperty property = list.get(i);
 
@@ -786,13 +812,13 @@
             }
 
             String defaultValue = property.getDefault();
-            
+
             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 (defaultValue != null) {
@@ -802,7 +828,7 @@
                 }
                 continue;
             }
-            
+
             switch (property.getType()) {
                 case BOOLEAN:
                     try {
@@ -834,13 +860,13 @@
                     i++; // valid reply, move to next property
                     break;
             }
-            
+
             mSdkLog.printf("\n"); // empty line
         }
 
         return map;
     }
-    
+
     /**
      * Reads the line from the input stream.
      * @param buffer
@@ -848,7 +874,7 @@
      */
     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
@@ -856,7 +882,7 @@
 
             // and read the rest
             String secondHalf = readLine(tempBuffer);
-            
+
             // return a concat of both
             return new String(buffer, 0, count) + secondHalf;
         }
@@ -865,16 +891,16 @@
         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;
@@ -889,9 +915,9 @@
 
         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);
     }
-}
\ No newline at end of file
+}
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java b/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
index 36172e9..2ff0c53 100644
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
+++ b/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
@@ -36,6 +36,7 @@
     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_ADB      = "adb";
 
     public static final String ARG_ALIAS    = "alias";
     public static final String ARG_ACTIVITY = "activity";
@@ -72,7 +73,7 @@
             { VERB_LIST, OBJECT_TARGET,
                 "Lists existing targets.",
                 OBJECT_TARGETS },
-    
+
             { VERB_CREATE, OBJECT_AVD,
                 "Creates a new Android Virtual Device." },
             { VERB_MOVE, OBJECT_AVD,
@@ -81,58 +82,61 @@
                 "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_UPDATE, OBJECT_ADB,
+                "Updates adb to support the USB devices declared in the SDK add-ons." },
         };
-    
+
     public SdkCommandLine(ISdkLog logger) {
         super(logger, ACTIONS);
 
         // --- create avd ---
-        
-        define(MODE.STRING, false, 
+
+        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, 
+        define(MODE.STRING, true,
                 VERB_CREATE, OBJECT_AVD, "n", KEY_NAME,
                 "Name of the new AVD", null);
-        define(MODE.INTEGER, true, 
+        define(MODE.INTEGER, true,
                 VERB_CREATE, OBJECT_AVD, "t", KEY_TARGET_ID,
                 "Target id of the new AVD", null);
-        define(MODE.STRING, false, 
+        define(MODE.STRING, false,
                 VERB_CREATE, OBJECT_AVD, "s", KEY_SKIN,
                 "Skin of the new AVD", null);
-        define(MODE.STRING, false, 
+        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, 
+        define(MODE.BOOLEAN, false,
                 VERB_CREATE, OBJECT_AVD, "f", KEY_FORCE,
                 "Force creation (override an existing AVD)", false);
 
         // --- delete avd ---
-        
-        define(MODE.STRING, true, 
+
+        define(MODE.STRING, true,
                 VERB_DELETE, OBJECT_AVD, "n", KEY_NAME,
                 "Name of the AVD to delete", null);
 
         // --- move avd ---
-        
-        define(MODE.STRING, true, 
+
+        define(MODE.STRING, true,
                 VERB_MOVE, OBJECT_AVD, "n", KEY_NAME,
                 "Name of the AVD to move or rename", null);
-        define(MODE.STRING, false, 
+        define(MODE.STRING, false,
                 VERB_MOVE, OBJECT_AVD, "r", KEY_RENAME,
                 "New name of the AVD to rename", null);
-        define(MODE.STRING, false, 
+        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, 
+
+        define(MODE.STRING, true,
                 VERB_UPDATE, OBJECT_AVD, "n", KEY_NAME,
                 "Name of the AVD to update", null);
 
@@ -140,51 +144,56 @@
 
         /* 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, 
+
+        define(MODE.ENUM, true,
                 VERB_CREATE, OBJECT_PROJECT, "m", KEY_MODE,
                 "Project mode", new String[] { ARG_ACTIVITY, ARG_ALIAS });
         */
-        define(MODE.STRING, true, 
+        define(MODE.STRING, true,
                 VERB_CREATE, OBJECT_PROJECT,
                 "p", KEY_PATH,
                 "Location path of new project", null);
-        define(MODE.INTEGER, true, 
+        define(MODE.INTEGER, true,
                 VERB_CREATE, OBJECT_PROJECT, "t", KEY_TARGET_ID,
                 "Target id of the new project", null);
-        define(MODE.STRING, true, 
+        define(MODE.STRING, true,
                 VERB_CREATE, OBJECT_PROJECT, "k", KEY_PACKAGE,
                 "Package name", null);
-        define(MODE.STRING, true, 
+        define(MODE.STRING, true,
                 VERB_CREATE, OBJECT_PROJECT, "a", KEY_ACTIVITY,
                 "Activity name", null);
-        define(MODE.STRING, false, 
+        define(MODE.STRING, false,
                 VERB_CREATE, OBJECT_PROJECT, "n", KEY_NAME,
                 "Project name", null);
 
         // --- update project ---
 
-        define(MODE.STRING, true, 
+        define(MODE.STRING, true,
                 VERB_UPDATE, OBJECT_PROJECT,
                 "p", KEY_PATH,
                 "Location path of the project", null);
-        define(MODE.INTEGER, true, 
+        define(MODE.INTEGER, true,
                 VERB_UPDATE, OBJECT_PROJECT,
                 "t", KEY_TARGET_ID,
                 "Target id to set for the project", -1);
-        define(MODE.STRING, false, 
+        define(MODE.STRING, false,
                 VERB_UPDATE, OBJECT_PROJECT,
                 "n", KEY_NAME,
                 "Project name", 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. */
     public int getParamTargetId() {
         return ((Integer) getValue(null, null, KEY_TARGET_ID)).intValue();
@@ -194,7 +203,7 @@
     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));
@@ -204,7 +213,7 @@
     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();
@@ -219,7 +228,7 @@
 
 
     // -- some helpers for project action flags
-    
+
     /** Helper to retrieve the --package value. */
     public String getParamProjectPackage() {
         return ((String) getValue(null, OBJECT_PROJECT, KEY_PACKAGE));
diff --git a/tools/sdkmanager/libs/sdklib/.classpath b/tools/sdkmanager/libs/sdklib/.classpath
index fc17a43..050eeb2 100644
--- a/tools/sdkmanager/libs/sdklib/.classpath
+++ b/tools/sdkmanager/libs/sdklib/.classpath
@@ -1,7 +1,9 @@
-<?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>
+<?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="output" path="bin"/>

+</classpath>

diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java
index 2336f47..c02c247 100644
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java
@@ -33,7 +33,7 @@
      * Format is vendor:name:apiVersion
      * */
     private final static String ADD_ON_FORMAT = "%s:%s:%d"; //$NON-NLS-1$
-    
+
     private final static class OptionalLibrary implements IOptionalLibrary {
         private final String mJarName;
         private final String mJarPath;
@@ -58,12 +58,12 @@
         public String getName() {
             return mName;
         }
-        
+
         public String getDescription() {
             return mDescription;
         }
     }
-    
+
     private final String mLocation;
     private final PlatformTarget mBasePlatform;
     private final String mName;
@@ -72,6 +72,7 @@
     private String[] mSkins;
     private String mDefaultSkin;
     private IOptionalLibrary[] mLibraries;
+    private int mVendorId = NO_USB_ID;
 
     /**
      * Creates a new add-on
@@ -94,7 +95,7 @@
         mVendor = vendor;
         mDescription = description;
         mBasePlatform = basePlatform;
-        
+
         // handle the optional libraries.
         if (libMap != null) {
             mLibraries = new IOptionalLibrary[libMap.size()];
@@ -108,23 +109,23 @@
             }
         }
     }
-    
+
     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());
     }
@@ -142,15 +143,15 @@
         // this is always defined by the base platform
         return mBasePlatform.getApiVersionNumber();
     }
-    
+
     public boolean isPlatform() {
         return false;
     }
-    
+
     public IAndroidTarget getParent() {
         return mBasePlatform;
     }
-    
+
     public String getPath(int pathId) {
         switch (pathId) {
             case IMAGES:
@@ -168,7 +169,7 @@
                         public boolean accept(File pathname) {
                             return pathname.isDirectory();
                         }
-                        
+
                     });
                     if (files != null && files.length > 0) {
                         return sampleLoc.getAbsolutePath();
@@ -183,7 +184,7 @@
     public String[] getSkins() {
         return mSkins;
     }
-    
+
     public String getDefaultSkin() {
         return mDefaultSkin;
     }
@@ -191,7 +192,20 @@
     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) {
@@ -213,28 +227,28 @@
 
         return false;
     }
-    
+
     public String hashString() {
         return String.format(ADD_ON_FORMAT, mVendor, mName, mBasePlatform.getApiVersionNumber());
     }
-    
+
     @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.getApiVersionNumber() == addon.mBasePlatform.getApiVersionNumber();
         }
 
         return super.equals(obj);
     }
-    
+
     /*
      * Always return +1 if the object we compare to is a platform.
      * Otherwise, do vendor then name then api version comparison.
@@ -245,7 +259,7 @@
         if (target.isPlatform()) {
             return +1;
         }
-        
+
         // vendor
         int value = mVendor.compareTo(target.getVendor());
 
@@ -253,27 +267,36 @@
         if (value == 0) {
             value = mName.compareTo(target.getName());
         }
-        
+
         // api version
         if (value == 0) {
             value = getApiVersionNumber() - target.getApiVersionNumber();
         }
-        
+
         return value;
     }
 
-    
     // ---- local methods.
 
-
-    public void setSkins(String[] skins, String defaultSkin) {
+    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/IAndroidTarget.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java
index 896a83c..75b1d65 100644
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java
@@ -17,11 +17,12 @@
 package com.android.sdklib;
 
 
+
 /**
- * A version of Android that application can target when building. 
+ * A version of Android that applications can target when building.
  */
 public interface IAndroidTarget extends Comparable<IAndroidTarget> {
-    
+
     /** OS Path to the "android.jar" file. */
     public static int ANDROID_JAR         = 1;
     /** OS Path to the "framework.aidl" file. */
@@ -30,7 +31,7 @@
     public static int IMAGES              = 3;
     /** OS Path to the "samples" folder which contains sample projects. */
     public static int SAMPLES             = 4;
-    /** OS Path to the "skins" folder which contains the emulator skins. */ 
+    /** OS Path to the "skins" folder which contains the emulator skins. */
     public static int SKINS               = 5;
     /** OS Path to the "templates" folder which contains the templates for new projects. */
     public static int TEMPLATES           = 6;
@@ -68,7 +69,13 @@
     public static int DX                  = 22;
     /** OS Path to the target's version of the dx.jar file. */
     public static int DX_JAR              = 23;
-    
+
+    /**
+     * Return value for {@link #getUsbVendorId()} meaning no USB vendor IDs are defined by the
+     * Android target.
+     */
+    public static int NO_USB_ID = 0;
+
     public interface IOptionalLibrary {
         String getName();
         String getJarName();
@@ -90,22 +97,22 @@
      * 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 api version as an integer.
      */
@@ -115,41 +122,54 @@
      * Returns the platform version as a readable string.
      */
     String getApiVersionName();
-    
+
     /**
      * 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
@@ -158,7 +178,7 @@
      * @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
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java
index d4e40b1..bbb3cd7 100644
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java
@@ -22,12 +22,12 @@
 import java.util.Map;
 
 /**
- * Represents a platform target in the SDK. 
+ * 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-%d";
-    
+
     private final static String PLATFORM_VENDOR = "Android Open Source Project";
     private final static String PLATFORM_NAME = "Android %s";
 
@@ -38,7 +38,7 @@
     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 apiNumber, String apiName) {
         mName = String.format(PLATFORM_NAME, apiName);
@@ -49,7 +49,7 @@
         mProperties = Collections.unmodifiableMap(properties);
         mApiVersionNumber = apiNumber;
         mApiVersionName = apiName;
-        
+
         // 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);
@@ -81,16 +81,16 @@
         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() {
@@ -100,65 +100,83 @@
     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", mApiVersionName);
     }
-    
+
     public int getApiVersionNumber(){
         return mApiVersionNumber;
     }
-    
+
     public String getApiVersionName() {
         return mApiVersionName;
     }
-    
+
     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 platforms have no optional libraries.
-     * 
-     * (non-Javadoc)
+    /**
+     * 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) {
@@ -169,7 +187,7 @@
         // equal.
         return target.getApiVersionNumber() >= mApiVersionNumber;
     }
-    
+
     public String hashString() {
         return String.format(PLATFORM_HASH, mApiVersionNumber);
     }
@@ -178,13 +196,13 @@
     public int hashCode() {
         return hashString().hashCode();
     }
-    
+
     @Override
     public boolean equals(Object obj) {
         if (obj instanceof PlatformTarget) {
             return mApiVersionNumber == ((PlatformTarget)obj).mApiVersionNumber;
         }
-        
+
         return super.equals(obj);
     }
 
@@ -203,11 +221,11 @@
     }
 
     // ---- platform only methods.
-    
+
     public String getProperty(String name) {
         return mProperties.get(name);
     }
-    
+
     public Map<String, String> getProperties() {
         return mProperties; // mProperties is unmodifiable.
     }
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java
index 9eb6ade..32b9a2e 100644
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java
@@ -41,7 +41,6 @@
      */
     public final static int CURRENT_PLATFORM = currentPlatform();
 
-    
     /** An SDK Project's AndroidManifest.xml file */
     public static final String FN_ANDROID_MANIFEST_XML= "AndroidManifest.xml";
     /** An SDK Project's build.xml file */
@@ -83,18 +82,26 @@
     /** dex.jar file */
     public static final String FN_DX_JAR = "dx.jar"; //$NON-NLS-1$
 
-    /** dx executable */
+    /** 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 */
+    /** 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 */
+    /** 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$
+
     /* Folder Names for Android Projects . */
 
     /** Resources folder name, i.e. "res". */
@@ -132,7 +139,7 @@
     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. */
@@ -167,6 +174,9 @@
     /** 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. */
@@ -182,7 +192,7 @@
             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;
@@ -230,14 +240,14 @@
     /** 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";
 
@@ -265,7 +275,7 @@
 
     /**
      * Returns current platform
-     * 
+     *
      * @return one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
      * {@link #PLATFORM_LINUX} or {@link #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
index 28227c6..a1be66f 100644
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java
@@ -16,15 +16,20 @@
 
 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;
@@ -32,26 +37,31 @@
 /**
  * The SDK manager parses the SDK folder and gives access to the content.
  * @see PlatformTarget
- * @see AddOnTarget 
+ * @see AddOnTarget
  */
 public final class SdkManager {
-    
+
     public final static String PROP_VERSION_SDK = "ro.build.version.sdk";
     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 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[] {
@@ -63,6 +73,14 @@
         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;
@@ -79,39 +97,39 @@
             ArrayList<IAndroidTarget> list = new ArrayList<IAndroidTarget>();
             manager.loadPlatforms(list, log);
             manager.loadAddOns(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.
      */
     public IAndroidTarget[] getTargets() {
         return mTargets;
     }
-    
+
     /**
      * 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.
      */
@@ -127,11 +145,43 @@
         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 {
+            writer.close();
+        }
+    }
 
     private SdkManager(String sdkLocation) {
         mSdkLocation = sdkLocation;
     }
-    
+
     private void setTargets(IAndroidTarget[] targets) {
         mTargets = targets;
     }
@@ -145,7 +195,7 @@
         File platformFolder = new File(mSdkLocation, SdkConstants.FD_PLATFORMS);
         if (platformFolder.isDirectory()) {
             File[] platforms  = platformFolder.listFiles();
-            
+
             for (File platform : platforms) {
                 if (platform.isDirectory()) {
                     PlatformTarget target = loadPlatform(platform, log);
@@ -156,7 +206,7 @@
                     log.warning("Ignoring platform '%1$s', not a folder.", platform.getName());
                 }
             }
-            
+
             return;
         }
 
@@ -178,10 +228,10 @@
      */
     private 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.
                 try {
@@ -198,7 +248,7 @@
                                 map,
                                 Integer.parseInt(apiNumber),
                                 apiName);
-                        
+
                         // need to parse the skins.
                         String[] skins = parseSkinFolder(target.getPath(IAndroidTarget.SKINS));
                         target.setSkins(skins);
@@ -219,7 +269,7 @@
             log.error(null, "Ignoring platform '%1$s': %2$s is missing.", platform.getName(),
                     SdkConstants.FN_BUILD_PROP);
         }
-        
+
         return null;
     }
 
@@ -232,7 +282,7 @@
         File addonFolder = new File(mSdkLocation, 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()) {
@@ -256,19 +306,19 @@
         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 list 
-     * @param log 
+     * @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 AddOnTarget loadAddon(File addon, ArrayList<IAndroidTarget> list, ISdkLog log) {
+    private 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
@@ -277,7 +327,7 @@
                     displayAddonManifestError(log, addon.getName(), ADDON_NAME);
                     return null;
                 }
-                
+
                 String vendor = propertyMap.get(ADDON_VENDOR);
                 if (vendor == null) {
                     displayAddonManifestError(log, addon.getName(), ADDON_VENDOR);
@@ -292,14 +342,14 @@
                 } else {
                     try {
                         int apiValue = Integer.parseInt(api);
-                        for (IAndroidTarget target : list) {
+                        for (IAndroidTarget target : targetList) {
                             if (target.isPlatform() &&
                                     target.getApiVersionNumber() == apiValue) {
                                 baseTarget = (PlatformTarget)target;
                                 break;
                             }
                         }
-                        
+
                         if (baseTarget == null) {
                             if (log != null) {
                                 log.error(null,
@@ -320,14 +370,14 @@
                         return null;
                     }
                 }
-                
+
                 // get the optional description
                 String description = propertyMap.get(ADDON_DESCRIPTION);
-                
+
                 // 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) {
@@ -340,7 +390,7 @@
 
                                 // 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);
@@ -364,13 +414,19 @@
 
                 AddOnTarget target = new AddOnTarget(addon.getAbsolutePath(), name, vendor,
                         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);
-                
+
+                // get the USB ID (if available)
+                int usbVendorId = convertId(propertyMap.get(ADDON_USB_VENDOR));
+                if (usbVendorId != IAndroidTarget.NO_USB_ID) {
+                    target.setUsbVendorId(usbVendorId);
+                }
+
                 if (defaultSkin == null) {
                     if (skins.length == 1) {
                         defaultSkin = skins[1];
@@ -378,7 +434,7 @@
                         defaultSkin = baseTarget.getDefaultSkin();
                     }
                 }
-                
+
                 target.setSkins(skins, defaultSkin);
 
                 return target;
@@ -387,17 +443,38 @@
             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 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 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.
@@ -413,12 +490,11 @@
                         platform.getName(), relativePath);
                 return false;
             }
-            
         }
         return true;
     }
 
-    
+
     /**
      * Parses a property file and returns
      * @param buildProp the property file to parse
@@ -436,7 +512,7 @@
             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));
@@ -447,7 +523,7 @@
                     }
                 }
             }
-            
+
             return map;
         } catch (FileNotFoundException e) {
             // this should not happen since we usually test the file existence before
@@ -477,7 +553,7 @@
 
         return null;
     }
-    
+
     /**
      * Parses the skin folder and builds the skin list.
      * @param osPath The path of the skin root folder.
@@ -505,7 +581,7 @@
 
             return skinList.toArray(new String[skinList.size()]);
         }
-        
+
         return new String[0];
     }
 }
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java
deleted file mode 100644
index cc12b82..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java
+++ /dev/null
@@ -1,1272 +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.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.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.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";
-
-    public final static String AVD_INFO_PATH = "path";
-    public final static String AVD_INFO_TARGET = "target";
-
-    /**
-     * 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";
-    /**
-     * 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";
-    /**
-     * 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";
-    /**
-     * 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";
-    /**
-     * 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";
-    /**
-     * 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";
-
-    /**
-     * 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,}");
-
-    private final static String USERDATA_IMG = "userdata.img";
-    private final static String CONFIG_INI = "config.ini";
-    private final static String SDCARD_IMG = "sdcard.img";
-
-    private final static String INI_EXTENSION = ".ini";
-    private final static Pattern INI_NAME_PATTERN = Pattern.compile("(.+)\\" + INI_EXTENSION + "$",
-            Pattern.CASE_INSENSITIVE);
-
-    private final static Pattern IMAGE_NAME_PATTERN = Pattern.compile("(.+)\\.img$",
-            Pattern.CASE_INSENSITIVE);
-
-    /**
-     * Pattern for matching SD Card sizes, e.g. "4K" or "16M".
-     */
-    private final static Pattern SDCARD_SIZE_PATTERN = Pattern.compile("\\d+[MK]?");
-
-    /** 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 ISdkLog mSdkLog;
-    private final SdkManager mSdk;
-
-    public AvdManager(SdkManager sdk, ISdkLog sdkLog) throws AndroidLocationException {
-        mSdk = sdk;
-        mSdkLog = sdkLog;
-        buildAvdList(mAllAvdList);
-    }
-
-    /**
-     * 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 : getValidAvds()) {
-                    if (info.getName().equals(name)) {
-                        return info;
-                    }
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Reloads the AVD list.
-     * @throws AndroidLocationException if there was an error finding the location of the
-     * AVD folder.
-     */
-    public void reloadAvds() 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);
-
-        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.
-     */
-    public AvdInfo createAvd(File avdFolder, String name, IAndroidTarget target,
-            String skinName, String sdcard, Map<String,String> hardwareConfig,
-            boolean removePrevious) {
-
-        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.
-                    if (mSdkLog != null) {
-                        mSdkLog.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) {
-                mSdkLog.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) == 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);
-                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(mSdk.getLocation(), SdkConstants.FD_TOOLS);
-                        File mkSdCard = new File(toolsFolder, SdkConstants.mkSdCardCmdName());
-
-                        if (mkSdCard.isFile() == false) {
-                            mSdkLog.error(null, "'%1$s' is missing from the SDK tools folder.",
-                                    mkSdCard.getName());
-                            needCleanup = true;
-                            return null;
-                        }
-
-                        if (createSdCard(mkSdCard.getAbsolutePath(), sdcard, path) == 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 {
-                        mSdkLog.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;
-                    }
-                }
-            }
-
-            if (hardwareConfig != null) {
-                values.putAll(hardwareConfig);
-            }
-
-            File configIniFile = new File(avdFolder, CONFIG_INI);
-            writeIniFile(configIniFile, values);
-
-            if (mSdkLog != null) {
-                if (target.isPlatform()) {
-                    mSdkLog.printf("Created AVD '%1$s' based on %2$s\n", name, target.getName());
-                } else {
-                    mSdkLog.printf("Created AVD '%1$s' based on %2$s (%3$s)\n", name, target.getName(),
-                               target.getVendor());
-                }
-            }
-
-            // create the AvdInfo object, and add it to the list
-            AvdInfo newAvdInfo = new AvdInfo(name,
-                    avdFolder.getAbsolutePath(),
-                    target.hashString(),
-                    target, values);
-
-            synchronized (mAllAvdList) {
-                mAllAvdList.add(newAvdInfo);
-                mValidAvdList = mBrokenAvdList = null;
-            }
-
-            return newAvdInfo;
-        } catch (AndroidLocationException e) {
-            if (mSdkLog != null) {
-                mSdkLog.error(e, null);
-            }
-        } catch (IOException e) {
-            if (mSdkLog != null) {
-                mSdkLog.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 = mSdk.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.
-     */
-    private String getSkinRelativePath(String skinName, IAndroidTarget target) {
-        // first look to see if the skin is in the 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);
-        }
-
-        // skin really does not exist!
-        if (skin.exists() == false) {
-            mSdkLog.error(null, "Skin '%1$s' does not exist.", skinName);
-            return null;
-        }
-
-        // get the skin path
-        path = skin.getAbsolutePath();
-
-        // make this path relative to the SDK location
-        String sdkLocation = mSdk.getLocation();
-        if (path.startsWith(sdkLocation) == false) {
-            // this really really should not happen.
-            mSdkLog.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;
-    }
-
-    /**
-     * 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
-     * @return True if the AVD was deleted with no error.
-     */
-    public void deleteAvd(AvdInfo avdInfo, ISdkLog log) {
-        try {
-            boolean error = false;
-
-            File f = avdInfo.getIniFile();
-            if (f != null && f.exists()) {
-                log.warning("Deleting file %1$s", f.getCanonicalPath());
-                if (!f.delete()) {
-                    log.error(null, "Failed to delete %1$s", f.getCanonicalPath());
-                    error = true;
-                }
-            }
-
-            String path = avdInfo.getPath();
-            if (path != null) {
-                f = new File(path);
-                if (f.exists()) {
-                    log.warning("Deleting folder %1$s", f.getCanonicalPath());
-                    recursiveDelete(f);
-                    if (!f.delete()) {
-                        log.error(null, "Failed to delete %1$s", f.getCanonicalPath());
-                        error = true;
-                    }
-                }
-            }
-
-            removeAvd(avdInfo);
-
-            if (error) {
-                log.printf("AVD '%1$s' deleted with errors. See warnings above.\n",
-                        avdInfo.getName());
-            } else {
-                log.printf("AVD '%1$s' deleted.\n", avdInfo.getName());
-            }
-
-        } catch (AndroidLocationException e) {
-            log.error(e, null);
-        } catch (IOException e) {
-            log.error(e, null);
-        }
-    }
-
-    /**
-     * 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.
-     * @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(avdInfo);
-            }
-
-            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
-     *
-     * @throws AndroidLocationException if there's a problem getting android root directory.
-     */
-    private void buildAvdList(ArrayList<AvdInfo> allList) throws AndroidLocationException {
-        File[] avds = buildAvdFilesList();
-        if (avds != null) {
-            for (File avd : avds) {
-                AvdInfo info = parseAvdInfo(avd);
-                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
-     * @return A new {@link AvdInfo} with an {@link AvdStatus} indicating whether this AVD is
-     *         valid or not.
-     */
-    private AvdInfo parseAvdInfo(File path) {
-        Map<String, String> map = SdkManager.parsePropertyFile(path, mSdkLog);
-
-        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 = mSdk.getTargetFromHashString(targetHash);
-        }
-
-        // load the AVD properties.
-        if (avdPath != null) {
-            configIniFile = new File(avdPath, CONFIG_INI);
-        }
-
-        if (configIniFile != null) {
-            properties = SdkManager.parsePropertyFile(configIniFile, mSdkLog);
-        }
-
-        // 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(mSdk.getLocation() + File.separator + imageSysDir);
-                if (f.isDirectory() == false) {
-                    validImageSysdir = false;
-                } else {
-                    imageSysDir = properties.get(AVD_INI_IMAGES_2);
-                    if (imageSysDir != null) {
-                        f = new File(mSdk.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.
-     *
-     * @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 {
-        FileWriter writer = new FileWriter(iniFile);
-
-        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.
-     * @return True if the sdcard could be created.
-     */
-    private boolean createSdCard(String toolLocation, String size, String location) {
-        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) {
-                    mSdkLog.error(null, error);
-                }
-            }
-
-        } catch (InterruptedException e) {
-            // pass, print error below
-        } catch (IOException e) {
-            // pass, print error below
-        }
-
-        mSdkLog.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) {
-            }
-            try {
-                t2.join();
-            } catch (InterruptedException e) {
-            }
-        }
-
-        // 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.
-     * @throws IOException
-     * @throws AndroidLocationException
-     */
-    public void updateAvd(String name) throws IOException, AndroidLocationException {
-        // 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.
-            mSdkLog.error(null, "There is no Android Virtual Device named '%s'.", name);
-            return;
-        }
-
-        // 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)) {
-            if (properties.containsKey(AVD_INI_IMAGES_1)) {
-                mSdkLog.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)) {
-                mSdkLog.printf("Updated '%1$s' with value '%2$s'\n", AVD_INI_IMAGES_2,
-                        properties.get(AVD_INI_IMAGES_2));
-            }
-
-            status = AvdStatus.OK;
-        } else {
-            mSdkLog.error(null, "Unable to find non empty system images folders for %1$s", name);
-            //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(
-                name,
-                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.
-     * @return true if success, false if some path are missing.
-     */
-    private boolean setImagePathProperties(IAndroidTarget target, Map<String, String> properties) {
-        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) {
-            mSdkLog.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/avd/HardwareProperties.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/HardwareProperties.java
deleted file mode 100644
index ed5b949..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/HardwareProperties.java
+++ /dev/null
@@ -1,159 +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.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.ArrayList;
-import java.util.List;
-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";
-    
-    public enum ValueType {
-        INTEGER("integer"),
-        BOOLEAN("boolean"),
-        DISKSIZE("diskSize");
-        
-        private String mValue;
-
-        ValueType(String value) {
-            mValue = value;
-        }
-        
-        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 List<HardwareProperty> parseHardwareDefinitions(File file, ISdkLog log) {
-        try {
-            FileInputStream fis = new FileInputStream(file);
-            BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
-
-            List<HardwareProperty> map = new ArrayList<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.add(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;
-    }
-
-}
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
new file mode 100644
index 0000000..3225236
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java
@@ -0,0 +1,1321 @@
+/*
+ * 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.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";
+
+    public final static String AVD_INFO_PATH = "path";
+    public final static String AVD_INFO_TARGET = "target";
+    
+    /**
+     * 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";
+    /**
+     * 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";
+    /**
+     * 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";
+    /**
+     * 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";
+    /**
+     * 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";
+    /**
+     * 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";
+
+    /**
+     * 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,}");
+
+    private final static String USERDATA_IMG = "userdata.img";
+    private final static String CONFIG_INI = "config.ini";
+    private final static String SDCARD_IMG = "sdcard.img";
+
+    private final static String INI_EXTENSION = ".ini";
+    private final static Pattern INI_NAME_PATTERN = Pattern.compile("(.+)\\" + INI_EXTENSION + "$",
+            Pattern.CASE_INSENSITIVE);
+
+    private final static Pattern IMAGE_NAME_PATTERN = Pattern.compile("(.+)\\.img$",
+            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]");
+
+    /** Regex used to validate characters that compose an AVD name. */
+    public final static Pattern RE_AVD_NAME = Pattern.compile("[a-zA-Z0-9._-]+");
+
+    /** 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 . _ -";
+
+    /** 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 mSdk;
+
+    /** 
+     * TODO remove this field. Each caller should give its own logger to the methods
+     * here instead of relying on a global logger. Otherwise that means that each
+     * caller needs to re-instantiate this just to change the logger, which is plain
+     * ugly.
+     * 
+     * We'll revisit this in the final AVD Manager UI for donut.
+     */ 
+    private ISdkLog mSdkLog;
+
+    public AvdManager(SdkManager sdk, ISdkLog sdkLog) throws AndroidLocationException {
+        mSdk = sdk;
+        mSdkLog = sdkLog;
+        buildAvdList(mAllAvdList);
+    }
+
+    /**
+     * Changes the current {@link ISdkLog}.
+     * 
+     * This method should not exist. See comments for {@link #mSdkLog}.
+     * 
+     * @return The {@link ISdkLog} that was currently being used.
+     * @see #mSdkLog
+     */
+    public ISdkLog setSdkLog(ISdkLog sdkLog) {
+        ISdkLog oldLogger = mSdkLog;
+        mSdkLog = sdkLog;
+        return oldLogger;
+    }
+
+    /**
+     * 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 : getValidAvds()) {
+                    if (info.getName().equals(name)) {
+                        return info;
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+    
+    /**
+     * Reloads the AVD list.
+     * @throws AndroidLocationException if there was an error finding the location of the
+     * AVD folder.
+     */
+    public void reloadAvds() 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);
+
+        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.
+     * @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) {
+        
+        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.
+                    if (mSdkLog != null) {
+                        mSdkLog.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) {
+                mSdkLog.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) == 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);
+                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(mSdk.getLocation(), SdkConstants.FD_TOOLS);
+                        File mkSdCard = new File(toolsFolder, SdkConstants.mkSdCardCmdName());
+                        
+                        if (mkSdCard.isFile() == false) {
+                            mSdkLog.error(null, "'%1$s' is missing from the SDK tools folder.",
+                                    mkSdCard.getName());
+                            needCleanup = true;
+                            return null;
+                        }
+                        
+                        if (createSdCard(mkSdCard.getAbsolutePath(), sdcard, path) == 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 {
+                        mSdkLog.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;
+                    }
+                }
+            }
+
+            if (hardwareConfig != null) {
+                values.putAll(hardwareConfig);
+            }
+
+            File configIniFile = new File(avdFolder, CONFIG_INI);
+            writeIniFile(configIniFile, values);
+            
+            if (mSdkLog != null) {
+                if (target.isPlatform()) {
+                    mSdkLog.printf("Created AVD '%1$s' based on %2$s\n", name, target.getName());
+                } else {
+                    mSdkLog.printf("Created AVD '%1$s' based on %2$s (%3$s)\n", name, target.getName(),
+                               target.getVendor());
+                }
+            }
+            
+            // 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())) {
+                mSdkLog.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) {
+            if (mSdkLog != null) {
+                mSdkLog.error(e, null);
+            }
+        } catch (IOException e) {
+            if (mSdkLog != null) {
+                mSdkLog.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 = mSdk.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.
+     */
+    private String getSkinRelativePath(String skinName, IAndroidTarget target) {
+        // first look to see if the skin is in the 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);
+        }
+        
+        // skin really does not exist!
+        if (skin.exists() == false) {
+            mSdkLog.error(null, "Skin '%1$s' does not exist.", skinName);
+            return null;
+        }
+        
+        // get the skin path
+        path = skin.getAbsolutePath();
+
+        // make this path relative to the SDK location
+        String sdkLocation = mSdk.getLocation();
+        if (path.startsWith(sdkLocation) == false) {
+            // this really really should not happen.
+            mSdkLog.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;
+    }
+
+    /**
+     * 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
+     * @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.warning("Deleting file %1$s", f.getCanonicalPath());
+                if (!f.delete()) {
+                    log.error(null, "Failed to delete %1$s", f.getCanonicalPath());
+                    error = true;
+                }
+            }
+
+            String path = avdInfo.getPath();
+            if (path != null) {
+                f = new File(path);
+                if (f.exists()) {
+                    log.warning("Deleting folder %1$s", f.getCanonicalPath());
+                    recursiveDelete(f);
+                    if (!f.delete()) {
+                        log.error(null, "Failed to delete %1$s", f.getCanonicalPath());
+                        error = true;
+                    }
+                }
+            }
+
+            removeAvd(avdInfo);
+
+            if (error) {
+                log.printf("AVD '%1$s' deleted with errors. See warnings above.\n",
+                        avdInfo.getName());
+            } else {
+                log.printf("AVD '%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.
+     * @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(avdInfo);
+            }
+
+            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
+     * 
+     * @throws AndroidLocationException if there's a problem getting android root directory.
+     */
+    private void buildAvdList(ArrayList<AvdInfo> allList) throws AndroidLocationException {
+        File[] avds = buildAvdFilesList();
+        if (avds != null) {
+            for (File avd : avds) {
+                AvdInfo info = parseAvdInfo(avd);
+                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
+     * @return A new {@link AvdInfo} with an {@link AvdStatus} indicating whether this AVD is
+     *         valid or not.
+     */
+    private AvdInfo parseAvdInfo(File path) {
+        Map<String, String> map = SdkManager.parsePropertyFile(path, mSdkLog);
+
+        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 = mSdk.getTargetFromHashString(targetHash);
+        }
+
+        // load the AVD properties.
+        if (avdPath != null) {
+            configIniFile = new File(avdPath, CONFIG_INI);
+        }
+        
+        if (configIniFile != null) {
+            properties = SdkManager.parsePropertyFile(configIniFile, mSdkLog);
+        }
+
+        // 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(mSdk.getLocation() + File.separator + imageSysDir);
+                if (f.isDirectory() == false) {
+                    validImageSysdir = false;
+                } else {
+                    imageSysDir = properties.get(AVD_INI_IMAGES_2);
+                    if (imageSysDir != null) {
+                        f = new File(mSdk.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.
+     * 
+     * @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 {
+        FileWriter writer = new FileWriter(iniFile);
+        
+        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.
+     * @return True if the sdcard could be created.
+     */
+    private boolean createSdCard(String toolLocation, String size, String location) {
+        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) {
+                    mSdkLog.error(null, error);
+                }
+            }
+
+        } catch (InterruptedException e) {
+            // pass, print error below
+        } catch (IOException e) {
+            // pass, print error below
+        }
+        
+        mSdkLog.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) {
+            }
+            try {
+                t2.join();
+            } catch (InterruptedException e) {
+            }
+        }
+
+        // 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.
+     * @throws IOException 
+     * @throws AndroidLocationException 
+     */
+    public void updateAvd(String name) throws IOException, AndroidLocationException {
+        // 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.
+            mSdkLog.error(null, "There is no Android Virtual Device named '%s'.", name);
+            return;
+        }
+
+        // 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)) {
+            if (properties.containsKey(AVD_INI_IMAGES_1)) {
+                mSdkLog.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)) {
+                mSdkLog.printf("Updated '%1$s' with value '%2$s'\n", AVD_INI_IMAGES_2,
+                        properties.get(AVD_INI_IMAGES_2));
+            }
+            
+            status = AvdStatus.OK;
+        } else {
+            mSdkLog.error(null, "Unable to find non empty system images folders for %1$s", name);
+            //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(
+                name,
+                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.
+     * @return true if success, false if some path are missing.
+     */
+    private boolean setImagePathProperties(IAndroidTarget target, Map<String, String> properties) {
+        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) {
+            mSdkLog.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
new file mode 100644
index 0000000..81acfef
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/HardwareProperties.java
@@ -0,0 +1,159 @@
+/*
+ * 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.ArrayList;
+import java.util.List;
+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";
+    
+    public enum ValueType {
+        INTEGER("integer"),
+        BOOLEAN("boolean"),
+        DISKSIZE("diskSize");
+        
+        private String mValue;
+
+        ValueType(String value) {
+            mValue = value;
+        }
+        
+        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 List<HardwareProperty> parseHardwareDefinitions(File file, ISdkLog log) {
+        try {
+            FileInputStream fis = new FileInputStream(file);
+            BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
+
+            List<HardwareProperty> map = new ArrayList<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.add(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;
+    }
+
+}
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
new file mode 100644
index 0000000..eeab46a
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ApkConfigurationHelper.java
@@ -0,0 +1,106 @@
+/*
+ * 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;
+import java.util.Set;
+import java.util.Map.Entry;
+
+/**
+ * Helper class to read and write Apk Configuration into a {@link ProjectProperties} file.
+ */
+public class ApkConfigurationHelper {
+    /** Prefix for property names for config definition. This prevents having config named
+     * after other valid properties such as "target". */
+    final static String CONFIG_PREFIX = "apk-config-";
+
+    /**
+     * Reads the Apk Configurations from a {@link ProjectProperties} file and returns them as a map.
+     * <p/>If there are no defined configurations, the returned map will be empty.
+     * @return 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) 
+     */
+    public static Map<String, String> getConfigs(ProjectProperties properties) {
+        HashMap<String, String> configMap = new HashMap<String, String>();
+
+        // get the list of configs.
+        String configList = properties.getProperty(ProjectProperties.PROPERTY_APK_CONFIGS);
+        if (configList != null) {
+            // this is a comma separated list
+            String[] configs = configList.split(","); //$NON-NLS-1$
+            
+            // read the value of each config and store it in a map
+            for (String config : configs) {
+                config = config.trim();
+                String configValue = properties.getProperty(CONFIG_PREFIX + config);
+                if (configValue != null) {
+                    configMap.put(config, configValue);
+                }
+            }
+        }
+        
+        return configMap;
+    }
+    
+    /**
+     * Writes the Apk Configurations from a given map into a {@link ProjectProperties}.
+     * @param properties the {@link ProjectProperties} in which to store the apk configurations. 
+     * @param configMap 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) 
+     * @return true if the {@link ProjectProperties} contained Apk Configuration that were not
+     * present in the map. 
+     */
+    public static boolean setConfigs(ProjectProperties properties, Map<String, String> configMap) {
+        // load the current configs, in order to remove the value properties for each of them
+        // in case a config was removed.
+        
+        // get the list of configs.
+        String configList = properties.getProperty(ProjectProperties.PROPERTY_APK_CONFIGS);
+
+        boolean hasRemovedConfig = false;
+
+        if (configList != null) {
+            // this is a comma separated list
+            String[] configs = configList.split(","); //$NON-NLS-1$
+            
+            for (String config : configs) {
+                config = config.trim();
+                if (configMap.containsKey(config) == false) {
+                    hasRemovedConfig = true;
+                    properties.removeProperty(CONFIG_PREFIX + config);
+                }
+            }
+        }
+        
+        // now add the properties.
+        Set<Entry<String, String>> entrySet = configMap.entrySet();
+        StringBuilder sb = new StringBuilder();
+        for (Entry<String, String> entry : entrySet) {
+            if (sb.length() > 0) {
+                sb.append(",");
+            }
+            sb.append(entry.getKey());
+            properties.setProperty(CONFIG_PREFIX + entry.getKey(), entry.getValue());
+        }
+        properties.setProperty(ProjectProperties.PROPERTY_APK_CONFIGS, sb.toString());
+        
+        return hasRemovedConfig;
+    }
+}
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
new file mode 100644
index 0000000..a33eaaa
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java
@@ -0,0 +1,769 @@
+/*
+ * 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 org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+/**
+ * Creates the basic files needed to get an Android project up and running. Also
+ * allows creation of IntelliJ project files.
+ *
+ * @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". */
+    private final static String PH_ACTIVITY_NAME = "ACTIVITY_NAME";
+    /** Project name substitution string used in template files, i.e. "PROJECT_NAME". */
+    private final static String PH_PROJECT_NAME = "PROJECT_NAME";
+    
+    private final static String FOLDER_TESTS = "tests";
+    
+    /** 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;
+        
+        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 activityName 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 isTestProject whether the project to create is a test project.
+     */
+    public void createProject(String folderPath, String projectName,
+            String packageName, String activityName, IAndroidTarget target,
+            boolean isTestProject) {
+        
+        // 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 {
+            // 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 an empty build.properties
+            ProjectProperties buildProperties = ProjectProperties.create(folderPath,
+                    PropertyType.BUILD);
+            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);
+            if (activityName != null) {
+                keywords.put(PH_ACTIVITY_NAME, activityName);
+            }
+
+            // Take the project name from the command line if there's one
+            if (projectName != null) {
+                keywords.put(PH_PROJECT_NAME, projectName);
+            } else {
+                if (activityName != null) {
+                    // Use the activity as project name 
+                    keywords.put(PH_PROJECT_NAME, activityName);
+                } 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 and the java package folders.
+            String srcFolderPath = SdkConstants.FD_SOURCES + File.separator + packagePath;
+            File sourceFolder = createDirs(projectFolder, srcFolderPath);
+            String javaTemplate = "java_file.template";
+            String activityFileName = activityName + ".java";
+            if (isTestProject) {
+                javaTemplate = "java_tests_file.template";
+                activityFileName = activityName + "Test.java";
+            }
+            installTemplate(javaTemplate, new File(sourceFolder, activityFileName),
+                    keywords, target);
+
+            // create the generate source folder
+            srcFolderPath = SdkConstants.FD_GEN_SOURCES + File.separator + packagePath;
+            sourceFolder = createDirs(projectFolder, srcFolderPath);
+
+            // create other useful folders
+            File resourceFodler = 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(resourceFodler, SdkConstants.FD_VALUES);
+                installTemplate("strings.template", new File(valueFolder, "strings.xml"),
+                        keywords, target);
+
+                File layoutFolder = createDirs(resourceFodler, SdkConstants.FD_LAYOUT);
+                installTemplate("layout.template", new File(layoutFolder, "main.xml"),
+                        keywords, target);
+            }
+
+            /* 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);
+
+            // if this is not a test project, then we create one.
+            if (isTestProject == false) {
+                // create the test project folder.
+                createDirs(projectFolder, FOLDER_TESTS);
+                File testProjectFolder = new File(folderPath, FOLDER_TESTS);
+                
+                createProject(testProjectFolder.getAbsolutePath(), projectName, packageName,
+                        activityName, target, true /*isTestProject*/);
+            }
+        } 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 ) {
+        // 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;
+        }
+
+        // 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;
+        }
+        
+        // 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) {
+            // Note that "<androidinit" 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, "<androidinit(?:\\s|/|$)");
+            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_NAME)) {
+                    // Use the activity as project name 
+                    keywords.put(PH_PROJECT_NAME, keywords.get(PH_ACTIVITY_NAME));
+                } 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);
+            }
+        }
+    }
+
+    /**
+     * 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_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 {
+            final String nsPrefix = "android";
+            final String nsURI = SdkConstants.NS_RESOURCES;
+            
+            XPath xpath = XPathFactory.newInstance().newXPath();
+            
+            xpath.setNamespaceContext(new NamespaceContext() {
+                public String getNamespaceURI(String prefix) {
+                    if (nsPrefix.equals(prefix)) {
+                        return nsURI;
+                    }
+                    return XMLConstants.NULL_NS_URI;
+                }
+
+                public String getPrefix(String namespaceURI) {
+                    if (nsURI.equals(namespaceURI)) {
+                        return nsPrefix;
+                    }
+                    return null;
+                }
+
+                @SuppressWarnings("unchecked")
+                public Iterator getPrefixes(String namespaceURI) {
+                    if (nsURI.equals(namespaceURI)) {
+                        ArrayList<String> list = new ArrayList<String>();
+                        list.add(nsPrefix);
+                        return list.iterator();
+                    }
+                    return null;
+                }
+                
+            });
+            
+            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", nsPrefix);
+
+            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.",
+                        nsPrefix, manifestFile.getName());
+            } else {
+                outKeywords.put(PH_ACTIVITY_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) {
+                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);
+    }
+
+    /**
+     * 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
new file mode 100644
index 0000000..c64bf7f
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java
@@ -0,0 +1,265 @@
+/*
+ * 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.SdkManager;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+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_APK_CONFIGS = "apk-configurations";
+    public final static String PROPERTY_SDK = "sdk-location";
+    
+    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" +
+           "# The name of your application package as defined in the manifest.\n" +
+           "# Used by the 'uninstall' rule.\n"+
+           "#application-package=com.example.myproject\n" +
+           "\n" +
+           "# The name of the source folder.\n" +
+           "#source-folder=src\n" +
+           "\n" +
+           "# The name of the output folder.\n" +
+           "#out-folder=bin\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_APK_CONFIGS,
+                "# apk configurations. This property allows creation of APK files with limited\n" +
+                "# resources. For example, if your application contains many locales and\n" +
+                "# you wish to release multiple smaller apks instead of a large one, you can\n" +
+                "# define configuration to create apks with limited language sets.\n" +
+                "# Format is a comma separated list of configuration names. For each\n" +
+                "# configuration, a property will declare the resource configurations to\n" +
+                "# include. Example:\n" +
+                "#     " + PROPERTY_APK_CONFIGS +"=european,northamerica\n" +
+                "#     " + ApkConfigurationHelper.CONFIG_PREFIX + "european=en,fr,it,de,es\n" +
+                "#     " + ApkConfigurationHelper.CONFIG_PREFIX + "northamerica=en,es\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");
+    }
+    
+    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.
+     * @throws IOException
+     */
+    public void save() throws IOException {
+        File toSave = new File(mProjectFolderOsPath, mType.mFilename);
+        
+        FileWriter writer = new FileWriter(toSave);
+        
+        // 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();
+            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
new file mode 100755
index 0000000..bd76a4c
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonPackage.java
@@ -0,0 +1,201 @@
+/*

+ * 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.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;

+

+/**

+ * Represents an add-on XML node in an SDK repository.

+ */

+public class AddonPackage extends Package {

+

+    private final String mVendor;

+    private final String mName;

+    private final int    mApiLevel;

+

+    /** 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) {

+        super(source, packageNode);

+        mVendor   = getXmlString(packageNode, SdkRepository.NODE_VENDOR);

+        mName     = getXmlString(packageNode, SdkRepository.NODE_NAME);

+        mApiLevel = getXmlInt   (packageNode, SdkRepository.NODE_API_LEVEL, 0);

+

+        mLibs = parseLibs(getFirstChild(packageNode, SdkRepository.NODE_LIBS));

+    }

+

+    /**

+     * Creates a new platform package based on an actual {@link IAndroidTarget} (with

+     * {@link IAndroidTarget#isPlatform()} false) from the {@link SdkManager}.

+     * This is used to list local SDK folders.

+     */

+    AddonPackage(IAndroidTarget target) {

+        super(  null,                       //source

+                0,                          //revision

+                target.getDescription(),  //description

+                null,                       //descUrl

+                Os.getCurrentOs(),          //archiveOs

+                Arch.getCurrentArch(),      //archiveArch

+                "",                         //archiveUrl   //$NON-NLS-1$

+                0,                          //archiveSize

+                null                        //archiveChecksum

+                );

+

+        mApiLevel = target.getApiVersionNumber();

+        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());

+            }

+        }

+    }

+

+    /**

+     * Parses a <libs> element.

+     */

+    private Lib[] parseLibs(Node libsNode) {

+        ArrayList<Lib> libs = new ArrayList<Lib>();

+

+        if (libsNode != null) {

+            for(Node child = libsNode.getFirstChild();

+                child != null;

+                child = child.getNextSibling()) {

+

+                if (child.getNodeType() == Node.ELEMENT_NODE &&

+                        SdkRepository.NS_SDK_REPOSITORY.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(getXmlString(libNode, SdkRepository.NODE_NAME),

+                       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 api-level, an int > 0, for platform, add-on and doc packages. */

+    public int getApiLevel() {

+        return mApiLevel;

+    }

+

+    /** 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 for Android API %3$d",

+                getName(),

+                getVendor(),

+                getApiLevel());

+    }

+

+    /** Returns a long description for an {@link IDescription}. */

+    @Override

+    public String getLongDescription() {

+        return String.format("%1$s.\n%2$s",

+                getShortDescription(),

+                super.getLongDescription());

+    }

+

+    /**

+     * 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.

+     * @return A new {@link File} corresponding to the directory to use to install this package.

+     */

+    @Override

+    public File getInstallFolder(String osSdkRoot) {

+        File addons = new File(osSdkRoot, SdkConstants.FD_ADDONS);

+

+        String name = String.format("%s-%d", getName(), getApiLevel()); // $NON-NLS-1$

+

+        name = name.replaceAll("[^a-zA-Z0-9_-]+", "_");                 // $NON-NLS-1$

+        name = name.replaceAll("_+", "_");                              // $NON-NLS-1$

+

+        File folder = new File(addons, name);

+

+        // TODO find similar existing addon in addons folder

+        return folder;

+    }

+}

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
new file mode 100755
index 0000000..9686cbd
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Archive.java
@@ -0,0 +1,273 @@
+/*

+ * 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 java.security.MessageDigest;

+import java.security.NoSuchAlgorithmException;

+

+

+/**

+ * 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 {

+

+    /** 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;

+        }

+

+        @Override

+        public String toString() {

+            return mUiName;

+        }

+

+        /**

+         * 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 OS")) {                      //$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;

+        }

+    }

+

+    /** 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;

+        }

+

+        @Override

+        public String toString() {

+            return mUiName;

+        }

+

+        /**

+         * 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;

+        }

+    }

+

+    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;

+

+    /**

+     * Creates a new archive.

+     */

+    Archive(Package pkg, Os os, Arch arch, String url, long size, String checksum) {

+        mPackage = pkg;

+        mOs = os;

+        mArch = arch;

+        mUrl = url;

+        mSize = size;

+        mChecksum = checksum;

+    }

+

+    /**

+     * 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.

+     * For a local installed folder, an URL is frabricated from the folder path.

+     */

+    public String getUrl() {

+        return mUrl;

+    }

+

+    /**

+     * 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 short description for this archive.

+     */

+    public String getShortDescription() {

+        String os;

+        if (mOs == null) {

+            os = "unknown OS";

+        } else if (mOs == Os.ANY) {

+            os = "any OS";

+        } else {

+            os = mOs.toString();

+        }

+

+        String arch = "";

+        if (mArch != null && mArch != Arch.ANY) {

+            arch = mArch.toString();

+        }

+

+        return String.format("Archive for %1$s %2$s", os, arch);

+    }

+

+    /**

+     * 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() {

+        // Check OS

+        Os os = getOs();

+

+        if (os != Os.ANY) {

+            Os os2 = Os.getCurrentOs();

+            if (os2 != os) {

+                return false;

+            }

+        }

+

+        // Check Arch

+        Arch arch = getArch();

+

+        if (arch != Arch.ANY) {

+            Arch arch2 = Arch.getCurrentArch();

+            if (arch2 != arch) {

+                return false;

+            }

+        }

+

+        return true;

+    }

+}

+

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
new file mode 100755
index 0000000..8f07255
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DocPackage.java
@@ -0,0 +1,108 @@
+/*

+ * 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.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;

+

+/**

+ * Represents a doc XML node in an SDK repository.

+ */

+public class DocPackage extends Package {

+

+    private final int mApiLevel;

+

+    /**

+     * 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) {

+        super(source, packageNode);

+        mApiLevel = getXmlInt(packageNode, SdkRepository.NODE_API_LEVEL, 0);

+    }

+

+    /**

+     * Manually create a new package with one archive and the given attributes.

+     * This is used to create packages from local directories.

+     */

+    DocPackage(RepoSource source,

+            int apiLevel,

+            int revision,

+            String description,

+            String descUrl,

+            Os archiveOs,

+            Arch archiveArch,

+            String archiveUrl,

+            long archiveSize,

+            String archiveChecksum) {

+        super(source,

+                revision,

+                description,

+                descUrl,

+                archiveOs,

+                archiveArch,

+                archiveUrl,

+                archiveSize,

+                archiveChecksum);

+        mApiLevel = apiLevel;

+    }

+

+    /** Returns the api-level, an int > 0, for platform, add-on and doc packages.

+     *  Can be 0 if this is a local package of unknown api-level. */

+    public int getApiLevel() {

+        return mApiLevel;

+    }

+

+    /** Returns a short description for an {@link IDescription}. */

+    @Override

+    public String getShortDescription() {

+        if (mApiLevel != 0) {

+            return String.format("Documentation for Android SDK, API %1$d", mApiLevel);

+        } else {

+            return String.format("Documentation for Android SDK");

+        }

+    }

+

+    /** Returns a long description for an {@link IDescription}. */

+    @Override

+    public String getLongDescription() {

+        return String.format("%1$s.\n%2$s",

+                getShortDescription(),

+                super.getLongDescription());

+    }

+

+    /**

+     * 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.

+     * @return A new {@link File} corresponding to the directory to use to install this package.

+     */

+    @Override

+    public File getInstallFolder(String osSdkRoot) {

+        return new File(osSdkRoot, SdkConstants.FD_DOCS);

+    }

+}

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
new file mode 100755
index 0000000..7af92e2
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IDescription.java
@@ -0,0 +1,40 @@
+/*

+ * 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/ITask.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITask.java
new file mode 100755
index 0000000..9178460
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITask.java
@@ -0,0 +1,26 @@
+/*

+ * 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
new file mode 100755
index 0000000..540825c
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskFactory.java
@@ -0,0 +1,25 @@
+/*

+ * 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
new file mode 100755
index 0000000..05c982d
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskMonitor.java
@@ -0,0 +1,63 @@
+/*

+ * 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.

+     */

+    public void setProgressMax(int max);

+

+    /**

+     * Increments the current value of the progress bar.

+     * This method can be invoked from a non-UI thread.

+     */

+    public void incProgress(int delta);

+

+    /**

+     * 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 cancelRequested();

+}

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
new file mode 100755
index 0000000..f150510
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java
@@ -0,0 +1,415 @@
+/*

+ * 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 com.android.sdklib.repository.SdkRepository;

+

+import org.w3c.dom.Document;

+import org.w3c.dom.Node;

+import org.xml.sax.InputSource;

+import org.xml.sax.SAXException;

+

+import java.io.BufferedReader;

+import java.io.File;

+import java.io.FileReader;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.StringReader;

+import java.net.MalformedURLException;

+import java.util.ArrayList;

+import java.util.HashSet;

+import java.util.Set;

+import java.util.regex.Matcher;

+import java.util.regex.Pattern;

+

+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;

+

+/**

+ * Scans a local SDK to find which packages are currently installed.

+ */

+public class LocalSdkParser {

+

+    private static final String SOURCE_XML = "source.xml";  //$NON-NLS-1$ // TODO move to global constants

+    private Package[] mPackages;

+

+    public LocalSdkParser() {

+        // TODO Auto-generated constructor stub

+    }

+

+    /**

+     * Returns the packages found by the last call to {@link #parseSdk(String)}.

+     */

+    public Package[] getPackages() {

+        return mPackages;

+    }

+

+    /**

+     * Clear the internal packages list. After this call, {@link #getPackages()} will return

+     * null till {@link #parseSdk(String)} 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.

+     * @return The packages found. Can be retrieved later using {@link #getPackages()}.

+     */

+    public Package[] parseSdk(String osSdkRoot) {

+        ArrayList<Package> packages = new ArrayList<Package>();

+

+        Package pkg = scanDoc(new File(osSdkRoot, SdkConstants.FD_DOCS));

+        if (pkg != null) {

+            packages.add(pkg);

+        }

+

+        pkg = scanTools(new File(osSdkRoot, SdkConstants.FD_TOOLS));

+        if (pkg != null) {

+            packages.add(pkg);

+        }

+

+        // for platforms and add-ons, rely on the SdkManager parser

+        SdkManager sdkman = SdkManager.createManager(osSdkRoot, new ISdkLog() {

+            // A dummy sdk logger that doesn't log anything.

+            public void error(Throwable t, String errorFormat, Object... args) {

+                // pass

+            }

+            public void printf(String msgFormat, Object... args) {

+                // pass

+            }

+            public void warning(String warningFormat, Object... args) {

+                // pass

+            }

+        });

+

+        for(IAndroidTarget target : sdkman.getTargets()) {

+            pkg = null;

+

+            if (target.isPlatform()) {

+                pkg = parseXml(new File(target.getLocation(), SOURCE_XML),

+                               SdkRepository.NODE_PLATFORM);

+                if (pkg == null) {

+                    pkg = new PlatformPackage(target);

+                }

+

+            } else {

+                pkg = parseXml(new File(target.getLocation(), SOURCE_XML),

+                                        SdkRepository.NODE_ADD_ON);

+

+                if (pkg == null) {

+                    pkg = new AddonPackage(target);

+                }

+            }

+

+            if (pkg != null) {

+                packages.add(pkg);

+            }

+        }

+

+        mPackages = packages.toArray(new Package[packages.size()]);

+        return mPackages;

+    }

+

+    /**

+     * Try to find a tools package at the given location.

+     * Returns null if not found.

+     */

+    private Package scanTools(File toolFolder) {

+        // Can we find a source.xml?

+        Package pkg = parseXml(new File(toolFolder, SOURCE_XML), SdkRepository.NODE_TOOL);

+

+        // 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;

+        }

+

+        // if we don't have the package info, make one up

+        if (pkg == null) {

+            pkg = new ToolPackage(

+                    null,                       //source

+                    0,                          //revision

+                    "Tools",                    //description

+                    null,                       //descUrl

+                    Os.getCurrentOs(),          //archiveOs

+                    Arch.getCurrentArch(),      //archiveArch

+                    "",                         //archiveUrl   //$NON-NLS-1$

+                    0,                          //archiveSize

+                    null                        //archiveChecksum

+                    );

+        }

+

+        return pkg;

+    }

+

+    /**

+     * Try to find a docs package at the given location.

+     * Returns null if not found.

+     */

+    private Package scanDoc(File docFolder) {

+        // Can we find a source.xml?

+        Package pkg = parseXml(new File(docFolder, SOURCE_XML), SdkRepository.NODE_DOC);

+

+        // To start with, a doc folder should have an "index.html" to be acceptable.

+        String html = readFile(new File(docFolder, "index.html"));

+        if (html != null) {

+            // Try to find something that looks like this line:

+            //   <a href="./sdk/1.5_r1/index.html">

+            // We should find one or more of these and we want the highest version

+            // and release numbers. Note that unfortunately that doesn't give us

+            // the api-level we care about for the doc package.

+

+            String found = null;

+            Pattern re = Pattern.compile(

+                    "<a\\s+href=\"./sdk/(\\d\\.\\d_r\\d)/index.html\">",

+                    Pattern.DOTALL);

+            Matcher m = re.matcher(html);

+            while(m.find()) {

+                String v = m.group(1);

+                if (found == null || v.compareTo(found) == 1) {

+                    found = v;

+                }

+            }

+

+            if (found == null) {

+                // That doesn't look like a doc folder.

+                return null;

+            }

+

+            // We found the line, so it seems like an SDK doc.

+            // Create a pkg if we don't have one yet.

+

+            if (pkg == null) {

+                String url = null;

+                try {

+                    url = docFolder.toURI().toURL().toString();

+                } catch (MalformedURLException e) {

+                    // ignore

+                }

+

+                pkg = new DocPackage(

+                        null,                       //source

+                        0,                          //apiLevel

+                        0,                          //revision

+                        String.format("Documentation for %1$s", found),     //description

+                        null,                       //descUrl

+                        Os.getCurrentOs(),          //archiveOs

+                        Arch.getCurrentArch(),      //archiveArch

+                        url,                        //archiveUrl

+                        0,                          //archiveSize

+                        null                        //archiveChecksum

+                        );

+            }

+        }

+

+        return pkg;

+    }

+

+    /**

+     * Parses the given XML file for the specific element filter.

+     * The element must one of the package type local names: doc, tool, platform or addon.

+     * Returns null if no such package was found.

+     */

+    private Package parseXml(File sourceXmlFile, String elementFilter) {

+

+        String xml = readFile(sourceXmlFile);

+        if (xml != null) {

+            if (validateXml(xml)) {

+                return parsePackages(xml, elementFilter);

+            }

+        }

+

+        return null;

+    }

+

+    /**

+     * Parses the given XML to find the specific element filter.

+     * The element must one of the package type local names: doc, tool, platform or addon.

+     * Returns null if no such package was found.

+     */

+    private Package parsePackages(String xml, String elementFilter) {

+

+        try {

+            Document doc = getDocument(xml);

+

+            Node root = getFirstChild(doc, SdkRepository.NODE_SDK_REPOSITORY);

+            if (root != null) {

+

+                for (Node child = root.getFirstChild();

+                     child != null;

+                     child = child.getNextSibling()) {

+                    if (child.getNodeType() == Node.ELEMENT_NODE &&

+                            SdkRepository.NS_SDK_REPOSITORY.equals(child.getNamespaceURI()) &&

+                            elementFilter.equals(child.getLocalName())) {

+                        String name = child.getLocalName();

+                        Package p = null;

+

+                        try {

+                            if (SdkRepository.NODE_ADD_ON.equals(name)) {

+                                return new AddonPackage(null /*source*/, child);

+

+                            } else if (SdkRepository.NODE_PLATFORM.equals(name)) {

+                                return new PlatformPackage(null /*source*/, child);

+

+                            } else if (SdkRepository.NODE_DOC.equals(name)) {

+                                return new DocPackage(null /*source*/, child);

+

+                            } else if (SdkRepository.NODE_TOOL.equals(name)) {

+                                return new ToolPackage(null /*source*/, child);

+                            }

+                        } catch (Exception e) {

+                            // Ignore invalid packages

+                        }

+                    }

+                }

+            }

+

+        } catch (Exception e) {

+            // ignore

+        }

+

+        return null;

+    }

+

+    /**

+     * Reads a file as a string.

+     * Returns null if the file could not be read.

+     */

+    private String readFile(File sourceXmlFile) {

+        FileReader fr = null;

+        try {

+            fr = new FileReader(sourceXmlFile);

+            BufferedReader br = new BufferedReader(fr);

+            StringBuilder dest = new StringBuilder();

+            char[] buf = new char[65536];

+            int n;

+            while ((n = br.read(buf)) > 0) {

+                if (n > 0) {

+                    dest.append(buf, 0, n);

+                }

+            }

+            return dest.toString();

+

+        } catch (IOException e) {

+            // ignore

+

+        } finally {

+            if (fr != null) {

+                try {

+                    fr.close();

+                } catch (IOException e) {

+                    // ignore

+                }

+            }

+        }

+

+        return null;

+    }

+

+    /**

+     * Validates this XML against the SDK Repository schema.

+     * Returns true if the XML was correctly validated.

+     */

+    private boolean validateXml(String xml) {

+

+        try {

+            Validator validator = getValidator();

+            validator.validate(new StreamSource(new StringReader(xml)));

+            return true;

+

+        } catch (SAXException e) {

+            // ignore

+

+        } catch (IOException e) {

+            // ignore

+        }

+

+        return false;

+    }

+

+    /**

+     * Helper method that returns a validator for our XSD

+     */

+    private Validator getValidator() throws SAXException {

+        InputStream xsdStream = SdkRepository.getXsdStream();

+        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

+

+        // 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.newValidator();

+

+        return validator;

+    }

+

+    /**

+     * 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 xmlLocalName) {

+

+        for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {

+            if (child.getNodeType() == Node.ELEMENT_NODE &&

+                    SdkRepository.NS_SDK_REPOSITORY.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.

+     */

+    private Document getDocument(String xml)

+            throws ParserConfigurationException, SAXException, IOException {

+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

+        factory.setIgnoringComments(true);

+        factory.setNamespaceAware(true);

+

+        DocumentBuilder builder = factory.newDocumentBuilder();

+        Document doc = builder.parse(new InputSource(new StringReader(xml)));

+

+        return doc;

+    }

+}

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
new file mode 100755
index 0000000..55ecaef
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/Package.java
@@ -0,0 +1,278 @@
+/*

+ * 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.io.File;

+import java.util.ArrayList;

+

+/**

+ * 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 final int mRevision;

+    private final String mDescription;

+    private final String mDescUrl;

+    private final Archive[] mArchives;

+    private final RepoSource mSource;

+

+    /**

+     * 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) {

+        mSource = source;

+        mRevision    = getXmlInt   (packageNode, SdkRepository.NODE_REVISION, 0);

+        mDescription = getXmlString(packageNode, SdkRepository.NODE_DESCRIPTION);

+        mDescUrl     = getXmlString(packageNode, SdkRepository.NODE_DESC_URL);

+

+        mArchives = parseArchives(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.

+     */

+    public Package(RepoSource source,

+            int revision,

+            String description,

+            String descUrl,

+            Os archiveOs,

+            Arch archiveArch,

+            String archiveUrl,

+            long archiveSize,

+            String archiveChecksum) {

+        mSource = source;

+        mRevision = revision;

+        mDescription = description;

+        mDescUrl = descUrl;

+        mArchives = new Archive[1];

+        mArchives[0] = new Archive(this,

+                archiveOs,

+                archiveArch,

+                archiveUrl,

+                archiveSize,

+                archiveChecksum);

+    }

+

+    /**

+     * Parses an XML node to process the <archives> element.

+     */

+    private Archive[] parseArchives(Node archivesNode) {

+        ArrayList<Archive> archives = new ArrayList<Archive>();

+

+        if (archivesNode != null) {

+            for(Node child = archivesNode.getFirstChild();

+                child != null;

+                child = child.getNextSibling()) {

+

+                if (child.getNodeType() == Node.ELEMENT_NODE &&

+                        SdkRepository.NS_SDK_REPOSITORY.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)   getEnumAttribute(archiveNode, SdkRepository.ATTR_OS,

+                            Os.values(), null),

+                    (Arch) getEnumAttribute(archiveNode, SdkRepository.ATTR_ARCH,

+                            Arch.values(), Arch.ANY),

+                    getXmlString(archiveNode, SdkRepository.NODE_URL),

+                    getXmlLong(archiveNode, SdkRepository.NODE_SIZE, 0),

+                    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. 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 archives defined in this package.

+     * Can be an empty array but not null.

+     */

+    public Archive[] getArchives() {

+        return mArchives;

+    }

+

+    /**

+     * 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() {

+        return String.format("%1$s\nRevision %2$d", getDescription(), getRevision());

+    }

+

+    /**

+     * 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.

+     * @return A new {@link File} corresponding to the directory to use to install this package.

+     */

+    public abstract File getInstallFolder(String osSdkRoot);

+

+    //---

+

+    /**

+     * Returns the first child element with the given XML local name.

+     * If xmlLocalName is null, returns the very first child element.

+     */

+    protected static Node getFirstChild(Node node, String xmlLocalName) {

+

+        for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {

+            if (child.getNodeType() == Node.ELEMENT_NODE &&

+                    SdkRepository.NS_SDK_REPOSITORY.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.

+     */

+    protected 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.

+     */

+    protected 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.

+     */

+    protected 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.

+     */

+    private 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/internal/repository/PlatformPackage.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformPackage.java
new file mode 100755
index 0000000..0d51c58
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/PlatformPackage.java
@@ -0,0 +1,114 @@
+/*

+ * 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.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;

+

+/**

+ * Represents a platform XML node in an SDK repository.

+ */

+public class PlatformPackage extends Package {

+

+    private final String mVersion;

+    private final int mApiLevel;

+

+    /**

+     * 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) {

+        super(source, packageNode);

+        mVersion  = getXmlString(packageNode, SdkRepository.NODE_VERSION);

+        mApiLevel = getXmlInt   (packageNode, SdkRepository.NODE_API_LEVEL, 0);

+    }

+

+    /**

+     * Creates a new platform package based on an actual {@link IAndroidTarget} (with

+     * must have {@link IAndroidTarget#isPlatform()} true) from the {@link SdkManager}.

+     * This is used to list local SDK folders.

+     */

+    PlatformPackage(IAndroidTarget target) {

+        super(  null,                       //source

+                0,                          //revision

+                target.getDescription(),  //description

+                null,                       //descUrl

+                Os.getCurrentOs(),          //archiveOs

+                Arch.getCurrentArch(),      //archiveArch

+                "",                         //archiveUrl   //$NON-NLS-1$

+                0,                          //archiveSize

+                null                        //archiveChecksum

+                );

+

+        mApiLevel = target.getApiVersionNumber();

+        mVersion  = target.getApiVersionName();

+    }

+

+    /** Returns the version, a string, for platform packages. */

+    public String getVersion() {

+        return mVersion;

+    }

+

+    /** Returns the api-level, an int > 0, for platform, add-on and doc packages. */

+    public int getApiLevel() {

+        return mApiLevel;

+    }

+

+    /** Returns a short description for an {@link IDescription}. */

+    @Override

+    public String getShortDescription() {

+        return String.format("SDK Platform Android %1$s, API %2$d",

+                getVersion(),

+                getApiLevel());

+    }

+

+    /** Returns a long description for an {@link IDescription}. */

+    @Override

+    public String getLongDescription() {

+        return String.format("%1$s.\n%2$s",

+                getShortDescription(),

+                super.getLongDescription());

+    }

+

+    /**

+     * 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.

+     * @return A new {@link File} corresponding to the directory to use to install this package.

+     */

+    @Override

+    public File getInstallFolder(String osSdkRoot) {

+        File platforms = new File(osSdkRoot, SdkConstants.FD_PLATFORMS);

+        File folder = new File(platforms, String.format("android-%s", getVersion())); //$NON-NLS-1$

+        // TODO find similar existing platform in platforms folder

+        return folder;

+    }

+}

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
new file mode 100755
index 0000000..1fd880f
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java
@@ -0,0 +1,334 @@
+/*

+ * 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.repository.SdkRepository;

+

+import org.w3c.dom.Document;

+import org.w3c.dom.Node;

+import org.xml.sax.InputSource;

+import org.xml.sax.SAXException;

+

+import java.io.BufferedReader;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.InputStreamReader;

+import java.io.StringReader;

+import java.net.URL;

+import java.util.ArrayList;

+

+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 final String mUrl;

+    private final boolean mAddonOnly;

+

+    private Package[] mPackages;

+    private String mDescription;

+

+    /**

+     * Constructs a new source for the given repository URL.

+     */

+    public RepoSource(String url, boolean addonOnly) {

+        mUrl = url;

+        mAddonOnly = addonOnly;

+        setDefaultDescription();

+    }

+

+    /** Returns the URL of the source repository. */

+    public String getUrl() {

+        return mUrl;

+    }

+

+    /**

+     * Returns the list of known packages found by the last call to {@link #load(ITaskFactory)}.

+     * 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 {@link #load(ITaskFactory)} is called.

+     */

+    public void clearPackages() {

+        mPackages = null;

+    }

+

+    public String getShortDescription() {

+        return mUrl;

+    }

+

+    public String getLongDescription() {

+        return mDescription == null ? "" : mDescription;  //$NON-NLS-1$

+    }

+

+    /**

+     * Tries to fetch the repository index for the given URL.

+     */

+    public void load(ITaskFactory taskFactory) {

+

+        taskFactory.start("Init SDK Updater", new ITask() {

+            public void run(ITaskMonitor monitor) {

+                monitor.setProgressMax(4);

+

+                setDefaultDescription();

+

+                monitor.setDescription("Fetching %1$s", mUrl);

+                monitor.incProgress(1);

+

+                String xml = fetchUrl(mUrl, monitor);

+

+                if (xml == null) {

+                    mDescription += String.format("\nFailed to fetch URL %1$s", mUrl);

+                    return;

+                }

+

+                monitor.setDescription("Validate XML");

+                monitor.incProgress(1);

+

+                if (!validateXml(xml, monitor)) {

+                    mDescription += String.format("\nFailed to validate XML at %1$s", mUrl);

+                    return;

+                }

+

+                monitor.setDescription("Parse XML");

+                monitor.incProgress(1);

+                parsePackages(xml, monitor);

+                if (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 (mAddonOnly) {

+            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 String fetchUrl(String urlString, ITaskMonitor monitor) {

+        URL url;

+        try {

+            url = new URL(urlString);

+

+            StringBuilder xml = new StringBuilder();

+            InputStream is = null;

+            BufferedReader br = null;

+            try {

+                is = url.openStream();

+                br = new BufferedReader(new InputStreamReader(is));

+

+                String line;

+                while ((line = br.readLine()) != null) {

+                    xml.append(line);

+                }

+

+                return xml.toString();

+

+            } finally {

+                if (br != null) {

+                    try {

+                        br.close();

+                    } catch (IOException e) {

+                        // pass

+                    }

+                }

+

+                if (is != null) {

+                    try {

+                        is.close();

+                    } catch (IOException e) {

+                        // pass

+                    }

+                }

+            }

+

+        } catch (IOException e) {

+            monitor.setResult(e.getMessage());

+        }

+

+        return null;

+    }

+

+    /**

+     * Validates this XML against the SDK Repository schema.

+     * Returns true if the XML was correctly validated.

+     */

+    private boolean validateXml(String xml, ITaskMonitor monitor) {

+

+        try {

+            Validator validator = getValidator();

+            validator.validate(new StreamSource(new StringReader(xml)));

+            return true;

+

+        } catch (SAXException e) {

+            monitor.setResult(e.getMessage());

+

+        } catch (IOException e) {

+            monitor.setResult(e.getMessage());

+        }

+

+        return false;

+    }

+

+    /**

+     * Helper method that returns a validator for our XSD

+     */

+    private Validator getValidator() throws SAXException {

+        InputStream xsdStream = SdkRepository.getXsdStream();

+        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

+

+        // 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.newValidator();

+

+        return validator;

+    }

+

+

+    /**

+     * Parse all packages defined in the SDK Repository XML and creates

+     * a new mPackages array with them.

+     */

+    private boolean parsePackages(String xml, ITaskMonitor monitor) {

+

+        try {

+            Document doc = getDocument(xml);

+

+            Node root = getFirstChild(doc, SdkRepository.NODE_SDK_REPOSITORY);

+            if (root != null) {

+

+                ArrayList<Package> packages = new ArrayList<Package>();

+

+                for (Node child = root.getFirstChild();

+                     child != null;

+                     child = child.getNextSibling()) {

+                    if (child.getNodeType() == Node.ELEMENT_NODE &&

+                            SdkRepository.NS_SDK_REPOSITORY.equals(child.getNamespaceURI())) {

+                        String name = child.getLocalName();

+                        Package p = null;

+

+                        try {

+                            if (SdkRepository.NODE_ADD_ON.equals(name)) {

+                                p = new AddonPackage(this, child);

+

+                            } else if (!mAddonOnly) {

+                                if (SdkRepository.NODE_PLATFORM.equals(name)) {

+                                    p = new PlatformPackage(this, child);

+                                } else if (SdkRepository.NODE_DOC.equals(name)) {

+                                    p = new DocPackage(this, child);

+                                } else if (SdkRepository.NODE_TOOL.equals(name)) {

+                                    p = new ToolPackage(this, child);

+                                }

+                            }

+

+                            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;

+            }

+

+        } catch (ParserConfigurationException e) {

+            monitor.setResult("Failed to create XML document builder for %1$s");

+

+        } catch (SAXException e) {

+            monitor.setResult("Failed to parse XML document %1$s");

+

+        } catch (IOException e) {

+            monitor.setResult("Failed to read XML document");

+        }

+

+        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 xmlLocalName) {

+

+        for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {

+            if (child.getNodeType() == Node.ELEMENT_NODE &&

+                    SdkRepository.NS_SDK_REPOSITORY.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.

+     */

+    private Document getDocument(String xml)

+            throws ParserConfigurationException, SAXException, IOException {

+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

+        factory.setIgnoringComments(true);

+        factory.setNamespaceAware(true);

+

+        DocumentBuilder builder = factory.newDocumentBuilder();

+        Document doc = builder.parse(new InputSource(new StringReader(xml)));

+

+        return doc;

+    }

+}

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
new file mode 100755
index 0000000..0a70953
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSources.java
@@ -0,0 +1,47 @@
+/*

+ * 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 java.util.ArrayList;

+

+/**

+ * A list of sdk-repository sources.

+ */

+public class RepoSources {

+

+    private ArrayList<RepoSource> mSources = new ArrayList<RepoSource>();

+    private ITaskFactory mTaskFactory;

+

+    public RepoSources() {

+    }

+

+    public void setTaskFactory(ITaskFactory taskFactory) {

+        mTaskFactory = taskFactory;

+    }

+

+    public ITaskFactory getTaskFactory() {

+        return mTaskFactory;

+    }

+

+    public void add(RepoSource source) {

+        mSources.add(source);

+    }

+

+    public ArrayList<RepoSource> getSources() {

+        return mSources;

+    }

+}

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
new file mode 100755
index 0000000..71e35c4
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ToolPackage.java
@@ -0,0 +1,92 @@
+/*

+ * 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.internal.repository.Archive.Arch;

+import com.android.sdklib.internal.repository.Archive.Os;

+

+import org.w3c.dom.Node;

+

+import java.io.File;

+

+/**

+ * 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) {

+        super(source, packageNode);

+    }

+

+    /**

+     * Manually create a new package with one archive and the given attributes.

+     * This is used to create packages from local directories.

+     */

+    ToolPackage(RepoSource source,

+            int revision,

+            String description,

+            String descUrl,

+            Os archiveOs,

+            Arch archiveArch,

+            String archiveUrl,

+            long archiveSize,

+            String archiveChecksum) {

+        super(source,

+                revision,

+                description,

+                descUrl,

+                archiveOs,

+                archiveArch,

+                archiveUrl,

+                archiveSize,

+                archiveChecksum);

+    }

+

+    /** 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() {

+        return String.format("Android SDK Tools, revision %1$d.\n%2$s",

+                getRevision(),

+                super.getLongDescription());

+    }

+

+    /**

+     * 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.

+     * @return A new {@link File} corresponding to the directory to use to install this package.

+     */

+    @Override

+    public File getInstallFolder(String osSdkRoot) {

+        return new File(osSdkRoot, SdkConstants.FD_TOOLS);

+    }

+}

diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ApkConfigurationHelper.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ApkConfigurationHelper.java
deleted file mode 100644
index b89d3bd..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ApkConfigurationHelper.java
+++ /dev/null
@@ -1,106 +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.project;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-/**
- * Helper class to read and write Apk Configuration into a {@link ProjectProperties} file.
- */
-public class ApkConfigurationHelper {
-    /** Prefix for property names for config definition. This prevents having config named
-     * after other valid properties such as "target". */
-    final static String CONFIG_PREFIX = "apk-config-";
-
-    /**
-     * Reads the Apk Configurations from a {@link ProjectProperties} file and returns them as a map.
-     * <p/>If there are no defined configurations, the returned map will be empty.
-     * @return 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) 
-     */
-    public static Map<String, String> getConfigs(ProjectProperties properties) {
-        HashMap<String, String> configMap = new HashMap<String, String>();
-
-        // get the list of configs.
-        String configList = properties.getProperty(ProjectProperties.PROPERTY_APK_CONFIGS);
-        if (configList != null) {
-            // this is a comma separated list
-            String[] configs = configList.split(","); //$NON-NLS-1$
-            
-            // read the value of each config and store it in a map
-            for (String config : configs) {
-                config = config.trim();
-                String configValue = properties.getProperty(CONFIG_PREFIX + config);
-                if (configValue != null) {
-                    configMap.put(config, configValue);
-                }
-            }
-        }
-        
-        return configMap;
-    }
-    
-    /**
-     * Writes the Apk Configurations from a given map into a {@link ProjectProperties}.
-     * @param properties the {@link ProjectProperties} in which to store the apk configurations. 
-     * @param configMap 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) 
-     * @return true if the {@link ProjectProperties} contained Apk Configuration that were not
-     * present in the map. 
-     */
-    public static boolean setConfigs(ProjectProperties properties, Map<String, String> configMap) {
-        // load the current configs, in order to remove the value properties for each of them
-        // in case a config was removed.
-        
-        // get the list of configs.
-        String configList = properties.getProperty(ProjectProperties.PROPERTY_APK_CONFIGS);
-
-        boolean hasRemovedConfig = false;
-
-        if (configList != null) {
-            // this is a comma separated list
-            String[] configs = configList.split(","); //$NON-NLS-1$
-            
-            for (String config : configs) {
-                config = config.trim();
-                if (configMap.containsKey(config) == false) {
-                    hasRemovedConfig = true;
-                    properties.removeProperty(CONFIG_PREFIX + config);
-                }
-            }
-        }
-        
-        // now add the properties.
-        Set<Entry<String, String>> entrySet = configMap.entrySet();
-        StringBuilder sb = new StringBuilder();
-        for (Entry<String, String> entry : entrySet) {
-            if (sb.length() > 0) {
-                sb.append(",");
-            }
-            sb.append(entry.getKey());
-            properties.setProperty(CONFIG_PREFIX + entry.getKey(), entry.getValue());
-        }
-        properties.setProperty(ProjectProperties.PROPERTY_APK_CONFIGS, sb.toString());
-        
-        return hasRemovedConfig;
-    }
-}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java
deleted file mode 100644
index b84be18..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java
+++ /dev/null
@@ -1,769 +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.project;
-
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.ISdkLog;
-import com.android.sdklib.SdkConstants;
-import com.android.sdklib.project.ProjectProperties.PropertyType;
-
-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.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-
-/**
- * Creates the basic files needed to get an Android project up and running. Also
- * allows creation of IntelliJ project files.
- *
- * @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". */
-    private final static String PH_ACTIVITY_NAME = "ACTIVITY_NAME";
-    /** Project name substitution string used in template files, i.e. "PROJECT_NAME". */
-    private final static String PH_PROJECT_NAME = "PROJECT_NAME";
-    
-    private final static String FOLDER_TESTS = "tests";
-    
-    /** 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;
-        
-        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 activityName 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 isTestProject whether the project to create is a test project.
-     */
-    public void createProject(String folderPath, String projectName,
-            String packageName, String activityName, IAndroidTarget target,
-            boolean isTestProject) {
-        
-        // 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 {
-            // 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 an empty build.properties
-            ProjectProperties buildProperties = ProjectProperties.create(folderPath,
-                    PropertyType.BUILD);
-            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);
-            if (activityName != null) {
-                keywords.put(PH_ACTIVITY_NAME, activityName);
-            }
-
-            // Take the project name from the command line if there's one
-            if (projectName != null) {
-                keywords.put(PH_PROJECT_NAME, projectName);
-            } else {
-                if (activityName != null) {
-                    // Use the activity as project name 
-                    keywords.put(PH_PROJECT_NAME, activityName);
-                } 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 and the java package folders.
-            String srcFolderPath = SdkConstants.FD_SOURCES + File.separator + packagePath;
-            File sourceFolder = createDirs(projectFolder, srcFolderPath);
-            String javaTemplate = "java_file.template";
-            String activityFileName = activityName + ".java";
-            if (isTestProject) {
-                javaTemplate = "java_tests_file.template";
-                activityFileName = activityName + "Test.java";
-            }
-            installTemplate(javaTemplate, new File(sourceFolder, activityFileName),
-                    keywords, target);
-
-            // create the generate source folder
-            srcFolderPath = SdkConstants.FD_GEN_SOURCES + File.separator + packagePath;
-            sourceFolder = createDirs(projectFolder, srcFolderPath);
-
-            // create other useful folders
-            File resourceFodler = 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(resourceFodler, SdkConstants.FD_VALUES);
-                installTemplate("strings.template", new File(valueFolder, "strings.xml"),
-                        keywords, target);
-
-                File layoutFolder = createDirs(resourceFodler, SdkConstants.FD_LAYOUT);
-                installTemplate("layout.template", new File(layoutFolder, "main.xml"),
-                        keywords, target);
-            }
-
-            /* 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);
-
-            // if this is not a test project, then we create one.
-            if (isTestProject == false) {
-                // create the test project folder.
-                createDirs(projectFolder, FOLDER_TESTS);
-                File testProjectFolder = new File(folderPath, FOLDER_TESTS);
-                
-                createProject(testProjectFolder.getAbsolutePath(), projectName, packageName,
-                        activityName, target, true /*isTestProject*/);
-            }
-        } 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 ) {
-        // 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;
-        }
-
-        // 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;
-        }
-        
-        // 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) {
-            // Note that "<androidinit" 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, "<androidinit(?:\\s|/|$)");
-            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_NAME)) {
-                    // Use the activity as project name 
-                    keywords.put(PH_PROJECT_NAME, keywords.get(PH_ACTIVITY_NAME));
-                } 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);
-            }
-        }
-    }
-
-    /**
-     * 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_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 {
-            final String nsPrefix = "android";
-            final String nsURI = SdkConstants.NS_RESOURCES;
-            
-            XPath xpath = XPathFactory.newInstance().newXPath();
-            
-            xpath.setNamespaceContext(new NamespaceContext() {
-                public String getNamespaceURI(String prefix) {
-                    if (nsPrefix.equals(prefix)) {
-                        return nsURI;
-                    }
-                    return XMLConstants.NULL_NS_URI;
-                }
-
-                public String getPrefix(String namespaceURI) {
-                    if (nsURI.equals(namespaceURI)) {
-                        return nsPrefix;
-                    }
-                    return null;
-                }
-
-                @SuppressWarnings("unchecked")
-                public Iterator getPrefixes(String namespaceURI) {
-                    if (nsURI.equals(namespaceURI)) {
-                        ArrayList<String> list = new ArrayList<String>();
-                        list.add(nsPrefix);
-                        return list.iterator();
-                    }
-                    return null;
-                }
-                
-            });
-            
-            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", nsPrefix);
-
-            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.",
-                        nsPrefix, manifestFile.getName());
-            } else {
-                outKeywords.put(PH_ACTIVITY_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) {
-                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);
-    }
-
-    /**
-     * 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/project/ProjectProperties.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectProperties.java
deleted file mode 100644
index f9ae583..0000000
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectProperties.java
+++ /dev/null
@@ -1,265 +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.project;
-
-import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.SdkManager;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-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_APK_CONFIGS = "apk-configurations";
-    public final static String PROPERTY_SDK = "sdk-location";
-    
-    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" +
-           "# The name of your application package as defined in the manifest.\n" +
-           "# Used by the 'uninstall' rule.\n"+
-           "#application-package=com.example.myproject\n" +
-           "\n" +
-           "# The name of the source folder.\n" +
-           "#source-folder=src\n" +
-           "\n" +
-           "# The name of the output folder.\n" +
-           "#out-folder=bin\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_APK_CONFIGS,
-                "# apk configurations. This property allows creation of APK files with limited\n" +
-                "# resources. For example, if your application contains many locales and\n" +
-                "# you wish to release multiple smaller apks instead of a large one, you can\n" +
-                "# define configuration to create apks with limited language sets.\n" +
-                "# Format is a comma separated list of configuration names. For each\n" +
-                "# configuration, a property will declare the resource configurations to\n" +
-                "# include. Example:\n" +
-                "#     " + PROPERTY_APK_CONFIGS +"=european,northamerica\n" +
-                "#     " + ApkConfigurationHelper.CONFIG_PREFIX + "european=en,fr,it,de,es\n" +
-                "#     " + ApkConfigurationHelper.CONFIG_PREFIX + "northamerica=en,es\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");
-    }
-    
-    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.
-     * @throws IOException
-     */
-    public void save() throws IOException {
-        File toSave = new File(mProjectFolderOsPath, mType.mFilename);
-        
-        FileWriter writer = new FileWriter(toSave);
-        
-        // 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();
-            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/repository/SdkRepository.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepository.java
new file mode 100755
index 0000000..673e43f
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepository.java
@@ -0,0 +1,91 @@
+/*

+ * 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.google.com/android/eclipse/repository/index.xml";           //$NON-NLS-1$

+

+    /** The XML namespace of the sdk-repository XML. */

+    public static final String NS_SDK_REPOSITORY =

+        "http://schemas.android.com/sdk/android/repository/1";                  //$NON-NLS-1$

+

+    /** 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$

+

+    /** 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 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 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 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$

+

+    public static InputStream getXsdStream() {

+        return SdkRepository.class.getResourceAsStream("sdk-repository.xsd");   //$NON-NLS-1$

+    }

+

+}

diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository.xsd b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository.xsd
new file mode 100755
index 0000000..6c80d2e
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository.xsd
@@ -0,0 +1,186 @@
+<?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 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>
+
+    <!-- The repository contains a collection of downloadable items -->
+
+    <xsd:element name="sdk-repository">
+        <xsd:annotation>
+            <xsd:documentation>
+                The repository contains collections of downloadable items.
+            </xsd:documentation>
+        </xsd:annotation>
+
+        <xsd:complexType>
+            <xsd:choice minOccurs="0" maxOccurs="unbounded">
+
+                <!-- The definition of an SDK platform item -->
+
+                <xsd:element name="platform">
+                    <xsd:complexType>
+                        <xsd:all>
+                            <xsd:element name="version"   type="xsd:normalizedString" />
+                            <xsd:element name="api-level" type="xsd:positiveInteger"  />
+
+                            <xsd:element name="revision"    type="xsd:positiveInteger" />
+                            <xsd:element name="description" type="xsd:string" minOccurs="0" />
+                            <xsd:element name="desc-url"    type="xsd:token"  minOccurs="0" />
+                            <xsd:element name="archives"    type="sdk:archivesType" />
+                        </xsd:all>
+                    </xsd:complexType>
+                </xsd:element>
+
+                <!-- The definition of an SDK Add-on item -->
+
+                <xsd:element name="add-on">
+                    <xsd:complexType>
+                        <xsd:all>
+                            <xsd:element name="name"      type="xsd:normalizedString" />
+                            <xsd:element name="vendor"    type="xsd:normalizedString" />
+                            <xsd:element name="api-level" type="xsd:positiveInteger"  />
+
+                            <xsd:element name="revision"    type="xsd:positiveInteger" />
+                            <xsd:element name="description" type="xsd:string" minOccurs="0" />
+                            <xsd:element name="desc-url"    type="xsd:token"  minOccurs="0" />
+                            <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>
+                                                    <xsd:element name="name" type="xsd:normalizedString" />
+                                                    <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 item -->
+
+                <xsd:element name="tool">
+                    <xsd:complexType>
+                        <xsd:all>
+                            <xsd:element name="revision"    type="xsd:positiveInteger" />
+                            <xsd:element name="description" type="xsd:string" minOccurs="0" />
+                            <xsd:element name="desc-url"    type="xsd:token"  minOccurs="0" />
+                            <xsd:element name="archives"    type="sdk:archivesType" />
+                        </xsd:all>
+                    </xsd:complexType>
+                </xsd:element>
+
+                <!-- The definition of an SDK doc item -->
+
+                <xsd:element name="doc">
+                    <xsd:complexType>
+                        <xsd:all>
+                            <xsd:element name="api-level" type="xsd:positiveInteger"  />
+
+                            <xsd:element name="revision"    type="xsd:positiveInteger" />
+                            <xsd:element name="description" type="xsd:string" minOccurs="0" />
+                            <xsd:element name="desc-url"    type="xsd:token"  minOccurs="0" />
+                            <xsd:element name="archives"    type="sdk:archivesType" />
+                        </xsd:all>
+                    </xsd:complexType>
+                </xsd:element>
+            </xsd:choice>
+        </xsd:complexType>
+    </xsd:element>
+
+    <!-- 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.
+     -->
+
+    <xsd:complexType name="archivesType">
+        <xsd:annotation>
+            <xsd:documentation>A collection of architecture-dependent archives.</xsd:documentation>
+        </xsd:annotation>
+        <xsd:sequence minOccurs="1" maxOccurs="unbounded">
+            <!-- One archive file -->
+            <xsd:element name="archive">
+                <xsd:complexType>
+                    <!-- Properties of the file -->
+                    <xsd:all>
+                        <xsd:element name="size"     type="xsd:positiveInteger" />
+                        <xsd:element name="checksum" type="sdk:checksumType" />
+                        <xsd:element name="url"      type="xsd:token" />
+                    </xsd:all>
+
+                    <!-- Attributes that identify the 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>
+
+</xsd:schema>
diff --git a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/TestSdkRepository.java b/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/TestSdkRepository.java
new file mode 100755
index 0000000..879f3e6
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/TestSdkRepository.java
@@ -0,0 +1,248 @@
+/*

+ * 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 TestSdkRepository 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 = "";

+

+        public String getErrors() {

+            return mErrors;

+        }

+

+        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(CaptureErrorHandler handler) throws SAXException {

+        InputStream xsdStream = SdkRepository.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;

+    }

+

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

+    public void testValidateLocalRepositoryFile() throws Exception {

+

+        InputStream xmlStream =

+            TestSdkRepository.class.getResourceAsStream("repository_sample.xml");

+        Source source = new StreamSource(xmlStream);

+

+        CaptureErrorHandler handler = new CaptureErrorHandler();

+        Validator validator = getValidator(handler);

+        validator.validate(source);

+        handler.verify();

+    }

+

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

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

+        assertNotNull(actualString);

+        assertTrue(

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

+                        expectedRegexp, actualString),

+                actualString.matches(expectedRegexp));

+    }

+

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

+

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

+    public void testEmptyXml() throws Exception {

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

+

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

+

+        CaptureErrorHandler handler = new CaptureErrorHandler();

+        Validator validator = getValidator(handler);

+

+        try {

+            validator.validate(source);

+        } catch (SAXParseException e) {

+            // We expect to get this specific exception message

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

+            return;

+        }

+        // We shouldn't get here

+        handler.verify();

+        fail();

+    }

+

+    /** A document with a root element containing no platform, addon, etc., is valid. */

+    public void testEmptyRootXml() throws Exception {

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

+            "<r:sdk-repository xmlns:r=\"http://schemas.android.com/sdk/android/repository/1\" />";

+

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

+

+        CaptureErrorHandler handler = new CaptureErrorHandler();

+        Validator validator = getValidator(handler);

+        validator.validate(source);

+        handler.verify();

+    }

+

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

+    public void testUnknownContentXml() throws Exception {

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

+            "<r:sdk-repository xmlns:r=\"http://schemas.android.com/sdk/android/repository/1\" >" +

+            "<r:unknown />" +

+            "</r:sdk-repository>";

+

+        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(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\"?>" +

+            "<r:sdk-repository xmlns:r=\"http://schemas.android.com/sdk/android/repository/1\" >" +

+            "<r:platform> <r:api-level>1</r:api-level> <r:libs /> </r:platform>" +

+            "</r:sdk-repository>";

+

+        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(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\"?>" +

+            "<r:sdk-repository xmlns:r=\"http://schemas.android.com/sdk/android/repository/1\" >" +

+            "<r:platform> <r:api-level>NotAnInteger</r:api-level> <r:libs /> </r:platform>" +

+            "</r:sdk-repository>";

+

+        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(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();

+    }

+}

diff --git a/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/repository_sample.xml b/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/repository_sample.xml
new file mode 100755
index 0000000..fb6283d
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/tests/com/android/sdklib/repository/repository_sample.xml
@@ -0,0 +1,216 @@
+<?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">

+

+    <!-- 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:description>Some optional description</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:doc>

+        <sdk:api-level>1</sdk:api-level>

+        <sdk:revision>1</sdk:revision>

+        <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: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: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:add-on>

+

+    <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: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: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: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: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:sdk-repository>

diff --git a/tools/sdkmanager/libs/sdkuilib/.classpath b/tools/sdkmanager/libs/sdkuilib/.classpath
index eb5af7e..5e78ee7 100644
--- a/tools/sdkmanager/libs/sdkuilib/.classpath
+++ b/tools/sdkmanager/libs/sdkuilib/.classpath
@@ -1,8 +1,8 @@
-<?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="/SdkLib"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

+	<classpathentry kind="src" path="src"/>

+	<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 kind="output" path="bin"/>

+</classpath>

diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/AvdSelector.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/AvdSelector.java
index 20c211b..0166556 100644
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/AvdSelector.java
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/AvdSelector.java
@@ -1,11 +1,11 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2009 The Android Open Source Project
  *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *      http://www.eclipse.org/org/documents/epl-v10.php
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,17 +17,19 @@
 package com.android.sdkuilib;
 
 import com.android.sdklib.IAndroidTarget;
-import com.android.sdklib.avd.AvdManager.AvdInfo;
+import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
 
 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.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.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Event;
 import org.eclipse.swt.widgets.Label;
@@ -40,49 +42,117 @@
 /**
  * The AVD selector is a table that is added to the given parent composite.
  * <p/>
- * To use, create it using {@link #AvdSelector(Composite, AvdInfo[])} then
+ * To use, create it using {@link #AvdSelector(Composite, SelectionMode, IExtraAction)} then
  * call {@link #setSelection(AvdInfo)}, {@link #setSelectionListener(SelectionListener)}
- * and finally use {@link #getFirstSelected()} to retrieve the selection.
+ * and finally use {@link #getSelected()} to retrieve the selection.
  */
 public final class AvdSelector {
-    
+
     private AvdInfo[] mAvds;
     private SelectionListener mSelectionListener;
     private Table mTable;
     private Label mDescription;
 
+    private static int NUM_COL = 2;
+    private final SelectionMode mSelectionMode;
+    private final IExtraAction mExtraAction;
+    private Button mExtraActionButton;
+
+    /** The selection mode, either {@link #SELECT} or {@link #CHECK} */
+    public enum SelectionMode {
+        /**
+         * 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.
+         */
+        CHECK,
+        /**
+         * 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.
+         */
+        SELECT
+    }
+
+    /**
+     * Defines an "extra action" button that can be shown under the AVD Selector.
+     */
+    public interface IExtraAction {
+        /**
+         * Label of the button that will be created.
+         * This is invoked once when the button is created and cannot be changed later.
+         */
+        public String label();
+
+        /**
+         * This is invoked just after the selection has changed to update the "enabled"
+         * state of the action. Implementation should use {@link AvdSelector#getSelected()}.
+         */
+        public boolean isEnabled();
+
+        /**
+         * Run the action, invoked when the button is clicked.
+         *
+         * The caller's action is responsible for reloading the AVD list
+         * using {@link AvdSelector#setAvds(AvdInfo[], IAndroidTarget)}.
+         */
+        public void run();
+    }
+
     /**
      * 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 avds The list of AVDs. This is <em>not</em> copied, the caller must not modify.
+     *             It can be null.
+     * @param filter When non-null, will display only the AVDs matching this target.
+     * @param extraAction When non-null, displays an extra action button.
+     * @param selectionMode One of {@link SelectionMode#SELECT} or {@link SelectionMode#CHECK}
      */
-    public AvdSelector(Composite parent, AvdInfo[] avds, IAndroidTarget filter) {
+    public AvdSelector(Composite parent,
+            AvdInfo[] avds,
+            IAndroidTarget filter,
+            IExtraAction extraAction,
+            SelectionMode selectionMode) {
         mAvds = avds;
+        mExtraAction = extraAction;
+        mSelectionMode = selectionMode;
 
-        // Layout has 1 column
+        // Layout has 2 columns
         Composite group = new Composite(parent, SWT.NONE);
-        group.setLayout(new GridLayout());
+        group.setLayout(new GridLayout(NUM_COL, false /*makeColumnsEqualWidth*/));
         group.setLayoutData(new GridData(GridData.FILL_BOTH));
         group.setFont(parent.getFont());
-        
-        mTable = new Table(group, SWT.CHECK | SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER);
+
+        int style = SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER;
+        if (selectionMode == SelectionMode.CHECK) {
+            style |= SWT.CHECK;
+        }
+        mTable = new Table(group, 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);
+        setTableHeightHint(0);
 
         mDescription = new Label(group, SWT.WRAP);
         mDescription.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 
+        if (extraAction != null) {
+            mExtraActionButton = new Button(group, SWT.PUSH);
+            mExtraActionButton.setText(extraAction.label());
+            mExtraActionButton.setEnabled(extraAction.isEnabled());
+            mExtraActionButton.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    super.widgetSelected(e);
+                    mExtraAction.run();
+                }
+            });
+        }
+
         // create the table columns
         final TableColumn column0 = new TableColumn(mTable, SWT.NONE);
         column0.setText("AVD Name");
@@ -98,39 +168,74 @@
         fillTable(mTable, filter);
         setupTooltip(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 avds The list of AVDs. This is <em>not</em> copied, the caller must not modify.
+     *             It can be null.
+     * @param extraAction When non-null, displays an extra action button.
+     * @param selectionMode One of {@link SelectionMode#SELECT} or {@link SelectionMode#CHECK}
      */
-    public AvdSelector(Composite parent, AvdInfo[] avds) {
-        this(parent, avds, null /* filter */);
+    public AvdSelector(Composite parent,
+            AvdInfo[] avds,
+            IExtraAction extraAction,
+            SelectionMode selectionMode) {
+        this(parent, avds, null /* filter */, extraAction, selectionMode);
     }
 
-    
+    /**
+     * 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 extraAction When non-null, displays an extra action button.
+     * @param selectionMode One of {@link SelectionMode#SELECT} or {@link SelectionMode#CHECK}
+     */
+    public AvdSelector(Composite parent,
+            SelectionMode selectionMode,
+            IExtraAction extraAction) {
+        this(parent, null /*avds*/, null /* filter */, extraAction, selectionMode);
+    }
+
+    /**
+     * 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();
-        data.heightHint = heightHint;
+        if (heightHint > 0) {
+            data.heightHint = heightHint;
+        }
         data.grabExcessVerticalSpace = true;
         data.grabExcessHorizontalSpace = true;
+        data.horizontalSpan = NUM_COL;
         data.horizontalAlignment = GridData.FILL;
         data.verticalAlignment = GridData.FILL;
         mTable.setLayoutData(data);
     }
-    
+
     /**
      * Sets a new set of AVD, with an optional filter.
-     * <p/>This must be called from the UI thread.
-     * 
+     * Tries to keep the selection.
+     * <p/>
+     * This must be called from the UI thread.
+     *
+     *
      * @param avds The list of AVDs. This is <em>not</em> copied, the caller must not modify.
+     *             It can be null.
      * @param filter An IAndroidTarget. If non-null, only AVD whose target are compatible with the
      * filter target will displayed an available for selection.
      */
     public void setAvds(AvdInfo[] avds, IAndroidTarget filter) {
+
+        AvdInfo selected = getSelected();
+
         mAvds = avds;
         fillTable(mTable, filter);
+
+        setSelection(selected);
     }
 
     /**
@@ -150,56 +255,84 @@
      * 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 #getFirstSelected()} method instead.
-     * 
+     * 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
+     *
+     * @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 ((AvdInfo) i.getData() == target) {
-                found = true;
-                if (!i.getChecked()) {
-                    modified = true;
-                    i.setChecked(true);
+            if (mSelectionMode == SelectionMode.SELECT) {
+                if ((AvdInfo) i.getData() == target) {
+                    found = true;
+                    if (index != selIndex) {
+                        mTable.setSelection(index);
+                        modified = true;
+                    }
+                    break;
                 }
-            } else if (i.getChecked()) {
-                modified = true;
-                i.setChecked(false);
+
+                index++;
+
+            } else if (mSelectionMode == SelectionMode.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);
+                }
             }
         }
-        
+
         if (modified && mSelectionListener != null) {
             mSelectionListener.widgetSelected(null);
         }
-        
+
+        if (mExtraAction != null && mExtraActionButton != null) {
+            mExtraActionButton.setEnabled(mExtraAction.isEnabled());
+        }
+
         return found;
     }
 
     /**
-     * Returns the first selected item.
-     * This is useful when the table is in single-selection mode.
-     * 
-     * @return The first selected item or null.
+     * Returns the currently selected item.
+     *
+     * @return The currently selected item or null.
      */
-    public AvdInfo getFirstSelected() {
-        for (TableItem i : mTable.getItems()) {
-            if (i.getChecked()) {
-                return (AvdInfo) i.getData();
+    public AvdInfo getSelected() {
+        if (mSelectionMode == SelectionMode.SELECT) {
+            int selIndex = mTable.getSelectionIndex();
+            if (selIndex >= 0) {
+                return (AvdInfo) mTable.getItem(selIndex).getData();
+            }
+
+        } else if (mSelectionMode == SelectionMode.CHECK) {
+            for (TableItem i : mTable.getItems()) {
+                if (i.getChecked()) {
+                    return (AvdInfo) i.getData();
+                }
             }
         }
         return null;
@@ -209,7 +342,7 @@
      * 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) {
@@ -233,7 +366,7 @@
             @Override
             public void controlResized(ControlEvent e) {
                 Rectangle r = table.getClientArea();
-                column0.setWidth(r.width * 30 / 100); // 30%  
+                column0.setWidth(r.width * 30 / 100); // 30%
                 column1.setWidth(r.width * 45 / 100); // 45%
                 column2.setWidth(r.width * 10 / 100); // 10%
                 column3.setWidth(r.width * 15 / 100); // 15%
@@ -249,7 +382,7 @@
     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}
@@ -264,20 +397,26 @@
                 if (mSelectionListener != null) {
                     mSelectionListener.widgetSelected(e);
                 }
+
+                if (mExtraAction != null && mExtraActionButton != null) {
+                    mExtraActionButton.setEnabled(mExtraAction.isEnabled());
+                }
             }
 
             /**
              * 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;
-                    i.setChecked(true);
+                    if (mSelectionMode == SelectionMode.CHECK) {
+                        i.setChecked(true);
+                    }
                     enforceSingleSelection(i);
                     updateDescription(i);
                 }
@@ -285,6 +424,10 @@
                 if (mSelectionListener != null) {
                     mSelectionListener.widgetDefaultSelected(e);
                 }
+
+                if (mExtraAction != null && mExtraActionButton != null) {
+                    mExtraActionButton.setEnabled(mExtraAction.isEnabled());
+                }
             }
 
             /**
@@ -292,11 +435,16 @@
              * This makes the chekboxes act as radio buttons.
              */
             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);
+                if (mSelectionMode == SelectionMode.SELECT) {
+                    // pass
+
+                } else if (mSelectionMode == SelectionMode.CHECK) {
+                    if (item.getChecked()) {
+                        Table parentTable = item.getParent();
+                        for (TableItem i2 : parentTable.getItems()) {
+                            if (i2 != item && i2.getChecked()) {
+                                i2.setChecked(false);
+                            }
                         }
                     }
                 }
@@ -330,7 +478,7 @@
                 }
             }
         }
-        
+
         if (table.getItemCount() == 0) {
             table.setEnabled(false);
             TableItem item = new TableItem(table, SWT.NONE);
@@ -350,36 +498,36 @@
      */
     private void setupTooltip(final Table table) {
         /*
-         * Reference: 
+         * 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);
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java
index cd789f6..b90bd61 100644
--- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java
@@ -1,11 +1,11 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2009 The Android Open Source Project
  *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *      http://www.eclipse.org/org/documents/epl-v10.php
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -28,6 +28,7 @@
 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;
@@ -45,17 +46,17 @@
  * 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.
@@ -66,7 +67,7 @@
 
     /**
      * 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.
@@ -78,7 +79,7 @@
         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) {
@@ -136,7 +137,7 @@
 
     /**
      * 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) {
@@ -153,19 +154,19 @@
      * 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.
      */
@@ -173,7 +174,7 @@
         if (!mAllowSelection) {
             return false;
         }
-        
+
         boolean found = false;
         boolean modified = false;
 
@@ -191,17 +192,17 @@
                 }
             }
         }
-        
+
         if (modified && mSelectionListener != null) {
             mSelectionListener.widgetSelected(null);
         }
-        
+
         return found;
     }
 
     /**
      * Returns the selected item.
-     * 
+     *
      * @return The selected item or null.
      */
     public IAndroidTarget getSelected() {
@@ -233,7 +234,7 @@
             @Override
             public void controlResized(ControlEvent e) {
                 Rectangle r = table.getClientArea();
-                column0.setWidth(r.width * 30 / 100); // 30%  
+                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%
@@ -266,7 +267,7 @@
                     mSelectionListener.widgetDefaultSelected(e);
                 }
             }
-            
+
             public void widgetSelected(SelectionEvent e) {
                 if (e.item instanceof TableItem) {
                     TableItem i = (TableItem) e.item;
@@ -314,7 +315,7 @@
         }
 
         table.removeAll();
-        
+
         if (mTargets != null && mTargets.length > 0) {
             table.setEnabled(true);
             for (IAndroidTarget target : mTargets) {
@@ -349,36 +350,36 @@
         }
 
         /*
-         * Reference: 
+         * 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);
@@ -397,4 +398,21 @@
             }
         }
     }
+
+    /** 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/internal/repository/LocalPackagesPage.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalPackagesPage.java
new file mode 100755
index 0000000..5bb9e8a
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalPackagesPage.java
@@ -0,0 +1,219 @@
+/*

+ * 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.ITask;

+import com.android.sdklib.internal.repository.ITaskMonitor;

+

+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;

+

+/*

+ * TODO list

+ * - parse local repo

+ * - create entries

+ * - 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 {

+    private 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 mHomePageButton;

+    private Label mDescriptionLabel;

+

+    /**

+     * Create the composite.

+     * @param parent The parent of the composite.

+     * @param updaterData An instance of {@link UpdaterData}. If null, a local

+     *        one will be allocated just to help with the SWT Designer.

+     */

+    public LocalPackagesPage(Composite parent, UpdaterData updaterData) {

+        super(parent, SWT.BORDER);

+

+        mUpdaterData = updaterData != null ? updaterData : new 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));

+

+        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.addSelectionListener(new SelectionAdapter() {

+            @Override

+            public void widgetSelected(SelectionEvent e) {

+                onUpdateInstalledPackage();  //$hide$ (hide from SWT designer)

+            }

+        });

+        mUpdateButton.setText("Update...");

+

+        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...");

+

+        mPlaceholder2 = new Label(mContainerButtons, SWT.NONE);

+        mPlaceholder2.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1));

+

+        mHomePageButton = new Button(mContainerButtons, SWT.NONE);

+        mHomePageButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));

+        mHomePageButton.setText("Home Page...");

+    }

+

+    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

+    protected void checkSubclass() {

+        // Disable the check that prevents subclassing of SWT components

+    }

+

+    // -- Start of internal part ----------

+    // Hide everything down-below from SWT designer

+    //$hide>>$

+

+    private void postCreate() {

+        adjustColumnsWidth();

+    }

+

+

+    /**

+     * 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

+        mTablePackages.addControlListener(new ControlAdapter() {

+            @Override

+            public void controlResized(ControlEvent e) {

+                Rectangle r = mTablePackages.getClientArea();

+                mColumnPackages.setWidth(r.width);

+            }

+        });

+    }

+

+    public void setInput(LocalSdkAdapter localSdkAdapter) {

+        mTableViewerPackages.setLabelProvider(  localSdkAdapter.getLabelProvider());

+        mTableViewerPackages.setContentProvider(localSdkAdapter.getContentProvider());

+        mTableViewerPackages.setInput(localSdkAdapter);

+    }

+

+    protected void onUpdateInstalledPackage() {

+        // TODO just a test, needs to be removed later.

+        ProgressTask.start(getShell(), "Test", new ITask() {

+            public void run(ITaskMonitor monitor) {

+                monitor.setDescription("Test");

+                monitor.setProgressMax(100);

+                int n = 0;

+                int d = 1;

+                while(!monitor.cancelRequested()) {

+                    monitor.incProgress(d);

+                    n += d;

+                    if (n == 0 || n == 100) d = -d;

+                    try {

+                        Thread.sleep(5);

+                    } catch (InterruptedException e) {

+                        // ignore

+                    }

+                }

+            }

+        });

+    }

+

+    // 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
new file mode 100755
index 0000000..330be18
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/LocalSdkAdapter.java
@@ -0,0 +1,116 @@
+/*

+ * 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.LocalSdkParser;

+import com.android.sdklib.internal.repository.Package;

+import com.android.sdklib.internal.repository.RepoSource;

+

+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 LocalSdkParser mLocalSdkParser;

+    private String mOsSdkRoot;

+

+    public LocalSdkAdapter(LocalSdkParser localSdkParser) {

+        mLocalSdkParser = localSdkParser;

+    }

+

+    public void setSdkRoot(String osSdkRoot) {

+        mOsSdkRoot = osSdkRoot;

+        mLocalSdkParser.clearPackages();

+    }

+

+    public ILabelProvider getLabelProvider() {

+        return new ViewerLabelProvider();

+    }

+

+

+    public IContentProvider getContentProvider() {

+        return new TableContentProvider();

+    }

+

+    // ------------

+

+    public static class ViewerLabelProvider extends LabelProvider {

+        /** Returns null by default */

+        @Override

+        public Image getImage(Object 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 static 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) {

+            // pass

+        }

+

+        /**

+         * 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 instanceof LocalSdkAdapter) {

+                LocalSdkAdapter adapter = (LocalSdkAdapter) inputElement;

+                LocalSdkParser parser = adapter.mLocalSdkParser;

+

+                Package[] packages = parser.getPackages();

+

+                if (packages == null) {

+                    // load on demand the first time

+                    packages = parser.parseSdk(adapter.mOsSdkRoot);

+                }

+

+                if (packages != null) {

+                    return packages;

+                }

+            }

+

+            return new Object[0];

+        }

+    }

+

+}

diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTask.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTask.java
new file mode 100755
index 0000000..7667355
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTask.java
@@ -0,0 +1,251 @@
+/*

+ * 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.ITask;

+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.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;

+

+/*

+ * TODO:

+ * - trap window.close and treat it as a cancel request

+ * - on cancel as been clicked *and* the task finished,, change it to a "close" button

+ */

+

+

+class ProgressTask extends Dialog

+    implements ITaskMonitor             //$hide$ (hide from SWT designer)

+    {

+

+    private boolean mCancelRequested;

+    private boolean mCloseRequested;

+    private boolean mAutomaticallyCloseOnTaskCompletion = true;

+

+

+    // UI fields

+    private Shell mDialogShell;

+    private Composite mRootComposite;

+    private Label mLabel;

+    private ProgressBar mProgressBar;

+    private Button mCancelButton;

+    private Text mResultText;

+

+

+    /**

+     * Create the dialog.

+     * @param parent Parent container

+     */

+    public ProgressTask(Shell parent) {

+        super(parent, SWT.APPLICATION_MODAL);

+    }

+

+    /**

+     * Open the dialog and blocks till it gets closed

+     */

+    public void open() {

+        createContents();

+        mDialogShell.open();

+        mDialogShell.layout();

+        Display display = getParent().getDisplay();

+

+        startTask();    //$hide$ (hide from SWT designer)

+

+        while (!mDialogShell.isDisposed() && !mCloseRequested) {

+            if (!display.readAndDispatch()) {

+                display.sleep();

+            }

+        }

+

+        mCancelRequested = true;

+

+        if (!mDialogShell.isDisposed()) {

+            mDialogShell.close();

+        }

+    }

+

+    /**

+     * Create contents of the dialog.

+     */

+    private void createContents() {

+        mDialogShell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);

+        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) {

+                mCancelRequested = true;

+                mCancelButton.setEnabled(false);

+            }

+        });

+

+        mResultText = new Text(mRootComposite,

+                SWT.BORDER | SWT.READ_ONLY | SWT.V_SCROLL | SWT.MULTI);

+        mResultText.setEditable(true);

+        mResultText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));

+        mResultText.setVisible(false);

+    }

+

+    // -- End of UI, Start of internal logic ----------

+    // Hide everything down-below from SWT designer

+    //$hide>>$

+

+    private ITask mTask;

+

+    /**

+     * 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 static ProgressTask start(Shell parent, String title, ITask task) {

+        ProgressTask t = new ProgressTask(parent);

+        t.setText(title);

+        t.setTask(task);

+        t.open();

+        return t;

+    }

+

+    /**

+     * Sets the description in the current task dialog.

+     * This method can be invoke from a non-UI thread.

+     */

+    public void setDescription(final String descriptionFormat, final Object...args) {

+        mDialogShell.getDisplay().asyncExec(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 invoke from a non-UI thread.

+     */

+    public void setResult(final String resultFormat, final Object...args) {

+        mAutomaticallyCloseOnTaskCompletion = false;

+        if (!mDialogShell.isDisposed()) {

+            mDialogShell.getDisplay().asyncExec(new Runnable() {

+                public void run() {

+                    if (!mResultText.isDisposed()) {

+                        mResultText.setVisible(true);

+                        mResultText.setText(String.format(resultFormat, args));

+                    }

+                }

+            });

+        }

+    }

+

+    /**

+     * Sets the max value of the progress bar.

+     * This method can be invoke from a non-UI thread.

+     *

+     * @see ProgressBar#setMaximum(int)

+     */

+    public void setProgressMax(final int max) {

+        if (!mDialogShell.isDisposed()) {

+            mDialogShell.getDisplay().asyncExec(new Runnable() {

+                public void run() {

+                    if (!mProgressBar.isDisposed()) {

+                        mProgressBar.setMaximum(max);

+                    }

+                }

+            });

+        }

+    }

+

+    /**

+     * Increments the current value of the progress bar.

+     *

+     * This method can be invoked from a non-UI thread.

+     */

+    public void incProgress(final int delta) {

+        if (!mDialogShell.isDisposed()) {

+            mDialogShell.getDisplay().asyncExec(new Runnable() {

+                public void run() {

+                    if (!mProgressBar.isDisposed()) {

+                        mProgressBar.setSelection(mProgressBar.getSelection() + delta);

+                    }

+                }

+            });

+        }

+    }

+

+    /**

+     * Returns true if the "Cancel" button was selected.

+     * It is up to the task thread to pool this and exit.

+     */

+    public boolean cancelRequested() {

+        return mCancelRequested;

+    }

+

+    /** Sets the task that will execute in a separate thread. */

+    private void setTask(ITask task) {

+        mTask = task;

+    }

+

+    /**

+     * Starts the task from {@link #setTask(ITask)} in a separate thread.

+     * When the task completes, set {@link #mCloseRequested} to end the dialog loop.

+     */

+    private void startTask() {

+        if (mTask != null) {

+            new Thread(getText()) {

+                @Override

+                public void run() {

+                    mTask.run(ProgressTask.this);

+                    if (mAutomaticallyCloseOnTaskCompletion) {

+                        mCloseRequested = true;

+                    }

+                }

+            }.start();

+        }

+    }

+

+    // End of hiding from SWT Designer

+    //$hide<<$

+}

diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTaskFactory.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTaskFactory.java
new file mode 100755
index 0000000..ceb701e
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ProgressTaskFactory.java
@@ -0,0 +1,39 @@
+/*

+ * 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.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 class ProgressTaskFactory implements ITaskFactory {

+

+    private final Shell mShell;

+

+    public ProgressTaskFactory(Shell shell) {

+        mShell = shell;

+    }

+

+    public void start(String title, ITask task) {

+        ProgressTask.start(mShell, title, task);

+    }

+}

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
new file mode 100755
index 0000000..1fe5ca4
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java
@@ -0,0 +1,242 @@
+/*

+ * 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 org.eclipse.jface.viewers.CheckStateChangedEvent;

+import org.eclipse.jface.viewers.CheckboxTreeViewer;

+import org.eclipse.jface.viewers.DoubleClickEvent;

+import org.eclipse.jface.viewers.ICheckStateListener;

+import org.eclipse.jface.viewers.IDoubleClickListener;

+import org.eclipse.jface.viewers.ISelection;

+import org.eclipse.jface.viewers.ITreeSelection;

+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;

+

+/*

+ * TODO list

+ * - check source => toggle packages: all, none

+ * - check package => set source check to tri-state

+ * - check callback => install enable if has selection

+ * - select tree item: delete site enable if add-on source

+ * - select tree item: refresh enable if source

+ * - load add-on sites from pref

+ * - delete site callback, update pref

+ * - refresh callback

+ * - install selected callback

+ */

+

+public class RemotePackagesPage extends Composite {

+

+    private final UpdaterWindowImpl mUpdaterWindow;

+    private final UpdaterData mUpdaterData;

+

+    private CheckboxTreeViewer mTreeViewerSources;

+    private Tree mTreeSources;

+    private TreeColumn mColumnSource;

+    private Group mDescriptionContainer;

+    private Button mAddSiteButton;

+    private Button mRemoveSiteButton;

+    private Label mPlaceholder3;

+    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}. If null, a local

+     *        one will be allocated just to help with the SWT Designer.

+     * @param updaterWindow The parent window.

+     */

+    RemotePackagesPage(Composite parent,

+            UpdaterData updaterData,

+            UpdaterWindowImpl updaterWindow) {

+        super(parent, SWT.BORDER);

+        mUpdaterWindow = updaterWindow;

+

+        mUpdaterData = updaterData != null ? updaterData : new UpdaterData();

+

+        createContents(this);

+        postCreate();  //$hide$

+    }

+

+    private void createContents(Composite parent) {

+        parent.setLayout(new GridLayout(5, false));

+

+        mTreeViewerSources = new CheckboxTreeViewer(parent, SWT.BORDER);

+        mTreeViewerSources.addDoubleClickListener(new IDoubleClickListener() {

+            public void doubleClick(DoubleClickEvent event) {

+                onTreeDoubleClick(event); //$hide$

+            }

+        });

+        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("Sources, 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...");

+

+        mRemoveSiteButton = new Button(parent, SWT.NONE);

+        mRemoveSiteButton.setText("Delete Site...");

+

+        mPlaceholder3 = new Label(parent, SWT.NONE);

+        mPlaceholder3.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1));

+

+        mRefreshButton = new Button(parent, SWT.NONE);

+        mRefreshButton.setText("Refresh");

+

+        mInstallSelectedButton = new Button(parent, SWT.NONE);

+        mInstallSelectedButton.addSelectionListener(new SelectionAdapter() {

+            @Override

+            public void widgetSelected(SelectionEvent e) {

+                onInstallSelectedArchives();  //$hide$

+            }

+        });

+        mInstallSelectedButton.setText("Install Selected");

+    }

+

+    @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>>$

+

+    /**

+     * Must be called once to set the adapter input for the sources tree viewer.

+     */

+    public void setInput(RepoSourcesAdapter sources) {

+        mTreeViewerSources.setContentProvider(sources.getContentProvider());

+        mTreeViewerSources.setLabelProvider(  sources.getLabelProvider());

+        mTreeViewerSources.setInput(sources);

+        onTreeSelected();

+    }

+

+    /**

+     * Called by the constructor right after {@link #createContents(Composite)}.

+     */

+    private void postCreate() {

+        adjustColumnsWidth();

+    }

+

+    /**

+     * 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

+        mTreeSources.addControlListener(new ControlAdapter() {

+            @Override

+            public void controlResized(ControlEvent e) {

+                Rectangle r = mTreeSources.getClientArea();

+                mColumnSource.setWidth(r.width);

+            }

+        });

+    }

+

+    /**

+     * 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() {

+        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-$

+    }

+

+    private void onTreeCheckStateChanged(CheckStateChangedEvent event) {

+        boolean b = event.getChecked();

+        Object elem = event.getElement(); // Will be Archive or Package or RepoSource

+        Object src = event.getSource();

+        // TODO

+    }

+

+    private void onTreeDoubleClick(DoubleClickEvent event) {

+        // TODO

+    }

+

+    private void onInstallSelectedArchives() {

+

+        ArrayList<Archive> archives = new ArrayList<Archive>();

+        for (Object element : mTreeViewerSources.getCheckedElements()) {

+            if (element instanceof Archive) {

+                archives.add((Archive) element);

+            }

+        }

+

+        mUpdaterWindow.installArchives(archives);

+    }

+

+    // 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
new file mode 100755
index 0000000..3f020d1
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java
@@ -0,0 +1,157 @@
+/*

+ * 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.sdklib.internal.repository.RepoSources;

+

+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;

+

+/**

+ * A list of sdk-repository sources.

+ *

+ * This implementation is UI dependent.

+ */

+class RepoSourcesAdapter {

+

+    private final RepoSources mRepoSources;

+

+    public RepoSourcesAdapter(RepoSources repoSources) {

+        mRepoSources = repoSources;

+    }

+

+    public ILabelProvider getLabelProvider() {

+        return new ViewerLabelProvider();

+    }

+

+

+    public IContentProvider getContentProvider() {

+        return new TreeContentProvider();

+    }

+

+    // ------------

+

+    public static class ViewerLabelProvider extends LabelProvider {

+        /** Returns null by default */

+        @Override

+        public Image getImage(Object 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 static class TreeContentProvider implements ITreeContentProvider {

+

+        private RepoSourcesAdapter mInput;

+

+        // 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 == null || newInput instanceof RepoSourcesAdapter;

+            mInput = (RepoSourcesAdapter) newInput;

+            // pass

+        }

+

+        /**

+         * 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 instanceof RepoSourcesAdapter) {

+                return ((RepoSourcesAdapter) parentElement).mRepoSources.getSources().toArray();

+

+            } else if (parentElement instanceof RepoSource) {

+                RepoSource source = (RepoSource) parentElement;

+                Package[] packages = source.getPackages();

+

+                if (packages == null) {

+                    source.load(mInput.mRepoSources.getTaskFactory());

+                    packages = source.getPackages();

+                }

+                if (packages != null) {

+                    return packages;

+                }

+

+            } else if (parentElement instanceof Package) {

+                return ((Package) parentElement).getArchives();

+            }

+

+            return new Object[0];

+        }

+

+        /**

+         * 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 mInput;

+

+            } else if (element instanceof Package) {

+                return ((Package) element).getParentSource();

+            }

+            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;

+        }

+    }

+

+}

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
new file mode 100755
index 0000000..384ff57
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java
@@ -0,0 +1,67 @@
+/*

+ * 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.LocalSdkParser;

+import com.android.sdklib.internal.repository.RepoSources;

+

+/**

+ * Data shared between {@link UpdaterWindowImpl} and its pages.

+ */

+class UpdaterData {

+    private String mOsSdkRoot;

+    private boolean mUserCanChangeSdkRoot;

+

+    private final LocalSdkParser mLocalSdkParser = new LocalSdkParser();

+    private final RepoSources mSources = new RepoSources();

+

+    private final LocalSdkAdapter mLocalSdkAdapter = new LocalSdkAdapter(mLocalSdkParser);

+    private final RepoSourcesAdapter mSourcesAdapter = new RepoSourcesAdapter(mSources);

+

+    public void setOsSdkRoot(String osSdkRoot) {

+        mOsSdkRoot = osSdkRoot;

+    }

+

+    public String getOsSdkRoot() {

+        return mOsSdkRoot;

+    }

+

+    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;

+    }

+

+}

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
new file mode 100755
index 0000000..2a3ff90
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java
@@ -0,0 +1,430 @@
+/*

+ * 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.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.repository.SdkRepository;

+

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.SWTException;

+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.Image;

+import org.eclipse.swt.graphics.ImageData;

+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.io.File;

+import java.io.FileOutputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.net.URL;

+import java.security.MessageDigest;

+import java.util.ArrayList;

+import java.util.Collection;

+

+/**

+ * This is the private implementation of the UpdateWindow.

+ */

+public class UpdaterWindowImpl {

+

+    private static final int NUM_FETCH_URL_MONITOR_INC = 10;

+

+    private final UpdaterData mUpdaterData = new UpdaterData();

+    private ArrayList<Composite> mPages = new ArrayList<Composite>();

+    private boolean mInternalPageChange;

+

+    // --- UI members ---

+

+    protected Shell mAndroidSdkUpdater;

+    private SashForm mSashForm;

+    private List mPageList;

+    private Composite mPagesRootComposite;

+    private LocalPackagesPage mLocalPackagePage;

+    private RemotePackagesPage mRemotePackagesPage;

+    private StackLayout mStackLayout;

+    private Image mIconImage;

+    private ProgressTaskFactory mTaskFactory;

+

+    public UpdaterWindowImpl(String osSdkRoot, boolean userCanChangeSdkRoot) {

+        mUpdaterData.setOsSdkRoot(osSdkRoot);

+        mUpdaterData.setUserCanChangeSdkRoot(userCanChangeSdkRoot);

+    }

+

+    /**

+     * Open the window.

+     * @wbp.parser.entryPoint

+     */

+    public void open() {

+        Display display = Display.getDefault();

+        createContents();

+        mAndroidSdkUpdater.open();

+        mAndroidSdkUpdater.layout();

+

+        firstInit();    //$hide$ (hide from SWT designer)

+

+        while (!mAndroidSdkUpdater.isDisposed()) {

+            if (!display.readAndDispatch()) {

+                display.sleep();

+            }

+        }

+    }

+

+    /**

+     * Create contents of the window.

+     */

+    protected void createContents() {

+        mAndroidSdkUpdater = new Shell();

+        setWindowImage(mAndroidSdkUpdater);

+        mAndroidSdkUpdater.addDisposeListener(new DisposeListener() {

+            public void widgetDisposed(DisposeEvent e) {

+                onAndroidSdkUpdaterDispose();    //$hide$ (hide from SWT designer)

+            }

+        });

+

+        mAndroidSdkUpdater.setLayout(new FillLayout(SWT.HORIZONTAL));

+        mAndroidSdkUpdater.setMinimumSize(new Point(200, 50));

+        mAndroidSdkUpdater.setSize(745, 433);

+        mAndroidSdkUpdater.setText("Android SDK Updater");

+

+        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);

+

+        mLocalPackagePage = new LocalPackagesPage(mPagesRootComposite, mUpdaterData);

+        mRemotePackagesPage = new RemotePackagesPage(mPagesRootComposite, mUpdaterData, this);

+        mSashForm.setWeights(new int[] {150, 576});

+    }

+

+

+    // -- Start of internal part ----------

+    // Hide everything down-below from SWT designer

+    //$hide>>$

+

+    // --- UI Callbacks -----------

+

+    private void onAndroidSdkUpdaterDispose() {

+        if (mIconImage != null) {

+            mIconImage.dispose();

+            mIconImage = null;

+        }

+    }

+

+    private void setWindowImage(Shell androidSdkUpdater) {

+        InputStream stream = getClass().getResourceAsStream("android_icon_16.png");  //$NON-NLS-1$

+        if (stream != null) {

+            try {

+                ImageData imgData = new ImageData(stream);

+                mIconImage = new Image(mAndroidSdkUpdater.getDisplay(),

+                        imgData,

+                        imgData.getTransparencyMask());

+                mAndroidSdkUpdater.setImage(mIconImage);

+            } catch (SWTException e) {

+                // ignore

+            } catch (IllegalArgumentException e) {

+                // ignore

+            }

+        }

+    }

+

+    private Shell getShell() {

+        return mAndroidSdkUpdater;

+    }

+

+    /**

+     * Once the UI has been created, initialize the content

+     */

+    private void firstInit() {

+        mTaskFactory = new ProgressTaskFactory(getShell());

+

+        addPage(mLocalPackagePage, "Installed Packages");

+        addPage(mRemotePackagesPage, "Available Packages");

+        displayPage(0);

+        mPageList.setSelection(0);

+

+        setupSources();

+        scanLocalSdkFolders();

+    }

+

+    // --- page switching ---

+

+    private void addPage(Composite page, String title) {

+        page.setData(title);

+        mPages.add(page);

+        mPageList.add(title);

+    }

+

+    private void onPageListSelected() {

+        if (mInternalPageChange == false) {

+            int index = mPageList.getSelectionIndex();

+            if (index >= 0) {

+                displayPage(index);

+            }

+        }

+    }

+

+    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;

+            }

+        }

+    }

+

+    private void setupSources() {

+        mUpdaterData.getSources().setTaskFactory(mTaskFactory);

+

+        mUpdaterData.getSources().add(

+                new RepoSource(SdkRepository.URL_GOOGLE_SDK_REPO_SITE, false /* addonOnly */));

+

+        String url = System.getenv("TEMP_SDK_URL"); // TODO STOPSHIP temporary remove before shipping

+        if (url != null) {

+            mUpdaterData.getSources().add(new RepoSource(url, false /* addonOnly */));

+        }

+

+        mRemotePackagesPage.setInput(mUpdaterData.getSourcesAdapter());

+    }

+

+    private void scanLocalSdkFolders() {

+        mUpdaterData.getLocalSdkAdapter().setSdkRoot(mUpdaterData.getOsSdkRoot());

+

+        mLocalPackagePage.setInput(mUpdaterData.getLocalSdkAdapter());

+    }

+

+    public void installArchives(final Collection<Archive> archives) {

+        // TODO move most parts to SdkLib, maybe as part of Archive, making archives self-installing.

+        mTaskFactory.start("Installing Archives", new ITask() {

+            public void run(ITaskMonitor monitor) {

+

+                monitor.setProgressMax(archives.size() * (NUM_FETCH_URL_MONITOR_INC + 3));

+                monitor.setDescription("Preparing to install archives");

+

+                int num_installed = 0;

+                for (Archive archive : archives) {

+

+                    if (!archive.isCompatible()) {

+                        monitor.setResult("Skipping incompatible archive: %1$s",

+                                archive.getShortDescription());

+                        monitor.incProgress(3);

+                        continue;

+                    }

+

+                    File archiveFile = null;

+                    try {

+                        archiveFile = downloadArchive(archive, monitor);

+                        monitor.incProgress(1);

+                        if (archiveFile != null) {

+                            if (installArchive(archive, archiveFile, monitor)) {

+                                num_installed++;

+                            }

+                        }

+                        monitor.incProgress(1);

+                    } finally {

+                        if (archiveFile != null) {

+                            if (!archiveFile.delete()) {

+                                archiveFile.deleteOnExit();

+                            }

+                        }

+                    }

+                }

+

+                if (num_installed == 0) {

+                    monitor.setResult("Nothing was installed.");

+                }

+            }

+        });

+    }

+

+    /**

+     * Downloads an archive and returns the temp file with it.

+     * Caller is responsible with deleting the temp file when done.

+     */

+    private File downloadArchive(Archive archive, ITaskMonitor monitor) {

+

+        try {

+            File tmpFile = File.createTempFile("sdkupload", "bin"); //$NON-NLS-1$ //$NON-NLS-2$

+

+            monitor.setDescription("Downloading %1$s", archive.getShortDescription());

+

+            String link = archive.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 = archive.getParentPackage();

+                RepoSource src = pkg.getParentSource();

+                if (src == null) {

+                    monitor.setResult("Internal error: no source for archive %1$s",

+                            archive.getShortDescription());

+                    return null;

+                }

+

+                String base = src.getUrl();

+                if (!base.endsWith("/") && !link.startsWith("/")) {  //$NON-NLS-1$ //$NON-NLS-2$

+                    base += "/";                                     //$NON-NLS-1$

+                }

+

+                link = base + link;

+            }

+

+            fetchUrl(tmpFile, archive, link, monitor);

+

+        } catch (IOException e) {

+            monitor.setResult(e.getMessage());

+        }

+        return null;

+    }

+

+    /**

+     * 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_FETCH_URL_MONITOR_INC} (which is 10).

+     */

+    private boolean fetchUrl(File tmpFile, Archive archive, String urlString, ITaskMonitor monitor) {

+        URL url;

+

+        FileOutputStream os = null;

+        InputStream is = null;

+        try {

+            url = new URL(urlString);

+            is = url.openStream();

+            os = new FileOutputStream(tmpFile);

+

+            MessageDigest digester = archive.getChecksumType().getMessageDigest();

+

+            byte[] buf = new byte[65536];

+            int n;

+

+            long total = 0;

+            long size = archive.getSize();

+            long inc = size / NUM_FETCH_URL_MONITOR_INC;

+            long next_inc = inc;

+

+            while ((n = is.read(buf)) >= 0) {

+                if (n > 0) {

+                    os.write(buf, 0, n);

+                    digester.update(buf, 0, n);

+                }

+

+                total += n;

+                if (total >= next_inc) {

+                    monitor.incProgress(1);

+                    next_inc += inc;

+                }

+

+                if (monitor.cancelRequested()) {

+                    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

+            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++) {

+                byte b = digest[i];

+                hexDigest[i*2 + 0] = hex.charAt(b >>> 4);

+                hexDigest[i*2 + 1] = hex.charAt(b & 0x0f);

+            }

+

+            String expected = archive.getChecksum();

+            String actual   = new String(hexDigest);

+            if (!actual.equalsIgnoreCase(expected)) {

+                monitor.setResult("Download finished with wrong checksum. Expected %1$s, got %2$s.",

+                        expected, actual);

+                return false;

+            }

+

+            return true;

+

+        } 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;

+    }

+

+    private boolean installArchive(Archive archive, File archiveFile, ITaskMonitor monitor) {

+        monitor.setDescription("Installing %1$s", archive.getShortDescription());

+

+        File destFolder = archive.getParentPackage().getInstallFolder(mUpdaterData.getOsSdkRoot());

+

+        return false;

+    }

+

+    // End of hiding from SWT Designer

+    //$hide<<$

+}

diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/android_icon_16.png b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/android_icon_16.png
new file mode 100755
index 0000000..0b0744b
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/android_icon_16.png
Binary files differ
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
new file mode 100755
index 0000000..0d067ae
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/repository/UpdaterWindow.java
@@ -0,0 +1,46 @@
+/*

+ * 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.sdkuilib.internal.repository.UpdaterWindowImpl;

+

+/**

+ * Opens an SDK Updater Window.

+ *

+ * This is the public interface for using the window.

+ */

+public class UpdaterWindow {

+

+    private UpdaterWindowImpl mWindow;

+

+    /**

+     * Creates a new window. Caller must call open(), which will block.

+     * @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(String osSdkRoot, boolean userCanChangeSdkRoot) {

+        mWindow = new UpdaterWindowImpl(osSdkRoot, userCanChangeSdkRoot);

+    }

+

+    /**

+     * Opens the window.

+     */

+    public void open() {

+        mWindow.open();

+    }

+}

diff --git a/tools/sdkstats/.gitignore b/tools/sdkstats/.gitignore
new file mode 100644
index 0000000..fe99505
--- /dev/null
+++ b/tools/sdkstats/.gitignore
@@ -0,0 +1,2 @@
+bin
+
diff --git a/tools/sdkstats/src/com/android/sdkstats/SdkStatsService.java b/tools/sdkstats/src/com/android/sdkstats/SdkStatsService.java
index 0b3d41b..688474e 100644
--- a/tools/sdkstats/src/com/android/sdkstats/SdkStatsService.java
+++ b/tools/sdkstats/src/com/android/sdkstats/SdkStatsService.java
@@ -110,8 +110,10 @@
      *
      * @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) {
+    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);
 
@@ -123,7 +125,7 @@
                 prefs.setValue(PING_ID, new Random().nextLong());
     
                 // Also give them a chance to opt out.
-                prefs.setValue(PING_OPT_IN, getUserPermission());
+                prefs.setValue(PING_OPT_IN, getUserPermission(display));
                 try {
                     prefs.save();
                 }
@@ -273,77 +275,90 @@
      * 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() {
-        // Use dialog trim for the shell, but without a close button.
-        final Display display = new Display();
-        final Shell shell = new Shell(display, 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(display, 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(display, 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);
-
+    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 };
 
-        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();
+        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();
+                }
             }
         });
 
-        // Size the window to a fixed width, as high as necessary, centered.
-        final Point size = shell.computeSize(450, SWT.DEFAULT, true);
-        final Rectangle screen = display.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 (!display.readAndDispatch())
-                display.sleep();
-        }
-
-        display.dispose();  // Otherwise ddms' own Display can't be created
         return permission[0];
     }
 
diff --git a/tools/traceview/.gitignore b/tools/traceview/.gitignore
new file mode 100644
index 0000000..ba077a4
--- /dev/null
+++ b/tools/traceview/.gitignore
@@ -0,0 +1 @@
+bin
diff --git a/tools/traceview/src/com/android/traceview/MainWindow.java b/tools/traceview/src/com/android/traceview/MainWindow.java
index b0c24e9..5800f81 100644
--- a/tools/traceview/src/com/android/traceview/MainWindow.java
+++ b/tools/traceview/src/com/android/traceview/MainWindow.java
@@ -133,7 +133,7 @@
         boolean regression = false;
         
         // ping the usage server
-        SdkStatsService.ping(PING_NAME, PING_VERSION);
+        SdkStatsService.ping(PING_NAME, PING_VERSION, null);
 
         // Process command line arguments
         int argc = 0;
diff --git a/tools/yuv420sp2rgb/Android.mk b/tools/yuv420sp2rgb/Android.mk
new file mode 100644
index 0000000..b7e7802
--- /dev/null
+++ b/tools/yuv420sp2rgb/Android.mk
@@ -0,0 +1,16 @@
+# Copyright 2005 Google Inc. All Rights Reserved.
+#
+# Android.mk for yuv420sp2rgb 
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(TARGET_ARCH),arm)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := yuv420sp2rgb.c cmdline.c debug.c
+
+LOCAL_MODULE := yuv420sp2rgb
+
+include $(BUILD_HOST_EXECUTABLE)
+endif
diff --git a/tools/yuv420sp2rgb/cmdline.c b/tools/yuv420sp2rgb/cmdline.c
new file mode 100644
index 0000000..eb870b5
--- /dev/null
+++ b/tools/yuv420sp2rgb/cmdline.c
@@ -0,0 +1,147 @@
+#include <debug.h>
+#include <cmdline.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <string.h>
+#include <ctype.h>
+
+extern char *optarg;
+extern int optind, opterr, optopt;
+
+static struct option long_options[] = {
+    {"output",  required_argument, 0, 'o'},
+    {"height",  required_argument, 0, 'h'},
+    {"width",   required_argument, 0, 'w'},
+    {"gray",    no_argument,       0, 'g'},
+    {"type",    required_argument, 0, 't'},
+    {"rotate",  required_argument, 0, 'r'},
+    {"verbose", no_argument,       0, 'V'},
+    {"help",    no_argument,       0, 1},
+    {0, 0, 0, 0},
+};
+
+/* This array must parallel long_options[] */
+static const char *descriptions[] = {
+    "output file",
+    "image height in pixels",
+    "image width in pixels",
+    "process the luma plane only",
+    "encode as one of { 'ppm', 'rgb', or 'argb' }",
+    "rotate (90, -90, 180 degrees)",
+    "print verbose output",
+    "print this help screen",
+};
+
+void print_help(const char *name) {
+    fprintf(stdout,
+            "Converts yuv 4:2:0 to rgb24 and generates a PPM file.\n"
+            "invokation:\n"
+            "\t%s infile --height <height> --width <width> --output <outfile> -t <ppm|grb|argb> [ --gray ] [ --rotate <degrees> ] [ --verbose ]\n"
+            "\t%s infile --help\n",
+            name, name);
+    fprintf(stdout, "options:\n");
+    struct option *opt = long_options;
+    const char **desc = descriptions;
+    while (opt->name) {
+        fprintf(stdout, "\t-%c/--%s%s: %s\n",
+                isprint(opt->val) ? opt->val : ' ',
+                opt->name,
+                (opt->has_arg ? " (argument)" : ""),
+                *desc);
+        opt++;
+        desc++;
+    }
+}
+
+int get_options(int argc, char **argv,
+                char **outfile,
+                int *height,
+                int *width,
+                int *gray,
+                char **type,
+                int *rotate,
+                int *verbose) {
+    int c;
+
+    ASSERT(outfile); *outfile = NULL;
+    ASSERT(height); *height = -1;
+    ASSERT(width); *width = -1;
+    ASSERT(gray); *gray = 0;
+    ASSERT(rotate); *rotate = 0;
+    ASSERT(verbose); *verbose = 0;
+    ASSERT(type); *type = NULL;
+
+    while (1) {
+        /* getopt_long stores the option index here. */
+        int option_index = 0;
+
+        c = getopt_long (argc, argv,
+                         "Vgo:h:w:r:t:",
+                         long_options,
+                         &option_index);
+        /* Detect the end of the options. */
+        if (c == -1) break;
+
+        if (isgraph(c)) {
+            INFO ("option -%c with value `%s'\n", c, (optarg ?: "(null)"));
+        }
+
+#define SET_STRING_OPTION(name) do {                                   \
+    ASSERT(optarg);                                                    \
+    (*name) = strdup(optarg);                                          \
+} while(0)
+
+#define SET_INT_OPTION(val) do {                                       \
+    ASSERT(optarg);                                                    \
+	if (strlen(optarg) >= 2 && optarg[0] == '0' && optarg[1] == 'x') { \
+			FAILIF(1 != sscanf(optarg+2, "%x", val),                   \
+				   "Expecting a hexadecimal argument!\n");             \
+	} else {                                                           \
+		FAILIF(1 != sscanf(optarg, "%d", val),                         \
+			   "Expecting a decimal argument!\n");                     \
+	}                                                                  \
+} while(0)
+
+        switch (c) {
+        case 0:
+            /* If this option set a flag, do nothing else now. */
+            if (long_options[option_index].flag != 0)
+                break;
+            INFO ("option %s", long_options[option_index].name);
+            if (optarg)
+                INFO (" with arg %s", optarg);
+            INFO ("\n");
+            break;
+        case 1: print_help(argv[0]); exit(1); break;
+		case 'o':
+			SET_STRING_OPTION(outfile);
+			break;
+		case 't':
+			SET_STRING_OPTION(type);
+			break;
+        case 'h':
+            SET_INT_OPTION(height);
+            break;
+        case 'w':
+            SET_INT_OPTION(width);
+            break;
+        case 'r':
+            SET_INT_OPTION(rotate);
+            break;
+        case 'g': *gray = 1; break;
+        case 'V': *verbose = 1; break;
+        case '?':
+            /* getopt_long already printed an error message. */
+            break;
+
+#undef SET_STRING_OPTION
+#undef SET_INT_OPTION
+
+        default:
+            FAILIF(1, "Unknown option");
+        }
+    }
+
+    return optind;
+}
diff --git a/tools/yuv420sp2rgb/cmdline.h b/tools/yuv420sp2rgb/cmdline.h
new file mode 100644
index 0000000..49760ad
--- /dev/null
+++ b/tools/yuv420sp2rgb/cmdline.h
@@ -0,0 +1,15 @@
+#ifndef CMDLINE_H
+#define CMDLINE_H
+
+void print_help(const char *executable_name);
+
+extern int get_options(int argc, char **argv,
+                       char **outfile,
+                       int *height,
+                       int *width,
+                       int *gray,
+                       char **type,
+                       int *rotate,
+                       int *verbose);
+
+#endif/*CMDLINE_H*/
diff --git a/tools/yuv420sp2rgb/debug.c b/tools/yuv420sp2rgb/debug.c
new file mode 100644
index 0000000..263e09f
--- /dev/null
+++ b/tools/yuv420sp2rgb/debug.c
@@ -0,0 +1,38 @@
+#include <debug.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#define NUM_COLS  (32)
+
+int dump_hex_buffer(FILE *s, void *b, size_t len, size_t elsize) {
+    int num_nonprintable = 0;
+    int i, last;
+    char *pchr = (char *)b;
+    fputc('\n', s);
+    fprintf(s, "%p: ", b);
+    for (i = last = 0; i < len; i++) {
+        if (!elsize) {
+            if (i && !(i % 4)) fprintf(s, " ");
+            if (i && !(i % 8)) fprintf(s, " ");
+        } else {
+            if (i && !(i % elsize)) fprintf(s, " ");
+        }
+
+        if (i && !(i % NUM_COLS)) {
+            while (last < i) {
+                if (isprint(pchr[last]))
+                    fputc(pchr[last], s);
+                else {
+                    fputc('.', s); 
+                    num_nonprintable++;
+                }
+                last++;
+            }
+            fprintf(s, " (%d)\n%p: ", i, b);
+        }
+        fprintf(s, "%02x", (unsigned char)pchr[i]);
+    }
+    if (i && (i % NUM_COLS)) fputs("\n", s);
+    return num_nonprintable;
+}
+
diff --git a/tools/yuv420sp2rgb/debug.h b/tools/yuv420sp2rgb/debug.h
new file mode 100644
index 0000000..9bbf47f
--- /dev/null
+++ b/tools/yuv420sp2rgb/debug.h
@@ -0,0 +1,90 @@
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define unlikely(expr) __builtin_expect (expr, 0)
+#define likely(expr)   __builtin_expect (expr, 1)
+
+#ifdef DEBUG
+
+    #define FAILIF(cond, msg...) do {                        \
+	if (unlikely(cond)) {                                \
+        fprintf(stderr, "%s(%d): ", __FILE__, __LINE__); \
+		fprintf(stderr, ##msg);                          \
+		exit(1);                                         \
+	}                                                    \
+} while(0)
+
+/* Debug enabled */
+    #define ASSERT(x) do {                                \
+	if (unlikely(!(x))) {                             \
+		fprintf(stderr,                               \
+				"ASSERTION FAILURE %s:%d: [%s]\n",    \
+				__FILE__, __LINE__, #x);              \
+		exit(1);                                      \
+	}                                                 \
+} while(0)
+
+#else
+
+    #define FAILIF(cond, msg...) do { \
+	if (unlikely(cond)) {         \
+		fprintf(stderr, ##msg);   \
+		exit(1);                  \
+	}                             \
+} while(0)
+
+/* No debug */
+    #define ASSERT(x)   do { } while(0)
+
+#endif/* DEBUG */
+
+#define FAILIF_LIBELF(cond, function) \
+    FAILIF(cond, "%s(): %s\n", #function, elf_errmsg(elf_errno()));
+
+static inline void *MALLOC(unsigned int size) {
+    void *m = malloc(size);
+    FAILIF(NULL == m, "malloc(%d) failed!\n", size);
+    return m;
+}
+
+static inline void *CALLOC(unsigned int num_entries, unsigned int entry_size) {
+    void *m = calloc(num_entries, entry_size);
+    FAILIF(NULL == m, "calloc(%d, %d) failed!\n", num_entries, entry_size);
+    return m;
+}
+
+static inline void *REALLOC(void *ptr, unsigned int size) {
+    void *m = realloc(ptr, size);
+    FAILIF(NULL == m, "realloc(%p, %d) failed!\n", ptr, size);
+    return m;
+}
+
+static inline void FREE(void *ptr) {
+    free(ptr);
+}
+
+static inline void FREEIF(void *ptr) {
+    if (ptr) FREE(ptr);
+}
+
+#define PRINT(x...)  do {                             \
+    extern int quiet_flag;                            \
+    if(likely(!quiet_flag))                           \
+        fprintf(stdout, ##x);                         \
+} while(0)
+
+#define ERROR PRINT
+
+#define INFO(x...)  do {                              \
+    extern int verbose_flag;                          \
+    if(unlikely(verbose_flag))                        \
+        fprintf(stdout, ##x);                         \
+} while(0)
+
+/* Prints a hex and ASCII dump of the selected buffer to the selected stream. */
+int dump_hex_buffer(FILE *s, void *b, size_t l, size_t elsize);
+
+#endif/*DEBUG_H*/
diff --git a/tools/yuv420sp2rgb/yuv420sp2rgb.c b/tools/yuv420sp2rgb/yuv420sp2rgb.c
new file mode 100644
index 0000000..6fe82e5
--- /dev/null
+++ b/tools/yuv420sp2rgb/yuv420sp2rgb.c
@@ -0,0 +1,339 @@
+#include <stdio.h>
+#include <debug.h>
+#include <cmdline.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#ifndef max
+#define max(a,b) ({typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b; })
+#define min(a,b) ({typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; })
+#endif
+
+#define CONVERT_TYPE_PPM 0
+#define CONVERT_TYPE_RGB 1
+#define CONVERT_TYPE_ARGB 2
+
+/*
+   YUV 4:2:0 image with a plane of 8 bit Y samples followed by an interleaved
+   U/V plane containing 8 bit 2x2 subsampled chroma samples.
+   except the interleave order of U and V is reversed.
+
+                        H V
+   Y Sample Period      1 1
+   U (Cb) Sample Period 2 2
+   V (Cr) Sample Period 2 2
+ */
+
+typedef struct rgb_context {
+    unsigned char *buffer;
+    int width;
+    int height;
+    int rotate;
+    int i;
+    int j;
+    int size; /* for debugging */
+} rgb_context;
+
+typedef void (*rgb_cb)(
+    unsigned char r,
+    unsigned char g,
+    unsigned char b,
+    rgb_context *ctx);
+
+const int bytes_per_pixel = 2;
+
+static void color_convert_common(
+    unsigned char *pY, unsigned char *pUV,
+    int width, int height,
+    unsigned char *buffer,
+    int size, /* buffer size in bytes */
+    int gray,
+    int rotate,
+    rgb_cb cb) 
+{
+	int i, j;
+	int nR, nG, nB;
+	int nY, nU, nV;
+    rgb_context ctx;
+
+    ctx.buffer = buffer;
+    ctx.size = size; /* debug */
+    ctx.width = width;
+    ctx.height = height;
+    ctx.rotate = rotate;
+
+    if (gray) {
+        for (i = 0; i < height; i++) {
+            for (j = 0; j < width; j++) {
+                nB = *(pY + i * width + j);
+                ctx.i = i;
+                ctx.j = j;
+                cb(nB, nB, nB, &ctx);
+            }
+        }	
+    } else {
+        // YUV 4:2:0
+        for (i = 0; i < height; i++) {
+            for (j = 0; j < width; j++) {
+                nY = *(pY + i * width + j);
+                nV = *(pUV + (i/2) * width + bytes_per_pixel * (j/2));
+                nU = *(pUV + (i/2) * width + bytes_per_pixel * (j/2) + 1);
+            
+                // Yuv Convert
+                nY -= 16;
+                nU -= 128;
+                nV -= 128;
+            
+                if (nY < 0)
+                    nY = 0;
+            
+                // nR = (int)(1.164 * nY + 2.018 * nU);
+                // nG = (int)(1.164 * nY - 0.813 * nV - 0.391 * nU);
+                // nB = (int)(1.164 * nY + 1.596 * nV);
+            
+                nB = (int)(1192 * nY + 2066 * nU);
+                nG = (int)(1192 * nY - 833 * nV - 400 * nU);
+                nR = (int)(1192 * nY + 1634 * nV);
+            
+                nR = min(262143, max(0, nR));
+                nG = min(262143, max(0, nG));
+                nB = min(262143, max(0, nB));
+            
+                nR >>= 10; nR &= 0xff;
+                nG >>= 10; nG &= 0xff;
+                nB >>= 10; nB &= 0xff;
+
+                ctx.i = i;
+                ctx.j = j;
+                cb(nR, nG, nB, &ctx);
+            }
+        }
+    }
+}   
+
+static void rgb16_cb(
+    unsigned char r,
+    unsigned char g,
+    unsigned char b,
+    rgb_context *ctx)
+{
+    unsigned short *rgb16 = (unsigned short *)ctx->buffer;
+    *(rgb16 + ctx->i * ctx->width + ctx->j) = b | (g << 5) | (r << 11);
+}
+
+static void common_rgb_cb(
+    unsigned char r,
+    unsigned char g,
+    unsigned char b,
+    rgb_context *ctx,
+    int alpha)
+{
+    unsigned char *out = ctx->buffer;
+    int offset = 0;
+    int bpp;
+    int i = 0;
+    switch(ctx->rotate) {
+    case 0: /* no rotation */
+        offset = ctx->i * ctx->width + ctx->j;
+        break;
+    case 1: /* 90 degrees */
+        offset = ctx->height * (ctx->j + 1) - ctx->i;
+        break;
+    case 2: /* 180 degrees */
+        offset = (ctx->height - 1 - ctx->i) * ctx->width + ctx->j;
+        break;
+    case 3: /* 270 degrees */
+        offset = (ctx->width - 1 - ctx->j) * ctx->height + ctx->i;
+        break;
+    default:
+        FAILIF(1, "Unexpected roation value %d!\n", ctx->rotate);
+    }
+
+    bpp = 3 + !!alpha;
+    offset *= bpp;
+    FAILIF(offset < 0, "point (%d, %d) generates a negative offset.\n", ctx->i, ctx->j);
+    FAILIF(offset + bpp > ctx->size, "point (%d, %d) at offset %d exceeds the size %d of the buffer.\n",
+           ctx->i, ctx->j,
+           offset,
+           ctx->size);
+
+    out += offset;
+
+    if (alpha) out[i++] = 0xff;
+    out[i++] = r;
+    out[i++] = g;
+    out[i] = b;
+}
+
+static void rgb24_cb(
+    unsigned char r,
+    unsigned char g,
+    unsigned char b,
+    rgb_context *ctx)
+{
+    return common_rgb_cb(r,g,b,ctx,0);
+}
+
+static void argb_cb(
+    unsigned char r,
+    unsigned char g,
+    unsigned char b,
+    rgb_context *ctx)
+{
+    return common_rgb_cb(r,g,b,ctx,1);
+}
+
+static void convert(const char *infile,
+                    const char *outfile,
+                    int height,
+                    int width,
+                    int gray,
+                    int type,
+                    int rotate)
+{
+    void *in, *out;
+    int ifd, ofd, rc;
+    int psz = getpagesize();
+    static char header[1024];
+    int header_size;
+    size_t outsize;
+
+    int bpp = 3;
+    switch (type) {
+    case CONVERT_TYPE_PPM:
+        PRINT("encoding PPM\n");
+        if (rotate & 1)
+            header_size = snprintf(header, sizeof(header), "P6\n%d %d\n255\n", height, width);
+        else
+            header_size = snprintf(header, sizeof(header), "P6\n%d %d\n255\n", width, height);
+	break;
+    case CONVERT_TYPE_RGB:
+        PRINT("encoding raw RGB24\n");
+        header_size = 0;
+        break;
+    case CONVERT_TYPE_ARGB:
+        PRINT("encoding raw ARGB\n");
+        header_size = 0;
+        bpp = 4;
+        break;
+    }
+        
+    outsize = header_size + width * height * bpp;
+    outsize = (outsize + psz - 1) & ~(psz - 1);
+
+    INFO("Opening input file %s\n", infile);
+    ifd = open(infile, O_RDONLY);
+    FAILIF(ifd < 0, "open(%s) failed: %s (%d)\n",
+           infile, strerror(errno), errno);
+
+    INFO("Opening output file %s\n", outfile);
+    ofd = open(outfile, O_RDWR | O_CREAT, 0664);
+    FAILIF(ofd < 0, "open(%s) failed: %s (%d)\n",
+           outfile, strerror(errno), errno);
+    
+    INFO("Memory-mapping input file %s\n", infile);
+    in = mmap(0, width * height * 3 / 2, PROT_READ, MAP_PRIVATE, ifd, 0);
+    FAILIF(in == MAP_FAILED, "could not mmap input file: %s (%d)\n",
+           strerror(errno), errno);
+
+    INFO("Truncating output file %s to %d bytes\n", outfile, outsize);
+    FAILIF(ftruncate(ofd, outsize) < 0,
+           "Could not truncate output file to required size: %s (%d)\n",
+           strerror(errno), errno);
+
+    INFO("Memory mapping output file %s\n", outfile);
+    out = mmap(0, outsize, PROT_WRITE, MAP_SHARED, ofd, 0);
+    FAILIF(out == MAP_FAILED, "could not mmap output file: %s (%d)\n",
+           strerror(errno), errno);
+
+    INFO("PPM header (%d) bytes:\n%s\n", header_size, header);
+    FAILIF(write(ofd, header, header_size) != header_size,
+           "Error wrinting PPM header: %s (%d)\n",
+           strerror(errno), errno);
+
+    INFO("Converting %dx%d YUV 4:2:0 to RGB24...\n", width, height);
+    color_convert_common(in, in + width * height,
+                         width, height, 
+                         out + header_size, outsize - header_size,
+                         gray, rotate,
+                         type == CONVERT_TYPE_ARGB ? argb_cb : rgb24_cb);
+}
+
+int verbose_flag;
+int quiet_flag;
+
+int main(int argc, char **argv) {
+
+    char *infile, *outfile, *type;
+    int height, width, gray, rotate;
+    int cmdline_error = 0;
+
+    /* Parse command-line arguments. */
+    
+    int first = get_options(argc, argv,
+                            &outfile,
+                            &height,
+                            &width,
+                            &gray,
+                            &type,
+                            &rotate,
+                            &verbose_flag);
+
+    if (first == argc) {
+        ERROR("You must specify an input file!\n");
+        cmdline_error++;
+    }
+    if (!outfile) {
+        ERROR("You must specify an output file!\n");
+        cmdline_error++;
+    }
+    if (height < 0 || width < 0) {
+        ERROR("You must specify both image height and width!\n");
+        cmdline_error++;
+    }
+
+    FAILIF(rotate % 90, "Rotation angle must be a multiple of 90 degrees!\n");
+
+    rotate /= 90;
+    rotate %= 4;
+    if (rotate < 0) rotate += 4;
+
+    if (cmdline_error) {
+        print_help(argv[0]);
+        exit(1);
+    }
+
+    infile = argv[first];
+
+    INFO("input file: [%s]\n", infile);
+    INFO("output file: [%s]\n", outfile);
+    INFO("height: %d\n", height);
+    INFO("width: %d\n", width);
+    INFO("gray only: %d\n", gray);
+    INFO("encode as: %s\n", type);
+    INFO("rotation: %d\n", rotate);
+    
+    /* Convert the image */
+
+    int conv_type;
+    if (!type || !strcmp(type, "ppm"))
+        conv_type = CONVERT_TYPE_PPM;
+    else if (!strcmp(type, "rgb"))
+        conv_type = CONVERT_TYPE_RGB;
+    else if (!strcmp(type, "argb"))
+        conv_type = CONVERT_TYPE_ARGB;
+    else FAILIF(1, "Unknown encoding type %s.\n", type);
+    
+    convert(infile, outfile,
+            height, width, gray,
+            conv_type,
+            rotate);
+        
+    free(outfile);
+    return 0;
+}