diff --git a/tools/androidprefs/.classpath b/tools/androidprefs/.classpath
new file mode 100644
index 0000000..fb50116
--- /dev/null
+++ b/tools/androidprefs/.classpath
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/androidprefs/.project b/tools/androidprefs/.project
new file mode 100644
index 0000000..6633bba
--- /dev/null
+++ b/tools/androidprefs/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>AndroidPrefs</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/androidprefs/Android.mk b/tools/androidprefs/Android.mk
new file mode 100644
index 0000000..363b085
--- /dev/null
+++ b/tools/androidprefs/Android.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+JARUTILS_LOCAL_DIR := $(call my-dir)
+include $(JARUTILS_LOCAL_DIR)/src/Android.mk
diff --git a/tools/androidprefs/src/Android.mk b/tools/androidprefs/src/Android.mk
new file mode 100644
index 0000000..ddc0aa6
--- /dev/null
+++ b/tools/androidprefs/src/Android.mk
@@ -0,0 +1,24 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_MODULE := androidprefs
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/androidprefs/src/com/android/prefs/AndroidLocation.java b/tools/androidprefs/src/com/android/prefs/AndroidLocation.java
new file mode 100644
index 0000000..cfd9f53
--- /dev/null
+++ b/tools/androidprefs/src/com/android/prefs/AndroidLocation.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.prefs;
+
+import java.io.File;
+
+/**
+ * Manages the location of the android files (including emulator files, ddms config, debug keystore)
+ */
+public final class AndroidLocation {
+    /**
+     * Virtual Device folder inside the path returned by {@link #getFolder()}
+     */
+    public static final String FOLDER_AVD = "avd";
+
+    /**
+     * Throw when the location of the android folder couldn't be found.
+     */
+    public static final class AndroidLocationException extends Exception {
+        private static final long serialVersionUID = 1L;
+
+        public AndroidLocationException(String string) {
+            super(string);
+        }
+    }
+    
+    private static String sPrefsLocation = null;
+    
+    /**
+     * Returns the folder used to store android related files.
+     * @return an OS specific path, terminated by a separator.
+     * @throws AndroidLocationException 
+     */
+    public final static String getFolder() throws AndroidLocationException {
+        if (sPrefsLocation == null) {
+            String home = findValidPath("ANDROID_SDK_HOME", "user.home", "HOME");
+            
+            // if the above failed, we throw an exception.
+            if (home == null) {
+                throw new AndroidLocationException(
+                        "Unable to get the home directory. Make sure the user.home property is set up");
+            } else {
+                sPrefsLocation = home + File.separator + ".android" + File.separator;
+
+                // make sure the folder exists!
+                File f = new File(sPrefsLocation);
+                if (f.exists() == false) {
+                    f.mkdir();
+                } else if (f.isFile()) {
+                    throw new AndroidLocationException(sPrefsLocation +
+                            " is not a directory! This is required to run Android tools.");
+                }
+            }
+        }
+
+        return sPrefsLocation;
+    }
+
+    /**
+     * Checks a list of system properties and/or system environment variables for validity, and
+     * existing director, and returns the first one.
+     * @param names
+     * @return the content of the first property/variable.
+     */
+    private static String findValidPath(String... names) {
+        for (String name : names) {
+            String path;
+            if (name.indexOf('.') != -1) {
+                path = System.getProperty(name);
+            } else {
+                path = System.getenv(name);
+            }
+
+            if (path != null) {
+                File f = new File(path);
+                if (f.isDirectory()) {
+                    return path;
+                }
+            }
+        }
+        
+        return null;
+    }
+}
diff --git a/tools/anttasks/.classpath b/tools/anttasks/.classpath
new file mode 100644
index 0000000..d6ce15a
--- /dev/null
+++ b/tools/anttasks/.classpath
@@ -0,0 +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="/SdkLib"/>
+	<classpathentry kind="var" path="ANDROID_SRC/prebuilt/common/ant/ant.jar"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/ApkBuilder"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/anttasks/.project b/tools/anttasks/.project
new file mode 100644
index 0000000..aed1b61
--- /dev/null
+++ b/tools/anttasks/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>ant-tasks</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/anttasks/Android.mk b/tools/anttasks/Android.mk
new file mode 100644
index 0000000..15ee903
--- /dev/null
+++ b/tools/anttasks/Android.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+ANTTASKS_LOCAL_DIR := $(call my-dir)
+include $(ANTTASKS_LOCAL_DIR)/src/Android.mk
diff --git a/tools/anttasks/src/Android.mk b/tools/anttasks/src/Android.mk
new file mode 100644
index 0000000..94d6d3f
--- /dev/null
+++ b/tools/anttasks/src/Android.mk
@@ -0,0 +1,29 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES := \
+        sdklib \
+        apkbuilder \
+        ant
+
+LOCAL_MODULE := anttasks
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/anttasks/src/com/android/ant/AaptExecLoopTask.java b/tools/anttasks/src/com/android/ant/AaptExecLoopTask.java
new file mode 100644
index 0000000..d2c7162
--- /dev/null
+++ b/tools/anttasks/src/com/android/ant/AaptExecLoopTask.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ant;
+
+import com.android.sdklib.project.ApkConfigurationHelper;
+import com.android.sdklib.project.ProjectProperties;
+import com.android.sdklib.project.ProjectProperties.PropertyType;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.ExecTask;
+import org.apache.tools.ant.types.Path;
+
+import java.io.File;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+/**
+ * Task able to run an Exec task on aapt several times.
+ * It does not follow the exec task format, instead it has its own parameters, which maps
+ * directly to aapt.
+ *
+ */
+public final class AaptExecLoopTask extends Task {
+    
+    private String mExecutable;
+    private String mCommand;
+    private String mManifest;
+    private String mResources;
+    private String mAssets;
+    private String mAndroidJar;
+    private String mOutFolder;
+    private String mBaseName;
+
+    /**
+     * Sets the value of the "executable" attribute.
+     * @param executable the value.
+     */
+    public void setExecutable(String executable) {
+        mExecutable = executable;
+    }
+    
+    /**
+     * Sets the value of the "command" attribute.
+     * @param command the value.
+     */
+    public void setCommand(String command) {
+        mCommand = command;
+    }
+    
+    /**
+     * Sets the value of the "manifest" attribute.
+     * @param manifest the value.
+     */
+    public void setManifest(Path manifest) {
+        mManifest = manifest.toString();
+    }
+    
+    /**
+     * Sets the value of the "resources" attribute.
+     * @param resources the value.
+     */
+    public void setResources(Path resources) {
+        mResources = resources.toString();
+    }
+    
+    /**
+     * Sets the value of the "assets" attribute.
+     * @param assets the value.
+     */
+    public void setAssets(Path assets) {
+        mAssets = assets.toString();
+    }
+    
+    /**
+     * Sets the value of the "androidjar" attribute.
+     * @param androidJar the value.
+     */
+    public void setAndroidjar(Path androidJar) {
+        mAndroidJar = androidJar.toString();
+    }
+    
+    /**
+     * Sets the value of the "outfolder" attribute.
+     * @param outFolder the value.
+     */
+    public void setOutfolder(Path outFolder) {
+        mOutFolder = outFolder.toString();
+    }
+    
+    /**
+     * Sets the value of the "basename" attribute.
+     * @param baseName the value.
+     */
+    public void setBasename(String baseName) {
+        mBaseName = baseName;
+    }
+    
+    /*
+     * (non-Javadoc)
+     * 
+     * Executes the loop. Based on the values inside default.properties, this will
+     * create alternate temporary ap_ files.
+     * 
+     * @see org.apache.tools.ant.Task#execute()
+     */
+    @Override
+    public void execute() throws BuildException {
+        Project taskProject = getProject();
+        
+        // first do a full resource package
+        createPackage(null /*configName*/, null /*resourceFilter*/);
+
+        // now see if we need to create file with filtered resources.
+        // Get the project base directory.
+        File baseDir = taskProject.getBaseDir();
+        ProjectProperties properties = ProjectProperties.load(baseDir.getAbsolutePath(),
+                PropertyType.DEFAULT);
+        
+        Map<String, String> apkConfigs = ApkConfigurationHelper.getConfigs(properties);
+        if (apkConfigs.size() > 0) {
+            Set<Entry<String, String>> entrySet = apkConfigs.entrySet();
+            for (Entry<String, String> entry : entrySet) {
+                createPackage(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+
+    /**
+     * Creates a resource package.
+     * @param configName the name of the filter config. Can be null in which case a full resource
+     * package will be generated.
+     * @param resourceFilter the resource configuration filter to pass to aapt (if configName is
+     * non null)
+     */
+    private void createPackage(String configName, String resourceFilter) {
+        Project taskProject = getProject();
+
+        if (configName == null || resourceFilter == null) {
+            System.out.println("Creating full resource package...");
+        } else {
+            System.out.println(String.format(
+                    "Creating resource package for config '%1$s' (%2$s)...",
+                    configName, resourceFilter));
+        }
+
+        // create a task for the default apk.
+        ExecTask task = new ExecTask();
+        task.setExecutable(mExecutable);
+        task.setFailonerror(true);
+        
+        // aapt command. Only "package" is supported at this time really.
+        task.createArg().setValue(mCommand);
+        
+        // filters if needed
+        if (configName != null && resourceFilter != null) {
+            task.createArg().setValue("-c");
+            task.createArg().setValue(resourceFilter);
+        }
+        
+        // force flag
+        task.createArg().setValue("-f");
+        
+        // manifest location
+        task.createArg().setValue("-M");
+        task.createArg().setValue(mManifest);
+
+        // resources location
+        task.createArg().setValue("-S");
+        task.createArg().setValue(mResources);
+        
+        // assets location. this may not exists, and aapt doesn't like it, so we check first.
+        File assets = new File(mAssets);
+        if (assets.isDirectory()) {
+            task.createArg().setValue("-A");
+            task.createArg().setValue(mAssets);
+        }
+        
+        // android.jar
+        task.createArg().setValue("-I");
+        task.createArg().setValue(mAndroidJar);
+        
+        // out file. This is based on the outFolder, baseName, and the configName (if applicable)
+        String filename;
+        if (configName != null && resourceFilter != null) {
+            filename = mBaseName + "-" + configName + ".ap_";
+        } else {
+            filename = mBaseName + ".ap_";
+        }
+        
+        File file = new File(mOutFolder, filename);
+        task.createArg().setValue("-F");
+        task.createArg().setValue(file.getAbsolutePath());
+        
+        // final setup of the task
+        task.setProject(taskProject);
+        task.setOwningTarget(getOwningTarget());
+        
+        // execute it.
+        task.execute();
+    }
+}
diff --git a/tools/anttasks/src/com/android/ant/ApkBuilderTask.java b/tools/anttasks/src/com/android/ant/ApkBuilderTask.java
new file mode 100644
index 0000000..22729ec
--- /dev/null
+++ b/tools/anttasks/src/com/android/ant/ApkBuilderTask.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ant;
+
+import com.android.apkbuilder.ApkBuilder;
+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 org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.types.Path;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+public class ApkBuilderTask extends Task {
+    
+    /**
+     * Class to represent nested elements. Since they all have only one attribute ('path'), the
+     * same class can be used for all the nested elements (zip, file, sourcefolder, jarfolder,
+     * nativefolder).
+     */
+    public final static class Value extends ProjectComponent {
+        String mPath;
+        
+        /**
+         * Sets the value of the "path" attribute.
+         * @param path the value.
+         */
+        public void setPath(Path path) {
+            mPath = path.toString();
+        }
+    }
+
+    private String mOutFolder;
+    private String mBaseName;
+    private boolean mVerbose = false;
+    private boolean mSigned = true;
+    
+    private final ArrayList<Value> mZipList = new ArrayList<Value>();
+    private final ArrayList<Value> mFileList = new ArrayList<Value>();
+    private final ArrayList<Value> mSourceList = new ArrayList<Value>();
+    private final ArrayList<Value> mJarList = new ArrayList<Value>();
+    private final ArrayList<Value> mNativeList = new ArrayList<Value>();
+
+    private final ArrayList<FileInputStream> mZipArchives = new ArrayList<FileInputStream>();
+    private final ArrayList<File> mArchiveFiles = new ArrayList<File>();
+    private final ArrayList<ApkFile> mJavaResources = new ArrayList<ApkFile>();
+    private final ArrayList<FileInputStream> mResourcesJars = new ArrayList<FileInputStream>();
+    private final ArrayList<ApkFile> mNativeLibraries = new ArrayList<ApkFile>();
+
+    /**
+     * Sets the value of the "outfolder" attribute.
+     * @param outFolder the value.
+     */
+    public void setOutfolder(Path outFolder) {
+        mOutFolder = outFolder.toString();
+    }
+    
+    /**
+     * Sets the value of the "basename" attribute.
+     * @param baseName the value.
+     */
+    public void setBasename(String baseName) {
+        mBaseName = baseName;
+    }
+    
+    /**
+     * Sets the value of the "verbose" attribute.
+     * @param verbose the value.
+     */
+    public void setVerbose(boolean verbose) {
+        mVerbose = verbose;
+    }
+    
+    /**
+     * Sets the value of the "signed" attribute.
+     * @param signed the value.
+     */
+    public void setSigned(boolean signed) {
+        mSigned = signed;
+    }
+    
+    /**
+     * Returns an object representing a nested <var>zip</var> element.
+     */
+    public Object createZip() {
+        Value zip = new Value();
+        mZipList.add(zip);
+        return zip;
+    }
+    
+    /**
+     * Returns an object representing a nested <var>file</var> element.
+     */
+    public Object createFile() {
+        Value file = new Value();
+        mFileList.add(file);
+        return file;
+    }
+
+    /**
+     * Returns an object representing a nested <var>sourcefolder</var> element.
+     */
+    public Object createSourcefolder() {
+        Value file = new Value();
+        mSourceList.add(file);
+        return file;
+    }
+
+    /**
+     * Returns an object representing a nested <var>jarfolder</var> element.
+     */
+    public Object createJarfolder() {
+        Value file = new Value();
+        mJarList.add(file);
+        return file;
+    }
+    
+    /**
+     * Returns an object representing a nested <var>nativefolder</var> element.
+     */
+    public Object createNativefolder() {
+        Value file = new Value();
+        mNativeList.add(file);
+        return file;
+    }
+    
+    @Override
+    public void execute() throws BuildException {
+        Project taskProject = getProject();
+        
+        ApkBuilder apkBuilder = new ApkBuilder();
+        apkBuilder.setVerbose(mVerbose);
+        apkBuilder.setSignedPackage(mSigned);
+        
+        try {
+            // setup the list of everything that needs to go in the archive.
+            
+            // go through the list of zip files to add. This will not include
+            // the resource package, which is handled separaly for each apk to create.
+            for (Value v : mZipList) {
+                FileInputStream input = new FileInputStream(v.mPath);
+                mZipArchives.add(input);
+            }
+            
+            // now go through the list of file to directly add the to the list.
+            for (Value v : mFileList) {
+                mArchiveFiles.add(ApkBuilder.getInputFile(v.mPath));
+            }
+            
+            // now go through the list of file to directly add the to the list.
+            for (Value v : mSourceList) {
+                ApkBuilder.processSourceFolderForResource(v.mPath, mJavaResources);
+            }
+            
+            // now go through the list of jar folders.
+            for (Value v : mJarList) {
+                ApkBuilder.processJarFolder(v.mPath, mResourcesJars);
+            }
+            
+            // now the native lib folder.
+            for (Value v : mNativeList) {
+                String parameter = v.mPath;
+                File f = new File(parameter);
+                
+                // compute the offset to get the relative path
+                int offset = parameter.length();
+                if (parameter.endsWith(File.separator) == false) {
+                    offset++;
+                }
+
+                ApkBuilder.processNativeFolder(offset, f, mNativeLibraries);
+            }
+
+            
+            // first do a full resource package
+            createApk(apkBuilder, null /*configName*/, null /*resourceFilter*/);
+    
+            // now see if we need to create file with filtered resources.
+            // Get the project base directory.
+            File baseDir = taskProject.getBaseDir();
+            ProjectProperties properties = ProjectProperties.load(baseDir.getAbsolutePath(),
+                    PropertyType.DEFAULT);
+            
+            Map<String, String> apkConfigs = ApkConfigurationHelper.getConfigs(properties);
+            if (apkConfigs.size() > 0) {
+                Set<Entry<String, String>> entrySet = apkConfigs.entrySet();
+                for (Entry<String, String> entry : entrySet) {
+                    createApk(apkBuilder, entry.getKey(), entry.getValue());
+                }
+            }
+        } catch (FileNotFoundException e) {
+            throw new BuildException(e);
+        } catch (IllegalArgumentException e) {
+            throw new BuildException(e);
+        }
+    }
+    
+    /**
+     * Creates an application package.
+     * @param apkBuilder 
+     * @param configName the name of the filter config. Can be null in which case a full resource
+     * package will be generated.
+     * @param resourceFilter the resource configuration filter to pass to aapt (if configName is
+     * non null)
+     * @throws FileNotFoundException 
+     */
+    private void createApk(ApkBuilder apkBuilder, String configName, String resourceFilter)
+            throws FileNotFoundException {
+        // All the files to be included in the archive have already been prep'ed up, except
+        // the resource package.
+        // figure out its name.
+        String filename;
+        if (configName != null && resourceFilter != null) {
+            filename = mBaseName + "-" + configName + ".ap_";
+        } else {
+            filename = mBaseName + ".ap_";
+        }
+        
+        // now we add it to the list of zip archive (it's just a zip file).
+        
+        // it's used as a zip archive input
+        FileInputStream resoucePackageZipFile = new FileInputStream(new File(mOutFolder, filename));
+        mZipArchives.add(resoucePackageZipFile);
+        
+        // prepare the filename to generate. Same thing as the resource file.
+        if (configName != null && resourceFilter != null) {
+            filename = mBaseName + "-" + configName;
+        } else {
+            filename = mBaseName;
+        }
+        
+        if (mSigned) {
+            filename = filename + "-debug.apk";
+        } else {
+            filename = filename + "-unsigned.apk";
+        }
+
+        if (configName == null || resourceFilter == null) {
+            if (mSigned) {
+                System.out.println(String.format(
+                        "Creating %s and signing it with a debug key...", filename));
+            } else {
+                System.out.println(String.format(
+                        "Creating %s for release...", filename));
+            }
+        } else {
+            if (mSigned) {
+                System.out.println(String.format(
+                        "Creating %1$s (with %2$s) and signing it with a debug key...",
+                        filename, resourceFilter));
+            } else {
+                System.out.println(String.format(
+                        "Creating %1$s (with %2$s) for release...",
+                        filename, resourceFilter));
+            }
+        }
+        
+        File f = new File(mOutFolder, filename);
+        
+        // and generate the apk
+        apkBuilder.createPackage(f.getAbsoluteFile(), mZipArchives,
+                mArchiveFiles, mJavaResources, mResourcesJars, mNativeLibraries);
+        
+        // we are done. We need to remove the resource package from the list of zip archives
+        // in case we have another apk to generate.
+        mZipArchives.remove(resoucePackageZipFile);
+    }
+}
diff --git a/tools/anttasks/src/com/android/ant/SetupTask.java b/tools/anttasks/src/com/android/ant/SetupTask.java
new file mode 100644
index 0000000..d425a2f
--- /dev/null
+++ b/tools/anttasks/src/com/android/ant/SetupTask.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ant;
+
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.ISdkLog;
+import com.android.sdklib.SdkManager;
+import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
+import com.android.sdklib.project.ProjectProperties;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.ImportTask;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.types.Path.PathElement;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+
+/**
+ * Setup/Import Ant task. This task accomplishes:
+ * <ul>
+ * <li>Gets the project target hash string from {@link ProjectProperties#PROPERTY_TARGET},
+ * and resolves it to get the project's {@link IAndroidTarget}.</li>
+ * <li>Sets up properties so that aapt can find the android.jar in the resolved target.</li>
+ * <li>Sets up the boot classpath ref so that the <code>javac</code> task knows where to find
+ * the libraries. This includes the default android.jar from the resolved target but also optional
+ * libraries provided by the target (if any, when the target is an add-on).</li>
+ * <li>Imports the build rules located in the resolved target so that the build actually does
+ * something. This can be disabled with the attribute <var>import</var> set to <code>false</code>
+ * </li></ul>
+ * 
+ * This is used in build.xml/template.
+ *
+ */
+public final class SetupTask extends ImportTask {
+    private final static String ANDROID_RULES = "android_rules.xml";
+    
+    // ant property with the path to the android.jar
+    private final static String PROPERTY_ANDROID_JAR = "android-jar";
+    // ant property with the path to the framework.jar
+    private final static String PROPERTY_ANDROID_AIDL = "android-aidl";
+    // ant property with the path to the aapt tool
+    private final static String PROPERTY_AAPT = "aapt";
+    // ant property with the path to the aidl tool
+    private final static String PROPERTY_AIDL = "aidl";
+    // ant property with the path to the dx tool
+    private final static String PROPERTY_DX = "dx";
+    // ref id to the <path> object containing all the boot classpaths.
+    private final static String REF_CLASSPATH = "android.target.classpath";
+    
+    private boolean mDoImport = true;
+
+    @Override
+    public void execute() throws BuildException {
+        Project antProject = getProject();
+        
+        // get the SDK location
+        String sdkLocation = antProject.getProperty(ProjectProperties.PROPERTY_SDK);
+        
+        // check if it's valid and exists
+        if (sdkLocation == null || sdkLocation.length() == 0) {
+            throw new BuildException("SDK Location is not set.");
+        }
+        
+        File sdk = new File(sdkLocation);
+        if (sdk.isDirectory() == false) {
+            throw new BuildException(String.format("SDK Location '%s' is not valid.", sdkLocation));
+        }
+
+        // get the target property value
+        String targetHashString = antProject.getProperty(ProjectProperties.PROPERTY_TARGET);
+        if (targetHashString == null) {
+            throw new BuildException("Android Target is not set.");
+        }
+
+        // load up the sdk targets.
+        final ArrayList<String> messages = new ArrayList<String>();
+        SdkManager manager = SdkManager.createManager(sdkLocation, new ISdkLog() {
+            public void error(Throwable t, String errorFormat, Object... args) {
+                if (errorFormat != null) {
+                    messages.add(String.format("Error: " + errorFormat, args));
+                }
+                if (t != null) {
+                    messages.add("Error: " + t.getMessage());
+                }
+            }
+
+            public void printf(String msgFormat, Object... args) {
+                messages.add(String.format(msgFormat, args));
+            }
+
+            public void warning(String warningFormat, Object... args) {
+                messages.add(String.format("Warning: " + warningFormat, args));
+            }
+        });
+
+        if (manager == null) {
+            // since we failed to parse the SDK, lets display the parsing output.
+            for (String msg : messages) {
+                System.out.println(msg);
+            }
+            throw new BuildException("Failed to parse SDK content.");
+        }
+
+        // resolve it
+        IAndroidTarget androidTarget = manager.getTargetFromHashString(targetHashString);
+        
+        if (androidTarget == null) {
+            throw new BuildException(String.format(
+                    "Unable to resolve target '%s'", targetHashString));
+        }
+        
+        // display it
+        System.out.println("Project Target: " + androidTarget.getName());
+        if (androidTarget.isPlatform() == false) {
+            System.out.println("Vendor: " + androidTarget.getVendor());
+            System.out.println("Platform Version: " + androidTarget.getApiVersionName());
+        }
+        System.out.println("API level: " + androidTarget.getApiVersionNumber());
+        
+        // sets up the properties to find android.jar/framework.aidl/target tools
+        String androidJar = androidTarget.getPath(IAndroidTarget.ANDROID_JAR);
+        antProject.setProperty(PROPERTY_ANDROID_JAR, androidJar);
+
+        antProject.setProperty(PROPERTY_ANDROID_AIDL,
+                androidTarget.getPath(IAndroidTarget.ANDROID_AIDL));
+        antProject.setProperty(PROPERTY_AAPT, androidTarget.getPath(IAndroidTarget.AAPT));
+        antProject.setProperty(PROPERTY_AIDL, androidTarget.getPath(IAndroidTarget.AIDL));
+        antProject.setProperty(PROPERTY_DX, androidTarget.getPath(IAndroidTarget.DX));
+
+        // sets up the boot classpath
+
+        // create the Path object
+        Path bootclasspath = new Path(antProject);
+
+        // create a PathElement for the framework jar
+        PathElement element = bootclasspath.createPathElement();
+        element.setPath(androidJar);
+        
+        // create PathElement for each optional library.
+        IOptionalLibrary[] libraries = androidTarget.getOptionalLibraries();
+        if (libraries != null) {
+            HashSet<String> visitedJars = new HashSet<String>();
+            for (IOptionalLibrary library : libraries) {
+                String jarPath = library.getJarPath();
+                if (visitedJars.contains(jarPath) == false) {
+                    visitedJars.add(jarPath);
+
+                    element = bootclasspath.createPathElement();
+                    element.setPath(library.getJarPath());
+                }
+            }
+        }
+        
+        // finally sets the path in the project with a reference
+        antProject.addReference(REF_CLASSPATH, bootclasspath);
+
+        // find the file to import, and import it.
+        String templateFolder = androidTarget.getPath(IAndroidTarget.TEMPLATES);
+        
+        // Now the import section. This is only executed if the task actually has to import a file.
+        if (mDoImport) {
+            // make sure the file exists.
+            File templates = new File(templateFolder);
+            if (templates.isDirectory() == false) {
+                throw new BuildException(String.format("Template directory '%s' is missing.",
+                        templateFolder));
+            }
+            
+            // now check the rules file exists.
+            File rules = new File(templateFolder, ANDROID_RULES);
+            if (rules.isFile() == false) {
+                throw new BuildException(String.format("Build rules file '%s' is missing.",
+                        templateFolder));
+           }
+            
+            // set the file location to import
+            setFile(rules.getAbsolutePath());
+            
+            // and import
+            super.execute();
+        }
+    }
+
+    /**
+     * Sets the value of the "import" attribute.
+     * @param value the value.
+     */
+    public void setImport(boolean value) {
+        mDoImport = value;
+    }
+}
diff --git a/tools/apkbuilder/.classpath b/tools/apkbuilder/.classpath
new file mode 100644
index 0000000..f1768fc
--- /dev/null
+++ b/tools/apkbuilder/.classpath
@@ -0,0 +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 combineaccessrules="false" kind="src" path="/JarUtils"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/apkbuilder/.project b/tools/apkbuilder/.project
new file mode 100644
index 0000000..cc97afc
--- /dev/null
+++ b/tools/apkbuilder/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>ApkBuilder</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/apkbuilder/Android.mk b/tools/apkbuilder/Android.mk
new file mode 100644
index 0000000..bdfe5c8
--- /dev/null
+++ b/tools/apkbuilder/Android.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+APKBUILDER_LOCAL_DIR := $(call my-dir)
+include $(APKBUILDER_LOCAL_DIR)/etc/Android.mk
+include $(APKBUILDER_LOCAL_DIR)/src/Android.mk
diff --git a/tools/apkbuilder/etc/Android.mk b/tools/apkbuilder/etc/Android.mk
new file mode 100644
index 0000000..d74db17
--- /dev/null
+++ b/tools/apkbuilder/etc/Android.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_EXECUTABLES := apkbuilder
+include $(BUILD_HOST_PREBUILT)
+
diff --git a/tools/apkbuilder/etc/apkbuilder b/tools/apkbuilder/etc/apkbuilder
new file mode 100755
index 0000000..3e7e822
--- /dev/null
+++ b/tools/apkbuilder/etc/apkbuilder
@@ -0,0 +1,81 @@
+#!/bin/sh
+# Copyright 2005-2007, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+    newProg=`/bin/ls -ld "${prog}"`
+    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+    if expr "x${newProg}" : 'x/' >/dev/null; then
+        prog="${newProg}"
+    else
+        progdir=`dirname "${prog}"`
+        prog="${progdir}/${newProg}"
+    fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+jarfile=apkbuilder.jar
+frameworkdir="$progdir"
+libdir="$progdir"
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/tools/lib
+    libdir=`dirname "$progdir"`/tools/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/framework
+    libdir=`dirname "$progdir"`/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    echo `basename "$prog"`": can't find $jarfile"
+    exit 1
+fi
+
+
+# Check args.
+if [ debug = "$1" ]; then
+    # add this in for debugging
+    java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
+    shift 1
+else
+    java_debug=
+fi
+
+# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
+if [ `uname` = "Darwin" ]; then
+    os_opts="-XstartOnFirstThread"
+else
+    os_opts=
+fi
+
+if [ "$OSTYPE" = "cygwin" ] ; then
+    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
+    progdir=`cygpath -w  "$progdir"`
+else
+    jarpath="$frameworkdir/$jarfile"
+fi
+
+# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
+# might need more memory, e.g. -Xmx128M
+exec java -Xmx128M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -jar "$jarpath" "$@"
diff --git a/tools/apkbuilder/etc/apkbuilder.bat b/tools/apkbuilder/etc/apkbuilder.bat
new file mode 100755
index 0000000..c4689c6
--- /dev/null
+++ b/tools/apkbuilder/etc/apkbuilder.bat
@@ -0,0 +1,43 @@
+@echo off
+rem Copyright (C) 2007 The Android Open Source Project
+rem
+rem Licensed under the Apache License, Version 2.0 (the "License");
+rem you may not use this file except in compliance with the License.
+rem You may obtain a copy of the License at
+rem
+rem      http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+
+rem don't modify the caller's environment
+setlocal
+
+rem Set up prog to be the path of this script, including following symlinks,
+rem and set up progdir to be the fully-qualified pathname of its directory.
+set prog=%~f0
+
+rem Change current directory and drive to where the script is, to avoid
+rem issues with directories containing whitespaces.
+cd /d %~dp0
+
+set jarfile=apkbuilder.jar
+set frameworkdir=
+set libdir=
+
+if exist %frameworkdir%%jarfile% goto JarFileOk
+    set frameworkdir=lib\
+    set libdir=lib\
+
+if exist %frameworkdir%%jarfile% goto JarFileOk
+    set frameworkdir=..\framework\
+    set libdir=..\lib\
+
+:JarFileOk
+
+set jarpath=%frameworkdir%%jarfile%
+
+call java -Djava.ext.dirs=%frameworkdir% -Djava.library.path=%libdir% -jar %jarpath% %*
diff --git a/tools/apkbuilder/etc/manifest.txt b/tools/apkbuilder/etc/manifest.txt
new file mode 100644
index 0000000..6aafb16
--- /dev/null
+++ b/tools/apkbuilder/etc/manifest.txt
@@ -0,0 +1 @@
+Main-Class: com.android.apkbuilder.ApkBuilder
diff --git a/tools/apkbuilder/src/Android.mk b/tools/apkbuilder/src/Android.mk
new file mode 100644
index 0000000..e403ca7
--- /dev/null
+++ b/tools/apkbuilder/src/Android.mk
@@ -0,0 +1,29 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_JAR_MANIFEST := ../etc/manifest.txt
+LOCAL_JAVA_LIBRARIES := \
+        androidprefs \
+        jarutils
+
+LOCAL_MODULE := apkbuilder
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/apkbuilder/src/com/android/apkbuilder/ApkBuilder.java b/tools/apkbuilder/src/com/android/apkbuilder/ApkBuilder.java
new file mode 100644
index 0000000..40abff1
--- /dev/null
+++ b/tools/apkbuilder/src/com/android/apkbuilder/ApkBuilder.java
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.apkbuilder;
+
+import com.android.jarutils.DebugKeyProvider;
+import com.android.jarutils.JavaResourceFilter;
+import com.android.jarutils.SignedJarBuilder;
+import com.android.jarutils.DebugKeyProvider.KeytoolException;
+import com.android.prefs.AndroidLocation.AndroidLocationException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.regex.Pattern;
+
+/**
+ * Command line APK builder with signing support.
+ */
+public final class ApkBuilder {
+    
+    private final static Pattern PATTERN_JAR_EXT = Pattern.compile("^.+\\.jar$",
+            Pattern.CASE_INSENSITIVE);
+    private final static Pattern PATTERN_NATIVELIB_EXT = Pattern.compile("^.+\\.so$",
+            Pattern.CASE_INSENSITIVE);
+    
+    private final static String NATIVE_LIB_ROOT = "lib/";
+
+    /**
+     * A File to be added to the APK archive.
+     * <p/>This includes the {@link File} representing the file and its path in the archive.
+     */
+    public final static class ApkFile {
+        String archivePath;
+        File file;
+
+        ApkFile(File file, String path) {
+            this.file = file;
+            this.archivePath = path;
+        }
+    }
+
+    private JavaResourceFilter mResourceFilter = new JavaResourceFilter();
+    private boolean mVerbose = false;
+    private boolean mSignedPackage = true;
+    /** the optional type of the debug keystore. If <code>null</code>, the default */
+    private String mStoreType = null;
+
+    /**
+     * @param args
+     */
+    public static void main(String[] args) {
+        new ApkBuilder().run(args);
+    }
+    
+    public void setVerbose(boolean verbose) {
+        mVerbose = verbose;
+    }
+    
+    public void setSignedPackage(boolean signedPackage) {
+        mSignedPackage = signedPackage;
+    }
+
+    private void run(String[] args) {
+        if (args.length < 1) {
+            printUsageAndQuit();
+        }
+
+        try {
+            // read the first args that should be a file path
+            File outFile = getOutFile(args[0]);
+    
+            ArrayList<FileInputStream> zipArchives = new ArrayList<FileInputStream>();
+            ArrayList<File> archiveFiles = new ArrayList<File>();
+            ArrayList<ApkFile> javaResources = new ArrayList<ApkFile>();
+            ArrayList<FileInputStream> resourcesJars = new ArrayList<FileInputStream>();
+            ArrayList<ApkFile> nativeLibraries = new ArrayList<ApkFile>();
+    
+            int index = 1;
+            do {
+                String argument = args[index++];
+    
+                if ("-v".equals(argument)) {
+                    mVerbose = true;
+                } else if ("-u".equals(argument)) {
+                    mSignedPackage = false;
+                } else if ("-z".equals(argument)) {
+                    // quick check on the next argument.
+                    if (index == args.length) printUsageAndQuit();
+                    
+                    try {
+                        FileInputStream input = new FileInputStream(args[index++]);
+                        zipArchives.add(input);
+                    } catch (FileNotFoundException e) {
+                        printAndExit(e.getMessage());
+                    }
+                } else if ("-f". equals(argument)) {
+                    // quick check on the next argument.
+                    if (index == args.length) printUsageAndQuit();
+    
+                    archiveFiles.add(getInputFile(args[index++]));
+                } else if ("-rf". equals(argument)) {
+                    // quick check on the next argument.
+                    if (index == args.length) printUsageAndQuit();
+    
+                    processSourceFolderForResource(args[index++], javaResources);
+                } else if ("-rj". equals(argument)) {
+                    // quick check on the next argument.
+                    if (index == args.length) printUsageAndQuit();
+                    
+                    processJarFolder(args[index++], resourcesJars);
+                } else if ("-nf".equals(argument)) {
+                    // quick check on the next argument.
+                    if (index == args.length) printUsageAndQuit();
+                    
+                    String parameter = args[index++];
+                    File f = new File(parameter);
+    
+                    // compute the offset to get the relative path
+                    int offset = parameter.length();
+                    if (parameter.endsWith(File.separator) == false) {
+                        offset++;
+                    }
+    
+                    processNativeFolder(offset, f, nativeLibraries);
+                } else if ("-storetype".equals(argument)) {
+                    // quick check on the next argument.
+                    if (index == args.length) printUsageAndQuit();
+                    
+                    mStoreType  = args[index++];
+                } else {
+                    printAndExit("Unknown argument: " + argument);
+                }
+            } while (index < args.length);
+            
+            createPackage(outFile, zipArchives, archiveFiles, javaResources, resourcesJars,
+                    nativeLibraries);
+        } catch (IllegalArgumentException e) {
+            printAndExit(e.getMessage());
+        } catch (FileNotFoundException e) {
+            printAndExit(e.getMessage());
+        }
+    }
+
+
+    private File getOutFile(String filepath) {
+        File f = new File(filepath);
+        
+        if (f.isDirectory()) {
+            printAndExit(filepath + " is a directory!");
+        }
+        
+        if (f.exists()) { // will be a file in this case.
+            if (f.canWrite() == false) {
+                printAndExit("Cannot write " + filepath);
+            }
+        } else {
+            try {
+                if (f.createNewFile() == false) {
+                    printAndExit("Failed to create " + filepath);
+                }
+            } catch (IOException e) {
+                printAndExit("Failed to create '" + filepath + "' : " + e.getMessage());
+            }
+        }
+        
+        return f;
+    }
+
+    public static File getInputFile(String filepath) throws IllegalArgumentException {
+        File f = new File(filepath);
+        
+        if (f.isDirectory()) {
+            throw new IllegalArgumentException(filepath + " is a directory!");
+        }
+        
+        if (f.exists()) {
+            if (f.canRead() == false) {
+                throw new IllegalArgumentException("Cannot read " + filepath);
+            }
+        } else {
+            throw new IllegalArgumentException(filepath + " does not exists!");
+        }
+
+        return f;
+    }
+
+    /**
+     * Processes a source folder and adds its java resources to a given list of {@link ApkFile}.
+     * @param folderPath the path to the source folder.
+     * @param javaResources the list of {@link ApkFile} to fill.
+     */
+    public static void processSourceFolderForResource(String folderPath,
+            ArrayList<ApkFile> javaResources) {
+        
+        File folder = new File(folderPath);
+        
+        if (folder.isDirectory()) {
+            // file is a directory, process its content.
+            File[] files = folder.listFiles();
+            for (File file : files) {
+                processFileForResource(file, null, javaResources);
+            }
+        } else {
+            // not a directory? output error and quit.
+            if (folder.exists()) {
+                throw new IllegalArgumentException(folderPath + " is not a folder!");
+            } else {
+                throw new IllegalArgumentException(folderPath + " does not exist!");
+            }
+        }
+    }
+    
+    public static void processJarFolder(String parameter, ArrayList<FileInputStream> resourcesJars)
+            throws FileNotFoundException {
+        File f = new File(parameter);
+        if (f.isDirectory()) {
+            String[] files = f.list(new FilenameFilter() {
+                public boolean accept(File dir, String name) {
+                    return PATTERN_JAR_EXT.matcher(name).matches();
+                }
+            });
+
+            for (String file : files) {
+                String path = f.getAbsolutePath() + File.separator + file;
+                FileInputStream input = new FileInputStream(path);
+                resourcesJars.add(input);
+            }
+        } else {
+            FileInputStream input = new FileInputStream(parameter);
+            resourcesJars.add(input);
+        }
+    }
+
+    
+    /**
+     * Processes a {@link File} that could be a {@link ApkFile}, or a folder containing
+     * java resources.
+     * @param file the {@link File} to process.
+     * @param path the relative path of this file to the source folder. Can be <code>null</code> to
+     * identify a root file. 
+     * @param javaResources the list of {@link ApkFile} object to fill.
+     */
+    private static void processFileForResource(File file, String path,
+            ArrayList<ApkFile> javaResources) {
+        if (file.isDirectory()) {
+            // a directory? we check it
+            if (JavaResourceFilter.checkFolderForPackaging(file.getName())) {
+                // if it's valid, we append its name to the current path.
+                if (path == null) {
+                    path = file.getName();
+                } else {
+                    path = path + "/" + file.getName();
+                }
+
+                // and process its content.
+                File[] files = file.listFiles();
+                for (File contentFile : files) {
+                    processFileForResource(contentFile, path, javaResources);
+                }
+            }
+        } else {
+            // a file? we check it
+            if (JavaResourceFilter.checkFileForPackaging(file.getName())) {
+                // we append its name to the current path
+                if (path == null) {
+                    path = file.getName();
+                } else {
+                    path = path + "/" + file.getName();
+                }
+
+                // and add it to the list.
+                javaResources.add(new ApkFile(file, path));
+            }
+        }
+    }
+    
+    /**
+     * Process a {@link File} for native library inclusion.
+     * @param offset the length of the root folder (used to compute relative path)
+     * @param f the {@link File} to process
+     * @param nativeLibraries the array to add native libraries.
+     */
+    public static void processNativeFolder(int offset, File f, ArrayList<ApkFile> nativeLibraries) {
+        if (f.isDirectory()) {
+            File[] children = f.listFiles();
+            
+            if (children != null) {
+                for (File child : children) {
+                    processNativeFolder(offset, child, nativeLibraries);
+                }
+            }
+        } else if (f.isFile()) {
+            if (PATTERN_NATIVELIB_EXT.matcher(f.getName()).matches()) {
+                String path = NATIVE_LIB_ROOT + 
+                        f.getAbsolutePath().substring(offset).replace('\\', '/');
+                
+                nativeLibraries.add(new ApkFile(f, path));
+            }
+        }
+    }
+
+    /**
+     * Creates the application package
+     * @param outFile 
+     * @param zipArchives
+     * @param resourcesJars 
+     * @param files 
+     * @param javaResources 
+     * keystore type of the Java VM is used.
+     */
+    public void createPackage(File outFile, ArrayList<FileInputStream> zipArchives,
+            ArrayList<File> files, ArrayList<ApkFile> javaResources,
+            ArrayList<FileInputStream> resourcesJars, ArrayList<ApkFile> nativeLibraries) {
+        
+        // get the debug key
+        try {
+            SignedJarBuilder builder;
+
+            if (mSignedPackage) {
+                System.err.println(String.format("Using keystore: %s",
+                        DebugKeyProvider.getDefaultKeyStoreOsPath()));
+                
+                
+                DebugKeyProvider keyProvider = new DebugKeyProvider(
+                        null /* osKeyPath: use default */,
+                        mStoreType, null /* IKeyGenOutput */);
+                PrivateKey key = keyProvider.getDebugKey();
+                X509Certificate certificate = (X509Certificate)keyProvider.getCertificate();
+                
+                if (key == null) {
+                    throw new IllegalArgumentException("Unable to get debug signature key");
+                }
+                
+                // compare the certificate expiration date
+                if (certificate != null && certificate.getNotAfter().compareTo(new Date()) < 0) {
+                    // TODO, regenerate a new one.
+                    throw new IllegalArgumentException("Debug Certificate expired on " +
+                            DateFormat.getInstance().format(certificate.getNotAfter()));
+                }
+
+                builder = new SignedJarBuilder(
+                        new FileOutputStream(outFile.getAbsolutePath(), false /* append */), key,
+                        certificate);
+            } else {
+                builder = new SignedJarBuilder(
+                        new FileOutputStream(outFile.getAbsolutePath(), false /* append */),
+                        null /* key */, null /* certificate */);
+            }
+
+            // add the archives
+            for (FileInputStream input : zipArchives) {
+                builder.writeZip(input, null /* filter */);
+            }
+
+            // add the single files
+            for (File input : files) {
+                // always put the file at the root of the archive in this case
+                builder.writeFile(input, input.getName());
+                if (mVerbose) {
+                    System.err.println(String.format("%1$s => %2$s", input.getAbsolutePath(),
+                            input.getName()));
+                }
+            }
+            
+            // add the java resource from the source folders.
+            for (ApkFile resource : javaResources) {
+                builder.writeFile(resource.file, resource.archivePath);
+                if (mVerbose) {
+                    System.err.println(String.format("%1$s => %2$s",
+                            resource.file.getAbsolutePath(), resource.archivePath));
+                }
+            }
+
+            // add the java resource from jar files.
+            for (FileInputStream input : resourcesJars) {
+                builder.writeZip(input, mResourceFilter);
+            }
+            
+            // add the native files
+            for (ApkFile file : nativeLibraries) {
+                builder.writeFile(file.file, file.archivePath);
+                if (mVerbose) {
+                    System.err.println(String.format("%1$s => %2$s", file.file.getAbsolutePath(),
+                            file.archivePath));
+                }
+            }
+            
+            // close and sign the application package.
+            builder.close();
+        } catch (KeytoolException e) {
+            if (e.getJavaHome() == null) {
+                throw new IllegalArgumentException(e.getMessage() + 
+                        "\nJAVA_HOME seems undefined, setting it will help locating keytool automatically\n" +
+                        "You can also manually execute the following command\n:" +
+                        e.getCommandLine());
+            } else {
+                throw new IllegalArgumentException(e.getMessage() + 
+                        "\nJAVA_HOME is set to: " + e.getJavaHome() +
+                        "\nUpdate it if necessary, or manually execute the following command:\n" +
+                        e.getCommandLine());
+            }
+        } catch (AndroidLocationException e) {
+            throw new IllegalArgumentException(e);
+        } catch (Exception e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    private void printUsageAndQuit() {
+        // 80 cols marker:  01234567890123456789012345678901234567890123456789012345678901234567890123456789
+        System.err.println("A command line tool to package an Android application from various sources.");
+        System.err.println("Usage: apkbuilder <out archive> [-v][-u][-storetype STORE_TYPE] [-z inputzip]");
+        System.err.println("            [-f inputfile] [-rf input-folder] [-rj -input-path]");
+        System.err.println("");
+        System.err.println("    -v      Verbose.");
+        System.err.println("    -u      Creates an unsigned package.");
+        System.err.println("    -storetype Forces the KeyStore type. If ommited the default is used.");
+        System.err.println("");
+        System.err.println("    -z      Followed by the path to a zip archive.");
+        System.err.println("            Adds the content of the application package.");
+        System.err.println("");
+        System.err.println("    -f      Followed by the path to a file.");
+        System.err.println("            Adds the file to the application package.");
+        System.err.println("");
+        System.err.println("    -rf     Followed by the path to a source folder.");
+        System.err.println("            Adds the java resources found in that folder to the application");
+        System.err.println("            package, while keeping their path relative to the source folder.");
+        System.err.println("");
+        System.err.println("    -rj     Followed by the path to a jar file or a folder containing");
+        System.err.println("            jar files.");
+        System.err.println("            Adds the java resources found in the jar file(s) to the application");
+        System.err.println("            package.");
+        System.err.println("");
+        System.err.println("    -nf     Followed by the root folder containing native libraries to");
+        System.err.println("            include in the application package.");
+        
+        System.exit(1);
+    }
+    
+    private void printAndExit(String... messages) {
+        for (String message : messages) {
+            System.err.println(message);
+        }
+        System.exit(1);
+    }
+}
diff --git a/tools/axl/README.txt b/tools/axl/README.txt
new file mode 100644
index 0000000..36f6811
--- /dev/null
+++ b/tools/axl/README.txt
@@ -0,0 +1,3 @@
+TCP and HTTP tests
+
+axl: hostile web server.
diff --git a/tools/axl/axl.py b/tools/axl/axl.py
new file mode 100755
index 0000000..f7b5410
--- /dev/null
+++ b/tools/axl/axl.py
@@ -0,0 +1,253 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+"""
+  axl.py: HTTP Client torture tester
+
+"""
+
+import sys, time
+
+from twisted.internet import protocol, reactor, defer
+from twisted.internet.protocol import ServerFactory, Protocol
+
+import singletonmixin, log
+
+class BaseProtocol(Protocol):
+    def __init__(self):
+        self.log = log.Log.getInstance()
+
+    def write(self, data):
+        self.log("BaseProtocol.write()", len(data), data)
+        return self.transport.write(data)
+
+    def dataReceived(self, data):
+        self.log("BaseProtocol.dataReceived()", len(data), data)
+
+    def connectionMade(self):
+        self.log("BaseProtocol.connectionMade()")
+        self.transport.setTcpNoDelay(1)	# send immediately
+
+    def connectionLost(self, reason):
+        self.log("BaseProtocol.connectionLost():", reason)
+
+    def sendResponse(self, response):
+        self.write("HTTP/1.1 200 OK\r\n")
+        self.write("Content-Length: %d\r\n\r\n" % len(response))
+        if len(response) > 0:
+            self.write(response)
+
+
+# Tests
+# 8000: test driven by resource request
+
+class Drop(BaseProtocol):
+    """Drops connection immediately after connect"""
+    PORT = 8001
+    def connectionMade(self):
+        BaseProtocol.connectionMade(self)
+        self.transport.loseConnection()
+
+class ReadAndDrop(BaseProtocol):
+    """Read 1st line of request, then drop connection"""
+    PORT = 8002
+    def dataReceived(self, data):
+        BaseProtocol.dataReceived(self, data)
+        self.transport.loseConnection()
+
+class GarbageStatus(BaseProtocol):
+    """Send garbage statusline"""
+    PORT = 8003
+    def dataReceived(self, data):
+        BaseProtocol.dataReceived(self, data)
+        self.write("welcome to the jungle baby\r\n")
+
+class BadHeader(BaseProtocol):
+    """Drop connection after a header is half-sent"""
+    PORT = 8004
+    def dataReceived(self, data):
+        BaseProtocol.dataReceived(self, data)
+        self.write("HTTP/1.1 200 OK\r\n")
+        self.write("Cache-Contr")
+        time.sleep(1)
+        self.transport.loseConnection()
+
+class PauseHeader(BaseProtocol):
+    """Pause for a second in middle of a header"""
+    PORT = 8005
+    def dataReceived(self, data):
+        BaseProtocol.dataReceived(self, data)
+        self.write("HTTP/1.1 200 OK\r\n")
+        self.write("Cache-Contr")
+        time.sleep(1)
+        self.write("ol: private\r\n\r\nwe've got fun and games")
+        time.sleep(1)
+        self.transport.loseConnection()
+
+class Redirect(BaseProtocol):
+    PORT = 8006
+    def dataReceived(self, data):
+        BaseProtocol.dataReceived(self, data)
+        self.write("HTTP/1.1 302 Moved Temporarily\r\n")
+        self.write("Content-Length: 0\r\n")
+        self.write("Location: http://shopping.yahoo.com/p:Canon PowerShot SD630 Digital Camera:1993588104;_ylc=X3oDMTFhZXNmcjFjBF9TAzI3MTYxNDkEc2VjA2ZwLXB1bHNlBHNsawNyc3NfcHVsc2U0LmluYw--\r\n\r\n")
+        self.transport.loseConnection()
+
+class DataDrop(BaseProtocol):
+    """Drop connection in body"""
+    PORT = 8007
+    def dataReceived(self, data):
+        if data.find("favico") >= 0:
+            self.write("HTTP/1.1 404 Not Found\r\n\r\n")
+            self.transport.loseConnection()
+            return
+
+        BaseProtocol.dataReceived(self, data)
+        self.write("HTTP/1.1 200 OK\r\n")
+#        self.write("Content-Length: 100\r\n\r\n")
+        self.write("\r\n")
+#        self.write("Data cuts off < 100 here!")
+#        time.sleep(4)
+        self.transport.loseConnection()
+
+class DropOnce(BaseProtocol):
+    """Drop every other connection"""
+    PORT = 8008
+    COUNT = 0
+    def dataReceived(self, data):
+        BaseProtocol.dataReceived(self, data)
+        self.write("HTTP/1.1 200 OK\r\n")
+        self.write("Content-Length: 5\r\n\r\n")
+
+        if (not(DropOnce.COUNT & 1)):
+            self.write("HE")
+        else:
+            self.write("HELLO")
+        self.transport.loseConnection()
+
+        DropOnce.COUNT += 1
+
+class NoCR(BaseProtocol):
+    """Send headers without carriage returns"""
+    PORT = 8009
+    def dataReceived(self, data):
+        BaseProtocol.dataReceived(self, data)
+        self.write("HTTP/1.1 200 OK\n")
+        self.write("Content-Length: 5\n\n")
+
+        self.write("HELLO")
+        self.transport.loseConnection()
+
+class PipeDrop(BaseProtocol):
+    PORT = 8010
+    COUNT = 0
+    def dataReceived(self, data):
+        BaseProtocol.dataReceived(self, data)
+        if not PipeDrop.COUNT % 3:
+            self.write("HTTP/1.1 200 OK\n")
+            self.write("Content-Length: 943\n\n")
+
+            self.write(open("./stfu.jpg").read())
+            PipeDrop.COUNT += 1
+
+        else:
+            self.transport.loseConnection()
+            PipeDrop.COUNT += 1
+
+class RedirectLoop(BaseProtocol):
+    """Redirect back to same resource"""
+    PORT = 8011
+    def dataReceived(self, data):
+        BaseProtocol.dataReceived(self, data)
+        self.write("HTTP/1.1 302 Moved Temporarily\r\n")
+        self.write("Content-Length: 0\r\n")
+        self.write("Location: http://localhost:8011/\r\n")
+        self.write("\r\n")
+        self.transport.loseConnection()
+
+class ReadAll(BaseProtocol):
+    """Read entire request"""
+    PORT = 8012
+
+    def connectionMade(self):
+        self.count = 0
+
+    def dataReceived(self, data):
+        BaseProtocol.dataReceived(self, data)
+        self.count += len(data)
+        if self.count == 190890:
+            self.transport.loseConnection()
+
+class Timeout(BaseProtocol):
+    """Timout sending body"""
+    PORT = 8013
+
+    def connectionMade(self):
+        self.count = 0
+
+    def dataReceived(self, data):
+        BaseProtocol.dataReceived(self, data)
+        if self.count == 0: self.write("HTTP/1.1 200 OK\r\n\r\n")
+        self.count += 1
+
+class SlowResponse(BaseProtocol):
+    """Ensure client does not time out on slow writes"""
+    PORT = 8014
+
+    def connectionMade(self):
+        self.count = 0
+
+    def dataReceived(self, data):
+        BaseProtocol.dataReceived(self, data)
+        if self.count == 0: self.write("HTTP/1.1 200 OK\r\n\r\n")
+        self.sendPack(0)
+
+    def sendPack(self, count):
+        if count > 10:
+            self.transport.loseConnection()
+
+        self.write("all work and no play makes jack a dull boy %s\n" % count)
+        d = defer.Deferred()
+        d.addCallback(self.sendPack)
+        reactor.callLater(15, d.callback, count + 1)
+
+
+# HTTP/1.1 200 OK
+# Cache-Control: private
+# Content-Type: text/html
+# Set-Cookie: PREF=ID=10644de62c423aa5:TM=1155044293:LM=1155044293:S=0lHtymefQRs2j7nD; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com
+# Server: GWS/2.1
+# Transfer-Encoding: chunked
+# Date: Tue, 08 Aug 2006 13:38:13 GMT
+
+def main():
+    # Initialize log
+    log.Log.getInstance(sys.stdout)
+
+    for protocol in Drop, ReadAndDrop, GarbageStatus, BadHeader, PauseHeader, \
+            Redirect, DataDrop, DropOnce, NoCR, PipeDrop, RedirectLoop, ReadAll, \
+            Timeout, SlowResponse:
+        factory = ServerFactory()
+        factory.protocol = protocol
+        reactor.listenTCP(protocol.PORT, factory)
+
+
+    reactor.run()
+
+if __name__ == '__main__':
+    main()
diff --git a/tools/axl/chewie.py b/tools/axl/chewie.py
new file mode 100755
index 0000000..7ed2ba6
--- /dev/null
+++ b/tools/axl/chewie.py
@@ -0,0 +1,184 @@
+#!/usr/bin/env python
+
+##
+## chewie.py
+## chews browser http log.  draws graph of connections
+## Be sure there is only one pageload in the log.
+##
+## you'll want to
+##   sudo apt-get install python-matplotlib
+## before running this
+##
+
+import sys, pylab
+
+# can't just use a dict, because there can be dups
+class Queue:
+    def __init__(self):
+        self.queue = []
+
+    def add(self, url, time):
+        self.queue.append([url, time])
+
+    def get(self, url):
+        for x in range(len(self.queue)):
+            rec = self.queue[x]
+            if rec[0] == url:
+                del self.queue[x]
+                return rec[1]
+
+## pull out request lag -- queue to start to done
+def lag():
+
+    font = {'color': '#909090', 'fontsize': 6}
+    extractMe = {
+        'RequestQueue.queueRequest': "Q",
+        'Connection.openHttpConnection()': "O",
+        'Request.sendRequest()': "S",
+        'Request.requestSent()': "T",
+        'processRequests()': 'R',
+        'Request.readResponse():': "D",         # done
+        'clearPipe()': 'U',	                    # unqueue
+        'Request.readResponse()': 'B',          # read data block
+        'Request.readResponseStatus():': 'HR',  # read http response line
+        'hdr': 'H',                             # http header
+        }
+    keys = extractMe.keys()
+
+    f = open(sys.argv[1], "r")
+
+    t0 = None
+
+    # thread, queued, opened, send, sent, reading, read, uri, server, y
+    # 0       1       2       3     4     5        6     7    8       9
+    vals = []
+
+    queued = Queue()
+    opened = {"http0": None,
+              "http1": None,
+              "http2": None,
+              "http3": None,
+              "http4": None,
+              "http5": None}
+    active = {"http0": [],
+              "http1": [],
+              "http2": [],
+              "http3": [],
+              "http4": [],
+              "http5": []}
+    connectionCount = 0
+    byteCount = 0
+    killed = [[], []]
+
+    while (True):
+        line = f.readline()
+        if len(line) == 0: break
+
+        splitup = line.split()
+
+        # http only
+        if splitup[0] != "V/http": continue
+
+        x = splitup[3:]
+
+        # filter to named lines
+        if x[2] not in keys: continue
+        x[2] = extractMe[x[2]]
+
+        # normalize time
+        if t0 == None: t0 = int(x[0])
+        x[0] = int(x[0]) - t0
+
+        thread, action = x[1], x[2]
+        if action == "Q":
+            time, url = x[0], x[3]
+            queued.add(url, time)
+        elif action == "O":
+            # save opened time and server for this thread, so we can stuff it in l8r
+            time, thread, host = x[0], x[1], x[4]
+            opened[thread] = [time, host, connectionCount]
+            connectionCount += 1
+        elif action == "S":
+            time, thread, url = x[0], x[1], x[3]
+            opentime, host, connection = opened[thread]
+            qtime = queued.get(url)
+            record = [thread, qtime, opentime, time, None, None, None, url, host, connection]
+            active[thread].append(record)
+        elif action == "T":
+            time, thread = x[0], x[1]
+            record = active[thread][-1]
+            record[4] = time
+        elif action == "R":
+            print x
+            if x[3] in ["sleep", "no", "wait"]: continue
+            time, thread, = x[0], x[1]
+            record = active[thread][0]
+            record[5] = time
+        elif action == 'U':
+            thread = x[1]
+            record = active[thread][0]
+            killed[0].append(record[9])
+            killed[1].append(x[0])
+            queued.add(record[7], record[1])
+            del active[thread][0]
+        elif action == "D":
+            time, thread = x[0], x[1]
+            record = active[thread][0]
+            record[6] = time
+            vals.append(record)
+            del active[thread][0]
+            print record
+            # print record[3] / 1000, record[6] / 1000, record[7]
+        elif action == "B":
+            byteCount += int(x[3])
+        elif action == "HR":
+            byteCount += int(x[2])
+
+    f.close()
+
+    rng = range(connectionCount)
+
+    opened = []
+    drawn = [False for x in rng]
+    for val in vals:
+        y= val[9]
+        if not drawn[y]:
+            drawn[y] = True
+            opened.append(val[2])
+            pylab.text(0, y - 0.25, "%s %s %s" % (val[9], val[0][4], val[8]), font)
+
+    # define limits
+    # pylab.plot([vals[-1][6]], rng)
+
+    print opened, rng
+    pylab.plot(opened, rng, 'ro')
+    pylab.plot(killed[1], killed[0], 'rx')
+
+    for val in vals:
+        thread, queued, opened, send, sent, reading, read, uri, server, y = val
+        # send arrow
+        arrow = pylab.Arrow(send, y, sent - send, 0)
+        arrow.set_facecolor("g")
+        ax = pylab.gca()
+        ax.add_patch(arrow)
+        # read arrow
+        arrow = pylab.Arrow(reading, y, read - reading, 0)
+        arrow.set_facecolor("r")
+        ax = pylab.gca()
+        ax.add_patch(arrow)
+
+    caption = \
+            "\nrequests: %s\n" % len(vals) + \
+            "byteCount: %s\n" % byteCount + \
+            "data rate: %s\n" % (1000 * byteCount / vals[-1][6])+ \
+            "connections: %s\n" % connectionCount
+
+    pylab.figtext(0.82, 0.30, caption, bbox=dict(facecolor='lightgrey', alpha=0.5))
+
+    # print lines, [[x, x] for x in range(len(vals))]
+    # pylab.plot(lines, [[x, x] for x in range(len(vals))], 'r-')
+
+    pylab.grid()
+    pylab.show()
+
+if __name__ == '__main__': lag()
diff --git a/tools/axl/chewperf.py b/tools/axl/chewperf.py
new file mode 100755
index 0000000..582bdb5
--- /dev/null
+++ b/tools/axl/chewperf.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+
+"""
+  chewperf.py: Chew an http perf log
+  bucketize
+
+"""
+
+import sys, time
+
+def resets():
+    f = open(sys.argv[1]).read()
+    rawLines = f.split('\n')
+
+    times = []
+    for x in range(len(rawLines)):
+        line = rawLines[x].split()
+        try:
+            if line[-1] == "SIGNAL_STRENGTH":
+                ts = int(rawLines[x - 1].split()[-1])
+                times.append(ts)
+        except:
+            pass
+
+    return times
+
+def augment():
+    f = open(sys.argv[1]).read()
+    rawLines = f.split('\r\n')
+
+    out = []
+    t0 = None
+    last = 0
+    for line in rawLines:
+        if "Pulled" in line:
+            chewed = [int(line.split()[5]), int(line.split()[7])]
+            if not t0: t0 = chewed[1]
+            tm = chewed[1] - t0
+            out.append("%s %d" % (line, (tm - last)))
+            last = tm
+        else:
+            out.append(line)
+    print "\n".join(out)
+
+def chew():
+    f = open(sys.argv[1]).read()
+    rawLines = f.split('\n')
+    lines = [x for x in rawLines if "Pulled" in x]
+
+    sidx = lines[0].split().index("Pulled")
+    print "sidx", sidx
+    chewed = [[int(x.split()[sidx + 2]), int(x.split()[sidx + 4])] for x in lines]
+
+    t0 = chewed[0][1]
+    tLast = chewed[-1][1]
+    chewed = [[x[1] - t0, x[0]] for x in chewed]
+
+    totalTime = tLast - t0
+    bytes = sum(x[1] for x in chewed)
+    print "total time", totalTime, "bytes", bytes, "rate", bytes * 1000 / totalTime
+
+    buckets = {}
+    for x in chewed:
+        bucket = x[0] / 1000
+        bytes = x[1]
+        if bucket in buckets:
+            buckets[bucket] += bytes
+        else:
+            buckets[bucket] = bytes
+
+    top = max(buckets.keys())
+    for x in range(top):
+        if x not in buckets.keys():
+            buckets[x] = 0
+
+    # smooth
+    window = [0 for x in range(5)]
+
+    for x in range(len(buckets.items())):
+        window[x % len(window)] = buckets.items()[x][1]
+        print "%s\t%s" % (buckets.items()[x][0], sum(window) / len(window))
+
+def main():
+    chew()
+
+if __name__ == '__main__':
+    main()
diff --git a/tools/axl/log.py b/tools/axl/log.py
new file mode 100644
index 0000000..7543270
--- /dev/null
+++ b/tools/axl/log.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+import time, sys
+import singletonmixin
+
+class Log(singletonmixin.Singleton):
+
+    def __init__(self, file):
+        """_file: filename or open file"""
+
+        if type(file) is str:
+            self._file = open(file, "a")
+        else:
+            self._file = file
+
+    def _getTime(self):
+        tm = time.time()
+        return "%s:%.2d" % (time.strftime('%m/%d/%Y %H:%M:%S',
+                                          time.localtime(tm)),
+                            int((tm - int(tm)) * 100))
+
+    def _log(self, *logstrs):
+        timeStr = self._getTime()
+        for ln in " ".join(map(str, logstrs)).split("\n"):
+            self._file.write("%s %s\n" % (timeStr, ln))
+        self._file.flush()
+
+    def debug(self, *logstrs):
+        self._log("D", *logstrs)
+    def info(self, *logstrs):
+        self._log("I", *logstrs)
+    def warn(self, *logstrs):
+        self._log("W", *logstrs)
+    def error(self, *logstrs):
+        self._log("E", *logstrs)
+
+    # default to info
+    log = info
+    __call__ = log
diff --git a/tools/axl/random.dat b/tools/axl/random.dat
new file mode 100644
index 0000000..48c5d48
--- /dev/null
+++ b/tools/axl/random.dat
Binary files differ
diff --git a/tools/axl/singletonmixin.py b/tools/axl/singletonmixin.py
new file mode 100644
index 0000000..7935d6d
--- /dev/null
+++ b/tools/axl/singletonmixin.py
@@ -0,0 +1,220 @@
+"""
+A Python Singleton mixin class that makes use of some of the ideas
+found at http://c2.com/cgi/wiki?PythonSingleton. Just inherit
+from it and you have a singleton. No code is required in
+subclasses to create singleton behavior -- inheritance from 
+Singleton is all that is needed.
+
+Assume S is a class that inherits from Singleton. Useful behaviors
+are:
+
+1) Getting the singleton:
+
+    S.getInstance() 
+    
+returns the instance of S. If none exists, it is created. 
+
+2) The usual idiom to construct an instance by calling the class, i.e.
+
+    S()
+    
+is disabled for the sake of clarity. If it were allowed, a programmer
+who didn't happen  notice the inheritance from Singleton might think he
+was creating a new instance. So it is felt that it is better to
+make that clearer by requiring the call of a class method that is defined in
+Singleton. An attempt to instantiate via S() will restult in an SingletonException
+being raised.
+
+3) If S.__init__(.) requires parameters, include them in the
+first call to S.getInstance(.). If subsequent calls have parameters,
+a SingletonException is raised.
+
+4) As an implementation detail, classes that inherit 
+from Singleton may not have their own __new__
+methods. To make sure this requirement is followed, 
+an exception is raised if a Singleton subclass includ
+es __new__. This happens at subclass instantiation
+time (by means of the MetaSingleton metaclass.
+
+By Gary Robinson, grobinson@transpose.com. No rights reserved -- 
+placed in the public domain -- which is only reasonable considering
+how much it owes to other people's version which are in the
+public domain. The idea of using a metaclass came from 
+a  comment on Gary's blog (see 
+http://www.garyrobinson.net/2004/03/python_singleto.html#comments). 
+Not guaranteed to be fit for any particular purpose. 
+"""
+
+class SingletonException(Exception):
+    pass
+
+class MetaSingleton(type):
+    def __new__(metaclass, strName, tupBases, dict):
+        if '__new__' in dict:
+            raise SingletonException, 'Can not override __new__ in a Singleton'
+        return super(MetaSingleton,metaclass).__new__(metaclass, strName, tupBases, dict)
+        
+    def __call__(cls, *lstArgs, **dictArgs):
+        raise SingletonException, 'Singletons may only be instantiated through getInstance()'
+        
+class Singleton(object):
+    __metaclass__ = MetaSingleton
+    
+    def getInstance(cls, *lstArgs):
+        """
+        Call this to instantiate an instance or retrieve the existing instance.
+        If the singleton requires args to be instantiated, include them the first
+        time you call getInstance.        
+        """
+        if cls._isInstantiated():
+            if len(lstArgs) != 0:
+                raise SingletonException, 'If no supplied args, singleton must already be instantiated, or __init__ must require no args'
+        else:
+            if len(lstArgs) != cls._getConstructionArgCountNotCountingSelf():
+                raise SingletonException, 'If the singleton requires __init__ args, supply them on first instantiation'
+            instance = cls.__new__(cls)
+            instance.__init__(*lstArgs)
+            cls.cInstance = instance
+        return cls.cInstance
+    getInstance = classmethod(getInstance)
+    
+    def _isInstantiated(cls):
+        return hasattr(cls, 'cInstance')
+    _isInstantiated = classmethod(_isInstantiated)
+
+    def _getConstructionArgCountNotCountingSelf(cls):
+        return cls.__init__.im_func.func_code.co_argcount - 1
+    _getConstructionArgCountNotCountingSelf = classmethod(_getConstructionArgCountNotCountingSelf)
+
+    def _forgetClassInstanceReferenceForTesting(cls):
+        """
+        This is designed for convenience in testing -- sometimes you 
+        want to get rid of a singleton during test code to see what
+        happens when you call getInstance() under a new situation.
+        
+        To really delete the object, all external references to it
+        also need to be deleted.
+        """
+        try:
+            delattr(cls,'cInstance')
+        except AttributeError:
+            # run up the chain of base classes until we find the one that has the instance
+            # and then delete it there
+            for baseClass in cls.__bases__: 
+                if issubclass(baseClass, Singleton):
+                    baseClass._forgetClassInstanceReferenceForTesting()
+    _forgetClassInstanceReferenceForTesting = classmethod(_forgetClassInstanceReferenceForTesting)
+
+
+if __name__ == '__main__':
+    import unittest
+    
+    class PublicInterfaceTest(unittest.TestCase):
+        def testReturnsSameObject(self):
+            """
+            Demonstrates normal use -- just call getInstance and it returns a singleton instance
+            """
+        
+            class A(Singleton): 
+                def __init__(self):
+                    super(A, self).__init__()
+                    
+            a1 = A.getInstance()
+            a2 = A.getInstance()
+            self.assertEquals(id(a1), id(a2))
+            
+        def testInstantiateWithMultiArgConstructor(self):
+            """
+            If the singleton needs args to construct, include them in the first
+            call to get instances.
+            """
+                    
+            class B(Singleton): 
+                    
+                def __init__(self, arg1, arg2):
+                    super(B, self).__init__()
+                    self.arg1 = arg1
+                    self.arg2 = arg2
+
+            b1 = B.getInstance('arg1 value', 'arg2 value')
+            b2 = B.getInstance()
+            self.assertEquals(b1.arg1, 'arg1 value')
+            self.assertEquals(b1.arg2, 'arg2 value')
+            self.assertEquals(id(b1), id(b2))
+            
+            
+        def testTryToInstantiateWithoutNeededArgs(self):
+            
+            class B(Singleton): 
+                    
+                def __init__(self, arg1, arg2):
+                    super(B, self).__init__()
+                    self.arg1 = arg1
+                    self.arg2 = arg2
+
+            self.assertRaises(SingletonException, B.getInstance)
+            
+        def testTryToInstantiateWithoutGetInstance(self):
+            """
+            Demonstrates that singletons can ONLY be instantiated through
+            getInstance, as long as they call Singleton.__init__ during construction.
+            
+            If this check is not required, you don't need to call Singleton.__init__().
+            """
+
+            class A(Singleton): 
+                def __init__(self):
+                    super(A, self).__init__()
+                    
+            self.assertRaises(SingletonException, A)
+            
+        def testDontAllowNew(self):
+        
+            def instantiatedAnIllegalClass():
+                class A(Singleton): 
+                    def __init__(self):
+                        super(A, self).__init__()
+                        
+                    def __new__(metaclass, strName, tupBases, dict):
+                        return super(MetaSingleton,metaclass).__new__(metaclass, strName, tupBases, dict)
+                                        
+            self.assertRaises(SingletonException, instantiatedAnIllegalClass)
+        
+        
+        def testDontAllowArgsAfterConstruction(self):
+            class B(Singleton): 
+                    
+                def __init__(self, arg1, arg2):
+                    super(B, self).__init__()
+                    self.arg1 = arg1
+                    self.arg2 = arg2
+
+            b1 = B.getInstance('arg1 value', 'arg2 value')
+            self.assertRaises(SingletonException, B, 'arg1 value', 'arg2 value')
+            
+        def test_forgetClassInstanceReferenceForTesting(self):
+            class A(Singleton): 
+                def __init__(self):
+                    super(A, self).__init__()
+            class B(A): 
+                def __init__(self):
+                    super(B, self).__init__()
+                    
+            # check that changing the class after forgetting the instance produces
+            # an instance of the new class
+            a = A.getInstance()
+            assert a.__class__.__name__ == 'A'
+            A._forgetClassInstanceReferenceForTesting()
+            b = B.getInstance()
+            assert b.__class__.__name__ == 'B'
+            
+            # check that invoking the 'forget' on a subclass still deletes the instance
+            B._forgetClassInstanceReferenceForTesting()
+            a = A.getInstance()
+            B._forgetClassInstanceReferenceForTesting()
+            b = B.getInstance()
+            assert b.__class__.__name__ == 'B'
+
+    unittest.main()
+
+    
diff --git a/tools/axl/stfu.jpg b/tools/axl/stfu.jpg
new file mode 100644
index 0000000..2cf38a5
--- /dev/null
+++ b/tools/axl/stfu.jpg
Binary files differ
diff --git a/tools/axl/udpEater.py b/tools/axl/udpEater.py
new file mode 100755
index 0000000..1440aad
--- /dev/null
+++ b/tools/axl/udpEater.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+"""
+  udpEater.py: receives UDP traffic
+
+"""
+
+import time, socket, string
+
+def main():
+    port = 9001
+
+    svrsocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    svrsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+    svrsocket.bind(('', port))
+
+    hostname = socket.gethostname()
+    ip = socket.gethostbyname(hostname)
+    print 'Server is at IP adress: ', ip
+    print 'Listening for requests on port %s ...' % port
+
+    count = 0
+    while count < 400:
+        data, address = svrsocket.recvfrom(8192)
+        print 'Received packet', count, data[:34]
+        count += 1
+
+if __name__ == "__main__":
+    main()
diff --git a/tools/axl/udpServer.py b/tools/axl/udpServer.py
new file mode 100755
index 0000000..fc37ab8
--- /dev/null
+++ b/tools/axl/udpServer.py
@@ -0,0 +1,29 @@
+# UDP server example
+import time, socket, string
+
+def main():
+
+    port = 9001
+    buf = open("random.dat").read()
+
+    svrsocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    svrsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+    svrsocket.bind(('', port))
+
+    # hostname = socket.gethostname()
+    hostname = "localhost"
+    ip = socket.gethostbyname(hostname)
+    print 'Server is at IP adress: ', ip
+    print 'Listening for requests on port %s ...' % port
+
+    data, address = svrsocket.recvfrom(8192)
+
+    count = 0
+    while count < 500:
+        print 'Sending packet', count, 'to', address[0]
+        svrsocket.sendto("%3.3s%s" % (count, buf), address)
+        time.sleep(0.08)
+        count += 1
+        
+if __name__ == "__main__":
+    main()
diff --git a/tools/ddms/Android.mk b/tools/ddms/Android.mk
new file mode 100644
index 0000000..82c248e
--- /dev/null
+++ b/tools/ddms/Android.mk
@@ -0,0 +1,5 @@
+# Copyright 2007 The Android Open Source Project
+#
+DDMS_LOCAL_DIR := $(call my-dir)
+include $(DDMS_LOCAL_DIR)/libs/Android.mk
+include $(DDMS_LOCAL_DIR)/app/Android.mk
diff --git a/tools/ddms/MODULE_LICENSE_APACHE2 b/tools/ddms/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/ddms/MODULE_LICENSE_APACHE2
diff --git a/tools/ddms/app/.classpath b/tools/ddms/app/.classpath
new file mode 100644
index 0000000..2fa1fb7
--- /dev/null
+++ b/tools/ddms/app/.classpath
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry excluding="Makefile|resources/" kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_SWT"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/ddmuilib"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/SdkStatsService"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/ddms/app/.project b/tools/ddms/app/.project
new file mode 100644
index 0000000..ffb19d7
--- /dev/null
+++ b/tools/ddms/app/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>ddms</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/ddms/app/Android.mk b/tools/ddms/app/Android.mk
new file mode 100644
index 0000000..3857706
--- /dev/null
+++ b/tools/ddms/app/Android.mk
@@ -0,0 +1,5 @@
+# Copyright 2007 The Android Open Source Project
+#
+DDMSAPP_LOCAL_DIR := $(call my-dir)
+include $(DDMSAPP_LOCAL_DIR)/etc/Android.mk
+include $(DDMSAPP_LOCAL_DIR)/src/Android.mk
diff --git a/tools/ddms/app/README b/tools/ddms/app/README
new file mode 100644
index 0000000..cc55ddd
--- /dev/null
+++ b/tools/ddms/app/README
@@ -0,0 +1,11 @@
+Using the Eclipse projects for ddms.
+
+ddms requires SWT to compile.
+
+SWT is available in the depot under //device/prebuild/<platform>/swt
+
+Because the build path cannot contain relative path that are not inside the project directory,
+the .classpath file references a user library called ANDROID_SWT.
+
+In order to compile the project, make a user library called ANDROID_SWT containing the jar
+available at //device/prebuild/<platform>/swt.
\ No newline at end of file
diff --git a/tools/ddms/app/etc/Android.mk b/tools/ddms/app/etc/Android.mk
new file mode 100644
index 0000000..9d69971
--- /dev/null
+++ b/tools/ddms/app/etc/Android.mk
@@ -0,0 +1,8 @@
+# Copyright 2007 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_EXECUTABLES := ddms
+include $(BUILD_HOST_PREBUILT)
+
diff --git a/tools/ddms/app/etc/ddms b/tools/ddms/app/etc/ddms
new file mode 100755
index 0000000..d809cfc
--- /dev/null
+++ b/tools/ddms/app/etc/ddms
@@ -0,0 +1,84 @@
+#!/bin/sh
+# Copyright 2005-2007, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+    newProg=`/bin/ls -ld "${prog}"`
+    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+    if expr "x${newProg}" : 'x/' >/dev/null; then
+        prog="${newProg}"
+    else
+        progdir=`dirname "${prog}"`
+        prog="${progdir}/${newProg}"
+    fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+jarfile=ddms.jar
+frameworkdir="$progdir"
+libdir="$progdir"
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/tools/lib
+    libdir=`dirname "$progdir"`/tools/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/framework
+    libdir=`dirname "$progdir"`/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    echo `basename "$prog"`": can't find $jarfile"
+    exit 1
+fi
+
+
+# Check args.
+if [ debug = "$1" ]; then
+    # add this in for debugging
+    java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
+    shift 1
+else
+    java_debug=
+fi
+
+# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
+if [ `uname` = "Darwin" ]; then
+    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"
+else
+    os_opts=
+    java_cmd="java"
+fi
+
+if [ "$OSTYPE" = "cygwin" ] ; then
+    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
+    progdir=`cygpath -w  "$progdir"`
+else
+    jarpath="$frameworkdir/$jarfile"
+fi
+
+# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
+# might need more memory, e.g. -Xmx128M
+exec "$java_cmd" -Xmx256M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -Dcom.android.ddms.bindir="$progdir" -jar "$jarpath" "$@"
diff --git a/tools/ddms/app/etc/ddms.bat b/tools/ddms/app/etc/ddms.bat
new file mode 100755
index 0000000..5da9fb5
--- /dev/null
+++ b/tools/ddms/app/etc/ddms.bat
@@ -0,0 +1,48 @@
+@echo off
+rem Copyright (C) 2007 The Android Open Source Project
+rem
+rem Licensed under the Apache License, Version 2.0 (the "License");
+rem you may not use this file except in compliance with the License.
+rem You may obtain a copy of the License at
+rem
+rem      http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+
+rem don't modify the caller's environment
+setlocal
+
+rem Set up prog to be the path of this script, including following symlinks,
+rem and set up progdir to be the fully-qualified pathname of its directory.
+set prog=%~f0
+
+rem Change current directory and drive to where the script is, to avoid
+rem issues with directories containing whitespaces.
+cd /d %~dp0
+
+set jarfile=ddms.jar
+set frameworkdir=
+set libdir=
+
+if exist %frameworkdir%%jarfile% goto JarFileOk
+    set frameworkdir=lib\
+    set libdir=lib\
+
+if exist %frameworkdir%%jarfile% goto JarFileOk
+    set frameworkdir=..\framework\
+    set libdir=..\lib\
+
+:JarFileOk
+
+if debug NEQ "%1" goto NoDebug
+    set java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
+    shift 1
+:NoDebug
+
+set jarpath=%frameworkdir%%jarfile%
+
+call java %java_debug% -Djava.ext.dirs=%frameworkdir% -Djava.library.path=%libdir% -Dcom.android.ddms.bindir= -jar %jarpath% %*
diff --git a/tools/ddms/app/etc/manifest.txt b/tools/ddms/app/etc/manifest.txt
new file mode 100644
index 0000000..84c8acd
--- /dev/null
+++ b/tools/ddms/app/etc/manifest.txt
@@ -0,0 +1 @@
+Main-Class: com.android.ddms.Main
diff --git a/tools/ddms/app/src/Android.mk b/tools/ddms/app/src/Android.mk
new file mode 100644
index 0000000..a013fa6
--- /dev/null
+++ b/tools/ddms/app/src/Android.mk
@@ -0,0 +1,22 @@
+# Copyright 2007 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_JAVA_RESOURCE_DIRS := resources
+
+LOCAL_JAR_MANIFEST := ../etc/manifest.txt
+LOCAL_JAVA_LIBRARIES := \
+	androidprefs \
+	sdkstats \
+	ddmlib \
+	ddmuilib \
+	swt \
+	org.eclipse.jface_3.2.0.I20060605-1400 \
+	org.eclipse.equinox.common_3.2.0.v20060603 \
+	org.eclipse.core.commands_3.2.0.I20060605-1400
+LOCAL_MODULE := ddms
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/ddms/app/src/com/android/ddms/AboutDialog.java b/tools/ddms/app/src/com/android/ddms/AboutDialog.java
new file mode 100644
index 0000000..2910e5e
--- /dev/null
+++ b/tools/ddms/app/src/com/android/ddms/AboutDialog.java
@@ -0,0 +1,153 @@
+/* //device/tools/ddms/src/com/android/ddms/AboutDialog.java
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.ddms;
+
+import com.android.ddmlib.Log;
+import com.android.ddmuilib.ImageHelper;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+import java.io.InputStream;
+
+/**
+ * Our "about" box.
+ */
+public class AboutDialog extends Dialog {
+
+    private Image logoImage;
+
+    /**
+     * Create with default style.
+     */
+    public AboutDialog(Shell parent) {
+        this(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+    }
+
+    /**
+     * Create with app-defined style.
+     */
+    public AboutDialog(Shell parent, int style) {
+        super(parent, style);
+    }
+
+    /**
+     * Prepare and display the dialog.
+     */
+    public void open() {
+        Shell parent = getParent();
+        Shell shell = new Shell(parent, getStyle());
+        shell.setText("About...");
+
+        logoImage = loadImage(shell, "ddms-logo.png"); // $NON-NLS-1$
+        createContents(shell);
+        shell.pack();
+
+        shell.open();
+        Display display = parent.getDisplay();
+        while (!shell.isDisposed()) {
+            if (!display.readAndDispatch())
+                display.sleep();
+        }
+
+        logoImage.dispose();
+    }
+
+    /*
+     * Load an image file from a resource.
+     *
+     * This depends on Display, so I'm not sure what the rules are for
+     * loading once and caching in a static class field.
+     */
+    private Image loadImage(Shell shell, String fileName) {
+        InputStream imageStream;
+        String pathName = "/images/" + fileName;  // $NON-NLS-1$
+
+        imageStream = this.getClass().getResourceAsStream(pathName);
+        if (imageStream == null) {
+            //throw new NullPointerException("couldn't find " + pathName);
+            Log.w("ddms", "Couldn't load " + pathName);
+            Display display = shell.getDisplay();
+            return ImageHelper.createPlaceHolderArt(display, 100, 50,
+                    display.getSystemColor(SWT.COLOR_BLUE));
+        }
+
+        Image img = new Image(shell.getDisplay(), imageStream);
+        if (img == null)
+            throw new NullPointerException("couldn't load " + pathName);
+        return img;
+    }
+
+    /*
+     * Create the about box contents.
+     */
+    private void createContents(final Shell shell) {
+        GridLayout layout;
+        GridData data;
+        Label label;
+
+        shell.setLayout(new GridLayout(2, false));
+
+        // Fancy logo
+        Label logo = new Label(shell, SWT.BORDER);
+        logo.setImage(logoImage);
+
+        // Text Area
+        Composite textArea = new Composite(shell, SWT.NONE);
+        layout = new GridLayout(1, true);
+        textArea.setLayout(layout);
+
+        // Text lines
+        label = new Label(textArea, SWT.NONE);
+        label.setText("Dalvik Debug Monitor v" + Main.VERSION);
+        label = new Label(textArea, SWT.NONE);
+        label.setText("Copyright 2007, The Android Open Source Project");
+        label = new Label(textArea, SWT.NONE);
+        label.setText("All Rights Reserved.");
+
+        // blank spot in grid
+        label = new Label(shell, SWT.NONE);
+
+        // "OK" button
+        Button ok = new Button(shell, SWT.PUSH);
+        ok.setText("OK");
+        data = new GridData(GridData.HORIZONTAL_ALIGN_END);
+        data.widthHint = 80;
+        ok.setLayoutData(data);
+        ok.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                shell.close();
+            }
+        });
+
+        shell.pack();
+
+        shell.setDefaultButton(ok);
+    }
+}
diff --git a/tools/ddms/app/src/com/android/ddms/DebugPortProvider.java b/tools/ddms/app/src/com/android/ddms/DebugPortProvider.java
new file mode 100644
index 0000000..89cc190
--- /dev/null
+++ b/tools/ddms/app/src/com/android/ddms/DebugPortProvider.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddms;
+
+import com.android.ddmlib.Device;
+import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * DDMS implementation of the IDebugPortProvider interface.
+ * This class handles saving/loading the list of static debug port from
+ * the preference store and provides the port number to the Device Monitor.
+ */
+public class DebugPortProvider implements IDebugPortProvider {
+
+    private static DebugPortProvider sThis  = new DebugPortProvider();
+
+    /** Preference name for the static port list. */
+    public static final String PREFS_STATIC_PORT_LIST = "android.staticPortList"; //$NON-NLS-1$
+
+    /**
+     * Mapping device serial numbers to maps. The embedded maps are mapping application names to
+     * debugger ports.
+     */
+    private Map<String, Map<String, Integer>> mMap;
+
+    public static DebugPortProvider getInstance() {
+        return sThis;
+    }
+
+    private DebugPortProvider() {
+        computePortList();
+    }
+
+    /**
+         * Returns a static debug port for the specified application running on the
+         * specified {@link Device}.
+         * @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)
+     */
+    public int getPort(Device device, String appName) {
+        if (mMap != null) {
+            Map<String, Integer> deviceMap = mMap.get(device.getSerialNumber());
+            if (deviceMap != null) {
+                Integer i = deviceMap.get(appName);
+                if (i != null) {
+                    return i.intValue();
+                }
+            }
+        }
+        return IDebugPortProvider.NO_STATIC_PORT;
+    }
+
+    /**
+     * Returns the map of Static debugger ports. The map links device serial numbers to
+     * a map linking application name to debugger ports.
+     */
+    public Map<String, Map<String, Integer>> getPortList() {
+        return mMap;
+    }
+
+    /**
+     * Create the map member from the values contained in the Preference Store.
+     */
+    private void computePortList() {
+        mMap = new HashMap<String, Map<String, Integer>>();
+
+        // get the prefs store
+        IPreferenceStore store = PrefsDialog.getStore();
+        String value = store.getString(PREFS_STATIC_PORT_LIST);
+
+        if (value != null && value.length() > 0) {
+            // format is
+            // port1|port2|port3|...
+            // where port# is
+            // appPackageName:appPortNumber:device-serial-number
+            String[] portSegments = value.split("\\|");  //$NON-NLS-1$
+            for (String seg : portSegments) {
+                String[] entry = seg.split(":");  //$NON-NLS-1$
+
+                // backward compatibility support. if we have only 2 entry, we default
+                // to the first emulator.
+                String deviceName = null;
+                if (entry.length == 3) {
+                    deviceName = entry[2];
+                } else {
+                    deviceName = Device.FIRST_EMULATOR_SN;
+                }
+
+                // get the device map
+                Map<String, Integer> deviceMap = mMap.get(deviceName);
+                if (deviceMap == null) {
+                    deviceMap = new HashMap<String, Integer>();
+                    mMap.put(deviceName, deviceMap);
+                }
+
+                deviceMap.put(entry[0], Integer.valueOf(entry[1]));
+            }
+        }
+    }
+
+    /**
+     * Sets new [device, app, port] values.
+     * The values are also sync'ed in the preference store.
+     * @param map The map containing the new values.
+     */
+    public void setPortList(Map<String, Map<String,Integer>> map) {
+        // update the member map.
+        mMap.clear();
+        mMap.putAll(map);
+
+        // create the value to store in the preference store.
+        // see format definition in getPortList
+        StringBuilder sb = new StringBuilder();
+
+        Set<String> deviceKeys = map.keySet();
+        for (String deviceKey : deviceKeys) {
+            Map<String, Integer> deviceMap = map.get(deviceKey);
+            if (deviceMap != null) {
+                Set<String> appKeys = deviceMap.keySet();
+
+                for (String appKey : appKeys) {
+                    Integer port = deviceMap.get(appKey);
+                    if (port != null) {
+                        sb.append(appKey).append(':').append(port.intValue()).append(':').
+                            append(deviceKey).append('|');
+                    }
+                }
+            }
+        }
+
+        String value = sb.toString();
+
+        // get the prefs store.
+        IPreferenceStore store = PrefsDialog.getStore();
+
+        // and give it the new value.
+        store.setValue(PREFS_STATIC_PORT_LIST, value);
+    }
+}
diff --git a/tools/ddms/app/src/com/android/ddms/DeviceCommandDialog.java b/tools/ddms/app/src/com/android/ddms/DeviceCommandDialog.java
new file mode 100644
index 0000000..2a1342e
--- /dev/null
+++ b/tools/ddms/app/src/com/android/ddms/DeviceCommandDialog.java
@@ -0,0 +1,423 @@
+/* //device/tools/ddms/src/com/android/ddms/DeviceCommandDialog.java
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.ddms;
+
+import com.android.ddmlib.Device;
+import com.android.ddmlib.IShellOutputReceiver;
+import com.android.ddmlib.Log;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+
+/**
+ * Execute a command on an ADB-attached device and save the output.
+ *
+ * There are several ways to do this.  One is to run a single command
+ * and show the output.  Another is to have several possible commands and
+ * let the user click a button next to the one (or ones) they want.  This
+ * currently uses the simple 1:1 form.
+ */
+public class DeviceCommandDialog extends Dialog {
+
+    public static final int DEVICE_STATE = 0;
+    public static final int APP_STATE = 1;
+    public static final int RADIO_STATE = 2;
+    public static final int LOGCAT = 3;
+
+    private String mCommand;
+    private String mFileName;
+
+    private Label mStatusLabel;
+    private Button mCancelDone;
+    private Button mSave;
+    private Text mText;
+    private Font mFont = null;
+    private boolean mCancel;
+    private boolean mFinished;
+
+
+    /**
+     * Create with default style.
+     */
+    public DeviceCommandDialog(String command, String fileName, Shell parent) {
+        // don't want a close button, but it seems hard to get rid of on GTK
+        // keep it on all platforms for consistency
+        this(command, fileName, parent,
+            SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL | SWT.RESIZE);
+    }
+
+    /**
+     * Create with app-defined style.
+     */
+    public DeviceCommandDialog(String command, String fileName, Shell parent,
+        int style)
+    {
+        super(parent, style);
+        mCommand = command;
+        mFileName = fileName;
+    }
+
+    /**
+     * Prepare and display the dialog.
+     * @param currentDevice
+     */
+    public void open(Device currentDevice) {
+        Shell parent = getParent();
+        Shell shell = new Shell(parent, getStyle());
+        shell.setText("Remote Command");
+
+        mFinished = false;
+        mFont = findFont(shell.getDisplay());
+        createContents(shell);
+
+        // Getting weird layout behavior under Linux when Text is added --
+        // looks like text widget has min width of 400 when FILL_HORIZONTAL
+        // is used, and layout gets tweaked to force this.  (Might be even
+        // more with the scroll bars in place -- it wigged out when the
+        // file save dialog was invoked.)
+        shell.setMinimumSize(500, 200);
+        shell.setSize(800, 600);
+        shell.open();
+
+        executeCommand(shell, currentDevice);
+
+        Display display = parent.getDisplay();
+        while (!shell.isDisposed()) {
+            if (!display.readAndDispatch())
+                display.sleep();
+        }
+
+        if (mFont != null)
+            mFont.dispose();
+    }
+
+    /*
+     * Create a text widget to show the output and some buttons to
+     * manage things.
+     */
+    private void createContents(final Shell shell) {
+        GridData data;
+
+        shell.setLayout(new GridLayout(2, true));
+
+        shell.addListener(SWT.Close, new Listener() {
+            public void handleEvent(Event event) {
+                if (!mFinished) {
+                    Log.i("ddms", "NOT closing - cancelling command");
+                    event.doit = false;
+                    mCancel = true;
+                }
+            }
+        });
+
+        mStatusLabel = new Label(shell, SWT.NONE);
+        mStatusLabel.setText("Executing '" + shortCommandString() + "'");
+        data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+        data.horizontalSpan = 2;
+        mStatusLabel.setLayoutData(data);
+
+        mText = new Text(shell, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
+        mText.setEditable(false);
+        mText.setFont(mFont);
+        data = new GridData(GridData.FILL_BOTH);
+        data.horizontalSpan = 2;
+        mText.setLayoutData(data);
+
+        // "save" button
+        mSave = new Button(shell, SWT.PUSH);
+        mSave.setText("Save");
+        data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+        data.widthHint = 80;
+        mSave.setLayoutData(data);
+        mSave.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                saveText(shell);
+            }
+        });
+        mSave.setEnabled(false);
+
+        // "cancel/done" button
+        mCancelDone = new Button(shell, SWT.PUSH);
+        mCancelDone.setText("Cancel");
+        data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+        data.widthHint = 80;
+        mCancelDone.setLayoutData(data);
+        mCancelDone.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                if (!mFinished)
+                    mCancel = true;
+                else
+                    shell.close();
+            }
+        });
+    }
+
+    /*
+     * Figure out what font to use.
+     *
+     * Returns "null" if we can't figure it out, which SWT understands to
+     * mean "use default system font".
+     */
+    private Font findFont(Display display) {
+        String fontStr = PrefsDialog.getStore().getString("textOutputFont");
+        if (fontStr != null) {
+            FontData fdat = new FontData(fontStr);
+            if (fdat != null)
+                return new Font(display, fdat);
+        }
+        return null;
+    }
+
+
+    /*
+     * Callback class for command execution.
+     */
+    class Gatherer extends Thread implements IShellOutputReceiver {
+        public static final int RESULT_UNKNOWN = 0;
+        public static final int RESULT_SUCCESS = 1;
+        public static final int RESULT_FAILURE = 2;
+        public static final int RESULT_CANCELLED = 3;
+
+        private Shell mShell;
+        private String mCommand;
+        private Text mText;
+        private int mResult;
+        private Device mDevice;
+
+        /**
+         * Constructor; pass in the text widget that will receive the output.
+         * @param device
+         */
+        public Gatherer(Shell shell, Device device, String command, Text text) {
+            mShell = shell;
+            mDevice = device;
+            mCommand = command;
+            mText = text;
+            mResult = RESULT_UNKNOWN;
+
+            // this is in outer class
+            mCancel = false;
+        }
+
+        /**
+         * Thread entry point.
+         */
+        @Override
+        public void run() {
+
+            if (mDevice == null) {
+                Log.w("ddms", "Cannot execute command: no device selected.");
+                mResult = RESULT_FAILURE;
+            } else {
+                try {
+                    mDevice.executeShellCommand(mCommand, this);
+                    if (mCancel)
+                        mResult = RESULT_CANCELLED;
+                    else
+                        mResult = RESULT_SUCCESS;
+                }
+                catch (IOException ioe) {
+                    Log.w("ddms", "Remote exec failed: " + ioe.getMessage());
+                    mResult = RESULT_FAILURE;
+                }
+            }
+
+            mShell.getDisplay().asyncExec(new Runnable() {
+                public void run() {
+                    updateForResult(mResult);
+                }
+            });
+        }
+
+        /**
+         * Called by executeRemoteCommand().
+         */
+        public void addOutput(byte[] data, int offset, int length) {
+
+            Log.v("ddms", "received " + length + " bytes");
+            try {
+                final String text;
+                text = new String(data, offset, length, "ISO-8859-1");
+
+                // add to text widget; must do in UI thread
+                mText.getDisplay().asyncExec(new Runnable() {
+                    public void run() {
+                        mText.append(text);
+                    }
+                });
+            }
+            catch (UnsupportedEncodingException uee) {
+                uee.printStackTrace();      // not expected
+            }
+        }
+
+        public void flush() {
+            // nothing to flush.
+        }
+
+        /**
+         * Called by executeRemoteCommand().
+         */
+        public boolean isCancelled() {
+            return mCancel;
+        }
+    };
+
+    /*
+     * Execute a remote command, add the output to the text widget, and
+     * update controls.
+     *
+     * We have to run the command in a thread so that the UI continues
+     * to work.
+     */
+    private void executeCommand(Shell shell, Device device) {
+        Gatherer gath = new Gatherer(shell, device, commandString(), mText);
+        gath.start();
+    }
+
+    /*
+     * Update the controls after the remote operation completes.  This
+     * must be called from the UI thread.
+     */
+    private void updateForResult(int result) {
+        if (result == Gatherer.RESULT_SUCCESS) {
+            mStatusLabel.setText("Successfully executed '"
+                + shortCommandString() + "'");
+            mSave.setEnabled(true);
+        } else if (result == Gatherer.RESULT_CANCELLED) {
+            mStatusLabel.setText("Execution cancelled; partial results below");
+            mSave.setEnabled(true);     // save partial
+        } else if (result == Gatherer.RESULT_FAILURE) {
+            mStatusLabel.setText("Failed");
+        }
+        mStatusLabel.pack();
+        mCancelDone.setText("Done");
+        mFinished = true;
+    }
+
+    /*
+     * Allow the user to save the contents of the text dialog.
+     */
+    private void saveText(Shell shell) {
+        FileDialog dlg = new FileDialog(shell, SWT.SAVE);
+        String fileName;
+
+        dlg.setText("Save output...");
+        dlg.setFileName(defaultFileName());
+        dlg.setFilterPath(PrefsDialog.getStore().getString("lastTextSaveDir"));
+        dlg.setFilterNames(new String[] {
+            "Text Files (*.txt)"
+        });
+        dlg.setFilterExtensions(new String[] {
+            "*.txt"
+        });
+
+        fileName = dlg.open();
+        if (fileName != null) {
+            PrefsDialog.getStore().setValue("lastTextSaveDir",
+                                            dlg.getFilterPath());
+
+            Log.i("ddms", "Saving output to " + fileName);
+
+            /*
+             * Convert to 8-bit characters.
+             */
+            String text = mText.getText();
+            byte[] ascii;
+            try {
+                ascii = text.getBytes("ISO-8859-1");
+            }
+            catch (UnsupportedEncodingException uee) {
+                uee.printStackTrace();
+                ascii = new byte[0];
+            }
+
+            /*
+             * Output data, converting CRLF to LF.
+             */
+            try {
+                int length = ascii.length;
+
+                FileOutputStream outFile = new FileOutputStream(fileName);
+                BufferedOutputStream out = new BufferedOutputStream(outFile);
+                for (int i = 0; i < length; i++) {
+                    if (i < length-1 &&
+                        ascii[i] == 0x0d && ascii[i+1] == 0x0a)
+                    {
+                        continue;
+                    }
+                    out.write(ascii[i]);
+                }
+                out.close();        // flush buffer, close file
+            }
+            catch (IOException ioe) {
+                Log.w("ddms", "Unable to save " + fileName + ": " + ioe);
+            }
+        }
+    }
+
+
+    /*
+     * Return the shell command we're going to use.
+     */
+    private String commandString() {
+        return mCommand;
+
+    }
+
+    /*
+     * Return a default filename for the "save" command.
+     */
+    private String defaultFileName() {
+        return mFileName;
+    }
+
+    /*
+     * Like commandString(), but length-limited.
+     */
+    private String shortCommandString() {
+        String str = commandString();
+        if (str.length() > 50)
+            return str.substring(0, 50) + "...";
+        else
+            return str;
+    }
+}
+
diff --git a/tools/ddms/app/src/com/android/ddms/DropdownSelectionListener.java b/tools/ddms/app/src/com/android/ddms/DropdownSelectionListener.java
new file mode 100644
index 0000000..99d63ce
--- /dev/null
+++ b/tools/ddms/app/src/com/android/ddms/DropdownSelectionListener.java
@@ -0,0 +1,80 @@
+/* //device/tools/ddms/src/com/android/ddms/DropdownSelectionListener.java
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.ddms;
+
+import com.android.ddmlib.Log;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.ToolItem;
+
+/**
+ * Helper class for drop-down menus in toolbars.
+ */
+public class DropdownSelectionListener extends SelectionAdapter {
+    private Menu mMenu;
+    private ToolItem mDropdown;
+
+    /**
+     * Basic constructor.  Creates an empty Menu to hold items.
+     */
+    public DropdownSelectionListener(ToolItem item) {
+        mDropdown = item;
+        mMenu = new Menu(item.getParent().getShell(), SWT.POP_UP);
+    }
+
+    /**
+     * Add an item to the dropdown menu.
+     */
+    public void add(String label) {
+        MenuItem item = new MenuItem(mMenu, SWT.NONE);
+        item.setText(label);
+        item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // update the dropdown's text to match the selection
+                MenuItem sel = (MenuItem) e.widget;
+                mDropdown.setText(sel.getText());
+            }
+        });
+    }
+
+    /**
+     * Invoked when dropdown or neighboring arrow is clicked.
+     */
+    @Override
+    public void widgetSelected(SelectionEvent e) {
+        if (e.detail == SWT.ARROW) {
+            // arrow clicked, show menu
+            ToolItem item = (ToolItem) e.widget;
+            Rectangle rect = item.getBounds();
+            Point pt = item.getParent().toDisplay(new Point(rect.x, rect.y));
+            mMenu.setLocation(pt.x, pt.y + rect.height);
+            mMenu.setVisible(true);
+        } else {
+            // button clicked
+            Log.i("ddms", mDropdown.getText() + " Pressed");
+        }
+    }
+}
+
diff --git a/tools/ddms/app/src/com/android/ddms/Main.java b/tools/ddms/app/src/com/android/ddms/Main.java
new file mode 100644
index 0000000..d63b884
--- /dev/null
+++ b/tools/ddms/app/src/com/android/ddms/Main.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddms;
+
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.DebugPortManager;
+import com.android.ddmlib.Log;
+import com.android.sdkstats.SdkStatsService;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+
+
+/**
+ * Start the UI and network.
+ */
+public class Main {
+
+    /** User visible version number. */
+    public static final String VERSION = "0.8.1";
+
+    public Main() {
+    }
+
+    /*
+     * If a thread bails with an uncaught exception, bring the whole
+     * thing down.
+     */
+    private static class UncaughtHandler implements Thread.UncaughtExceptionHandler {
+        public void uncaughtException(Thread t, Throwable e) {
+            Log.e("ddms", "shutting down due to uncaught exception");
+
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+            e.printStackTrace(pw);
+            Log.e("ddms", sw.toString());
+
+            System.exit(1);
+        }
+    }
+
+    /**
+     * Parse args, start threads.
+     */
+    public static void main(String[] args) {
+        // In order to have the AWT/SWT bridge work on Leopard, we do this little hack.
+        String os = System.getProperty("os.name"); //$NON-NLS-1$
+        if (os.startsWith("Mac OS")) { //$NON-NLS-1$
+            RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
+            System.setProperty(
+                    "JAVA_STARTED_ON_FIRST_THREAD_" + (rt.getName().split("@"))[0], //$NON-NLS-1$
+                    "1"); //$NON-NLS-1$
+        }
+        
+        Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());
+
+        // load prefs and init the default values
+        PrefsDialog.init();
+
+        Log.d("ddms", "Initializing");
+
+        // the "ping" argument means to check in with the server and exit
+        // the application name and version number must also be supplied
+        if (args.length >= 3 && args[0].equals("ping")) {
+            SdkStatsService.ping(args[1], args[2]);
+            return;
+        } else if (args.length > 0) {
+            Log.e("ddms", "Unknown argument: " + args[0]);
+            System.exit(1);
+        }
+
+        // ddms itself is wanted: send a ping for ourselves
+        SdkStatsService.ping("ddms", VERSION);  //$NON-NLS-1$
+
+        DebugPortManager.setProvider(DebugPortProvider.getInstance());
+
+        // create the three main threads
+        UIThread ui = UIThread.getInstance();
+
+        try {
+            ui.runUI();
+        } finally {
+            PrefsDialog.save();
+    
+            AndroidDebugBridge.terminate();
+        }
+
+        Log.d("ddms", "Bye");
+        
+        // this is kinda bad, but on MacOS the shutdown doesn't seem to finish because of
+        // a thread called AWT-Shutdown. This will help while I track this down.
+        System.exit(0);
+    }
+}
diff --git a/tools/ddms/app/src/com/android/ddms/PrefsDialog.java b/tools/ddms/app/src/com/android/ddms/PrefsDialog.java
new file mode 100644
index 0000000..69c48b0
--- /dev/null
+++ b/tools/ddms/app/src/com/android/ddms/PrefsDialog.java
@@ -0,0 +1,545 @@
+/* //device/tools/ddms/src/com/android/ddms/PrefsDialog.java
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.ddms;
+
+import com.android.ddmlib.DdmPreferences;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmuilib.DdmUiPreferences;
+import com.android.ddmuilib.PortFieldEditor;
+import com.android.sdkstats.SdkStatsService;
+
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.DirectoryFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.jface.preference.FontFieldEditor;
+import org.eclipse.jface.preference.IntegerFieldEditor;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.jface.preference.PreferenceManager;
+import org.eclipse.jface.preference.PreferenceNode;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.preference.PreferenceStore;
+import org.eclipse.jface.preference.RadioGroupFieldEditor;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.Shell;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Preferences dialog.
+ */
+public final class PrefsDialog {
+
+    // Preference store.
+    private static PreferenceStore mPrefStore;
+
+    // public const values for storage
+    public final static String SHELL_X = "shellX"; //$NON-NLS-1$
+    public final static String SHELL_Y = "shellY"; //$NON-NLS-1$
+    public final static String SHELL_WIDTH = "shellWidth"; //$NON-NLS-1$
+    public final static String SHELL_HEIGHT = "shellHeight"; //$NON-NLS-1$
+    public final static String EXPLORER_SHELL_X = "explorerShellX"; //$NON-NLS-1$
+    public final static String EXPLORER_SHELL_Y = "explorerShellY"; //$NON-NLS-1$
+    public final static String EXPLORER_SHELL_WIDTH = "explorerShellWidth"; //$NON-NLS-1$
+    public final static String EXPLORER_SHELL_HEIGHT = "explorerShellHeight"; //$NON-NLS-1$
+    public final static String SHOW_NATIVE_HEAP = "native"; //$NON-NLS-1$
+
+    public final static String LOGCAT_COLUMN_MODE = "ddmsLogColumnMode"; //$NON-NLS-1$
+    public final static String LOGCAT_FONT = "ddmsLogFont"; //$NON-NLS-1$
+
+    public final static String LOGCAT_COLUMN_MODE_AUTO = "auto"; //$NON-NLS-1$
+    public final static String LOGCAT_COLUMN_MODE_MANUAL = "manual"; //$NON-NLS-1$
+
+    private final static String PREFS_DEBUG_PORT_BASE = "adbDebugBasePort"; //$NON-NLS-1$
+    private final static String PREFS_SELECTED_DEBUG_PORT = "debugSelectedPort"; //$NON-NLS-1$
+    private final static String PREFS_DEFAULT_THREAD_UPDATE = "defaultThreadUpdateEnabled"; //$NON-NLS-1$
+    private final static String PREFS_DEFAULT_HEAP_UPDATE = "defaultHeapUpdateEnabled"; //$NON-NLS-1$
+
+    private final static String PREFS_THREAD_REFRESH_INTERVAL = "threadStatusInterval"; //$NON-NLS-1$
+
+    private final static String PREFS_LOG_LEVEL = "ddmsLogLevel"; //$NON-NLS-1$
+
+
+    /**
+     * Private constructor -- do not instantiate.
+     */
+    private PrefsDialog() {}
+
+    /**
+     * Return the PreferenceStore that holds our values.
+     */
+    public static PreferenceStore getStore() {
+        return mPrefStore;
+    }
+
+    /**
+     * Save the prefs to the config file.
+     */
+    public static void save() {
+        try {
+            mPrefStore.save();
+        }
+        catch (IOException ioe) {
+            Log.w("ddms", "Failed saving prefs file: " + ioe.getMessage());
+        }
+    }
+
+    /**
+     * Do some one-time prep.
+     *
+     * The original plan was to let the individual classes define their
+     * own defaults, which we would get and then override with the config
+     * file.  However, PreferencesStore.load() doesn't trigger the "changed"
+     * events, which means we have to pull the loaded config values out by
+     * hand.
+     *
+     * So, we set the defaults, load the values from the config file, and
+     * then run through and manually export the values.  Then we duplicate
+     * the second part later on for the "changed" events.
+     */
+    public static void init() {
+        assert mPrefStore == null;
+        
+        mPrefStore = SdkStatsService.getPreferenceStore();
+        
+        if (mPrefStore == null) {
+            // we have a serious issue here...
+            Log.e("ddms",
+                    "failed to access both the user HOME directory and the system wide temp folder. Quitting.");
+            System.exit(1);
+        }
+
+        // configure default values
+        setDefaults(System.getProperty("user.home")); //$NON-NLS-1$
+
+        // listen for changes
+        mPrefStore.addPropertyChangeListener(new ChangeListener());
+
+        // Now we initialize the value of the preference, from the values in the store.
+
+        // First the ddm lib.
+        DdmPreferences.setDebugPortBase(mPrefStore.getInt(PREFS_DEBUG_PORT_BASE));
+        DdmPreferences.setSelectedDebugPort(mPrefStore.getInt(PREFS_SELECTED_DEBUG_PORT));
+        DdmPreferences.setLogLevel(mPrefStore.getString(PREFS_LOG_LEVEL));
+        DdmPreferences.setInitialThreadUpdate(mPrefStore.getBoolean(PREFS_DEFAULT_THREAD_UPDATE));
+        DdmPreferences.setInitialHeapUpdate(mPrefStore.getBoolean(PREFS_DEFAULT_HEAP_UPDATE));
+
+        // some static values
+        String out = System.getenv("ANDROID_PRODUCT_OUT"); //$NON-NLS-1$
+        DdmUiPreferences.setSymbolsLocation(out + File.separator + "symbols"); //$NON-NLS-1$
+        DdmUiPreferences.setAddr2LineLocation("arm-eabi-addr2line"); //$NON-NLS-1$
+
+        String traceview = System.getProperty("com.android.ddms.bindir");  //$NON-NLS-1$
+        if (traceview != null && traceview.length() != 0) {
+            traceview += File.separator + "traceview"; //$NON-NLS-1$
+        } else {
+            traceview = "traceview"; //$NON-NLS-1$
+        }
+        DdmUiPreferences.setTraceviewLocation(traceview);
+
+        // Now the ddmui lib
+        DdmUiPreferences.setStore(mPrefStore);
+        DdmUiPreferences.setThreadRefreshInterval(mPrefStore.getInt(PREFS_THREAD_REFRESH_INTERVAL));
+    }
+
+    /*
+     * Set default values for all preferences.  These are either defined
+     * statically or are based on the values set by the class initializers
+     * in other classes.
+     *
+     * The other threads (e.g. VMWatcherThread) haven't been created yet,
+     * so we want to use static values rather than reading fields from
+     * class.getInstance().
+     */
+    private static void setDefaults(String homeDir) {
+        mPrefStore.setDefault(PREFS_DEBUG_PORT_BASE, DdmPreferences.DEFAULT_DEBUG_PORT_BASE);
+
+        mPrefStore.setDefault(PREFS_SELECTED_DEBUG_PORT,
+                DdmPreferences.DEFAULT_SELECTED_DEBUG_PORT);
+
+        mPrefStore.setDefault(PREFS_DEFAULT_THREAD_UPDATE, true);
+        mPrefStore.setDefault(PREFS_DEFAULT_HEAP_UPDATE, false);
+        mPrefStore.setDefault(PREFS_THREAD_REFRESH_INTERVAL,
+            DdmUiPreferences.DEFAULT_THREAD_REFRESH_INTERVAL);
+
+        mPrefStore.setDefault("textSaveDir", homeDir); //$NON-NLS-1$
+        mPrefStore.setDefault("imageSaveDir", homeDir); //$NON-NLS-1$
+
+        mPrefStore.setDefault(PREFS_LOG_LEVEL, "info"); //$NON-NLS-1$
+
+        // choose a default font for the text output
+        FontData fdat = new FontData("Courier", 10, SWT.NORMAL); //$NON-NLS-1$
+        mPrefStore.setDefault("textOutputFont", fdat.toString()); //$NON-NLS-1$
+
+        // layout information.
+        mPrefStore.setDefault(SHELL_X, 100);
+        mPrefStore.setDefault(SHELL_Y, 100);
+        mPrefStore.setDefault(SHELL_WIDTH, 800);
+        mPrefStore.setDefault(SHELL_HEIGHT, 600);
+
+        mPrefStore.setDefault(EXPLORER_SHELL_X, 50);
+        mPrefStore.setDefault(EXPLORER_SHELL_Y, 50);
+
+        mPrefStore.setDefault(SHOW_NATIVE_HEAP, false);
+    }
+
+
+    /*
+     * Create a "listener" to take action when preferences change.  These are
+     * required for ongoing activities that don't check prefs on each use.
+     *
+     * This is only invoked when something explicitly changes the value of
+     * a preference (e.g. not when the prefs file is loaded).
+     */
+    private static class ChangeListener implements IPropertyChangeListener {
+        public void propertyChange(PropertyChangeEvent event) {
+            String changed = event.getProperty();
+
+            if (changed.equals(PREFS_DEBUG_PORT_BASE)) {
+                DdmPreferences.setDebugPortBase(mPrefStore.getInt(PREFS_DEBUG_PORT_BASE));
+            } else if (changed.equals(PREFS_SELECTED_DEBUG_PORT)) {
+                DdmPreferences.setSelectedDebugPort(mPrefStore.getInt(PREFS_SELECTED_DEBUG_PORT));
+            } else if (changed.equals(PREFS_LOG_LEVEL)) {
+                DdmPreferences.setLogLevel((String)event.getNewValue());
+            } else if (changed.equals("textSaveDir")) {
+                mPrefStore.setValue("lastTextSaveDir",
+                    (String) event.getNewValue());
+            } else if (changed.equals("imageSaveDir")) {
+                mPrefStore.setValue("lastImageSaveDir",
+                    (String) event.getNewValue());
+
+            } else {
+                Log.v("ddms", "Preference change: " + event.getProperty()
+                    + ": '" + event.getOldValue()
+                    + "' --> '" + event.getNewValue() + "'");
+            }
+        }
+    }
+
+
+    /**
+     * Create and display the dialog.
+     */
+    public static void run(Shell shell) {
+        assert mPrefStore != null;
+
+        PreferenceManager prefMgr = new PreferenceManager();
+
+        PreferenceNode node, subNode;
+
+        // this didn't work -- got NPE, possibly from class lookup:
+        //PreferenceNode app = new PreferenceNode("app", "Application", null,
+        //    AppPrefs.class.getName());
+
+        node = new PreferenceNode("client", new ClientPrefs());
+        prefMgr.addToRoot(node);
+
+        subNode = new PreferenceNode("panel", new PanelPrefs());
+        //prefMgr.addTo(node.getId(), subNode);
+        prefMgr.addToRoot(subNode);
+
+        node = new PreferenceNode("device", new DevicePrefs());
+        prefMgr.addToRoot(node);
+
+        node = new PreferenceNode("LogCat", new LogCatPrefs());
+        prefMgr.addToRoot(node);
+
+        node = new PreferenceNode("app", new AppPrefs());
+        prefMgr.addToRoot(node);
+
+        node = new PreferenceNode("stats", new UsageStatsPrefs());
+        prefMgr.addToRoot(node);
+
+        PreferenceDialog dlg = new PreferenceDialog(shell, prefMgr);
+        dlg.setPreferenceStore(mPrefStore);
+
+        // run it
+        dlg.open();
+
+        // save prefs
+        try {
+            mPrefStore.save();
+        }
+        catch (IOException ioe) {
+        }
+
+        // discard the stuff we created
+        //prefMgr.dispose();
+        //dlg.dispose();
+    }
+
+    /**
+     * "Client Scan" prefs page.
+     */
+    private static class ClientPrefs extends FieldEditorPreferencePage {
+
+        /**
+         * Basic constructor.
+         */
+        public ClientPrefs() {
+            super(GRID);        // use "grid" layout so edit boxes line up
+            setTitle("Client Scan");
+        }
+
+         /**
+         * Create field editors.
+         */
+        @Override
+        protected void createFieldEditors() {
+            IntegerFieldEditor ife;
+
+            ife = new PortFieldEditor(PREFS_DEBUG_PORT_BASE,
+                "ADB debugger base:", getFieldEditorParent());
+            addField(ife);
+
+            ife = new PortFieldEditor(PREFS_SELECTED_DEBUG_PORT,
+                "Debug selected VM:", getFieldEditorParent());
+            addField(ife);
+        }
+    }
+
+    /**
+     * "Panel" prefs page.
+     */
+    private static class PanelPrefs extends FieldEditorPreferencePage {
+
+        /**
+         * Basic constructor.
+         */
+        public PanelPrefs() {
+            super(FLAT);        // use "flat" layout
+            setTitle("Info Panels");
+        }
+
+        /**
+         * Create field editors.
+         */
+        @Override
+        protected void createFieldEditors() {
+            BooleanFieldEditor bfe;
+            IntegerFieldEditor ife;
+
+            bfe = new BooleanFieldEditor(PREFS_DEFAULT_THREAD_UPDATE,
+                "Thread updates enabled by default", getFieldEditorParent());
+            addField(bfe);
+
+            bfe = new BooleanFieldEditor(PREFS_DEFAULT_HEAP_UPDATE,
+                "Heap updates enabled by default", getFieldEditorParent());
+            addField(bfe);
+
+            ife = new IntegerFieldEditor(PREFS_THREAD_REFRESH_INTERVAL,
+                "Thread status interval (seconds):", getFieldEditorParent());
+            ife.setValidRange(1, 60);
+            addField(ife);
+        }
+    }
+
+    /**
+     * "Device" prefs page.
+     */
+    private static class DevicePrefs extends FieldEditorPreferencePage {
+
+        /**
+         * Basic constructor.
+         */
+        public DevicePrefs() {
+            super(FLAT);        // use "flat" layout
+            setTitle("Device");
+        }
+
+        /**
+         * Create field editors.
+         */
+        @Override
+        protected void createFieldEditors() {
+            DirectoryFieldEditor dfe;
+            FontFieldEditor ffe;
+
+            dfe = new DirectoryFieldEditor("textSaveDir",
+                "Default text save dir:", getFieldEditorParent());
+            addField(dfe);
+
+            dfe = new DirectoryFieldEditor("imageSaveDir",
+                "Default image save dir:", getFieldEditorParent());
+            addField(dfe);
+
+            ffe = new FontFieldEditor("textOutputFont", "Text output font:",
+                getFieldEditorParent());
+            addField(ffe);
+        }
+    }
+
+    /**
+     * "logcat" prefs page.
+     */
+    private static class LogCatPrefs extends FieldEditorPreferencePage {
+
+        /**
+         * Basic constructor.
+         */
+        public LogCatPrefs() {
+            super(FLAT);        // use "flat" layout
+            setTitle("Logcat");
+        }
+
+        /**
+         * Create field editors.
+         */
+        @Override
+        protected void createFieldEditors() {
+            RadioGroupFieldEditor rgfe;
+
+            rgfe = new RadioGroupFieldEditor(PrefsDialog.LOGCAT_COLUMN_MODE,
+                "Message Column Resizing Mode", 1, new String[][] {
+                    { "Manual", PrefsDialog.LOGCAT_COLUMN_MODE_MANUAL },
+                    { "Automatic", PrefsDialog.LOGCAT_COLUMN_MODE_AUTO },
+                    },
+                getFieldEditorParent(), true);
+            addField(rgfe);
+
+            FontFieldEditor ffe = new FontFieldEditor(PrefsDialog.LOGCAT_FONT, "Text output font:",
+                    getFieldEditorParent());
+            addField(ffe);
+        }
+    }
+
+
+    /**
+     * "Application" prefs page.
+     */
+    private static class AppPrefs extends FieldEditorPreferencePage {
+
+        /**
+         * Basic constructor.
+         */
+        public AppPrefs() {
+            super(FLAT);        // use "flat" layout
+            setTitle("DDMS");
+        }
+
+        /**
+         * Create field editors.
+         */
+        @Override
+        protected void createFieldEditors() {
+            RadioGroupFieldEditor rgfe;
+
+            rgfe = new RadioGroupFieldEditor(PREFS_LOG_LEVEL,
+                "Logging Level", 1, new String[][] {
+                    { "Verbose", LogLevel.VERBOSE.getStringValue() },
+                    { "Debug", LogLevel.DEBUG.getStringValue() },
+                    { "Info", LogLevel.INFO.getStringValue() },
+                    { "Warning", LogLevel.WARN.getStringValue() },
+                    { "Error", LogLevel.ERROR.getStringValue() },
+                    { "Assert", LogLevel.ASSERT.getStringValue() },
+                    },
+                getFieldEditorParent(), true);
+            addField(rgfe);
+        }
+    }
+
+    /**
+     * "Device" prefs page.
+     */
+    private static class UsageStatsPrefs extends PreferencePage {
+
+        private BooleanFieldEditor mOptInCheckbox;
+        private Composite mTop;
+
+        /**
+         * Basic constructor.
+         */
+        public UsageStatsPrefs() {
+            setTitle("Usage Stats");
+        }
+
+        @Override
+        protected Control createContents(Composite parent) {
+            mTop = new Composite(parent, SWT.NONE);
+            mTop.setLayout(new GridLayout(1, false));
+            mTop.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+            Link text = new Link(mTop, SWT.WRAP);
+            text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+            text.setText(SdkStatsService.BODY_TEXT);
+
+            text.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent event) {
+                    SdkStatsService.openUrl(event.text);
+                }
+            });
+
+            mOptInCheckbox = new BooleanFieldEditor(SdkStatsService.PING_OPT_IN,
+                    SdkStatsService.CHECKBOX_TEXT, mTop);
+            mOptInCheckbox.setPage(this);
+            mOptInCheckbox.setPreferenceStore(getPreferenceStore());
+            mOptInCheckbox.load();
+
+            return null;
+        }
+
+        @Override
+        protected Point doComputeSize() {
+            if (mTop != null) {
+                return mTop.computeSize(450, SWT.DEFAULT, true);
+            }
+
+            return super.doComputeSize();
+        }
+
+        @Override
+        protected void performDefaults() {
+            if (mOptInCheckbox != null) {
+                mOptInCheckbox.loadDefault();
+            }
+            super.performDefaults();
+        }
+
+        @Override
+        public void performApply() {
+            if (mOptInCheckbox != null) {
+                mOptInCheckbox.store();
+            }
+            super.performApply();
+        }
+
+        @Override
+        public boolean performOk() {
+            if (mOptInCheckbox != null) {
+                mOptInCheckbox.store();
+            }
+            return super.performOk();
+        }
+    }
+
+}
+
+
diff --git a/tools/ddms/app/src/com/android/ddms/StaticPortConfigDialog.java b/tools/ddms/app/src/com/android/ddms/StaticPortConfigDialog.java
new file mode 100644
index 0000000..d00bc7f
--- /dev/null
+++ b/tools/ddms/app/src/com/android/ddms/StaticPortConfigDialog.java
@@ -0,0 +1,394 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddms;
+
+import com.android.ddmuilib.TableHelper;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Dialog to configure the static debug ports.
+ *
+ */
+public class StaticPortConfigDialog extends Dialog {
+
+    /** Preference name for the 0th column width */
+    private static final String PREFS_DEVICE_COL = "spcd.deviceColumn"; //$NON-NLS-1$
+
+    /** Preference name for the 1st column width */
+    private static final String PREFS_APP_COL = "spcd.AppColumn"; //$NON-NLS-1$
+
+    /** Preference name for the 2nd column width */
+    private static final String PREFS_PORT_COL = "spcd.PortColumn"; //$NON-NLS-1$
+
+    private static final int COL_DEVICE = 0;
+    private static final int COL_APPLICATION = 1;
+    private static final int COL_PORT = 2;
+
+
+    private static final int DLG_WIDTH = 500;
+    private static final int DLG_HEIGHT = 300;
+
+    private Shell mShell;
+    private Shell mParent;
+
+    private Table mPortTable;
+
+    /**
+     * Array containing the list of already used static port to avoid
+     * duplication.
+     */
+    private ArrayList<Integer> mPorts = new ArrayList<Integer>();
+
+    /**
+     * Basic constructor.
+     * @param parent
+     */
+    public StaticPortConfigDialog(Shell parent) {
+        super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
+    }
+
+    /**
+     * Open and display the dialog. This method returns only when the
+     * user closes the dialog somehow.
+     *
+     */
+    public void open() {
+        createUI();
+
+        if (mParent == null || mShell == null) {
+            return;
+        }
+
+        updateFromStore();
+
+        // Set the dialog size.
+        mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
+        Rectangle r = mParent.getBounds();
+        // get the center new top left.
+        int cx = r.x + r.width/2;
+        int x = cx - DLG_WIDTH / 2;
+        int cy = r.y + r.height/2;
+        int y = cy - DLG_HEIGHT / 2;
+        mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
+
+        mShell.pack();
+
+        // actually open the dialog
+        mShell.open();
+
+        // event loop until the dialog is closed.
+        Display display = mParent.getDisplay();
+        while (!mShell.isDisposed()) {
+            if (!display.readAndDispatch())
+                display.sleep();
+        }
+    }
+
+    /**
+     * Creates the dialog ui.
+     */
+    private void createUI() {
+        mParent = getParent();
+        mShell = new Shell(mParent, getStyle());
+        mShell.setText("Static Port Configuration");
+
+        mShell.setLayout(new GridLayout(1, true));
+
+        mShell.addListener(SWT.Close, new Listener() {
+            public void handleEvent(Event event) {
+                event.doit = true;
+            }
+        });
+
+        // center part with the list on the left and the buttons
+        // on the right.
+        Composite main = new Composite(mShell, SWT.NONE);
+        main.setLayoutData(new GridData(GridData.FILL_BOTH));
+        main.setLayout(new GridLayout(2, false));
+
+        // left part: list view
+        mPortTable = new Table(main, SWT.SINGLE | SWT.FULL_SELECTION);
+        mPortTable.setLayoutData(new GridData(GridData.FILL_BOTH));
+        mPortTable.setHeaderVisible(true);
+        mPortTable.setLinesVisible(true);
+
+        TableHelper.createTableColumn(mPortTable, "Device Serial Number",
+                SWT.LEFT, "emulator-5554", //$NON-NLS-1$
+                PREFS_DEVICE_COL, PrefsDialog.getStore());
+
+        TableHelper.createTableColumn(mPortTable, "Application Package",
+                SWT.LEFT, "com.android.samples.phone", //$NON-NLS-1$
+                PREFS_APP_COL, PrefsDialog.getStore());
+
+        TableHelper.createTableColumn(mPortTable, "Debug Port",
+                SWT.RIGHT, "Debug Port", //$NON-NLS-1$
+                PREFS_PORT_COL, PrefsDialog.getStore());
+
+        // right part: buttons
+        Composite buttons = new Composite(main, SWT.NONE);
+        buttons.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+        buttons.setLayout(new GridLayout(1, true));
+
+        Button newButton = new Button(buttons, SWT.NONE);
+        newButton.setText("New...");
+        newButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                StaticPortEditDialog dlg = new StaticPortEditDialog(mShell,
+                        mPorts);
+                if (dlg.open()) {
+                    // get the text
+                    String device = dlg.getDeviceSN();
+                    String app = dlg.getAppName();
+                    int port = dlg.getPortNumber();
+
+                    // add it to the list
+                    addEntry(device, app, port);
+                }
+            }
+        });
+
+        final Button editButton = new Button(buttons, SWT.NONE);
+        editButton.setText("Edit...");
+        editButton.setEnabled(false);
+        editButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                int index = mPortTable.getSelectionIndex();
+                String oldDeviceName = getDeviceName(index);
+                String oldAppName = getAppName(index);
+                String oldPortNumber = getPortNumber(index);
+                StaticPortEditDialog dlg = new StaticPortEditDialog(mShell,
+                        mPorts, oldDeviceName, oldAppName, oldPortNumber);
+                if (dlg.open()) {
+                    // get the text
+                    String deviceName = dlg.getDeviceSN();
+                    String app = dlg.getAppName();
+                    int port = dlg.getPortNumber();
+
+                    // add it to the list
+                    replaceEntry(index, deviceName, app, port);
+                }
+            }
+        });
+
+        final Button deleteButton = new Button(buttons, SWT.NONE);
+        deleteButton.setText("Delete");
+        deleteButton.setEnabled(false);
+        deleteButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                int index = mPortTable.getSelectionIndex();
+                removeEntry(index);
+            }
+        });
+
+        // bottom part with the ok/cancel
+        Composite bottomComp = new Composite(mShell, SWT.NONE);
+        bottomComp.setLayoutData(new GridData(
+                GridData.HORIZONTAL_ALIGN_CENTER));
+        bottomComp.setLayout(new GridLayout(2, true));
+
+        Button okButton = new Button(bottomComp, SWT.NONE);
+        okButton.setText("OK");
+        okButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                updateStore();
+                mShell.close();
+            }
+        });
+
+        Button cancelButton = new Button(bottomComp, SWT.NONE);
+        cancelButton.setText("Cancel");
+        cancelButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mShell.close();
+            }
+        });
+
+        mPortTable.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // get the selection index
+                int index = mPortTable.getSelectionIndex();
+
+                boolean enabled = index != -1;
+                editButton.setEnabled(enabled);
+                deleteButton.setEnabled(enabled);
+            }
+        });
+
+        mShell.pack();
+
+    }
+
+    /**
+     * Add a new entry in the list.
+     * @param deviceName the serial number of the device
+     * @param appName java package for the application
+     * @param portNumber port number
+     */
+    private void addEntry(String deviceName, String appName, int portNumber) {
+        // create a new item for the table
+        TableItem item = new TableItem(mPortTable, SWT.NONE);
+
+        item.setText(COL_DEVICE, deviceName);
+        item.setText(COL_APPLICATION, appName);
+        item.setText(COL_PORT, Integer.toString(portNumber));
+
+        // add the port to the list of port number used.
+        mPorts.add(portNumber);
+    }
+
+    /**
+     * Remove an entry from the list.
+     * @param index The index of the entry to be removed
+     */
+    private void removeEntry(int index) {
+        // remove from the ui
+        mPortTable.remove(index);
+
+        // and from the port list.
+        mPorts.remove(index);
+    }
+
+    /**
+     * Replace an entry in the list with new values.
+     * @param index The index of the item to be replaced
+     * @param deviceName the serial number of the device
+     * @param appName The new java package for the application
+     * @param portNumber The new port number.
+     */
+    private void replaceEntry(int index, String deviceName, String appName, int portNumber) {
+        // get the table item by index
+        TableItem item = mPortTable.getItem(index);
+
+        // set its new value
+        item.setText(COL_DEVICE, deviceName);
+        item.setText(COL_APPLICATION, appName);
+        item.setText(COL_PORT, Integer.toString(portNumber));
+
+        // and replace the port number in the port list.
+        mPorts.set(index, portNumber);
+    }
+
+
+    /**
+     * Returns the device name for a specific index
+     * @param index The index
+     * @return the java package name of the application
+     */
+    private String getDeviceName(int index) {
+        TableItem item = mPortTable.getItem(index);
+        return item.getText(COL_DEVICE);
+    }
+
+    /**
+     * Returns the application name for a specific index
+     * @param index The index
+     * @return the java package name of the application
+     */
+    private String getAppName(int index) {
+        TableItem item = mPortTable.getItem(index);
+        return item.getText(COL_APPLICATION);
+    }
+
+    /**
+     * Returns the port number for a specific index
+     * @param index The index
+     * @return the port number
+     */
+    private String getPortNumber(int index) {
+        TableItem item = mPortTable.getItem(index);
+        return item.getText(COL_PORT);
+    }
+
+    /**
+     * Updates the ui from the value in the preference store.
+     */
+    private void updateFromStore() {
+        // get the map from the debug port manager
+        DebugPortProvider provider = DebugPortProvider.getInstance();
+        Map<String, Map<String, Integer>> map = provider.getPortList();
+
+        // we're going to loop on the keys and fill the table.
+        Set<String> deviceKeys = map.keySet();
+
+        for (String deviceKey : deviceKeys) {
+            Map<String, Integer> deviceMap = map.get(deviceKey);
+            if (deviceMap != null) {
+                Set<String> appKeys = deviceMap.keySet();
+
+                for (String appKey : appKeys) {
+                    Integer port = deviceMap.get(appKey);
+                    if (port != null) {
+                        addEntry(deviceKey, appKey, port);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Update the store from the content of the ui.
+     */
+    private void updateStore() {
+        // create a new Map object and fill it.
+        HashMap<String, Map<String, Integer>> map = new HashMap<String, Map<String, Integer>>();
+
+        int count = mPortTable.getItemCount();
+
+        for (int i = 0 ; i < count ; i++) {
+            TableItem item = mPortTable.getItem(i);
+            String deviceName = item.getText(COL_DEVICE);
+
+            Map<String, Integer> deviceMap = map.get(deviceName);
+            if (deviceMap == null) {
+                deviceMap = new HashMap<String, Integer>();
+                map.put(deviceName, deviceMap);
+            }
+
+            deviceMap.put(item.getText(COL_APPLICATION), Integer.valueOf(item.getText(COL_PORT)));
+        }
+
+        // set it in the store through the debug port manager.
+        DebugPortProvider provider = DebugPortProvider.getInstance();
+        provider.setPortList(map);
+    }
+}
diff --git a/tools/ddms/app/src/com/android/ddms/StaticPortEditDialog.java b/tools/ddms/app/src/com/android/ddms/StaticPortEditDialog.java
new file mode 100644
index 0000000..6330126
--- /dev/null
+++ b/tools/ddms/app/src/com/android/ddms/StaticPortEditDialog.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddms;
+
+import com.android.ddmlib.Device;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+import java.util.ArrayList;
+
+/**
+ * Small dialog box to edit a static port number.
+ */
+public class StaticPortEditDialog extends Dialog {
+
+    private static final int DLG_WIDTH = 400;
+    private static final int DLG_HEIGHT = 200;
+
+    private Shell mParent;
+
+    private Shell mShell;
+
+    private boolean mOk = false;
+
+    private String mAppName;
+
+    private String mPortNumber;
+
+    private Button mOkButton;
+
+    private Label mWarning;
+
+    /** List of ports already in use */
+    private ArrayList<Integer> mPorts;
+
+    /** This is the port being edited. */
+    private int mEditPort = -1;
+    private String mDeviceSn;
+
+    /**
+     * Creates a dialog with empty fields.
+     * @param parent The parent Shell
+     * @param ports The list of already used port numbers.
+     */
+    public StaticPortEditDialog(Shell parent, ArrayList<Integer> ports) {
+        super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
+        mPorts = ports;
+        mDeviceSn = Device.FIRST_EMULATOR_SN;
+    }
+
+    /**
+     * Creates a dialog with predefined values.
+     * @param shell The parent shell
+     * @param ports The list of already used port numbers.
+     * @param oldDeviceSN the device serial number to display
+     * @param oldAppName The application name to display
+     * @param oldPortNumber The port number to display
+     */
+    public StaticPortEditDialog(Shell shell, ArrayList<Integer> ports,
+            String oldDeviceSN, String oldAppName, String oldPortNumber) {
+        this(shell, ports);
+
+        mDeviceSn = oldDeviceSN;
+        mAppName = oldAppName;
+        mPortNumber = oldPortNumber;
+        mEditPort = Integer.valueOf(mPortNumber);
+    }
+
+    /**
+     * Opens the dialog. The method will return when the user closes the dialog
+     * somehow.
+     *
+     * @return true if ok was pressed, false if cancelled.
+     */
+    public boolean open() {
+        createUI();
+
+        if (mParent == null || mShell == null) {
+            return false;
+        }
+
+        mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
+        Rectangle r = mParent.getBounds();
+        // get the center new top left.
+        int cx = r.x + r.width/2;
+        int x = cx - DLG_WIDTH / 2;
+        int cy = r.y + r.height/2;
+        int y = cy - DLG_HEIGHT / 2;
+        mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
+
+        mShell.open();
+
+        Display display = mParent.getDisplay();
+        while (!mShell.isDisposed()) {
+            if (!display.readAndDispatch())
+                display.sleep();
+        }
+
+        return mOk;
+    }
+
+    public String getDeviceSN() {
+        return mDeviceSn;
+    }
+
+    public String getAppName() {
+        return mAppName;
+    }
+
+    public int getPortNumber() {
+        return Integer.valueOf(mPortNumber);
+    }
+
+    private void createUI() {
+        mParent = getParent();
+        mShell = new Shell(mParent, getStyle());
+        mShell.setText("Static Port");
+
+        mShell.setLayout(new GridLayout(1, false));
+
+        mShell.addListener(SWT.Close, new Listener() {
+            public void handleEvent(Event event) {
+            }
+        });
+
+        // center part with the edit field
+        Composite main = new Composite(mShell, SWT.NONE);
+        main.setLayoutData(new GridData(GridData.FILL_BOTH));
+        main.setLayout(new GridLayout(2, false));
+
+        Label l0 = new Label(main, SWT.NONE);
+        l0.setText("Device Name:");
+
+        final Text deviceSNText = new Text(main, SWT.SINGLE | SWT.BORDER);
+        deviceSNText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        if (mDeviceSn != null) {
+            deviceSNText.setText(mDeviceSn);
+        }
+        deviceSNText.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                mDeviceSn = deviceSNText.getText().trim();
+                validate();
+            }
+        });
+
+        Label l = new Label(main, SWT.NONE);
+        l.setText("Application Name:");
+
+        final Text appNameText = new Text(main, SWT.SINGLE | SWT.BORDER);
+        if (mAppName != null) {
+            appNameText.setText(mAppName);
+        }
+        appNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        appNameText.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                mAppName = appNameText.getText().trim();
+                validate();
+            }
+        });
+
+        Label l2 = new Label(main, SWT.NONE);
+        l2.setText("Debug Port:");
+
+        final Text debugPortText = new Text(main, SWT.SINGLE | SWT.BORDER);
+        if (mPortNumber != null) {
+            debugPortText.setText(mPortNumber);
+        }
+        debugPortText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        debugPortText.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                mPortNumber = debugPortText.getText().trim();
+                validate();
+            }
+        });
+
+        // warning label
+        Composite warningComp = new Composite(mShell, SWT.NONE);
+        warningComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        warningComp.setLayout(new GridLayout(1, true));
+
+        mWarning = new Label(warningComp, SWT.NONE);
+        mWarning.setText("");
+        mWarning.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        // bottom part with the ok/cancel
+        Composite bottomComp = new Composite(mShell, SWT.NONE);
+        bottomComp
+                .setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
+        bottomComp.setLayout(new GridLayout(2, true));
+
+        mOkButton = new Button(bottomComp, SWT.NONE);
+        mOkButton.setText("OK");
+        mOkButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mOk = true;
+                mShell.close();
+            }
+        });
+        mOkButton.setEnabled(false);
+        mShell.setDefaultButton(mOkButton);
+
+        Button cancelButton = new Button(bottomComp, SWT.NONE);
+        cancelButton.setText("Cancel");
+        cancelButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mShell.close();
+            }
+        });
+
+        validate();
+    }
+
+    /**
+     * Validates the content of the 2 text fields and enable/disable "ok", while
+     * setting up the warning/error message.
+     */
+    private void validate() {
+        // first we reset the warning dialog. This allows us to latter
+        // display warnings.
+        mWarning.setText(""); // $NON-NLS-1$
+
+        // check the device name field is not empty
+        if (mDeviceSn == null || mDeviceSn.length() == 0) {
+            mWarning.setText("Device name missing.");
+            mOkButton.setEnabled(false);
+            return;
+        }
+
+        // check the application name field is not empty
+        if (mAppName == null || mAppName.length() == 0) {
+            mWarning.setText("Application name missing.");
+            mOkButton.setEnabled(false);
+            return;
+        }
+
+        String packageError = "Application name must be a valid Java package name.";
+
+        // validate the package name as well. It must be a fully qualified
+        // java package.
+        String[] packageSegments = mAppName.split("\\."); // $NON-NLS-1$
+        for (String p : packageSegments) {
+            if (p.matches("^[a-zA-Z][a-zA-Z0-9]*") == false) { // $NON-NLS-1$
+                mWarning.setText(packageError);
+                mOkButton.setEnabled(false);
+                return;
+            }
+
+            // lets also display a warning if the package contains upper case
+            // letters.
+            if (p.matches("^[a-z][a-z0-9]*") == false) { // $NON-NLS-1$
+                mWarning.setText("Lower case is recommended for Java packages.");
+            }
+        }
+
+        // the split will not detect the last char being a '.'
+        // so we test it manually
+        if (mAppName.charAt(mAppName.length()-1) == '.') {
+            mWarning.setText(packageError);
+            mOkButton.setEnabled(false);
+            return;
+        }
+
+        // now we test the package name field is not empty.
+        if (mPortNumber == null || mPortNumber.length() == 0) {
+            mWarning.setText("Port Number missing.");
+            mOkButton.setEnabled(false);
+            return;
+        }
+
+        // then we check it only contains digits.
+        if (mPortNumber.matches("[0-9]*") == false) { // $NON-NLS-1$
+            mWarning.setText("Port Number invalid.");
+            mOkButton.setEnabled(false);
+            return;
+        }
+
+        // get the int from the port number to validate
+        long port = Long.valueOf(mPortNumber);
+        if (port >= 32767) {
+            mOkButton.setEnabled(false);
+            return;
+        }
+
+        // check if its in the list of already used ports
+        if (port != mEditPort) {
+            for (Integer i : mPorts) {
+                if (port == i.intValue()) {
+                    mWarning.setText("Port already in use.");
+                    mOkButton.setEnabled(false);
+                    return;
+                }
+            }
+        }
+
+        // at this point there's not error, so we enable the ok button.
+        mOkButton.setEnabled(true);
+    }
+}
diff --git a/tools/ddms/app/src/com/android/ddms/UIThread.java b/tools/ddms/app/src/com/android/ddms/UIThread.java
new file mode 100644
index 0000000..ff89e2c
--- /dev/null
+++ b/tools/ddms/app/src/com/android/ddms/UIThread.java
@@ -0,0 +1,1491 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddms;
+
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.Client;
+import com.android.ddmlib.Device;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.Log.ILogOutput;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmuilib.AllocationPanel;
+import com.android.ddmuilib.DevicePanel;
+import com.android.ddmuilib.DevicePanel.IUiSelectionListener;
+import com.android.ddmuilib.EmulatorControlPanel;
+import com.android.ddmuilib.HeapPanel;
+import com.android.ddmuilib.ITableFocusListener;
+import com.android.ddmuilib.ImageHelper;
+import com.android.ddmuilib.ImageLoader;
+import com.android.ddmuilib.InfoPanel;
+import com.android.ddmuilib.NativeHeapPanel;
+import com.android.ddmuilib.ScreenShotDialog;
+import com.android.ddmuilib.SysinfoPanel;
+import com.android.ddmuilib.TablePanel;
+import com.android.ddmuilib.ThreadPanel;
+import com.android.ddmuilib.actions.ToolItemAction;
+import com.android.ddmuilib.explorer.DeviceExplorer;
+import com.android.ddmuilib.log.event.EventLogPanel;
+import com.android.ddmuilib.logcat.LogColors;
+import com.android.ddmuilib.logcat.LogFilter;
+import com.android.ddmuilib.logcat.LogPanel;
+import com.android.ddmuilib.logcat.LogPanel.ILogFilterStorageManager;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.MenuAdapter;
+import org.eclipse.swt.events.MenuEvent;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.ShellEvent;
+import org.eclipse.swt.events.ShellListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.MessageBox;
+import org.eclipse.swt.widgets.Sash;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+import java.io.File;
+import java.util.ArrayList;
+
+/**
+ * This acts as the UI builder. This cannot be its own thread since this prevent using AWT in an
+ * SWT application. So this class mainly builds the ui, and manages communication between the panels
+ * when {@link Device} / {@link Client} selection changes.
+ */
+public class UIThread implements IUiSelectionListener {
+    /*
+     * UI tab panel definitions. The constants here must match up with the array
+     * indices in mPanels. PANEL_CLIENT_LIST is a "virtual" panel representing
+     * the client list.
+     */
+    public static final int PANEL_CLIENT_LIST = -1;
+
+    public static final int PANEL_INFO = 0;
+
+    public static final int PANEL_THREAD = 1;
+
+    public static final int PANEL_HEAP = 2;
+
+    public static final int PANEL_NATIVE_HEAP = 3;
+
+    private static final int PANEL_ALLOCATIONS = 4;
+
+    private static final int PANEL_SYSINFO = 5;
+
+    private static final int PANEL_COUNT = 6;
+
+    /** Content is setup in the constructor */
+    private static TablePanel[] mPanels = new TablePanel[PANEL_COUNT];
+
+    private static final String[] mPanelNames = new String[] {
+            "Info", "Threads", "VM Heap", "Native Heap", "Allocation Tracker", "Sysinfo"
+    };
+
+    private static final String[] mPanelTips = new String[] {
+            "Client information", "Thread status", "VM heap status",
+            "Native heap status", "Allocation Tracker", "Sysinfo graphs"
+    };
+
+    private static final String PREFERENCE_LOGSASH =
+        "logSashLocation"; //$NON-NLS-1$
+    private static final String PREFERENCE_SASH =
+        "sashLocation"; //$NON-NLS-1$
+
+    private static final String PREFS_COL_TIME =
+        "logcat.time"; //$NON-NLS-1$
+    private static final String PREFS_COL_LEVEL =
+        "logcat.level"; //$NON-NLS-1$
+    private static final String PREFS_COL_PID =
+        "logcat.pid"; //$NON-NLS-1$
+    private static final String PREFS_COL_TAG =
+        "logcat.tag"; //$NON-NLS-1$
+    private static final String PREFS_COL_MESSAGE =
+        "logcat.message"; //$NON-NLS-1$
+
+    private static final String PREFS_FILTERS = "logcat.filter"; //$NON-NLS-1$
+
+    // singleton instance
+    private static UIThread mInstance = new UIThread();
+
+    // our display
+    private Display mDisplay;
+
+    // the table we show in the left-hand pane
+    private DevicePanel mDevicePanel;
+
+    private Device mCurrentDevice = null;
+    private Client mCurrentClient = null;
+
+    // status line at the bottom of the app window
+    private Label mStatusLine;
+
+    // some toolbar items we need to update
+    private ToolItem mTBShowThreadUpdates;
+    private ToolItem mTBShowHeapUpdates;
+    private ToolItem mTBHalt;
+    private ToolItem mTBCauseGc;
+
+    private ImageLoader mDdmsImageLoader;
+    private ImageLoader mDdmuiLibImageLoader; 
+
+    private final class FilterStorage implements ILogFilterStorageManager {
+
+        public LogFilter[] getFilterFromStore() {
+            String filterPrefs = PrefsDialog.getStore().getString(
+                    PREFS_FILTERS);
+
+            // split in a string per filter
+            String[] filters = filterPrefs.split("\\|"); //$NON-NLS-1$
+
+            ArrayList<LogFilter> list =
+                new ArrayList<LogFilter>(filters.length);
+
+            for (String f : filters) {
+                if (f.length() > 0) {
+                    LogFilter logFilter = new LogFilter();
+                    if (logFilter.loadFromString(f)) {
+                        list.add(logFilter);
+                    }
+                }
+            }
+
+            return list.toArray(new LogFilter[list.size()]);
+        }
+
+        public void saveFilters(LogFilter[] filters) {
+            StringBuilder sb = new StringBuilder();
+            for (LogFilter f : filters) {
+                String filterString = f.toString();
+                sb.append(filterString);
+                sb.append('|');
+            }
+
+            PrefsDialog.getStore().setValue(PREFS_FILTERS, sb.toString());
+        }
+
+        public boolean requiresDefaultFilter() {
+            return true;
+        }
+    }
+
+
+    private LogPanel mLogPanel;
+
+    private ToolItemAction mCreateFilterAction;
+    private ToolItemAction mDeleteFilterAction;
+    private ToolItemAction mEditFilterAction;
+    private ToolItemAction mExportAction;
+    private ToolItemAction mClearAction;
+
+    private ToolItemAction[] mLogLevelActions;
+    private String[] mLogLevelIcons = {
+            "v.png", //$NON-NLS-1S
+            "d.png", //$NON-NLS-1S
+            "i.png", //$NON-NLS-1S
+            "w.png", //$NON-NLS-1S
+            "e.png", //$NON-NLS-1S
+    };
+
+    protected Clipboard mClipboard;
+
+    private MenuItem mCopyMenuItem;
+
+    private MenuItem mSelectAllMenuItem;
+
+    private TableFocusListener mTableListener;
+
+    private DeviceExplorer mExplorer = null;
+    private Shell mExplorerShell = null;
+
+    private EmulatorControlPanel mEmulatorPanel;
+    
+    private EventLogPanel mEventLogPanel;
+
+    private class TableFocusListener implements ITableFocusListener {
+
+        private IFocusedTableActivator mCurrentActivator;
+
+        public void focusGained(IFocusedTableActivator activator) {
+            mCurrentActivator = activator;
+            if (mCopyMenuItem.isDisposed() == false) {
+                mCopyMenuItem.setEnabled(true);
+                mSelectAllMenuItem.setEnabled(true);
+            }
+        }
+
+        public void focusLost(IFocusedTableActivator activator) {
+            // if we move from one table to another, it's unclear
+            // if the old table lose its focus before the new
+            // one gets the focus, so we need to check.
+            if (activator == mCurrentActivator) {
+                activator = null;
+                if (mCopyMenuItem.isDisposed() == false) {
+                    mCopyMenuItem.setEnabled(false);
+                    mSelectAllMenuItem.setEnabled(false);
+                }
+            }
+        }
+
+        public void copy(Clipboard clipboard) {
+            if (mCurrentActivator != null) {
+                mCurrentActivator.copy(clipboard);
+            }
+        }
+
+        public void selectAll() {
+            if (mCurrentActivator != null) {
+                mCurrentActivator.selectAll();
+            }
+        }
+
+    }
+
+
+    /**
+     * Generic constructor.
+     */
+    private UIThread() {
+        mPanels[PANEL_INFO] = new InfoPanel();
+        mPanels[PANEL_THREAD] = new ThreadPanel();
+        mPanels[PANEL_HEAP] = new HeapPanel();
+        if (PrefsDialog.getStore().getBoolean(PrefsDialog.SHOW_NATIVE_HEAP)) {
+            mPanels[PANEL_NATIVE_HEAP] = new NativeHeapPanel();
+        } else {
+            mPanels[PANEL_NATIVE_HEAP] = null;
+        }
+        mPanels[PANEL_ALLOCATIONS] = new AllocationPanel();
+        mPanels[PANEL_SYSINFO] = new SysinfoPanel();
+    }
+
+    /**
+     * Get singleton instance of the UI thread.
+     */
+    public static UIThread getInstance() {
+        return mInstance;
+    }
+
+    /**
+     * Return the Display. Don't try this unless you're in the UI thread.
+     */
+    public Display getDisplay() {
+        return mDisplay;
+    }
+
+    public void asyncExec(Runnable r) {
+        if (mDisplay != null && mDisplay.isDisposed() == false) {
+            mDisplay.asyncExec(r);
+        }
+    }
+
+    /** returns the IPreferenceStore */
+    public IPreferenceStore getStore() {
+        return PrefsDialog.getStore();
+    }
+
+    /**
+     * Create SWT objects and drive the user interface event loop.
+     */
+    public void runUI() {
+        Display.setAppName("ddms");
+        mDisplay = new Display();
+        Shell shell = new Shell(mDisplay);
+
+        // create the image loaders for DDMS and DDMUILIB
+        mDdmsImageLoader = new ImageLoader(this.getClass());
+        mDdmuiLibImageLoader = new ImageLoader(DevicePanel.class);
+        
+        shell.setImage(ImageHelper.loadImage(mDdmsImageLoader, mDisplay,
+                "ddms-icon.png", //$NON-NLS-1$
+                100, 50, null));
+
+        Log.setLogOutput(new ILogOutput() {
+            public void printAndPromptLog(final LogLevel logLevel, final String tag,
+                    final String message) {
+                Log.printLog(logLevel, tag, message);
+                // dialog box only run in UI thread..
+                mDisplay.asyncExec(new Runnable() {
+                    public void run() {
+                        Shell shell = mDisplay.getActiveShell();
+                        if (logLevel == LogLevel.ERROR) {
+                            MessageDialog.openError(shell, tag, message);
+                        } else {
+                            MessageDialog.openWarning(shell, tag, message);
+                        }
+                    }
+                });
+            }
+
+            public void printLog(LogLevel logLevel, String tag, String message) {
+                Log.printLog(logLevel, tag, message);
+            }
+        });
+
+        // [try to] ensure ADB is running
+        String adbLocation = System.getProperty("com.android.ddms.bindir"); //$NON-NLS-1$
+        if (adbLocation != null && adbLocation.length() != 0) {
+            adbLocation += File.separator + "adb"; //$NON-NLS-1$
+        } else {
+            adbLocation = "adb"; //$NON-NLS-1$
+        }
+
+        AndroidDebugBridge.init(true /* debugger support */);
+        AndroidDebugBridge.createBridge(adbLocation, true /* forceNewBridge */);
+
+        shell.setText("Dalvik Debug Monitor");
+        setConfirmClose(shell);
+        createMenus(shell);
+        createWidgets(shell);
+
+        shell.pack();
+        setSizeAndPosition(shell);
+        shell.open();
+
+        Log.d("ddms", "UI is up");
+
+        while (!shell.isDisposed()) {
+            if (!mDisplay.readAndDispatch())
+                mDisplay.sleep();
+        }
+        mLogPanel.stopLogCat(true);
+
+        mDevicePanel.dispose();
+        for (TablePanel panel : mPanels) {
+            if (panel != null) {
+                panel.dispose();
+            }
+        }
+
+        mDisplay.dispose();
+        Log.d("ddms", "UI is down");
+    }
+
+    /**
+     * Set the size and position of the main window from the preference, and
+     * setup listeners for control events (resize/move of the window)
+     */
+    private void setSizeAndPosition(final Shell shell) {
+        shell.setMinimumSize(400, 200);
+
+        // get the x/y and w/h from the prefs
+        PreferenceStore prefs = PrefsDialog.getStore();
+        int x = prefs.getInt(PrefsDialog.SHELL_X);
+        int y = prefs.getInt(PrefsDialog.SHELL_Y);
+        int w = prefs.getInt(PrefsDialog.SHELL_WIDTH);
+        int h = prefs.getInt(PrefsDialog.SHELL_HEIGHT);
+
+        // check that we're not out of the display area
+        Rectangle rect = mDisplay.getClientArea();
+        // first check the width/height
+        if (w > rect.width) {
+            w = rect.width;
+            prefs.setValue(PrefsDialog.SHELL_WIDTH, rect.width);
+        }
+        if (h > rect.height) {
+            h = rect.height;
+            prefs.setValue(PrefsDialog.SHELL_HEIGHT, rect.height);
+        }
+        // then check x. Make sure the left corner is in the screen
+        if (x < rect.x) {
+            x = rect.x;
+            prefs.setValue(PrefsDialog.SHELL_X, rect.x);
+        } else if (x >= rect.x + rect.width) {
+            x = rect.x + rect.width - w;
+            prefs.setValue(PrefsDialog.SHELL_X, rect.x);
+        }
+        // then check y. Make sure the left corner is in the screen
+        if (y < rect.y) {
+            y = rect.y;
+            prefs.setValue(PrefsDialog.SHELL_Y, rect.y);
+        } else if (y >= rect.y + rect.height) {
+            y = rect.y + rect.height - h;
+            prefs.setValue(PrefsDialog.SHELL_Y, rect.y);
+        }
+
+        // now we can set the location/size
+        shell.setBounds(x, y, w, h);
+
+        // add listener for resize/move
+        shell.addControlListener(new ControlListener() {
+            public void controlMoved(ControlEvent e) {
+                // get the new x/y
+                Rectangle rect = shell.getBounds();
+                // store in pref file
+                PreferenceStore prefs = PrefsDialog.getStore();
+                prefs.setValue(PrefsDialog.SHELL_X, rect.x);
+                prefs.setValue(PrefsDialog.SHELL_Y, rect.y);
+            }
+
+            public void controlResized(ControlEvent e) {
+                // get the new w/h
+                Rectangle rect = shell.getBounds();
+                // store in pref file
+                PreferenceStore prefs = PrefsDialog.getStore();
+                prefs.setValue(PrefsDialog.SHELL_WIDTH, rect.width);
+                prefs.setValue(PrefsDialog.SHELL_HEIGHT, rect.height);
+            }
+        });
+    }
+
+    /**
+     * Set the size and position of the file explorer window from the
+     * preference, and setup listeners for control events (resize/move of
+     * the window)
+     */
+    private void setExplorerSizeAndPosition(final Shell shell) {
+        shell.setMinimumSize(400, 200);
+
+        // get the x/y and w/h from the prefs
+        PreferenceStore prefs = PrefsDialog.getStore();
+        int x = prefs.getInt(PrefsDialog.EXPLORER_SHELL_X);
+        int y = prefs.getInt(PrefsDialog.EXPLORER_SHELL_Y);
+        int w = prefs.getInt(PrefsDialog.EXPLORER_SHELL_WIDTH);
+        int h = prefs.getInt(PrefsDialog.EXPLORER_SHELL_HEIGHT);
+
+        // check that we're not out of the display area
+        Rectangle rect = mDisplay.getClientArea();
+        // first check the width/height
+        if (w > rect.width) {
+            w = rect.width;
+            prefs.setValue(PrefsDialog.EXPLORER_SHELL_WIDTH, rect.width);
+        }
+        if (h > rect.height) {
+            h = rect.height;
+            prefs.setValue(PrefsDialog.EXPLORER_SHELL_HEIGHT, rect.height);
+        }
+        // then check x. Make sure the left corner is in the screen
+        if (x < rect.x) {
+            x = rect.x;
+            prefs.setValue(PrefsDialog.EXPLORER_SHELL_X, rect.x);
+        } else if (x >= rect.x + rect.width) {
+            x = rect.x + rect.width - w;
+            prefs.setValue(PrefsDialog.EXPLORER_SHELL_X, rect.x);
+        }
+        // then check y. Make sure the left corner is in the screen
+        if (y < rect.y) {
+            y = rect.y;
+            prefs.setValue(PrefsDialog.EXPLORER_SHELL_Y, rect.y);
+        } else if (y >= rect.y + rect.height) {
+            y = rect.y + rect.height - h;
+            prefs.setValue(PrefsDialog.EXPLORER_SHELL_Y, rect.y);
+        }
+
+        // now we can set the location/size
+        shell.setBounds(x, y, w, h);
+
+        // add listener for resize/move
+        shell.addControlListener(new ControlListener() {
+            public void controlMoved(ControlEvent e) {
+                // get the new x/y
+                Rectangle rect = shell.getBounds();
+                // store in pref file
+                PreferenceStore prefs = PrefsDialog.getStore();
+                prefs.setValue(PrefsDialog.EXPLORER_SHELL_X, rect.x);
+                prefs.setValue(PrefsDialog.EXPLORER_SHELL_Y, rect.y);
+            }
+
+            public void controlResized(ControlEvent e) {
+                // get the new w/h
+                Rectangle rect = shell.getBounds();
+                // store in pref file
+                PreferenceStore prefs = PrefsDialog.getStore();
+                prefs.setValue(PrefsDialog.EXPLORER_SHELL_WIDTH, rect.width);
+                prefs.setValue(PrefsDialog.EXPLORER_SHELL_HEIGHT, rect.height);
+            }
+        });
+    }
+
+    /*
+     * Set the confirm-before-close dialog. TODO: enable/disable in prefs. TODO:
+     * is there any point in having this?
+     */
+    private void setConfirmClose(final Shell shell) {
+        if (true)
+            return;
+
+        shell.addListener(SWT.Close, new Listener() {
+            public void handleEvent(Event event) {
+                int style = SWT.APPLICATION_MODAL | SWT.YES | SWT.NO;
+                MessageBox msgBox = new MessageBox(shell, style);
+                msgBox.setText("Confirm...");
+                msgBox.setMessage("Close DDM?");
+                event.doit = (msgBox.open() == SWT.YES);
+            }
+        });
+    }
+
+    /*
+     * Create the menu bar and items.
+     */
+    private void createMenus(final Shell shell) {
+        // create menu bar
+        Menu menuBar = new Menu(shell, SWT.BAR);
+
+        // create top-level items
+        MenuItem fileItem = new MenuItem(menuBar, SWT.CASCADE);
+        fileItem.setText("&File");
+        MenuItem editItem = new MenuItem(menuBar, SWT.CASCADE);
+        editItem.setText("&Edit");
+        MenuItem actionItem = new MenuItem(menuBar, SWT.CASCADE);
+        actionItem.setText("&Actions");
+        MenuItem deviceItem = new MenuItem(menuBar, SWT.CASCADE);
+        deviceItem.setText("&Device");
+        MenuItem helpItem = new MenuItem(menuBar, SWT.CASCADE);
+        helpItem.setText("&Help");
+
+        // create top-level menus
+        Menu fileMenu = new Menu(menuBar);
+        fileItem.setMenu(fileMenu);
+        Menu editMenu = new Menu(menuBar);
+        editItem.setMenu(editMenu);
+        Menu actionMenu = new Menu(menuBar);
+        actionItem.setMenu(actionMenu);
+        Menu deviceMenu = new Menu(menuBar);
+        deviceItem.setMenu(deviceMenu);
+        Menu helpMenu = new Menu(menuBar);
+        helpItem.setMenu(helpMenu);
+
+        MenuItem item;
+
+        // create File menu items
+        item = new MenuItem(fileMenu, SWT.NONE);
+        item.setText("&Preferences...");
+        item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                PrefsDialog.run(shell);
+            }
+        });
+
+        item = new MenuItem(fileMenu, SWT.NONE);
+        item.setText("&Static Port Configuration...");
+        item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                StaticPortConfigDialog dlg = new StaticPortConfigDialog(shell);
+                dlg.open();
+            }
+        });
+
+        new MenuItem(fileMenu, SWT.SEPARATOR);
+
+        item = new MenuItem(fileMenu, SWT.NONE);
+        item.setText("E&xit\tCtrl-Q");
+        item.setAccelerator('Q' | SWT.CONTROL);
+        item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                shell.close();
+            }
+        });
+
+        // create edit menu items
+        mCopyMenuItem = new MenuItem(editMenu, SWT.NONE);
+        mCopyMenuItem.setText("&Copy\tCtrl-C");
+        mCopyMenuItem.setAccelerator('C' | SWT.COMMAND);
+        mCopyMenuItem.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mTableListener.copy(mClipboard);
+            }
+        });
+
+        new MenuItem(editMenu, SWT.SEPARATOR);
+
+        mSelectAllMenuItem = new MenuItem(editMenu, SWT.NONE);
+        mSelectAllMenuItem.setText("Select &All\tCtrl-A");
+        mSelectAllMenuItem.setAccelerator('A' | SWT.COMMAND);
+        mSelectAllMenuItem.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mTableListener.selectAll();
+            }
+        });
+
+        // create Action menu items
+        // TODO: this should come with a confirmation dialog
+        final MenuItem actionHaltItem = new MenuItem(actionMenu, SWT.NONE);
+        actionHaltItem.setText("&Halt VM");
+        actionHaltItem.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mDevicePanel.killSelectedClient();
+            }
+        });
+
+        final MenuItem actionCauseGcItem = new MenuItem(actionMenu, SWT.NONE);
+        actionCauseGcItem.setText("Cause &GC");
+        actionCauseGcItem.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mDevicePanel.forceGcOnSelectedClient();
+            }
+        });
+
+        // configure Action items based on current state
+        actionMenu.addMenuListener(new MenuAdapter() {
+            @Override
+            public void menuShown(MenuEvent e) {
+                actionHaltItem.setEnabled(mTBHalt.getEnabled());
+                actionCauseGcItem.setEnabled(mTBCauseGc.getEnabled());
+            }
+        });
+
+        // create Device menu items
+        item = new MenuItem(deviceMenu, SWT.NONE);
+        item.setText("&Screen capture...\tCTrl-S");
+        item.setAccelerator('S' | SWT.CONTROL);
+        item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                if (mCurrentDevice != null) {
+                    ScreenShotDialog dlg = new ScreenShotDialog(shell);
+                    dlg.open(mCurrentDevice);
+                }
+            }
+        });
+
+        new MenuItem(deviceMenu, SWT.SEPARATOR);
+
+        item = new MenuItem(deviceMenu, SWT.NONE);
+        item.setText("File Explorer...");
+        item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                createFileExplorer();
+            }
+        });
+
+        new MenuItem(deviceMenu, SWT.SEPARATOR);
+
+        item = new MenuItem(deviceMenu, SWT.NONE);
+        item.setText("Show &process status...");
+        item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                DeviceCommandDialog dlg;
+                dlg = new DeviceCommandDialog("ps -x", "ps-x.txt", shell);
+                dlg.open(mCurrentDevice);
+            }
+        });
+
+        item = new MenuItem(deviceMenu, SWT.NONE);
+        item.setText("Dump &device state...");
+        item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                DeviceCommandDialog dlg;
+                dlg = new DeviceCommandDialog("/system/bin/dumpstate /proc/self/fd/0",
+                        "device-state.txt", shell);
+                dlg.open(mCurrentDevice);
+            }
+        });
+
+        item = new MenuItem(deviceMenu, SWT.NONE);
+        item.setText("Dump &app state...");
+        item.setEnabled(false);
+        item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                DeviceCommandDialog dlg;
+                dlg = new DeviceCommandDialog("dumpsys", "app-state.txt", shell);
+                dlg.open(mCurrentDevice);
+            }
+        });
+
+        item = new MenuItem(deviceMenu, SWT.NONE);
+        item.setText("Dump &radio state...");
+        item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                DeviceCommandDialog dlg;
+                dlg = new DeviceCommandDialog(
+                        "cat /data/logs/radio.4 /data/logs/radio.3"
+                        + " /data/logs/radio.2 /data/logs/radio.1"
+                        + " /data/logs/radio",
+                        "radio-state.txt", shell);
+                dlg.open(mCurrentDevice);
+            }
+        });
+
+        item = new MenuItem(deviceMenu, SWT.NONE);
+        item.setText("Run &logcat...");
+        item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                DeviceCommandDialog dlg;
+                dlg = new DeviceCommandDialog("logcat '*:d jdwp:w'", "log.txt",
+                        shell);
+                dlg.open(mCurrentDevice);
+            }
+        });
+
+        // create Help menu items
+        item = new MenuItem(helpMenu, SWT.NONE);
+        item.setText("&Contents...");
+        item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                int style = SWT.APPLICATION_MODAL | SWT.OK;
+                MessageBox msgBox = new MessageBox(shell, style);
+                msgBox.setText("Help!");
+                msgBox.setMessage("Help wanted.");
+                msgBox.open();
+            }
+        });
+
+        new MenuItem(helpMenu, SWT.SEPARATOR);
+
+        item = new MenuItem(helpMenu, SWT.NONE);
+        item.setText("&About...");
+        item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                AboutDialog dlg = new AboutDialog(shell);
+                dlg.open();
+            }
+        });
+
+        // tell the shell to use this menu
+        shell.setMenuBar(menuBar);
+    }
+
+    /*
+     * Create the widgets in the main application window. The basic layout is a
+     * two-panel sash, with a scrolling list of VMs on the left and detailed
+     * output for a single VM on the right.
+     */
+    private void createWidgets(final Shell shell) {
+        Color darkGray = shell.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
+
+        /*
+         * Create three areas: tool bar, split panels, status line
+         */
+        shell.setLayout(new GridLayout(1, false));
+
+        // 1. panel area
+        final Composite panelArea = new Composite(shell, SWT.BORDER);
+
+        // make the panel area absorb all space
+        panelArea.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        // 2. status line.
+        mStatusLine = new Label(shell, SWT.NONE);
+
+        // make status line extend all the way across
+        mStatusLine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        mStatusLine.setText("Initializing...");
+
+        /*
+         * Configure the split-panel area.
+         */
+        final PreferenceStore prefs = PrefsDialog.getStore();
+
+        Composite topPanel = new Composite(panelArea, SWT.NONE);
+        final Sash sash = new Sash(panelArea, SWT.HORIZONTAL);
+        sash.setBackground(darkGray);
+        Composite bottomPanel = new Composite(panelArea, SWT.NONE);
+
+        panelArea.setLayout(new FormLayout());
+
+        createTopPanel(topPanel, darkGray);
+        createBottomPanel(bottomPanel);
+
+        // form layout data
+        FormData data = new FormData();
+        data.top = new FormAttachment(0, 0);
+        data.bottom = new FormAttachment(sash, 0);
+        data.left = new FormAttachment(0, 0);
+        data.right = new FormAttachment(100, 0);
+        topPanel.setLayoutData(data);
+
+        final FormData sashData = new FormData();
+        if (prefs != null && prefs.contains(PREFERENCE_LOGSASH)) {
+            sashData.top = new FormAttachment(0, prefs.getInt(
+                    PREFERENCE_LOGSASH));
+        } else {
+            sashData.top = new FormAttachment(50,0); // 50% across
+        }
+        sashData.left = new FormAttachment(0, 0);
+        sashData.right = new FormAttachment(100, 0);
+        sash.setLayoutData(sashData);
+
+        data = new FormData();
+        data.top = new FormAttachment(sash, 0);
+        data.bottom = new FormAttachment(100, 0);
+        data.left = new FormAttachment(0, 0);
+        data.right = new FormAttachment(100, 0);
+        bottomPanel.setLayoutData(data);
+
+        // allow resizes, but cap at minPanelWidth
+        sash.addListener(SWT.Selection, new Listener() {
+            public void handleEvent(Event e) {
+                Rectangle sashRect = sash.getBounds();
+                Rectangle panelRect = panelArea.getClientArea();
+                int bottom = panelRect.height - sashRect.height - 100;
+                e.y = Math.max(Math.min(e.y, bottom), 100);
+                if (e.y != sashRect.y) {
+                    sashData.top = new FormAttachment(0, e.y);
+                    prefs.setValue(PREFERENCE_LOGSASH, e.y);
+                    panelArea.layout();
+                }
+            }
+        });
+
+        // add a global focus listener for all the tables
+        mTableListener = new TableFocusListener();
+
+        // now set up the listener in the various panels
+        mLogPanel.setTableFocusListener(mTableListener);
+        mEventLogPanel.setTableFocusListener(mTableListener);
+        for (TablePanel p : mPanels) {
+            if (p != null) {
+                p.setTableFocusListener(mTableListener);
+            }
+        }
+        
+        mStatusLine.setText("");
+    }
+
+    /*
+     * Populate the tool bar.
+     */
+    private void createDevicePanelToolBar(ToolBar toolBar) {
+        Display display = toolBar.getDisplay();
+        
+        // add "show thread updates" button
+        mTBShowThreadUpdates = new ToolItem(toolBar, SWT.CHECK);
+        mTBShowThreadUpdates.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
+                DevicePanel.ICON_THREAD, DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+        mTBShowThreadUpdates.setToolTipText("Show thread updates");
+        mTBShowThreadUpdates.setEnabled(false);
+        mTBShowThreadUpdates.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                if (mCurrentClient != null) {
+                    // boolean status = ((ToolItem)e.item).getSelection();
+                    // invert previous state
+                    boolean enable = !mCurrentClient.isThreadUpdateEnabled();
+
+                    mCurrentClient.setThreadUpdateEnabled(enable);
+                } else {
+                    e.doit = false; // this has no effect?
+                }
+            }
+        });
+
+        // add "show heap updates" button
+        mTBShowHeapUpdates = new ToolItem(toolBar, SWT.CHECK);
+        mTBShowHeapUpdates.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
+                DevicePanel.ICON_HEAP, DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+        mTBShowHeapUpdates.setToolTipText("Show heap updates");
+        mTBShowHeapUpdates.setEnabled(false);
+        mTBShowHeapUpdates.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                if (mCurrentClient != null) {
+                    // boolean status = ((ToolItem)e.item).getSelection();
+                    // invert previous state
+                    boolean enable = !mCurrentClient.isHeapUpdateEnabled();
+                    mCurrentClient.setHeapUpdateEnabled(enable);
+                } else {
+                    e.doit = false; // this has no effect?
+                }
+            }
+        });
+
+        new ToolItem(toolBar, SWT.SEPARATOR);
+
+        // add "kill VM" button; need to make this visually distinct from
+        // the status update buttons
+        mTBHalt = new ToolItem(toolBar, SWT.PUSH);
+        mTBHalt.setToolTipText("Halt the target VM");
+        mTBHalt.setEnabled(false);
+        mTBHalt.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
+                DevicePanel.ICON_HALT, DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+        mTBHalt.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mDevicePanel.killSelectedClient();
+            }
+        });
+        
+        new ToolItem(toolBar, SWT.SEPARATOR);
+
+        // add "cause GC" button
+        mTBCauseGc = new ToolItem(toolBar, SWT.PUSH);
+        mTBCauseGc.setToolTipText("Cause an immediate GC in the target VM");
+        mTBCauseGc.setEnabled(false);
+        mTBCauseGc.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
+                DevicePanel.ICON_GC, DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+        mTBCauseGc.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mDevicePanel.forceGcOnSelectedClient();
+            }
+        });
+
+       toolBar.pack();
+    }
+
+    private void createTopPanel(final Composite comp, Color darkGray) {
+        final PreferenceStore prefs = PrefsDialog.getStore();
+
+        comp.setLayout(new FormLayout());
+
+        Composite leftPanel = new Composite(comp, SWT.NONE);
+        final Sash sash = new Sash(comp, SWT.VERTICAL);
+        sash.setBackground(darkGray);
+        Composite rightPanel = new Composite(comp, SWT.NONE);
+
+        createLeftPanel(leftPanel);
+        createRightPanel(rightPanel);
+
+        FormData data = new FormData();
+        data.top = new FormAttachment(0, 0);
+        data.bottom = new FormAttachment(100, 0);
+        data.left = new FormAttachment(0, 0);
+        data.right = new FormAttachment(sash, 0);
+        leftPanel.setLayoutData(data);
+
+        final FormData sashData = new FormData();
+        sashData.top = new FormAttachment(0, 0);
+        sashData.bottom = new FormAttachment(100, 0);
+        if (prefs != null && prefs.contains(PREFERENCE_SASH)) {
+            sashData.left = new FormAttachment(0, prefs.getInt(
+                    PREFERENCE_SASH));
+        } else {
+            // position the sash 380 from the right instead of x% (done by using
+            // FormAttachment(x, 0)) in order to keep the sash at the same
+            // position
+            // from the left when the window is resized.
+            // 380px is just enough to display the left table with no horizontal
+            // scrollbar with the default font.
+            sashData.left = new FormAttachment(0, 380);
+        }
+        sash.setLayoutData(sashData);
+
+        data = new FormData();
+        data.top = new FormAttachment(0, 0);
+        data.bottom = new FormAttachment(100, 0);
+        data.left = new FormAttachment(sash, 0);
+        data.right = new FormAttachment(100, 0);
+        rightPanel.setLayoutData(data);
+
+        final int minPanelWidth = 60;
+
+        // allow resizes, but cap at minPanelWidth
+        sash.addListener(SWT.Selection, new Listener() {
+            public void handleEvent(Event e) {
+                Rectangle sashRect = sash.getBounds();
+                Rectangle panelRect = comp.getClientArea();
+                int right = panelRect.width - sashRect.width - minPanelWidth;
+                e.x = Math.max(Math.min(e.x, right), minPanelWidth);
+                if (e.x != sashRect.x) {
+                    sashData.left = new FormAttachment(0, e.x);
+                    prefs.setValue(PREFERENCE_SASH, e.x);
+                    comp.layout();
+                }
+            }
+        });
+    }
+
+    private void createBottomPanel(final Composite comp) {
+        final PreferenceStore prefs = PrefsDialog.getStore();
+
+        // create clipboard
+        Display display = comp.getDisplay();
+        mClipboard = new Clipboard(display);
+
+        LogColors colors = new LogColors();
+
+        colors.infoColor = new Color(display, 0, 127, 0);
+        colors.debugColor = new Color(display, 0, 0, 127);
+        colors.errorColor = new Color(display, 255, 0, 0);
+        colors.warningColor = new Color(display, 255, 127, 0);
+        colors.verboseColor = new Color(display, 0, 0, 0);
+
+        // set the preferences names
+        LogPanel.PREFS_TIME = PREFS_COL_TIME;
+        LogPanel.PREFS_LEVEL = PREFS_COL_LEVEL;
+        LogPanel.PREFS_PID = PREFS_COL_PID;
+        LogPanel.PREFS_TAG = PREFS_COL_TAG;
+        LogPanel.PREFS_MESSAGE = PREFS_COL_MESSAGE;
+
+        comp.setLayout(new GridLayout(1, false));
+
+        ToolBar toolBar = new ToolBar(comp, SWT.HORIZONTAL);
+
+        mCreateFilterAction = new ToolItemAction(toolBar, SWT.PUSH);
+        mCreateFilterAction.item.setToolTipText("Create Filter");
+        mCreateFilterAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
+                "add.png", //$NON-NLS-1$
+                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+        mCreateFilterAction.item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mLogPanel.addFilter();
+            }
+        });
+
+        mEditFilterAction = new ToolItemAction(toolBar, SWT.PUSH);
+        mEditFilterAction.item.setToolTipText("Edit Filter");
+        mEditFilterAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
+                "edit.png", //$NON-NLS-1$
+                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+        mEditFilterAction.item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mLogPanel.editFilter();
+            }
+        });
+
+        mDeleteFilterAction = new ToolItemAction(toolBar, SWT.PUSH);
+        mDeleteFilterAction.item.setToolTipText("Delete Filter");
+        mDeleteFilterAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
+                "delete.png", //$NON-NLS-1$
+                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+        mDeleteFilterAction.item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mLogPanel.deleteFilter();
+            }
+        });
+
+
+        new ToolItem(toolBar, SWT.SEPARATOR);
+
+        LogLevel[] levels = LogLevel.values();
+        mLogLevelActions = new ToolItemAction[mLogLevelIcons.length];
+        for (int i = 0 ; i < mLogLevelActions.length; i++) {
+            String name = levels[i].getStringValue();
+            final ToolItemAction newAction = new ToolItemAction(toolBar, SWT.CHECK);
+            mLogLevelActions[i] = newAction;
+            //newAction.item.setText(name);
+            newAction.item.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    // disable the other actions and record current index
+                    for (int i = 0 ; i < mLogLevelActions.length; i++) {
+                        ToolItemAction a = mLogLevelActions[i];
+                        if (a == newAction) {
+                            a.setChecked(true);
+
+                            // set the log level
+                            mLogPanel.setCurrentFilterLogLevel(i+2);
+                        } else {
+                            a.setChecked(false);
+                        }
+                    }
+                }
+            });
+
+            newAction.item.setToolTipText(name);
+            newAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
+                    mLogLevelIcons[i],
+                    DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+        }
+
+        new ToolItem(toolBar, SWT.SEPARATOR);
+
+        mClearAction = new ToolItemAction(toolBar, SWT.PUSH);
+        mClearAction.item.setToolTipText("Clear Log");
+        
+        mClearAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
+                "clear.png", //$NON-NLS-1$
+                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+        mClearAction.item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mLogPanel.clear();
+            }
+        });
+
+        new ToolItem(toolBar, SWT.SEPARATOR);
+
+        mExportAction = new ToolItemAction(toolBar, SWT.PUSH);
+        mExportAction.item.setToolTipText("Export Selection As Text...");
+        mExportAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
+                "save.png", //$NON-NLS-1$
+                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+        mExportAction.item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mLogPanel.save();
+            }
+        });
+
+
+        toolBar.pack();
+
+        // now create the log view
+        mLogPanel = new LogPanel(new ImageLoader(LogPanel.class), colors, new FilterStorage(),
+                LogPanel.FILTER_MANUAL);
+
+        mLogPanel.setActions(mDeleteFilterAction, mEditFilterAction, mLogLevelActions);
+
+        String colMode = prefs.getString(PrefsDialog.LOGCAT_COLUMN_MODE);
+        if (PrefsDialog.LOGCAT_COLUMN_MODE_AUTO.equals(colMode)) {
+            mLogPanel.setColumnMode(LogPanel.COLUMN_MODE_AUTO);
+        }
+
+        String fontStr = PrefsDialog.getStore().getString(PrefsDialog.LOGCAT_FONT);
+        if (fontStr != null) {
+            try {
+                FontData fdat = new FontData(fontStr);
+                mLogPanel.setFont(new Font(display, fdat));
+            } catch (IllegalArgumentException e) {
+                // Looks like fontStr isn't a valid font representation.
+                // We do nothing in this case, the logcat view will use the default font.
+            } catch (SWTError e2) {
+                // Looks like the Font() constructor failed.
+                // We do nothing in this case, the logcat view will use the default font.
+            }
+        }
+
+        mLogPanel.createPanel(comp);
+
+        // and start the logcat
+        mLogPanel.startLogCat(mCurrentDevice);
+    }
+
+    /*
+     * Create the contents of the left panel: a table of VMs.
+     */
+    private void createLeftPanel(final Composite comp) {
+        comp.setLayout(new GridLayout(1, false));
+        ToolBar toolBar = new ToolBar(comp, SWT.HORIZONTAL | SWT.RIGHT | SWT.WRAP);
+        toolBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        createDevicePanelToolBar(toolBar);
+
+        Composite c = new Composite(comp, SWT.NONE);
+        c.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        mDevicePanel = new DevicePanel(new ImageLoader(DevicePanel.class), true /* showPorts */);
+        mDevicePanel.createPanel(c);
+
+        // add ourselves to the device panel selection listener
+        mDevicePanel.addSelectionListener(this);
+    }
+
+    /*
+     * Create the contents of the right panel: tabs with VM information.
+     */
+    private void createRightPanel(final Composite comp) {
+        TabItem item;
+        TabFolder tabFolder;
+
+        comp.setLayout(new FillLayout());
+
+        tabFolder = new TabFolder(comp, SWT.NONE);
+
+        for (int i = 0; i < mPanels.length; i++) {
+            if (mPanels[i] != null) {
+                item = new TabItem(tabFolder, SWT.NONE);
+                item.setText(mPanelNames[i]);
+                item.setToolTipText(mPanelTips[i]);
+                item.setControl(mPanels[i].createPanel(tabFolder));
+            }
+        }
+
+        // add the emulator control panel to the folders.
+        item = new TabItem(tabFolder, SWT.NONE);
+        item.setText("Emulator Control");
+        item.setToolTipText("Emulator Control Panel");
+        mEmulatorPanel = new EmulatorControlPanel(mDdmuiLibImageLoader);
+        item.setControl(mEmulatorPanel.createPanel(tabFolder));
+
+        // add the event log panel to the folders.
+        item = new TabItem(tabFolder, SWT.NONE);
+        item.setText("Event Log");
+        item.setToolTipText("Event Log");
+        
+        // create the composite that will hold the toolbar and the event log panel.
+        Composite eventLogTopComposite = new Composite(tabFolder, SWT.NONE);
+        item.setControl(eventLogTopComposite);
+        eventLogTopComposite.setLayout(new GridLayout(1, false));
+        
+        // create the toolbar and the actions
+        ToolBar toolbar = new ToolBar(eventLogTopComposite, SWT.HORIZONTAL);
+        toolbar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        ToolItemAction optionsAction = new ToolItemAction(toolbar, SWT.PUSH);
+        optionsAction.item.setToolTipText("Opens the options panel");
+        optionsAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
+                "edit.png", //$NON-NLS-1$
+                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+
+        ToolItemAction clearAction = new ToolItemAction(toolbar, SWT.PUSH);
+        clearAction.item.setToolTipText("Clears the event log");
+        clearAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
+                "clear.png", //$NON-NLS-1$
+                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+        
+        new ToolItem(toolbar, SWT.SEPARATOR);
+
+        ToolItemAction saveAction = new ToolItemAction(toolbar, SWT.PUSH);
+        saveAction.item.setToolTipText("Saves the event log");
+        saveAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
+                "save.png", //$NON-NLS-1$
+                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+
+        ToolItemAction loadAction = new ToolItemAction(toolbar, SWT.PUSH);
+        loadAction.item.setToolTipText("Loads an event log");
+        loadAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
+                "load.png", //$NON-NLS-1$
+                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+
+        ToolItemAction importBugAction = new ToolItemAction(toolbar, SWT.PUSH);
+        importBugAction.item.setToolTipText("Imports a bug report");
+        importBugAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
+                "importBug.png", //$NON-NLS-1$
+                DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
+
+        // create the event log panel
+        mEventLogPanel = new EventLogPanel(mDdmuiLibImageLoader);
+        
+        // set the external actions
+        mEventLogPanel.setActions(optionsAction, clearAction, saveAction, loadAction,
+                importBugAction);
+
+        // create the panel
+        mEventLogPanel.createPanel(eventLogTopComposite);
+    }
+
+    private void createFileExplorer() {
+        if (mExplorer == null) {
+            mExplorerShell = new Shell(mDisplay);
+
+            // create the ui
+            mExplorerShell.setLayout(new GridLayout(1, false));
+
+            // toolbar + action
+            ToolBar toolBar = new ToolBar(mExplorerShell, SWT.HORIZONTAL);
+            toolBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+            ToolItemAction pullAction = new ToolItemAction(toolBar, SWT.PUSH);
+            pullAction.item.setToolTipText("Pull File from Device");
+            pullAction.item.setImage(mDdmuiLibImageLoader.loadImage("pull.png", mDisplay)); //$NON-NLS-1$
+
+            ToolItemAction pushAction = new ToolItemAction(toolBar, SWT.PUSH);
+            pushAction.item.setToolTipText("Push file onto Device");
+            pushAction.item.setImage(mDdmuiLibImageLoader.loadImage("push.png", mDisplay)); //$NON-NLS-1$
+
+            ToolItemAction deleteAction = new ToolItemAction(toolBar, SWT.PUSH);
+            deleteAction.item.setToolTipText("Delete");
+            deleteAction.item.setImage(mDdmuiLibImageLoader.loadImage("delete.png", mDisplay)); //$NON-NLS-1$
+
+            // device explorer
+            mExplorer = new DeviceExplorer();
+
+            mExplorer.setImages(mDdmuiLibImageLoader.loadImage("file.png", mDisplay), //$NON-NLS-1$
+                    mDdmuiLibImageLoader.loadImage("folder.png", mDisplay), //$NON-NLS-1$
+                    mDdmuiLibImageLoader.loadImage("android.png", mDisplay), //$NON-NLS-1$
+                    null);
+            mExplorer.setActions(pushAction, pullAction, deleteAction);
+
+            pullAction.item.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    mExplorer.pullSelection();
+                }
+            });
+            pullAction.setEnabled(false);
+
+            pushAction.item.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    mExplorer.pushIntoSelection();
+                }
+            });
+            pushAction.setEnabled(false);
+
+            deleteAction.item.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    mExplorer.deleteSelection();
+                }
+            });
+            deleteAction.setEnabled(false);
+
+            Composite parent = new Composite(mExplorerShell, SWT.NONE);
+            parent.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+            mExplorer.createPanel(parent);
+            mExplorer.switchDevice(mCurrentDevice);
+
+            mExplorerShell.addShellListener(new ShellListener() {
+                public void shellActivated(ShellEvent e) {
+                    // pass
+                }
+
+                public void shellClosed(ShellEvent e) {
+                    mExplorer = null;
+                    mExplorerShell = null;
+                }
+
+                public void shellDeactivated(ShellEvent e) {
+                    // pass
+                }
+
+                public void shellDeiconified(ShellEvent e) {
+                    // pass
+                }
+
+                public void shellIconified(ShellEvent e) {
+                    // pass
+                }
+            });
+
+            mExplorerShell.pack();
+            setExplorerSizeAndPosition(mExplorerShell);
+            mExplorerShell.open();
+        } else {
+            if (mExplorerShell != null) {
+                mExplorerShell.forceActive();
+            }
+        }
+    }
+
+    /**
+     * Set the status line. TODO: make this a stack, so we can safely have
+     * multiple things trying to set it all at once. Also specify an expiration?
+     */
+    public void setStatusLine(final String str) {
+        try {
+            mDisplay.asyncExec(new Runnable() {
+                public void run() {
+                    doSetStatusLine(str);
+                }
+            });
+        } catch (SWTException swte) {
+            if (!mDisplay.isDisposed())
+                throw swte;
+        }
+    }
+
+    private void doSetStatusLine(String str) {
+        if (mStatusLine.isDisposed())
+            return;
+
+        if (!mStatusLine.getText().equals(str)) {
+            mStatusLine.setText(str);
+
+            // try { Thread.sleep(100); }
+            // catch (InterruptedException ie) {}
+        }
+    }
+
+    public void displayError(final String msg) {
+        try {
+            mDisplay.syncExec(new Runnable() {
+                public void run() {
+                    MessageDialog.openError(mDisplay.getActiveShell(), "Error",
+                            msg);
+                }
+            });
+        } catch (SWTException swte) {
+            if (!mDisplay.isDisposed())
+                throw swte;
+        }
+    }
+
+    private void enableButtons() {
+        if (mCurrentClient != null) {
+            mTBShowThreadUpdates.setSelection(mCurrentClient.isThreadUpdateEnabled());
+            mTBShowThreadUpdates.setEnabled(true);
+            mTBShowHeapUpdates.setSelection(mCurrentClient.isHeapUpdateEnabled());
+            mTBShowHeapUpdates.setEnabled(true);
+            mTBHalt.setEnabled(true);
+            mTBCauseGc.setEnabled(true);
+        } else {
+            // list is empty, disable these
+            mTBShowThreadUpdates.setSelection(false);
+            mTBShowThreadUpdates.setEnabled(false);
+            mTBShowHeapUpdates.setSelection(false);
+            mTBShowHeapUpdates.setEnabled(false);
+            mTBHalt.setEnabled(false);
+            mTBCauseGc.setEnabled(false);
+        }
+    }
+
+    /**
+     * Sent when a new {@link Device} 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) {
+        if (mCurrentDevice != selectedDevice) {
+            mCurrentDevice = selectedDevice;
+            for (TablePanel panel : mPanels) {
+                if (panel != null) {
+                    panel.deviceSelected(mCurrentDevice);
+                }
+            }
+
+            mEmulatorPanel.deviceSelected(mCurrentDevice);
+            mLogPanel.deviceSelected(mCurrentDevice);
+            if (mEventLogPanel != null) {
+                mEventLogPanel.deviceSelected(mCurrentDevice);
+            }
+
+            if (mExplorer != null) {
+                mExplorer.switchDevice(mCurrentDevice);
+            }
+        }
+
+        if (mCurrentClient != selectedClient) {
+            AndroidDebugBridge.getBridge().setSelectedClient(selectedClient);
+            mCurrentClient = selectedClient;
+            for (TablePanel panel : mPanels) {
+                if (panel != null) {
+                    panel.clientSelected(mCurrentClient);
+                }
+            }
+
+            enableButtons();
+        }
+    }
+}
diff --git a/tools/ddms/app/src/resources/images/ddms-icon.png b/tools/ddms/app/src/resources/images/ddms-icon.png
new file mode 100644
index 0000000..167a83b
--- /dev/null
+++ b/tools/ddms/app/src/resources/images/ddms-icon.png
Binary files differ
diff --git a/tools/ddms/app/src/resources/images/ddms-logo.png b/tools/ddms/app/src/resources/images/ddms-logo.png
new file mode 100644
index 0000000..b4708b4
--- /dev/null
+++ b/tools/ddms/app/src/resources/images/ddms-logo.png
Binary files differ
diff --git a/tools/ddms/libs/Android.mk b/tools/ddms/libs/Android.mk
new file mode 100644
index 0000000..c62c6d0
--- /dev/null
+++ b/tools/ddms/libs/Android.mk
@@ -0,0 +1,5 @@
+# Copyright 2007 The Android Open Source Project
+#
+DDMSLIBS_LOCAL_DIR := $(call my-dir)
+include $(DDMSLIBS_LOCAL_DIR)/ddmlib/Android.mk
+include $(DDMSLIBS_LOCAL_DIR)/ddmuilib/Android.mk
diff --git a/tools/ddms/libs/ddmlib/.classpath b/tools/ddms/libs/ddmlib/.classpath
new file mode 100644
index 0000000..fb50116
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/.classpath
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/ddms/libs/ddmlib/.project b/tools/ddms/libs/ddmlib/.project
new file mode 100644
index 0000000..fea25c7
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>ddmlib</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/ddms/libs/ddmlib/Android.mk b/tools/ddms/libs/ddmlib/Android.mk
new file mode 100644
index 0000000..a49bdd2
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/Android.mk
@@ -0,0 +1,4 @@
+# Copyright 2007 The Android Open Source Project
+#
+DDMLIB_LOCAL_DIR := $(call my-dir)
+include $(DDMLIB_LOCAL_DIR)/src/Android.mk
diff --git a/tools/ddms/libs/ddmlib/src/Android.mk b/tools/ddms/libs/ddmlib/src/Android.mk
new file mode 100644
index 0000000..da07f97
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/Android.mk
@@ -0,0 +1,11 @@
+# Copyright 2007 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_MODULE := ddmlib
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java
new file mode 100644
index 0000000..42022fe
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AdbHelper.java
@@ -0,0 +1,714 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmlib.log.LogReceiver;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.SocketChannel;
+
+/**
+ * Helper class to handle requests and connections to adb.
+ * <p/>{@link DebugBridgeServer} is the public API to connection to adb, while {@link AdbHelper}
+ * does the low level stuff. 
+ * <p/>This currently uses spin-wait non-blocking I/O. A Selector would be more efficient,
+ * but seems like overkill for what we're doing here.
+ */
+final class AdbHelper {
+
+    // public static final long kOkay = 0x59414b4fL;
+    // public static final long kFail = 0x4c494146L;
+
+    static final int WAIT_TIME = 5; // spin-wait sleep, in ms
+
+    public static final int STD_TIMEOUT = 5000; // standard delay, in ms
+
+    static final String DEFAULT_ENCODING = "ISO-8859-1"; //$NON-NLS-1$
+
+    /** do not instantiate */
+    private AdbHelper() {
+    }
+
+    /**
+     * Response from ADB.
+     */
+    static class AdbResponse {
+        public AdbResponse() {
+            // ioSuccess = okay = timeout = false;
+            message = "";
+        }
+
+        public boolean ioSuccess; // read all expected data, no timeoutes
+
+        public boolean okay; // first 4 bytes in response were "OKAY"?
+
+        public boolean timeout; // TODO: implement
+
+        public String message; // diagnostic string
+    }
+
+    /**
+     * Create and connect a new pass-through socket, from the host to a port on
+     * the device.
+     *
+     * @param adbSockAddr
+     * @param device the device to connect to. Can be null in which case the connection will be
+     * to the first available device.
+     * @param devicePort the port we're opening
+     */
+    public static SocketChannel open(InetSocketAddress adbSockAddr,
+            Device device, int devicePort) throws IOException {
+
+        SocketChannel adbChan = SocketChannel.open(adbSockAddr);
+        try {
+            adbChan.socket().setTcpNoDelay(true);
+            adbChan.configureBlocking(false);
+
+            // if the device is not -1, then we first tell adb we're looking to
+            // talk to a specific device
+            setDevice(adbChan, device);
+
+            byte[] req = createAdbForwardRequest(null, devicePort);
+            // Log.hexDump(req);
+
+            if (write(adbChan, req) == false)
+                throw new IOException("failed submitting request to ADB"); //$NON-NLS-1$
+
+            AdbResponse resp = readAdbResponse(adbChan, false);
+            if (!resp.okay)
+                throw new IOException("connection request rejected"); //$NON-NLS-1$
+
+            adbChan.configureBlocking(true);
+        } catch (IOException ioe) {
+            adbChan.close();
+            throw ioe;
+        }
+
+        return adbChan;
+    }
+
+    /**
+     * Creates and connects a new pass-through socket, from the host to a port on
+     * the device.
+     *
+     * @param adbSockAddr
+     * @param device the device to connect to. Can be null in which case the connection will be
+     * to the first available device.
+     * @param pid the process pid to connect to.
+     */
+    public static SocketChannel createPassThroughConnection(InetSocketAddress adbSockAddr,
+            Device device, int pid) throws IOException {
+
+        SocketChannel adbChan = SocketChannel.open(adbSockAddr);
+        try {
+            adbChan.socket().setTcpNoDelay(true);
+            adbChan.configureBlocking(false);
+
+            // if the device is not -1, then we first tell adb we're looking to
+            // talk to a specific device
+            setDevice(adbChan, device);
+
+            byte[] req = createJdwpForwardRequest(pid);
+            // Log.hexDump(req);
+
+            if (write(adbChan, req) == false)
+                throw new IOException("failed submitting request to ADB"); //$NON-NLS-1$
+
+            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
+            if (!resp.okay)
+                throw new IOException("connection request rejected: " + resp.message); //$NON-NLS-1$
+
+            adbChan.configureBlocking(true);
+        } catch (IOException ioe) {
+            adbChan.close();
+            throw ioe;
+        }
+
+        return adbChan;
+    }
+
+    /**
+     * Creates a port forwarding request for adb. This returns an array
+     * containing "####tcp:{port}:{addStr}".
+     * @param addrStr the host. Can be null.
+     * @param port the port on the device. This does not need to be numeric.
+     */
+    private static byte[] createAdbForwardRequest(String addrStr, int port) {
+        String reqStr;
+
+        if (addrStr == null)
+            reqStr = "tcp:" + port;
+        else
+            reqStr = "tcp:" + port + ":" + addrStr;
+        return formAdbRequest(reqStr);
+    }
+
+    /**
+     * Creates a port forwarding request to a jdwp process. This returns an array
+     * containing "####jwdp:{pid}".
+     * @param pid the jdwp process pid on the device.
+     */
+    private static byte[] createJdwpForwardRequest(int pid) {
+        String reqStr = String.format("jdwp:%1$d", pid); //$NON-NLS-1$
+        return formAdbRequest(reqStr);
+    }
+
+    /**
+     * Create an ASCII string preceeded by four hex digits. The opening "####"
+     * is the length of the rest of the string, encoded as ASCII hex (case
+     * doesn't matter). "port" and "host" are what we want to forward to. If
+     * we're on the host side connecting into the device, "addrStr" should be
+     * null.
+     */
+    static byte[] formAdbRequest(String req) {
+        String resultStr = String.format("%04X%s", req.length(), req); //$NON-NLS-1$
+        byte[] result;
+        try {
+            result = resultStr.getBytes(DEFAULT_ENCODING);
+        } catch (UnsupportedEncodingException uee) {
+            uee.printStackTrace(); // not expected
+            return null;
+        }
+        assert result.length == req.length() + 4;
+        return result;
+    }
+
+    /**
+     * Reads the response from ADB after a command.
+     * @param chan The socket channel that is connected to adb.
+     * @param readDiagString If true, we're expecting an OKAY response to be
+     *      followed by a diagnostic string. Otherwise, we only expect the
+     *      diagnostic string to follow a FAIL.
+     */
+    static AdbResponse readAdbResponse(SocketChannel chan, boolean readDiagString)
+            throws IOException {
+
+        AdbResponse resp = new AdbResponse();
+
+        byte[] reply = new byte[4];
+        if (read(chan, reply) == false) {
+            return resp;
+        }
+        resp.ioSuccess = true;
+
+        if (isOkay(reply)) {
+            resp.okay = true;
+        } else {
+            readDiagString = true; // look for a reason after the FAIL
+            resp.okay = false;
+        }
+
+        // not a loop -- use "while" so we can use "break"
+        while (readDiagString) {
+            // length string is in next 4 bytes
+            byte[] lenBuf = new byte[4];
+            if (read(chan, lenBuf) == false) {
+                Log.w("ddms", "Expected diagnostic string not found");
+                break;
+            }
+
+            String lenStr = replyToString(lenBuf);
+
+            int len;
+            try {
+                len = Integer.parseInt(lenStr, 16);
+            } catch (NumberFormatException nfe) {
+                Log.w("ddms", "Expected digits, got '" + lenStr + "': "
+                        + lenBuf[0] + " " + lenBuf[1] + " " + lenBuf[2] + " "
+                        + lenBuf[3]);
+                Log.w("ddms", "reply was " + replyToString(reply));
+                break;
+            }
+
+            byte[] msg = new byte[len];
+            if (read(chan, msg) == false) {
+                Log.w("ddms", "Failed reading diagnostic string, len=" + len);
+                break;
+            }
+
+            resp.message = replyToString(msg);
+            Log.v("ddms", "Got reply '" + replyToString(reply) + "', diag='"
+                    + resp.message + "'");
+
+            break;
+        }
+
+        return resp;
+    }
+
+    /**
+     * Retrieve the frame buffer from the device.
+     */
+    public static RawImage getFrameBuffer(InetSocketAddress adbSockAddr, Device device)
+            throws IOException {
+
+        RawImage imageParams = new RawImage();
+        byte[] request = formAdbRequest("framebuffer:"); //$NON-NLS-1$
+        byte[] nudge = {
+            0
+        };
+        byte[] reply;
+
+        SocketChannel adbChan = null;
+        try {
+            adbChan = SocketChannel.open(adbSockAddr);
+            adbChan.configureBlocking(false);
+    
+            // if the device is not -1, then we first tell adb we're looking to talk
+            // to a specific device
+            setDevice(adbChan, device);
+    
+            if (write(adbChan, request) == false)
+                throw new IOException("failed asking for frame buffer");
+    
+            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
+            if (!resp.ioSuccess || !resp.okay) {
+                Log.w("ddms", "Got timeout or unhappy response from ADB fb req: "
+                        + resp.message);
+                adbChan.close();
+                return null;
+            }
+    
+            reply = new byte[16];
+            if (read(adbChan, reply) == false) {
+                Log.w("ddms", "got partial reply from ADB fb:");
+                Log.hexDump("ddms", LogLevel.WARN, reply, 0, reply.length);
+                adbChan.close();
+                return null;
+            }
+            ByteBuffer buf = ByteBuffer.wrap(reply);
+            buf.order(ByteOrder.LITTLE_ENDIAN);
+    
+            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");
+                adbChan.close();
+                return null;
+            }
+            imageParams.data = reply;
+        } finally {
+            if (adbChan != null) {
+                adbChan.close();
+            }
+        }
+
+        return imageParams;
+    }
+
+    /**
+     * Execute a command on the device and retrieve the output. The output is
+     * handed to "rcvr" as it arrives.
+     */
+    public static void executeRemoteCommand(InetSocketAddress adbSockAddr,
+            String command, Device device, IShellOutputReceiver rcvr)
+            throws IOException {
+        Log.v("ddms", "execute: running " + command);
+
+        SocketChannel adbChan = null;
+        try {
+            adbChan = SocketChannel.open(adbSockAddr);
+            adbChan.configureBlocking(false);
+
+            // if the device is not -1, then we first tell adb we're looking to
+            // talk
+            // to a specific device
+            setDevice(adbChan, device);
+
+            byte[] request = formAdbRequest("shell:" + command); //$NON-NLS-1$
+            if (write(adbChan, request) == false)
+                throw new IOException("failed submitting shell command");
+
+            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
+            if (!resp.ioSuccess || !resp.okay) {
+                Log.e("ddms", "ADB rejected shell command (" + command + "): " + resp.message);
+                throw new IOException("sad result from adb: " + resp.message);
+            }
+
+            byte[] data = new byte[16384];
+            ByteBuffer buf = ByteBuffer.wrap(data);
+            while (true) {
+                int count;
+
+                if (rcvr != null && rcvr.isCancelled()) {
+                    Log.v("ddms", "execute: cancelled");
+                    break;
+                }
+
+                count = adbChan.read(buf);
+                if (count < 0) {
+                    // we're at the end, we flush the output
+                    rcvr.flush();
+                    Log.v("ddms", "execute '" + command + "' on '" + device + "' : EOF hit. Read: "
+                            + count);
+                    break;
+                } else if (count == 0) {
+                    try {
+                        Thread.sleep(WAIT_TIME * 5);
+                    } catch (InterruptedException ie) {
+                    }
+                } else {
+                    if (rcvr != null) {
+                        rcvr.addOutput(buf.array(), buf.arrayOffset(), buf.position());
+                    }
+                    buf.rewind();
+                }
+            }
+        } finally {
+            if (adbChan != null) {
+                adbChan.close();
+            }
+            Log.v("ddms", "execute: returning");
+        }
+    }
+
+    /**
+     * Runs the Event log service on the {@link Device}, and provides its output to the
+     * {@link LogReceiver}.
+     * @param adbSockAddr the socket address to connect to adb
+     * @param device the Device on which to run the service
+     * @param rcvr the {@link LogReceiver} to receive the log output
+     * @throws IOException
+     */
+    public static void runEventLogService(InetSocketAddress adbSockAddr, Device device,
+            LogReceiver rcvr) throws IOException {
+        runLogService(adbSockAddr, device, "events", rcvr); //$NON-NLS-1$
+    }
+
+    /**
+     * Runs a log service on the {@link Device}, and provides its output to the {@link LogReceiver}.
+     * @param adbSockAddr the socket address to connect to adb
+     * @param device the Device on which to run the service
+     * @param logName the name of the log file to output
+     * @param rcvr the {@link LogReceiver} to receive the log output
+     * @throws IOException
+     */
+    public static void runLogService(InetSocketAddress adbSockAddr, Device device, String logName,
+            LogReceiver rcvr) throws IOException {
+        SocketChannel adbChan = null;
+        
+        try {
+            adbChan = SocketChannel.open(adbSockAddr);
+            adbChan.configureBlocking(false);
+    
+            // if the device is not -1, then we first tell adb we're looking to talk
+            // to a specific device
+            setDevice(adbChan, device);
+    
+            byte[] request = formAdbRequest("log:" + logName);
+            if (write(adbChan, request) == false) {
+                throw new IOException("failed to submit the log command");
+            }
+    
+            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
+            if (!resp.ioSuccess || !resp.okay) {
+                throw new IOException("Device rejected log command: " + resp.message);
+            }
+    
+            byte[] data = new byte[16384];
+            ByteBuffer buf = ByteBuffer.wrap(data);
+            while (true) {
+                int count;
+    
+                if (rcvr != null && rcvr.isCancelled()) {
+                    break;
+                }
+    
+                count = adbChan.read(buf);
+                if (count < 0) {
+                    break;
+                } else if (count == 0) {
+                    try {
+                        Thread.sleep(WAIT_TIME * 5);
+                    } catch (InterruptedException ie) {
+                    }
+                } else {
+                    if (rcvr != null) {
+                        rcvr.parseNewData(buf.array(), buf.arrayOffset(), buf.position());
+                    }
+                    buf.rewind();
+                }
+            }
+        } finally {
+            if (adbChan != null) {
+                adbChan.close();
+            }
+        }
+    }
+    
+    /**
+     * Creates a port forwarding between a local and a remote port.
+     * @param adbSockAddr the socket address to connect to adb
+     * @param device the device on which to do the port fowarding
+     * @param localPort the local port to forward
+     * @param remotePort the remote port.
+     * @return <code>true</code> if success.
+     * @throws IOException 
+     */
+    public static boolean createForward(InetSocketAddress adbSockAddr, Device device, int localPort,
+            int remotePort) throws IOException {
+
+        SocketChannel adbChan = null;
+        try {
+            adbChan = SocketChannel.open(adbSockAddr);
+            adbChan.configureBlocking(false);
+    
+            byte[] request = formAdbRequest(String.format(
+                    "host-serial:%1$s:forward:tcp:%2$d;tcp:%3$d", //$NON-NLS-1$
+                    device.serialNumber, localPort, remotePort));
+    
+            if (write(adbChan, request) == false) {
+                throw new IOException("failed to submit the forward command.");
+            }
+            
+            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
+            if (!resp.ioSuccess || !resp.okay) {
+                throw new IOException("Device rejected command: " + resp.message);
+            }
+        } finally {
+            if (adbChan != null) {
+                adbChan.close();
+            }
+        }
+        
+        return true;
+    }
+
+    /**
+     * Remove a port forwarding between a local and a remote port.
+     * @param adbSockAddr the socket address to connect to adb
+     * @param device the device on which to remove the port fowarding
+     * @param localPort the local port of the forward
+     * @param remotePort the remote port.
+     * @return <code>true</code> if success.
+     * @throws IOException
+     */
+    public static boolean removeForward(InetSocketAddress adbSockAddr, Device device, int localPort,
+            int remotePort) throws IOException {
+
+        SocketChannel adbChan = null;
+        try {
+            adbChan = SocketChannel.open(adbSockAddr);
+            adbChan.configureBlocking(false);
+    
+            byte[] request = formAdbRequest(String.format(
+                    "host-serial:%1$s:killforward:tcp:%2$d;tcp:%3$d", //$NON-NLS-1$
+                    device.serialNumber, localPort, remotePort));
+    
+            if (!write(adbChan, request)) {
+                throw new IOException("failed to submit the remove forward command.");
+            }
+    
+            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
+            if (!resp.ioSuccess || !resp.okay) {
+                throw new IOException("Device rejected command: " + resp.message);
+            }
+        } finally {
+            if (adbChan != null) {
+                adbChan.close();
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Checks to see if the first four bytes in "reply" are OKAY.
+     */
+    static boolean isOkay(byte[] reply) {
+        return reply[0] == (byte)'O' && reply[1] == (byte)'K'
+                && reply[2] == (byte)'A' && reply[3] == (byte)'Y';
+    }
+
+    /**
+     * Converts an ADB reply to a string.
+     */
+    static String replyToString(byte[] reply) {
+        String result;
+        try {
+            result = new String(reply, DEFAULT_ENCODING);
+        } catch (UnsupportedEncodingException uee) {
+            uee.printStackTrace(); // not expected
+            result = "";
+        }
+        return result;
+    }
+    
+    /**
+     * Reads from the socket until the array is filled, or no more data is coming (because
+     * the socket closed or the timeout expired).
+     *
+     * @param chan the opened socket to read from. It must be in non-blocking
+     *      mode for timeouts to work
+     * @param data the buffer to store the read data into.
+     * @return "true" if all data was read.
+     * @throws IOException 
+     */
+    static boolean read(SocketChannel chan, byte[] data) {
+       try {
+           read(chan, data, -1, STD_TIMEOUT);
+       } catch (IOException e) {
+           Log.d("ddms", "readAll: IOException: " + e.getMessage());
+           return false;
+       }
+       
+       return true;
+    }
+
+    /**
+     * Reads from the socket until the array is filled, the optional length
+     * is reached, or no more data is coming (because the socket closed or the
+     * timeout expired). After "timeout" milliseconds since the
+     * previous successful read, this will return whether or not new data has
+     * been found.
+     *
+     * @param chan the opened socket to read from. It must be in non-blocking
+     *      mode for timeouts to work
+     * @param data the buffer to store the read data into.
+     * @param length the length to read or -1 to fill the data buffer completely
+     * @param timeout The timeout value. A timeout of zero means "wait forever".
+     * @throws IOException 
+     */
+    static void read(SocketChannel chan, byte[] data, int length, int timeout) throws IOException {
+        ByteBuffer buf = ByteBuffer.wrap(data, 0, length != -1 ? length : data.length);
+        int numWaits = 0;
+
+        while (buf.position() != buf.limit()) {
+            int count;
+
+            count = chan.read(buf);
+            if (count < 0) {
+                Log.d("ddms", "read: channel EOF");
+                throw new IOException("EOF");
+            } else if (count == 0) {
+                // TODO: need more accurate timeout?
+                if (timeout != 0 && numWaits * WAIT_TIME > timeout) {
+                    Log.i("ddms", "read: timeout");
+                    throw new IOException("timeout");
+                }
+                // non-blocking spin
+                try {
+                    Thread.sleep(WAIT_TIME);
+                } catch (InterruptedException ie) {
+                }
+                numWaits++;
+            } else {
+                numWaits = 0;
+            }
+        }
+    }
+
+    /**
+     * Write until all data in "data" is written or the connection fails.
+     * @param chan the opened socket to write to.
+     * @param data the buffer to send.
+     * @return "true" if all data was written.
+     */
+    static boolean write(SocketChannel chan, byte[] data) {
+        try {
+            write(chan, data, -1, STD_TIMEOUT);
+        } catch (IOException e) {
+            Log.e("ddms", e);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Write until all data in "data" is written, the optional length is reached,
+     * the timeout expires, or the connection fails. Returns "true" if all
+     * data was written.
+     * @param chan the opened socket to write to.
+     * @param data the buffer to send.
+     * @param length the length to write or -1 to send the whole buffer.
+     * @param timeout The timeout value. A timeout of zero means "wait forever".
+     * @throws IOException 
+     */
+    static void write(SocketChannel chan, byte[] data, int length, int timeout)
+            throws IOException {
+        ByteBuffer buf = ByteBuffer.wrap(data, 0, length != -1 ? length : data.length);
+        int numWaits = 0;
+
+        while (buf.position() != buf.limit()) {
+            int count;
+
+            count = chan.write(buf);
+            if (count < 0) {
+                Log.d("ddms", "write: channel EOF");
+                throw new IOException("channel EOF");
+            } else if (count == 0) {
+                // TODO: need more accurate timeout?
+                if (timeout != 0 && numWaits * WAIT_TIME > timeout) {
+                    Log.i("ddms", "write: timeout");
+                    throw new IOException("timeout");
+                }
+                // non-blocking spin
+                try {
+                    Thread.sleep(WAIT_TIME);
+                } catch (InterruptedException ie) {
+                }
+                numWaits++;
+            } else {
+                numWaits = 0;
+            }
+        }
+    }
+
+    /**
+     * tells adb to talk to a specific device
+     *
+     * @param adbChan the socket connection to adb
+     * @param device The device to talk to.
+     * @throws IOException
+     */
+    static void setDevice(SocketChannel adbChan, Device device)
+            throws IOException {
+        // if the device is not -1, then we first tell adb we're looking to talk
+        // to a specific device
+        if (device != null) {
+            String msg = "host:transport:" + device.serialNumber; //$NON-NLS-1$
+            byte[] device_query = formAdbRequest(msg);
+
+            if (write(adbChan, device_query) == false)
+                throw new IOException("failed submitting device (" + device +
+                        ") request to ADB");
+
+            AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
+            if (!resp.okay)
+                throw new IOException("device (" + device +
+                        ") request rejected: " + resp.message);
+        }
+
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AllocationInfo.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AllocationInfo.java
new file mode 100644
index 0000000..c6d4b50
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AllocationInfo.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+/**
+ * Holds an Allocation information.
+ */
+public class AllocationInfo implements Comparable<AllocationInfo>, IStackTraceInfo {
+    private String mAllocatedClass;
+    private int mAllocationSize;
+    private short mThreadId;
+    private StackTraceElement[] mStackTrace;
+
+    /*
+     * Simple constructor.
+     */
+    AllocationInfo(String allocatedClass, int allocationSize,
+        short threadId, StackTraceElement[] stackTrace) {
+        mAllocatedClass = allocatedClass;
+        mAllocationSize = allocationSize;
+        mThreadId = threadId;
+        mStackTrace = stackTrace;
+    }
+    
+    /**
+     * Returns the name of the allocated class.
+     */
+    public String getAllocatedClass() {
+        return mAllocatedClass;
+    }
+
+    /**
+     * Returns the size of the allocation.
+     */
+    public int getSize() {
+        return mAllocationSize;
+    }
+
+    /**
+     * Returns the id of the thread that performed the allocation.
+     */
+    public short getThreadId() {
+        return mThreadId;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IStackTraceInfo#getStackTrace()
+     */
+    public StackTraceElement[] getStackTrace() {
+        return mStackTrace;
+    }
+
+    public int compareTo(AllocationInfo otherAlloc) {
+        return otherAlloc.mAllocationSize - mAllocationSize;
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java
new file mode 100644
index 0000000..795bf88
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/AndroidDebugBridge.java
@@ -0,0 +1,1050 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import com.android.ddmlib.Log.LogLevel;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.Thread.State;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A connection to the host-side android debug bridge (adb)
+ * <p/>This is the central point to communicate with any devices, emulators, or the applications
+ * running on them.
+ * <p/><b>{@link #init(boolean)} must be called before anything is done.</b>
+ */
+public final class AndroidDebugBridge {
+    
+    /*
+     * Minimum and maximum version of adb supported. This correspond to
+     * ADB_SERVER_VERSION found in //device/tools/adb/adb.h
+     */
+
+    private final static int ADB_VERSION_MICRO_MIN = 20;
+    private final static int ADB_VERSION_MICRO_MAX = -1;
+
+    private final static Pattern sAdbVersion = Pattern.compile(
+            "^.*(\\d+)\\.(\\d+)\\.(\\d+)$"); //$NON-NLS-1$
+    
+    private final static String ADB = "adb"; //$NON-NLS-1$
+    private final static String DDMS = "ddms"; //$NON-NLS-1$
+
+    // Where to find the ADB bridge.
+    final static String ADB_HOST = "127.0.0.1"; //$NON-NLS-1$
+    final static int ADB_PORT = 5037;
+
+    static InetAddress sHostAddr;
+    static InetSocketAddress sSocketAddr;
+
+    static {
+        // built-in local address/port for ADB.
+        try {
+            sHostAddr = InetAddress.getByName(ADB_HOST);
+            sSocketAddr = new InetSocketAddress(sHostAddr, ADB_PORT);
+        } catch (UnknownHostException e) {
+
+        }
+    }
+
+    private static AndroidDebugBridge sThis;
+    private static boolean sClientSupport;
+
+    /** Full path to adb. */
+    private String mAdbOsLocation = null;
+
+    private boolean mVersionCheck;
+
+    private boolean mStarted = false;
+
+    private DeviceMonitor mDeviceMonitor;
+
+    private final static ArrayList<IDebugBridgeChangeListener> sBridgeListeners =
+        new ArrayList<IDebugBridgeChangeListener>();
+    private final static ArrayList<IDeviceChangeListener> sDeviceListeners =
+        new ArrayList<IDeviceChangeListener>();
+    private final static ArrayList<IClientChangeListener> sClientListeners =
+        new ArrayList<IClientChangeListener>();
+
+    // lock object for synchronization
+    private static final Object sLock = sBridgeListeners;
+
+    /**
+     * Classes which implement this interface provide a method that deals
+     * with {@link AndroidDebugBridge} changes.
+     */
+    public interface IDebugBridgeChangeListener {
+        /**
+         * Sent when a new {@link AndroidDebugBridge} is connected.
+         * <p/>
+         * This is sent from a non UI thread.
+         * @param bridge the new {@link AndroidDebugBridge} object.
+         */
+        public void bridgeChanged(AndroidDebugBridge bridge);
+    }
+
+    /**
+     * Classes which implement this interface provide methods that deal
+     * with {@link Device} addition, deletion, and changes.
+     */
+    public interface IDeviceChangeListener {
+        /**
+         * Sent when the a device is connected to the {@link AndroidDebugBridge}.
+         * <p/>
+         * This is sent from a non UI thread.
+         * @param device the new device.
+         */
+        public void deviceConnected(Device device);
+
+        /**
+         * Sent when the a device is connected to the {@link AndroidDebugBridge}.
+         * <p/>
+         * This is sent from a non UI thread.
+         * @param device the new device.
+         */
+        public void deviceDisconnected(Device device);
+
+        /**
+         * Sent when a device data changed, or when clients are started/terminated on the device.
+         * <p/>
+         * This is sent from a non UI thread.
+         * @param device the device that was updated.
+         * @param changeMask the mask describing what changed. It can contain any of the following
+         * values: {@link Device#CHANGE_BUILD_INFO}, {@link Device#CHANGE_STATE},
+         * {@link Device#CHANGE_CLIENT_LIST}
+         */
+        public void deviceChanged(Device device, int changeMask);
+    }
+
+    /**
+     * Classes which implement this interface provide methods that deal
+     * with {@link Client}  changes.
+     */
+    public interface IClientChangeListener {
+        /**
+         * Sent when an existing client information changed.
+         * <p/>
+         * This is sent from a non UI thread.
+         * @param client the updated client.
+         * @param changeMask the bit mask describing the changed properties. It can contain
+         * any of the following values: {@link Client#CHANGE_INFO},
+         * {@link Client#CHANGE_DEBUGGER_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}
+         */
+        public void clientChanged(Client client, int changeMask);
+    }
+
+    /**
+     * Initializes the <code>ddm</code> library.
+     * <p/>This must be called once <b>before</b> any call to
+     * {@link #createBridge(String, boolean)}.
+     * <p>The library can be initialized in 2 ways:
+     * <ul>
+     * <li>Mode 1: <var>clientSupport</var> == <code>true</code>.<br>The library monitors the
+     * devices and the applications running on them. It will connect to each application, as a
+     * debugger of sort, to be able to interact with them through JDWP packets.</li>
+     * <li>Mode 2: <var>clientSupport</var> == <code>false</code>.<br>The library only monitors
+     * devices. The applications are left untouched, letting other tools built on
+     * <code>ddmlib</code> to connect a debugger to them.</li>
+     * </ul>
+     * <p/><b>Only one tool can run in mode 1 at the same time.</b>
+     * <p/>Note that mode 1 does not prevent debugging of applications running on devices. Mode 1
+     * lets debuggers connect to <code>ddmlib</code> which acts as a proxy between the debuggers and
+     * the applications to debug. See {@link Client#getDebuggerListenPort()}.
+     * <p/>The preferences of <code>ddmlib</code> should also be initialized with whatever default
+     * values were changed from the default values.
+     * <p/>When the application quits, {@link #terminate()} should be called.
+     * @param clientSupport Indicates whether the library should enable the monitoring and
+     * interaction with applications running on the devices.
+     * @see AndroidDebugBridge#createBridge(String, boolean)
+     * @see DdmPreferences
+     */
+    public static void init(boolean clientSupport) {
+        sClientSupport = clientSupport;
+
+        MonitorThread monitorThread = MonitorThread.createInstance();
+        monitorThread.start();
+
+        HandleHello.register(monitorThread);
+        HandleAppName.register(monitorThread);
+        HandleTest.register(monitorThread);
+        HandleThread.register(monitorThread);
+        HandleHeap.register(monitorThread);
+        HandleWait.register(monitorThread);
+    }
+
+    /**
+     * Terminates the ddm library. This must be called upon application termination.
+     */
+    public static void terminate() {
+        // kill the monitoring services
+        if (sThis != null && sThis.mDeviceMonitor != null) {
+            sThis.mDeviceMonitor.stop();
+            sThis.mDeviceMonitor = null;
+        }
+
+        MonitorThread monitorThread = MonitorThread.getInstance();
+        if (monitorThread != null) {
+            monitorThread.quit();
+        }
+    }
+    
+    /**
+     * Returns whether the ddmlib is setup to support monitoring and interacting with
+     * {@link Client}s running on the {@link Device}s.
+     */
+    static boolean getClientSupport() {
+        return sClientSupport;
+    }
+    
+    /**
+     * Creates a {@link AndroidDebugBridge} that is not linked to any particular executable.
+     * <p/>This bridge will expect adb to be running. It will not be able to start/stop/restart
+     * adb.
+     * <p/>If a bridge has already been started, it is directly returned with no changes (similar
+     * to calling {@link #getBridge()}).
+     * @return a connected bridge.
+     */
+    public static AndroidDebugBridge createBridge() {
+        synchronized (sLock) {
+            if (sThis != null) {
+                return sThis;
+            }
+
+            try {
+                sThis = new AndroidDebugBridge();
+                sThis.start();
+            } catch (InvalidParameterException e) {
+                sThis = null;
+            }
+
+            // because the listeners could remove themselves from the list while processing
+            // their event callback, we make a copy of the list and iterate on it instead of
+            // the main list.
+            // This mostly happens when the application quits.
+            IDebugBridgeChangeListener[] listenersCopy = sBridgeListeners.toArray(
+                    new IDebugBridgeChangeListener[sBridgeListeners.size()]);
+
+            // notify the listeners of the change
+            for (IDebugBridgeChangeListener listener : listenersCopy) {
+                // we attempt to catch any exception so that a bad listener doesn't kill our
+                // thread
+                try {
+                    listener.bridgeChanged(sThis);
+                } catch (Exception e) {
+                    Log.e(DDMS, e);
+                }
+            }
+
+            return sThis;
+        }
+    }
+
+
+    /**
+     * Creates a new debug bridge from the location of the command line tool.
+     * <p/>
+     * Any existing server will be disconnected, unless the location is the same and
+     * <code>forceNewBridge</code> is set to false.
+     * @param osLocation the location of the command line tool 'adb'
+     * @param forceNewBridge force creation of a new bridge even if one with the same location
+     * already exists.
+     * @return a connected bridge.
+     */
+    public static AndroidDebugBridge createBridge(String osLocation, boolean forceNewBridge) {
+        synchronized (sLock) {
+            if (sThis != null) {
+                if (sThis.mAdbOsLocation != null && sThis.mAdbOsLocation.equals(osLocation) &&
+                        forceNewBridge == false) {
+                    return sThis;
+                } else {
+                    // stop the current server
+                    sThis.stop();
+                }
+            }
+
+            try {
+                sThis = new AndroidDebugBridge(osLocation);
+                sThis.start();
+            } catch (InvalidParameterException e) {
+                sThis = null;
+            }
+
+            // because the listeners could remove themselves from the list while processing
+            // their event callback, we make a copy of the list and iterate on it instead of
+            // the main list.
+            // This mostly happens when the application quits.
+            IDebugBridgeChangeListener[] listenersCopy = sBridgeListeners.toArray(
+                    new IDebugBridgeChangeListener[sBridgeListeners.size()]);
+
+            // notify the listeners of the change
+            for (IDebugBridgeChangeListener listener : listenersCopy) {
+                // we attempt to catch any exception so that a bad listener doesn't kill our
+                // thread
+                try {
+                    listener.bridgeChanged(sThis);
+                } catch (Exception e) {
+                    Log.e(DDMS, e);
+                }
+            }
+
+            return sThis;
+        }
+    }
+
+    /**
+     * Returns the current debug bridge. Can be <code>null</code> if none were created.
+     */
+    public static AndroidDebugBridge getBridge() {
+        return sThis;
+    }
+
+    /**
+     * Disconnects the current debug bridge, and destroy the object.
+     * <p/>
+     * A new object will have to be created with {@link #createBridge(String, boolean)}.
+     */
+    public static void disconnectBridge() {
+        synchronized (sLock) {
+            if (sThis != null) {
+                sThis.stop();
+                sThis = null;
+
+                // because the listeners could remove themselves from the list while processing
+                // their event callback, we make a copy of the list and iterate on it instead of
+                // the main list.
+                // This mostly happens when the application quits.
+                IDebugBridgeChangeListener[] listenersCopy = sBridgeListeners.toArray(
+                        new IDebugBridgeChangeListener[sBridgeListeners.size()]);
+
+                // notify the listeners.
+                for (IDebugBridgeChangeListener listener : listenersCopy) {
+                    // we attempt to catch any exception so that a bad listener doesn't kill our
+                    // thread
+                    try {
+                        listener.bridgeChanged(sThis);
+                    } catch (Exception e) {
+                        Log.e(DDMS, e);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Adds the listener to the collection of listeners who will be notified when a new
+     * {@link AndroidDebugBridge} is connected, by sending it one of the messages defined
+     * in the {@link IDebugBridgeChangeListener} interface.
+     * @param listener The listener which should be notified.
+     */
+    public static void addDebugBridgeChangeListener(IDebugBridgeChangeListener listener) {
+        synchronized (sLock) {
+            if (sBridgeListeners.contains(listener) == false) {
+                sBridgeListeners.add(listener);
+                if (sThis != null) {
+                    // we attempt to catch any exception so that a bad listener doesn't kill our
+                    // thread
+                    try {
+                        listener.bridgeChanged(sThis);
+                    } catch (Exception e) {
+                        Log.e(DDMS, e);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes the listener from the collection of listeners who will be notified when a new
+     * {@link AndroidDebugBridge} is started.
+     * @param listener The listener which should no longer be notified.
+     */
+    public static void removeDebugBridgeChangeListener(IDebugBridgeChangeListener listener) {
+        synchronized (sLock) {
+            sBridgeListeners.remove(listener);
+        }
+    }
+
+    /**
+     * Adds the listener to the collection of listeners who will be notified when a {@link Device}
+     * is connected, disconnected, or when its properties or its {@link Client} list changed,
+     * by sending it one of the messages defined in the {@link IDeviceChangeListener} interface.
+     * @param listener The listener which should be notified.
+     */
+    public static void addDeviceChangeListener(IDeviceChangeListener listener) {
+        synchronized (sLock) {
+            if (sDeviceListeners.contains(listener) == false) {
+                sDeviceListeners.add(listener);
+            }
+        }
+    }
+
+    /**
+     * Removes the listener from the collection of listeners who will be notified when a
+     * {@link Device} is connected, disconnected, or when its properties or its {@link Client}
+     * list changed.
+     * @param listener The listener which should no longer be notified.
+     */
+    public static void removeDeviceChangeListener(IDeviceChangeListener listener) {
+        synchronized (sLock) {
+            sDeviceListeners.remove(listener);
+        }
+    }
+
+    /**
+     * Adds the listener to the collection of listeners who will be notified when a {@link Client}
+     * property changed, by sending it one of the messages defined in the
+     * {@link IClientChangeListener} interface.
+     * @param listener The listener which should be notified.
+     */
+    public static void addClientChangeListener(IClientChangeListener listener) {
+        synchronized (sLock) {
+            if (sClientListeners.contains(listener) == false) {
+                sClientListeners.add(listener);
+            }
+        }
+    }
+
+    /**
+     * Removes the listener from the collection of listeners who will be notified when a
+     * {@link Client} property changed.
+     * @param listener The listener which should no longer be notified.
+     */
+    public static void removeClientChangeListener(IClientChangeListener listener) {
+        synchronized (sLock) {
+            sClientListeners.remove(listener);
+        }
+    }
+
+
+    /**
+     * Returns the devices.
+     * @see #hasInitialDeviceList()
+     */
+    public Device[] getDevices() {
+        synchronized (sLock) {
+            if (mDeviceMonitor != null) {
+                return mDeviceMonitor.getDevices();
+            }
+        }
+
+        return new Device[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
+     * built before the call to {@link #getDevices()}.
+     * <p/>The recommended way to get the list of {@link Device} objects is to create a 
+     * {@link IDeviceChangeListener} object.
+     */
+    public boolean hasInitialDeviceList() {
+        if (mDeviceMonitor != null) {
+            return mDeviceMonitor.hasInitialDeviceList();
+        }
+        
+        return false;
+    }
+
+    /**
+     * Sets the client to accept debugger connection on the custom "Selected debug port".
+     * @param selectedClient the client. Can be null.
+     */
+    public void setSelectedClient(Client selectedClient) {
+        MonitorThread monitorThread = MonitorThread.getInstance();
+        if (monitorThread != null) {
+            monitorThread.setSelectedClient(selectedClient);
+        }
+    }
+
+    /**
+     * Returns whether the {@link AndroidDebugBridge} object is still connected to the adb daemon.
+     */
+    public boolean isConnected() {
+        MonitorThread monitorThread = MonitorThread.getInstance();
+        if (mDeviceMonitor != null && monitorThread != null) {
+            return mDeviceMonitor.isMonitoring() && monitorThread.getState() != State.TERMINATED;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the number of times the {@link AndroidDebugBridge} object attempted to connect
+     * to the adb daemon.
+     */
+    public int getConnectionAttemptCount() {
+        if (mDeviceMonitor != null) {
+            return mDeviceMonitor.getConnectionAttemptCount();
+        }
+        return -1;
+    }
+
+    /**
+     * Returns the number of times the {@link AndroidDebugBridge} object attempted to restart
+     * the adb daemon.
+     */
+    public int getRestartAttemptCount() {
+        if (mDeviceMonitor != null) {
+            return mDeviceMonitor.getRestartAttemptCount();
+        }
+        return -1;
+    }
+    
+    /**
+     * Creates a new bridge.
+     * @param osLocation the location of the command line tool
+     * @throws InvalidParameterException
+     */
+    private AndroidDebugBridge(String osLocation) throws InvalidParameterException {
+        if (osLocation == null || osLocation.length() == 0) {
+            throw new InvalidParameterException();
+        }
+        mAdbOsLocation = osLocation;
+
+        checkAdbVersion();
+    }
+    
+    /**
+     * Creates a new bridge not linked to any particular adb executable.
+     */
+    private AndroidDebugBridge() {
+    }
+
+    /**
+     * Queries adb for its version number and checks it against {@link #MIN_VERSION_NUMBER} and
+     * {@link #MAX_VERSION_NUMBER}
+     */
+    private void checkAdbVersion() {
+        // default is bad check
+        mVersionCheck = false;
+
+        if (mAdbOsLocation == null) {
+            return;
+        }
+
+        try {
+            String[] command = new String[2];
+            command[0] = mAdbOsLocation;
+            command[1] = "version"; //$NON-NLS-1$
+            Log.d(DDMS, String.format("Checking '%1$s version'", mAdbOsLocation)); //$NON-NLS-1$
+            Process process = Runtime.getRuntime().exec(command);
+
+            ArrayList<String> errorOutput = new ArrayList<String>();
+            ArrayList<String> stdOutput = new ArrayList<String>();
+            int status = grabProcessOutput(process, errorOutput, stdOutput,
+                    true /* waitForReaders */);
+
+            if (status != 0) {
+                StringBuilder builder = new StringBuilder("'adb version' failed!"); //$NON-NLS-1$
+                for (String error : errorOutput) {
+                    builder.append('\n');
+                    builder.append(error);
+                }
+                Log.logAndDisplay(LogLevel.ERROR, "adb", builder.toString());
+            }
+
+            // check both stdout and stderr
+            boolean versionFound = false;
+            for (String line : stdOutput) {
+                versionFound = scanVersionLine(line);
+                if (versionFound) {
+                    break;
+                }
+            }
+            if (!versionFound) {
+                for (String line : errorOutput) {
+                    versionFound = scanVersionLine(line);
+                    if (versionFound) {
+                        break;
+                    }
+                }
+            }
+
+            if (!versionFound) {
+                // if we get here, we failed to parse the output.
+                Log.logAndDisplay(LogLevel.ERROR, ADB,
+                        "Failed to parse the output of 'adb version'"); //$NON-NLS-1$
+            }
+            
+        } catch (IOException e) {
+            Log.logAndDisplay(LogLevel.ERROR, ADB,
+                    "Failed to get the adb version: " + e.getMessage()); //$NON-NLS-1$
+        } catch (InterruptedException e) {
+        } finally {
+
+        }
+    }
+
+    /**
+     * Scans a line resulting from 'adb version' for a potential version number.
+     * <p/>
+     * If a version number is found, it checks the version number against what is expected
+     * by this version of ddms.
+     * <p/>
+     * Returns true when a version number has been found so that we can stop scanning,
+     * whether the version number is in the acceptable range or not.
+     * 
+     * @param line The line to scan.
+     * @return True if a version number was found (whether it is acceptable or not).
+     */
+    private boolean scanVersionLine(String line) {
+        if (line != null) {
+            Matcher matcher = sAdbVersion.matcher(line);
+            if (matcher.matches()) {
+                int majorVersion = Integer.parseInt(matcher.group(1));
+                int minorVersion = Integer.parseInt(matcher.group(2));
+                int microVersion = Integer.parseInt(matcher.group(3));
+
+                // check only the micro version for now.
+                if (microVersion < ADB_VERSION_MICRO_MIN) {
+                    String message = String.format(
+                            "Required minimum version of adb: %1$d.%2$d.%3$d." //$NON-NLS-1$
+                            + "Current version is %1$d.%2$d.%4$d", //$NON-NLS-1$
+                            majorVersion, minorVersion, ADB_VERSION_MICRO_MIN,
+                            microVersion);
+                    Log.logAndDisplay(LogLevel.ERROR, ADB, message);
+                } else if (ADB_VERSION_MICRO_MAX != -1 &&
+                        microVersion > ADB_VERSION_MICRO_MAX) {
+                    String message = String.format(
+                            "Required maximum version of adb: %1$d.%2$d.%3$d." //$NON-NLS-1$
+                            + "Current version is %1$d.%2$d.%4$d", //$NON-NLS-1$
+                            majorVersion, minorVersion, ADB_VERSION_MICRO_MAX,
+                            microVersion);
+                    Log.logAndDisplay(LogLevel.ERROR, ADB, message);
+                } else {
+                    mVersionCheck = true;
+                }
+
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Starts the debug bridge.
+     * @return true if success.
+     */
+    boolean start() {
+        if (mAdbOsLocation != null && (mVersionCheck == false || startAdb() == false)) {
+            return false;
+        }
+
+        mStarted = true;
+
+        // now that the bridge is connected, we start the underlying services.
+        mDeviceMonitor = new DeviceMonitor(this);
+        mDeviceMonitor.start();
+
+        return true;
+    }
+
+   /**
+     * Kills the debug bridge.
+     * @return true if success
+     */
+    boolean stop() {
+        // if we haven't started we return false;
+        if (mStarted == false) {
+            return false;
+        }
+
+        // kill the monitoring services
+        mDeviceMonitor.stop();
+        mDeviceMonitor = null;
+
+        if (stopAdb() == false) {
+            return false;
+        }
+
+        mStarted = false;
+        return true;
+    }
+
+    /**
+     * Restarts adb, but not the services around it.
+     * @return true if success.
+     */
+    public boolean restart() {
+        if (mAdbOsLocation == null) {
+            Log.e(ADB,
+                    "Cannot restart adb when AndroidDebugBridge is created without the location of adb."); //$NON-NLS-1$
+            return false;
+        }
+
+        if (mVersionCheck == false) {
+            Log.logAndDisplay(LogLevel.ERROR, ADB,
+                    "Attempting to restart adb, but version check failed!"); //$NON-NLS-1$
+            return false;
+        }
+        synchronized (this) {
+            stopAdb();
+
+            boolean restart = startAdb();
+
+            if (restart && mDeviceMonitor == null) {
+                mDeviceMonitor = new DeviceMonitor(this);
+                mDeviceMonitor.start();
+            }
+
+            return restart;
+        }
+    }
+
+    /**
+     * Notify the listener of a new {@link Device}.
+     * <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
+     * {@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
+     * the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
+     * @param device the new <code>Device</code>.
+     * @see #getLock()
+     */
+    void deviceConnected(Device device) {
+        // because the listeners could remove themselves from the list while processing
+        // their event callback, we make a copy of the list and iterate on it instead of
+        // the main list.
+        // This mostly happens when the application quits.
+        IDeviceChangeListener[] listenersCopy = null;
+        synchronized (sLock) {
+            listenersCopy = sDeviceListeners.toArray(
+                    new IDeviceChangeListener[sDeviceListeners.size()]);
+        }
+        
+        // Notify the listeners
+        for (IDeviceChangeListener listener : listenersCopy) {
+            // we attempt to catch any exception so that a bad listener doesn't kill our
+            // thread
+            try {
+                listener.deviceConnected(device);
+            } catch (Exception e) {
+                Log.e(DDMS, e);
+            }
+        }
+    }
+
+    /**
+     * Notify the listener of a disconnected {@link Device}.
+     * <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
+     * {@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
+     * the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
+     * @param device the disconnected <code>Device</code>.
+     * @see #getLock()
+     */
+    void deviceDisconnected(Device device) {
+        // because the listeners could remove themselves from the list while processing
+        // their event callback, we make a copy of the list and iterate on it instead of
+        // the main list.
+        // This mostly happens when the application quits.
+        IDeviceChangeListener[] listenersCopy = null;
+        synchronized (sLock) {
+            listenersCopy = sDeviceListeners.toArray(
+                    new IDeviceChangeListener[sDeviceListeners.size()]);
+        }
+        
+        // Notify the listeners
+        for (IDeviceChangeListener listener : listenersCopy) {
+            // we attempt to catch any exception so that a bad listener doesn't kill our
+            // thread
+            try {
+                listener.deviceDisconnected(device);
+            } catch (Exception e) {
+                Log.e(DDMS, e);
+            }
+        }
+    }
+
+    /**
+     * Notify the listener of a modified {@link Device}.
+     * <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
+     * {@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
+     * the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
+     * @param device the modified <code>Device</code>.
+     * @see #getLock()
+     */
+    void deviceChanged(Device device, int changeMask) {
+        // because the listeners could remove themselves from the list while processing
+        // their event callback, we make a copy of the list and iterate on it instead of
+        // the main list.
+        // This mostly happens when the application quits.
+        IDeviceChangeListener[] listenersCopy = null;
+        synchronized (sLock) {
+            listenersCopy = sDeviceListeners.toArray(
+                    new IDeviceChangeListener[sDeviceListeners.size()]);
+        }
+        
+        // Notify the listeners
+        for (IDeviceChangeListener listener : listenersCopy) {
+            // we attempt to catch any exception so that a bad listener doesn't kill our
+            // thread
+            try {
+                listener.deviceChanged(device, changeMask);
+            } catch (Exception e) {
+                Log.e(DDMS, e);
+            }
+        }
+    }
+
+    /**
+     * Notify the listener of a modified {@link Client}.
+     * <p/>
+     * The notification of the listeners is done in a synchronized block. It is important to
+     * expect the listeners to potentially access various methods of {@link Device} 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
+     * the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
+     * @param device the modified <code>Client</code>.
+     * @param changeMask the mask indicating what changed in the <code>Client</code>
+     * @see #getLock()
+     */
+    void clientChanged(Client client, int changeMask) {
+        // because the listeners could remove themselves from the list while processing
+        // their event callback, we make a copy of the list and iterate on it instead of
+        // the main list.
+        // This mostly happens when the application quits.
+        IClientChangeListener[] listenersCopy = null;
+        synchronized (sLock) {
+            listenersCopy = sClientListeners.toArray(
+                    new IClientChangeListener[sClientListeners.size()]);
+            
+        }
+
+        // Notify the listeners
+        for (IClientChangeListener listener : listenersCopy) {
+            // we attempt to catch any exception so that a bad listener doesn't kill our
+            // thread
+            try {
+                listener.clientChanged(client, changeMask);
+            } catch (Exception e) {
+                Log.e(DDMS, e);
+            }
+        }
+    }
+
+    /**
+     * Returns the {@link DeviceMonitor} object.
+     */
+    DeviceMonitor getDeviceMonitor() {
+        return mDeviceMonitor;
+    }
+
+    /**
+     * Starts the adb host side server.
+     * @return true if success
+     */
+    synchronized boolean startAdb() {
+        if (mAdbOsLocation == null) {
+            Log.e(ADB,
+                "Cannot start adb when AndroidDebugBridge is created without the location of adb."); //$NON-NLS-1$
+            return false;
+        }
+
+        Process proc;
+        int status = -1;
+
+        try {
+            String[] command = new String[2];
+            command[0] = mAdbOsLocation;
+            command[1] = "start-server"; //$NON-NLS-1$
+            Log.d(DDMS,
+                    String.format("Launching '%1$s %2$s' to ensure ADB is running.", //$NON-NLS-1$
+                    mAdbOsLocation, command[1]));
+            proc = Runtime.getRuntime().exec(command);
+
+            ArrayList<String> errorOutput = new ArrayList<String>();
+            ArrayList<String> stdOutput = new ArrayList<String>();
+            status = grabProcessOutput(proc, errorOutput, stdOutput,
+                    false /* waitForReaders */);
+
+        } catch (IOException ioe) {
+            Log.d(DDMS, "Unable to run 'adb': " + ioe.getMessage()); //$NON-NLS-1$
+            // we'll return false;
+        } catch (InterruptedException ie) {
+            Log.d(DDMS, "Unable to run 'adb': " + ie.getMessage()); //$NON-NLS-1$
+            // we'll return false;
+        }
+
+        if (status != 0) {
+            Log.w(DDMS,
+                    "'adb start-server' failed -- run manually if necessary"); //$NON-NLS-1$
+            return false;
+        }
+
+        Log.d(DDMS, "'adb start-server' succeeded"); //$NON-NLS-1$
+
+        return true;
+    }
+
+    /**
+     * Stops the adb host side server.
+     * @return true if success
+     */
+    private synchronized boolean stopAdb() {
+        if (mAdbOsLocation == null) {
+            Log.e(ADB,
+                "Cannot stop adb when AndroidDebugBridge is created without the location of adb."); //$NON-NLS-1$
+            return false;
+        }
+
+        Process proc;
+        int status = -1;
+
+        try {
+            String[] command = new String[2];
+            command[0] = mAdbOsLocation;
+            command[1] = "kill-server"; //$NON-NLS-1$
+            proc = Runtime.getRuntime().exec(command);
+            status = proc.waitFor();
+        }
+        catch (IOException ioe) {
+            // we'll return false;
+        }
+        catch (InterruptedException ie) {
+            // we'll return false;
+        }
+
+        if (status != 0) {
+            Log.w(DDMS,
+                    "'adb kill-server' failed -- run manually if necessary"); //$NON-NLS-1$
+            return false;
+        }
+
+        Log.d(DDMS, "'adb kill-server' succeeded"); //$NON-NLS-1$
+        return true;
+    }
+
+    /**
+     * Get the stderr/stdout outputs of a process and return when the process is done.
+     * Both <b>must</b> be read or the process will block on windows.
+     * @param process The process to get the ouput from
+     * @param errorOutput The array to store the stderr output. cannot be null.
+     * @param stdOutput The array to store the stdout output. cannot be null.
+     * @param displayStdOut If true this will display stdout as well
+     * @param waitforReaders if true, this will wait for the reader threads. 
+     * @return the process return code.
+     * @throws InterruptedException
+     */
+    private int grabProcessOutput(final Process process, final ArrayList<String> errorOutput,
+            final ArrayList<String> stdOutput, boolean waitforReaders)
+            throws InterruptedException {
+        assert errorOutput != null;
+        assert stdOutput != null;
+        // read the lines as they come. if null is returned, it's
+        // because the process finished
+        Thread t1 = new Thread("") { //$NON-NLS-1$
+            @Override
+            public void run() {
+                // create a buffer to read the stderr output
+                InputStreamReader is = new InputStreamReader(process.getErrorStream());
+                BufferedReader errReader = new BufferedReader(is);
+
+                try {
+                    while (true) {
+                        String line = errReader.readLine();
+                        if (line != null) {
+                            Log.e(ADB, line);
+                            errorOutput.add(line);
+                        } else {
+                            break;
+                        }
+                    }
+                } catch (IOException e) {
+                    // do nothing.
+                }
+            }
+        };
+
+        Thread t2 = new Thread("") { //$NON-NLS-1$
+            @Override
+            public void run() {
+                InputStreamReader is = new InputStreamReader(process.getInputStream());
+                BufferedReader outReader = new BufferedReader(is);
+
+                try {
+                    while (true) {
+                        String line = outReader.readLine();
+                        if (line != null) {
+                            Log.d(ADB, line);
+                            stdOutput.add(line);
+                        } else {
+                            break;
+                        }
+                    }
+                } catch (IOException e) {
+                    // do nothing.
+                }
+            }
+        };
+
+        t1.start();
+        t2.start();
+
+        // it looks like on windows process#waitFor() can return
+        // before the thread have filled the arrays, so we wait for both threads and the
+        // process itself.
+        if (waitforReaders) {
+            try {
+                t1.join();
+            } catch (InterruptedException e) {
+            }
+            try {
+                t2.join();
+            } catch (InterruptedException e) {
+            }
+        }
+
+        // get the return code from the process
+        return process.waitFor();
+    }
+
+    /**
+     * Returns the singleton lock used by this class to protect any access to the listener.
+     * <p/>
+     * This includes adding/removing listeners, but also notifying listeners of new bridges,
+     * devices, and clients.
+     */
+    static Object getLock() {
+        return sLock;
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/BadPacketException.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/BadPacketException.java
new file mode 100644
index 0000000..129b312
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/BadPacketException.java
@@ -0,0 +1,35 @@
+/* //device/tools/ddms/libs/ddmlib/src/com/android/ddmlib/BadPacketException.java
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.ddmlib;
+
+/**
+ * Thrown if the contents of a packet are bad.
+ */
+@SuppressWarnings("serial")
+class BadPacketException extends RuntimeException {
+    public BadPacketException()
+    {
+        super();
+    }
+
+    public BadPacketException(String msg)
+    {
+        super(msg);
+    }
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ChunkHandler.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ChunkHandler.java
new file mode 100644
index 0000000..441b024
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ChunkHandler.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Subclass this with a class that handles one or more chunk types.
+ */
+abstract class ChunkHandler {
+
+    public static final int CHUNK_HEADER_LEN = 8;   // 4-byte type, 4-byte len
+    public static final ByteOrder CHUNK_ORDER = ByteOrder.BIG_ENDIAN;
+
+    public static final int CHUNK_FAIL = type("FAIL");
+
+    ChunkHandler() {}
+
+    /**
+     * Client is ready.  The monitor thread calls this method on all
+     * handlers when the client is determined to be DDM-aware (usually
+     * after receiving a HELO response.)
+     *
+     * The handler can use this opportunity to initialize client-side
+     * activity.  Because there's a fair chance we'll want to send a
+     * message to the client, this method can throw an IOException.
+     */
+    abstract void clientReady(Client client) throws IOException;
+
+    /**
+     * Client has gone away.  Can be used to clean up any resources
+     * associated with this client connection.
+     */
+    abstract void clientDisconnected(Client client);
+
+    /**
+     * Handle an incoming chunk.  The data, of chunk type "type", begins
+     * at the start of "data" and continues to data.limit().
+     *
+     * If "isReply" is set, then "msgId" will be the ID of the request
+     * we sent to the client.  Otherwise, it's the ID generated by the
+     * client for this event.  Note that it's possible to receive chunks
+     * in reply packets for which we are not registered.
+     *
+     * The handler may not modify the contents of "data".
+     */
+    abstract void handleChunk(Client client, int type,
+        ByteBuffer data, boolean isReply, int msgId);
+
+    /**
+     * Handle chunks not recognized by handlers.  The handleChunk() method
+     * in sub-classes should call this if the chunk type isn't recognized.
+     */
+    protected void handleUnknownChunk(Client client, int type,
+        ByteBuffer data, boolean isReply, int msgId) {
+        if (type == CHUNK_FAIL) {
+            int errorCode, msgLen;
+            String msg;
+
+            errorCode = data.getInt();
+            msgLen = data.getInt();
+            msg = getString(data, msgLen);
+            Log.w("ddms", "WARNING: failure code=" + errorCode + " msg=" + msg);
+        } else {
+            Log.w("ddms", "WARNING: received unknown chunk " + name(type)
+                + ": len=" + data.limit() + ", reply=" + isReply
+                + ", msgId=0x" + Integer.toHexString(msgId));
+        }
+        Log.w("ddms", "         client " + client + ", handler " + this);
+    }
+
+
+    /**
+     * Utility function to copy a String out of a ByteBuffer.
+     *
+     * This is here because multiple chunk handlers can make use of it,
+     * and there's nowhere better to put it.
+     */
+    static String getString(ByteBuffer buf, int len) {
+        char[] data = new char[len];
+        for (int i = 0; i < len; i++)
+            data[i] = buf.getChar();
+        return new String(data);
+    }
+
+    /**
+     * Utility function to copy a String into a ByteBuffer.
+     */
+    static void putString(ByteBuffer buf, String str) {
+        int len = str.length();
+        for (int i = 0; i < len; i++)
+            buf.putChar(str.charAt(i));
+    }
+
+    /**
+     * Convert a 4-character string to a 32-bit type.
+     */
+    static int type(String typeName) {
+        int val = 0;
+
+        if (typeName.length() != 4) {
+            Log.e("ddms", "Type name must be 4 letter long");
+            throw new RuntimeException("Type name must be 4 letter long");
+        }
+
+        for (int i = 0; i < 4; i++) {
+            val <<= 8;
+            val |= (byte) typeName.charAt(i);
+        }
+
+        return val;
+    }
+
+    /**
+     * Convert an integer type to a 4-character string.
+     */
+    static String name(int type) {
+        char[] ascii = new char[4];
+
+        ascii[0] = (char) ((type >> 24) & 0xff);
+        ascii[1] = (char) ((type >> 16) & 0xff);
+        ascii[2] = (char) ((type >> 8) & 0xff);
+        ascii[3] = (char) (type & 0xff);
+
+        return new String(ascii);
+    }
+
+    /**
+     * Allocate a ByteBuffer with enough space to hold the JDWP packet
+     * header and one chunk header in addition to the demands of the
+     * chunk being created.
+     *
+     * "maxChunkLen" indicates the size of the chunk contents only.
+     */
+    static ByteBuffer allocBuffer(int maxChunkLen) {
+        ByteBuffer buf =
+            ByteBuffer.allocate(JdwpPacket.JDWP_HEADER_LEN + 8 +maxChunkLen);
+        buf.order(CHUNK_ORDER);
+        return buf;
+    }
+
+    /**
+     * Return the slice of the JDWP packet buffer that holds just the
+     * chunk data.
+     */
+    static ByteBuffer getChunkDataBuf(ByteBuffer jdwpBuf) {
+        ByteBuffer slice;
+
+        assert jdwpBuf.position() == 0;
+
+        jdwpBuf.position(JdwpPacket.JDWP_HEADER_LEN + CHUNK_HEADER_LEN);
+        slice = jdwpBuf.slice();
+        slice.order(CHUNK_ORDER);
+        jdwpBuf.position(0);
+
+        return slice;
+    }
+
+    /**
+     * Write the chunk header at the start of the chunk.
+     *
+     * Pass in the byte buffer returned by JdwpPacket.getPayload().
+     */
+    static void finishChunkPacket(JdwpPacket packet, int type, int chunkLen) {
+        ByteBuffer buf = packet.getPayload();
+
+        buf.putInt(0x00, type);
+        buf.putInt(0x04, chunkLen);
+
+        packet.finishPacket(CHUNK_HEADER_LEN + chunkLen);
+    }
+
+    /**
+     * Check that the client is opened with the proper debugger port for the
+     * specified application name, and if not, reopen it.
+     * @param client
+     * @param uiThread
+     * @param appName
+     * @return
+     */
+    protected static Client checkDebuggerPortForAppName(Client client, String appName) {
+        IDebugPortProvider provider = DebugPortManager.getProvider();
+        if (provider != null) {
+            Device device = client.getDevice();
+            int newPort = provider.getPort(device, appName);
+
+            if (newPort != IDebugPortProvider.NO_STATIC_PORT &&
+                    newPort != client.getDebuggerListenPort()) {
+
+                AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
+                if (bridge != null) {
+                    DeviceMonitor deviceMonitor = bridge.getDeviceMonitor();
+                    if (deviceMonitor != null) {
+                        deviceMonitor.addClientToDropAndReopen(client, newPort);
+                        client = null;
+                    }
+                }
+            }
+        }
+
+        return client;
+    }
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java
new file mode 100644
index 0000000..866d578
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java
@@ -0,0 +1,768 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
+import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
+
+import java.io.IOException;
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.util.HashMap;
+
+/**
+ * This represents a single client, usually a DAlvik VM process.
+ * <p/>This class gives access to basic client information, as well as methods to perform actions
+ * on the client.
+ * <p/>More detailed information, usually updated in real time, can be access through the
+ * {@link ClientData} class. Each <code>Client</code> object has its own <code>ClientData</code>
+ * accessed through {@link #getClientData()}.
+ */
+public class Client {
+
+    private static final int SERVER_PROTOCOL_VERSION = 1;
+
+    /** Client change bit mask: application name change */
+    public static final int CHANGE_NAME = 0x0001;
+    /** Client change bit mask: debugger interest change */
+    public static final int CHANGE_DEBUGGER_INTEREST = 0x0002;
+    /** Client change bit mask: debugger port change */
+    public static final int CHANGE_PORT = 0x0004;
+    /** Client change bit mask: thread update flag change */
+    public static final int CHANGE_THREAD_MODE = 0x0008;
+    /** Client change bit mask: thread data updated */
+    public static final int CHANGE_THREAD_DATA = 0x0010;
+    /** Client change bit mask: heap update flag change */
+    public static final int CHANGE_HEAP_MODE = 0x0020;
+    /** Client change bit mask: head data updated */
+    public static final int CHANGE_HEAP_DATA = 0x0040;
+    /** Client change bit mask: native heap data updated */
+    public static final int CHANGE_NATIVE_HEAP_DATA = 0x0080;
+    /** Client change bit mask: thread stack trace updated */
+    public static final int CHANGE_THREAD_STACKTRACE = 0x0100;
+    /** Client change bit mask: allocation information updated */
+    public static final int CHANGE_HEAP_ALLOCATIONS = 0x0200;
+    /** Client change bit mask: allocation information updated */
+    public static final int CHANGE_HEAP_ALLOCATION_STATUS = 0x0400;
+
+    /** Client change bit mask: combination of {@link Client#CHANGE_NAME},
+     * {@link Client#CHANGE_DEBUGGER_INTEREST}, and {@link Client#CHANGE_PORT}.
+     */
+    public static final int CHANGE_INFO = CHANGE_NAME | CHANGE_DEBUGGER_INTEREST | CHANGE_PORT;
+
+    private SocketChannel mChan;
+
+    // debugger we're associated with, if any
+    private Debugger mDebugger;
+    private int mDebuggerListenPort;
+
+    // list of IDs for requests we have sent to the client
+    private HashMap<Integer,ChunkHandler> mOutstandingReqs;
+
+    // chunk handlers stash state data in here
+    private ClientData mClientData;
+
+    // User interface state.  Changing the value causes a message to be
+    // sent to the client.
+    private boolean mThreadUpdateEnabled;
+    private boolean mHeapUpdateEnabled;
+
+    /*
+     * Read/write buffers.  We can get large quantities of data from the
+     * client, e.g. the response to a "give me the list of all known classes"
+     * request from the debugger.  Requests from the debugger, and from us,
+     * are much smaller.
+     *
+     * Pass-through debugger traffic is sent without copying.  "mWriteBuffer"
+     * is only used for data generated within Client.
+     */
+    private static final int INITIAL_BUF_SIZE = 2*1024;
+    private static final int MAX_BUF_SIZE = 200*1024*1024;
+    private ByteBuffer mReadBuffer;
+
+    private static final int WRITE_BUF_SIZE = 256;
+    private ByteBuffer mWriteBuffer;
+
+    private Device mDevice;
+
+    private int mConnState;
+
+    private static final int ST_INIT         = 1;
+    private static final int ST_NOT_JDWP     = 2;
+    private static final int ST_AWAIT_SHAKE  = 10;
+    private static final int ST_NEED_DDM_PKT = 11;
+    private static final int ST_NOT_DDM      = 12;
+    private static final int ST_READY        = 13;
+    private static final int ST_ERROR        = 20;
+    private static final int ST_DISCONNECTED = 21;
+
+
+    /**
+     * Create an object for a new client connection.
+     *
+     * @param device the device this client belongs to
+     * @param chan the connected {@link SocketChannel}.
+     * @param pid the client pid.
+     */
+    Client(Device device, SocketChannel chan, int pid) {
+        mDevice = device;
+        mChan = chan;
+
+        mReadBuffer = ByteBuffer.allocate(INITIAL_BUF_SIZE);
+        mWriteBuffer = ByteBuffer.allocate(WRITE_BUF_SIZE);
+
+        mOutstandingReqs = new HashMap<Integer,ChunkHandler>();
+
+        mConnState = ST_INIT;
+
+        mClientData = new ClientData(pid);
+        
+        mThreadUpdateEnabled = DdmPreferences.getInitialThreadUpdate();
+        mHeapUpdateEnabled = DdmPreferences.getInitialHeapUpdate();
+    }
+
+    /**
+     * Returns a string representation of the {@link Client} object.
+     */
+    @Override
+    public String toString() {
+        return "[Client pid: " + mClientData.getPid() + "]";
+    }
+
+    /**
+     * Returns the {@link Device} on which this Client is running.
+     */
+    public Device getDevice() {
+        return mDevice;
+    }
+
+    /**
+     * Returns the debugger port for this client.
+     */
+    public int getDebuggerListenPort() {
+        return mDebuggerListenPort;
+    }
+
+    /**
+     * Returns <code>true</code> if the client VM is DDM-aware.
+     *
+     * Calling here is only allowed after the connection has been
+     * established.
+     */
+    public boolean isDdmAware() {
+        switch (mConnState) {
+            case ST_INIT:
+            case ST_NOT_JDWP:
+            case ST_AWAIT_SHAKE:
+            case ST_NEED_DDM_PKT:
+            case ST_NOT_DDM:
+            case ST_ERROR:
+            case ST_DISCONNECTED:
+                return false;
+            case ST_READY:
+                return true;
+            default:
+                assert false;
+                return false;
+        }
+    }
+
+    /**
+     * Returns <code>true</code> if a debugger is currently attached to the client.
+     */
+    public boolean isDebuggerAttached() {
+        return mDebugger.isDebuggerAttached();
+    }
+
+    /**
+     * Return the Debugger object associated with this client.
+     */
+    Debugger getDebugger() {
+        return mDebugger;
+    }
+
+    /**
+     * Returns the {@link ClientData} object containing this client information.
+     */
+    public ClientData getClientData() {
+        return mClientData;
+    }
+
+    /**
+     * Forces the client to execute its garbage collector.
+     */
+    public void executeGarbageCollector() {
+        try {
+            HandleHeap.sendHPGC(this);
+        } catch (IOException ioe) {
+            Log.w("ddms", "Send of HPGC message failed");
+            // ignore
+        }
+    }
+
+    /**
+     * Enables or disables the thread update.
+     * <p/>If <code>true</code> the VM will be able to send thread information. Thread information
+     * must be requested with {@link #requestThreadUpdate()}.
+     * @param enabled the enable flag.
+     */
+    public void setThreadUpdateEnabled(boolean enabled) {
+        mThreadUpdateEnabled = enabled;
+        if (enabled == false) {
+            mClientData.clearThreads();
+        }
+
+        try {
+            HandleThread.sendTHEN(this, enabled);
+        } catch (IOException ioe) {
+            // ignore it here; client will clean up shortly
+            ioe.printStackTrace();
+        }
+
+        update(CHANGE_THREAD_MODE);
+    }
+    
+    /**
+     * Returns whether the thread update is enabled.
+     */
+    public boolean isThreadUpdateEnabled() {
+        return mThreadUpdateEnabled;
+    }
+
+    /**
+     * Sends a thread update request. This is asynchronous.
+     * <p/>The thread info can be accessed by {@link ClientData#getThreads()}. The notification
+     * that the new data is available will be received through
+     * {@link IClientChangeListener#clientChanged(Client, int)} with a <code>changeMask</code>
+     * containing the mask {@link #CHANGE_THREAD_DATA}.
+     */
+    public void requestThreadUpdate() {
+        HandleThread.requestThreadUpdate(this);
+    }
+
+    /**
+     * Sends a thread stack trace update request. This is asynchronous.
+     * <p/>The thread info can be accessed by {@link ClientData#getThreads()} and
+     * {@link ThreadInfo#getStackTrace()}.
+     * <p/>The notification that the new data is available
+     * will be received through {@link IClientChangeListener#clientChanged(Client, int)}
+     * with a <code>changeMask</code> containing the mask {@link #CHANGE_THREAD_STACKTRACE}.
+     */
+    public void requestThreadStackTrace(int threadId) {
+        HandleThread.requestThreadStackCallRefresh(this, threadId);
+    }
+    
+    /**
+     * Enables or disables the heap update.
+     * <p/>If <code>true</code>, any GC will cause the client to send its heap information.
+     * <p/>The heap information can be accessed by {@link ClientData#getVmHeapData()}.
+     * <p/>The notification that the new data is available
+     * will be received through {@link IClientChangeListener#clientChanged(Client, int)}
+     * with a <code>changeMask</code> containing the value {@link #CHANGE_HEAP_DATA}.
+     * @param enabled the enable flag
+     */
+    public void setHeapUpdateEnabled(boolean enabled) {
+        mHeapUpdateEnabled = enabled;
+
+        try {
+            HandleHeap.sendHPIF(this,
+                    enabled ? HandleHeap.HPIF_WHEN_EVERY_GC : HandleHeap.HPIF_WHEN_NEVER);
+
+            HandleHeap.sendHPSG(this,
+                    enabled ? HandleHeap.WHEN_GC : HandleHeap.WHEN_DISABLE,
+                    HandleHeap.WHAT_MERGE);
+        } catch (IOException ioe) {
+            // ignore it here; client will clean up shortly
+        }
+
+        update(CHANGE_HEAP_MODE);
+    }
+
+    /**
+     * Returns whether the heap update is enabled.
+     * @see #setHeapUpdateEnabled(boolean)
+     */
+    public boolean isHeapUpdateEnabled() {
+        return mHeapUpdateEnabled;
+    }
+
+    /**
+     * Sends a native heap update request. this is asynchronous.
+     * <p/>The native heap info can be accessed by {@link ClientData#getNativeAllocationList()}.
+     * The notification that the new data is available will be received through
+     * {@link IClientChangeListener#clientChanged(Client, int)} with a <code>changeMask</code>
+     * containing the mask {@link #CHANGE_NATIVE_HEAP_DATA}.
+     */
+    public boolean requestNativeHeapInformation() {
+        try {
+            HandleNativeHeap.sendNHGT(this);
+            return true;
+        } catch (IOException e) {
+            Log.e("ddmlib", e);
+        }
+
+        return false;
+    }
+    
+    /**
+     * Enables or disables the Allocation tracker for this client.
+     * <p/>If enabled, the VM will start tracking allocation informations. A call to
+     * {@link #requestAllocationDetails()} will make the VM sends the information about all the
+     * allocations that happened between the enabling and the request.
+     * @param enable
+     * @see #requestAllocationDetails()
+     */
+    public void enableAllocationTracker(boolean enable) {
+        try {
+            HandleHeap.sendREAE(this, enable);
+        } catch (IOException e) {
+            Log.e("ddmlib", e);
+        }
+    }
+    
+    /**
+     * Sends a request to the VM to send the enable status of the allocation tracking.
+     * This is asynchronous.
+     * <p/>The allocation status can be accessed by {@link ClientData#getAllocationStatus()}.
+     * The notification that the new status is available will be received through
+     * {@link IClientChangeListener#clientChanged(Client, int)} with a <code>changeMask</code>
+     * containing the mask {@link #CHANGE_HEAP_ALLOCATION_STATUS}.
+     */
+    public void requestAllocationStatus() {
+        try {
+            HandleHeap.sendREAQ(this);
+        } catch (IOException e) {
+            Log.e("ddmlib", e);
+        }   
+    }
+    
+    /**
+     * Sends a request to the VM to send the information about all the allocations that have
+     * happened since the call to {@link #enableAllocationTracker(boolean)} with <var>enable</var>
+     * set to <code>null</code>. This is asynchronous.
+     * <p/>The allocation information can be accessed by {@link ClientData#getAllocations()}.
+     * The notification that the new data is available will be received through
+     * {@link IClientChangeListener#clientChanged(Client, int)} with a <code>changeMask</code>
+     * containing the mask {@link #CHANGE_HEAP_ALLOCATIONS}.
+     */
+    public void requestAllocationDetails() {
+        try {
+            HandleHeap.sendREAL(this);
+        } catch (IOException e) {
+            Log.e("ddmlib", e);
+        }
+    }
+
+    /**
+     * Sends a kill message to the VM.
+     */
+    public void kill() {
+        try {
+            HandleExit.sendEXIT(this, 1);
+        } catch (IOException ioe) {
+            Log.w("ddms", "Send of EXIT message failed");
+            // ignore
+        }
+    }
+
+    /**
+     * Registers the client with a Selector.
+     */
+    void register(Selector sel) throws IOException {
+        if (mChan != null) {
+            mChan.register(sel, SelectionKey.OP_READ, this);
+        }
+    }
+
+    /**
+     * Sets the client to accept debugger connection on the "selected debugger port".
+     *
+     * @see AndroidDebugBridge#setSelectedClient(Client)
+     * @see DdmPreferences#setSelectedDebugPort(int)
+     */
+    public void setAsSelectedClient() {
+        MonitorThread monitorThread = MonitorThread.getInstance();
+        if (monitorThread != null) {
+            monitorThread.setSelectedClient(this);
+        }
+    }
+
+    /**
+     * Returns whether this client is the current selected client, accepting debugger connection
+     * on the "selected debugger port".
+     *
+     * @see #setAsSelectedClient()
+     * @see AndroidDebugBridge#setSelectedClient(Client)
+     * @see DdmPreferences#setSelectedDebugPort(int)
+     */
+    public boolean isSelectedClient() {
+        MonitorThread monitorThread = MonitorThread.getInstance();
+        if (monitorThread != null) {
+            return monitorThread.getSelectedClient() == this;
+        }
+
+        return false;
+    }
+
+    /**
+     * Tell the client to open a server socket channel and listen for
+     * connections on the specified port.
+     */
+    void listenForDebugger(int listenPort) throws IOException {
+        mDebuggerListenPort = listenPort;
+        mDebugger = new Debugger(this, listenPort);
+    }
+
+    /**
+     * Initiate the JDWP handshake.
+     *
+     * On failure, closes the socket and returns false.
+     */
+    boolean sendHandshake() {
+        assert mWriteBuffer.position() == 0;
+
+        try {
+            // assume write buffer can hold 14 bytes
+            JdwpPacket.putHandshake(mWriteBuffer);
+            int expectedLen = mWriteBuffer.position();
+            mWriteBuffer.flip();
+            if (mChan.write(mWriteBuffer) != expectedLen)
+                throw new IOException("partial handshake write");
+        }
+        catch (IOException ioe) {
+            Log.e("ddms-client", "IO error during handshake: " + ioe.getMessage());
+            mConnState = ST_ERROR;
+            close(true /* notify */);
+            return false;
+        }
+        finally {
+            mWriteBuffer.clear();
+        }
+
+        mConnState = ST_AWAIT_SHAKE;
+        
+        return true;
+    }
+
+
+    /**
+     * Send a non-DDM packet to the client.
+     *
+     * Equivalent to sendAndConsume(packet, null).
+     */
+    void sendAndConsume(JdwpPacket packet) throws IOException {
+        sendAndConsume(packet, null);
+    }
+
+    /**
+     * Send a DDM packet to the client.
+     *
+     * Ideally, we can do this with a single channel write.  If that doesn't
+     * happen, we have to prevent anybody else from writing to the channel
+     * until this packet completes, so we synchronize on the channel.
+     *
+     * Another goal is to avoid unnecessary buffer copies, so we write
+     * directly out of the JdwpPacket's ByteBuffer.
+     */
+    void sendAndConsume(JdwpPacket packet, ChunkHandler replyHandler)
+        throws IOException {
+
+        if (mChan == null) {
+            // can happen for e.g. THST packets
+            Log.v("ddms", "Not sending packet -- client is closed");
+            return;
+        }
+
+        if (replyHandler != null) {
+            /*
+             * Add the ID to the list of outstanding requests.  We have to do
+             * this before sending the packet, in case the response comes back
+             * before our thread returns from the packet-send function.
+             */
+            addRequestId(packet.getId(), replyHandler);
+        }
+
+        synchronized (mChan) {
+            try {
+                packet.writeAndConsume(mChan);
+            }
+            catch (IOException ioe) {
+                removeRequestId(packet.getId());
+                throw ioe;
+            }
+        }
+    }
+
+    /**
+     * Forward the packet to the debugger (if still connected to one).
+     *
+     * Consumes the packet.
+     */
+    void forwardPacketToDebugger(JdwpPacket packet)
+        throws IOException {
+
+        Debugger dbg = mDebugger;
+
+        if (dbg == null) {
+            Log.i("ddms", "Discarding packet");
+            packet.consume();
+        } else {
+            dbg.sendAndConsume(packet);
+        }
+    }
+
+    /**
+     * Read data from our channel.
+     *
+     * This is called when data is known to be available, and we don't yet
+     * have a full packet in the buffer.  If the buffer is at capacity,
+     * expand it.
+     */
+    void read()
+        throws IOException, BufferOverflowException {
+
+        int count;
+
+        if (mReadBuffer.position() == mReadBuffer.capacity()) {
+            if (mReadBuffer.capacity() * 2 > MAX_BUF_SIZE) {
+                Log.e("ddms", "Exceeded MAX_BUF_SIZE!");
+                throw new BufferOverflowException();
+            }
+            Log.d("ddms", "Expanding read buffer to "
+                + mReadBuffer.capacity() * 2);
+
+            ByteBuffer newBuffer = ByteBuffer.allocate(mReadBuffer.capacity() * 2);
+
+            // copy entire buffer to new buffer
+            mReadBuffer.position(0);
+            newBuffer.put(mReadBuffer);  // leaves "position" at end of copied
+
+            mReadBuffer = newBuffer;
+        }
+
+        count = mChan.read(mReadBuffer);
+        if (count < 0)
+            throw new IOException("read failed");
+
+        if (Log.Config.LOGV) Log.v("ddms", "Read " + count + " bytes from " + this);
+        //Log.hexDump("ddms", Log.DEBUG, mReadBuffer.array(),
+        //    mReadBuffer.arrayOffset(), mReadBuffer.position());
+    }
+
+    /**
+     * Return information for the first full JDWP packet in the buffer.
+     *
+     * If we don't yet have a full packet, return null.
+     *
+     * If we haven't yet received the JDWP handshake, we watch for it here
+     * and consume it without admitting to have done so.  Upon receipt
+     * we send out the "HELO" message, which is why this can throw an
+     * IOException.
+     */
+    JdwpPacket getJdwpPacket() throws IOException {
+
+        /*
+         * On entry, the data starts at offset 0 and ends at "position".
+         * "limit" is set to the buffer capacity.
+         */
+        if (mConnState == ST_AWAIT_SHAKE) {
+            /*
+             * The first thing we get from the client is a response to our
+             * handshake.  It doesn't look like a packet, so we have to
+             * handle it specially.
+             */
+            int result;
+
+            result = JdwpPacket.findHandshake(mReadBuffer);
+            //Log.v("ddms", "findHand: " + result);
+            switch (result) {
+                case JdwpPacket.HANDSHAKE_GOOD:
+                    Log.i("ddms",
+                        "Good handshake from client, sending HELO to " + mClientData.getPid());
+                    JdwpPacket.consumeHandshake(mReadBuffer);
+                    mConnState = ST_NEED_DDM_PKT;
+                    HandleHello.sendHELO(this, SERVER_PROTOCOL_VERSION);
+                    // see if we have another packet in the buffer
+                    return getJdwpPacket();
+                case JdwpPacket.HANDSHAKE_BAD:
+                    Log.i("ddms", "Bad handshake from client");
+                    if (MonitorThread.getInstance().getRetryOnBadHandshake()) {
+                        // we should drop the client, but also attempt to reopen it.
+                        // This is done by the DeviceMonitor.
+                        mDevice.getMonitor().addClientToDropAndReopen(this,
+                                IDebugPortProvider.NO_STATIC_PORT);
+                    } else {
+                        // mark it as bad, close the socket, and don't retry
+                        mConnState = ST_NOT_JDWP;
+                        close(true /* notify */);
+                    }
+                    break;
+                case JdwpPacket.HANDSHAKE_NOTYET:
+                    Log.i("ddms", "No handshake from client yet.");
+                    break;
+                default:
+                    Log.e("ddms", "Unknown packet while waiting for client handshake");
+            }
+            return null;
+        } else if (mConnState == ST_NEED_DDM_PKT ||
+            mConnState == ST_NOT_DDM ||
+            mConnState == ST_READY) {
+            /*
+             * Normal packet traffic.
+             */
+            if (mReadBuffer.position() != 0) {
+                if (Log.Config.LOGV) Log.v("ddms",
+                    "Checking " + mReadBuffer.position() + " bytes");
+            }
+            return JdwpPacket.findPacket(mReadBuffer);
+        } else {
+            /*
+             * Not expecting data when in this state.
+             */
+            Log.e("ddms", "Receiving data in state = " + mConnState);
+        }
+        
+        return null;
+    }
+
+    /*
+     * Add the specified ID to the list of request IDs for which we await
+     * a response.
+     */
+    private void addRequestId(int id, ChunkHandler handler) {
+        synchronized (mOutstandingReqs) {
+            if (Log.Config.LOGV) Log.v("ddms",
+                "Adding req 0x" + Integer.toHexString(id) +" to set");
+            mOutstandingReqs.put(id, handler);
+        }
+    }
+
+    /*
+     * Remove the specified ID from the list, if present.
+     */
+    void removeRequestId(int id) {
+        synchronized (mOutstandingReqs) {
+            if (Log.Config.LOGV) Log.v("ddms",
+                "Removing req 0x" + Integer.toHexString(id) + " from set");
+            mOutstandingReqs.remove(id);
+        }
+
+        //Log.w("ddms", "Request " + Integer.toHexString(id)
+        //    + " could not be removed from " + this);
+    }
+
+    /**
+     * Determine whether this is a response to a request we sent earlier.
+     * If so, return the ChunkHandler responsible.
+     */
+    ChunkHandler isResponseToUs(int id) {
+
+        synchronized (mOutstandingReqs) {
+            ChunkHandler handler = mOutstandingReqs.get(id);
+            if (handler != null) {
+                if (Log.Config.LOGV) Log.v("ddms",
+                    "Found 0x" + Integer.toHexString(id)
+                    + " in request set - " + handler);
+                return handler;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * An earlier request resulted in a failure.  This is the expected
+     * response to a HELO message when talking to a non-DDM client.
+     */
+    void packetFailed(JdwpPacket reply) {
+        if (mConnState == ST_NEED_DDM_PKT) {
+            Log.i("ddms", "Marking " + this + " as non-DDM client");
+            mConnState = ST_NOT_DDM;
+        } else if (mConnState != ST_NOT_DDM) {
+            Log.w("ddms", "WEIRD: got JDWP failure packet on DDM req");
+        }
+    }
+
+    /**
+     * The MonitorThread calls this when it sees a DDM request or reply.
+     * If we haven't seen a DDM packet before, we advance the state to
+     * ST_READY and return "false".  Otherwise, just return true.
+     *
+     * The idea is to let the MonitorThread know when we first see a DDM
+     * packet, so we can send a broadcast to the handlers when a client
+     * connection is made.  This method is synchronized so that we only
+     * send the broadcast once.
+     */
+    synchronized boolean ddmSeen() {
+        if (mConnState == ST_NEED_DDM_PKT) {
+            mConnState = ST_READY;
+            return false;
+        } else if (mConnState != ST_READY) {
+            Log.w("ddms", "WEIRD: in ddmSeen with state=" + mConnState);
+        }
+        return true;
+    }
+
+    /**
+     * Close the client socket channel.  If there is a debugger associated
+     * with us, close that too.
+     *
+     * Closing a channel automatically unregisters it from the selector.
+     * However, we have to iterate through the selector loop before it
+     * actually lets them go and allows the file descriptors to close.
+     * The caller is expected to manage that.
+     * @param notify Whether or not to notify the listeners of a change.
+     */
+    void close(boolean notify) {
+        Log.i("ddms", "Closing " + this.toString());
+
+        mOutstandingReqs.clear();
+
+        try {
+            if (mChan != null) {
+                mChan.close();
+                mChan = null;
+            }
+
+            if (mDebugger != null) {
+                mDebugger.close();
+                mDebugger = null;
+            }
+        }
+        catch (IOException ioe) {
+            Log.w("ddms", "failed to close " + this);
+            // swallow it -- not much else to do
+        }
+
+        mDevice.removeClient(this, notify);
+    }
+    
+    /**
+     * Returns whether this {@link Client} has a valid connection to the application VM.
+     */
+    public boolean isValid() {
+        return mChan != null;
+    }
+
+    void update(int changeMask) {
+        mDevice.update(this, changeMask);
+    }
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java
new file mode 100644
index 0000000..2b46b6f
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java
@@ -0,0 +1,502 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import com.android.ddmlib.HeapSegment.HeapSegmentElement;
+
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+
+/**
+ * Contains the data of a {@link Client}.
+ */
+public class ClientData {
+    /* This is a place to stash data associated with a Client, such as thread
+    * states or heap data.  ClientData maps 1:1 to Client, but it's a little
+    * cleaner if we separate the data out.
+    *
+    * Message handlers are welcome to stash arbitrary data here.
+    *
+    * IMPORTANT: The data here is written by HandleFoo methods and read by
+    * FooPanel methods, which run in different threads.  All non-trivial
+    * access should be synchronized against the ClientData object.
+    */
+
+    
+    /** Temporary name of VM to be ignored. */
+    private final static String PRE_INITIALIZED = "<pre-initialized>"; //$NON-NLS-1$
+
+    /** Debugger connection status: not waiting on one, not connected to one, but accepting
+     * new connections. This is the default value. */
+    public static final int DEBUGGER_DEFAULT = 1;
+    /**
+     * Debugger connection status: the application's VM is paused, waiting for a debugger to
+     * connect to it before resuming. */
+    public static final int DEBUGGER_WAITING = 2;
+    /** Debugger connection status : Debugger is connected */
+    public static final int DEBUGGER_ATTACHED = 3;
+    /** Debugger connection status: The listening port for debugger connection failed to listen.
+     * No debugger will be able to connect. */
+    public static final int DEBUGGER_ERROR = 4;
+    
+    /**
+     * Allocation tracking status: unknown.
+     * <p/>This happens right after a {@link Client} is discovered
+     * by the {@link AndroidDebugBridge}, and before the {@link Client} answered the query regarding
+     * its allocation tracking status.
+     * @see Client#requestAllocationStatus()
+     */
+    public static final int ALLOCATION_TRACKING_UNKNOWN = -1;
+    /**
+     * Allocation tracking status: the {@link Client} is not tracking allocations. */
+    public static final int ALLOCATION_TRACKING_OFF = 0;
+    /**
+     * Allocation tracking status: the {@link Client} is tracking allocations. */
+    public static final int ALLOCATION_TRACKING_ON = 1;
+
+    /**
+     * Name of the value representing the max size of the heap, in the {@link Map} returned by
+     * {@link #getVmHeapInfo(int)}
+     */
+    public final static String HEAP_MAX_SIZE_BYTES = "maxSizeInBytes"; // $NON-NLS-1$
+    /**
+     * Name of the value representing the size of the heap, in the {@link Map} returned by
+     * {@link #getVmHeapInfo(int)}
+     */
+    public final static String HEAP_SIZE_BYTES = "sizeInBytes"; // $NON-NLS-1$
+    /**
+     * Name of the value representing the number of allocated bytes of the heap, in the
+     * {@link Map} returned by {@link #getVmHeapInfo(int)}
+     */
+    public final static String HEAP_BYTES_ALLOCATED = "bytesAllocated"; // $NON-NLS-1$
+    /**
+     * Name of the value representing the number of objects in the heap, in the {@link Map}
+     * returned by {@link #getVmHeapInfo(int)}
+     */
+    public final static String HEAP_OBJECTS_ALLOCATED = "objectsAllocated"; // $NON-NLS-1$
+
+    // is this a DDM-aware client?
+    private boolean mIsDdmAware;
+
+    // the client's process ID
+    private final int mPid;
+
+    // Java VM identification string
+    private String mVmIdentifier;
+
+    // client's self-description
+    private String mClientDescription;
+
+    // how interested are we in a debugger?
+    private int mDebuggerInterest;
+
+    // Thread tracking (THCR, THDE).
+    private TreeMap<Integer,ThreadInfo> mThreadMap;
+
+    /** VM Heap data */
+    private final HeapData mHeapData = new HeapData();
+    /** Native Heap data */
+    private final HeapData mNativeHeapData = new HeapData();
+
+    private HashMap<Integer, HashMap<String, Long>> mHeapInfoMap =
+            new HashMap<Integer, HashMap<String, Long>>();
+
+
+    /** library map info. Stored here since the backtrace data
+     * is computed on a need to display basis.
+     */
+    private ArrayList<NativeLibraryMapInfo> mNativeLibMapInfo =
+        new ArrayList<NativeLibraryMapInfo>();
+
+    /** Native Alloc info list */
+    private ArrayList<NativeAllocationInfo> mNativeAllocationList =
+        new ArrayList<NativeAllocationInfo>();
+    private int mNativeTotalMemory;
+
+    private AllocationInfo[] mAllocations;
+    private int mAllocationStatus = ALLOCATION_TRACKING_UNKNOWN;
+
+    /**
+     * Heap Information.
+     * <p/>The heap is composed of several {@link HeapSegment} objects.
+     * <p/>A call to {@link #isHeapDataComplete()} will indicate if the segments (available through
+     * {@link #getHeapSegments()}) represent the full heap.
+     */
+    public static class HeapData {
+        private TreeSet<HeapSegment> mHeapSegments = new TreeSet<HeapSegment>();
+        private boolean mHeapDataComplete = false;
+        private byte[] mProcessedHeapData;
+        private Map<Integer, ArrayList<HeapSegmentElement>> mProcessedHeapMap;
+
+        /**
+         * Abandon the current list of heap segments.
+         */
+        public synchronized void clearHeapData() {
+            /* Abandon the old segments instead of just calling .clear().
+             * This lets the user hold onto the old set if it wants to.
+             */
+            mHeapSegments = new TreeSet<HeapSegment>();
+            mHeapDataComplete = false;
+        }
+
+        /**
+         * Add raw HPSG chunk data to the list of heap segments.
+         *
+         * @param data The raw data from an HPSG chunk.
+         */
+        synchronized void addHeapData(ByteBuffer data) {
+            HeapSegment hs;
+
+            if (mHeapDataComplete) {
+                clearHeapData();
+            }
+
+            try {
+                hs = new HeapSegment(data);
+            } catch (BufferUnderflowException e) {
+                System.err.println("Discarding short HPSG data (length " + data.limit() + ")");
+                return;
+            }
+
+            mHeapSegments.add(hs);
+        }
+
+        /**
+         * Called when all heap data has arrived.
+         */
+        synchronized void sealHeapData() {
+            mHeapDataComplete = true;
+        }
+
+        /**
+         * Returns whether the heap data has been sealed.
+         */
+        public boolean isHeapDataComplete() {
+            return mHeapDataComplete;
+        }
+
+        /**
+         * Get the collected heap data, if sealed.
+         *
+         * @return The list of heap segments if the heap data has been sealed, or null if it hasn't.
+         */
+        public Collection<HeapSegment> getHeapSegments() {
+            if (isHeapDataComplete()) {
+                return mHeapSegments;
+            }
+            return null;
+        }
+
+        /**
+         * Sets the processed heap data.
+         *
+         * @param heapData The new heap data (can be null)
+         */
+        public void setProcessedHeapData(byte[] heapData) {
+            mProcessedHeapData = heapData;
+        }
+
+        /**
+         * Get the processed heap data, if present.
+         *
+         * @return the processed heap data, or null.
+         */
+        public byte[] getProcessedHeapData() {
+            return mProcessedHeapData;
+        }
+
+        public void setProcessedHeapMap(Map<Integer, ArrayList<HeapSegmentElement>> heapMap) {
+            mProcessedHeapMap = heapMap;
+        }
+        
+        public Map<Integer, ArrayList<HeapSegmentElement>> getProcessedHeapMap() {
+            return mProcessedHeapMap;
+        }
+        
+
+    }
+
+
+    /**
+     * Generic constructor.
+     */
+    ClientData(int pid) {
+        mPid = pid;
+
+        mDebuggerInterest = DEBUGGER_DEFAULT;
+        mThreadMap = new TreeMap<Integer,ThreadInfo>();
+    }
+    
+    /**
+     * Returns whether the process is DDM-aware.
+     */
+    public boolean isDdmAware() {
+        return mIsDdmAware;
+    }
+
+    /**
+     * Sets DDM-aware status.
+     */
+    void isDdmAware(boolean aware) {
+        mIsDdmAware = aware;
+    }
+
+    /**
+     * Returns the process ID.
+     */
+    public int getPid() {
+        return mPid;
+    }
+
+    /**
+     * Returns the Client's VM identifier.
+     */
+    public String getVmIdentifier() {
+        return mVmIdentifier;
+    }
+
+    /**
+     * Sets VM identifier.
+     */
+    void setVmIdentifier(String ident) {
+        mVmIdentifier = ident;
+    }
+
+    /**
+     * Returns the client description.
+     * <p/>This is generally the name of the package defined in the
+     * <code>AndroidManifest.xml</code>.
+     * 
+     * @return the client description or <code>null</code> if not the description was not yet
+     * sent by the client.
+     */
+    public String getClientDescription() {
+        return mClientDescription;
+    }
+
+    /**
+     * Sets client description.
+     *
+     * There may be a race between HELO and APNM.  Rather than try
+     * to enforce ordering on the device, we just don't allow an empty
+     * name to replace a specified one.
+     */
+    void setClientDescription(String description) {
+        if (mClientDescription == null && description.length() > 0) {
+            /*
+             * The application VM is first named <pre-initialized> before being assigned
+             * its real name.
+             * Depending on the timing, we can get an APNM chunk setting this name before
+             * another one setting the final actual name. So if we get a SetClientDescription
+             * with this value we ignore it.
+             */
+            if (PRE_INITIALIZED.equals(description) == false) {
+                mClientDescription = description;
+            }
+        }
+    }
+    
+    /**
+     * Returns the debugger connection status. Possible values are {@link #DEBUGGER_DEFAULT},
+     * {@link #DEBUGGER_WAITING}, {@link #DEBUGGER_ATTACHED}, and {@link #DEBUGGER_ERROR}.
+     */
+    public int getDebuggerConnectionStatus() {
+        return mDebuggerInterest;
+    }
+
+    /**
+     * Sets debugger connection status.
+     */
+    void setDebuggerConnectionStatus(int val) {
+        mDebuggerInterest = val;
+    }
+
+    /**
+     * Sets the current heap info values for the specified heap.
+     *
+     * @param heapId The heap whose info to update
+     * @param sizeInBytes The size of the heap, in bytes
+     * @param bytesAllocated The number of bytes currently allocated in the heap
+     * @param objectsAllocated The number of objects currently allocated in
+     *                         the heap
+     */
+    // TODO: keep track of timestamp, reason
+    synchronized void setHeapInfo(int heapId, long maxSizeInBytes,
+            long sizeInBytes, long bytesAllocated, long objectsAllocated) {
+        HashMap<String, Long> heapInfo = new HashMap<String, Long>();
+        heapInfo.put(HEAP_MAX_SIZE_BYTES, maxSizeInBytes);
+        heapInfo.put(HEAP_SIZE_BYTES, sizeInBytes);
+        heapInfo.put(HEAP_BYTES_ALLOCATED, bytesAllocated);
+        heapInfo.put(HEAP_OBJECTS_ALLOCATED, objectsAllocated);
+        mHeapInfoMap.put(heapId, heapInfo);
+    }
+
+    /**
+     * Returns the {@link HeapData} object for the VM.
+     */
+    public HeapData getVmHeapData() {
+        return mHeapData;
+    }
+
+    /**
+     * Returns the {@link HeapData} object for the native code.
+     */
+    HeapData getNativeHeapData() {
+        return mNativeHeapData;
+    }
+
+    /**
+     * Returns an iterator over the list of known VM heap ids.
+     * <p/>
+     * The caller must synchronize on the {@link ClientData} object while iterating.
+     *
+     * @return an iterator over the list of heap ids
+     */
+    public synchronized Iterator<Integer> getVmHeapIds() {
+        return mHeapInfoMap.keySet().iterator();
+    }
+
+    /**
+     * Returns the most-recent info values for the specified VM heap.
+     *
+     * @param heapId The heap whose info should be returned
+     * @return a map containing the info values for the specified heap.
+     *         Returns <code>null</code> if the heap ID is unknown.
+     */
+    public synchronized Map<String, Long> getVmHeapInfo(int heapId) {
+        return mHeapInfoMap.get(heapId);
+    }
+
+    /**
+     * Adds a new thread to the list.
+     */
+    synchronized void addThread(int threadId, String threadName) {
+        ThreadInfo attr = new ThreadInfo(threadId, threadName);
+        mThreadMap.put(threadId, attr);
+    }
+
+    /**
+     * Removes a thread from the list.
+     */
+    synchronized void removeThread(int threadId) {
+        mThreadMap.remove(threadId);
+    }
+
+    /**
+     * Returns the list of threads as {@link ThreadInfo} objects.
+     * <p/>The list is empty until a thread update was requested with
+     * {@link Client#requestThreadUpdate()}.
+     */
+    public synchronized ThreadInfo[] getThreads() {
+        Collection<ThreadInfo> threads = mThreadMap.values();
+        return threads.toArray(new ThreadInfo[threads.size()]);
+    }
+
+    /**
+     * Returns the {@link ThreadInfo} by thread id.
+     */
+    synchronized ThreadInfo getThread(int threadId) {
+        return mThreadMap.get(threadId);
+    }
+    
+    synchronized void clearThreads() {
+        mThreadMap.clear();
+    }
+
+    /**
+     * Returns the list of {@link NativeAllocationInfo}.
+     * @see Client#requestNativeHeapInformation()
+     */
+    public synchronized List<NativeAllocationInfo> getNativeAllocationList() {
+        return Collections.unmodifiableList(mNativeAllocationList);
+    }
+
+    /**
+     * adds a new {@link NativeAllocationInfo} to the {@link Client}
+     * @param allocInfo The {@link NativeAllocationInfo} to add.
+     */
+    synchronized void addNativeAllocation(NativeAllocationInfo allocInfo) {
+        mNativeAllocationList.add(allocInfo);
+    }
+
+    /**
+     * Clear the current malloc info.
+     */
+    synchronized void clearNativeAllocationInfo() {
+        mNativeAllocationList.clear();
+    }
+
+    /**
+     * Returns the total native memory.
+     * @see Client#requestNativeHeapInformation()
+     */
+    public synchronized int getTotalNativeMemory() {
+        return mNativeTotalMemory;
+    }
+
+    synchronized void setTotalNativeMemory(int totalMemory) {
+        mNativeTotalMemory = totalMemory;
+    }
+
+    synchronized void addNativeLibraryMapInfo(long startAddr, long endAddr, String library) {
+        mNativeLibMapInfo.add(new NativeLibraryMapInfo(startAddr, endAddr, library));
+    }
+
+    /**
+     * Returns an {@link Iterator} on {@link NativeLibraryMapInfo} objects.
+     * <p/>
+     * The caller must synchronize on the {@link ClientData} object while iterating.
+     */
+    public synchronized Iterator<NativeLibraryMapInfo> getNativeLibraryMapInfo() {
+        return mNativeLibMapInfo.iterator();
+    }
+    
+    synchronized void setAllocationStatus(boolean enabled) {
+        mAllocationStatus = enabled ? ALLOCATION_TRACKING_ON : ALLOCATION_TRACKING_OFF;
+    }
+
+    /**
+     * Returns the allocation tracking status.
+     * @see Client#requestAllocationStatus()
+     */
+    public synchronized int getAllocationStatus() {
+        return mAllocationStatus;
+    }
+    
+    synchronized void setAllocations(AllocationInfo[] allocs) {
+        mAllocations = allocs;
+    }
+    
+    /**
+     * Returns the list of tracked allocations.
+     * @see Client#requestAllocationDetails()
+     */
+    public synchronized AllocationInfo[] getAllocations() {
+        return mAllocations;
+    }
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DdmPreferences.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DdmPreferences.java
new file mode 100644
index 0000000..c96d40d
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DdmPreferences.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import com.android.ddmlib.Log.LogLevel;
+
+/**
+ * Preferences for the ddm library.
+ * <p/>This class does not handle storing the preferences. It is merely a central point for
+ * applications using the ddmlib to override the default values.
+ * <p/>Various components of the ddmlib query this class to get their values.
+ * <p/>Calls to some <code>set##()</code> methods will update the components using the values
+ * right away, while other methods will have no effect once {@link AndroidDebugBridge#init(boolean)}
+ * has been called.
+ * <p/>Check the documentation of each method.
+ */
+public final class DdmPreferences {
+
+    /** Default value for thread update flag upon client connection. */
+    public final static boolean DEFAULT_INITIAL_THREAD_UPDATE = false;
+    /** Default value for heap update flag upon client connection. */
+    public final static boolean DEFAULT_INITIAL_HEAP_UPDATE = false;
+    /** Default value for the selected client debug port */
+    public final static int DEFAULT_SELECTED_DEBUG_PORT = 8700;
+    /** Default value for the debug port base */
+    public final static int DEFAULT_DEBUG_PORT_BASE = 8600;
+    /** Default value for the logcat {@link LogLevel} */
+    public final static LogLevel DEFAULT_LOG_LEVEL = LogLevel.ERROR;
+
+    private static boolean sThreadUpdate = DEFAULT_INITIAL_THREAD_UPDATE;
+    private static boolean sInitialHeapUpdate = DEFAULT_INITIAL_HEAP_UPDATE;
+
+    private static int sSelectedDebugPort = DEFAULT_SELECTED_DEBUG_PORT;
+    private static int sDebugPortBase = DEFAULT_DEBUG_PORT_BASE;
+    private static LogLevel sLogLevel = DEFAULT_LOG_LEVEL;
+
+    /**
+     * Returns the initial {@link Client} flag for thread updates.
+     * @see #setInitialThreadUpdate(boolean)
+     */
+    public static boolean getInitialThreadUpdate() {
+        return sThreadUpdate;
+    }
+
+    /**
+     * Sets the initial {@link Client} flag for thread updates.
+     * <p/>This change takes effect right away, for newly created {@link Client} objects.
+     */
+    public static void setInitialThreadUpdate(boolean state) {
+        sThreadUpdate = state;
+    }
+
+    /**
+     * Returns the initial {@link Client} flag for heap updates.
+     * @see #setInitialHeapUpdate(boolean)
+     */
+    public static boolean getInitialHeapUpdate() {
+        return sInitialHeapUpdate;
+    }
+
+    /**
+     * Sets the initial {@link Client} flag for heap updates.
+     * <p/>If <code>true</code>, the {@link ClientData} will automatically be updated with
+     * the VM heap information whenever a GC happens. 
+     * <p/>This change takes effect right away, for newly created {@link Client} objects.
+     */
+    public static void setInitialHeapUpdate(boolean state) {
+        sInitialHeapUpdate = state;
+    }
+
+    /**
+     * Returns the debug port used by the selected {@link Client}.
+     */
+    public static int getSelectedDebugPort() {
+        return sSelectedDebugPort;
+    }
+
+    /**
+     * Sets the debug port used by the selected {@link Client}.
+     * <p/>This change takes effect right away.
+     * @param port the new port to use.
+     */
+    public static void setSelectedDebugPort(int port) {
+        sSelectedDebugPort = port;
+
+        MonitorThread monitorThread = MonitorThread.getInstance();
+        if (monitorThread != null) {
+            monitorThread.setDebugSelectedPort(port);
+        }
+    }
+
+    /**
+     * Returns the debug port used by the first {@link Client}. Following clients, will use the
+     * next port.
+     */
+    public static int getDebugPortBase() {
+        return sDebugPortBase;
+    }
+
+    /**
+     * Sets the debug port used by the first {@link Client}.
+     * <p/>Once a port is used, the next Client will use port + 1. Quitting applications will
+     * release their debug port, and new clients will be able to reuse them.
+     * <p/>This must be called before {@link AndroidDebugBridge#init(boolean)}.
+     */
+    public static void setDebugPortBase(int port) {
+        sDebugPortBase = port;
+    }
+
+    /**
+     * Returns the minimum {@link LogLevel} being displayed.
+     */
+    public static LogLevel getLogLevel() {
+        return sLogLevel;
+    }
+
+    /**
+     * Sets the minimum {@link LogLevel} to display.
+     * <p/>This change takes effect right away.
+     */
+    public static void setLogLevel(String value) {
+        sLogLevel = LogLevel.getByString(value);
+
+        Log.setLevel(sLogLevel);
+    }
+    
+    /**
+     * Non accessible constructor.
+     */
+    private DdmPreferences() {
+        // pass, only static methods in the class.
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DebugPortManager.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DebugPortManager.java
new file mode 100644
index 0000000..9392127
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DebugPortManager.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import com.android.ddmlib.Device;
+
+/**
+ * Centralized point to provide a {@link IDebugPortProvider} to ddmlib. 
+ * 
+ * <p/>When {@link Client} objects are created, they start listening for debuggers on a specific
+ * port. The default behavior is to start with {@link DdmPreferences#getDebugPortBase()} and 
+ * increment this value for each new <code>Client</code>.
+ * 
+ * <p/>This {@link DebugPortManager} allows applications using ddmlib to provide a custom
+ * port provider on a per-<code>Client</code> basis, depending on the device/emulator they are
+ * running on, and/or their names.
+ */
+public class DebugPortManager {
+
+    /**
+     * Classes which implement this interface provide a method that provides a non random
+     * debugger port for a newly created {@link Client}.
+     */
+    public interface IDebugPortProvider {
+
+        public static final int NO_STATIC_PORT = -1;
+
+        /**
+         * Returns a non-random debugger port for the specified application running on the
+         * specified {@link Device}.
+         * @param device The device the application is running on.
+         * @param appName The application name, as defined in the <code>AndroidManifest.xml</code>
+         * <var>package</var> attribute of the <var>manifest</var> node.
+         * @return The non-random debugger port or {@link #NO_STATIC_PORT} if the {@link Client}
+         * should use the automatic debugger port provider.
+         */
+        public int getPort(Device device, String appName);
+    }
+
+    private static IDebugPortProvider sProvider = null;
+
+    /**
+     * Sets the {@link IDebugPortProvider} that will be used when a new {@link Client} requests
+     * a debugger port.
+     * @param provider the <code>IDebugPortProvider</code> to use.
+     */
+    public static void setProvider(IDebugPortProvider provider) {
+        sProvider = provider;
+    }
+
+    /**
+     * Returns the 
+     * @return
+     */
+    static IDebugPortProvider getProvider() {
+        return sProvider;
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Debugger.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Debugger.java
new file mode 100644
index 0000000..f30509a
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Debugger.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+
+/**
+ * This represents a pending or established connection with a JDWP debugger.
+ */
+class Debugger {
+
+    /*
+     * Messages from the debugger should be pretty small; may not even
+     * need an expanding-buffer implementation for this.
+     */
+    private static final int INITIAL_BUF_SIZE = 1 * 1024;
+    private static final int MAX_BUF_SIZE = 32 * 1024;
+    private ByteBuffer mReadBuffer;
+
+    private static final int PRE_DATA_BUF_SIZE = 256;
+    private ByteBuffer mPreDataBuffer;
+
+    /* connection state */
+    private int mConnState;
+    private static final int ST_NOT_CONNECTED = 1;
+    private static final int ST_AWAIT_SHAKE   = 2;
+    private static final int ST_READY         = 3;
+
+    /* peer */
+    private Client mClient;         // client we're forwarding to/from
+    private int mListenPort;        // listen to me
+    private ServerSocketChannel mListenChannel;
+
+    /* this goes up and down; synchronize methods that access the field */
+    private SocketChannel mChannel;
+
+    /**
+     * Create a new Debugger object, configured to listen for connections
+     * on a specific port.
+     */
+    Debugger(Client client, int listenPort) throws IOException {
+
+        mClient = client;
+        mListenPort = listenPort;
+
+        mListenChannel = ServerSocketChannel.open();
+        mListenChannel.configureBlocking(false);        // required for Selector
+
+        InetSocketAddress addr = new InetSocketAddress(
+                InetAddress.getByName("localhost"), // $NON-NLS-1$
+                listenPort);
+        mListenChannel.socket().setReuseAddress(true);  // enable SO_REUSEADDR
+        mListenChannel.socket().bind(addr);
+
+        mReadBuffer = ByteBuffer.allocate(INITIAL_BUF_SIZE);
+        mPreDataBuffer = ByteBuffer.allocate(PRE_DATA_BUF_SIZE);
+        mConnState = ST_NOT_CONNECTED;
+
+        Log.i("ddms", "Created: " + this.toString());
+    }
+
+    /**
+     * Returns "true" if a debugger is currently attached to us.
+     */
+    boolean isDebuggerAttached() {
+        return mChannel != null;
+    }
+
+    /**
+     * Represent the Debugger as a string.
+     */
+    @Override
+    public String toString() {
+        // mChannel != null means we have connection, ST_READY means it's going
+        return "[Debugger " + mListenPort + "-->" + mClient.getClientData().getPid()
+                + ((mConnState != ST_READY) ? " inactive]" : " active]");
+    }
+
+    /**
+     * Register the debugger's listen socket with the Selector.
+     */
+    void registerListener(Selector sel) throws IOException {
+        mListenChannel.register(sel, SelectionKey.OP_ACCEPT, this);
+    }
+
+    /**
+     * Return the Client being debugged.
+     */
+    Client getClient() {
+        return mClient;
+    }
+
+    /**
+     * Accept a new connection, but only if we don't already have one.
+     *
+     * Must be synchronized with other uses of mChannel and mPreBuffer.
+     *
+     * Returns "null" if we're already talking to somebody.
+     */
+    synchronized SocketChannel accept() throws IOException {
+        return accept(mListenChannel);
+    }
+
+    /**
+     * Accept a new connection from the specified listen channel.  This
+     * is so we can listen on a dedicated port for the "current" client,
+     * where "current" is constantly in flux.
+     *
+     * Must be synchronized with other uses of mChannel and mPreBuffer.
+     *
+     * Returns "null" if we're already talking to somebody.
+     */
+    synchronized SocketChannel accept(ServerSocketChannel listenChan)
+        throws IOException {
+
+        if (listenChan != null) {
+            SocketChannel newChan;
+    
+            newChan = listenChan.accept();
+            if (mChannel != null) {
+                Log.w("ddms", "debugger already talking to " + mClient
+                    + " on " + mListenPort);
+                newChan.close();
+                return null;
+            }
+            mChannel = newChan;
+            mChannel.configureBlocking(false);         // required for Selector
+            mConnState = ST_AWAIT_SHAKE;
+            return mChannel;
+        }
+        
+        return null;
+    }
+
+    /**
+     * Close the data connection only.
+     */
+    synchronized void closeData() {
+        try {
+            if (mChannel != null) {
+                mChannel.close();
+                mChannel = null;
+                mConnState = ST_NOT_CONNECTED;
+
+                ClientData cd = mClient.getClientData();
+                cd.setDebuggerConnectionStatus(ClientData.DEBUGGER_DEFAULT);
+                mClient.update(Client.CHANGE_DEBUGGER_INTEREST);
+            }
+        } catch (IOException ioe) {
+            Log.w("ddms", "Failed to close data " + this);
+        }
+    }
+
+    /**
+     * Close the socket that's listening for new connections and (if
+     * we're connected) the debugger data socket.
+     */
+    synchronized void close() {
+        try {
+            if (mListenChannel != null) {
+                mListenChannel.close();
+            }
+            mListenChannel = null;
+            closeData();
+        } catch (IOException ioe) {
+            Log.w("ddms", "Failed to close listener " + this);
+        }
+    }
+
+    // TODO: ?? add a finalizer that verifies the channel was closed
+
+    /**
+     * Read data from our channel.
+     *
+     * This is called when data is known to be available, and we don't yet
+     * have a full packet in the buffer.  If the buffer is at capacity,
+     * expand it.
+     */
+    void read() throws IOException {
+        int count;
+
+        if (mReadBuffer.position() == mReadBuffer.capacity()) {
+            if (mReadBuffer.capacity() * 2 > MAX_BUF_SIZE) {
+                throw new BufferOverflowException();
+            }
+            Log.d("ddms", "Expanding read buffer to "
+                + mReadBuffer.capacity() * 2);
+
+            ByteBuffer newBuffer =
+                    ByteBuffer.allocate(mReadBuffer.capacity() * 2);
+            mReadBuffer.position(0);
+            newBuffer.put(mReadBuffer);     // leaves "position" at end
+
+            mReadBuffer = newBuffer;
+        }
+
+        count = mChannel.read(mReadBuffer);
+        Log.v("ddms", "Read " + count + " bytes from " + this);
+        if (count < 0) throw new IOException("read failed");
+    }
+
+    /**
+     * Return information for the first full JDWP packet in the buffer.
+     *
+     * If we don't yet have a full packet, return null.
+     *
+     * If we haven't yet received the JDWP handshake, we watch for it here
+     * and consume it without admitting to have done so.  We also send
+     * the handshake response to the debugger, along with any pending
+     * pre-connection data, which is why this can throw an IOException.
+     */
+    JdwpPacket getJdwpPacket() throws IOException {
+        /*
+         * On entry, the data starts at offset 0 and ends at "position".
+         * "limit" is set to the buffer capacity.
+         */
+        if (mConnState == ST_AWAIT_SHAKE) {
+            int result;
+
+            result = JdwpPacket.findHandshake(mReadBuffer);
+            //Log.v("ddms", "findHand: " + result);
+            switch (result) {
+                case JdwpPacket.HANDSHAKE_GOOD:
+                    Log.i("ddms", "Good handshake from debugger");
+                    JdwpPacket.consumeHandshake(mReadBuffer);
+                    sendHandshake();
+                    mConnState = ST_READY;
+
+                    ClientData cd = mClient.getClientData();
+                    cd.setDebuggerConnectionStatus(ClientData.DEBUGGER_ATTACHED);
+                    mClient.update(Client.CHANGE_DEBUGGER_INTEREST);
+
+                    // see if we have another packet in the buffer
+                    return getJdwpPacket();
+                case JdwpPacket.HANDSHAKE_BAD:
+                    // not a debugger, throw an exception so we drop the line
+                    Log.i("ddms", "Bad handshake from debugger");
+                    throw new IOException("bad handshake");
+                case JdwpPacket.HANDSHAKE_NOTYET:
+                    break;
+                default:
+                    Log.e("ddms", "Unknown packet while waiting for client handshake");
+            }
+            return null;
+        } else if (mConnState == ST_READY) {
+            if (mReadBuffer.position() != 0) {
+                Log.v("ddms", "Checking " + mReadBuffer.position() + " bytes");
+            }
+            return JdwpPacket.findPacket(mReadBuffer);
+        } else {
+            Log.e("ddms", "Receiving data in state = " + mConnState);
+        }
+        
+        return null;
+    }
+
+    /**
+     * Forward a packet to the client.
+     *
+     * "mClient" will never be null, though it's possible that the channel
+     * in the client has closed and our send attempt will fail.
+     *
+     * Consumes the packet.
+     */
+    void forwardPacketToClient(JdwpPacket packet) throws IOException {
+        mClient.sendAndConsume(packet);
+    }
+
+    /**
+     * Send the handshake to the debugger.  We also send along any packets
+     * we already received from the client (usually just a VM_START event,
+     * if anything at all).
+     */
+    private synchronized void sendHandshake() throws IOException {
+        ByteBuffer tempBuffer = ByteBuffer.allocate(JdwpPacket.HANDSHAKE_LEN);
+        JdwpPacket.putHandshake(tempBuffer);
+        int expectedLength = tempBuffer.position();
+        tempBuffer.flip();
+        if (mChannel.write(tempBuffer) != expectedLength) {
+            throw new IOException("partial handshake write");
+        }
+
+        expectedLength = mPreDataBuffer.position();
+        if (expectedLength > 0) {
+            Log.d("ddms", "Sending " + mPreDataBuffer.position()
+                    + " bytes of saved data");
+            mPreDataBuffer.flip();
+            if (mChannel.write(mPreDataBuffer) != expectedLength) {
+                throw new IOException("partial pre-data write");
+            }
+            mPreDataBuffer.clear();
+        }
+    }
+
+    /**
+     * Send a packet to the debugger.
+     *
+     * Ideally, we can do this with a single channel write.  If that doesn't
+     * happen, we have to prevent anybody else from writing to the channel
+     * until this packet completes, so we synchronize on the channel.
+     *
+     * Another goal is to avoid unnecessary buffer copies, so we write
+     * directly out of the JdwpPacket's ByteBuffer.
+     *
+     * We must synchronize on "mChannel" before writing to it.  We want to
+     * coordinate the buffered data with mChannel creation, so this whole
+     * method is synchronized.
+     */
+    synchronized void sendAndConsume(JdwpPacket packet)
+        throws IOException {
+
+        if (mChannel == null) {
+            /*
+             * Buffer this up so we can send it to the debugger when it
+             * finally does connect.  This is essential because the VM_START
+             * message might be telling the debugger that the VM is
+             * suspended.  The alternative approach would be for us to
+             * capture and interpret VM_START and send it later if we
+             * didn't choose to un-suspend the VM for our own purposes.
+             */
+            Log.d("ddms", "Saving packet 0x"
+                    + Integer.toHexString(packet.getId()));
+            packet.movePacket(mPreDataBuffer);
+        } else {
+            packet.writeAndConsume(mChannel);
+        }
+    }
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
new file mode 100644
index 0000000..0e7f0bb
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import com.android.ddmlib.Client;
+import com.android.ddmlib.log.LogReceiver;
+
+import java.io.IOException;
+import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 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;
+        }
+    }
+
+    /** Emulator Serial Number regexp. */
+    final static String RE_EMULATOR_SN = "emulator-(\\d+)"; //$NON-NLS-1$
+
+    /** Serial number of the device */
+    String serialNumber = null;
+
+    /** Name of the AVD */
+    String mAvdName = null;
+
+    /** State of the device. */
+    DeviceState state = null;
+
+    /** Device properties. */
+    private final Map<String, String> mProperties = new HashMap<String, String>();
+
+    private final ArrayList<Client> mClients = new ArrayList<Client>();
+    private DeviceMonitor mMonitor;
+
+    /**
+     * Socket for the connection monitoring client connection/disconnection.
+     */
+    private SocketChannel mSocketChannel;
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#getSerialNumber()
+     */
+    public String getSerialNumber() {
+        return serialNumber;
+    }
+
+    public String getAvdName() {
+        return mAvdName;
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#getState()
+     */
+    public DeviceState getState() {
+        return state;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#getProperties()
+     */
+    public Map<String, String> getProperties() {
+        return Collections.unmodifiableMap(mProperties);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#getPropertyCount()
+     */
+    public int getPropertyCount() {
+        return mProperties.size();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#getProperty(java.lang.String)
+     */
+    public String getProperty(String name) {
+        return mProperties.get(name);
+    }
+
+
+    @Override
+    public String toString() {
+        return serialNumber;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#isOnline()
+     */
+    public boolean isOnline() {
+        return state == DeviceState.ONLINE;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#isEmulator()
+     */
+    public boolean isEmulator() {
+        return serialNumber.matches(RE_EMULATOR_SN);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#isOffline()
+     */
+    public boolean isOffline() {
+        return state == DeviceState.OFFLINE;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#isBootLoader()
+     */
+    public boolean isBootLoader() {
+        return state == DeviceState.BOOTLOADER;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#hasClients()
+     */
+    public boolean hasClients() {
+        return mClients.size() > 0;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#getClients()
+     */
+    public Client[] getClients() {
+        synchronized (mClients) {
+            return mClients.toArray(new Client[mClients.size()]);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#getClient(java.lang.String)
+     */
+    public Client getClient(String applicationName) {
+        synchronized (mClients) {
+            for (Client c : mClients) {
+                if (applicationName.equals(c.getClientData().getClientDescription())) {
+                    return c;
+                }
+            }
+
+        }
+
+        return null;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#getSyncService()
+     */
+    public SyncService getSyncService() {
+        SyncService syncService = new SyncService(AndroidDebugBridge.sSocketAddr, this);
+        if (syncService.openSync()) {
+            return syncService;
+         }
+
+        return null;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#getFileListingService()
+     */
+    public FileListingService getFileListingService() {
+        return new FileListingService(this);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#getScreenshot()
+     */
+    public RawImage getScreenshot() throws IOException {
+        return AdbHelper.getFrameBuffer(AndroidDebugBridge.sSocketAddr, this);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#executeShellCommand(java.lang.String, com.android.ddmlib.IShellOutputReceiver)
+     */
+    public void executeShellCommand(String command, IShellOutputReceiver receiver)
+            throws IOException {
+        AdbHelper.executeRemoteCommand(AndroidDebugBridge.sSocketAddr, command, this,
+                receiver);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#runEventLogService(com.android.ddmlib.log.LogReceiver)
+     */
+    public void runEventLogService(LogReceiver receiver) throws IOException {
+        AdbHelper.runEventLogService(AndroidDebugBridge.sSocketAddr, this, receiver);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#runLogService(com.android.ddmlib.log.LogReceiver)
+     */
+    public void runLogService(String logname,
+            LogReceiver receiver) throws IOException {
+        AdbHelper.runLogService(AndroidDebugBridge.sSocketAddr, this, logname, receiver);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#createForward(int, int)
+     */
+    public boolean createForward(int localPort, int remotePort) {
+        try {
+            return AdbHelper.createForward(AndroidDebugBridge.sSocketAddr, this,
+                    localPort, remotePort);
+        } catch (IOException e) {
+            Log.e("adb-forward", e); //$NON-NLS-1$
+            return false;
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#removeForward(int, int)
+     */
+    public boolean removeForward(int localPort, int remotePort) {
+        try {
+            return AdbHelper.removeForward(AndroidDebugBridge.sSocketAddr, this,
+                    localPort, remotePort);
+        } catch (IOException e) {
+            Log.e("adb-remove-forward", e); //$NON-NLS-1$
+            return false;
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IDevice#getClientName(int)
+     */
+    public String getClientName(int pid) {
+        synchronized (mClients) {
+            for (Client c : mClients) {
+                if (c.getClientData().getPid() == pid) {
+                    return c.getClientData().getClientDescription();
+                }
+            }
+        }
+
+        return null;
+    }
+
+
+    Device(DeviceMonitor monitor) {
+        mMonitor = monitor;
+    }
+
+    DeviceMonitor getMonitor() {
+        return mMonitor;
+    }
+
+    void addClient(Client client) {
+        synchronized (mClients) {
+            mClients.add(client);
+        }
+    }
+
+    List<Client> getClientList() {
+        return mClients;
+    }
+
+    boolean hasClient(int pid) {
+        synchronized (mClients) {
+            for (Client client : mClients) {
+                if (client.getClientData().getPid() == pid) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    void clearClientList() {
+        synchronized (mClients) {
+            mClients.clear();
+        }
+    }
+
+    /**
+     * Sets the client monitoring socket.
+     * @param socketChannel the sockets
+     */
+    void setClientMonitoringSocket(SocketChannel socketChannel) {
+        mSocketChannel = socketChannel;
+    }
+
+    /**
+     * Returns the client monitoring socket.
+     */
+    SocketChannel getClientMonitoringSocket() {
+        return mSocketChannel;
+    }
+
+    /**
+     * Removes a {@link Client} from the list.
+     * @param client the client to remove.
+     * @param notify Whether or not to notify the listeners of a change.
+     */
+    void removeClient(Client client, boolean notify) {
+        mMonitor.addPortToAvailableList(client.getDebuggerListenPort());
+        synchronized (mClients) {
+            mClients.remove(client);
+        }
+        if (notify) {
+            mMonitor.getServer().deviceChanged(this, CHANGE_CLIENT_LIST);
+        }
+    }
+
+    void update(int changeMask) {
+        mMonitor.getServer().deviceChanged(this, changeMask);
+    }
+
+    void update(Client client, int changeMask) {
+        mMonitor.getServer().clientChanged(client, changeMask);
+    }
+
+    void addProperty(String label, String value) {
+        mProperties.put(label, value);
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DeviceMonitor.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DeviceMonitor.java
new file mode 100644
index 0000000..f9d0fa0
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DeviceMonitor.java
@@ -0,0 +1,866 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import com.android.ddmlib.AdbHelper.AdbResponse;
+import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
+import com.android.ddmlib.Device.DeviceState;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.channels.AsynchronousCloseException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A Device monitor. This connects to the Android Debug Bridge and get device and
+ * debuggable process information from it.
+ */
+final class DeviceMonitor {
+    private byte[] mLengthBuffer = new byte[4];
+    private byte[] mLengthBuffer2 = new byte[4];
+
+    private boolean mQuit = false;
+
+    private AndroidDebugBridge mServer;
+
+    private SocketChannel mMainAdbConnection = null;
+    private boolean mMonitoring = false;
+    private int mConnectionAttempt = 0;
+    private int mRestartAttemptCount = 0;
+    private boolean mInitialDeviceListDone = false;
+
+    private Selector mSelector;
+
+    private final ArrayList<Device> mDevices = new ArrayList<Device>();
+
+    private final ArrayList<Integer> mDebuggerPorts = new ArrayList<Integer>();
+
+    private final HashMap<Client, Integer> mClientsToReopen = new HashMap<Client, Integer>();
+
+    /**
+     * Creates a new {@link DeviceMonitor} object and links it to the running
+     * {@link AndroidDebugBridge} object.
+     * @param server the running {@link AndroidDebugBridge}.
+     */
+    DeviceMonitor(AndroidDebugBridge server) {
+        mServer = server;
+
+        mDebuggerPorts.add(DdmPreferences.getDebugPortBase());
+    }
+
+    /**
+     * Starts the monitoring.
+     */
+    void start() {
+        new Thread("Device List Monitor") { //$NON-NLS-1$
+            @Override
+            public void run() {
+                deviceMonitorLoop();
+            }
+        }.start();
+    }
+
+    /**
+     * Stops the monitoring.
+     */
+    void stop() {
+        mQuit = true;
+
+        // wakeup the main loop thread by closing the main connection to adb.
+        try {
+            if (mMainAdbConnection != null) {
+                mMainAdbConnection.close();
+            }
+        } catch (IOException e1) {
+        }
+
+        // wake up the secondary loop by closing the selector.
+        if (mSelector != null) {
+            mSelector.wakeup();
+        }
+    }
+
+
+
+    /**
+     * Returns if the monitor is currently connected to the debug bridge server.
+     * @return
+     */
+    boolean isMonitoring() {
+        return mMonitoring;
+    }
+    
+    int getConnectionAttemptCount() {
+        return mConnectionAttempt;
+    }
+    
+    int getRestartAttemptCount() {
+        return mRestartAttemptCount;
+    }
+
+    /**
+     * Returns the devices.
+     */
+    Device[] getDevices() {
+        synchronized (mDevices) {
+            return mDevices.toArray(new Device[mDevices.size()]);
+        }
+    }
+    
+    boolean hasInitialDeviceList() {
+        return mInitialDeviceListDone;
+    }
+
+    AndroidDebugBridge getServer() {
+        return mServer;
+    }
+
+    void addClientToDropAndReopen(Client client, int port) {
+        synchronized (mClientsToReopen) {
+            Log.d("DeviceMonitor",
+                    "Adding " + client + " to list of client to reopen (" + port +").");
+            if (mClientsToReopen.get(client) == null) {
+                mClientsToReopen.put(client, port);
+            }
+        }
+        mSelector.wakeup();
+    }
+
+    /**
+     * Monitors the devices. This connects to the Debug Bridge
+     */
+    private void deviceMonitorLoop() {
+        do {
+            try {
+                if (mMainAdbConnection == null) {
+                    Log.d("DeviceMonitor", "Opening adb connection");
+                    mMainAdbConnection = openAdbConnection();
+                    if (mMainAdbConnection == null) {
+                        mConnectionAttempt++;
+                        Log.e("DeviceMonitor", "Connection attempts: " + mConnectionAttempt);
+                        if (mConnectionAttempt > 10) {
+                            if (mServer.startAdb() == false) {
+                                mRestartAttemptCount++;
+                                Log.e("DeviceMonitor",
+                                        "adb restart attempts: " + mRestartAttemptCount);
+                            } else {
+                                mRestartAttemptCount = 0;
+                            }
+                        }
+                        waitABit();
+                    } else {
+                        Log.d("DeviceMonitor", "Connected to adb for device monitoring");
+                        mConnectionAttempt = 0;
+                    }
+                }
+
+                if (mMainAdbConnection != null && mMonitoring == false) {
+                    mMonitoring = sendDeviceListMonitoringRequest();
+                }
+
+                if (mMonitoring) {
+                    // read the length of the incoming message
+                    int length = readLength(mMainAdbConnection, mLengthBuffer);
+                    
+                    if (length >= 0) {
+                        // read the incoming message
+                        processIncomingDeviceData(length);
+                        
+                        // flag the fact that we have build the list at least once.
+                        mInitialDeviceListDone = true;
+                    }
+                }
+            } catch (AsynchronousCloseException ace) {
+                // this happens because of a call to Quit. We do nothing, and the loop will break.
+            } catch (IOException ioe) {
+                if (mQuit == false) {
+                    Log.e("DeviceMonitor", "Adb connection Error:" + ioe.getMessage());
+                    mMonitoring = false;
+                    if (mMainAdbConnection != null) {
+                        try {
+                            mMainAdbConnection.close();
+                        } catch (IOException ioe2) {
+                            // we can safely ignore that one.
+                        }
+                        mMainAdbConnection = null;
+                    }
+                }
+            }
+        } while (mQuit == false);
+    }
+
+    /**
+     * Sleeps for a little bit.
+     */
+    private void waitABit() {
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e1) {
+        }
+    }
+
+    /**
+     * Attempts to connect to the debug bridge server.
+     * @return a connect socket if success, null otherwise
+     */
+    private SocketChannel openAdbConnection() {
+        Log.d("DeviceMonitor", "Connecting to adb for Device List Monitoring...");
+
+        SocketChannel adbChannel = null;
+        try {
+            adbChannel = SocketChannel.open(AndroidDebugBridge.sSocketAddr);
+            adbChannel.socket().setTcpNoDelay(true);
+        } catch (IOException e) {
+        }
+
+        return adbChannel;
+    }
+
+    /**
+     *
+     * @return
+     * @throws IOException
+     */
+    private boolean sendDeviceListMonitoringRequest() throws IOException {
+        byte[] request = AdbHelper.formAdbRequest("host:track-devices"); //$NON-NLS-1$
+
+        if (AdbHelper.write(mMainAdbConnection, request) == false) {
+            Log.e("DeviceMonitor", "Sending Tracking request failed!");
+            mMainAdbConnection.close();
+            throw new IOException("Sending Tracking request failed!");
+        }
+
+        AdbResponse resp = AdbHelper.readAdbResponse(mMainAdbConnection,
+                false /* readDiagString */);
+
+        if (resp.ioSuccess == false) {
+            Log.e("DeviceMonitor", "Failed to read the adb response!");
+            mMainAdbConnection.close();
+            throw new IOException("Failed to read the adb response!");
+        }
+
+        if (resp.okay == false) {
+            // request was refused by adb!
+            Log.e("DeviceMonitor", "adb refused request: " + resp.message);
+        }
+
+        return resp.okay;
+    }
+
+    /**
+     * Processes an incoming device message from the socket
+     * @param socket
+     * @param length
+     * @throws IOException
+     */
+    private void processIncomingDeviceData(int length) throws IOException {
+        ArrayList<Device> list = new ArrayList<Device>();
+        
+        if (length > 0) {
+            byte[] buffer = new byte[length];
+            String result = read(mMainAdbConnection, buffer);
+            
+            String[] devices = result.split("\n"); // $NON-NLS-1$
+
+            for (String d : devices) {
+                String[] param = d.split("\t"); // $NON-NLS-1$
+                if (param.length == 2) {
+                    // new adb uses only serial numbers to identify devices
+                    Device device = new Device(this);
+                    device.serialNumber = param[0];
+                    device.state = DeviceState.getState(param[1]);
+
+                    //add the device to the list
+                    list.add(device);
+                }
+            }
+        }
+
+        // now merge the new devices with the old ones.
+        updateDevices(list);
+    }
+
+    /**
+     *  Updates the device list with the new items received from the monitoring service.
+     */
+    private void updateDevices(ArrayList<Device> newList) {
+        // because we are going to call mServer.deviceDisconnected which will acquire this lock
+        // we lock it first, so that the AndroidDebugBridge lock is always locked first.
+        synchronized (AndroidDebugBridge.getLock()) {
+            synchronized (mDevices) {
+                // For each device in the current list, we look for a matching the new list.
+                // * if we find it, we update the current object with whatever new information
+                //   there is
+                //   (mostly state change, if the device becomes ready, we query for build info).
+                //   We also remove the device from the new list to mark it as "processed"
+                // * if we do not find it, we remove it from the current list.
+                // Once this is done, the new list contains device we aren't monitoring yet, so we
+                // add them to the list, and start monitoring them.
+    
+                for (int d = 0 ; d < mDevices.size() ;) {
+                    Device device = mDevices.get(d);
+    
+                    // look for a similar device in the new list.
+                    int count = newList.size();
+                    boolean foundMatch = false;
+                    for (int dd = 0 ; dd < count ; dd++) {
+                        Device newDevice = newList.get(dd);
+                        // see if it matches in id and serial number.
+                        if (newDevice.serialNumber.equals(device.serialNumber)) {
+                            foundMatch = true;
+    
+                            // update the state if needed.
+                            if (device.state != newDevice.state) {
+                                device.state = newDevice.state;
+                                device.update(Device.CHANGE_STATE);
+    
+                                // if the device just got ready/online, we need to start
+                                // monitoring it.
+                                if (device.isOnline()) {
+                                    if (AndroidDebugBridge.getClientSupport() == true) {
+                                        if (startMonitoringDevice(device) == false) {
+                                            Log.e("DeviceMonitor",
+                                                    "Failed to start monitoring "
+                                                    + device.serialNumber);
+                                        }
+                                    }
+
+                                    if (device.getPropertyCount() == 0) {
+                                        queryNewDeviceForInfo(device);
+                                    }
+                                }
+                            }
+    
+                            // remove the new device from the list since it's been used
+                            newList.remove(dd);
+                            break;
+                        }
+                    }
+    
+                    if (foundMatch == false) {
+                        // the device is gone, we need to remove it, and keep current index
+                        // to process the next one.
+                        removeDevice(device);
+                        mServer.deviceDisconnected(device);
+                    } else {
+                        // process the next one
+                        d++;
+                    }
+                }
+    
+                // at this point we should still have some new devices in newList, so we
+                // process them.
+                for (Device newDevice : newList) {
+                    // add them to the list
+                    mDevices.add(newDevice);
+                    mServer.deviceConnected(newDevice);
+    
+                    // start monitoring them.
+                    if (AndroidDebugBridge.getClientSupport() == true) {
+                        if (newDevice.isOnline()) {
+                            startMonitoringDevice(newDevice);
+                        }
+                    }
+    
+                    // look for their build info.
+                    if (newDevice.isOnline()) {
+                        queryNewDeviceForInfo(newDevice);
+                    }
+                }
+            }
+        }
+        newList.clear();
+    }
+
+    private void removeDevice(Device device) {
+        device.clearClientList();
+        mDevices.remove(device);
+        
+        SocketChannel channel = device.getClientMonitoringSocket();
+        if (channel != null) {
+            try {
+                channel.close();
+            } catch (IOException e) {
+                // doesn't really matter if the close fails.
+            }
+        }
+    }
+
+    /**
+     * Queries a device for its build info.
+     * @param device the device to query.
+     */
+    private void queryNewDeviceForInfo(Device device) {
+        // TODO: do this in a separate thread.
+        try {
+            // first get the list of properties.
+            device.executeShellCommand(GetPropReceiver.GETPROP_COMMAND,
+                    new GetPropReceiver(device));
+            
+            // now get the emulator Virtual Device name (if applicable).
+            if (device.isEmulator()) {
+                EmulatorConsole console = EmulatorConsole.getConsole(device);
+                if (console != null) {
+                    device.mAvdName = console.getAvdName();
+                }
+            }
+        } catch (IOException e) {
+            // if we can't get the build info, it doesn't matter too much
+        }
+    }
+
+    /**
+     * Starts a monitoring service for a device.
+     * @param device the device to monitor.
+     * @return true if success.
+     */
+    private boolean startMonitoringDevice(Device device) {
+        SocketChannel socketChannel = openAdbConnection();
+
+        if (socketChannel != null) {
+            try {
+                boolean result = sendDeviceMonitoringRequest(socketChannel, device);
+                if (result) {
+
+                    if (mSelector == null) {
+                        startDeviceMonitorThread();
+                    }
+
+                    device.setClientMonitoringSocket(socketChannel);
+
+                    synchronized (mDevices) {
+                        // always wakeup before doing the register. The synchronized block
+                        // ensure that the selector won't select() before the end of this block.
+                        // @see deviceClientMonitorLoop
+                        mSelector.wakeup();
+
+                        socketChannel.configureBlocking(false);
+                        socketChannel.register(mSelector, SelectionKey.OP_READ, device);
+                    }
+
+                    return true;
+                }
+            } catch (IOException e) {
+                try {
+                    // attempt to close the socket if needed.
+                    socketChannel.close();
+                } catch (IOException e1) {
+                    // we can ignore that one. It may already have been closed.
+                }
+                Log.d("DeviceMonitor",
+                        "Connection Failure when starting to monitor device '"
+                        + device + "' : " + e.getMessage());
+            }
+        }
+
+        return false;
+    }
+
+    private void startDeviceMonitorThread() throws IOException {
+        mSelector = Selector.open();
+        new Thread("Device Client Monitor") { //$NON-NLS-1$
+            @Override
+            public void run() {
+                deviceClientMonitorLoop();
+            }
+        }.start();
+    }
+
+    private void deviceClientMonitorLoop() {
+        do {
+            try {
+                // This synchronized block stops us from doing the select() if a new
+                // Device is being added.
+                // @see startMonitoringDevice()
+                synchronized (mDevices) {
+                }
+
+                int count = mSelector.select();
+
+                if (mQuit) {
+                    return;
+                }
+
+                synchronized (mClientsToReopen) {
+                    if (mClientsToReopen.size() > 0) {
+                        Set<Client> clients = mClientsToReopen.keySet();
+                        MonitorThread monitorThread = MonitorThread.getInstance();
+
+                        for (Client client : clients) {
+                            Device device = client.getDevice();
+                            int pid = client.getClientData().getPid();
+
+                            monitorThread.dropClient(client, false /* notify */);
+
+                            // This is kinda bad, but if we don't wait a bit, the client
+                            // will never answer the second handshake!
+                            waitABit();
+
+                            int port = mClientsToReopen.get(client);
+
+                            if (port == IDebugPortProvider.NO_STATIC_PORT) {
+                                port = getNextDebuggerPort();
+                            }
+                            Log.d("DeviceMonitor", "Reopening " + client);
+                            openClient(device, pid, port, monitorThread);
+                            device.update(Device.CHANGE_CLIENT_LIST);
+                        }
+
+                        mClientsToReopen.clear();
+                    }
+                }
+
+                if (count == 0) {
+                    continue;
+                }
+
+                Set<SelectionKey> keys = mSelector.selectedKeys();
+                Iterator<SelectionKey> iter = keys.iterator();
+
+                while (iter.hasNext()) {
+                    SelectionKey key = iter.next();
+                    iter.remove();
+
+                    if (key.isValid() && key.isReadable()) {
+                        Object attachment = key.attachment();
+
+                        if (attachment instanceof Device) {
+                            Device device = (Device)attachment;
+
+                            SocketChannel socket = device.getClientMonitoringSocket();
+
+                            if (socket != null) {
+                                try {
+                                    int length = readLength(socket, mLengthBuffer2);
+
+                                    processIncomingJdwpData(device, socket, length);
+                                } catch (IOException ioe) {
+                                    Log.d("DeviceMonitor",
+                                            "Error reading jdwp list: " + ioe.getMessage());
+                                    socket.close();
+
+                                    // restart the monitoring of that device
+                                    synchronized (mDevices) {
+                                        if (mDevices.contains(device)) {
+                                            Log.d("DeviceMonitor",
+                                                    "Restarting monitoring service for " + device);
+                                            startMonitoringDevice(device);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            } catch (IOException e) {
+                if (mQuit == false) {
+
+                }
+            }
+
+        } while (mQuit == false);
+    }
+
+    private boolean sendDeviceMonitoringRequest(SocketChannel socket, Device device)
+            throws IOException {
+
+        AdbHelper.setDevice(socket, device);
+
+        byte[] request = AdbHelper.formAdbRequest("track-jdwp"); //$NON-NLS-1$
+
+        if (AdbHelper.write(socket, request) == false) {
+            Log.e("DeviceMonitor", "Sending jdwp tracking request failed!");
+            socket.close();
+            throw new IOException();
+        }
+
+        AdbResponse resp = AdbHelper.readAdbResponse(socket, false /* readDiagString */);
+
+        if (resp.ioSuccess == false) {
+            Log.e("DeviceMonitor", "Failed to read the adb response!");
+            socket.close();
+            throw new IOException();
+        }
+
+        if (resp.okay == false) {
+            // request was refused by adb!
+            Log.e("DeviceMonitor", "adb refused request: " + resp.message);
+        }
+
+        return resp.okay;
+    }
+
+    private void processIncomingJdwpData(Device device, SocketChannel monitorSocket, int length)
+            throws IOException {
+        if (length >= 0) {
+            // array for the current pids.
+            ArrayList<Integer> pidList = new ArrayList<Integer>();
+
+            // get the string data if there are any
+            if (length > 0) {
+                byte[] buffer = new byte[length];
+                String result = read(monitorSocket, buffer);
+    
+                // split each line in its own list and create an array of integer pid
+                String[] pids = result.split("\n"); //$NON-NLS-1$
+    
+                for (String pid : pids) {
+                    try {
+                        pidList.add(Integer.valueOf(pid));
+                    } catch (NumberFormatException nfe) {
+                        // looks like this pid is not really a number. Lets ignore it.
+                        continue;
+                    }
+                }
+            }
+
+            MonitorThread monitorThread = MonitorThread.getInstance();
+
+            // Now we merge the current list with the old one.
+            // this is the same mechanism as the merging of the device list.
+
+            // For each client in the current list, we look for a matching the pid in the new list.
+            // * if we find it, we do nothing, except removing the pid from its list,
+            //   to mark it as "processed"
+            // * if we do not find any match, we remove the client from the current list.
+            // Once this is done, the new list contains pids for which we don't have clients yet,
+            // so we create clients for them, add them to the list, and start monitoring them.
+
+            List<Client> clients = device.getClientList();
+
+            boolean changed = false;
+
+            // because MonitorThread#dropClient acquires first the monitorThread lock and then the
+            // Device client list lock (when removing the Client from the list), we have to make
+            // sure we acquire the locks in the same order, since another thread (MonitorThread),
+            // could call dropClient itself.
+            synchronized (monitorThread) {
+                synchronized (clients) {
+                    for (int c = 0 ; c < clients.size() ;) {
+                        Client client = clients.get(c);
+                        int pid = client.getClientData().getPid();
+        
+                        // look for a matching pid
+                        Integer match = null;
+                        for (Integer matchingPid : pidList) {
+                            if (pid == matchingPid.intValue()) {
+                                match = matchingPid;
+                                break;
+                            }
+                        }
+        
+                        if (match != null) {
+                            pidList.remove(match);
+                            c++; // move on to the next client.
+                        } else {
+                            // we need to drop the client. the client will remove itself from the
+                            // list of its device which is 'clients', so there's no need to
+                            // increment c.
+                            // We ask the monitor thread to not send notification, as we'll do
+                            // it once at the end.
+                            monitorThread.dropClient(client, false /* notify */);
+                            changed = true;
+                        }
+                    }
+                }
+            }
+
+            // at this point whatever pid is left in the list needs to be converted into Clients.
+            for (int newPid : pidList) {
+                openClient(device, newPid, getNextDebuggerPort(), monitorThread);
+                changed = true;
+            }
+
+            if (changed) {
+                mServer.deviceChanged(device, Device.CHANGE_CLIENT_LIST);
+            }
+        }
+    }
+
+    /**
+     * Opens and creates a new client.
+     * @return
+     */
+    private void openClient(Device device, int pid, int port, MonitorThread monitorThread) {
+        
+        SocketChannel clientSocket;
+        try {
+            clientSocket = AdbHelper.createPassThroughConnection(
+                    AndroidDebugBridge.sSocketAddr, device, pid);
+
+            // required for Selector
+            clientSocket.configureBlocking(false);
+        } catch (UnknownHostException uhe) {
+            Log.d("DeviceMonitor", "Unknown Jdwp pid: " + pid);
+            return;
+        } catch (IOException ioe) {
+            Log.w("DeviceMonitor",
+                    "Failed to connect to client '" + pid + "': " + ioe.getMessage());
+            return ;
+        }
+        
+        createClient(device, pid, clientSocket, port, monitorThread);
+    }
+
+    /**
+     * Creates a client and register it to the monitor thread
+     * @param device
+     * @param pid
+     * @param socket
+     * @param debuggerPort the debugger port.
+     * @param monitorThread the {@link MonitorThread} object.
+     */
+    private void createClient(Device device, int pid, SocketChannel socket, int debuggerPort,
+            MonitorThread monitorThread) {
+
+        /*
+         * Successfully connected to something. Create a Client object, add
+         * it to the list, and initiate the JDWP handshake.
+         */
+
+        Client client = new Client(device, socket, pid);
+
+        if (client.sendHandshake()) {
+            try {
+                if (AndroidDebugBridge.getClientSupport()) {
+                    client.listenForDebugger(debuggerPort);
+                }
+                client.requestAllocationStatus();
+            } catch (IOException ioe) {
+                client.getClientData().setDebuggerConnectionStatus(ClientData.DEBUGGER_ERROR);
+                Log.e("ddms", "Can't bind to local " + debuggerPort + " for debugger");
+                // oh well
+            }
+        } else {
+            Log.e("ddms", "Handshake with " + client + " failed!");
+            /*
+             * The handshake send failed. We could remove it now, but if the
+             * failure is "permanent" we'll just keep banging on it and
+             * getting the same result. Keep it in the list with its "error"
+             * state so we don't try to reopen it.
+             */
+        }
+
+        if (client.isValid()) {
+            device.addClient(client);
+            monitorThread.addClient(client);
+        } else {
+            client = null;
+        }
+    }
+
+    private int getNextDebuggerPort() {
+        // get the first port and remove it
+        synchronized (mDebuggerPorts) {
+            if (mDebuggerPorts.size() > 0) {
+                int port = mDebuggerPorts.get(0);
+
+                // remove it.
+                mDebuggerPorts.remove(0);
+
+                // if there's nothing left, add the next port to the list
+                if (mDebuggerPorts.size() == 0) {
+                    mDebuggerPorts.add(port+1);
+                }
+
+                return port;
+            }
+        }
+
+        return -1;
+    }
+
+    void addPortToAvailableList(int port) {
+        if (port > 0) {
+            synchronized (mDebuggerPorts) {
+                // because there could be case where clients are closed twice, we have to make
+                // sure the port number is not already in the list.
+                if (mDebuggerPorts.indexOf(port) == -1) {
+                    // add the port to the list while keeping it sorted. It's not like there's
+                    // going to be tons of objects so we do it linearly.
+                    int count = mDebuggerPorts.size();
+                    for (int i = 0 ; i < count ; i++) {
+                        if (port < mDebuggerPorts.get(i)) {
+                            mDebuggerPorts.add(i, port);
+                            break;
+                        }
+                    }
+                    // TODO: check if we can compact the end of the list.
+                }
+            }
+        }
+    }
+    
+    /**
+     * Reads the length of the next message from a socket.
+     * @param socket The {@link SocketChannel} to read from.
+     * @return the length, or 0 (zero) if no data is available from the socket.
+     * @throws IOException if the connection failed.
+     */
+    private int readLength(SocketChannel socket, byte[] buffer) throws IOException {
+        String msg = read(socket, buffer);
+
+        if (msg != null) {
+            try {
+                return Integer.parseInt(msg, 16);
+            } catch (NumberFormatException nfe) {
+                // we'll throw an exception below.
+            }
+       }
+
+        // we receive something we can't read. It's better to reset the connection at this point.
+        throw new IOException("Unable to read length");
+    }
+
+    /**
+     * Fills a buffer from a socket.
+     * @param socket
+     * @param buffer
+     * @return the content of the buffer as a string, or null if it failed to convert the buffer.
+     * @throws IOException
+     */
+    private String read(SocketChannel socket, byte[] buffer) throws IOException {
+        ByteBuffer buf = ByteBuffer.wrap(buffer, 0, buffer.length);
+
+        while (buf.position() != buf.limit()) {
+            int count;
+
+            count = socket.read(buf);
+            if (count < 0) {
+                throw new IOException("EOF");
+            }
+        }
+
+        try {
+            return new String(buffer, 0, buf.position(), AdbHelper.DEFAULT_ENCODING);
+        } catch (UnsupportedEncodingException e) {
+            // we'll return null below.
+        }
+
+        return null;
+    }
+
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/EmulatorConsole.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/EmulatorConsole.java
new file mode 100644
index 0000000..f3986ed
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/EmulatorConsole.java
@@ -0,0 +1,751 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+import java.security.InvalidParameterException;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Provides control over emulated hardware of the Android emulator.
+ * <p/>This is basically a wrapper around the command line console normally used with telnet.
+ *<p/>
+ * Regarding line termination handling:<br>
+ * One of the issues is that the telnet protocol <b>requires</b> usage of <code>\r\n</code>. Most
+ * implementations don't enforce it (the dos one does). In this particular case, this is mostly
+ * irrelevant since we don't use telnet in Java, but that means we want to make
+ * sure we use the same line termination than what the console expects. The console
+ * code removes <code>\r</code> and waits for <code>\n</code>.
+ * <p/>However this means you <i>may</i> receive <code>\r\n</code> when reading from the console.
+ * <p/>
+ * <b>This API will change in the near future.</b> 
+ */
+public final class EmulatorConsole {
+
+    private final static String DEFAULT_ENCODING = "ISO-8859-1"; //$NON-NLS-1$
+
+    private final static int WAIT_TIME = 5; // spin-wait sleep, in ms
+
+    private final static int STD_TIMEOUT = 5000; // standard delay, in ms
+
+    private final static String HOST = "127.0.0.1";  //$NON-NLS-1$
+
+    private final static String COMMAND_PING = "help\r\n"; //$NON-NLS-1$
+    private final static String COMMAND_AVD_NAME = "avd name\r\n"; //$NON-NLS-1$
+    private final static String COMMAND_KILL = "kill\r\n"; //$NON-NLS-1$
+    private final static String COMMAND_GSM_STATUS = "gsm status\r\n"; //$NON-NLS-1$
+    private final static String COMMAND_GSM_CALL = "gsm call %1$s\r\n"; //$NON-NLS-1$
+    private final static String COMMAND_GSM_CANCEL_CALL = "gsm cancel %1$s\r\n"; //$NON-NLS-1$
+    private final static String COMMAND_GSM_DATA = "gsm data %1$s\r\n"; //$NON-NLS-1$
+    private final static String COMMAND_GSM_VOICE = "gsm voice %1$s\r\n"; //$NON-NLS-1$
+    private final static String COMMAND_SMS_SEND = "sms send %1$s %2$s\r\n"; //$NON-NLS-1$
+    private final static String COMMAND_NETWORK_STATUS = "network status\r\n"; //$NON-NLS-1$
+    private final static String COMMAND_NETWORK_SPEED = "network speed %1$s\r\n"; //$NON-NLS-1$
+    private final static String COMMAND_NETWORK_LATENCY = "network delay %1$s\r\n"; //$NON-NLS-1$
+    private final static String COMMAND_GPS = 
+        "geo nmea $GPGGA,%1$02d%2$02d%3$02d.%4$03d," + //$NON-NLS-1$
+        "%5$03d%6$09.6f,%7$c,%8$03d%9$09.6f,%10$c," + //$NON-NLS-1$
+        "1,10,0.0,0.0,0,0.0,0,0.0,0000\r\n"; //$NON-NLS-1$
+
+    private final static Pattern RE_KO = Pattern.compile("KO:\\s+(.*)"); //$NON-NLS-1$
+
+    /**
+     * Array of delay values: no delay, gprs, edge/egprs, umts/3d
+     */
+    public final static int[] MIN_LATENCIES = new int[] {
+        0,      // No delay
+        150,    // gprs
+        80,     // edge/egprs
+        35      // umts/3g
+    };
+
+    /**
+     * Array of download speeds: full speed, gsm, hscsd, gprs, edge/egprs, umts/3g, hsdpa.
+     */
+    public final int[] DOWNLOAD_SPEEDS = new int[] {
+        0,          // full speed
+        14400,      // gsm
+        43200,      // hscsd
+        80000,      // gprs
+        236800,     // edge/egprs
+        1920000,    // umts/3g
+        14400000    // hsdpa
+    };
+
+    /** Arrays of valid network speeds */
+    public final static String[] NETWORK_SPEEDS = new String[] {
+        "full", //$NON-NLS-1$
+        "gsm", //$NON-NLS-1$
+        "hscsd", //$NON-NLS-1$
+        "gprs", //$NON-NLS-1$
+        "edge", //$NON-NLS-1$
+        "umts", //$NON-NLS-1$
+        "hsdpa", //$NON-NLS-1$
+    };
+
+    /** Arrays of valid network latencies */
+    public final static String[] NETWORK_LATENCIES = new String[] {
+        "none", //$NON-NLS-1$
+        "gprs", //$NON-NLS-1$
+        "edge", //$NON-NLS-1$
+        "umts", //$NON-NLS-1$
+    };
+
+    /** Gsm Mode enum. */
+    public static enum GsmMode {
+        UNKNOWN((String)null),
+        UNREGISTERED(new String[] { "unregistered", "off" }),
+        HOME(new String[] { "home", "on" }),
+        ROAMING("roaming"),
+        SEARCHING("searching"),
+        DENIED("denied");
+
+        private final String[] tags;
+
+        GsmMode(String tag) {
+            if (tag != null) {
+                this.tags = new String[] { tag };
+            } else {
+                this.tags = new String[0];
+            }
+        }
+
+        GsmMode(String[] tags) {
+            this.tags = tags;
+        }
+
+        public static GsmMode getEnum(String tag) {
+            for (GsmMode mode : values()) {
+                for (String t : mode.tags) {
+                    if (t.equals(tag)) {
+                        return mode;
+                    }
+                }
+            }
+            return UNKNOWN;
+        }
+
+        /**
+         * Returns the first tag of the enum.
+         */
+        public String getTag() {
+            if (tags.length > 0) {
+                return tags[0];
+            }
+            return null;
+        }
+    }
+
+    public final static String RESULT_OK = null;
+
+    private final static Pattern sEmulatorRegexp = Pattern.compile(Device.RE_EMULATOR_SN);
+    private final static Pattern sVoiceStatusRegexp = Pattern.compile(
+            "gsm\\s+voice\\s+state:\\s*([a-z]+)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+    private final static Pattern sDataStatusRegexp = Pattern.compile(
+            "gsm\\s+data\\s+state:\\s*([a-z]+)", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+    private final static Pattern sDownloadSpeedRegexp = Pattern.compile(
+            "\\s+download\\s+speed:\\s+(\\d+)\\s+bits.*", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+    private final static Pattern sMinLatencyRegexp = Pattern.compile(
+            "\\s+minimum\\s+latency:\\s+(\\d+)\\s+ms", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+
+    private final static HashMap<Integer, EmulatorConsole> sEmulators =
+        new HashMap<Integer, EmulatorConsole>();
+
+    /** Gsm Status class */
+    public static class GsmStatus {
+        /** Voice status. */
+        public GsmMode voice = GsmMode.UNKNOWN;
+        /** Data status. */
+        public GsmMode data = GsmMode.UNKNOWN;
+    }
+
+    /** Network Status class */
+    public static class NetworkStatus {
+        /** network speed status. This is an index in the {@link #DOWNLOAD_SPEEDS} array. */
+        public int speed = -1;
+        /** network latency status.  This is an index in the {@link #MIN_LATENCIES} array. */
+        public int latency = -1;
+    }
+
+    private int mPort;
+
+    private SocketChannel mSocketChannel;
+
+    private byte[] mBuffer = new byte[1024];
+
+    /**
+     * Returns an {@link EmulatorConsole} object for the given {@link Device}. This can
+     * be an already existing console, or a new one if it hadn't been created yet.
+     * @param d The device that the console links to.
+     * @return an <code>EmulatorConsole</code> object or <code>null</code> if the connection failed.
+     */
+    public static synchronized EmulatorConsole getConsole(Device d) {
+        // we need to make sure that the device is an emulator
+        Matcher m = sEmulatorRegexp.matcher(d.serialNumber);
+        if (m.matches()) {
+            // get the port number. This is the console port.
+            int port;
+            try {
+                port = Integer.parseInt(m.group(1));
+                if (port <= 0) {
+                    return null;
+                }
+            } catch (NumberFormatException e) {
+                // looks like we failed to get the port number. This is a bit strange since
+                // it's coming from a regexp that only accept digit, but we handle the case
+                // and return null.
+                return null;
+            }
+
+            EmulatorConsole console = sEmulators.get(port);
+
+            if (console != null) {
+                // if the console exist, we ping the emulator to check the connection.
+                if (console.ping() == false) {
+                    RemoveConsole(console.mPort);
+                    console = null;
+                }
+            }
+
+            if (console == null) {
+                // no console object exists for this port so we create one, and start
+                // the connection.
+                console = new EmulatorConsole(port);
+                if (console.start()) {
+                    sEmulators.put(port, console);
+                } else {
+                    console = null;
+                }
+            }
+
+            return console;
+        }
+
+        return null;
+    }
+
+    /**
+     * Removes the console object associated with a port from the map.
+     * @param port The port of the console to remove.
+     */
+    private static synchronized void RemoveConsole(int port) {
+        sEmulators.remove(port);
+    }
+
+    private EmulatorConsole(int port) {
+        super();
+        mPort = port;
+    }
+
+    /**
+     * Starts the connection of the console.
+     * @return true if success.
+     */
+    private boolean start() {
+
+        InetSocketAddress socketAddr;
+        try {
+            InetAddress hostAddr = InetAddress.getByName(HOST);
+            socketAddr = new InetSocketAddress(hostAddr, mPort);
+        } catch (UnknownHostException e) {
+            return false;
+        }
+
+        try {
+            mSocketChannel = SocketChannel.open(socketAddr);
+        } catch (IOException e1) {
+            return false;
+        }
+
+        // read some stuff from it
+        readLines();
+
+        return true;
+    }
+
+    /**
+     * Ping the emulator to check if the connection is still alive.
+     * @return true if the connection is alive.
+     */
+    private synchronized boolean ping() {
+        // it looks like we can send stuff, even when the emulator quit, but we can't read
+        // from the socket. So we check the return of readLines()
+        if (sendCommand(COMMAND_PING)) {
+            return readLines() != null;
+        }
+
+        return false;
+    }
+
+    /**
+     * Sends a KILL command to the emulator.
+     */
+    public synchronized void kill() {
+        if (sendCommand(COMMAND_KILL)) {
+            RemoveConsole(mPort);
+        }
+    }
+    
+    public synchronized String getAvdName() {
+        if (sendCommand(COMMAND_AVD_NAME)) {
+            String[] result = readLines();
+            if (result != null && result.length == 2) { // this should be the name on first line,
+                                                        // and ok on 2nd line
+                return result[0];
+            } else {
+                // try to see if there's a message after KO
+                Matcher m = RE_KO.matcher(result[result.length-1]);
+                if (m.matches()) {
+                    return m.group(1);
+                }
+            }
+        }
+        
+        return null;
+    }
+
+    /**
+     * Get the network status of the emulator.
+     * @return a {@link NetworkStatus} object containing the {@link GsmStatus}, or
+     * <code>null</code> if the query failed.
+     */
+    public synchronized NetworkStatus getNetworkStatus() {
+        if (sendCommand(COMMAND_NETWORK_STATUS)) {
+            /* Result is in the format
+                Current network status:
+                download speed:      14400 bits/s (1.8 KB/s)
+                upload speed:        14400 bits/s (1.8 KB/s)
+                minimum latency:  0 ms
+                maximum latency:  0 ms
+             */
+            String[] result = readLines();
+
+            if (isValid(result)) {
+                // we only compare agains the min latency and the download speed
+                // let's not rely on the order of the output, and simply loop through
+                // the line testing the regexp.
+                NetworkStatus status = new NetworkStatus();
+                for (String line : result) {
+                    Matcher m = sDownloadSpeedRegexp.matcher(line);
+                    if (m.matches()) {
+                        // get the string value
+                        String value = m.group(1);
+
+                        // get the index from the list
+                        status.speed = getSpeedIndex(value);
+
+                        // move on to next line.
+                        continue;
+                    }
+
+                    m = sMinLatencyRegexp.matcher(line);
+                    if (m.matches()) {
+                        // get the string value
+                        String value = m.group(1);
+
+                        // get the index from the list
+                        status.latency = getLatencyIndex(value);
+
+                        // move on to next line.
+                        continue;
+                    }
+                }
+
+                return status;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the current gsm status of the emulator
+     * @return a {@link GsmStatus} object containing the gms status, or <code>null</code>
+     * if the query failed.
+     */
+    public synchronized GsmStatus getGsmStatus() {
+        if (sendCommand(COMMAND_GSM_STATUS)) {
+            /*
+             * result is in the format:
+             * gsm status
+             * gsm voice state: home
+             * gsm data state:  home
+             */
+
+            String[] result = readLines();
+            if (isValid(result)) {
+
+                GsmStatus status = new GsmStatus();
+
+                // let's not rely on the order of the output, and simply loop through
+                // the line testing the regexp.
+                for (String line : result) {
+                    Matcher m = sVoiceStatusRegexp.matcher(line);
+                    if (m.matches()) {
+                        // get the string value
+                        String value = m.group(1);
+
+                        // get the index from the list
+                        status.voice = GsmMode.getEnum(value.toLowerCase());
+
+                        // move on to next line.
+                        continue;
+                    }
+
+                    m = sDataStatusRegexp.matcher(line);
+                    if (m.matches()) {
+                        // get the string value
+                        String value = m.group(1);
+
+                        // get the index from the list
+                        status.data = GsmMode.getEnum(value.toLowerCase());
+
+                        // move on to next line.
+                        continue;
+                    }
+                }
+
+                return status;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Sets the GSM voice mode.
+     * @param mode the {@link GsmMode} value.
+     * @return RESULT_OK if success, an error String otherwise.
+     * @throws InvalidParameterException if mode is an invalid value.
+     */
+    public synchronized String setGsmVoiceMode(GsmMode mode) throws InvalidParameterException {
+        if (mode == GsmMode.UNKNOWN) {
+            throw new InvalidParameterException();
+        }
+
+        String command = String.format(COMMAND_GSM_VOICE, mode.getTag());
+        return processCommand(command);
+    }
+
+    /**
+     * Sets the GSM data mode.
+     * @param mode the {@link GsmMode} value
+     * @return {@link #RESULT_OK} if success, an error String otherwise.
+     * @throws InvalidParameterException if mode is an invalid value.
+     */
+    public synchronized String setGsmDataMode(GsmMode mode) throws InvalidParameterException {
+        if (mode == GsmMode.UNKNOWN) {
+            throw new InvalidParameterException();
+        }
+
+        String command = String.format(COMMAND_GSM_DATA, mode.getTag());
+        return processCommand(command);
+    }
+
+    /**
+     * Initiate an incoming call on the emulator.
+     * @param number a string representing the calling number.
+     * @return {@link #RESULT_OK} if success, an error String otherwise.
+     */
+    public synchronized String call(String number) {
+        String command = String.format(COMMAND_GSM_CALL, number);
+        return processCommand(command);
+    }
+
+    /**
+     * Cancels a current call.
+     * @param number the number of the call to cancel
+     * @return {@link #RESULT_OK} if success, an error String otherwise.
+     */
+    public synchronized String cancelCall(String number) {
+        String command = String.format(COMMAND_GSM_CANCEL_CALL, number);
+        return processCommand(command);
+    }
+
+    /**
+     * Sends an SMS to the emulator
+     * @param number The sender phone number
+     * @param message The SMS message. \ characters must be escaped. The carriage return is
+     * the 2 character sequence  {'\', 'n' }
+     *
+     * @return {@link #RESULT_OK} if success, an error String otherwise.
+     */
+    public synchronized String sendSms(String number, String message) {
+        String command = String.format(COMMAND_SMS_SEND, number, message);
+        return processCommand(command);
+    }
+
+    /**
+     * Sets the network speed.
+     * @param selectionIndex The index in the {@link #NETWORK_SPEEDS} table.
+     * @return {@link #RESULT_OK} if success, an error String otherwise.
+     */
+    public synchronized String setNetworkSpeed(int selectionIndex) {
+        String command = String.format(COMMAND_NETWORK_SPEED, NETWORK_SPEEDS[selectionIndex]);
+        return processCommand(command);
+    }
+
+    /**
+     * Sets the network latency.
+     * @param selectionIndex The index in the {@link #NETWORK_LATENCIES} table.
+     * @return {@link #RESULT_OK} if success, an error String otherwise.
+     */
+    public synchronized String setNetworkLatency(int selectionIndex) {
+        String command = String.format(COMMAND_NETWORK_LATENCY, NETWORK_LATENCIES[selectionIndex]);
+        return processCommand(command);
+    }
+    
+    public synchronized String sendLocation(double longitude, double latitude, double elevation) {
+        
+        Calendar c = Calendar.getInstance();
+        
+        double absLong = Math.abs(longitude);
+        int longDegree = (int)Math.floor(absLong);
+        char longDirection = 'E';
+        if (longitude < 0) {
+            longDirection = 'W';
+        }
+        
+        double longMinute = (absLong - Math.floor(absLong)) * 60;
+
+        double absLat = Math.abs(latitude);
+        int latDegree = (int)Math.floor(absLat);
+        char latDirection = 'N';
+        if (latitude < 0) {
+            latDirection = 'S';
+        }
+        
+        double latMinute = (absLat - Math.floor(absLat)) * 60;
+        
+        String command = String.format(COMMAND_GPS,
+                c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE),
+                c.get(Calendar.SECOND), c.get(Calendar.MILLISECOND),
+                latDegree, latMinute, latDirection,
+                longDegree, longMinute, longDirection);
+        
+        return processCommand(command);
+    }
+
+    /**
+     * Sends a command to the emulator console.
+     * @param command The command string. <b>MUST BE TERMINATED BY \n</b>.
+     * @return true if success
+     */
+    private boolean sendCommand(String command) {
+        boolean result = false;
+        try {
+            byte[] bCommand;
+            try {
+                bCommand = command.getBytes(DEFAULT_ENCODING);
+            } catch (UnsupportedEncodingException e) {
+                // wrong encoding...
+                return result;
+            }
+
+            // write the command
+            AdbHelper.write(mSocketChannel, bCommand, bCommand.length, AdbHelper.STD_TIMEOUT);
+
+            result = true;
+        } catch (IOException e) {
+            return false;
+        } finally {
+            if (result == false) {
+                // FIXME connection failed somehow, we need to disconnect the console.
+                RemoveConsole(mPort);
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Sends a command to the emulator and parses its answer.
+     * @param command the command to send.
+     * @return {@link #RESULT_OK} if success, an error message otherwise.
+     */
+    private String processCommand(String command) {
+        if (sendCommand(command)) {
+            String[] result = readLines();
+
+            if (result != null && result.length > 0) {
+                Matcher m = RE_KO.matcher(result[result.length-1]);
+                if (m.matches()) {
+                    return m.group(1);
+                }
+                return RESULT_OK;
+            }
+
+            return "Unable to communicate with the emulator";
+        }
+
+        return "Unable to send command to the emulator";
+    }
+
+    /**
+     * Reads line from the console socket. This call is blocking until we read the lines:
+     * <ul>
+     * <li>OK\r\n</li>
+     * <li>KO<msg>\r\n</li>
+     * </ul>
+     * @return the array of strings read from the emulator.
+     */
+    private String[] readLines() {
+        try {
+            ByteBuffer buf = ByteBuffer.wrap(mBuffer, 0, mBuffer.length);
+            int numWaits = 0;
+            boolean stop = false;
+            
+            while (buf.position() != buf.limit() && stop == false) {
+                int count;
+
+                count = mSocketChannel.read(buf);
+                if (count < 0) {
+                    return null;
+                } else if (count == 0) {
+                    if (numWaits * WAIT_TIME > STD_TIMEOUT) {
+                        return null;
+                    }
+                    // non-blocking spin
+                    try {
+                        Thread.sleep(WAIT_TIME);
+                    } catch (InterruptedException ie) {
+                    }
+                    numWaits++;
+                } else {
+                    numWaits = 0;
+                }
+
+                // check the last few char aren't OK. For a valid message to test
+                // we need at least 4 bytes (OK/KO + \r\n)
+                if (buf.position() >= 4) {
+                    int pos = buf.position();
+                    if (endsWithOK(pos) || lastLineIsKO(pos)) {
+                        stop = true;
+                    }
+                }
+            }
+
+            String msg = new String(mBuffer, 0, buf.position(), DEFAULT_ENCODING);
+            return msg.split("\r\n"); //$NON-NLS-1$
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Returns true if the 4 characters *before* the current position are "OK\r\n"
+     * @param currentPosition The current position
+     */
+    private boolean endsWithOK(int currentPosition) {
+        if (mBuffer[currentPosition-1] == '\n' &&
+                mBuffer[currentPosition-2] == '\r' &&
+                mBuffer[currentPosition-3] == 'K' &&
+                mBuffer[currentPosition-4] == 'O') {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns true if the last line starts with KO and is also terminated by \r\n
+     * @param currentPosition the current position
+     */
+    private boolean lastLineIsKO(int currentPosition) {
+        // first check that the last 2 characters are CRLF
+        if (mBuffer[currentPosition-1] != '\n' ||
+                mBuffer[currentPosition-2] != '\r') {
+            return false;
+        }
+
+        // now loop backward looking for the previous CRLF, or the beginning of the buffer
+        int i = 0;
+        for (i = currentPosition-3 ; i >= 0; i--) {
+            if (mBuffer[i] == '\n') {
+                // found \n!
+                if (i > 0 && mBuffer[i-1] == '\r') {
+                    // found \r!
+                    break;
+                }
+            }
+        }
+
+        // here it is either -1 if we reached the start of the buffer without finding
+        // a CRLF, or the position of \n. So in both case we look at the characters at i+1 and i+2
+        if (mBuffer[i+1] == 'K' && mBuffer[i+2] == 'O') {
+            // found error!
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns true if the last line of the result does not start with KO
+     */
+    private boolean isValid(String[] result) {
+        if (result != null && result.length > 0) {
+            return !(RE_KO.matcher(result[result.length-1]).matches());
+        }
+        return false;
+    }
+
+    private int getLatencyIndex(String value) {
+        try {
+            // get the int value
+            int latency = Integer.parseInt(value);
+
+            // check for the speed from the index
+            for (int i = 0 ; i < MIN_LATENCIES.length; i++) {
+                if (MIN_LATENCIES[i] == latency) {
+                    return i;
+                }
+            }
+        } catch (NumberFormatException e) {
+            // Do nothing, we'll just return -1.
+        }
+
+        return -1;
+    }
+
+    private int getSpeedIndex(String value) {
+        try {
+            // get the int value
+            int speed = Integer.parseInt(value);
+
+            // check for the speed from the index
+            for (int i = 0 ; i < DOWNLOAD_SPEEDS.length; i++) {
+                if (DOWNLOAD_SPEEDS[i] == speed) {
+                    return i;
+                }
+            }
+        } catch (NumberFormatException e) {
+            // Do nothing, we'll just return -1.
+        }
+
+        return -1;
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/FileListingService.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/FileListingService.java
new file mode 100644
index 0000000..b50cf79
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/FileListingService.java
@@ -0,0 +1,767 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Provides {@link Device} side file listing service.
+ * <p/>To get an instance for a known {@link Device}, call {@link Device#getFileListingService()}.
+ */
+public final class FileListingService {
+
+    /** Pattern to find filenames that match "*.apk" */
+    private final static Pattern sApkPattern =
+        Pattern.compile(".*\\.apk", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
+
+    private final static String PM_FULL_LISTING = "pm list packages -f"; //$NON-NLS-1$
+
+    /** Pattern to parse the output of the 'pm -lf' command.<br>
+     * The output format looks like:<br>
+     * /data/app/myapp.apk=com.mypackage.myapp */
+    private final static Pattern sPmPattern = Pattern.compile("^package:(.+?)=(.+)$"); //$NON-NLS-1$
+
+    /** Top level data folder. */
+    public final static String DIRECTORY_DATA = "data"; //$NON-NLS-1$
+    /** Top level sdcard folder. */
+    public final static String DIRECTORY_SDCARD = "sdcard"; //$NON-NLS-1$
+    /** Top level system folder. */
+    public final static String DIRECTORY_SYSTEM = "system"; //$NON-NLS-1$
+    /** Top level temp folder. */
+    public final static String DIRECTORY_TEMP = "tmp"; //$NON-NLS-1$
+    /** Application folder. */
+    public final static String DIRECTORY_APP = "app"; //$NON-NLS-1$
+
+    private final static String[] sRootLevelApprovedItems = {
+        DIRECTORY_DATA,
+        DIRECTORY_SDCARD,
+        DIRECTORY_SYSTEM,
+        DIRECTORY_TEMP
+    };
+
+    public static final long REFRESH_RATE = 5000L;
+    /**
+     * Refresh test has to be slightly lower for precision issue.
+     */
+    static final long REFRESH_TEST = (long)(REFRESH_RATE * .8);
+
+    /** Entry type: File */
+    public static final int TYPE_FILE = 0;
+    /** Entry type: Directory */
+    public static final int TYPE_DIRECTORY = 1;
+    /** Entry type: Directory Link */
+    public static final int TYPE_DIRECTORY_LINK = 2;
+    /** Entry type: Block */
+    public static final int TYPE_BLOCK = 3;
+    /** Entry type: Character */
+    public static final int TYPE_CHARACTER = 4;
+    /** Entry type: Link */
+    public static final int TYPE_LINK = 5;
+    /** Entry type: Socket */
+    public static final int TYPE_SOCKET = 6;
+    /** Entry type: FIFO */
+    public static final int TYPE_FIFO = 7;
+    /** Entry type: Other */
+    public static final int TYPE_OTHER = 8;
+
+    /** Device side file separator. */
+    public static final String FILE_SEPARATOR = "/"; //$NON-NLS-1$
+
+    private static final String FILE_ROOT = "/"; //$NON-NLS-1$
+
+
+    /**
+     * Regexp pattern to parse the result from ls.
+     */
+    private static Pattern sLsPattern = Pattern.compile(
+        "^([bcdlsp-][-r][-w][-xsS][-r][-w][-xsS][-r][-w][-xstST])\\s+(\\S+)\\s+(\\S+)\\s+([\\d\\s,]*)\\s+(\\d{4}-\\d\\d-\\d\\d)\\s+(\\d\\d:\\d\\d)\\s+(.*)$"); //$NON-NLS-1$
+
+    private Device mDevice;
+    private FileEntry mRoot;
+
+    private ArrayList<Thread> mThreadList = new ArrayList<Thread>();
+
+    /**
+     * Represents an entry in a directory. This can be a file or a directory.
+     */
+    public final static class FileEntry {
+        /** Pattern to escape filenames for shell command consumption. */
+        private final static Pattern sEscapePattern = Pattern.compile(
+                "([\\\\()*+?\"'#/\\s])"); //$NON-NLS-1$
+
+        /**
+         * Comparator object for FileEntry
+         */
+        private static Comparator<FileEntry> sEntryComparator = new Comparator<FileEntry>() {
+            public int compare(FileEntry o1, FileEntry o2) {
+                if (o1 instanceof FileEntry && o2 instanceof FileEntry) {
+                    FileEntry fe1 = (FileEntry)o1;
+                    FileEntry fe2 = (FileEntry)o2;
+                    return fe1.name.compareTo(fe2.name);
+                }
+                return 0;
+            }
+        };
+
+        FileEntry parent;
+        String name;
+        String info;
+        String permissions;
+        String size;
+        String date;
+        String time;
+        String owner;
+        String group;
+        int type;
+        boolean isAppPackage;
+
+        boolean isRoot;
+
+        /**
+         * Indicates whether the entry content has been fetched yet, or not.
+         */
+        long fetchTime = 0;
+
+        final ArrayList<FileEntry> mChildren = new ArrayList<FileEntry>();
+
+        /**
+         * Creates a new file entry.
+         * @param parent parent entry or null if entry is root
+         * @param name name of the entry.
+         * @param type entry type. Can be one of the following: {@link FileListingService#TYPE_FILE},
+         * {@link FileListingService#TYPE_DIRECTORY}, {@link FileListingService#TYPE_OTHER}.
+         */
+        private FileEntry(FileEntry parent, String name, int type, boolean isRoot) {
+            this.parent = parent;
+            this.name = name;
+            this.type = type;
+            this.isRoot = isRoot;
+
+            checkAppPackageStatus();
+        }
+
+        /**
+         * Returns the name of the entry
+         */
+        public String getName() {
+            return name;
+        }
+
+        /**
+         * Returns the size string of the entry, as returned by <code>ls</code>.
+         */
+        public String getSize() {
+            return size;
+        }
+
+        /**
+         * Returns the size of the entry.
+         */
+        public int getSizeValue() {
+            return Integer.parseInt(size);
+        }
+
+        /**
+         * Returns the date string of the entry, as returned by <code>ls</code>.
+         */
+        public String getDate() {
+            return date;
+        }
+
+        /**
+         * Returns the time string of the entry, as returned by <code>ls</code>.
+         */
+        public String getTime() {
+            return time;
+        }
+
+        /**
+         * Returns the permission string of the entry, as returned by <code>ls</code>.
+         */
+        public String getPermissions() {
+            return permissions;
+        }
+
+        /**
+         * Returns the extra info for the entry.
+         * <p/>For a link, it will be a description of the link.
+         * <p/>For an application apk file it will be the application package as returned
+         * by the Package Manager.  
+         */
+        public String getInfo() {
+            return info;
+        }
+
+        /**
+         * Return the full path of the entry.
+         * @return a path string using {@link FileListingService#FILE_SEPARATOR} as separator.
+         */
+        public String getFullPath() {
+            if (isRoot) {
+                return FILE_ROOT;
+            }
+            StringBuilder pathBuilder = new StringBuilder();
+            fillPathBuilder(pathBuilder, false);
+
+            return pathBuilder.toString();
+        }
+
+        /**
+         * Return the fully escaped path of the entry. This path is safe to use in a
+         * shell command line.
+         * @return a path string using {@link FileListingService#FILE_SEPARATOR} as separator
+         */
+        public String getFullEscapedPath() {
+            StringBuilder pathBuilder = new StringBuilder();
+            fillPathBuilder(pathBuilder, true);
+
+            return pathBuilder.toString();
+        }
+
+        /**
+         * Returns the path as a list of segments.
+         */
+        public String[] getPathSegments() {
+            ArrayList<String> list = new ArrayList<String>();
+            fillPathSegments(list);
+
+            return list.toArray(new String[list.size()]);
+        }
+
+        /**
+         * Returns true if the entry is a directory, false otherwise;
+         */
+        public int getType() {
+            return type;
+        }
+
+        /**
+         * Returns if the entry is a folder or a link to a folder.
+         */
+        public boolean isDirectory() {
+            return type == TYPE_DIRECTORY || type == TYPE_DIRECTORY_LINK;
+        }
+
+        /**
+         * Returns the parent entry.
+         */
+        public FileEntry getParent() {
+            return parent;
+        }
+
+        /**
+         * Returns the cached children of the entry. This returns the cache created from calling
+         * <code>FileListingService.getChildren()</code>.
+         */
+        public FileEntry[] getCachedChildren() {
+            return mChildren.toArray(new FileEntry[mChildren.size()]);
+        }
+
+        /**
+         * Returns the child {@link FileEntry} matching the name.
+         * This uses the cached children list.
+         * @param name the name of the child to return.
+         * @return the FileEntry matching the name or null.
+         */
+        public FileEntry findChild(String name) {
+            for (FileEntry entry : mChildren) {
+                if (entry.name.equals(name)) {
+                    return entry;
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Returns whether the entry is the root.
+         */
+        public boolean isRoot() {
+            return isRoot;
+        }
+
+        void addChild(FileEntry child) {
+            mChildren.add(child);
+        }
+
+        void setChildren(ArrayList<FileEntry> newChildren) {
+            mChildren.clear();
+            mChildren.addAll(newChildren);
+        }
+
+        boolean needFetch() {
+            if (fetchTime == 0) {
+                return true;
+            }
+            long current = System.currentTimeMillis();
+            if (current-fetchTime > REFRESH_TEST) {
+                return true;
+            }
+
+            return false;
+        }
+
+        /**
+         * Returns if the entry is a valid application package.
+         */
+        public boolean isApplicationPackage() {
+            return isAppPackage;
+        }
+
+        /**
+         * Returns if the file name is an application package name.
+         */
+        public boolean isAppFileName() {
+            Matcher m = sApkPattern.matcher(name);
+            return m.matches();
+        }
+
+        /**
+         * Recursively fills the pathBuilder with the full path
+         * @param pathBuilder a StringBuilder used to create the path.
+         * @param escapePath Whether the path need to be escaped for consumption by
+         * a shell command line.
+         */
+        protected void fillPathBuilder(StringBuilder pathBuilder, boolean escapePath) {
+            if (isRoot) {
+                return;
+            }
+
+            if (parent != null) {
+                parent.fillPathBuilder(pathBuilder, escapePath);
+            }
+            pathBuilder.append(FILE_SEPARATOR);
+            pathBuilder.append(escapePath ? escape(name) : name);
+        }
+
+        /**
+         * Recursively fills the segment list with the full path.
+         * @param list The list of segments to fill.
+         */
+        protected void fillPathSegments(ArrayList<String> list) {
+            if (isRoot) {
+                return;
+            }
+
+            if (parent != null) {
+                parent.fillPathSegments(list);
+            }
+
+            list.add(name);
+        }
+
+        /**
+         * Sets the internal app package status flag. This checks whether the entry is in an app
+         * directory like /data/app or /system/app
+         */
+        private void checkAppPackageStatus() {
+            isAppPackage = false;
+
+            String[] segments = getPathSegments();
+            if (type == TYPE_FILE && segments.length == 3 && isAppFileName()) {
+                isAppPackage = DIRECTORY_APP.equals(segments[1]) &&
+                    (DIRECTORY_SYSTEM.equals(segments[0]) || DIRECTORY_DATA.equals(segments[0]));
+            }
+        }
+
+        /**
+         * Returns an escaped version of the entry name.
+         * @param entryName
+         */
+        private String escape(String entryName) {
+            return sEscapePattern.matcher(entryName).replaceAll("\\\\$1"); //$NON-NLS-1$
+        }
+    }
+
+    private class LsReceiver extends MultiLineReceiver {
+
+        private ArrayList<FileEntry> mEntryList;
+        private ArrayList<String> mLinkList;
+        private FileEntry[] mCurrentChildren;
+        private FileEntry mParentEntry;
+
+        /**
+         * Create an ls receiver/parser.
+         * @param currentChildren The list of current children. To prevent
+         *      collapse during update, reusing the same FileEntry objects for
+         *      files that were already there is paramount.
+         * @param entryList the list of new children to be filled by the
+         *      receiver.
+         * @param linkList the list of link path to compute post ls, to figure
+         *      out if the link pointed to a file or to a directory.
+         */
+        public LsReceiver(FileEntry parentEntry, ArrayList<FileEntry> entryList,
+                ArrayList<String> linkList) {
+            mParentEntry = parentEntry;
+            mCurrentChildren = parentEntry.getCachedChildren();
+            mEntryList = entryList;
+            mLinkList = linkList;
+        }
+
+        @Override
+        public void processNewLines(String[] lines) {
+            for (String line : lines) {
+                // no need to handle empty lines.
+                if (line.length() == 0) {
+                    continue;
+                }
+
+                // run the line through the regexp
+                Matcher m = sLsPattern.matcher(line);
+                if (m.matches() == false) {
+                    continue;
+                }
+
+                // get the name
+                String name = m.group(7);
+
+                // if the parent is root, we only accept selected items
+                if (mParentEntry.isRoot()) {
+                    boolean found = false;
+                    for (String approved : sRootLevelApprovedItems) {
+                        if (approved.equals(name)) {
+                            found = true;
+                            break;
+                        }
+                    }
+
+                    // if it's not in the approved list we skip this entry.
+                    if (found == false) {
+                        continue;
+                    }
+                }
+
+                // get the rest of the groups
+                String permissions = m.group(1);
+                String owner = m.group(2);
+                String group = m.group(3);
+                String size = m.group(4);
+                String date = m.group(5);
+                String time = m.group(6);
+                String info = null;
+
+                // and the type
+                int objectType = TYPE_OTHER;
+                switch (permissions.charAt(0)) {
+                    case '-' :
+                        objectType = TYPE_FILE;
+                        break;
+                    case 'b' :
+                        objectType = TYPE_BLOCK;
+                        break;
+                    case 'c' :
+                        objectType = TYPE_CHARACTER;
+                        break;
+                    case 'd' :
+                        objectType = TYPE_DIRECTORY;
+                        break;
+                    case 'l' :
+                        objectType = TYPE_LINK;
+                        break;
+                    case 's' :
+                        objectType = TYPE_SOCKET;
+                        break;
+                    case 'p' :
+                        objectType = TYPE_FIFO;
+                        break;
+                }
+
+
+                // now check what we may be linking to
+                if (objectType == TYPE_LINK) {
+                    String[] segments = name.split("\\s->\\s"); //$NON-NLS-1$
+
+                    // we should have 2 segments
+                    if (segments.length == 2) {
+                        // update the entry name to not contain the link
+                        name = segments[0];
+
+                        // and the link name
+                        info = segments[1];
+
+                        // now get the path to the link
+                        String[] pathSegments = info.split(FILE_SEPARATOR);
+                        if (pathSegments.length == 1) {
+                            // the link is to something in the same directory,
+                            // unless the link is ..
+                            if ("..".equals(pathSegments[0])) { //$NON-NLS-1$
+                                // set the type and we're done.
+                                objectType = TYPE_DIRECTORY_LINK;
+                            } else {
+                                // either we found the object already
+                                // or we'll find it later.
+                            }
+                        }
+                    }
+
+                    // add an arrow in front to specify it's a link.
+                    info = "-> " + info; //$NON-NLS-1$;
+                }
+
+                // get the entry, either from an existing one, or a new one
+                FileEntry entry = getExistingEntry(name);
+                if (entry == null) {
+                    entry = new FileEntry(mParentEntry, name, objectType, false /* isRoot */);
+                }
+
+                // add some misc info
+                entry.permissions = permissions;
+                entry.size = size;
+                entry.date = date;
+                entry.time = time;
+                entry.owner = owner;
+                entry.group = group;
+                if (objectType == TYPE_LINK) {
+                    entry.info = info;
+                }
+
+                mEntryList.add(entry);
+            }
+        }
+
+        /**
+         * Queries for an already existing Entry per name
+         * @param name the name of the entry
+         * @return the existing FileEntry or null if no entry with a matching
+         * name exists.
+         */
+        private FileEntry getExistingEntry(String name) {
+            for (int i = 0 ; i < mCurrentChildren.length; i++) {
+                FileEntry e = mCurrentChildren[i];
+
+                // since we're going to "erase" the one we use, we need to
+                // check that the item is not null.
+                if (e != null) {
+                    // compare per name, case-sensitive.
+                    if (name.equals(e.name)) {
+                        // erase from the list
+                        mCurrentChildren[i] = null;
+
+                        // and return the object
+                        return e;
+                    }
+                }
+            }
+
+            // couldn't find any matching object, return null
+            return null;
+        }
+
+        public boolean isCancelled() {
+            return false;
+        }
+
+        public void finishLinks() {
+            // TODO Handle links in the listing service
+        }
+    }
+
+    /**
+     * Classes which implement this interface provide a method that deals with asynchronous
+     * result from <code>ls</code> command on the device.
+     *
+     * @see FileListingService#getChildren(com.android.ddmlib.FileListingService.FileEntry, boolean, com.android.ddmlib.FileListingService.IListingReceiver)
+     */
+    public interface IListingReceiver {
+        public void setChildren(FileEntry entry, FileEntry[] children);
+
+        public void refreshEntry(FileEntry entry);
+    }
+
+    /**
+     * Creates a File Listing Service for a specified {@link Device}.
+     * @param device The Device the service is connected to.
+     */
+    FileListingService(Device device) {
+        mDevice = device;
+    }
+
+    /**
+     * Returns the root element.
+     * @return the {@link FileEntry} object representing the root element or
+     * <code>null</code> if the device is invalid.
+     */
+    public FileEntry getRoot() {
+        if (mDevice != null) {
+            if (mRoot == null) {
+                mRoot = new FileEntry(null /* parent */, "" /* name */, TYPE_DIRECTORY,
+                        true /* isRoot */);
+            }
+
+            return mRoot;
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the children of a {@link FileEntry}.
+     * <p/>
+     * This method supports a cache mechanism and synchronous and asynchronous modes.
+     * <p/>
+     * If <var>receiver</var> is <code>null</code>, the device side <code>ls</code>
+     * command is done synchronously, and the method will return upon completion of the command.<br>
+     * If <var>receiver</var> is non <code>null</code>, the command is launched is a separate
+     * thread and upon completion, the receiver will be notified of the result.
+     * <p/>
+     * The result for each <code>ls</code> command is cached in the parent
+     * <code>FileEntry</code>. <var>useCache</var> allows usage of this cache, but only if the
+     * cache is valid. The cache is valid only for {@link FileListingService#REFRESH_RATE} ms.
+     * After that a new <code>ls</code> command is always executed.
+     * <p/>
+     * If the cache is valid and <code>useCache == true</code>, the method will always simply
+     * return the value of the cache, whether a {@link IListingReceiver} has been provided or not.
+     *
+     * @param entry The parent entry.
+     * @param useCache A flag to use the cache or to force a new ls command.
+     * @param receiver A receiver for asynchronous calls.
+     * @return The list of children or <code>null</code> for asynchronous calls.
+     *
+     * @see FileEntry#getCachedChildren()
+     */
+    public FileEntry[] getChildren(final FileEntry entry, boolean useCache,
+            final IListingReceiver receiver) {
+        // first thing we do is check the cache, and if we already have a recent
+        // enough children list, we just return that.
+        if (useCache && entry.needFetch() == false) {
+            return entry.getCachedChildren();
+        }
+
+        // if there's no receiver, then this is a synchronous call, and we
+        // return the result of ls
+        if (receiver == null) {
+            doLs(entry);
+            return entry.getCachedChildren();
+        }
+
+        // this is a asynchronous call.
+        // we launch a thread that will do ls and give the listing
+        // to the receiver
+        Thread t = new Thread("ls " + entry.getFullPath()) { //$NON-NLS-1$
+            @Override
+            public void run() {
+                doLs(entry);
+
+                receiver.setChildren(entry, entry.getCachedChildren());
+
+                final FileEntry[] children = entry.getCachedChildren();
+                if (children.length > 0 && children[0].isApplicationPackage()) {
+                    final HashMap<String, FileEntry> map = new HashMap<String, FileEntry>();
+
+                    for (FileEntry child : children) {
+                        String path = child.getFullPath();
+                        map.put(path, child);
+                    }
+
+                    // call pm.
+                    String command = PM_FULL_LISTING;
+                    try {
+                        mDevice.executeShellCommand(command, new MultiLineReceiver() {
+                            @Override
+                            public void processNewLines(String[] lines) {
+                                for (String line : lines) {
+                                    if (line.length() > 0) {
+                                        // get the filepath and package from the line
+                                        Matcher m = sPmPattern.matcher(line);
+                                        if (m.matches()) {
+                                            // get the children with that path
+                                            FileEntry entry = map.get(m.group(1));
+                                            if (entry != null) {
+                                                entry.info = m.group(2);
+                                                receiver.refreshEntry(entry);
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                            public boolean isCancelled() {
+                                return false;
+                            }
+                        });
+                    } catch (IOException e) {
+                        // adb failed somehow, we do nothing.
+                    }
+                }
+
+
+                // if another thread is pending, launch it
+                synchronized (mThreadList) {
+                    // first remove ourselves from the list
+                    mThreadList.remove(this);
+
+                    // then launch the next one if applicable.
+                    if (mThreadList.size() > 0) {
+                        Thread t = mThreadList.get(0);
+                        t.start();
+                    }
+                }
+            }
+        };
+
+        // we don't want to run multiple ls on the device at the same time, so we
+        // store the thread in a list and launch it only if there's no other thread running.
+        // the thread will launch the next one once it's done.
+        synchronized (mThreadList) {
+            // add to the list
+            mThreadList.add(t);
+
+            // if it's the only one, launch it.
+            if (mThreadList.size() == 1) {
+                t.start();
+            }
+        }
+
+        // and we return null.
+        return null;
+    }
+
+    private void doLs(FileEntry entry) {
+        // create a list that will receive the list of the entries
+        ArrayList<FileEntry> entryList = new ArrayList<FileEntry>();
+
+        // create a list that will receive the link to compute post ls;
+        ArrayList<String> linkList = new ArrayList<String>();
+
+        try {
+            // create the command
+            String command = "ls -l " + entry.getFullPath(); //$NON-NLS-1$
+
+            // create the receiver object that will parse the result from ls
+            LsReceiver receiver = new LsReceiver(entry, entryList, linkList);
+
+            // call ls.
+            mDevice.executeShellCommand(command, receiver);
+
+            // finish the process of the receiver to handle links
+            receiver.finishLinks();
+        } catch (IOException e) {
+        }
+
+
+        // at this point we need to refresh the viewer
+        entry.fetchTime = System.currentTimeMillis();
+
+        // sort the children and set them as the new children
+        Collections.sort(entryList, FileEntry.sEntryComparator);
+        entry.setChildren(entryList);
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/GetPropReceiver.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/GetPropReceiver.java
new file mode 100644
index 0000000..9293379
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/GetPropReceiver.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A receiver able to parse the result of the execution of 
+ * {@link #GETPROP_COMMAND} on a device.
+ */
+final class GetPropReceiver extends MultiLineReceiver {
+    final static String GETPROP_COMMAND = "getprop"; //$NON-NLS-1$
+    
+    private final static Pattern GETPROP_PATTERN = Pattern.compile("^\\[([^]]+)\\]\\:\\s*\\[(.*)\\]$"); //$NON-NLS-1$
+
+    /** indicates if we need to read the first */
+    private Device mDevice = null;
+
+    /**
+     * Creates the receiver with the device the receiver will modify.
+     * @param device The device to modify
+     */
+    public GetPropReceiver(Device device) {
+        mDevice = device;
+    }
+
+    @Override
+    public void processNewLines(String[] lines) {
+        // We receive an array of lines. We're expecting
+        // to have the build info in the first line, and the build
+        // date in the 2nd line. There seems to be an empty line
+        // after all that.
+
+        for (String line : lines) {
+            if (line.length() == 0 || line.startsWith("#")) {
+                continue;
+            }
+            
+            Matcher m = GETPROP_PATTERN.matcher(line);
+            if (m.matches()) {
+                String label = m.group(1);
+                String value = m.group(2);
+                
+                if (label.length() > 0) {
+                    mDevice.addProperty(label, value);
+                }
+            }
+        }
+    }
+    
+    public boolean isCancelled() {
+        return false;
+    }
+    
+    @Override
+    public void done() {
+        mDevice.update(Device.CHANGE_BUILD_INFO);
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleAppName.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleAppName.java
new file mode 100644
index 0000000..99bd4d0
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleAppName.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Handle the "app name" chunk (APNM).
+ */
+final class HandleAppName extends ChunkHandler {
+
+    public static final int CHUNK_APNM = ChunkHandler.type("APNM");
+
+    private static final HandleAppName mInst = new HandleAppName();
+
+
+    private HandleAppName() {}
+
+    /**
+     * Register for the packets we expect to get from the client.
+     */
+    public static void register(MonitorThread mt) {
+        mt.registerChunkHandler(CHUNK_APNM, mInst);
+    }
+
+    /**
+     * Client is ready.
+     */
+    @Override
+    public void clientReady(Client client) throws IOException {}
+
+    /**
+     * Client went away.
+     */
+    @Override
+    public void clientDisconnected(Client client) {}
+
+    /**
+     * Chunk handler entry point.
+     */
+    @Override
+    public void handleChunk(Client client, int type, ByteBuffer data,
+            boolean isReply, int msgId) {
+
+        Log.d("ddm-appname", "handling " + ChunkHandler.name(type));
+
+        if (type == CHUNK_APNM) {
+            assert !isReply;
+            handleAPNM(client, data);
+        } else {
+            handleUnknownChunk(client, type, data, isReply, msgId);
+        }
+    }
+
+    /*
+     * Handle a reply to our APNM message.
+     */
+    private static void handleAPNM(Client client, ByteBuffer data) {
+        int appNameLen;
+        String appName;
+
+        appNameLen = data.getInt();
+        appName = getString(data, appNameLen);
+
+        Log.i("ddm-appname", "APNM: app='" + appName + "'");
+
+        ClientData cd = client.getClientData();
+        synchronized (cd) {
+            cd.setClientDescription(appName);
+        }
+
+        client = checkDebuggerPortForAppName(client, appName);
+
+        if (client != null) {
+            client.update(Client.CHANGE_NAME);
+        }
+    }
+ }
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleExit.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleExit.java
new file mode 100644
index 0000000..adeedbb
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleExit.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Submit an exit request.
+ */
+final class HandleExit extends ChunkHandler {
+
+    public static final int CHUNK_EXIT = type("EXIT");
+
+    private static final HandleExit mInst = new HandleExit();
+
+
+    private HandleExit() {}
+
+    /**
+     * Register for the packets we expect to get from the client.
+     */
+    public static void register(MonitorThread mt) {}
+
+    /**
+     * Client is ready.
+     */
+    @Override
+    public void clientReady(Client client) throws IOException {}
+
+    /**
+     * Client went away.
+     */
+    @Override
+    public void clientDisconnected(Client client) {}
+
+    /**
+     * Chunk handler entry point.
+     */
+    @Override
+    public void handleChunk(Client client, int type, ByteBuffer data, boolean isReply, int msgId) {
+        handleUnknownChunk(client, type, data, isReply, msgId);
+    }
+
+    /**
+     * Send an EXIT request to the client.
+     */
+    public static void sendEXIT(Client client, int status)
+        throws IOException
+    {
+        ByteBuffer rawBuf = allocBuffer(4);
+        JdwpPacket packet = new JdwpPacket(rawBuf);
+        ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+        buf.putInt(status);
+
+        finishChunkPacket(packet, CHUNK_EXIT, buf.position());
+        Log.d("ddm-exit", "Sending " + name(CHUNK_EXIT) + ": " + status);
+        client.sendAndConsume(packet, mInst);
+    }
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHeap.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHeap.java
new file mode 100644
index 0000000..5752b86
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHeap.java
@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * Handle heap status updates.
+ */
+final class HandleHeap extends ChunkHandler {
+
+    public static final int CHUNK_HPIF = type("HPIF");
+    public static final int CHUNK_HPST = type("HPST");
+    public static final int CHUNK_HPEN = type("HPEN");
+    public static final int CHUNK_HPSG = type("HPSG");
+    public static final int CHUNK_HPGC = type("HPGC");
+    public static final int CHUNK_REAE = type("REAE");
+    public static final int CHUNK_REAQ = type("REAQ");
+    public static final int CHUNK_REAL = type("REAL");
+
+    // args to sendHPSG
+    public static final int WHEN_DISABLE = 0;
+    public static final int WHEN_GC = 1;
+    public static final int WHAT_MERGE = 0; // merge adjacent objects
+    public static final int WHAT_OBJ = 1;   // keep objects distinct
+
+    // args to sendHPIF
+    public static final int HPIF_WHEN_NEVER = 0;
+    public static final int HPIF_WHEN_NOW = 1;
+    public static final int HPIF_WHEN_NEXT_GC = 2;
+    public static final int HPIF_WHEN_EVERY_GC = 3;
+
+    private static final HandleHeap mInst = new HandleHeap();
+
+    private HandleHeap() {}
+
+    /**
+     * Register for the packets we expect to get from the client.
+     */
+    public static void register(MonitorThread mt) {
+        mt.registerChunkHandler(CHUNK_HPIF, mInst);
+        mt.registerChunkHandler(CHUNK_HPST, mInst);
+        mt.registerChunkHandler(CHUNK_HPEN, mInst);
+        mt.registerChunkHandler(CHUNK_HPSG, mInst);
+        mt.registerChunkHandler(CHUNK_REAQ, mInst);
+        mt.registerChunkHandler(CHUNK_REAL, mInst);
+    }
+
+    /**
+     * Client is ready.
+     */
+    @Override
+    public void clientReady(Client client) throws IOException {
+        if (client.isHeapUpdateEnabled()) {
+            //sendHPSG(client, WHEN_GC, WHAT_MERGE);
+            sendHPIF(client, HPIF_WHEN_EVERY_GC);
+        }
+    }
+
+    /**
+     * Client went away.
+     */
+    @Override
+    public void clientDisconnected(Client client) {}
+
+    /**
+     * Chunk handler entry point.
+     */
+    @Override
+    public void handleChunk(Client client, int type, ByteBuffer data, boolean isReply, int msgId) {
+        Log.d("ddm-heap", "handling " + ChunkHandler.name(type));
+
+        if (type == CHUNK_HPIF) {
+            handleHPIF(client, data);
+            client.update(Client.CHANGE_HEAP_DATA);
+        } else if (type == CHUNK_HPST) {
+            handleHPST(client, data);
+        } else if (type == CHUNK_HPEN) {
+            handleHPEN(client, data);
+            client.update(Client.CHANGE_HEAP_DATA);
+        } else if (type == CHUNK_HPSG) {
+            handleHPSG(client, data);
+        } else if (type == CHUNK_REAQ) {
+            handleREAQ(client, data);
+            client.update(Client.CHANGE_HEAP_ALLOCATION_STATUS);
+        } else if (type == CHUNK_REAL) {
+            handleREAL(client, data);
+            client.update(Client.CHANGE_HEAP_ALLOCATIONS);
+        } else {
+            handleUnknownChunk(client, type, data, isReply, msgId);
+        }
+    }
+
+    /*
+     * Handle a heap info message.
+     */
+    private void handleHPIF(Client client, ByteBuffer data) {
+        Log.d("ddm-heap", "HPIF!");
+        try {
+            int numHeaps = data.getInt();
+
+            for (int i = 0; i < numHeaps; i++) {
+                int heapId = data.getInt();
+                @SuppressWarnings("unused")
+                long timeStamp = data.getLong();
+                @SuppressWarnings("unused")
+                byte reason = data.get();
+                long maxHeapSize = (long)data.getInt() & 0x00ffffffff;
+                long heapSize = (long)data.getInt() & 0x00ffffffff;
+                long bytesAllocated = (long)data.getInt() & 0x00ffffffff;
+                long objectsAllocated = (long)data.getInt() & 0x00ffffffff;
+
+                client.getClientData().setHeapInfo(heapId, maxHeapSize,
+                        heapSize, bytesAllocated, objectsAllocated);
+            }
+        } catch (BufferUnderflowException ex) {
+            Log.w("ddm-heap", "malformed HPIF chunk from client");
+        }
+    }
+
+    /**
+     * Send an HPIF (HeaP InFo) request to the client.
+     */
+    public static void sendHPIF(Client client, int when) throws IOException {
+        ByteBuffer rawBuf = allocBuffer(1);
+        JdwpPacket packet = new JdwpPacket(rawBuf);
+        ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+        buf.put((byte)when);
+
+        finishChunkPacket(packet, CHUNK_HPIF, buf.position());
+        Log.d("ddm-heap", "Sending " + name(CHUNK_HPIF) + ": when=" + when);
+        client.sendAndConsume(packet, mInst);
+    }
+
+    /*
+     * Handle a heap segment series start message.
+     */
+    private void handleHPST(Client client, ByteBuffer data) {
+        /* Clear out any data that's sitting around to
+         * get ready for the chunks that are about to come.
+         */
+//xxx todo: only clear data that belongs to the heap mentioned in <data>.
+        client.getClientData().getVmHeapData().clearHeapData();
+    }
+
+    /*
+     * Handle a heap segment series end message.
+     */
+    private void handleHPEN(Client client, ByteBuffer data) {
+        /* Let the UI know that we've received all of the
+         * data for this heap.
+         */
+//xxx todo: only seal data that belongs to the heap mentioned in <data>.
+        client.getClientData().getVmHeapData().sealHeapData();
+    }
+
+    /*
+     * Handle a heap segment message.
+     */
+    private void handleHPSG(Client client, ByteBuffer data) {
+        byte dataCopy[] = new byte[data.limit()];
+        data.rewind();
+        data.get(dataCopy);
+        data = ByteBuffer.wrap(dataCopy);
+        client.getClientData().getVmHeapData().addHeapData(data);
+//xxx todo: add to the heap mentioned in <data>
+    }
+
+    /**
+     * Sends an HPSG (HeaP SeGment) request to the client.
+     */
+    public static void sendHPSG(Client client, int when, int what)
+        throws IOException {
+
+        ByteBuffer rawBuf = allocBuffer(2);
+        JdwpPacket packet = new JdwpPacket(rawBuf);
+        ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+        buf.put((byte)when);
+        buf.put((byte)what);
+
+        finishChunkPacket(packet, CHUNK_HPSG, buf.position());
+        Log.d("ddm-heap", "Sending " + name(CHUNK_HPSG) + ": when="
+            + when + ", what=" + what);
+        client.sendAndConsume(packet, mInst);
+    }
+
+    /**
+     * Sends an HPGC request to the client.
+     */
+    public static void sendHPGC(Client client)
+        throws IOException {
+        ByteBuffer rawBuf = allocBuffer(0);
+        JdwpPacket packet = new JdwpPacket(rawBuf);
+        ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+        // no data
+
+        finishChunkPacket(packet, CHUNK_HPGC, buf.position());
+        Log.d("ddm-heap", "Sending " + name(CHUNK_HPGC));
+        client.sendAndConsume(packet, mInst);
+    }
+
+    /**
+     * Sends a REAE (REcent Allocation Enable) request to the client.
+     */
+    public static void sendREAE(Client client, boolean enable)
+        throws IOException {
+        ByteBuffer rawBuf = allocBuffer(1);
+        JdwpPacket packet = new JdwpPacket(rawBuf);
+        ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+        buf.put((byte) (enable ? 1 : 0));
+
+        finishChunkPacket(packet, CHUNK_REAE, buf.position());
+        Log.d("ddm-heap", "Sending " + name(CHUNK_REAE) + ": " + enable);
+        client.sendAndConsume(packet, mInst);
+    }
+
+    /**
+     * Sends a REAQ (REcent Allocation Query) request to the client.
+     */
+    public static void sendREAQ(Client client)
+        throws IOException {
+        ByteBuffer rawBuf = allocBuffer(0);
+        JdwpPacket packet = new JdwpPacket(rawBuf);
+        ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+        // no data
+
+        finishChunkPacket(packet, CHUNK_REAQ, buf.position());
+        Log.d("ddm-heap", "Sending " + name(CHUNK_REAQ));
+        client.sendAndConsume(packet, mInst);
+    }
+
+    /**
+     * Sends a REAL (REcent ALlocation) request to the client.
+     */
+    public static void sendREAL(Client client)
+        throws IOException {
+        ByteBuffer rawBuf = allocBuffer(0);
+        JdwpPacket packet = new JdwpPacket(rawBuf);
+        ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+        // no data
+
+        finishChunkPacket(packet, CHUNK_REAL, buf.position());
+        Log.d("ddm-heap", "Sending " + name(CHUNK_REAL));
+        client.sendAndConsume(packet, mInst);
+    }
+
+    /*
+     * Handle the response from our REcent Allocation Query message.
+     */
+    private void handleREAQ(Client client, ByteBuffer data) {
+        boolean enabled;
+
+        enabled = (data.get() != 0);
+        Log.d("ddm-heap", "REAQ says: enabled=" + enabled);
+        
+        client.getClientData().setAllocationStatus(enabled);
+    }
+
+    /**
+     * Converts a VM class descriptor string ("Landroid/os/Debug;") to
+     * a dot-notation class name ("android.os.Debug").
+     */
+    private String descriptorToDot(String str) {
+        // count the number of arrays.
+        int array = 0;
+        while (str.startsWith("[")) {
+            str = str.substring(1);
+            array++;
+        }
+
+        int len = str.length();
+
+        /* strip off leading 'L' and trailing ';' if appropriate */
+        if (len >= 2 && str.charAt(0) == 'L' && str.charAt(len - 1) == ';') {
+            str = str.substring(1, len-1);
+            str = str.replace('/', '.');
+        } else {
+            // convert the basic types
+            if ("C".equals(str)) {
+                str = "char";
+            } else if ("B".equals(str)) {
+                str = "byte";
+            } else if ("Z".equals(str)) {
+                str = "boolean";
+            } else if ("S".equals(str)) {
+                str = "short";
+            } else if ("I".equals(str)) {
+                str = "int";
+            } else if ("J".equals(str)) {
+                str = "long";
+            } else if ("F".equals(str)) {
+                str = "float";
+            } else if ("D".equals(str)) {
+                str = "double";
+            }
+        }
+        
+        // now add the array part
+        for (int a = 0 ; a < array; a++) {
+            str = str + "[]";
+        }
+
+        return str;
+    }
+
+    /**
+     * Reads a string table out of "data".
+     *
+     * This is just a serial collection of strings, each of which is a
+     * four-byte length followed by UTF-16 data.
+     */
+    private void readStringTable(ByteBuffer data, String[] strings) {
+        int count = strings.length;
+        int i;
+
+        for (i = 0; i < count; i++) {
+            int nameLen = data.getInt();
+            String descriptor = getString(data, nameLen);
+            strings[i] = descriptorToDot(descriptor);
+        }
+    }
+
+    /*
+     * Handle a REcent ALlocation response.
+     *
+     * Message header (all values big-endian):
+     *   (1b) message header len (to allow future expansion); includes itself
+     *   (1b) entry header len
+     *   (1b) stack frame len
+     *   (2b) number of entries
+     *   (4b) offset to string table from start of message
+     *   (2b) number of class name strings
+     *   (2b) number of method name strings
+     *   (2b) number of source file name strings
+     *   For each entry:
+     *     (4b) total allocation size
+     *     (2b) threadId
+     *     (2b) allocated object's class name index
+     *     (1b) stack depth
+     *     For each stack frame:
+     *       (2b) method's class name
+     *       (2b) method name
+     *       (2b) method source file
+     *       (2b) line number, clipped to 32767; -2 if native; -1 if no source
+     *   (xb) class name strings
+     *   (xb) method name strings
+     *   (xb) source file strings
+     * 
+     *   As with other DDM traffic, strings are sent as a 4-byte length
+     *   followed by UTF-16 data.
+     */
+    private void handleREAL(Client client, ByteBuffer data) {
+        Log.e("ddm-heap", "*** Received " + name(CHUNK_REAL));
+        int messageHdrLen, entryHdrLen, stackFrameLen;
+        int numEntries, offsetToStrings;
+        int numClassNames, numMethodNames, numFileNames;
+
+        /*
+         * Read the header.
+         */
+        messageHdrLen = (data.get() & 0xff);
+        entryHdrLen = (data.get() & 0xff);
+        stackFrameLen = (data.get() & 0xff);
+        numEntries = (data.getShort() & 0xffff);
+        offsetToStrings = data.getInt();
+        numClassNames = (data.getShort() & 0xffff);
+        numMethodNames = (data.getShort() & 0xffff);
+        numFileNames = (data.getShort() & 0xffff);
+
+
+        /*
+         * Skip forward to the strings and read them.
+         */
+        data.position(offsetToStrings);
+
+        String[] classNames = new String[numClassNames];
+        String[] methodNames = new String[numMethodNames];
+        String[] fileNames = new String[numFileNames];
+
+        readStringTable(data, classNames);
+        readStringTable(data, methodNames);
+        //System.out.println("METHODS: "
+        //    + java.util.Arrays.deepToString(methodNames));
+        readStringTable(data, fileNames);
+
+        /*
+         * Skip back to a point just past the header and start reading
+         * entries.
+         */
+        data.position(messageHdrLen);
+
+        ArrayList<AllocationInfo> list = new ArrayList<AllocationInfo>(numEntries);
+        for (int i = 0; i < numEntries; i++) {
+            int totalSize;
+            int threadId, classNameIndex, stackDepth;
+
+            totalSize = data.getInt();
+            threadId = (data.getShort() & 0xffff);
+            classNameIndex = (data.getShort() & 0xffff);
+            stackDepth = (data.get() & 0xff);
+            /* we've consumed 9 bytes; gobble up any extra */
+            for (int skip = 9; skip < entryHdrLen; skip++)
+                data.get();
+
+            StackTraceElement[] steArray = new StackTraceElement[stackDepth];
+
+            /*
+             * Pull out the stack trace.
+             */
+            for (int sti = 0; sti < stackDepth; sti++) {
+                int methodClassNameIndex, methodNameIndex;
+                int methodSourceFileIndex;
+                short lineNumber;
+                String methodClassName, methodName, methodSourceFile;
+
+                methodClassNameIndex = (data.getShort() & 0xffff);
+                methodNameIndex = (data.getShort() & 0xffff);
+                methodSourceFileIndex = (data.getShort() & 0xffff);
+                lineNumber = data.getShort();
+
+                methodClassName = classNames[methodClassNameIndex];
+                methodName = methodNames[methodNameIndex];
+                methodSourceFile = fileNames[methodSourceFileIndex];
+
+                steArray[sti] = new StackTraceElement(methodClassName,
+                    methodName, methodSourceFile, lineNumber);
+
+                /* we've consumed 8 bytes; gobble up any extra */
+                for (int skip = 9; skip < stackFrameLen; skip++)
+                    data.get();
+            }
+
+            list.add(new AllocationInfo(classNames[classNameIndex],
+                totalSize, (short) threadId, steArray));
+        }
+        
+        // sort biggest allocations first.
+        Collections.sort(list);
+        
+        client.getClientData().setAllocations(list.toArray(new AllocationInfo[numEntries]));
+    }
+
+    /*
+     * For debugging: dump the contents of an AllocRecord array.
+     *
+     * The array starts with the oldest known allocation and ends with
+     * the most recent allocation.
+     */
+    @SuppressWarnings("unused")
+    private static void dumpRecords(AllocationInfo[] records) {
+        System.out.println("Found " + records.length + " records:");
+
+        for (AllocationInfo rec: records) {
+            System.out.println("tid=" + rec.getThreadId() + " "
+                + rec.getAllocatedClass() + " (" + rec.getSize() + " bytes)");
+
+            for (StackTraceElement ste: rec.getStackTrace()) {
+                if (ste.isNativeMethod()) {
+                    System.out.println("    " + ste.getClassName() 
+                        + "." + ste.getMethodName()
+                        + " (Native method)");
+                } else {
+                    System.out.println("    " + ste.getClassName() 
+                        + "." + ste.getMethodName()
+                        + " (" + ste.getFileName()
+                        + ":" + ste.getLineNumber() + ")");
+                }
+            }
+        }
+    }
+
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java
new file mode 100644
index 0000000..5ba5aeb
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleHello.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Handle the "hello" chunk (HELO).
+ */
+final class HandleHello extends ChunkHandler {
+
+    public static final int CHUNK_HELO = ChunkHandler.type("HELO");
+
+    private static final HandleHello mInst = new HandleHello();
+
+
+    private HandleHello() {}
+
+    /**
+     * Register for the packets we expect to get from the client.
+     */
+    public static void register(MonitorThread mt) {
+        mt.registerChunkHandler(CHUNK_HELO, mInst);
+    }
+
+    /**
+     * Client is ready.
+     */
+    @Override
+    public void clientReady(Client client) throws IOException {
+        Log.d("ddm-hello", "Now ready: " + client);
+    }
+
+    /**
+     * Client went away.
+     */
+    @Override
+    public void clientDisconnected(Client client) {
+        Log.d("ddm-hello", "Now disconnected: " + client);
+    }
+
+    /**
+     * Chunk handler entry point.
+     */
+    @Override
+    public void handleChunk(Client client, int type, ByteBuffer data, boolean isReply, int msgId) {
+
+        Log.d("ddm-hello", "handling " + ChunkHandler.name(type));
+
+        if (type == CHUNK_HELO) {
+            assert isReply;
+            handleHELO(client, data);
+        } else {
+            handleUnknownChunk(client, type, data, isReply, msgId);
+        }
+    }
+
+    /*
+     * Handle a reply to our HELO message.
+     */
+    private static void handleHELO(Client client, ByteBuffer data) {
+        int version, pid, vmIdentLen, appNameLen;
+        String vmIdent, appName;
+
+        version = data.getInt();
+        pid = data.getInt();
+        vmIdentLen = data.getInt();
+        appNameLen = data.getInt();
+
+        vmIdent = getString(data, vmIdentLen);
+        appName = getString(data, appNameLen);
+        
+        Log.d("ddm-hello", "HELO: v=" + version + ", pid=" + pid
+            + ", vm='" + vmIdent + "', app='" + appName + "'");
+
+        ClientData cd = client.getClientData();
+        
+        synchronized (cd) {
+            if (cd.getPid() == pid) {
+                cd.setVmIdentifier(vmIdent);
+                cd.setClientDescription(appName);
+                cd.isDdmAware(true);
+            } else {
+                Log.e("ddm-hello", "Received pid (" + pid + ") does not match client pid ("
+                        + cd.getPid() + ")");
+            }
+        }
+
+        client = checkDebuggerPortForAppName(client, appName);
+
+        if (client != null) {
+            client.update(Client.CHANGE_NAME);
+        }
+    }
+
+
+    /**
+     * Send a HELO request to the client.
+     */
+    public static void sendHELO(Client client, int serverProtocolVersion)
+        throws IOException
+    {
+        ByteBuffer rawBuf = allocBuffer(4);
+        JdwpPacket packet = new JdwpPacket(rawBuf);
+        ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+        buf.putInt(serverProtocolVersion);
+
+        finishChunkPacket(packet, CHUNK_HELO, buf.position());
+        Log.d("ddm-hello", "Sending " + name(CHUNK_HELO)
+            + " ID=0x" + Integer.toHexString(packet.getId()));
+        client.sendAndConsume(packet, mInst);
+    }
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleNativeHeap.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleNativeHeap.java
new file mode 100644
index 0000000..ca26590
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleNativeHeap.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Handle thread status updates.
+ */
+final class HandleNativeHeap extends ChunkHandler {
+
+    public static final int CHUNK_NHGT = type("NHGT"); // $NON-NLS-1$
+    public static final int CHUNK_NHSG = type("NHSG"); // $NON-NLS-1$
+    public static final int CHUNK_NHST = type("NHST"); // $NON-NLS-1$
+    public static final int CHUNK_NHEN = type("NHEN"); // $NON-NLS-1$
+
+    private static final HandleNativeHeap mInst = new HandleNativeHeap();
+
+    private HandleNativeHeap() {
+    }
+
+
+    /**
+     * Register for the packets we expect to get from the client.
+     */
+    public static void register(MonitorThread mt) {
+        mt.registerChunkHandler(CHUNK_NHGT, mInst);
+        mt.registerChunkHandler(CHUNK_NHSG, mInst);
+        mt.registerChunkHandler(CHUNK_NHST, mInst);
+        mt.registerChunkHandler(CHUNK_NHEN, mInst);
+    }
+
+    /**
+     * Client is ready.
+     */
+    @Override
+    public void clientReady(Client client) throws IOException {}
+
+    /**
+     * Client went away.
+     */
+    @Override
+    public void clientDisconnected(Client client) {}
+
+    /**
+     * Chunk handler entry point.
+     */
+    @Override
+    public void handleChunk(Client client, int type, ByteBuffer data, boolean isReply, int msgId) {
+
+        Log.d("ddm-nativeheap", "handling " + ChunkHandler.name(type));
+
+        if (type == CHUNK_NHGT) {
+            handleNHGT(client, data);
+        } else if (type == CHUNK_NHST) {
+            // start chunk before any NHSG chunk(s)
+            client.getClientData().getNativeHeapData().clearHeapData();
+        } else if (type == CHUNK_NHEN) {
+            // end chunk after NHSG chunk(s)
+            client.getClientData().getNativeHeapData().sealHeapData();
+        } else if (type == CHUNK_NHSG) {
+            handleNHSG(client, data);
+        } else {
+            handleUnknownChunk(client, type, data, isReply, msgId);
+        }
+
+        client.update(Client.CHANGE_NATIVE_HEAP_DATA);
+    }
+
+    /**
+     * Send an NHGT (Native Thread GeT) request to the client.
+     */
+    public static void sendNHGT(Client client) throws IOException {
+
+        ByteBuffer rawBuf = allocBuffer(0);
+        JdwpPacket packet = new JdwpPacket(rawBuf);
+        ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+        // no data in request message
+
+        finishChunkPacket(packet, CHUNK_NHGT, buf.position());
+        Log.d("ddm-nativeheap", "Sending " + name(CHUNK_NHGT));
+        client.sendAndConsume(packet, mInst);
+
+        rawBuf = allocBuffer(2);
+        packet = new JdwpPacket(rawBuf);
+        buf = getChunkDataBuf(rawBuf);
+
+        buf.put((byte)HandleHeap.WHEN_GC);
+        buf.put((byte)HandleHeap.WHAT_OBJ);
+
+        finishChunkPacket(packet, CHUNK_NHSG, buf.position());
+        Log.d("ddm-nativeheap", "Sending " + name(CHUNK_NHSG));
+        client.sendAndConsume(packet, mInst);
+    }
+
+    /*
+     * Handle our native heap data.
+     */
+    private void handleNHGT(Client client, ByteBuffer data) {
+        ClientData cd = client.getClientData();
+
+        Log.d("ddm-nativeheap", "NHGT: " + data.limit() + " bytes");
+
+        // TODO - process incoming data and save in "cd"
+        byte[] copy = new byte[data.limit()];
+        data.get(copy);
+
+        // clear the previous run
+        cd.clearNativeAllocationInfo();
+
+        ByteBuffer buffer = ByteBuffer.wrap(copy);
+        buffer.order(ByteOrder.LITTLE_ENDIAN);
+
+//        read the header
+//        typedef struct Header {
+//            uint32_t mapSize;
+//            uint32_t allocSize;
+//            uint32_t allocInfoSize;
+//            uint32_t totalMemory;
+//              uint32_t backtraceSize;
+//        };
+
+        int mapSize = buffer.getInt();
+        int allocSize = buffer.getInt();
+        int allocInfoSize = buffer.getInt();
+        int totalMemory = buffer.getInt();
+        int backtraceSize = buffer.getInt();
+
+        Log.d("ddms", "mapSize: " + mapSize);
+        Log.d("ddms", "allocSize: " + allocSize);
+        Log.d("ddms", "allocInfoSize: " + allocInfoSize);
+        Log.d("ddms", "totalMemory: " + totalMemory);
+
+        cd.setTotalNativeMemory(totalMemory);
+
+        // this means that updates aren't turned on.
+        if (allocInfoSize == 0)
+          return;
+
+        if (mapSize > 0) {
+            byte[] maps = new byte[mapSize];
+            buffer.get(maps, 0, mapSize);
+            parseMaps(cd, maps);
+        }
+
+        int iterations = allocSize / allocInfoSize;
+
+        for (int i = 0 ; i < iterations ; i++) {
+            NativeAllocationInfo info = new NativeAllocationInfo(
+                    buffer.getInt() /* size */,
+                    buffer.getInt() /* allocations */);
+
+            for (int j = 0 ; j < backtraceSize ; j++) {
+                long addr = ((long)buffer.getInt()) & 0x00000000ffffffffL;
+
+                info.addStackCallAddress(addr);;
+            }
+
+            cd.addNativeAllocation(info);
+        }
+    }
+
+    private void handleNHSG(Client client, ByteBuffer data) {
+        byte dataCopy[] = new byte[data.limit()];
+        data.rewind();
+        data.get(dataCopy);
+        data = ByteBuffer.wrap(dataCopy);
+        client.getClientData().getNativeHeapData().addHeapData(data);
+
+        if (true) {
+            return;
+        }
+
+        // WORK IN PROGRESS
+
+//        Log.e("ddm-nativeheap", "NHSG: ----------------------------------");
+//        Log.e("ddm-nativeheap", "NHSG: " + data.limit() + " bytes");
+
+        byte[] copy = new byte[data.limit()];
+        data.get(copy);
+
+        ByteBuffer buffer = ByteBuffer.wrap(copy);
+        buffer.order(ByteOrder.BIG_ENDIAN);
+
+        int id = buffer.getInt();
+        int unitsize = (int) buffer.get();
+        long startAddress = (long) buffer.getInt() & 0x00000000ffffffffL;
+        int offset = buffer.getInt();
+        int allocationUnitCount = buffer.getInt();
+
+//        Log.e("ddm-nativeheap", "id: " + id);
+//        Log.e("ddm-nativeheap", "unitsize: " + unitsize);
+//        Log.e("ddm-nativeheap", "startAddress: 0x" + Long.toHexString(startAddress));
+//        Log.e("ddm-nativeheap", "offset: " + offset);
+//        Log.e("ddm-nativeheap", "allocationUnitCount: " + allocationUnitCount);
+//        Log.e("ddm-nativeheap", "end: 0x" +
+//                Long.toHexString(startAddress + unitsize * allocationUnitCount));
+
+        // read the usage
+        while (buffer.position() < buffer.limit()) {
+            int eState = (int)buffer.get() & 0x000000ff;
+            int eLen = ((int)buffer.get() & 0x000000ff) + 1;
+            //Log.e("ddm-nativeheap", "solidity: " + (eState & 0x7) + " - kind: "
+            //        + ((eState >> 3) & 0x7) + " - len: " + eLen);
+        }
+
+
+//        count += unitsize * allocationUnitCount;
+//        Log.e("ddm-nativeheap", "count = " + count);
+
+    }
+
+    private void parseMaps(ClientData cd, byte[] maps) {
+        InputStreamReader input = new InputStreamReader(new ByteArrayInputStream(maps));
+        BufferedReader reader = new BufferedReader(input);
+
+        String line;
+
+        try {
+
+            // most libraries are defined on several lines, so we need to make sure we parse
+            // all the library lines and only add the library at the end
+            long startAddr = 0;
+            long endAddr = 0;
+            String library = null;
+
+            while ((line = reader.readLine()) != null) {
+                Log.d("ddms", "line: " + line);
+                if (line.length() < 16) {
+                    continue;
+                }
+
+                try {
+                    long tmpStart = Long.parseLong(line.substring(0, 8), 16);
+                    long tmpEnd = Long.parseLong(line.substring(9, 17), 16);
+
+                     /*
+                      * only check for library addresses as defined in
+                      * //device/config/prelink-linux-arm.map
+                      */
+                    if (tmpStart >= 0x0000000080000000L && tmpStart <= 0x00000000BFFFFFFFL) {
+
+                        int index = line.indexOf('/');
+
+                        if (index == -1)
+                            continue;
+
+                        String tmpLib = line.substring(index);
+
+                        if (library == null ||
+                                (library != null && tmpLib.equals(library) == false)) {
+
+                            if (library != null) {
+                                cd.addNativeLibraryMapInfo(startAddr, endAddr, library);
+                                Log.d("ddms", library + "(" + Long.toHexString(startAddr) +
+                                        " - " + Long.toHexString(endAddr) + ")");
+                            }
+
+                            // now init the new library
+                            library = tmpLib;
+                            startAddr = tmpStart;
+                            endAddr = tmpEnd;
+                        } else {
+                            // add the new end
+                            endAddr = tmpEnd;
+                        }
+                    }
+                } catch (NumberFormatException e) {
+                    e.printStackTrace();
+                }
+            }
+
+            if (library != null) {
+                cd.addNativeLibraryMapInfo(startAddr, endAddr, library);
+                Log.d("ddms", library + "(" + Long.toHexString(startAddr) +
+                        " - " + Long.toHexString(endAddr) + ")");
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleTest.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleTest.java
new file mode 100644
index 0000000..b9f3a74
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import com.android.ddmlib.Log.LogLevel;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Handle thread status updates.
+ */
+final class HandleTest extends ChunkHandler {
+
+    public static final int CHUNK_TEST = type("TEST");
+
+    private static final HandleTest mInst = new HandleTest();
+
+
+    private HandleTest() {}
+
+    /**
+     * Register for the packets we expect to get from the client.
+     */
+    public static void register(MonitorThread mt) {
+        mt.registerChunkHandler(CHUNK_TEST, mInst);
+    }
+
+    /**
+     * Client is ready.
+     */
+    @Override
+    public void clientReady(Client client) throws IOException {}
+
+    /**
+     * Client went away.
+     */
+    @Override
+    public void clientDisconnected(Client client) {}
+
+    /**
+     * Chunk handler entry point.
+     */
+    @Override
+    public void handleChunk(Client client, int type, ByteBuffer data, boolean isReply, int msgId) {
+
+        Log.d("ddm-test", "handling " + ChunkHandler.name(type));
+
+        if (type == CHUNK_TEST) {
+            handleTEST(client, data);
+        } else {
+            handleUnknownChunk(client, type, data, isReply, msgId);
+        }
+    }
+
+    /*
+     * Handle a thread creation message.
+     */
+    private void handleTEST(Client client, ByteBuffer data)
+    {
+        /*
+         * Can't call data.array() on a read-only ByteBuffer, so we make
+         * a copy.
+         */
+        byte[] copy = new byte[data.limit()];
+        data.get(copy);
+
+        Log.d("ddm-test", "Received:");
+        Log.hexDump("ddm-test", LogLevel.DEBUG, copy, 0, copy.length);
+    }
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleThread.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleThread.java
new file mode 100644
index 0000000..572eed2
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleThread.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Handle thread status updates.
+ */
+final class HandleThread extends ChunkHandler {
+
+    public static final int CHUNK_THEN = type("THEN");
+    public static final int CHUNK_THCR = type("THCR");
+    public static final int CHUNK_THDE = type("THDE");
+    public static final int CHUNK_THST = type("THST");
+    public static final int CHUNK_THNM = type("THNM");
+    public static final int CHUNK_STKL = type("STKL");
+
+    private static final HandleThread mInst = new HandleThread();
+
+    // only read/written by requestThreadUpdates()
+    private static volatile boolean mThreadStatusReqRunning = false;
+    private static volatile boolean mThreadStackTraceReqRunning = false;
+
+    private HandleThread() {}
+
+
+    /**
+     * Register for the packets we expect to get from the client.
+     */
+    public static void register(MonitorThread mt) {
+        mt.registerChunkHandler(CHUNK_THCR, mInst);
+        mt.registerChunkHandler(CHUNK_THDE, mInst);
+        mt.registerChunkHandler(CHUNK_THST, mInst);
+        mt.registerChunkHandler(CHUNK_THNM, mInst);
+        mt.registerChunkHandler(CHUNK_STKL, mInst);
+    }
+
+    /**
+     * Client is ready.
+     */
+    @Override
+    public void clientReady(Client client) throws IOException {
+        Log.d("ddm-thread", "Now ready: " + client);
+        if (client.isThreadUpdateEnabled())
+            sendTHEN(client, true);
+    }
+
+    /**
+     * Client went away.
+     */
+    @Override
+    public void clientDisconnected(Client client) {}
+
+    /**
+     * Chunk handler entry point.
+     */
+    @Override
+    public void handleChunk(Client client, int type, ByteBuffer data, boolean isReply, int msgId) {
+
+        Log.d("ddm-thread", "handling " + ChunkHandler.name(type));
+
+        if (type == CHUNK_THCR) {
+            handleTHCR(client, data);
+        } else if (type == CHUNK_THDE) {
+            handleTHDE(client, data);
+        } else if (type == CHUNK_THST) {
+            handleTHST(client, data);
+        } else if (type == CHUNK_THNM) {
+            handleTHNM(client, data);
+        } else if (type == CHUNK_STKL) {
+            handleSTKL(client, data);
+        } else {
+            handleUnknownChunk(client, type, data, isReply, msgId);
+        }
+    }
+
+    /*
+     * Handle a thread creation message.
+     *
+     * We should be tolerant of receiving a duplicate create message.  (It
+     * shouldn't happen with the current implementation.)
+     */
+    private void handleTHCR(Client client, ByteBuffer data) {
+        int threadId, nameLen;
+        String name;
+
+        threadId = data.getInt();
+        nameLen = data.getInt();
+        name = getString(data, nameLen);
+
+        Log.v("ddm-thread", "THCR: " + threadId + " '" + name + "'");
+
+        client.getClientData().addThread(threadId, name);
+        client.update(Client.CHANGE_THREAD_DATA);
+    }
+
+    /*
+     * Handle a thread death message.
+     */
+    private void handleTHDE(Client client, ByteBuffer data) {
+        int threadId;
+
+        threadId = data.getInt();
+        Log.v("ddm-thread", "THDE: " + threadId);
+
+        client.getClientData().removeThread(threadId);
+        client.update(Client.CHANGE_THREAD_DATA);
+    }
+
+    /*
+     * Handle a thread status update message.
+     *
+     * Response has:
+     *  (1b) header len
+     *  (1b) bytes per entry
+     *  (2b) thread count
+     * Then, for each thread:
+     *  (4b) threadId (matches value from THCR)
+     *  (1b) thread status
+     *  (4b) tid
+     *  (4b) utime
+     *  (4b) stime
+     */
+    private void handleTHST(Client client, ByteBuffer data) {
+        int headerLen, bytesPerEntry, extraPerEntry;
+        int threadCount;
+
+        headerLen = (data.get() & 0xff);
+        bytesPerEntry = (data.get() & 0xff);
+        threadCount = data.getShort();
+
+        headerLen -= 4;     // we've read 4 bytes
+        while (headerLen-- > 0)
+            data.get();
+
+        extraPerEntry = bytesPerEntry - 18;     // we want 18 bytes
+
+        Log.v("ddm-thread", "THST: threadCount=" + threadCount);
+
+        /*
+         * For each thread, extract the data, find the appropriate
+         * client, and add it to the ClientData.
+         */
+        for (int i = 0; i < threadCount; i++) {
+            int threadId, status, tid, utime, stime;
+            boolean isDaemon = false;
+
+            threadId = data.getInt();
+            status = data.get();
+            tid = data.getInt();
+            utime = data.getInt();
+            stime = data.getInt();
+            if (bytesPerEntry >= 18)
+                isDaemon = (data.get() != 0);
+
+            Log.v("ddm-thread", "  id=" + threadId
+                + ", status=" + status + ", tid=" + tid
+                + ", utime=" + utime + ", stime=" + stime);
+
+            ClientData cd = client.getClientData();
+            ThreadInfo threadInfo = cd.getThread(threadId);
+            if (threadInfo != null)
+                threadInfo.updateThread(status, tid, utime, stime, isDaemon);
+            else
+                Log.i("ddms", "Thread with id=" + threadId + " not found");
+
+            // slurp up any extra
+            for (int slurp = extraPerEntry; slurp > 0; slurp--)
+                data.get();
+        }
+        
+        client.update(Client.CHANGE_THREAD_DATA);
+    }
+
+    /*
+     * Handle a THNM (THread NaMe) message.  We get one of these after
+     * somebody calls Thread.setName() on a running thread.
+     */
+    private void handleTHNM(Client client, ByteBuffer data) {
+        int threadId, nameLen;
+        String name;
+
+        threadId = data.getInt();
+        nameLen = data.getInt();
+        name = getString(data, nameLen);
+
+        Log.v("ddm-thread", "THNM: " + threadId + " '" + name + "'");
+
+        ThreadInfo threadInfo = client.getClientData().getThread(threadId);
+        if (threadInfo != null) {
+            threadInfo.setThreadName(name);
+            client.update(Client.CHANGE_THREAD_DATA);
+        } else {
+            Log.i("ddms", "Thread with id=" + threadId + " not found");
+        }
+    }
+
+
+    /**
+     * Parse an incoming STKL.
+     */
+    private void handleSTKL(Client client, ByteBuffer data) {
+        StackTraceElement[] trace;
+        int i, threadId, stackDepth;
+        @SuppressWarnings("unused")
+        int future;
+
+        future = data.getInt();
+        threadId = data.getInt();
+
+        Log.v("ddms", "STKL: " + threadId);
+
+        /* un-serialize the StackTraceElement[] */
+        stackDepth = data.getInt();
+        trace = new StackTraceElement[stackDepth];
+        for (i = 0; i < stackDepth; i++) {
+            String className, methodName, fileName;
+            int len, lineNumber;
+
+            len = data.getInt();
+            className = getString(data, len);
+            len = data.getInt();
+            methodName = getString(data, len);
+            len = data.getInt();
+            if (len == 0) {
+                fileName = null;
+            } else {
+                fileName = getString(data, len);
+            }
+            lineNumber = data.getInt();
+
+            trace[i] = new StackTraceElement(className, methodName, fileName,
+                        lineNumber);
+        }
+
+        ThreadInfo threadInfo = client.getClientData().getThread(threadId);
+        if (threadInfo != null) {
+            threadInfo.setStackCall(trace);
+            client.update(Client.CHANGE_THREAD_STACKTRACE);
+        } else {
+            Log.d("STKL", String.format(
+                    "Got stackcall for thread %1$d, which does not exists (anymore?).", //$NON-NLS-1$
+                    threadId));
+        }
+    }
+
+
+    /**
+     * Send a THEN (THread notification ENable) request to the client.
+     */
+    public static void sendTHEN(Client client, boolean enable)
+        throws IOException {
+
+        ByteBuffer rawBuf = allocBuffer(1);
+        JdwpPacket packet = new JdwpPacket(rawBuf);
+        ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+        if (enable)
+            buf.put((byte)1);
+        else
+            buf.put((byte)0);
+
+        finishChunkPacket(packet, CHUNK_THEN, buf.position());
+        Log.d("ddm-thread", "Sending " + name(CHUNK_THEN) + ": " + enable);
+        client.sendAndConsume(packet, mInst);
+    }
+
+
+    /**
+     * Send a STKL (STacK List) request to the client.  The VM will suspend
+     * the target thread, obtain its stack, and return it.  If the thread
+     * is no longer running, a failure result will be returned.
+     */
+    public static void sendSTKL(Client client, int threadId)
+        throws IOException {
+
+        if (false) {
+            Log.i("ddm-thread", "would send STKL " + threadId);
+            return;
+        }
+
+        ByteBuffer rawBuf = allocBuffer(4);
+        JdwpPacket packet = new JdwpPacket(rawBuf);
+        ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+        buf.putInt(threadId);
+
+        finishChunkPacket(packet, CHUNK_STKL, buf.position());
+        Log.d("ddm-thread", "Sending " + name(CHUNK_STKL) + ": " + threadId);
+        client.sendAndConsume(packet, mInst);
+    }
+
+
+    /**
+     * This is called periodically from the UI thread.  To avoid locking
+     * the UI while we request the updates, we create a new thread.
+     *
+     */
+    static void requestThreadUpdate(final Client client) {
+        if (client.isDdmAware() && client.isThreadUpdateEnabled()) {
+            if (mThreadStatusReqRunning) {
+                Log.w("ddms", "Waiting for previous thread update req to finish");
+                return;
+            }
+
+            new Thread("Thread Status Req") {
+                @Override
+                public void run() {
+                    mThreadStatusReqRunning = true;
+                    try {
+                        sendTHST(client);
+                    } catch (IOException ioe) {
+                        Log.i("ddms", "Unable to request thread updates from "
+                                + client + ": " + ioe.getMessage());
+                    } finally {
+                        mThreadStatusReqRunning = false;
+                    }
+                }
+            }.start();
+        }
+    }
+    
+    static void requestThreadStackCallRefresh(final Client client, final int threadId) {
+        if (client.isDdmAware() && client.isThreadUpdateEnabled()) {
+            if (mThreadStackTraceReqRunning ) {
+                Log.w("ddms", "Waiting for previous thread stack call req to finish");
+                return;
+            }
+
+            new Thread("Thread Status Req") {
+                @Override
+                public void run() {
+                    mThreadStackTraceReqRunning = true;
+                    try {
+                        sendSTKL(client, threadId);
+                    } catch (IOException ioe) {
+                        Log.i("ddms", "Unable to request thread stack call updates from "
+                                + client + ": " + ioe.getMessage());
+                    } finally {
+                        mThreadStackTraceReqRunning = false;
+                    }
+                }
+            }.start();
+        }
+        
+    }
+
+    /*
+     * Send a THST request to the specified client.
+     */
+    private static void sendTHST(Client client) throws IOException {
+        ByteBuffer rawBuf = allocBuffer(0);
+        JdwpPacket packet = new JdwpPacket(rawBuf);
+        ByteBuffer buf = getChunkDataBuf(rawBuf);
+
+        // nothing much to say
+
+        finishChunkPacket(packet, CHUNK_THST, buf.position());
+        Log.d("ddm-thread", "Sending " + name(CHUNK_THST));
+        client.sendAndConsume(packet, mInst);
+    }
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleWait.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleWait.java
new file mode 100644
index 0000000..d27e636
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HandleWait.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * Handle the "wait" chunk (WAIT).  These are sent up when the client is
+ * waiting for something, e.g. for a debugger to attach.
+ */
+final class HandleWait extends ChunkHandler {
+
+    public static final int CHUNK_WAIT = ChunkHandler.type("WAIT");
+
+    private static final HandleWait mInst = new HandleWait();
+
+
+    private HandleWait() {}
+
+    /**
+     * Register for the packets we expect to get from the client.
+     */
+    public static void register(MonitorThread mt) {
+        mt.registerChunkHandler(CHUNK_WAIT, mInst);
+    }
+
+    /**
+     * Client is ready.
+     */
+    @Override
+    public void clientReady(Client client) throws IOException {}
+
+    /**
+     * Client went away.
+     */
+    @Override
+    public void clientDisconnected(Client client) {}
+
+    /**
+     * Chunk handler entry point.
+     */
+    @Override
+    public void handleChunk(Client client, int type, ByteBuffer data, boolean isReply, int msgId) {
+
+        Log.d("ddm-wait", "handling " + ChunkHandler.name(type));
+
+        if (type == CHUNK_WAIT) {
+            assert !isReply;
+            handleWAIT(client, data);
+        } else {
+            handleUnknownChunk(client, type, data, isReply, msgId);
+        }
+    }
+
+    /*
+     * Handle a reply to our WAIT message.
+     */
+    private static void handleWAIT(Client client, ByteBuffer data) {
+        byte reason;
+
+        reason = data.get();
+
+        Log.i("ddm-wait", "WAIT: reason=" + reason);
+
+
+        ClientData cd = client.getClientData();
+        synchronized (cd) {
+            cd.setDebuggerConnectionStatus(ClientData.DEBUGGER_WAITING);
+        }
+
+        client.update(Client.CHANGE_DEBUGGER_INTEREST);
+    }
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HeapSegment.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HeapSegment.java
new file mode 100644
index 0000000..6a62e60
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/HeapSegment.java
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.text.ParseException;
+
+/**
+ * Describes the types and locations of objects in a segment of a heap.
+ */
+public final class HeapSegment implements Comparable<HeapSegment> {
+
+    /**
+     * Describes an object/region encoded in the HPSG data.
+     */
+    public static class HeapSegmentElement implements Comparable<HeapSegmentElement> {
+
+        /*
+         * Solidity values, which must match the values in
+         * the HPSG data.
+         */
+
+        /** The element describes a free block. */
+        public static int SOLIDITY_FREE = 0;
+
+        /** The element is strongly-reachable. */
+        public static int SOLIDITY_HARD = 1;
+
+        /** The element is softly-reachable. */
+        public static int SOLIDITY_SOFT = 2;
+
+        /** The element is weakly-reachable. */
+        public static int SOLIDITY_WEAK = 3;
+
+        /** The element is phantom-reachable. */
+        public static int SOLIDITY_PHANTOM = 4;
+
+        /** The element is pending finalization. */
+        public static int SOLIDITY_FINALIZABLE = 5;
+
+        /** The element is not reachable, and is about to be swept/freed. */
+        public static int SOLIDITY_SWEEP = 6;
+
+        /** The reachability of the object is unknown. */
+        public static int SOLIDITY_INVALID = -1;
+
+
+        /*
+         * Kind values, which must match the values in
+         * the HPSG data.
+         */
+
+        /** The element describes a data object. */
+        public static int KIND_OBJECT = 0;
+
+        /** The element describes a class object. */
+        public static int KIND_CLASS_OBJECT = 1;
+
+        /** The element describes an array of 1-byte elements. */
+        public static int KIND_ARRAY_1 = 2;
+
+        /** The element describes an array of 2-byte elements. */
+        public static int KIND_ARRAY_2 = 3;
+
+        /** The element describes an array of 4-byte elements. */
+        public static int KIND_ARRAY_4 = 4;
+
+        /** The element describes an array of 8-byte elements. */
+        public static int KIND_ARRAY_8 = 5;
+
+        /** The element describes an unknown type of object. */
+        public static int KIND_UNKNOWN = 6;
+
+        /** The element describes a native object. */
+        public static int KIND_NATIVE = 7;
+
+        /** The object kind is unknown or unspecified. */
+        public static int KIND_INVALID = -1;
+
+
+        /**
+         * A bit in the HPSG data that indicates that an element should
+         * be combined with the element that follows, typically because
+         * an element is too large to be described by a single element.
+         */
+        private static int PARTIAL_MASK = 1 << 7;
+
+
+        /**
+         * Describes the reachability/solidity of the element.  Must
+         * be set to one of the SOLIDITY_* values.
+         */
+        private int mSolidity;
+
+        /**
+         * Describes the type/kind of the element.  Must be set to one
+         * of the KIND_* values.
+         */
+        private int mKind;
+
+        /**
+         * Describes the length of the element, in bytes.
+         */
+        private int mLength;
+
+
+        /**
+         * Creates an uninitialized element.
+         */
+        public HeapSegmentElement() {
+            setSolidity(SOLIDITY_INVALID);
+            setKind(KIND_INVALID);
+            setLength(-1);
+        }
+
+        /**
+         * Create an element describing the entry at the current
+         * position of hpsgData.
+         *
+         * @param hs The heap segment to pull the entry from.
+         * @throws BufferUnderflowException if there is not a whole entry
+         *                                  following the current position
+         *                                  of hpsgData.
+         * @throws ParseException           if the provided data is malformed.
+         */
+        public HeapSegmentElement(HeapSegment hs)
+                throws BufferUnderflowException, ParseException {
+            set(hs);
+        }
+
+        /**
+         * Replace the element with the entry at the current position of
+         * hpsgData.
+         *
+         * @param hs The heap segment to pull the entry from.
+         * @return this object.
+         * @throws BufferUnderflowException if there is not a whole entry
+         *                                  following the current position of
+         *                                  hpsgData.
+         * @throws ParseException           if the provided data is malformed.
+         */
+        public HeapSegmentElement set(HeapSegment hs)
+                throws BufferUnderflowException, ParseException {
+
+            /* TODO: Maybe keep track of the virtual address of each element
+             *       so that they can be examined independently.
+             */
+            ByteBuffer data = hs.mUsageData;
+            int eState = (int)data.get() & 0x000000ff;
+            int eLen = ((int)data.get() & 0x000000ff) + 1;
+
+            while ((eState & PARTIAL_MASK) != 0) {
+
+                /* If the partial bit was set, the next byte should describe
+                 * the same object as the current one.
+                 */
+                int nextState = (int)data.get() & 0x000000ff;
+                if ((nextState & ~PARTIAL_MASK) != (eState & ~PARTIAL_MASK)) {
+                    throw new ParseException("State mismatch", data.position());
+                }
+                eState = nextState;
+                eLen += ((int)data.get() & 0x000000ff) + 1;
+            }
+
+            setSolidity(eState & 0x7);
+            setKind((eState >> 3) & 0x7);
+            setLength(eLen * hs.mAllocationUnitSize);
+
+            return this;
+        }
+
+        public int getSolidity() {
+            return mSolidity;
+        }
+
+        public void setSolidity(int solidity) {
+            this.mSolidity = solidity;
+        }
+
+        public int getKind() {
+            return mKind;
+        }
+
+        public void setKind(int kind) {
+            this.mKind = kind;
+        }
+
+        public int getLength() {
+            return mLength;
+        }
+
+        public void setLength(int length) {
+            this.mLength = length;
+        }
+
+        public int compareTo(HeapSegmentElement other) {
+            if (mLength != other.mLength) {
+                return mLength < other.mLength ? -1 : 1;
+            }
+            return 0;
+        }
+    }
+
+    //* The ID of the heap that this segment belongs to.
+    protected int mHeapId;
+
+    //* The size of an allocation unit, in bytes. (e.g., 8 bytes)
+    protected int mAllocationUnitSize;
+
+    //* The virtual address of the start of this segment.
+    protected long mStartAddress;
+
+    //* The offset of this pices from mStartAddress, in bytes.
+    protected int mOffset;
+
+    //* The number of allocation units described in this segment.
+    protected int mAllocationUnitCount;
+
+    //* The raw data that describes the contents of this segment.
+    protected ByteBuffer mUsageData;
+
+    //* mStartAddress is set to this value when the segment becomes invalid.
+    private final static long INVALID_START_ADDRESS = -1;
+
+    /**
+     * Create a new HeapSegment based on the raw contents
+     * of an HPSG chunk.
+     *
+     * @param hpsgData The raw data from an HPSG chunk.
+     * @throws BufferUnderflowException if hpsgData is too small
+     *                                  to hold the HPSG chunk header data.
+     */
+    public HeapSegment(ByteBuffer hpsgData) throws BufferUnderflowException {
+        /* Read the HPSG chunk header.
+         * These get*() calls may throw a BufferUnderflowException
+         * if the underlying data isn't big enough.
+         */
+        hpsgData.order(ByteOrder.BIG_ENDIAN);
+        mHeapId = hpsgData.getInt();
+        mAllocationUnitSize = (int) hpsgData.get();
+        mStartAddress = (long) hpsgData.getInt() & 0x00000000ffffffffL;
+        mOffset = hpsgData.getInt();
+        mAllocationUnitCount = hpsgData.getInt();
+
+        // Hold onto the remainder of the data.
+        mUsageData = hpsgData.slice();
+        mUsageData.order(ByteOrder.BIG_ENDIAN);   // doesn't actually matter
+
+        // Validate the data.
+//xxx do it
+//xxx make sure the number of elements matches mAllocationUnitCount.
+//xxx make sure the last element doesn't have P set
+    }
+
+    /**
+     * See if this segment still contains data, and has not been
+     * appended to another segment.
+     *
+     * @return true if this segment has not been appended to
+     *         another segment.
+     */
+    public boolean isValid() {
+        return mStartAddress != INVALID_START_ADDRESS;
+    }
+
+    /**
+     * See if <code>other</code> comes immediately after this segment.
+     *
+     * @param other The HeapSegment to check.
+     * @return true if <code>other</code> comes immediately after this
+     *         segment.
+     */
+    public boolean canAppend(HeapSegment other) {
+        return isValid() && other.isValid() && mHeapId == other.mHeapId &&
+                mAllocationUnitSize == other.mAllocationUnitSize &&
+                getEndAddress() == other.getStartAddress();
+    }
+
+    /**
+     * Append the contents of <code>other</code> to this segment
+     * if it describes the segment immediately after this one.
+     *
+     * @param other The segment to append to this segment, if possible.
+     *              If appended, <code>other</code> will be invalid
+     *              when this method returns.
+     * @return true if <code>other</code> was successfully appended to
+     *         this segment.
+     */
+    public boolean append(HeapSegment other) {
+        if (canAppend(other)) {
+            /* Preserve the position.  The mark is not preserved,
+             * but we don't use it anyway.
+             */
+            int pos = mUsageData.position();
+
+            // Guarantee that we have enough room for the new data.
+            if (mUsageData.capacity() - mUsageData.limit() <
+                    other.mUsageData.limit()) {
+                /* Grow more than necessary in case another append()
+                 * is about to happen.
+                 */
+                int newSize = mUsageData.limit() + other.mUsageData.limit();
+                ByteBuffer newData = ByteBuffer.allocate(newSize * 2);
+
+                mUsageData.rewind();
+                newData.put(mUsageData);
+                mUsageData = newData;
+            }
+
+            // Copy the data from the other segment and restore the position.
+            other.mUsageData.rewind();
+            mUsageData.put(other.mUsageData);
+            mUsageData.position(pos);
+
+            // Fix this segment's header to cover the new data.
+            mAllocationUnitCount += other.mAllocationUnitCount;
+
+            // Mark the other segment as invalid.
+            other.mStartAddress = INVALID_START_ADDRESS;
+            other.mUsageData = null;
+
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public long getStartAddress() {
+        return mStartAddress + mOffset;
+    }
+
+    public int getLength() {
+        return mAllocationUnitSize * mAllocationUnitCount;
+    }
+
+    public long getEndAddress() {
+        return getStartAddress() + getLength();
+    }
+
+    public void rewindElements() {
+        if (mUsageData != null) {
+            mUsageData.rewind();
+        }
+    }
+
+    public HeapSegmentElement getNextElement(HeapSegmentElement reuse) {
+        try {
+            if (reuse != null) {
+                return reuse.set(this);
+            } else {
+                return new HeapSegmentElement(this);
+            }
+        } catch (BufferUnderflowException ex) {
+            /* Normal "end of buffer" situation.
+             */
+        } catch (ParseException ex) {
+            /* Malformed data.
+             */
+//TODO: we should catch this in the constructor
+        }
+        return null;
+    }
+
+    /*
+     * Method overrides for Comparable
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof HeapSegment) {
+            return compareTo((HeapSegment) o) == 0;
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return mHeapId * 31 +
+                mAllocationUnitSize * 31 +
+                (int) mStartAddress * 31 +
+                mOffset * 31 +
+                mAllocationUnitCount * 31 +
+                mUsageData.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder();
+
+        str.append("HeapSegment { heap ").append(mHeapId)
+                .append(", start 0x")
+                .append(Integer.toHexString((int) getStartAddress()))
+                .append(", length ").append(getLength())
+                .append(" }");
+
+        return str.toString();
+    }
+
+    public int compareTo(HeapSegment other) {
+        if (mHeapId != other.mHeapId) {
+            return mHeapId < other.mHeapId ? -1 : 1;
+        }
+        if (getStartAddress() != other.getStartAddress()) {
+            return getStartAddress() < other.getStartAddress() ? -1 : 1;
+        }
+
+        /* If two segments have the same start address, the rest of
+         * the fields should be equal.  Go through the motions, though.
+         * Note that we re-check the components of getStartAddress()
+         * (mStartAddress and mOffset) to make sure that all fields in
+         * an equal segment are equal.
+         */
+
+        if (mAllocationUnitSize != other.mAllocationUnitSize) {
+            return mAllocationUnitSize < other.mAllocationUnitSize ? -1 : 1;
+        }
+        if (mStartAddress != other.mStartAddress) {
+            return mStartAddress < other.mStartAddress ? -1 : 1;
+        }
+        if (mOffset != other.mOffset) {
+            return mOffset < other.mOffset ? -1 : 1;
+        }
+        if (mAllocationUnitCount != other.mAllocationUnitCount) {
+            return mAllocationUnitCount < other.mAllocationUnitCount ? -1 : 1;
+        }
+        if (mUsageData != other.mUsageData) {
+            return mUsageData.compareTo(other.mUsageData);
+        }
+        return 0;
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
new file mode 100755
index 0000000..5dbce92
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import com.android.ddmlib.Device.DeviceState;
+import com.android.ddmlib.log.LogReceiver;
+
+import java.io.IOException;
+import java.util.Map;
+
+
+/**
+ *  A Device. It can be a physical device or an emulator.
+ */
+public interface IDevice {
+
+    public final static String PROP_BUILD_VERSION = "ro.build.version.release";
+    public final static String PROP_BUILD_VERSION_NUMBER = "ro.build.version.sdk";
+    public final static String PROP_DEBUGGABLE = "ro.debuggable";
+    /** Serial number of the first connected emulator. */
+    public final static String FIRST_EMULATOR_SN = "emulator-5554"; //$NON-NLS-1$
+    /** Device change bit mask: {@link DeviceState} change. */
+    public static final int CHANGE_STATE = 0x0001;
+    /** Device change bit mask: {@link Client} list change. */
+    public static final int CHANGE_CLIENT_LIST = 0x0002;
+    /** Device change bit mask: build info change. */
+    public static final int CHANGE_BUILD_INFO = 0x0004;
+
+    /**
+     * Returns the serial number of the device.
+     */
+    public String getSerialNumber();
+
+    /**
+     * Returns the name of the AVD the emulator is running.
+     * <p/>This is only valid if {@link #isEmulator()} returns true.
+     * <p/>If the emulator is not running any AVD (for instance it's running from an Android source
+     * tree build), this method will return "<code>&lt;build&gt;</code>".
+     * @return the name of the AVD or <code>null</code> if there isn't any.
+     */
+    public String getAvdName();
+
+    /**
+     * Returns the state of the device.
+     */
+    public DeviceState getState();
+
+    /**
+     * Returns the device properties. It contains the whole output of 'getprop'
+     */
+    public Map<String, String> getProperties();
+
+    /**
+     * Returns the number of property for this device.
+     */
+    public int getPropertyCount();
+
+    /**
+     * Returns a property value.
+     * @param name the name of the value to return.
+     * @return the value or <code>null</code> if the property does not exist.
+     */
+    public String getProperty(String name);
+
+    /**
+     * Returns if the device is ready.
+     * @return <code>true</code> if {@link #getState()} returns {@link DeviceState#ONLINE}.
+     */
+    public boolean isOnline();
+
+    /**
+     * Returns <code>true</code> if the device is an emulator.
+     */
+    public boolean isEmulator();
+
+    /**
+     * Returns if the device is offline.
+     * @return <code>true</code> if {@link #getState()} returns {@link DeviceState#OFFLINE}.
+     */
+    public boolean isOffline();
+
+    /**
+     * Returns if the device is in bootloader mode.
+     * @return <code>true</code> if {@link #getState()} returns {@link DeviceState#BOOTLOADER}.
+     */
+    public boolean isBootLoader();
+
+    /**
+     * Returns whether the {@link Device} has {@link Client}s.
+     */
+    public boolean hasClients();
+
+    /**
+     * Returns the array of clients.
+     */
+    public Client[] getClients();
+
+    /**
+     * Returns a {@link Client} by its application name.
+     * @param applicationName the name of the application
+     * @return the <code>Client</code> object or <code>null</code> if no match was found.
+     */
+    public Client getClient(String applicationName);
+
+    /**
+     * Returns a {@link SyncService} object to push / pull files to and from the device.
+     * @return <code>null</code> if the SyncService couldn't be created.
+     */
+    public SyncService getSyncService();
+
+    /**
+     * Returns a {@link FileListingService} for this device.
+     */
+    public FileListingService getFileListingService();
+
+    /**
+     * Takes a screen shot of the device and returns it as a {@link RawImage}.
+     * @return the screenshot as a <code>RawImage</code> or <code>null</code> if
+     * something went wrong.
+     * @throws IOException
+     */
+    public RawImage getScreenshot() throws IOException;
+
+    /**
+     * Executes a shell command on the device, and sends the result to a receiver.
+     * @param command The command to execute
+     * @param receiver The receiver object getting the result from the command.
+     * @throws IOException
+     */
+    public void executeShellCommand(String command,
+            IShellOutputReceiver receiver) throws IOException;
+
+    /**
+     * Runs the event log service and outputs the event log to the {@link LogReceiver}.
+     * @param receiver the receiver to receive the event log entries.
+     * @throws IOException
+     */
+    public void runEventLogService(LogReceiver receiver) throws IOException;
+
+    /**
+     * Runs the log service for the given log and outputs the log to the {@link LogReceiver}.
+     * @param logname the logname of the log to read from.
+     * @param receiver the receiver to receive the event log entries.
+     * @throws IOException
+     */
+    public void runLogService(String logname, LogReceiver receiver) throws IOException;
+
+    /**
+     * Creates a port forwarding between a local and a remote port.
+     * @param localPort the local port to forward
+     * @param remotePort the remote port.
+     * @return <code>true</code> if success.
+     */
+    public boolean createForward(int localPort, int remotePort);
+
+    /**
+     * Removes a port forwarding between a local and a remote port.
+     * @param localPort the local port to forward
+     * @param remotePort the remote port.
+     * @return <code>true</code> if success.
+     */
+    public boolean removeForward(int localPort, int remotePort);
+
+    /**
+     * Returns the name of the client by pid or <code>null</code> if pid is unknown
+     * @param pid the pid of the client.
+     */
+    public String getClientName(int pid);
+
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IShellOutputReceiver.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IShellOutputReceiver.java
new file mode 100644
index 0000000..fb671bb
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IShellOutputReceiver.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+/**
+ * Classes which implement this interface provide methods that deal with out from a remote shell
+ * command on a device/emulator.
+ */
+public interface IShellOutputReceiver {
+    /**
+     * Called every time some new data is available.
+     * @param data The new data.
+     * @param offset The offset at which the new data starts.
+     * @param length The length of the new data.
+     */
+    public void addOutput(byte[] data, int offset, int length);
+
+    /**
+     * Called at the end of the process execution (unless the process was
+     * canceled). This allows the receiver to terminate and flush whatever
+     * data was not yet processed.
+     */
+    public void flush();
+
+    /**
+     * Cancel method to stop the execution of the remote shell command.
+     * @return true to cancel the execution of the command.
+     */
+    public boolean isCancelled();
+};
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IStackTraceInfo.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IStackTraceInfo.java
new file mode 100644
index 0000000..3b9d730
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IStackTraceInfo.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+/**
+ * Classes which implement this interface provide a method that returns a stack trace.
+ */
+public interface IStackTraceInfo {
+
+    /**
+     * Returns the stack trace. This can be <code>null</code>.
+     */
+    public StackTraceElement[] getStackTrace();
+
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/JdwpPacket.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/JdwpPacket.java
new file mode 100644
index 0000000..92bbb82
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/JdwpPacket.java
@@ -0,0 +1,371 @@
+/* //device/tools/ddms/libs/ddmlib/src/com/android/ddmlib/JdwpPacket.java
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.ddmlib;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.SocketChannel;
+
+/**
+ * A JDWP packet, sitting at the start of a ByteBuffer somewhere.
+ *
+ * This allows us to wrap a "pointer" to the data with the results of
+ * decoding the packet.
+ *
+ * None of the operations here are synchronized.  If multiple threads will
+ * be accessing the same ByteBuffers, external sync will be required.
+ *
+ * Use the constructor to create an empty packet, or "findPacket()" to
+ * wrap a JdwpPacket around existing data.
+ */
+final class JdwpPacket {
+    // header len
+    public static final int JDWP_HEADER_LEN = 11;
+
+    // results from findHandshake
+    public static final int HANDSHAKE_GOOD = 1;
+    public static final int HANDSHAKE_NOTYET = 2;
+    public static final int HANDSHAKE_BAD = 3;
+
+    // our cmdSet/cmd
+    private static final int DDMS_CMD_SET = 0xc7;       // 'G' + 128
+    private static final int DDMS_CMD = 0x01;
+
+    // "flags" field
+    private static final int REPLY_PACKET = 0x80;
+
+    // this is sent and expected at the start of a JDWP connection
+    private static final byte[] mHandshake = {
+        'J', 'D', 'W', 'P', '-', 'H', 'a', 'n', 'd', 's', 'h', 'a', 'k', 'e'
+    };
+
+    public static final int HANDSHAKE_LEN = mHandshake.length;
+
+    private ByteBuffer mBuffer;
+    private int mLength, mId, mFlags, mCmdSet, mCmd, mErrCode;
+    private boolean mIsNew;
+
+    private static int mSerialId = 0x40000000;
+
+
+    /**
+     * Create a new, empty packet, in "buf".
+     */
+    JdwpPacket(ByteBuffer buf) {
+        mBuffer = buf;
+        mIsNew = true;
+    }
+
+    /**
+     * Finish a packet created with newPacket().
+     *
+     * This always creates a command packet, with the next serial number
+     * in sequence.
+     *
+     * We have to take "payloadLength" as an argument because we can't
+     * see the position in the "slice" returned by getPayload().  We could
+     * fish it out of the chunk header, but it's legal for there to be
+     * more than one chunk in a JDWP packet.
+     *
+     * On exit, "position" points to the end of the data.
+     */
+    void finishPacket(int payloadLength) {
+        assert mIsNew;
+
+        ByteOrder oldOrder = mBuffer.order();
+        mBuffer.order(ChunkHandler.CHUNK_ORDER);
+
+        mLength = JDWP_HEADER_LEN + payloadLength;
+        mId = getNextSerial();
+        mFlags = 0;
+        mCmdSet = DDMS_CMD_SET;
+        mCmd = DDMS_CMD;
+
+        mBuffer.putInt(0x00, mLength);
+        mBuffer.putInt(0x04, mId);
+        mBuffer.put(0x08, (byte) mFlags);
+        mBuffer.put(0x09, (byte) mCmdSet);
+        mBuffer.put(0x0a, (byte) mCmd);
+
+        mBuffer.order(oldOrder);
+        mBuffer.position(mLength);
+    }
+
+    /**
+     * Get the next serial number.  This creates a unique serial number
+     * across all connections, not just for the current connection.  This
+     * is a useful property when debugging, but isn't necessary.
+     *
+     * We can't synchronize on an int, so we use a sync method.
+     */
+    private static synchronized int getNextSerial() {
+        return mSerialId++;
+    }
+
+    /**
+     * Return a slice of the byte buffer, positioned past the JDWP header
+     * to the start of the chunk header.  The buffer's limit will be set
+     * to the size of the payload if the size is known; if this is a
+     * packet under construction the limit will be set to the end of the
+     * buffer.
+     *
+     * Doesn't examine the packet at all -- works on empty buffers.
+     */
+    ByteBuffer getPayload() {
+        ByteBuffer buf;
+        int oldPosn = mBuffer.position();
+
+        mBuffer.position(JDWP_HEADER_LEN);
+        buf = mBuffer.slice();     // goes from position to limit
+        mBuffer.position(oldPosn);
+
+        if (mLength > 0)
+            buf.limit(mLength - JDWP_HEADER_LEN);
+        else
+            assert mIsNew;
+        buf.order(ChunkHandler.CHUNK_ORDER);
+        return buf;
+    }
+
+    /**
+     * Returns "true" if this JDWP packet has a JDWP command type.
+     *
+     * This never returns "true" for reply packets.
+     */
+    boolean isDdmPacket() {
+        return (mFlags & REPLY_PACKET) == 0 &&
+               mCmdSet == DDMS_CMD_SET &&
+               mCmd == DDMS_CMD;
+    }
+
+    /**
+     * Returns "true" if this JDWP packet is tagged as a reply.
+     */
+    boolean isReply() {
+        return (mFlags & REPLY_PACKET) != 0;
+    }
+
+    /**
+     * Returns "true" if this JDWP packet is a reply with a nonzero
+     * error code.
+     */
+    boolean isError() {
+        return isReply() && mErrCode != 0;
+    }
+
+    /**
+     * Returns "true" if this JDWP packet has no data.
+     */
+    boolean isEmpty() {
+        return (mLength == JDWP_HEADER_LEN);
+    }
+
+    /**
+     * Return the packet's ID.  For a reply packet, this allows us to
+     * match the reply with the original request.
+     */
+    int getId() {
+        return mId;
+    }
+
+    /**
+     * Return the length of a packet.  This includes the header, so an
+     * empty packet is 11 bytes long.
+     */
+    int getLength() {
+        return mLength;
+    }
+
+    /**
+     * Write our packet to "chan".  Consumes the packet as part of the
+     * write.
+     *
+     * The JDWP packet starts at offset 0 and ends at mBuffer.position().
+     */
+    void writeAndConsume(SocketChannel chan) throws IOException {
+        int oldLimit;
+
+        //Log.i("ddms", "writeAndConsume: pos=" + mBuffer.position()
+        //    + ", limit=" + mBuffer.limit());
+
+        assert mLength > 0;
+
+        mBuffer.flip();         // limit<-posn, posn<-0
+        oldLimit = mBuffer.limit();
+        mBuffer.limit(mLength);
+        while (mBuffer.position() != mBuffer.limit()) {
+            chan.write(mBuffer);
+        }
+        // position should now be at end of packet
+        assert mBuffer.position() == mLength;
+
+        mBuffer.limit(oldLimit);
+        mBuffer.compact();      // shift posn...limit, posn<-pending data
+
+        //Log.i("ddms", "               : pos=" + mBuffer.position()
+        //    + ", limit=" + mBuffer.limit());
+    }
+
+    /**
+     * "Move" the packet data out of the buffer we're sitting on and into
+     * buf at the current position.
+     */
+    void movePacket(ByteBuffer buf) {
+        Log.v("ddms", "moving " + mLength + " bytes");
+        int oldPosn = mBuffer.position();
+
+        mBuffer.position(0);
+        mBuffer.limit(mLength);
+        buf.put(mBuffer);
+        mBuffer.position(mLength);
+        mBuffer.limit(oldPosn);
+        mBuffer.compact();      // shift posn...limit, posn<-pending data
+    }
+
+    /**
+     * Consume the JDWP packet.
+     *
+     * On entry and exit, "position" is the #of bytes in the buffer.
+     */
+    void consume()
+    {
+        //Log.d("ddms", "consuming " + mLength + " bytes");
+        //Log.d("ddms", "  posn=" + mBuffer.position()
+        //    + ", limit=" + mBuffer.limit());
+
+        /*
+         * The "flip" call sets "limit" equal to the position (usually the
+         * end of data) and "position" equal to zero.
+         *
+         * compact() copies everything from "position" and "limit" to the
+         * start of the buffer, sets "position" to the end of data, and
+         * sets "limit" to the capacity.
+         *
+         * On entry, "position" is set to the amount of data in the buffer
+         * and "limit" is set to the capacity.  We want to call flip()
+         * so that position..limit spans our data, advance "position" past
+         * the current packet, then compact.
+         */
+        mBuffer.flip();         // limit<-posn, posn<-0
+        mBuffer.position(mLength);
+        mBuffer.compact();      // shift posn...limit, posn<-pending data
+        mLength = 0;
+        //Log.d("ddms", "  after compact, posn=" + mBuffer.position()
+        //    + ", limit=" + mBuffer.limit());
+    }
+
+    /**
+     * Find the JDWP packet at the start of "buf".  The start is known,
+     * but the length has to be parsed out.
+     *
+     * On entry, the packet data in "buf" must start at offset 0 and end
+     * at "position".  "limit" should be set to the buffer capacity.  This
+     * method does not alter "buf"s attributes.
+     *
+     * Returns a new JdwpPacket if a full one is found in the buffer.  If
+     * not, returns null.  Throws an exception if the data doesn't look like
+     * a valid JDWP packet.
+     */
+    static JdwpPacket findPacket(ByteBuffer buf) {
+        int count = buf.position();
+        int length, id, flags, cmdSet, cmd;
+
+        if (count < JDWP_HEADER_LEN)
+            return null;
+
+        ByteOrder oldOrder = buf.order();
+        buf.order(ChunkHandler.CHUNK_ORDER);
+
+        length = buf.getInt(0x00);
+        id = buf.getInt(0x04);
+        flags = buf.get(0x08) & 0xff;
+        cmdSet = buf.get(0x09) & 0xff;
+        cmd = buf.get(0x0a) & 0xff;
+
+        buf.order(oldOrder);
+
+        if (length < JDWP_HEADER_LEN)
+            throw new BadPacketException();
+        if (count < length)
+            return null;
+
+        JdwpPacket pkt = new JdwpPacket(buf);
+        //pkt.mBuffer = buf;
+        pkt.mLength = length;
+        pkt.mId = id;
+        pkt.mFlags = flags;
+
+        if ((flags & REPLY_PACKET) == 0) {
+            pkt.mCmdSet = cmdSet;
+            pkt.mCmd = cmd;
+            pkt.mErrCode = -1;
+        } else {
+            pkt.mCmdSet = -1;
+            pkt.mCmd = -1;
+            pkt.mErrCode = cmdSet | (cmd << 8);
+        }
+
+        return pkt;
+    }
+
+    /**
+     * Like findPacket(), but when we're expecting the JDWP handshake.
+     *
+     * Returns one of:
+     *   HANDSHAKE_GOOD   - found handshake, looks good
+     *   HANDSHAKE_BAD    - found enough data, but it's wrong
+     *   HANDSHAKE_NOTYET - not enough data has been read yet
+     */
+    static int findHandshake(ByteBuffer buf) {
+        int count = buf.position();
+        int i;
+
+        if (count < mHandshake.length)
+            return HANDSHAKE_NOTYET;
+
+        for (i = mHandshake.length -1; i >= 0; --i) {
+            if (buf.get(i) != mHandshake[i])
+                return HANDSHAKE_BAD;
+        }
+
+        return HANDSHAKE_GOOD;
+    }
+
+    /**
+     * Remove the handshake string from the buffer.
+     *
+     * On entry and exit, "position" is the #of bytes in the buffer.
+     */
+    static void consumeHandshake(ByteBuffer buf) {
+        // in theory, nothing else can have arrived, so this is overkill
+        buf.flip();         // limit<-posn, posn<-0
+        buf.position(mHandshake.length);
+        buf.compact();      // shift posn...limit, posn<-pending data
+    }
+
+    /**
+     * Copy the handshake string into the output buffer.
+     *
+     * On exit, "buf"s position will be advanced.
+     */
+    static void putHandshake(ByteBuffer buf) {
+        buf.put(mHandshake);
+    }
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Log.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Log.java
new file mode 100644
index 0000000..ce95b04
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Log.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * Log class that mirrors the API in main Android sources.
+ * <p/>Default behavior outputs the log to {@link System#out}. Use
+ * {@link #setLogOutput(com.android.ddmlib.Log.ILogOutput)} to redirect the log somewhere else.
+ */
+public final class Log {
+
+    /**
+     * Log Level enum.
+     */
+    public enum LogLevel {
+        VERBOSE(2, "verbose", 'V'), //$NON-NLS-1$
+        DEBUG(3, "debug", 'D'), //$NON-NLS-1$
+        INFO(4, "info", 'I'), //$NON-NLS-1$
+        WARN(5, "warn", 'W'), //$NON-NLS-1$
+        ERROR(6, "error", 'E'), //$NON-NLS-1$
+        ASSERT(7, "assert", 'A'); //$NON-NLS-1$
+
+        private int mPriorityLevel;
+        private String mStringValue;
+        private char mPriorityLetter;
+
+        LogLevel(int intPriority, String stringValue, char priorityChar) {
+            mPriorityLevel = intPriority;
+            mStringValue = stringValue;
+            mPriorityLetter = priorityChar;
+        }
+
+        public static LogLevel getByString(String value) {
+            for (LogLevel mode : values()) {
+                if (mode.mStringValue.equals(value)) {
+                    return mode;
+                }
+            }
+
+            return null;
+        }
+        
+        /**
+         * Returns the {@link LogLevel} enum matching the specified letter.
+         * @param letter the letter matching a <code>LogLevel</code> enum
+         * @return a <code>LogLevel</code> object or <code>null</code> if no match were found.
+         */
+        public static LogLevel getByLetter(char letter) {
+            for (LogLevel mode : values()) {
+                if (mode.mPriorityLetter == letter) {
+                    return mode;
+                }
+            }
+
+            return null;
+        }
+
+        /**
+         * Returns the {@link LogLevel} enum matching the specified letter.
+         * <p/>
+         * The letter is passed as a {@link String} argument, but only the first character
+         * is used. 
+         * @param letter the letter matching a <code>LogLevel</code> enum
+         * @return a <code>LogLevel</code> object or <code>null</code> if no match were found.
+         */
+        public static LogLevel getByLetterString(String letter) {
+            if (letter.length() > 0) {
+                return getByLetter(letter.charAt(0));
+            }
+
+            return null;
+        }
+
+        /**
+         * Returns the letter identifying the priority of the {@link LogLevel}.
+         */
+        public char getPriorityLetter() {
+            return mPriorityLetter;
+        }
+
+        /**
+         * Returns the numerical value of the priority.
+         */
+        public int getPriority() {
+            return mPriorityLevel;
+        }
+
+        /**
+         * Returns a non translated string representing the LogLevel.
+         */
+        public String getStringValue() {
+            return mStringValue;
+        }
+    }
+    
+    /**
+     * Classes which implement this interface provides methods that deal with outputting log
+     * messages.
+     */
+    public interface ILogOutput {
+        /**
+         * Sent when a log message needs to be printed.
+         * @param logLevel The {@link LogLevel} enum representing the priority of the message.
+         * @param tag The tag associated with the message.
+         * @param message The message to display.
+         */
+        public void printLog(LogLevel logLevel, String tag, String message);
+
+        /**
+         * Sent when a log message needs to be printed, and, if possible, displayed to the user
+         * in a dialog box.
+         * @param logLevel The {@link LogLevel} enum representing the priority of the message.
+         * @param tag The tag associated with the message.
+         * @param message The message to display.
+         */
+        public void printAndPromptLog(LogLevel logLevel, String tag, String message);
+    }
+
+    private static LogLevel mLevel = DdmPreferences.getLogLevel();
+
+    private static ILogOutput sLogOutput;
+
+    private static final char[] mSpaceLine = new char[72];
+    private static final char[] mHexDigit = new char[]
+        { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
+    static {
+        /* prep for hex dump */
+        int i = mSpaceLine.length-1;
+        while (i >= 0)
+            mSpaceLine[i--] = ' ';
+        mSpaceLine[0] = mSpaceLine[1] = mSpaceLine[2] = mSpaceLine[3] = '0';
+        mSpaceLine[4] = '-';
+    }
+
+    static final class Config {
+        static final boolean LOGV = true;
+        static final boolean LOGD = true;
+    };
+
+    private Log() {}
+
+    /**
+     * Outputs a {@link LogLevel#VERBOSE} level message.
+     * @param tag The tag associated with the message.
+     * @param message The message to output.
+     */
+    public static void v(String tag, String message) {
+        println(LogLevel.VERBOSE, tag, message);
+    }
+
+    /**
+     * Outputs a {@link LogLevel#DEBUG} level message.
+     * @param tag The tag associated with the message.
+     * @param message The message to output.
+     */
+    public static void d(String tag, String message) {
+        println(LogLevel.DEBUG, tag, message);
+    }
+
+    /**
+     * Outputs a {@link LogLevel#INFO} level message.
+     * @param tag The tag associated with the message.
+     * @param message The message to output.
+     */
+    public static void i(String tag, String message) {
+        println(LogLevel.INFO, tag, message);
+    }
+
+    /**
+     * Outputs a {@link LogLevel#WARN} level message.
+     * @param tag The tag associated with the message.
+     * @param message The message to output.
+     */
+    public static void w(String tag, String message) {
+        println(LogLevel.WARN, tag, message);
+    }
+
+    /**
+     * Outputs a {@link LogLevel#ERROR} level message.
+     * @param tag The tag associated with the message.
+     * @param message The message to output.
+     */
+    public static void e(String tag, String message) {
+        println(LogLevel.ERROR, tag, message);
+    }
+
+    /**
+     * Outputs a log message and attempts to display it in a dialog.
+     * @param tag The tag associated with the message.
+     * @param message The message to output.
+     */
+    public static void logAndDisplay(LogLevel logLevel, String tag, String message) {
+        if (sLogOutput != null) {
+            sLogOutput.printAndPromptLog(logLevel, tag, message);
+        } else {
+            println(logLevel, tag, message);
+        }
+    }
+
+    /**
+     * Outputs a {@link LogLevel#ERROR} level {@link Throwable} information.
+     * @param tag The tag associated with the message.
+     * @param throwable The {@link Throwable} to output.
+     */
+    public static void e(String tag, Throwable throwable) {
+        if (throwable != null) {
+            StringWriter sw = new StringWriter();
+            PrintWriter pw = new PrintWriter(sw);
+
+            throwable.printStackTrace(pw);
+            println(LogLevel.ERROR, tag, throwable.getMessage() + '\n' + sw.toString());
+        }
+    }
+
+    static void setLevel(LogLevel logLevel) {
+        mLevel = logLevel;
+    }
+
+    /**
+     * Sets the {@link ILogOutput} to use to print the logs. If not set, {@link System#out}
+     * will be used.
+     * @param logOutput The {@link ILogOutput} to use to print the log.
+     */
+    public static void setLogOutput(ILogOutput logOutput) {
+        sLogOutput = logOutput;
+    }
+
+    /**
+     * Show hex dump.
+     * <p/>
+     * Local addition.  Output looks like:
+     * 1230- 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  0123456789abcdef
+     * <p/>
+     * Uses no string concatenation; creates one String object per line.
+     */
+    static void hexDump(String tag, LogLevel level, byte[] data, int offset, int length) {
+
+        int kHexOffset = 6;
+        int kAscOffset = 55;
+        char[] line = new char[mSpaceLine.length];
+        int addr, baseAddr, count;
+        int i, ch;
+        boolean needErase = true;
+
+        //Log.w(tag, "HEX DUMP: off=" + offset + ", length=" + length);
+
+        baseAddr = 0;
+        while (length != 0) {
+            if (length > 16) {
+                // full line
+                count = 16;
+            } else {
+                // partial line; re-copy blanks to clear end
+                count = length;
+                needErase = true;
+            }
+
+            if (needErase) {
+                System.arraycopy(mSpaceLine, 0, line, 0, mSpaceLine.length);
+                needErase = false;
+            }
+
+            // output the address (currently limited to 4 hex digits)
+            addr = baseAddr;
+            addr &= 0xffff;
+            ch = 3;
+            while (addr != 0) {
+                line[ch] = mHexDigit[addr & 0x0f];
+                ch--;
+                addr >>>= 4;
+            }
+
+            // output hex digits and ASCII chars
+            ch = kHexOffset;
+            for (i = 0; i < count; i++) {
+                byte val = data[offset + i];
+
+                line[ch++] = mHexDigit[(val >>> 4) & 0x0f];
+                line[ch++] = mHexDigit[val & 0x0f];
+                ch++;
+
+                if (val >= 0x20 && val < 0x7f)
+                    line[kAscOffset + i] = (char) val;
+                else
+                    line[kAscOffset + i] = '.';
+            }
+
+            println(level, tag, new String(line));
+
+            // advance to next chunk of data
+            length -= count;
+            offset += count;
+            baseAddr += count;
+        }
+
+    }
+
+    /**
+     * Dump the entire contents of a byte array with DEBUG priority.
+     */
+    static void hexDump(byte[] data) {
+        hexDump("ddms", LogLevel.DEBUG, data, 0, data.length);
+    }
+
+    /* currently prints to stdout; could write to a log window */
+    private static void println(LogLevel logLevel, String tag, String message) {
+        if (logLevel.getPriority() >= mLevel.getPriority()) {
+            if (sLogOutput != null) {
+                sLogOutput.printLog(logLevel, tag, message);
+            } else {
+                printLog(logLevel, tag, message);
+            }
+        }
+    }
+    
+    /**
+     * Prints a log message.
+     * @param logLevel
+     * @param tag
+     * @param message
+     */
+    public static void printLog(LogLevel logLevel, String tag, String message) {
+        long msec;
+        
+        msec = System.currentTimeMillis();
+        String outMessage = String.format("%02d:%02d %c/%s: %s\n",
+                (msec / 60000) % 60, (msec / 1000) % 60,
+                logLevel.getPriorityLetter(), tag, message);
+        System.out.print(outMessage);
+    }
+
+}
+
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MonitorThread.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MonitorThread.java
new file mode 100644
index 0000000..79eb5bb
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MonitorThread.java
@@ -0,0 +1,780 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+
+import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
+import com.android.ddmlib.Log.LogLevel;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+import java.nio.channels.CancelledKeyException;
+import java.nio.channels.NotYetBoundException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Monitor open connections.
+ */
+final class MonitorThread extends Thread {
+
+    // For broadcasts to message handlers
+    //private static final int CLIENT_CONNECTED = 1;
+
+    private static final int CLIENT_READY = 2;
+
+    private static final int CLIENT_DISCONNECTED = 3;
+
+    private volatile boolean mQuit = false;
+
+    // List of clients we're paying attention to
+    private ArrayList<Client> mClientList;
+
+    // The almighty mux
+    private Selector mSelector;
+
+    // Map chunk types to handlers
+    private HashMap<Integer, ChunkHandler> mHandlerMap;
+
+    // port for "debug selected"
+    private ServerSocketChannel mDebugSelectedChan;
+
+    private int mNewDebugSelectedPort;
+
+    private int mDebugSelectedPort = -1;
+
+    /**
+     * "Selected" client setup to answer debugging connection to the mNewDebugSelectedPort port.
+     */
+    private Client mSelectedClient = null;
+
+    // singleton
+    private static MonitorThread mInstance;
+
+    /**
+     * Generic constructor.
+     */
+    private MonitorThread() {
+        super("Monitor");
+        mClientList = new ArrayList<Client>();
+        mHandlerMap = new HashMap<Integer, ChunkHandler>();
+
+        mNewDebugSelectedPort = DdmPreferences.getSelectedDebugPort();
+    }
+
+    /**
+     * Creates and return the singleton instance of the client monitor thread.
+     */
+    static MonitorThread createInstance() {
+        return mInstance = new MonitorThread();
+    }
+
+    /**
+     * Get singleton instance of the client monitor thread.
+     */
+    static MonitorThread getInstance() {
+        return mInstance;
+    }
+
+
+    /**
+     * Sets or changes the port number for "debug selected". 
+     */
+    synchronized void setDebugSelectedPort(int port) throws IllegalStateException {
+        if (mInstance == null) {
+            return;
+        }
+
+        if (AndroidDebugBridge.getClientSupport() == false) {
+            return;
+        }
+
+        if (mDebugSelectedChan != null) {
+            Log.d("ddms", "Changing debug-selected port to " + port);
+            mNewDebugSelectedPort = port;
+            wakeup();
+        } else {
+            // we set mNewDebugSelectedPort instead of mDebugSelectedPort so that it's automatically
+            // opened on the first run loop.
+            mNewDebugSelectedPort = port;
+        }
+    }
+
+    /**
+     * Sets the client to accept debugger connection on the custom "Selected debug port".
+     * @param selectedClient the client. Can be null.
+     */
+    synchronized void setSelectedClient(Client selectedClient) {
+        if (mInstance == null) {
+            return;
+        }
+
+        if (mSelectedClient != selectedClient) {
+            Client oldClient = mSelectedClient;
+            mSelectedClient = selectedClient;
+
+            if (oldClient != null) {
+                oldClient.update(Client.CHANGE_PORT);
+            }
+
+            if (mSelectedClient != null) {
+                mSelectedClient.update(Client.CHANGE_PORT);
+            }
+        }
+    }
+
+    /**
+     * Returns the client accepting debugger connection on the custom "Selected debug port".
+     */
+    Client getSelectedClient() {
+        return mSelectedClient;
+    }
+
+
+    /**
+     * Returns "true" if we want to retry connections to clients if we get a bad
+     * JDWP handshake back, "false" if we want to just mark them as bad and
+     * leave them alone.
+     */
+    boolean getRetryOnBadHandshake() {
+        return true; // TODO? make configurable
+    }
+
+    /**
+     * Get an array of known clients.
+     */
+    Client[] getClients() {
+        synchronized (mClientList) {
+            return mClientList.toArray(new Client[0]);
+        }
+    }
+
+    /**
+     * Register "handler" as the handler for type "type".
+     */
+    synchronized void registerChunkHandler(int type, ChunkHandler handler) {
+        if (mInstance == null) {
+            return;
+        }
+
+        synchronized (mHandlerMap) {
+            if (mHandlerMap.get(type) == null) {
+                mHandlerMap.put(type, handler);
+            }
+        }
+    }
+
+    /**
+     * Watch for activity from clients and debuggers.
+     */
+    @Override
+    public void run() {
+        Log.d("ddms", "Monitor is up");
+
+        // create a selector
+        try {
+            mSelector = Selector.open();
+        } catch (IOException ioe) {
+            Log.logAndDisplay(LogLevel.ERROR, "ddms",
+                    "Failed to initialize Monitor Thread: " + ioe.getMessage());
+            return;
+        }
+
+        while (!mQuit) {
+            
+            try {
+                /*
+                 * sync with new registrations: we wait until addClient is done before going through
+                 * and doing mSelector.select() again.
+                 * @see {@link #addClient(Client)}
+                 */
+                synchronized (mClientList) {
+                }
+    
+                // (re-)open the "debug selected" port, if it's not opened yet or
+                // if the port changed.
+                try {
+                    if (AndroidDebugBridge.getClientSupport()) {
+                        if ((mDebugSelectedChan == null ||
+                                mNewDebugSelectedPort != mDebugSelectedPort) &&
+                                mNewDebugSelectedPort != -1) {
+                            if (reopenDebugSelectedPort()) {
+                                mDebugSelectedPort = mNewDebugSelectedPort;
+                            }
+                        }
+                    }
+                } catch (IOException ioe) {
+                    Log.e("ddms",
+                            "Failed to reopen debug port for Selected Client to: " + mNewDebugSelectedPort);
+                    Log.e("ddms", ioe);
+                    mNewDebugSelectedPort = mDebugSelectedPort; // no retry
+                }
+    
+                int count;
+                try {
+                    count = mSelector.select();
+                } catch (IOException ioe) {
+                    ioe.printStackTrace();
+                    continue;
+                } catch (CancelledKeyException cke) {
+                    continue;
+                }
+    
+                if (count == 0) {
+                    // somebody called wakeup() ?
+                    // Log.i("ddms", "selector looping");
+                    continue;
+                }
+    
+                Set<SelectionKey> keys = mSelector.selectedKeys();
+                Iterator<SelectionKey> iter = keys.iterator();
+    
+                while (iter.hasNext()) {
+                    SelectionKey key = iter.next();
+                    iter.remove();
+    
+                    try {
+                        if (key.attachment() instanceof Client) {
+                            processClientActivity(key);
+                        }
+                        else if (key.attachment() instanceof Debugger) {
+                            processDebuggerActivity(key);
+                        }
+                        else if (key.attachment() instanceof MonitorThread) {
+                            processDebugSelectedActivity(key);
+                        }
+                        else {
+                            Log.e("ddms", "unknown activity key");
+                        }
+                    } catch (Exception e) {
+                        // we don't want to have our thread be killed because of any uncaught
+                        // exception, so we intercept all here.
+                        Log.e("ddms", "Exception during activity from Selector.");
+                        Log.e("ddms", e);
+                    }
+                }
+            } catch (Exception e) {
+                // we don't want to have our thread be killed because of any uncaught
+                // exception, so we intercept all here.
+                Log.e("ddms", "Exception MonitorThread.run()");
+                Log.e("ddms", e);
+            }
+        }
+    }
+
+
+    /**
+     * Returns the port on which the selected client listen for debugger
+     */
+    int getDebugSelectedPort() {
+        return mDebugSelectedPort;
+    }
+
+    /*
+     * Something happened. Figure out what.
+     */
+    private void processClientActivity(SelectionKey key) {
+        Client client = (Client)key.attachment();
+        
+        try {
+            if (key.isReadable() == false || key.isValid() == false) {
+                Log.d("ddms", "Invalid key from " + client + ". Dropping client.");
+                dropClient(client, true /* notify */);
+                return;
+            }
+
+            client.read();
+
+            /*
+             * See if we have a full packet in the buffer. It's possible we have
+             * more than one packet, so we have to loop.
+             */
+            JdwpPacket packet = client.getJdwpPacket();
+            while (packet != null) {
+                if (packet.isDdmPacket()) {
+                    // unsolicited DDM request - hand it off
+                    assert !packet.isReply();
+                    callHandler(client, packet, null);
+                    packet.consume();
+                } else if (packet.isReply()
+                        && client.isResponseToUs(packet.getId()) != null) {
+                    // reply to earlier DDM request
+                    ChunkHandler handler = client
+                            .isResponseToUs(packet.getId());
+                    if (packet.isError())
+                        client.packetFailed(packet);
+                    else if (packet.isEmpty())
+                        Log.d("ddms", "Got empty reply for 0x"
+                                + Integer.toHexString(packet.getId())
+                                + " from " + client);
+                    else
+                        callHandler(client, packet, handler);
+                    packet.consume();
+                    client.removeRequestId(packet.getId());
+                } else {
+                    Log.v("ddms", "Forwarding client "
+                            + (packet.isReply() ? "reply" : "event") + " 0x"
+                            + Integer.toHexString(packet.getId()) + " to "
+                            + client.getDebugger());
+                    client.forwardPacketToDebugger(packet);
+                }
+
+                // find next
+                packet = client.getJdwpPacket();
+            }
+        } catch (CancelledKeyException e) {
+            // key was canceled probably due to a disconnected client before we could
+            // read stuff coming from the client, so we drop it.
+            dropClient(client, true /* notify */);
+        } catch (IOException ex) {
+            // something closed down, no need to print anything. The client is simply dropped.
+            dropClient(client, true /* notify */);
+        } catch (Exception ex) {
+            Log.e("ddms", ex);
+
+            /* close the client; automatically un-registers from selector */
+            dropClient(client, true /* notify */);
+
+            if (ex instanceof BufferOverflowException) {
+                Log.w("ddms",
+                        "Client data packet exceeded maximum buffer size "
+                                + client);
+            } else {
+                // don't know what this is, display it
+                Log.e("ddms", ex);
+            }
+        }
+    }
+
+    /*
+     * Process an incoming DDM packet. If this is a reply to an earlier request,
+     * "handler" will be set to the handler responsible for the original
+     * request. The spec allows a JDWP message to include multiple DDM chunks.
+     */
+    private void callHandler(Client client, JdwpPacket packet,
+            ChunkHandler handler) {
+
+        // on first DDM packet received, broadcast a "ready" message
+        if (!client.ddmSeen())
+            broadcast(CLIENT_READY, client);
+
+        ByteBuffer buf = packet.getPayload();
+        int type, length;
+        boolean reply = true;
+
+        type = buf.getInt();
+        length = buf.getInt();
+
+        if (handler == null) {
+            // not a reply, figure out who wants it
+            synchronized (mHandlerMap) {
+                handler = mHandlerMap.get(type);
+                reply = false;
+            }
+        }
+
+        if (handler == null) {
+            Log.w("ddms", "Received unsupported chunk type "
+                    + ChunkHandler.name(type) + " (len=" + length + ")");
+        } else {
+            Log.d("ddms", "Calling handler for " + ChunkHandler.name(type)
+                    + " [" + handler + "] (len=" + length + ")");
+            ByteBuffer ibuf = buf.slice();
+            ByteBuffer roBuf = ibuf.asReadOnlyBuffer(); // enforce R/O
+            roBuf.order(ChunkHandler.CHUNK_ORDER);
+            // do the handling of the chunk synchronized on the client list
+            // to be sure there's no concurrency issue when we look for HOME
+            // in hasApp()
+            synchronized (mClientList) {
+                handler.handleChunk(client, type, roBuf, reply, packet.getId());
+            }
+        }
+    }
+
+    /**
+     * Drops a client from the monitor.
+     * <p/>This will lock the {@link Client} list of the {@link Device} running <var>client</var>.
+     * @param client
+     * @param notify
+     */
+    synchronized void dropClient(Client client, boolean notify) {
+        if (mInstance == null) { 
+            return;
+        }
+
+        synchronized (mClientList) {
+            if (mClientList.remove(client) == false) {
+                return;
+            }
+        }
+        client.close(notify);
+        broadcast(CLIENT_DISCONNECTED, client);
+
+        /*
+         * http://forum.java.sun.com/thread.jspa?threadID=726715&start=0
+         * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5073504
+         */
+        wakeup();
+    }
+
+    /*
+     * Process activity from one of the debugger sockets. This could be a new
+     * connection or a data packet.
+     */
+    private void processDebuggerActivity(SelectionKey key) {
+        Debugger dbg = (Debugger)key.attachment();
+
+        try {
+            if (key.isAcceptable()) {
+                try {
+                    acceptNewDebugger(dbg, null);
+                } catch (IOException ioe) {
+                    Log.w("ddms", "debugger accept() failed");
+                    ioe.printStackTrace();
+                }
+            } else if (key.isReadable()) {
+                processDebuggerData(key);
+            } else {
+                Log.d("ddm-debugger", "key in unknown state");
+            }
+        } catch (CancelledKeyException cke) {
+            // key has been cancelled we can ignore that.
+        }
+    }
+
+    /*
+     * Accept a new connection from a debugger. If successful, register it with
+     * the Selector.
+     */
+    private void acceptNewDebugger(Debugger dbg, ServerSocketChannel acceptChan)
+            throws IOException {
+
+        synchronized (mClientList) {
+            SocketChannel chan;
+
+            if (acceptChan == null)
+                chan = dbg.accept();
+            else
+                chan = dbg.accept(acceptChan);
+
+            if (chan != null) {
+                chan.socket().setTcpNoDelay(true);
+
+                wakeup();
+
+                try {
+                    chan.register(mSelector, SelectionKey.OP_READ, dbg);
+                } catch (IOException ioe) {
+                    // failed, drop the connection
+                    dbg.closeData();
+                    throw ioe;
+                } catch (RuntimeException re) {
+                    // failed, drop the connection
+                    dbg.closeData();
+                    throw re;
+                }
+            } else {
+                Log.i("ddms", "ignoring duplicate debugger");
+                // new connection already closed
+            }
+        }
+    }
+
+    /*
+     * We have incoming data from the debugger. Forward it to the client.
+     */
+    private void processDebuggerData(SelectionKey key) {
+        Debugger dbg = (Debugger)key.attachment();
+
+        try {
+            /*
+             * Read pending data.
+             */
+            dbg.read();
+
+            /*
+             * See if we have a full packet in the buffer. It's possible we have
+             * more than one packet, so we have to loop.
+             */
+            JdwpPacket packet = dbg.getJdwpPacket();
+            while (packet != null) {
+                Log.v("ddms", "Forwarding dbg req 0x"
+                        + Integer.toHexString(packet.getId()) + " to "
+                        + dbg.getClient());
+
+                dbg.forwardPacketToClient(packet);
+
+                packet = dbg.getJdwpPacket();
+            }
+        } catch (IOException ioe) {
+            /*
+             * Close data connection; automatically un-registers dbg from
+             * selector. The failure could be caused by the debugger going away,
+             * or by the client going away and failing to accept our data.
+             * Either way, the debugger connection does not need to exist any
+             * longer. We also need to recycle the connection to the client, so
+             * that the VM sees the debugger disconnect. For a DDM-aware client
+             * this won't be necessary, and we can just send a "debugger
+             * disconnected" message.
+             */
+            Log.i("ddms", "Closing connection to debugger " + dbg);
+            dbg.closeData();
+            Client client = dbg.getClient();
+            if (client.isDdmAware()) {
+                // TODO: soft-disconnect DDM-aware clients
+                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,
+                        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,
+                        IDebugPortProvider.NO_STATIC_PORT);
+            }
+        }
+    }
+
+    /*
+     * Tell the thread that something has changed.
+     */
+    private void wakeup() {
+        mSelector.wakeup();
+    }
+
+    /**
+     * Tell the thread to stop. Called from UI thread.
+     */
+    synchronized void quit() {
+        mQuit = true;
+        wakeup();
+        Log.d("ddms", "Waiting for Monitor thread");
+        try {
+            this.join();
+            // since we're quitting, lets drop all the client and disconnect
+            // the DebugSelectedPort
+            synchronized (mClientList) {
+                for (Client c : mClientList) {
+                    c.close(false /* notify */);
+                    broadcast(CLIENT_DISCONNECTED, c);
+                }
+                mClientList.clear();
+            }
+
+            if (mDebugSelectedChan != null) {
+                mDebugSelectedChan.close();
+                mDebugSelectedChan.socket().close();
+                mDebugSelectedChan = null;
+            }
+            mSelector.close();
+        } catch (InterruptedException ie) {
+            ie.printStackTrace();
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+        mInstance = null;
+    }
+
+    /**
+     * Add a new Client to the list of things we monitor. Also adds the client's
+     * channel and the client's debugger listener to the selection list. This
+     * should only be called from one thread (the VMWatcherThread) to avoid a
+     * race between "alreadyOpen" and Client creation.
+     */
+    synchronized void addClient(Client client) {
+        if (mInstance == null) {
+            return;
+        }
+
+        Log.d("ddms", "Adding new client " + client);
+
+        synchronized (mClientList) {
+            mClientList.add(client);
+
+            /*
+             * Register the Client's socket channel with the selector. We attach
+             * the Client to the SelectionKey. If you try to register a new
+             * channel with the Selector while it is waiting for I/O, you will
+             * block. The solution is to call wakeup() and then hold a lock to
+             * ensure that the registration happens before the Selector goes
+             * back to sleep.
+             */
+            try {
+                wakeup();
+
+                client.register(mSelector);
+
+                Debugger dbg = client.getDebugger();
+                if (dbg != null) {
+                    dbg.registerListener(mSelector);
+                }
+            } catch (IOException ioe) {
+                // not really expecting this to happen
+                ioe.printStackTrace();
+            }
+        }
+    }
+    
+    /*
+     * Broadcast an event to all message handlers.
+     */
+    private void broadcast(int event, Client client) {
+        Log.d("ddms", "broadcast " + event + ": " + client);
+
+        /*
+         * The handler objects appear once in mHandlerMap for each message they
+         * handle. We want to notify them once each, so we convert the HashMap
+         * to a HashSet before we iterate.
+         */
+        HashSet<ChunkHandler> set;
+        synchronized (mHandlerMap) {
+            Collection<ChunkHandler> values = mHandlerMap.values();
+            set = new HashSet<ChunkHandler>(values);
+        }
+
+        Iterator<ChunkHandler> iter = set.iterator();
+        while (iter.hasNext()) {
+            ChunkHandler handler = iter.next();
+            switch (event) {
+                case CLIENT_READY:
+                    try {
+                        handler.clientReady(client);
+                    } catch (IOException ioe) {
+                        // Something failed with the client. It should
+                        // fall out of the list the next time we try to
+                        // do something with it, so we discard the
+                        // exception here and assume cleanup will happen
+                        // later. May need to propagate farther. The
+                        // trouble is that not all values for "event" may
+                        // actually throw an exception.
+                        Log.w("ddms",
+                                "Got exception while broadcasting 'ready'");
+                        return;
+                    }
+                    break;
+                case CLIENT_DISCONNECTED:
+                    handler.clientDisconnected(client);
+                    break;
+                default:
+                    throw new UnsupportedOperationException();
+            }
+        }
+
+    }
+
+    /**
+     * Opens (or reopens) the "debug selected" port and listen for connections.
+     * @return true if the port was opened successfully.
+     * @throws IOException
+     */
+    private boolean reopenDebugSelectedPort() throws IOException {
+
+        Log.d("ddms", "reopen debug-selected port: " + mNewDebugSelectedPort);
+        if (mDebugSelectedChan != null) {
+            mDebugSelectedChan.close();
+        }
+
+        mDebugSelectedChan = ServerSocketChannel.open();
+        mDebugSelectedChan.configureBlocking(false); // required for Selector
+
+        InetSocketAddress addr = new InetSocketAddress(
+                InetAddress.getByName("localhost"), //$NON-NLS-1$
+                mNewDebugSelectedPort);
+        mDebugSelectedChan.socket().setReuseAddress(true); // enable SO_REUSEADDR
+
+        try {
+            mDebugSelectedChan.socket().bind(addr);
+            if (mSelectedClient != null) {
+                mSelectedClient.update(Client.CHANGE_PORT);
+            }
+
+            mDebugSelectedChan.register(mSelector, SelectionKey.OP_ACCEPT, this);
+            
+            return true;
+        } catch (java.net.BindException e) {
+            displayDebugSelectedBindError(mNewDebugSelectedPort);
+
+            // do not attempt to reopen it.
+            mDebugSelectedChan = null;
+            mNewDebugSelectedPort = -1;
+            
+            return false;
+        }
+    }
+
+    /*
+     * We have some activity on the "debug selected" port. Handle it.
+     */
+    private void processDebugSelectedActivity(SelectionKey key) {
+        assert key.isAcceptable();
+
+        ServerSocketChannel acceptChan = (ServerSocketChannel)key.channel();
+
+        /*
+         * Find the debugger associated with the currently-selected client.
+         */
+        if (mSelectedClient != null) {
+            Debugger dbg = mSelectedClient.getDebugger();
+
+            if (dbg != null) {
+                Log.i("ddms", "Accepting connection on 'debug selected' port");
+                try {
+                    acceptNewDebugger(dbg, acceptChan);
+                } catch (IOException ioe) {
+                    // client should be gone, keep going
+                }
+
+                return;
+            }
+        }
+
+        Log.w("ddms",
+                "Connection on 'debug selected' port, but none selected");
+        try {
+            SocketChannel chan = acceptChan.accept();
+            chan.close();
+        } catch (IOException ioe) {
+            // not expected; client should be gone, keep going
+        } catch (NotYetBoundException e) {
+            displayDebugSelectedBindError(mDebugSelectedPort);
+        }
+    }
+
+    private void displayDebugSelectedBindError(int port) {
+        String message = String.format(
+                "Could not open Selected VM debug port (%1$d). Make sure you do not have another instance of DDMS or of the eclipse plugin running. If it's being used by something else, choose a new port number in the preferences.",
+                port);
+
+        Log.logAndDisplay(LogLevel.ERROR, "ddms", message);
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MultiLineReceiver.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MultiLineReceiver.java
new file mode 100644
index 0000000..24dbb05
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/MultiLineReceiver.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+
+/**
+ * Base implementation of {@link IShellOutputReceiver}, that takes the raw data coming from the
+ * socket, and convert it into {@link String} objects.
+ * <p/>Additionally, it splits the string by lines.
+ * <p/>Classes extending it must implement {@link #processNewLines(String[])} which receives
+ * new parsed lines as they become available.
+ */
+public abstract class MultiLineReceiver implements IShellOutputReceiver {
+
+    private boolean mTrimLines = true;
+
+    /** unfinished message line, stored for next packet */
+    private String mUnfinishedLine = null;
+
+    private final ArrayList<String> mArray = new ArrayList<String>();
+
+    /**
+     * Set the trim lines flag.
+     * @param trim hether the lines are trimmed, or not.
+     */
+    public void setTrimLine(boolean trim) {
+        mTrimLines = trim;
+    }
+
+    /* (non-Javadoc)
+     * @see com.android.ddmlib.adb.IShellOutputReceiver#addOutput(
+     *      byte[], int, int)
+     */
+    public final void addOutput(byte[] data, int offset, int length) {
+        if (isCancelled() == false) {
+            String s = null;
+            try {
+                s = new String(data, offset, length, "ISO-8859-1"); //$NON-NLS-1$
+            } catch (UnsupportedEncodingException e) {
+                // normal encoding didn't work, try the default one
+                s = new String(data, offset,length);
+            }
+
+            // ok we've got a string
+            if (s != null) {
+                // if we had an unfinished line we add it.
+                if (mUnfinishedLine != null) {
+                    s = mUnfinishedLine + s;
+                    mUnfinishedLine = null;
+                }
+
+                // now we split the lines
+                mArray.clear();
+                int start = 0;
+                do {
+                    int index = s.indexOf("\r\n", start); //$NON-NLS-1$
+
+                    // if \r\n was not found, this is an unfinished line
+                    // and we store it to be processed for the next packet
+                    if (index == -1) {
+                        mUnfinishedLine = s.substring(start);
+                        break;
+                    }
+
+                    // so we found a \r\n;
+                    // extract the line
+                    String line = s.substring(start, index);
+                    if (mTrimLines) {
+                        line = line.trim();
+                    }
+                    mArray.add(line);
+
+                    // move start to after the \r\n we found
+                    start = index + 2;
+                } while (true);
+
+                if (mArray.size() > 0) {
+                    // at this point we've split all the lines.
+                    // make the array
+                    String[] lines = mArray.toArray(new String[mArray.size()]);
+
+                    // send it for final processing
+                    processNewLines(lines);
+                }
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see com.android.ddmlib.adb.IShellOutputReceiver#flush()
+     */
+    public final void flush() {
+        if (mUnfinishedLine != null) {
+            processNewLines(new String[] { mUnfinishedLine });
+        }
+
+        done();
+    }
+
+    /**
+     * Terminates the process. This is called after the last lines have been through
+     * {@link #processNewLines(String[])}.
+     */
+    public void done() {
+        // do nothing.
+    }
+
+    /**
+     * Called when new lines are being received by the remote process.
+     * <p/>It is guaranteed that the lines are complete when they are given to this method.
+     * @param lines The array containing the new lines.
+     */
+    public abstract void processNewLines(String[] lines);
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeAllocationInfo.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeAllocationInfo.java
new file mode 100644
index 0000000..956b004
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeAllocationInfo.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Stores native allocation information.
+ * <p/>Contains number of allocations, their size and the stack trace.
+ * <p/>Note: the ddmlib does not resolve the stack trace automatically. While this class provides
+ * storage for resolved stack trace, this is merely for convenience.
+ */
+public final class NativeAllocationInfo {
+    /* constants for flag bits */
+    private static final int FLAG_ZYGOTE_CHILD  = (1<<31);
+    private static final int FLAG_MASK          = (FLAG_ZYGOTE_CHILD);
+
+    /**
+     * list of alloc functions that are filtered out when attempting to display
+     * a relevant method responsible for an allocation
+     */
+    private static ArrayList<String> sAllocFunctionFilter;
+    static {
+        sAllocFunctionFilter = new ArrayList<String>();
+        sAllocFunctionFilter.add("malloc"); //$NON-NLS-1$
+        sAllocFunctionFilter.add("calloc"); //$NON-NLS-1$
+        sAllocFunctionFilter.add("realloc"); //$NON-NLS-1$
+        sAllocFunctionFilter.add("get_backtrace"); //$NON-NLS-1$
+        sAllocFunctionFilter.add("get_hash"); //$NON-NLS-1$
+        sAllocFunctionFilter.add("??"); //$NON-NLS-1$
+        sAllocFunctionFilter.add("internal_free"); //$NON-NLS-1$
+        sAllocFunctionFilter.add("operator new"); //$NON-NLS-1$
+        sAllocFunctionFilter.add("leak_free"); //$NON-NLS-1$
+        sAllocFunctionFilter.add("chk_free"); //$NON-NLS-1$
+        sAllocFunctionFilter.add("chk_memalign"); //$NON-NLS-1$
+        sAllocFunctionFilter.add("Malloc"); //$NON-NLS-1$
+    }
+
+    private final int mSize;
+
+    private final boolean mIsZygoteChild;
+
+    private final int mAllocations;
+
+    private final ArrayList<Long> mStackCallAddresses = new ArrayList<Long>();
+
+    private ArrayList<NativeStackCallInfo> mResolvedStackCall = null;
+
+    private boolean mIsStackCallResolved = false;
+
+    /**
+     * Constructs a new {@link NativeAllocationInfo}.
+     * @param size The size of the allocations.
+     * @param allocations the allocation count
+     */
+    NativeAllocationInfo(int size, int allocations) {
+        this.mSize = size & ~FLAG_MASK;
+        this.mIsZygoteChild = ((size & FLAG_ZYGOTE_CHILD) != 0);
+        this.mAllocations = allocations;
+    }
+    
+    /**
+     * Adds a stack call address for this allocation.
+     * @param address The address to add.
+     */
+    void addStackCallAddress(long address) {
+        mStackCallAddresses.add(address);
+    }
+    
+    /**
+     * Returns the total size of this allocation.
+     */
+    public int getSize() {
+        return mSize;
+    }
+
+    /**
+     * Returns whether the allocation happened in a child of the zygote
+     * process.
+     */
+    public boolean isZygoteChild() {
+        return mIsZygoteChild;
+    }
+
+    /**
+     * Returns the allocation count.
+     */
+    public int getAllocationCount() {
+        return mAllocations;
+    }
+    
+    /**
+     * Returns whether the stack call addresses have been resolved into
+     * {@link NativeStackCallInfo} objects.
+     */
+    public boolean isStackCallResolved() {
+        return mIsStackCallResolved;
+    }
+
+    /**
+     * Returns the stack call of this allocation as raw addresses.
+     * @return the list of addresses where the allocation happened.
+     */
+    public Long[] getStackCallAddresses() {
+        return mStackCallAddresses.toArray(new Long[mStackCallAddresses.size()]);
+    }
+    
+    /**
+     * Sets the resolved stack call for this allocation.
+     * <p/>
+     * If <code>resolvedStackCall</code> is non <code>null</code> then
+     * {@link #isStackCallResolved()} will return <code>true</code> after this call.
+     * @param resolvedStackCall The list of {@link NativeStackCallInfo}.
+     */
+    public synchronized void setResolvedStackCall(List<NativeStackCallInfo> resolvedStackCall) {
+        if (mResolvedStackCall == null) {
+            mResolvedStackCall = new ArrayList<NativeStackCallInfo>();
+        } else {
+            mResolvedStackCall.clear();
+        }
+        mResolvedStackCall.addAll(resolvedStackCall);
+        mIsStackCallResolved = mResolvedStackCall.size() != 0;
+    }
+
+    /**
+     * Returns the resolved stack call.
+     * @return An array of {@link NativeStackCallInfo} or <code>null</code> if the stack call
+     * was not resolved.
+     * @see #setResolvedStackCall(ArrayList)
+     * @see #isStackCallResolved()
+     */
+    public synchronized NativeStackCallInfo[] getResolvedStackCall() {
+        if (mIsStackCallResolved) {
+            return mResolvedStackCall.toArray(new NativeStackCallInfo[mResolvedStackCall.size()]);
+        }
+        
+        return null;
+    }
+
+    /**
+     * Indicates whether some other object is "equal to" this one.
+     * @param obj the reference object with which to compare.
+     * @return <code>true</code> if this object is equal to the obj argument;
+     * <code>false</code> otherwise.
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this)
+            return true;
+        if (obj instanceof NativeAllocationInfo) {
+            NativeAllocationInfo mi = (NativeAllocationInfo)obj;
+            // quick compare of size, alloc, and stackcall size
+            if (mSize != mi.mSize || mAllocations != mi.mAllocations ||
+                    mStackCallAddresses.size() != mi.mStackCallAddresses.size()) {
+                return false;
+            }
+            // compare the stack addresses
+            int count = mStackCallAddresses.size();
+            for (int i = 0 ; i < count ; i++) {
+                long a = mStackCallAddresses.get(i);
+                long b = mi.mStackCallAddresses.get(i);
+                if (a != b) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns a string representation of the object.
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public String toString() {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("Allocations: ");
+        buffer.append(mAllocations);
+        buffer.append("\n"); //$NON-NLS-1$
+
+        buffer.append("Size: ");
+        buffer.append(mSize);
+        buffer.append("\n"); //$NON-NLS-1$
+
+        buffer.append("Total Size: ");
+        buffer.append(mSize * mAllocations);
+        buffer.append("\n"); //$NON-NLS-1$
+
+        Iterator<Long> addrIterator = mStackCallAddresses.iterator();
+        Iterator<NativeStackCallInfo> sourceIterator = mResolvedStackCall.iterator();
+
+        while (sourceIterator.hasNext()) {
+            long addr = addrIterator.next();
+            NativeStackCallInfo source = sourceIterator.next();
+            if (addr == 0)
+                continue;
+
+            if (source.getLineNumber() != -1) {
+                buffer.append(String.format("\t%1$08x\t%2$s --- %3$s --- %4$s:%5$d\n", addr,
+                        source.getLibraryName(), source.getMethodName(),
+                        source.getSourceFile(), source.getLineNumber()));
+            } else {
+                buffer.append(String.format("\t%1$08x\t%2$s --- %3$s --- %4$s\n", addr,
+                        source.getLibraryName(), source.getMethodName(), source.getSourceFile()));
+            }
+        }
+
+        return buffer.toString();
+    }
+
+    /**
+     * Returns the first {@link NativeStackCallInfo} that is relevant.
+     * <p/>
+     * A relevant <code>NativeStackCallInfo</code> is a stack call that is not deep in the
+     * lower level of the libc, but the actual method that performed the allocation. 
+     * @return a <code>NativeStackCallInfo</code> or <code>null</code> if the stack call has not
+     * been processed from the raw addresses.
+     * @see #setResolvedStackCall(ArrayList)
+     * @see #isStackCallResolved()
+     */
+    public synchronized NativeStackCallInfo getRelevantStackCallInfo() {
+        if (mIsStackCallResolved && mResolvedStackCall != null) {
+            Iterator<NativeStackCallInfo> sourceIterator = mResolvedStackCall.iterator();
+            Iterator<Long> addrIterator = mStackCallAddresses.iterator();
+
+            while (sourceIterator.hasNext() && addrIterator.hasNext()) {
+                long addr = addrIterator.next();
+                NativeStackCallInfo info = sourceIterator.next();
+                if (addr != 0 && info != null) {
+                    if (isRelevant(info.getMethodName())) {
+                        return info;
+                    }
+                }
+            }
+
+            // couldnt find a relevant one, so we'll return the first one if it
+            // exists.
+            if (mResolvedStackCall.size() > 0)
+                return mResolvedStackCall.get(0);
+        }
+
+        return null;
+    }
+    
+    /**
+     * Returns true if the method name is relevant.
+     * @param methodName the method name to test.
+     */
+    private boolean isRelevant(String methodName) {
+        for (String filter : sAllocFunctionFilter) {
+            if (methodName.contains(filter)) {
+                return false;
+            }
+        }
+        
+        return true;
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeLibraryMapInfo.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeLibraryMapInfo.java
new file mode 100644
index 0000000..5a26317
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeLibraryMapInfo.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+/**
+ * Memory address to library mapping for native libraries.
+ * <p/>
+ * Each instance represents a single native library and its start and end memory addresses. 
+ */
+public final class NativeLibraryMapInfo {
+    private long mStartAddr;
+    private long mEndAddr;
+
+    private String mLibrary;
+
+    /**
+     * Constructs a new native library map info.
+     * @param startAddr The start address of the library.
+     * @param endAddr The end address of the library.
+     * @param library The name of the library.
+     */
+    NativeLibraryMapInfo(long startAddr, long endAddr, String library) {
+        this.mStartAddr = startAddr;
+        this.mEndAddr = endAddr;
+        this.mLibrary = library;
+    }
+    
+    /**
+     * Returns the name of the library.
+     */
+    public String getLibraryName() {
+        return mLibrary;
+    }
+    
+    /**
+     * Returns the start address of the library.
+     */
+    public long getStartAddress() {
+        return mStartAddr;
+    }
+    
+    /**
+     * Returns the end address of the library.
+     */
+    public long getEndAddress() {
+        return mEndAddr;
+    }
+
+    /**
+     * Returns whether the specified address is inside the library.
+     * @param address The address to test.
+     * @return <code>true</code> if the address is between the start and end address of the library.
+     * @see #getStartAddress()
+     * @see #getEndAddress()
+     */
+    public boolean isWithinLibrary(long address) {
+        return address >= mStartAddr && address <= mEndAddr;
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeStackCallInfo.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeStackCallInfo.java
new file mode 100644
index 0000000..e54818d
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NativeStackCallInfo.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Represents a stack call. This is used to return all of the call
+ * information as one object.
+ */
+public final class NativeStackCallInfo {
+    private final static Pattern SOURCE_NAME_PATTERN = Pattern.compile("^(.+):(\\d+)$");
+    
+    /** name of the library */
+    private String mLibrary;
+
+    /** name of the method */
+    private String mMethod;
+
+    /**
+     * name of the source file + line number in the format<br>
+     * &lt;sourcefile&gt;:&lt;linenumber&gt;
+     */
+    private String mSourceFile;
+    
+    private int mLineNumber = -1; 
+
+    /**
+     * Basic constructor with library, method, and sourcefile information
+     *
+     * @param lib The name of the library
+     * @param method the name of the method
+     * @param sourceFile the name of the source file and the line number
+     * as "[sourcefile]:[fileNumber]"
+     */
+    public NativeStackCallInfo(String lib, String method, String sourceFile) {
+        mLibrary = lib;
+        mMethod = method;
+        
+        Matcher m = SOURCE_NAME_PATTERN.matcher(sourceFile);
+        if (m.matches()) {
+            mSourceFile = m.group(1);
+            try {
+                mLineNumber = Integer.parseInt(m.group(2));
+            } catch (NumberFormatException e) {
+                // do nothing, the line number will stay at -1
+            }
+        } else {
+            mSourceFile = sourceFile;
+        }
+    }
+    
+    /**
+     * Returns the name of the library name.
+     */
+    public String getLibraryName() {
+        return mLibrary;
+    }
+
+    /** 
+     * Returns the name of the method.
+     */
+    public String getMethodName() {
+        return mMethod;
+    }
+    
+    /**
+     * Returns the name of the source file.
+     */
+    public String getSourceFile() {
+        return mSourceFile;
+    }
+
+    /**
+     * Returns the line number, or -1 if unknown.
+     */
+    public int getLineNumber() {
+        return mLineNumber;
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NullOutputReceiver.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NullOutputReceiver.java
new file mode 100644
index 0000000..d2b5a1e
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/NullOutputReceiver.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+/**
+ * Implementation of {@link IShellOutputReceiver} that does nothing.
+ * <p/>This can be used to execute a remote shell command when the output is not needed.
+ */
+public final class NullOutputReceiver implements IShellOutputReceiver {
+
+    private static NullOutputReceiver sReceiver = new NullOutputReceiver();
+
+    public static IShellOutputReceiver getReceiver() {
+        return sReceiver;
+    }
+
+    /* (non-Javadoc)
+     * @see com.android.ddmlib.adb.IShellOutputReceiver#addOutput(byte[], int, int)
+     */
+    public void addOutput(byte[] data, int offset, int length) {
+    }
+
+    /* (non-Javadoc)
+     * @see com.android.ddmlib.adb.IShellOutputReceiver#flush()
+     */
+    public void flush() {
+    }
+
+    /* (non-Javadoc)
+     * @see com.android.ddmlib.adb.IShellOutputReceiver#isCancelled()
+     */
+    public boolean isCancelled() {
+        return false;
+    }
+
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/RawImage.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/RawImage.java
new file mode 100644
index 0000000..610cb59
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/RawImage.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+/**
+ * Data representing an image taken from a device frame buffer.
+ */
+public final class RawImage {
+    /**
+     * bit-per-pixel value.
+     */
+    public int bpp;
+    public int size;
+    public int width;
+    public int height;
+
+    public byte[] data;
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java
new file mode 100644
index 0000000..44df000
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/SyncService.java
@@ -0,0 +1,949 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+import com.android.ddmlib.AdbHelper.AdbResponse;
+import com.android.ddmlib.FileListingService.FileEntry;
+import com.android.ddmlib.utils.ArrayHelper;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.InetSocketAddress;
+import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
+
+/**
+ * Sync service class to push/pull to/from devices/emulators, through the debug bridge.
+ * <p/>
+ * To get a {@link SyncService} object, use {@link Device#getSyncService()}.
+ */
+public final class SyncService {
+
+    private final static byte[] ID_OKAY = { 'O', 'K', 'A', 'Y' };
+    private final static byte[] ID_FAIL = { 'F', 'A', 'I', 'L' };
+    private final static byte[] ID_STAT = { 'S', 'T', 'A', 'T' };
+    private final static byte[] ID_RECV = { 'R', 'E', 'C', 'V' };
+    private final static byte[] ID_DATA = { 'D', 'A', 'T', 'A' };
+    private final static byte[] ID_DONE = { 'D', 'O', 'N', 'E' };
+    private final static byte[] ID_SEND = { 'S', 'E', 'N', 'D' };
+//    private final static byte[] ID_LIST = { 'L', 'I', 'S', 'T' };
+//    private final static byte[] ID_DENT = { 'D', 'E', 'N', 'T' };
+
+    private final static NullSyncProgresMonitor sNullSyncProgressMonitor =
+            new NullSyncProgresMonitor();
+
+    private final static int S_ISOCK = 0xC000; // type: symbolic link
+    private final static int S_IFLNK = 0xA000; // type: symbolic link
+    private final static int S_IFREG = 0x8000; // type: regular file
+    private final static int S_IFBLK = 0x6000; // type: block device
+    private final static int S_IFDIR = 0x4000; // type: directory
+    private final static int S_IFCHR = 0x2000; // type: character device
+    private final static int S_IFIFO = 0x1000; // type: fifo
+/*
+    private final static int S_ISUID = 0x0800; // set-uid bit
+    private final static int S_ISGID = 0x0400; // set-gid bit
+    private final static int S_ISVTX = 0x0200; // sticky bit
+    private final static int S_IRWXU = 0x01C0; // user permissions
+    private final static int S_IRUSR = 0x0100; // user: read
+    private final static int S_IWUSR = 0x0080; // user: write
+    private final static int S_IXUSR = 0x0040; // user: execute
+    private final static int S_IRWXG = 0x0038; // group permissions
+    private final static int S_IRGRP = 0x0020; // group: read
+    private final static int S_IWGRP = 0x0010; // group: write
+    private final static int S_IXGRP = 0x0008; // group: execute
+    private final static int S_IRWXO = 0x0007; // other permissions
+    private final static int S_IROTH = 0x0004; // other: read
+    private final static int S_IWOTH = 0x0002; // other: write
+    private final static int S_IXOTH = 0x0001; // other: execute
+*/
+
+    private final static int SYNC_DATA_MAX = 64*1024;
+    private final static int REMOTE_PATH_MAX_LENGTH = 1024;
+
+    /** Result code for transfer success. */
+    public static final int RESULT_OK = 0;
+    /** Result code for canceled transfer */
+    public static final int RESULT_CANCELED = 1;
+    /** Result code for unknown error */
+    public static final int RESULT_UNKNOWN_ERROR = 2;
+    /** Result code for network connection error */
+    public static final int RESULT_CONNECTION_ERROR = 3;
+    /** Result code for unknown remote object during a pull */
+    public static final int RESULT_NO_REMOTE_OBJECT = 4;
+    /** Result code when attempting to pull multiple files into a file */
+    public static final int RESULT_TARGET_IS_FILE = 5;
+    /** Result code when attempting to pull multiple into a directory that does not exist. */
+    public static final int RESULT_NO_DIR_TARGET = 6;
+    /** Result code for wrong encoding on the remote path. */
+    public static final int RESULT_REMOTE_PATH_ENCODING = 7;
+    /** Result code for remote path that is too long. */
+    public static final int RESULT_REMOTE_PATH_LENGTH = 8;
+    /** Result code for error while writing local file. */
+    public static final int RESULT_FILE_WRITE_ERROR = 9;
+    /** Result code for error while reading local file. */
+    public static final int RESULT_FILE_READ_ERROR = 10;
+    /** Result code for attempting to push a file that does not exist. */
+    public static final int RESULT_NO_LOCAL_FILE = 11;
+    /** Result code for attempting to push a directory. */
+    public static final int RESULT_LOCAL_IS_DIRECTORY = 12;
+    /** Result code for when the target path of a multi file push is a file. */
+    public static final int RESULT_REMOTE_IS_FILE = 13;
+    /** Result code for receiving too much data from the remove device at once */
+    public static final int RESULT_BUFFER_OVERRUN = 14;
+
+    /**
+     * A file transfer result.
+     * <p/>
+     * This contains a code, and an optional string
+     */
+    public static class SyncResult {
+        private int mCode;
+        private String mMessage;
+        SyncResult(int code, String message) {
+            mCode = code;
+            mMessage = message;
+        }
+
+        SyncResult(int code, Exception e) {
+            this(code, e.getMessage());
+        }
+
+        SyncResult(int code) {
+            this(code, errorCodeToString(code));
+        }
+
+        public int getCode() {
+            return mCode;
+        }
+
+        public String getMessage() {
+            return mMessage;
+        }
+    }
+
+    /**
+     * Classes which implement this interface provide methods that deal
+     * with displaying transfer progress.
+     */
+    public interface ISyncProgressMonitor {
+        /**
+         * Sent when the transfer starts
+         * @param totalWork the total amount of work.
+         */
+        public void start(int totalWork);
+        /**
+         * Sent when the transfer is finished or interrupted.
+         */
+        public void stop();
+        /**
+         * Sent to query for possible cancellation.
+         * @return true if the transfer should be stopped.
+         */
+        public boolean isCanceled();
+        /**
+         * Sent when a sub task is started.
+         * @param name the name of the sub task.
+         */
+        public void startSubTask(String name);
+        /**
+         * Sent when some progress have been made.
+         * @param work the amount of work done.
+         */
+        public void advance(int work);
+    }
+
+    /**
+     * A Sync progress monitor that does nothing
+     */
+    private static class NullSyncProgresMonitor implements ISyncProgressMonitor {
+        public void advance(int work) {
+        }
+        public boolean isCanceled() {
+            return false;
+        }
+
+        public void start(int totalWork) {
+        }
+        public void startSubTask(String name) {
+        }
+        public void stop() {
+        }
+    }
+
+    private InetSocketAddress mAddress;
+    private Device mDevice;
+    private SocketChannel mChannel;
+
+    /**
+     * Buffer used to send data. Allocated when needed and reused afterward.
+     */
+    private byte[] mBuffer;
+
+    /**
+     * Creates a Sync service object.
+     * @param address The address to connect to
+     * @param device the {@link Device} that the service connects to.
+     */
+    SyncService(InetSocketAddress address, Device device) {
+        mAddress = address;
+        mDevice = device;
+    }
+
+    /**
+     * Opens the sync connection. This must be called before any calls to push[File] / pull[File].
+     * @return true if the connection opened, false otherwise.
+     */
+    boolean openSync() {
+        try {
+            mChannel = SocketChannel.open(mAddress);
+            mChannel.configureBlocking(false);
+
+            // target a specific device
+            AdbHelper.setDevice(mChannel, mDevice);
+
+            byte[] request = AdbHelper.formAdbRequest("sync:"); // $NON-NLS-1$
+            AdbHelper.write(mChannel, request, -1, AdbHelper.STD_TIMEOUT);
+
+            AdbResponse resp = AdbHelper.readAdbResponse(mChannel, false /* readDiagString */);
+
+            if (!resp.ioSuccess || !resp.okay) {
+                Log.w("ddms",
+                        "Got timeout or unhappy response from ADB sync req: "
+                        + resp.message);
+                mChannel.close();
+                mChannel = null;
+                return false;
+            }
+        } catch (IOException e) {
+            if (mChannel != null) {
+                try {
+                    mChannel.close();
+                } catch (IOException e1) {
+                    // we do nothing, since we'll return false just below
+                }
+                mChannel = null;
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Closes the connection.
+     */
+    public void close() {
+        if (mChannel != null) {
+            try {
+                mChannel.close();
+            } catch (IOException e) {
+                // nothing to be done really...
+            }
+            mChannel = null;
+        }
+    }
+
+    /**
+     * Returns a sync progress monitor that does nothing. This allows background tasks that don't
+     * want/need to display ui, to pass a valid {@link ISyncProgressMonitor}.
+     * <p/>This object can be reused multiple times and can be used by concurrent threads.
+     */
+    public static ISyncProgressMonitor getNullProgressMonitor() {
+        return sNullSyncProgressMonitor;
+    }
+
+    /**
+     * Converts an error code into a non-localized string
+     * @param code the error code;
+     */
+    private static String errorCodeToString(int code) {
+        switch (code) {
+            case RESULT_OK:
+                return "Success.";
+            case RESULT_CANCELED:
+                return "Tranfert canceled by the user.";
+            case RESULT_UNKNOWN_ERROR:
+                return "Unknown Error.";
+            case RESULT_CONNECTION_ERROR:
+                return "Adb Connection Error.";
+            case RESULT_NO_REMOTE_OBJECT:
+                return "Remote object doesn't exist!";
+            case RESULT_TARGET_IS_FILE:
+                return "Target object is a file.";
+            case RESULT_NO_DIR_TARGET:
+                return "Target directory doesn't exist.";
+            case RESULT_REMOTE_PATH_ENCODING:
+                return "Remote Path encoding is not supported.";
+            case RESULT_REMOTE_PATH_LENGTH:
+                return "Remove path is too long.";
+            case RESULT_FILE_WRITE_ERROR:
+                return "Writing local file failed!";
+            case RESULT_FILE_READ_ERROR:
+                return "Reading local file failed!";
+            case RESULT_NO_LOCAL_FILE:
+                return "Local file doesn't exist.";
+            case RESULT_LOCAL_IS_DIRECTORY:
+                return "Local path is a directory.";
+            case RESULT_REMOTE_IS_FILE:
+                return "Remote path is a file.";
+            case RESULT_BUFFER_OVERRUN:
+                return "Receiving too much data.";
+        }
+
+        throw new RuntimeException();
+    }
+
+    /**
+     * Pulls file(s) or folder(s).
+     * @param entries the remote item(s) to pull
+     * @param localPath The local destination. If the entries count is > 1 or
+     *      if the unique entry is a folder, this should be a folder.
+     * @param monitor The progress monitor. Cannot be null.
+     * @return a {@link SyncResult} object with a code and an optional message.
+     *
+     * @see FileListingService.FileEntry
+     * @see #getNullProgressMonitor()
+     */
+    public SyncResult pull(FileEntry[] entries, String localPath, ISyncProgressMonitor monitor) {
+
+        // first we check the destination is a directory and exists
+        File f = new File(localPath);
+        if (f.exists() == false) {
+            return new SyncResult(RESULT_NO_DIR_TARGET);
+        }
+        if (f.isDirectory() == false) {
+            return new SyncResult(RESULT_TARGET_IS_FILE);
+        }
+
+        // get a FileListingService object
+        FileListingService fls = new FileListingService(mDevice);
+
+        // compute the number of file to move
+        int total = getTotalRemoteFileSize(entries, fls);
+
+        // start the monitor
+        monitor.start(total);
+
+        SyncResult result = doPull(entries, localPath, fls, monitor);
+
+        monitor.stop();
+
+        return result;
+    }
+
+    /**
+     * Pulls a single file.
+     * @param remote the remote file
+     * @param localFilename The local destination.
+     * @param monitor The progress monitor. Cannot be null.
+     * @return a {@link SyncResult} object with a code and an optional message.
+     *
+     * @see FileListingService.FileEntry
+     * @see #getNullProgressMonitor()
+     */
+    public SyncResult pullFile(FileEntry remote, String localFilename,
+            ISyncProgressMonitor monitor) {
+        int total = remote.getSizeValue();
+        monitor.start(total);
+
+        SyncResult result = doPullFile(remote.getFullPath(), localFilename, monitor);
+
+        monitor.stop();
+        return result;
+    }
+
+    /**
+     * Push several files.
+     * @param local An array of loca files to push
+     * @param remote the remote {@link FileEntry} representing a directory.
+     * @param monitor The progress monitor. Cannot be null.
+     * @return a {@link SyncResult} object with a code and an optional message.
+     */
+    public SyncResult push(String[] local, FileEntry remote, ISyncProgressMonitor monitor) {
+        if (remote.isDirectory() == false) {
+            return new SyncResult(RESULT_REMOTE_IS_FILE);
+        }
+
+        // make a list of File from the list of String
+        ArrayList<File> files = new ArrayList<File>();
+        for (String path : local) {
+            files.add(new File(path));
+        }
+
+        // get the total count of the bytes to transfer
+        File[] fileArray = files.toArray(new File[files.size()]);
+        int total = getTotalLocalFileSize(fileArray);
+
+        monitor.start(total);
+
+        SyncResult result = doPush(fileArray, remote.getFullPath(), monitor);
+
+        monitor.stop();
+
+        return result;
+    }
+
+    /**
+     * Push a single file.
+     * @param local the local filepath.
+     * @param remote The remote filepath.
+     * @param monitor The progress monitor. Cannot be null.
+     * @return a {@link SyncResult} object with a code and an optional message.
+     */
+    public SyncResult pushFile(String local, String remote, ISyncProgressMonitor monitor) {
+        File f = new File(local);
+        if (f.exists() == false) {
+            return new SyncResult(RESULT_NO_LOCAL_FILE);
+        }
+
+        if (f.isDirectory()) {
+            return new SyncResult(RESULT_LOCAL_IS_DIRECTORY);
+        }
+
+        monitor.start((int)f.length());
+
+        SyncResult result = doPushFile(local, remote, monitor);
+
+        monitor.stop();
+
+        return result;
+    }
+
+    /**
+     * compute the recursive file size of all the files in the list. Folder
+     * have a weight of 1.
+     * @param entries
+     * @param fls
+     * @return
+     */
+    private int getTotalRemoteFileSize(FileEntry[] entries, FileListingService fls) {
+        int count = 0;
+        for (FileEntry e : entries) {
+            int type = e.getType();
+            if (type == FileListingService.TYPE_DIRECTORY) {
+                // get the children
+                FileEntry[] children = fls.getChildren(e, false, null);
+                count += getTotalRemoteFileSize(children, fls) + 1;
+            } else if (type == FileListingService.TYPE_FILE) {
+                count += e.getSizeValue();
+            }
+        }
+
+        return count;
+    }
+
+    /**
+     * compute the recursive file size of all the files in the list. Folder
+     * have a weight of 1.
+     * This does not check for circular links.
+     * @param files
+     * @return
+     */
+    private int getTotalLocalFileSize(File[] files) {
+        int count = 0;
+
+        for (File f : files) {
+            if (f.exists()) {
+                if (f.isDirectory()) {
+                    return getTotalLocalFileSize(f.listFiles()) + 1;
+                } else if (f.isFile()) {
+                    count += f.length();
+                }
+            }
+        }
+
+        return count;
+    }
+
+    /**
+     * Pulls multiple files/folders recursively.
+     * @param entries The list of entry to pull
+     * @param localPath the localpath to a directory
+     * @param fileListingService a FileListingService object to browse through remote directories.
+     * @param monitor the progress monitor. Must be started already.
+     * @return a {@link SyncResult} object with a code and an optional message.
+     */
+    private SyncResult doPull(FileEntry[] entries, String localPath,
+            FileListingService fileListingService,
+            ISyncProgressMonitor monitor) {
+
+        for (FileEntry e : entries) {
+            // check if we're cancelled
+            if (monitor.isCanceled() == true) {
+                return new SyncResult(RESULT_CANCELED);
+            }
+
+            // get type (we only pull directory and files for now)
+            int type = e.getType();
+            if (type == FileListingService.TYPE_DIRECTORY) {
+                monitor.startSubTask(e.getFullPath());
+                String dest = localPath + File.separator + e.getName();
+
+                // make the directory
+                File d = new File(dest);
+                d.mkdir();
+
+                // then recursively call the content. Since we did a ls command
+                // to get the number of files, we can use the cache
+                FileEntry[] children = fileListingService.getChildren(e, true, null);
+                SyncResult result = doPull(children, dest, fileListingService, monitor);
+                if (result.mCode != RESULT_OK) {
+                    return result;
+                }
+                monitor.advance(1);
+            } else if (type == FileListingService.TYPE_FILE) {
+                monitor.startSubTask(e.getFullPath());
+                String dest = localPath + File.separator + e.getName();
+                SyncResult result = doPullFile(e.getFullPath(), dest, monitor);
+                if (result.mCode != RESULT_OK) {
+                    return result;
+                }
+            }
+        }
+
+        return new SyncResult(RESULT_OK);
+    }
+
+    /**
+     * Pulls a remote file
+     * @param remotePath the remote file (length max is 1024)
+     * @param localPath the local destination
+     * @param monitor the monitor. The monitor must be started already.
+     * @return a {@link SyncResult} object with a code and an optional message.
+     */
+    private SyncResult doPullFile(String remotePath, String localPath,
+            ISyncProgressMonitor monitor) {
+        byte[] msg = null;
+        byte[] pullResult = new byte[8];
+        try {
+            byte[] remotePathContent = remotePath.getBytes(AdbHelper.DEFAULT_ENCODING);
+
+            if (remotePathContent.length > REMOTE_PATH_MAX_LENGTH) {
+                return new SyncResult(RESULT_REMOTE_PATH_LENGTH);
+            }
+
+            // create the full request message
+            msg = createFileReq(ID_RECV, remotePathContent);
+
+            // and send it.
+            AdbHelper.write(mChannel, msg, -1, AdbHelper.STD_TIMEOUT);
+
+            // read the result, in a byte array containing 2 ints
+            // (id, size)
+            AdbHelper.read(mChannel, pullResult, -1, AdbHelper.STD_TIMEOUT);
+
+            // check we have the proper data back
+            if (checkResult(pullResult, ID_DATA) == false &&
+                    checkResult(pullResult, ID_DONE) == false) {
+                return new SyncResult(RESULT_CONNECTION_ERROR);
+            }
+        } catch (UnsupportedEncodingException e) {
+            return new SyncResult(RESULT_REMOTE_PATH_ENCODING, e);
+        } catch (IOException e) {
+            return new SyncResult(RESULT_CONNECTION_ERROR, e);
+        }
+
+        // access the destination file
+        File f = new File(localPath);
+
+        // create the stream to write in the file. We use a new try/catch block to differentiate
+        // between file and network io exceptions.
+        FileOutputStream fos = null;
+        try {
+            fos = new FileOutputStream(f);
+        } catch (FileNotFoundException e) {
+            return new SyncResult(RESULT_FILE_WRITE_ERROR, e);
+        }
+
+        // the buffer to read the data
+        byte[] data = new byte[SYNC_DATA_MAX];
+
+        // loop to get data until we're done.
+        while (true) {
+            // check if we're cancelled
+            if (monitor.isCanceled() == true) {
+                return new SyncResult(RESULT_CANCELED);
+            }
+
+            // if we're done, we stop the loop
+            if (checkResult(pullResult, ID_DONE)) {
+                break;
+            }
+            if (checkResult(pullResult, ID_DATA) == false) {
+                // hmm there's an error
+                return new SyncResult(RESULT_CONNECTION_ERROR);
+            }
+            int length = ArrayHelper.swap32bitFromArray(pullResult, 4);
+            if (length > SYNC_DATA_MAX) {
+                // buffer overrun!
+                // error and exit
+                return new SyncResult(RESULT_BUFFER_OVERRUN);
+            }
+
+            try {
+                // now read the length we received
+                AdbHelper.read(mChannel, data, length, AdbHelper.STD_TIMEOUT);
+
+                // get the header for the next packet.
+                AdbHelper.read(mChannel, pullResult, -1, AdbHelper.STD_TIMEOUT);
+            } catch (IOException e) {
+                return new SyncResult(RESULT_CONNECTION_ERROR, e);
+            }
+
+            // write the content in the file
+            try {
+                fos.write(data, 0, length);
+            } catch (IOException e) {
+                return new SyncResult(RESULT_FILE_WRITE_ERROR, e);
+            }
+
+            monitor.advance(length);
+        }
+
+        try {
+            fos.flush();
+        } catch (IOException e) {
+            return new SyncResult(RESULT_FILE_WRITE_ERROR, e);
+        }
+        return new SyncResult(RESULT_OK);
+    }
+
+
+    /**
+     * Push multiple files
+     * @param fileArray
+     * @param remotePath
+     * @param monitor
+     * @return a {@link SyncResult} object with a code and an optional message.
+     */
+    private SyncResult doPush(File[] fileArray, String remotePath, ISyncProgressMonitor monitor) {
+        for (File f : fileArray) {
+            // check if we're canceled
+            if (monitor.isCanceled() == true) {
+                return new SyncResult(RESULT_CANCELED);
+            }
+            if (f.exists()) {
+                if (f.isDirectory()) {
+                    // append the name of the directory to the remote path
+                    String dest = remotePath + "/" + f.getName(); // $NON-NLS-1S
+                    monitor.startSubTask(dest);
+                    SyncResult result = doPush(f.listFiles(), dest, monitor);
+
+                    if (result.mCode != RESULT_OK) {
+                        return result;
+                    }
+
+                    monitor.advance(1);
+                } else if (f.isFile()) {
+                    // append the name of the file to the remote path
+                    String remoteFile = remotePath + "/" + f.getName(); // $NON-NLS-1S
+                    monitor.startSubTask(remoteFile);
+                    SyncResult result = doPushFile(f.getAbsolutePath(), remoteFile, monitor);
+                    if (result.mCode != RESULT_OK) {
+                        return result;
+                    }
+                }
+            }
+        }
+
+        return new SyncResult(RESULT_OK);
+    }
+
+    /**
+     * Push a single file
+     * @param localPath the local file to push
+     * @param remotePath the remote file (length max is 1024)
+     * @param monitor the monitor. The monitor must be started already.
+     * @return a {@link SyncResult} object with a code and an optional message.
+     */
+    private SyncResult doPushFile(String localPath, String remotePath,
+            ISyncProgressMonitor monitor) {
+        FileInputStream fis = null;
+        byte[] msg;
+
+        try {
+            byte[] remotePathContent = remotePath.getBytes(AdbHelper.DEFAULT_ENCODING);
+
+            if (remotePathContent.length > REMOTE_PATH_MAX_LENGTH) {
+                return new SyncResult(RESULT_REMOTE_PATH_LENGTH);
+            }
+
+            File f = new File(localPath);
+
+            // this shouldn't happen but still...
+            if (f.exists() == false) {
+                return new SyncResult(RESULT_NO_LOCAL_FILE);
+            }
+
+            // create the stream to read the file
+            fis = new FileInputStream(f);
+
+            // create the header for the action
+            msg = createSendFileReq(ID_SEND, remotePathContent, 0644);
+        } catch (UnsupportedEncodingException e) {
+            return new SyncResult(RESULT_REMOTE_PATH_ENCODING, e);
+        } catch (FileNotFoundException e) {
+            return new SyncResult(RESULT_FILE_READ_ERROR, e);
+        }
+
+        // and send it. We use a custom try/catch block to make the difference between
+        // file and network IO exceptions.
+        try {
+            AdbHelper.write(mChannel, msg, -1, AdbHelper.STD_TIMEOUT);
+        } catch (IOException e) {
+            return new SyncResult(RESULT_CONNECTION_ERROR, e);
+        }
+
+        // create the buffer used to read.
+        // we read max SYNC_DATA_MAX, but we need 2 4 bytes at the beginning.
+        if (mBuffer == null) {
+            mBuffer = new byte[SYNC_DATA_MAX + 8];
+        }
+        System.arraycopy(ID_DATA, 0, mBuffer, 0, ID_DATA.length);
+
+        // look while there is something to read
+        while (true) {
+            // check if we're canceled
+            if (monitor.isCanceled() == true) {
+                return new SyncResult(RESULT_CANCELED);
+            }
+
+            // read up to SYNC_DATA_MAX
+            int readCount = 0;
+            try {
+                readCount = fis.read(mBuffer, 8, SYNC_DATA_MAX);
+            } catch (IOException e) {
+                return new SyncResult(RESULT_FILE_READ_ERROR, e);
+            }
+
+            if (readCount == -1) {
+                // we reached the end of the file
+                break;
+            }
+
+            // now send the data to the device
+            // first write the amount read
+            ArrayHelper.swap32bitsToArray(readCount, mBuffer, 4);
+
+            // now write it
+            try {
+                AdbHelper.write(mChannel, mBuffer, readCount+8, AdbHelper.STD_TIMEOUT);
+            } catch (IOException e) {
+                return new SyncResult(RESULT_CONNECTION_ERROR, e);
+            }
+
+            // and advance the monitor
+            monitor.advance(readCount);
+        }
+        // close the local file
+        try {
+            fis.close();
+        } catch (IOException e) {
+            return new SyncResult(RESULT_FILE_READ_ERROR, e);
+        }
+
+        try {
+            // create the DONE message
+            long time = System.currentTimeMillis() / 1000;
+            msg = createReq(ID_DONE, (int)time);
+
+            // and send it.
+            AdbHelper.write(mChannel, msg, -1, AdbHelper.STD_TIMEOUT);
+
+            // read the result, in a byte array containing 2 ints
+            // (id, size)
+            byte[] result = new byte[8];
+            AdbHelper.read(mChannel, result, -1 /* full length */, AdbHelper.STD_TIMEOUT);
+
+            if (checkResult(result, ID_OKAY) == false) {
+                if (checkResult(result, ID_FAIL)) {
+                    // read some error message...
+                    int len = ArrayHelper.swap32bitFromArray(result, 4);
+
+                    AdbHelper.read(mChannel, mBuffer, len, AdbHelper.STD_TIMEOUT);
+
+                    // output the result?
+                    String message = new String(mBuffer, 0, len);
+                    Log.e("ddms", "transfer error: " + message);
+                    return new SyncResult(RESULT_UNKNOWN_ERROR, message);
+                }
+
+                return new SyncResult(RESULT_UNKNOWN_ERROR);
+            }
+        } catch (IOException e) {
+            return new SyncResult(RESULT_CONNECTION_ERROR, e);
+        }
+
+        return new SyncResult(RESULT_OK);
+    }
+
+
+    /**
+     * Returns the mode of the remote file.
+     * @param path the remote file
+     * @return and Integer containing the mode if all went well or null
+     *      otherwise
+     */
+    private Integer readMode(String path) {
+        try {
+            // create the stat request message.
+            byte[] msg = createFileReq(ID_STAT, path);
+
+            AdbHelper.write(mChannel, msg, -1 /* full length */, AdbHelper.STD_TIMEOUT);
+
+            // read the result, in a byte array containing 4 ints
+            // (id, mode, size, time)
+            byte[] statResult = new byte[16];
+            AdbHelper.read(mChannel, statResult, -1 /* full length */, AdbHelper.STD_TIMEOUT);
+
+            // check we have the proper data back
+            if (checkResult(statResult, ID_STAT) == false) {
+                return null;
+            }
+
+            // we return the mode (2nd int in the array)
+            return ArrayHelper.swap32bitFromArray(statResult, 4);
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Create a command with a code and an int values
+     * @param command
+     * @param value
+     * @return
+     */
+    private static byte[] createReq(byte[] command, int value) {
+        byte[] array = new byte[8];
+
+        System.arraycopy(command, 0, array, 0, 4);
+        ArrayHelper.swap32bitsToArray(value, array, 4);
+
+        return array;
+    }
+
+    /**
+     * Creates the data array for a stat request.
+     * @param command the 4 byte command (ID_STAT, ID_RECV, ...)
+     * @param path The path of the remote file on which to execute the command
+     * @return the byte[] to send to the device through adb
+     */
+    private static byte[] createFileReq(byte[] command, String path) {
+        byte[] pathContent = null;
+        try {
+            pathContent = path.getBytes(AdbHelper.DEFAULT_ENCODING);
+        } catch (UnsupportedEncodingException e) {
+            return null;
+        }
+
+        return createFileReq(command, pathContent);
+    }
+
+    /**
+     * Creates the data array for a file request. This creates an array with a 4 byte command + the
+     * remote file name.
+     * @param command the 4 byte command (ID_STAT, ID_RECV, ...).
+     * @param path The path, as a byte array, of the remote file on which to
+     *      execute the command.
+     * @return the byte[] to send to the device through adb
+     */
+    private static byte[] createFileReq(byte[] command, byte[] path) {
+        byte[] array = new byte[8 + path.length];
+
+        System.arraycopy(command, 0, array, 0, 4);
+        ArrayHelper.swap32bitsToArray(path.length, array, 4);
+        System.arraycopy(path, 0, array, 8, path.length);
+
+        return array;
+    }
+
+    private static byte[] createSendFileReq(byte[] command, byte[] path, int mode) {
+        // make the mode into a string
+        String modeStr = "," + (mode & 0777); // $NON-NLS-1S
+        byte[] modeContent = null;
+        try {
+            modeContent = modeStr.getBytes(AdbHelper.DEFAULT_ENCODING);
+        } catch (UnsupportedEncodingException e) {
+            return null;
+        }
+
+        byte[] array = new byte[8 + path.length + modeContent.length];
+
+        System.arraycopy(command, 0, array, 0, 4);
+        ArrayHelper.swap32bitsToArray(path.length + modeContent.length, array, 4);
+        System.arraycopy(path, 0, array, 8, path.length);
+        System.arraycopy(modeContent, 0, array, 8 + path.length, modeContent.length);
+
+        return array;
+
+
+    }
+
+    /**
+     * Checks the result array starts with the provided code
+     * @param result The result array to check
+     * @param code The 4 byte code.
+     * @return true if the code matches.
+     */
+    private static boolean checkResult(byte[] result, byte[] code) {
+        if (result[0] != code[0] ||
+                result[1] != code[1] ||
+                result[2] != code[2] ||
+                result[3] != code[3]) {
+            return false;
+        }
+
+        return true;
+
+    }
+
+    private static int getFileType(int mode) {
+        if ((mode & S_ISOCK) == S_ISOCK) {
+            return FileListingService.TYPE_SOCKET;
+        }
+
+        if ((mode & S_IFLNK) == S_IFLNK) {
+            return FileListingService.TYPE_LINK;
+        }
+
+        if ((mode & S_IFREG) == S_IFREG) {
+            return FileListingService.TYPE_FILE;
+        }
+
+        if ((mode & S_IFBLK) == S_IFBLK) {
+            return FileListingService.TYPE_BLOCK;
+        }
+
+        if ((mode & S_IFDIR) == S_IFDIR) {
+            return FileListingService.TYPE_DIRECTORY;
+        }
+
+        if ((mode & S_IFCHR) == S_IFCHR) {
+            return FileListingService.TYPE_CHARACTER;
+        }
+
+        if ((mode & S_IFIFO) == S_IFIFO) {
+            return FileListingService.TYPE_FIFO;
+        }
+
+        return FileListingService.TYPE_OTHER;
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ThreadInfo.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ThreadInfo.java
new file mode 100644
index 0000000..8f284f3
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/ThreadInfo.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib;
+
+/**
+ * Holds a thread information.
+ */
+public final class ThreadInfo implements IStackTraceInfo {
+    private int mThreadId;
+    private String mThreadName;
+    private int mStatus;
+    private int mTid;
+    private int mUtime;
+    private int mStime;
+    private boolean mIsDaemon;
+    private StackTraceElement[] mTrace;
+    private long mTraceTime;
+
+    // priority?
+    // total CPU used?
+    // method at top of stack?
+
+    /**
+     * Construct with basic identification.
+     */
+    ThreadInfo(int threadId, String threadName) {
+        mThreadId = threadId;
+        mThreadName = threadName;
+
+        mStatus = -1;
+        //mTid = mUtime = mStime = 0;
+        //mIsDaemon = false;
+    }
+
+    /**
+     * Set with the values we get from a THST chunk.
+     */
+    void updateThread(int status, int tid, int utime, int stime, boolean isDaemon) {
+
+        mStatus = status;
+        mTid = tid;
+        mUtime = utime;
+        mStime = stime;
+        mIsDaemon = isDaemon;
+    }
+    
+    /**
+     * Sets the stack call of the thread.
+     * @param trace stackcall information.
+     */
+    void setStackCall(StackTraceElement[] trace) {
+        mTrace = trace;
+        mTraceTime = System.currentTimeMillis();
+    }
+
+    /**
+     * Returns the thread's ID.
+     */
+    public int getThreadId() {
+        return mThreadId;
+    }
+
+    /**
+     * Returns the thread's name.
+     */
+    public String getThreadName() {
+        return mThreadName;
+    }
+    
+    void setThreadName(String name) {
+        mThreadName = name;
+    }
+
+    /**
+     * Returns the system tid.
+     */
+    public int getTid() {
+        return mTid;
+    }
+
+    /**
+     * Returns the VM thread status.
+     */
+    public int getStatus() {
+        return mStatus;
+    }
+
+    /**
+     * Returns the cumulative user time.
+     */
+    public int getUtime() {
+        return mUtime;
+    }
+
+    /**
+     * Returns the cumulative system time.
+     */
+    public int getStime() {
+        return mStime;
+    }
+
+    /**
+     * Returns whether this is a daemon thread.
+     */
+    public boolean isDaemon() {
+        return mIsDaemon;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.IStackTraceInfo#getStackTrace()
+     */
+    public StackTraceElement[] getStackTrace() {
+        return mTrace;
+    }
+
+    /**
+     * Returns the approximate time of the stacktrace data.
+     * @see #getStackTrace()
+     */
+    public long getStackCallTime() {
+        return mTraceTime;
+    }
+}
+
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventContainer.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventContainer.java
new file mode 100644
index 0000000..ec9186c
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventContainer.java
@@ -0,0 +1,461 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib.log;
+
+import com.android.ddmlib.log.LogReceiver.LogEntry;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Represents an event and its data.
+ */
+public class EventContainer {
+    
+    /**
+     * Comparison method for {@link EventContainer#testValue(int, Object, com.android.ddmlib.log.EventContainer.CompareMethod)}
+     *
+     */
+    public enum CompareMethod {
+        EQUAL_TO("equals", "=="),
+        LESSER_THAN("less than or equals to", "<="),
+        LESSER_THAN_STRICT("less than", "<"),
+        GREATER_THAN("greater than or equals to", ">="),
+        GREATER_THAN_STRICT("greater than", ">"),
+        BIT_CHECK("bit check", "&");
+        
+        private final String mName;
+        private final String mTestString;
+
+        private CompareMethod(String name, String testString) {
+            mName = name;
+            mTestString = testString;
+        }
+
+        /**
+         * Returns the display string.
+         */
+        @Override
+        public String toString() {
+            return mName;
+        }
+
+        /**
+         * Returns a short string representing the comparison.
+         */
+        public String testString() {
+            return mTestString;
+        }
+    }
+
+    
+    /**
+     * Type for event data.
+     */
+    public static enum EventValueType {
+        UNKNOWN(0),
+        INT(1),
+        LONG(2),
+        STRING(3),
+        LIST(4),
+        TREE(5);
+        
+        private final static Pattern STORAGE_PATTERN = Pattern.compile("^(\\d+)@(.*)$"); //$NON-NLS-1$
+        
+        private int mValue;
+        
+        /**
+         * Returns a {@link EventValueType} from an integer value, or <code>null</code> if no match
+         * was found.
+         * @param value the integer value.
+         */
+        static EventValueType getEventValueType(int value) {
+            for (EventValueType type : values()) {
+                if (type.mValue == value) {
+                    return type;
+                }
+            }
+            
+            return null;
+        }
+
+        /**
+         * Returns a storage string for an {@link Object} of type supported by
+         * {@link EventValueType}.
+         * <p/>
+         * Strings created by this method can be reloaded with
+         * {@link #getObjectFromStorageString(String)}.
+         * <p/>
+         * NOTE: for now, only {@link #STRING}, {@link #INT}, and {@link #LONG} are supported.
+         * @param object the object to "convert" into a storage string.
+         * @return a string storing the object and its type or null if the type was not recognized.
+         */
+        public static String getStorageString(Object object) {
+            if (object instanceof String) {
+                return STRING.mValue + "@" + (String)object; //$NON-NLS-1$ 
+            } else if (object instanceof Integer) {
+                return INT.mValue + "@" + object.toString(); //$NON-NLS-1$ 
+            } else if (object instanceof Long) {
+                return LONG.mValue + "@" + object.toString(); //$NON-NLS-1$ 
+            }
+            
+            return null;
+        }
+        
+        /**
+         * Creates an {@link Object} from a storage string created with
+         * {@link #getStorageString(Object)}.
+         * @param value the storage string
+         * @return an {@link Object} or null if the string or type were not recognized.
+         */
+        public static Object getObjectFromStorageString(String value) {
+            Matcher m = STORAGE_PATTERN.matcher(value);
+            if (m.matches()) {
+                try {
+                    EventValueType type = getEventValueType(Integer.parseInt(m.group(1)));
+
+                    if (type == null) {
+                        return null;
+                    }
+                    
+                    switch (type) {
+                        case STRING:
+                            return m.group(2);
+                        case INT:
+                            return Integer.valueOf(m.group(2));
+                        case LONG:
+                            return Long.valueOf(m.group(2));
+                    }
+                } catch (NumberFormatException nfe) {
+                    return null;
+                }
+            }
+            
+            return null;
+        }
+        
+        
+        /**
+         * Returns the integer value of the enum.
+         */
+        public int getValue() {
+            return mValue;
+        }
+
+        @Override
+        public String toString() {
+            return super.toString().toLowerCase();
+        }
+
+        private EventValueType(int value) {
+            mValue = value;
+        }
+    }
+
+    public int mTag;
+    public int pid;    /* generating process's pid */
+    public int tid;    /* generating process's tid */
+    public int sec;    /* seconds since Epoch */
+    public int nsec;   /* nanoseconds */
+
+    private Object mData; 
+
+    /**
+     * Creates an {@link EventContainer} from a {@link LogEntry}.
+     * @param entry  the LogEntry from which pid, tid, and time info is copied.
+     * @param tag the event tag value
+     * @param data the data of the EventContainer.
+     */
+    EventContainer(LogEntry entry, int tag, Object data) {
+        getType(data);
+        mTag = tag;
+        mData = data;
+
+        pid = entry.pid;
+        tid = entry.tid;
+        sec = entry.sec;
+        nsec = entry.nsec;
+    }
+    
+    /**
+     * Creates an {@link EventContainer} with raw data
+     */
+    EventContainer(int tag, int pid, int tid, int sec, int nsec, Object data) {
+        getType(data);
+        mTag = tag;
+        mData = data;
+        
+        this.pid = pid;
+        this.tid = tid;
+        this.sec = sec;
+        this.nsec = nsec;
+    }
+
+    /**
+     * Returns the data as an int.
+     * @throws InvalidTypeException if the data type is not {@link EventValueType#INT}.
+     * @see #getType()
+     */
+    public final Integer getInt() throws InvalidTypeException {
+        if (getType(mData) == EventValueType.INT) {
+            return (Integer)mData;
+        }
+
+        throw new InvalidTypeException();
+    }
+    
+    /**
+     * Returns the data as a long.
+     * @throws InvalidTypeException if the data type is not {@link EventValueType#LONG}. 
+     * @see #getType()
+     */
+    public final Long getLong() throws InvalidTypeException {
+        if (getType(mData) == EventValueType.LONG) {
+            return (Long)mData;
+        }
+
+        throw new InvalidTypeException();
+    }
+
+    /**
+     * Returns the data as a String.
+     * @throws InvalidTypeException if the data type is not {@link EventValueType#STRING}.
+     * @see #getType()
+     */
+    public final String getString() throws InvalidTypeException {
+        if (getType(mData) == EventValueType.STRING) {
+            return (String)mData;
+        }
+
+        throw new InvalidTypeException();
+    }
+    
+    /**
+     * Returns a value by index. The return type is defined by its type.
+     * @param valueIndex the index of the value. If the data is not a list, this is ignored.
+     */
+    public Object getValue(int valueIndex) {
+        return getValue(mData, valueIndex, true);
+    }
+
+    /**
+     * Returns a value by index as a double.
+     * @param valueIndex the index of the value. If the data is not a list, this is ignored.
+     * @throws InvalidTypeException if the data type is not {@link EventValueType#INT},
+     * {@link EventValueType#LONG}, {@link EventValueType#LIST}, or if the item in the
+     * list at index <code>valueIndex</code> is not of type {@link EventValueType#INT} or
+     * {@link EventValueType#LONG}.
+     * @see #getType()
+     */
+    public double getValueAsDouble(int valueIndex) throws InvalidTypeException {
+        return getValueAsDouble(mData, valueIndex, true);
+    }
+
+    /**
+     * Returns a value by index as a String.
+     * @param valueIndex the index of the value. If the data is not a list, this is ignored.
+     * @throws InvalidTypeException if the data type is not {@link EventValueType#INT},
+     * {@link EventValueType#LONG}, {@link EventValueType#STRING}, {@link EventValueType#LIST},
+     * or if the item in the list at index <code>valueIndex</code> is not of type
+     * {@link EventValueType#INT}, {@link EventValueType#LONG}, or {@link EventValueType#STRING}
+     * @see #getType()
+     */
+    public String getValueAsString(int valueIndex) throws InvalidTypeException {
+        return getValueAsString(mData, valueIndex, true);
+    }
+    
+    /**
+     * Returns the type of the data.
+     */
+    public EventValueType getType() {
+        return getType(mData);
+    }
+
+    /**
+     * Returns the type of an object.
+     */
+    public final EventValueType getType(Object data) {
+        if (data instanceof Integer) {
+            return EventValueType.INT;
+        } else if (data instanceof Long) {
+            return EventValueType.LONG;
+        } else if (data instanceof String) {
+            return EventValueType.STRING;
+        } else if (data instanceof Object[]) {
+            // loop through the list to see if we have another list
+            Object[] objects = (Object[])data;
+            for (Object obj : objects) {
+                EventValueType type = getType(obj);
+                if (type == EventValueType.LIST || type == EventValueType.TREE) {
+                    return EventValueType.TREE;
+                }
+            }
+            return EventValueType.LIST;
+        }
+
+        return EventValueType.UNKNOWN;
+    }
+    
+    /**
+     * Checks that the <code>index</code>-th value of this event against a provided value.
+     * @param index the index of the value to test
+     * @param value the value to test against
+     * @param compareMethod the method of testing
+     * @return true if the test passed.
+     * @throws InvalidTypeException in case of type mismatch between the value to test and the value
+     * to test against, or if the compare method is incompatible with the type of the values.
+     * @see CompareMethod
+     */
+    public boolean testValue(int index, Object value,
+            CompareMethod compareMethod) throws InvalidTypeException {
+        EventValueType type = getType(mData);
+        if (index > 0 && type != EventValueType.LIST) {
+            throw new InvalidTypeException();
+        }
+        
+        Object data = mData;
+        if (type == EventValueType.LIST) {
+            data = ((Object[])mData)[index];
+        }
+
+        if (data.getClass().equals(data.getClass()) == false) {
+            throw new InvalidTypeException();
+        }
+
+        switch (compareMethod) {
+            case EQUAL_TO:
+                return data.equals(value);
+            case LESSER_THAN:
+                if (data instanceof Integer) {
+                    return (((Integer)data).compareTo((Integer)value) <= 0);
+                } else if (data instanceof Long) {
+                    return (((Long)data).compareTo((Long)value) <= 0);
+                }
+
+                // other types can't use this compare method.
+                throw new InvalidTypeException();
+            case LESSER_THAN_STRICT:
+                if (data instanceof Integer) {
+                    return (((Integer)data).compareTo((Integer)value) < 0);
+                } else if (data instanceof Long) {
+                    return (((Long)data).compareTo((Long)value) < 0);
+                }
+
+                // other types can't use this compare method.
+                throw new InvalidTypeException();
+            case GREATER_THAN:
+                if (data instanceof Integer) {
+                    return (((Integer)data).compareTo((Integer)value) >= 0);
+                } else if (data instanceof Long) {
+                    return (((Long)data).compareTo((Long)value) >= 0);
+                }
+
+                // other types can't use this compare method.
+                throw new InvalidTypeException();
+            case GREATER_THAN_STRICT:
+                if (data instanceof Integer) {
+                    return (((Integer)data).compareTo((Integer)value) > 0);
+                } else if (data instanceof Long) {
+                    return (((Long)data).compareTo((Long)value) > 0);
+                }
+
+                // other types can't use this compare method.
+                throw new InvalidTypeException();
+            case BIT_CHECK:
+                if (data instanceof Integer) {
+                    return (((Integer)data).intValue() & ((Integer)value).intValue()) != 0;
+                } else if (data instanceof Long) {
+                    return (((Long)data).longValue() & ((Long)value).longValue()) != 0;
+                }
+
+                // other types can't use this compare method.
+                throw new InvalidTypeException();
+            default :
+                throw new InvalidTypeException();
+        }
+    }
+    
+    private final Object getValue(Object data, int valueIndex, boolean recursive) {
+        EventValueType type = getType(data);
+        
+        switch (type) {
+            case INT:
+            case LONG:
+            case STRING:
+                return data;
+            case LIST:
+                if (recursive) {
+                    Object[] list = (Object[]) data;
+                    if (valueIndex >= 0 && valueIndex < list.length) {
+                        return getValue(list[valueIndex], valueIndex, false);
+                    }
+                }
+        }
+        
+        return null;
+    }
+
+    private final double getValueAsDouble(Object data, int valueIndex, boolean recursive)
+            throws InvalidTypeException {
+        EventValueType type = getType(data);
+        
+        switch (type) {
+            case INT:
+                return ((Integer)data).doubleValue();
+            case LONG:
+                return ((Long)data).doubleValue();
+            case STRING:
+                throw new InvalidTypeException();
+            case LIST:
+                if (recursive) {
+                    Object[] list = (Object[]) data;
+                    if (valueIndex >= 0 && valueIndex < list.length) {
+                        return getValueAsDouble(list[valueIndex], valueIndex, false);
+                    }
+                }
+        }
+        
+        throw new InvalidTypeException();
+    }
+
+    private final String getValueAsString(Object data, int valueIndex, boolean recursive)
+            throws InvalidTypeException {
+        EventValueType type = getType(data);
+        
+        switch (type) {
+            case INT:
+                return ((Integer)data).toString();
+            case LONG:
+                return ((Long)data).toString();
+            case STRING:
+                return (String)data;
+            case LIST:
+                if (recursive) {
+                    Object[] list = (Object[]) data;
+                    if (valueIndex >= 0 && valueIndex < list.length) {
+                        return getValueAsString(list[valueIndex], valueIndex, false);
+                    }
+                } else {
+                    throw new InvalidTypeException(
+                            "getValueAsString() doesn't support EventValueType.TREE");
+                }
+        }
+
+        throw new InvalidTypeException(
+                "getValueAsString() unsupported type:" + type);
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventLogParser.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventLogParser.java
new file mode 100644
index 0000000..85e99c1
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventLogParser.java
@@ -0,0 +1,577 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib.log;
+
+import com.android.ddmlib.Device;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.MultiLineReceiver;
+import com.android.ddmlib.log.EventContainer.EventValueType;
+import com.android.ddmlib.log.EventValueDescription.ValueType;
+import com.android.ddmlib.log.LogReceiver.LogEntry;
+import com.android.ddmlib.utils.ArrayHelper;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Parser for the "event" log.
+ */
+public final class EventLogParser {
+
+    /** Location of the tag map file on the device */
+    private final static String EVENT_TAG_MAP_FILE = "/system/etc/event-log-tags"; //$NON-NLS-1$
+
+    /**
+     * Event log entry types.  These must match up with the declarations in
+     * java/android/android/util/EventLog.java.
+     */
+    private final static int EVENT_TYPE_INT      = 0;
+    private final static int EVENT_TYPE_LONG     = 1;
+    private final static int EVENT_TYPE_STRING   = 2;
+    private final static int EVENT_TYPE_LIST     = 3;
+    
+    private final static Pattern PATTERN_SIMPLE_TAG = Pattern.compile(
+    "^(\\d+)\\s+([A-Za-z0-9_]+)\\s*$"); //$NON-NLS-1$
+    private final static Pattern PATTERN_TAG_WITH_DESC = Pattern.compile(
+            "^(\\d+)\\s+([A-Za-z0-9_]+)\\s*(.*)\\s*$"); //$NON-NLS-1$
+    private final static Pattern PATTERN_DESCRIPTION = Pattern.compile(
+            "\\(([A-Za-z0-9_\\s]+)\\|(\\d+)(\\|\\d+){0,1}\\)"); //$NON-NLS-1$
+
+    private final static Pattern TEXT_LOG_LINE = Pattern.compile(
+            "(\\d\\d)-(\\d\\d)\\s(\\d\\d):(\\d\\d):(\\d\\d).(\\d{3})\\s+I/([a-zA-Z0-9_]+)\\s*\\(\\s*(\\d+)\\):\\s+(.*)"); //$NON-NLS-1$
+
+    private final TreeMap<Integer, String> mTagMap = new TreeMap<Integer, String>();
+    
+    private final TreeMap<Integer, EventValueDescription[]> mValueDescriptionMap =
+        new TreeMap<Integer, EventValueDescription[]>(); 
+
+    public EventLogParser() {
+    }
+
+    /**
+     * Inits the parser for a specific Device.
+     * <p/>
+     * This methods reads the event-log-tags located on the device to find out
+     * what tags are being written to the event log and what their format is.
+     * @param device The device.
+     * @return <code>true</code> if success, <code>false</code> if failure or cancellation.
+     */
+    public boolean init(Device device) {
+        // read the event tag map file on the device.
+        try {
+            device.executeShellCommand("cat " + EVENT_TAG_MAP_FILE, //$NON-NLS-1$
+                    new MultiLineReceiver() {
+                @Override
+                public void processNewLines(String[] lines) {
+                    for (String line : lines) {
+                        processTagLine(line);
+                    }
+                }
+                public boolean isCancelled() {
+                    return false;
+                }
+            });
+        } catch (IOException e) {
+            return false;
+        }
+
+        return true;
+    }
+    
+    /**
+     * Inits the parser with the content of a tag file.
+     * @param tagFileContent the lines of a tag file.
+     * @return <code>true</code> if success, <code>false</code> if failure.
+     */
+    public boolean init(String[] tagFileContent) {
+        for (String line : tagFileContent) {
+            processTagLine(line);
+        }
+        return true;
+    }
+    
+    /**
+     * Inits the parser with a specified event-log-tags file.
+     * @param filePath
+     * @return <code>true</code> if success, <code>false</code> if failure.
+     */
+    public boolean init(String filePath)  {
+        try {
+            BufferedReader reader = new BufferedReader(new FileReader(filePath));
+            
+            String line = null;
+            do {
+                line = reader.readLine();
+                if (line != null) {
+                    processTagLine(line);
+                }
+            } while (line != null);
+            
+            return true;
+        } catch (IOException e) {
+            return false;
+        }
+    }
+    
+    /**
+     * Processes a line from the event-log-tags file.
+     * @param line the line to process
+     */
+    private void processTagLine(String line) {
+        // ignore empty lines and comment lines
+        if (line.length() > 0 && line.charAt(0) != '#') {
+            Matcher m = PATTERN_TAG_WITH_DESC.matcher(line);
+            if (m.matches()) {
+                try {
+                    int value = Integer.parseInt(m.group(1));
+                    String name = m.group(2);
+                    if (name != null && mTagMap.get(value) == null) {
+                        mTagMap.put(value, name);
+                    }
+                    
+                    // special case for the GC tag. We ignore what is in the file,
+                    // and take what the custom GcEventContainer class tells us.
+                    // This is due to the event encoding several values on 2 longs.
+                    // @see GcEventContainer
+                    if (value == GcEventContainer.GC_EVENT_TAG) {
+                        mValueDescriptionMap.put(value,
+                            GcEventContainer.getValueDescriptions());
+                    } else {
+                        
+                        String description = m.group(3);
+                        if (description != null && description.length() > 0) {
+                            EventValueDescription[] desc =
+                                processDescription(description);
+                            
+                            if (desc != null) {
+                                mValueDescriptionMap.put(value, desc);
+                            }
+                        }
+                    }
+                } catch (NumberFormatException e) {
+                    // failed to convert the number into a string. just ignore it.
+                }
+            } else {
+                m = PATTERN_SIMPLE_TAG.matcher(line);
+                if (m.matches()) {
+                    int value = Integer.parseInt(m.group(1));
+                    String name = m.group(2);
+                    if (name != null && mTagMap.get(value) == null) {
+                        mTagMap.put(value, name);
+                    }
+                }
+            }
+        }
+    }
+    
+    private EventValueDescription[] processDescription(String description) {
+        String[] descriptions = description.split("\\s*,\\s*"); //$NON-NLS-1$
+        
+        ArrayList<EventValueDescription> list = new ArrayList<EventValueDescription>();
+        
+        for (String desc : descriptions) {
+            Matcher m = PATTERN_DESCRIPTION.matcher(desc);
+            if (m.matches()) {
+                try {
+                    String name = m.group(1);
+
+                    String typeString = m.group(2);
+                    int typeValue = Integer.parseInt(typeString);
+                    EventValueType eventValueType = EventValueType.getEventValueType(typeValue);
+                    if (eventValueType == null) {
+                        // just ignore this description if the value is not recognized.
+                        // TODO: log the error.
+                    }
+                    
+                    typeString = m.group(3);
+                    if (typeString != null && typeString.length() > 0) {
+                        //skip the |
+                        typeString = typeString.substring(1);
+                        
+                        typeValue = Integer.parseInt(typeString);
+                        ValueType valueType = ValueType.getValueType(typeValue);
+                        
+                        list.add(new EventValueDescription(name, eventValueType, valueType));
+                    } else {
+                        list.add(new EventValueDescription(name, eventValueType));
+                    }
+                } catch (NumberFormatException nfe) {
+                    // just ignore this description if one number is malformed.
+                    // TODO: log the error.
+                } catch (InvalidValueTypeException e) {
+                    // just ignore this description if data type and data unit don't match
+                    // TODO: log the error.
+                }
+            } else {
+                Log.e("EventLogParser",  //$NON-NLS-1$
+                    String.format("Can't parse %1$s", description));  //$NON-NLS-1$
+            }
+        }
+        
+        if (list.size() == 0) {
+            return null;
+        }
+        
+        return list.toArray(new EventValueDescription[list.size()]);
+        
+    }
+    
+    public EventContainer parse(LogEntry entry) {
+        if (entry.len < 4) {
+            return null;
+        }
+
+        int inOffset = 0;
+
+        int tagValue = ArrayHelper.swap32bitFromArray(entry.data, inOffset);
+        inOffset += 4;
+        
+        String tag = mTagMap.get(tagValue);
+        if (tag == null) {
+            Log.e("EventLogParser", String.format("unknown tag number: %1$d", tagValue));
+        }
+
+        ArrayList<Object> list = new ArrayList<Object>();
+        if (parseBinaryEvent(entry.data, inOffset, list) == -1) {
+            return null;
+        }
+
+        Object data;
+        if (list.size() == 1) {
+            data = list.get(0);
+        } else{
+            data = list.toArray();
+        }
+
+        EventContainer event = null;
+        if (tagValue == GcEventContainer.GC_EVENT_TAG) {
+            event = new GcEventContainer(entry, tagValue, data);
+        } else {
+            event = new EventContainer(entry, tagValue, data);
+        }
+        
+        return event;
+    }
+    
+    public EventContainer parse(String textLogLine) {
+        // line will look like
+        // 04-29 23:16:16.691 I/dvm_gc_info(  427): <data>
+        // where <data> is either
+        // [value1,value2...]
+        // or
+        // value
+        if (textLogLine.length() == 0) {
+            return null;
+        }
+        
+        // parse the header first
+        Matcher m = TEXT_LOG_LINE.matcher(textLogLine);
+        if (m.matches()) {
+            try {
+                int month = Integer.parseInt(m.group(1));
+                int day = Integer.parseInt(m.group(2));
+                int hours = Integer.parseInt(m.group(3));
+                int minutes = Integer.parseInt(m.group(4));
+                int seconds = Integer.parseInt(m.group(5));
+                int milliseconds = Integer.parseInt(m.group(6));
+                
+                // convert into seconds since epoch and nano-seconds.
+                Calendar cal = Calendar.getInstance();
+                cal.set(cal.get(Calendar.YEAR), month-1, day, hours, minutes, seconds);
+                int sec = (int)Math.floor(cal.getTimeInMillis()/1000);
+                int nsec = milliseconds * 1000000;
+
+                String tag = m.group(7);
+                
+                // get the numerical tag value
+                int tagValue = -1;
+                Set<Entry<Integer, String>> tagSet = mTagMap.entrySet();
+                for (Entry<Integer, String> entry : tagSet) {
+                    if (tag.equals(entry.getValue())) {
+                        tagValue = entry.getKey();
+                        break;
+                    }
+                }
+                
+                if (tagValue == -1) {
+                    return null;
+                }
+                
+                int pid = Integer.parseInt(m.group(8));
+                
+                Object data = parseTextData(m.group(9), tagValue);
+                if (data == null) {
+                    return null;
+                }
+                
+                // now we can allocate and return the EventContainer
+                EventContainer event = null;
+                if (tagValue == GcEventContainer.GC_EVENT_TAG) {
+                    event = new GcEventContainer(tagValue, pid, -1 /* tid */, sec, nsec, data);
+                } else {
+                    event = new EventContainer(tagValue, pid, -1 /* tid */, sec, nsec, data);
+                }
+                
+                return event;
+            } catch (NumberFormatException e) {
+                return null;
+            }
+        }
+        
+        return null;
+    }
+    
+    public Map<Integer, String> getTagMap() {
+        return mTagMap;
+    }
+    
+    public Map<Integer, EventValueDescription[]> getEventInfoMap() {
+        return mValueDescriptionMap;
+    }
+
+    /**
+     * Recursively convert binary log data to printable form.
+     *
+     * This needs to be recursive because you can have lists of lists.
+     *
+     * If we run out of room, we stop processing immediately.  It's important
+     * for us to check for space on every output element to avoid producing
+     * garbled output.
+     *
+     * Returns the amount read on success, -1 on failure.
+     */
+    private static int parseBinaryEvent(byte[] eventData, int dataOffset, ArrayList<Object> list) {
+
+        if (eventData.length - dataOffset < 1)
+            return -1;
+        
+        int offset = dataOffset;
+
+        int type = eventData[offset++];
+
+        //fprintf(stderr, "--- type=%d (rem len=%d)\n", type, eventDataLen);
+
+        switch (type) {
+        case EVENT_TYPE_INT: { /* 32-bit signed int */
+                int ival;
+
+                if (eventData.length - offset < 4)
+                    return -1;
+                ival = ArrayHelper.swap32bitFromArray(eventData, offset);
+                offset += 4;
+                
+                list.add(new Integer(ival));
+            }
+            break;
+        case EVENT_TYPE_LONG: { /* 64-bit signed long */
+                long lval;
+
+                if (eventData.length - offset < 8)
+                    return -1;
+                lval = ArrayHelper.swap64bitFromArray(eventData, offset);
+                offset += 8;
+                
+                list.add(new Long(lval));
+            }
+            break;
+        case EVENT_TYPE_STRING: { /* UTF-8 chars, not NULL-terminated */
+                int strLen;
+
+                if (eventData.length - offset < 4)
+                    return -1;
+                strLen = ArrayHelper.swap32bitFromArray(eventData, offset);
+                offset += 4;
+
+                if (eventData.length - offset < strLen)
+                    return -1;
+                
+                // get the string
+                try {
+                    String str = new String(eventData, offset, strLen, "UTF-8"); //$NON-NLS-1$
+                    list.add(str);
+                } catch (UnsupportedEncodingException e) {
+                }
+                offset += strLen;
+                break;
+            }
+        case EVENT_TYPE_LIST: { /* N items, all different types */
+
+                if (eventData.length - offset < 1)
+                    return -1;
+
+                int count = eventData[offset++];
+
+                // make a new temp list
+                ArrayList<Object> subList = new ArrayList<Object>();
+                for (int i = 0; i < count; i++) {
+                    int result = parseBinaryEvent(eventData, offset, subList);
+                    if (result == -1) {
+                        return result;
+                    }
+                    
+                    offset += result;
+                }
+
+                list.add(subList.toArray());
+            }
+            break;
+        default:
+            Log.e("EventLogParser",  //$NON-NLS-1$
+                    String.format("Unknown binary event type %1$d", type));  //$NON-NLS-1$
+            return -1;
+        }
+        
+        return offset - dataOffset;
+    }
+    
+    private Object parseTextData(String data, int tagValue) {
+        // first, get the description of what we're supposed to parse
+        EventValueDescription[] desc = mValueDescriptionMap.get(tagValue);
+        
+        if (desc == null) {
+            // TODO parse and create string values.
+            return null;
+        }
+        
+        if (desc.length == 1) {
+            return getObjectFromString(data, desc[0].getEventValueType());
+        } else if (data.startsWith("[") && data.endsWith("]")) {
+            data = data.substring(1, data.length() - 1);
+            
+            // get each individual values as String
+            String[] values = data.split(",");
+            
+            if (tagValue == GcEventContainer.GC_EVENT_TAG) {
+                // special case for the GC event!
+                Object[] objects = new Object[2];
+                
+                objects[0] = getObjectFromString(values[0], EventValueType.LONG);
+                objects[1] = getObjectFromString(values[1], EventValueType.LONG);
+                
+                return objects;
+            } else {
+                // must be the same number as the number of descriptors.
+                if (values.length != desc.length) {
+                    return null;
+                }
+                
+                Object[] objects = new Object[values.length];
+                
+                for (int i = 0 ; i < desc.length ; i++) {
+                    Object obj = getObjectFromString(values[i], desc[i].getEventValueType());
+                    if (obj == null) {
+                        return null;
+                    }
+                    objects[i] = obj; 
+                }
+                
+                return objects;
+            }
+        }
+        
+        return null;
+    }
+
+    
+    private Object getObjectFromString(String value, EventValueType type) {
+        try {
+            switch (type) {
+                case INT:
+                    return Integer.valueOf(value);
+                case LONG:
+                    return Long.valueOf(value);
+                case STRING:
+                    return value;
+            }
+        } catch (NumberFormatException e) {
+            // do nothing, we'll return null.
+        }
+        
+        return null;
+    }
+
+    /**
+     * Recreates the event-log-tags at the specified file path. 
+     * @param filePath the file path to write the file.
+     * @throws IOException 
+     */
+    public void saveTags(String filePath) throws IOException {
+        File destFile = new File(filePath);
+        destFile.createNewFile();
+        FileOutputStream fos = null;
+
+        try {
+            
+            fos = new FileOutputStream(destFile);
+            
+            for (Integer key : mTagMap.keySet()) {
+                // get the tag name
+                String tagName = mTagMap.get(key);
+                
+                // get the value descriptions
+                EventValueDescription[] descriptors = mValueDescriptionMap.get(key);
+                
+                String line = null;
+                if (descriptors != null) {
+                    StringBuilder sb = new StringBuilder();
+                    sb.append(String.format("%1$d %2$s", key, tagName)); //$NON-NLS-1$
+                    boolean first = true;
+                    for (EventValueDescription evd : descriptors) {
+                        if (first) {
+                            sb.append(" ("); //$NON-NLS-1$
+                            first = false;
+                        } else {
+                            sb.append(",("); //$NON-NLS-1$
+                        }
+                        sb.append(evd.getName());
+                        sb.append("|"); //$NON-NLS-1$
+                        sb.append(evd.getEventValueType().getValue());
+                        sb.append("|"); //$NON-NLS-1$
+                        sb.append(evd.getValueType().getValue());
+                        sb.append("|)"); //$NON-NLS-1$
+                    }
+                    sb.append("\n"); //$NON-NLS-1$
+                    
+                    line = sb.toString();
+                } else {
+                    line = String.format("%1$d %2$s\n", key, tagName); //$NON-NLS-1$
+                }
+    
+                byte[] buffer = line.getBytes();
+                fos.write(buffer);
+            }
+        } finally {
+            if (fos != null) {
+                fos.close();
+            }
+        }
+    }
+
+
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventValueDescription.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventValueDescription.java
new file mode 100644
index 0000000..b68b4e8
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/EventValueDescription.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib.log;
+
+import com.android.ddmlib.log.EventContainer.EventValueType;
+
+
+/**
+ * Describes an {@link EventContainer} value.
+ * <p/>
+ * This is a stand-alone object, not linked to a particular Event. It describes the value, by
+ * name, type ({@link EventValueType}), and (if needed) value unit ({@link ValueType}).
+ * <p/>
+ * The index of the value is not contained within this class, and is instead dependent on the
+ * index of this particular object in the array of {@link EventValueDescription} returned by
+ * {@link EventLogParser#getEventInfoMap()} when queried for a particular event tag.
+ * 
+ */
+public final class EventValueDescription {
+    
+    /**
+     * Represents the type of a numerical value. This is used to display values of vastly different
+     * type/range in graphs. 
+     */
+    public static enum ValueType {
+        NOT_APPLICABLE(0),
+        OBJECTS(1),
+        BYTES(2),
+        MILLISECONDS(3),
+        ALLOCATIONS(4),
+        ID(5),
+        PERCENT(6);
+
+        private int mValue;
+
+        /**
+         * Checks that the {@link EventValueType} is compatible with the {@link ValueType}.
+         * @param type the {@link EventValueType} to check.
+         * @throws InvalidValueTypeException if the types are not compatible.
+         */
+        public void checkType(EventValueType type) throws InvalidValueTypeException {
+            if ((type != EventValueType.INT && type != EventValueType.LONG)
+                    && this != NOT_APPLICABLE) {
+                throw new InvalidValueTypeException(
+                        String.format("%1$s doesn't support type %2$s", type, this));
+            }
+        }
+
+        /**
+         * Returns a {@link ValueType} from an integer value, or <code>null</code> if no match
+         * were found.
+         * @param value the integer value.
+         */
+        public static ValueType getValueType(int value) {
+            for (ValueType type : values()) {
+                if (type.mValue == value) {
+                    return type;
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Returns the integer value of the enum.
+         */
+        public int getValue() {
+            return mValue;
+        }
+        
+        @Override
+        public String toString() {
+            return super.toString().toLowerCase();
+        }
+        
+        private ValueType(int value) {
+            mValue = value;
+        }
+    }
+    
+    private String mName;
+    private EventValueType mEventValueType;
+    private ValueType mValueType;
+    
+    /**
+     * Builds a {@link EventValueDescription} with a name and a type.
+     * <p/>
+     * If the type is {@link EventValueType#INT} or {@link EventValueType#LONG}, the
+     * {@link #mValueType} is set to {@link ValueType#BYTES} by default. It set to
+     * {@link ValueType#NOT_APPLICABLE} for all other {@link EventValueType} values.
+     * @param name
+     * @param type
+     */
+    EventValueDescription(String name, EventValueType type) {
+        mName = name;
+        mEventValueType = type;
+        if (mEventValueType == EventValueType.INT || mEventValueType == EventValueType.LONG) {
+            mValueType = ValueType.BYTES;
+        } else {
+            mValueType = ValueType.NOT_APPLICABLE;
+        }
+    }
+
+    /**
+     * Builds a {@link EventValueDescription} with a name and a type, and a {@link ValueType}.
+     * <p/>
+     * @param name
+     * @param type
+     * @param valueType
+     * @throws InvalidValueTypeException if type and valuetype are not compatible.
+     * 
+     */
+    EventValueDescription(String name, EventValueType type, ValueType valueType)
+            throws InvalidValueTypeException {
+        mName = name;
+        mEventValueType = type;
+        mValueType = valueType;
+        mValueType.checkType(mEventValueType);
+    }
+    
+    /**
+     * @return the Name.
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * @return the {@link EventValueType}.
+     */
+    public EventValueType getEventValueType() {
+        return mEventValueType;
+    }
+
+    /**
+     * @return the {@link ValueType}.
+     */
+    public ValueType getValueType() {
+        return mValueType;
+    }
+    
+    @Override
+    public String toString() {
+        if (mValueType != ValueType.NOT_APPLICABLE) {
+            return String.format("%1$s (%2$s, %3$s)", mName, mEventValueType.toString(),
+                    mValueType.toString());
+        }
+        
+        return String.format("%1$s (%2$s)", mName, mEventValueType.toString());
+    }
+
+    /**
+     * Checks if the value is of the proper type for this receiver.
+     * @param value the value to check.
+     * @return true if the value is of the proper type for this receiver.
+     */
+    public boolean checkForType(Object value) {
+        switch (mEventValueType) {
+            case INT:
+                return value instanceof Integer;
+            case LONG:
+                return value instanceof Long;
+            case STRING:
+                return value instanceof String;
+            case LIST:
+                return value instanceof Object[];
+        }
+        
+        return false;
+    }
+    
+    /**
+     * Returns an object of a valid type (based on the value returned by
+     * {@link #getEventValueType()}) from a String value.
+     * <p/>
+     * IMPORTANT {@link EventValueType#LIST} and {@link EventValueType#TREE} are not
+     * supported.
+     * @param value the value of the object expressed as a string.
+     * @return an object or null if the conversion could not be done.
+     */
+    public Object getObjectFromString(String value) {
+        switch (mEventValueType) {
+            case INT:
+                try {
+                    return Integer.valueOf(value);
+                } catch (NumberFormatException e) {
+                    return null;
+                }
+            case LONG:
+                try {
+                    return Long.valueOf(value);
+                } catch (NumberFormatException e) {
+                    return null;
+                }
+            case STRING:
+                return value;
+        }
+        
+        return null;
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/GcEventContainer.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/GcEventContainer.java
new file mode 100644
index 0000000..7bae202
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/GcEventContainer.java
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib.log;
+
+import com.android.ddmlib.log.EventValueDescription.ValueType;
+import com.android.ddmlib.log.LogReceiver.LogEntry;
+
+/**
+ * Custom Event Container for the Gc event since this event doesn't simply output data in
+ * int or long format, but encodes several values on 4 longs.
+ * <p/>
+ * The array of {@link EventValueDescription}s parsed from the "event-log-tags" file must
+ * be ignored, and instead, the array returned from {@link #getValueDescriptions()} must be used. 
+ */
+final class GcEventContainer extends EventContainer {
+    
+    public final static int GC_EVENT_TAG = 20001;
+
+    private String processId;
+    private long gcTime;
+    private long bytesFreed;
+    private long objectsFreed;
+    private long actualSize;
+    private long allowedSize;
+    private long softLimit;
+    private long objectsAllocated;
+    private long bytesAllocated;
+    private long zActualSize;
+    private long zAllowedSize;
+    private long zObjectsAllocated;
+    private long zBytesAllocated;
+    private long dlmallocFootprint;
+    private long mallinfoTotalAllocatedSpace;
+    private long externalLimit;
+    private long externalBytesAllocated;
+
+    GcEventContainer(LogEntry entry, int tag, Object data) {
+        super(entry, tag, data);
+        init(data);
+    }
+
+    GcEventContainer(int tag, int pid, int tid, int sec, int nsec, Object data) {
+        super(tag, pid, tid, sec, nsec, data);
+        init(data);
+    }
+
+    /**
+     * @param data
+     */
+    private void init(Object data) {
+        if (data instanceof Object[]) {
+            Object[] values = (Object[])data;
+            for (int i = 0; i < values.length; i++) {
+                if (values[i] instanceof Long) {
+                    parseDvmHeapInfo((Long)values[i], i);
+                }
+            }
+        }
+    }
+    
+    @Override
+    public EventValueType getType() {
+        return EventValueType.LIST;
+    }
+
+    @Override
+    public boolean testValue(int index, Object value, CompareMethod compareMethod)
+            throws InvalidTypeException {
+        // do a quick easy check on the type.
+        if (index == 0) {
+            if ((value instanceof String) == false) {
+                throw new InvalidTypeException();
+            }
+        } else if ((value instanceof Long) == false) {
+            throw new InvalidTypeException();
+        }
+        
+        switch (compareMethod) {
+            case EQUAL_TO:
+                if (index == 0) {
+                    return processId.equals(value);
+                } else {
+                    return getValueAsLong(index) == ((Long)value).longValue();
+                }
+            case LESSER_THAN:
+                return getValueAsLong(index) <= ((Long)value).longValue();
+            case LESSER_THAN_STRICT:
+                return getValueAsLong(index) < ((Long)value).longValue();
+            case GREATER_THAN:
+                return getValueAsLong(index) >= ((Long)value).longValue();
+            case GREATER_THAN_STRICT:
+                return getValueAsLong(index) > ((Long)value).longValue();
+            case BIT_CHECK:
+                return (getValueAsLong(index) & ((Long)value).longValue()) != 0;
+        }
+
+        throw new ArrayIndexOutOfBoundsException();
+    }
+
+    @Override
+    public Object getValue(int valueIndex) {
+        if (valueIndex == 0) {
+            return processId;
+        }
+        
+        try {
+            return new Long(getValueAsLong(valueIndex));
+        } catch (InvalidTypeException e) {
+            // this would only happened if valueIndex was 0, which we test above.
+        }
+        
+        return null;
+    }
+
+    @Override
+    public double getValueAsDouble(int valueIndex) throws InvalidTypeException {
+        return (double)getValueAsLong(valueIndex);
+    }
+
+    @Override
+    public String getValueAsString(int valueIndex) {
+        switch (valueIndex) {
+            case 0:
+                return processId;
+            default:
+                try {
+                    return Long.toString(getValueAsLong(valueIndex));
+                } catch (InvalidTypeException e) {
+                    // we shouldn't stop there since we test, in this method first.
+                }
+        }
+
+        throw new ArrayIndexOutOfBoundsException();
+    }
+    
+    /**
+     * Returns a custom array of {@link EventValueDescription} since the actual content of this
+     * event (list of (long, long) does not match the values encoded into those longs.
+     */
+    static EventValueDescription[] getValueDescriptions() {
+        try {
+            return new EventValueDescription[] {
+                    new EventValueDescription("Process Name", EventValueType.STRING),
+                    new EventValueDescription("GC Time", EventValueType.LONG,
+                            ValueType.MILLISECONDS),
+                    new EventValueDescription("Freed Objects", EventValueType.LONG,
+                            ValueType.OBJECTS),
+                    new EventValueDescription("Freed Bytes", EventValueType.LONG, ValueType.BYTES),
+                    new EventValueDescription("Soft Limit", EventValueType.LONG, ValueType.BYTES),
+                    new EventValueDescription("Actual Size (aggregate)", EventValueType.LONG,
+                            ValueType.BYTES),
+                    new EventValueDescription("Allowed Size (aggregate)", EventValueType.LONG,
+                            ValueType.BYTES),
+                    new EventValueDescription("Allocated Objects (aggregate)",
+                            EventValueType.LONG, ValueType.OBJECTS),
+                    new EventValueDescription("Allocated Bytes (aggregate)", EventValueType.LONG,
+                            ValueType.BYTES),
+                    new EventValueDescription("Actual Size", EventValueType.LONG, ValueType.BYTES),
+                    new EventValueDescription("Allowed Size", EventValueType.LONG, ValueType.BYTES),
+                    new EventValueDescription("Allocated Objects", EventValueType.LONG,
+                            ValueType.OBJECTS),
+                    new EventValueDescription("Allocated Bytes", EventValueType.LONG,
+                            ValueType.BYTES),
+                    new EventValueDescription("Actual Size (zygote)", EventValueType.LONG,
+                            ValueType.BYTES),
+                    new EventValueDescription("Allowed Size (zygote)", EventValueType.LONG,
+                            ValueType.BYTES),
+                    new EventValueDescription("Allocated Objects (zygote)", EventValueType.LONG,
+                            ValueType.OBJECTS),
+                    new EventValueDescription("Allocated Bytes (zygote)", EventValueType.LONG,
+                            ValueType.BYTES),
+                    new EventValueDescription("External Allocation Limit", EventValueType.LONG,
+                            ValueType.BYTES),
+                    new EventValueDescription("External Bytes Allocated", EventValueType.LONG,
+                            ValueType.BYTES),
+                    new EventValueDescription("dlmalloc Footprint", EventValueType.LONG,
+                            ValueType.BYTES),
+                    new EventValueDescription("Malloc Info: Total Allocated Space",
+                            EventValueType.LONG, ValueType.BYTES),
+                  };
+        } catch (InvalidValueTypeException e) {
+            // this shouldn't happen since we control manual the EventValueType and the ValueType
+            // values. For development purpose, we assert if this happens.
+            assert false;
+        }
+
+        // this shouldn't happen, but the compiler complains otherwise.
+        return null;
+    }
+
+    private void parseDvmHeapInfo(long data, int index) {
+        switch (index) {
+            case 0:
+                //    [63   ] Must be zero
+                //    [62-24] ASCII process identifier
+                //    [23-12] GC time in ms
+                //    [11- 0] Bytes freed
+                
+                gcTime = float12ToInt((int)((data >> 12) & 0xFFFL));
+                bytesFreed = float12ToInt((int)(data & 0xFFFL));
+                
+                // convert the long into an array, in the proper order so that we can convert the
+                // first 5 char into a string.
+                byte[] dataArray = new byte[8];
+                put64bitsToArray(data, dataArray, 0);
+                
+                // get the name from the string
+                processId = new String(dataArray, 0, 5);
+                break;
+            case 1:
+                //    [63-62] 10
+                //    [61-60] Reserved; must be zero
+                //    [59-48] Objects freed
+                //    [47-36] Actual size (current footprint)
+                //    [35-24] Allowed size (current hard max)
+                //    [23-12] Objects allocated
+                //    [11- 0] Bytes allocated
+                objectsFreed = float12ToInt((int)((data >> 48) & 0xFFFL));
+                actualSize = float12ToInt((int)((data >> 36) & 0xFFFL));
+                allowedSize = float12ToInt((int)((data >> 24) & 0xFFFL));
+                objectsAllocated = float12ToInt((int)((data >> 12) & 0xFFFL));
+                bytesAllocated = float12ToInt((int)(data & 0xFFFL));
+                break;
+            case 2:
+                //    [63-62] 11
+                //    [61-60] Reserved; must be zero
+                //    [59-48] Soft limit (current soft max)
+                //    [47-36] Actual size (current footprint)
+                //    [35-24] Allowed size (current hard max)
+                //    [23-12] Objects allocated
+                //    [11- 0] Bytes allocated
+                softLimit = float12ToInt((int)((data >> 48) & 0xFFFL));
+                zActualSize = float12ToInt((int)((data >> 36) & 0xFFFL));
+                zAllowedSize = float12ToInt((int)((data >> 24) & 0xFFFL));
+                zObjectsAllocated = float12ToInt((int)((data >> 12) & 0xFFFL));
+                zBytesAllocated = float12ToInt((int)(data & 0xFFFL));
+                break;
+            case 3:
+                //    [63-48] Reserved; must be zero
+                //    [47-36] dlmallocFootprint
+                //    [35-24] mallinfo: total allocated space
+                //    [23-12] External byte limit
+                //    [11- 0] External bytes allocated
+                dlmallocFootprint = float12ToInt((int)((data >> 36) & 0xFFFL));
+                mallinfoTotalAllocatedSpace = float12ToInt((int)((data >> 24) & 0xFFFL));
+                externalLimit = float12ToInt((int)((data >> 12) & 0xFFFL));
+                externalBytesAllocated = float12ToInt((int)(data & 0xFFFL));
+                break;
+            default:
+                break;
+        }
+    }
+    
+    /**
+     * Converts a 12 bit float representation into an unsigned int (returned as a long)
+     * @param f12
+     */
+    private static long float12ToInt(int f12) {
+        return (f12 & 0x1FF) << ((f12 >>> 9) * 4);
+    }
+    
+    /**
+     * puts an unsigned value in an array.
+     * @param value The value to put.
+     * @param dest the destination array
+     * @param offset the offset in the array where to put the value.
+     *      Array length must be at least offset + 8
+     */
+    private static void put64bitsToArray(long value, byte[] dest, int offset) {
+        dest[offset + 7] = (byte)(value & 0x00000000000000FFL);
+        dest[offset + 6] = (byte)((value & 0x000000000000FF00L) >> 8);
+        dest[offset + 5] = (byte)((value & 0x0000000000FF0000L) >> 16);
+        dest[offset + 4] = (byte)((value & 0x00000000FF000000L) >> 24);
+        dest[offset + 3] = (byte)((value & 0x000000FF00000000L) >> 32);
+        dest[offset + 2] = (byte)((value & 0x0000FF0000000000L) >> 40);
+        dest[offset + 1] = (byte)((value & 0x00FF000000000000L) >> 48);
+        dest[offset + 0] = (byte)((value & 0xFF00000000000000L) >> 56);
+    }
+    
+    /**
+     * Returns the long value of the <code>valueIndex</code>-th value.
+     * @param valueIndex the index of the value.
+     * @throws InvalidTypeException if index is 0 as it is a string value.
+     */
+    private final long getValueAsLong(int valueIndex) throws InvalidTypeException {
+        switch (valueIndex) {
+            case 0:
+                throw new InvalidTypeException();
+            case 1:
+                return gcTime;
+            case 2:
+                return objectsFreed;
+            case 3:
+                return bytesFreed;
+            case 4:
+                return softLimit;
+            case 5:
+                return actualSize;
+            case 6:
+                return allowedSize;
+            case 7:
+                return objectsAllocated;
+            case 8:
+                return bytesAllocated;
+            case 9:
+                return actualSize - zActualSize;
+            case 10:
+                return allowedSize - zAllowedSize;
+            case 11:
+                return objectsAllocated - zObjectsAllocated;
+            case 12:
+                return bytesAllocated - zBytesAllocated;
+            case 13:
+               return zActualSize;
+            case 14:
+                return zAllowedSize;
+            case 15:
+                return zObjectsAllocated;
+            case 16:
+                return zBytesAllocated;
+            case 17:
+                return externalLimit;
+            case 18:
+                return externalBytesAllocated;
+            case 19:
+                return dlmallocFootprint;
+            case 20:
+                return mallinfoTotalAllocatedSpace;
+        }
+
+        throw new ArrayIndexOutOfBoundsException();
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/InvalidTypeException.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/InvalidTypeException.java
new file mode 100644
index 0000000..016f8aa
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/InvalidTypeException.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib.log;
+
+import java.io.Serializable;
+
+/**
+ * Exception thrown when accessing an {@link EventContainer} value with the wrong type.
+ */
+public final class InvalidTypeException extends Exception {
+
+    /**
+     * Needed by {@link Serializable}.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructs a new exception with the default detail message.
+     * @see java.lang.Exception
+     */
+    public InvalidTypeException() {
+        super("Invalid Type");
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message.
+     * @param message the detail message. The detail message is saved for later retrieval
+     * by the {@link Throwable#getMessage()} method.
+     * @see java.lang.Exception
+     */
+    public InvalidTypeException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail message of
+     * <code>(cause==null ? null : cause.toString())</code> (which typically contains
+     * the class and detail message of cause).
+     * @param cause the cause (which is saved for later retrieval by the
+     * {@link Throwable#getCause()} method). (A <code>null</code> value is permitted,
+     * and indicates that the cause is nonexistent or unknown.)
+     * @see java.lang.Exception
+     */
+    public InvalidTypeException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message and cause.
+     * @param message the detail message. The detail message is saved for later retrieval
+     * by the {@link Throwable#getMessage()} method.
+     * @param cause the cause (which is saved for later retrieval by the
+     * {@link Throwable#getCause()} method). (A <code>null</code> value is permitted,
+     * and indicates that the cause is nonexistent or unknown.)
+     * @see java.lang.Exception
+     */
+    public InvalidTypeException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/InvalidValueTypeException.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/InvalidValueTypeException.java
new file mode 100644
index 0000000..a3050c8
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/InvalidValueTypeException.java
@@ -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.
+ */
+
+package com.android.ddmlib.log;
+
+import com.android.ddmlib.log.EventContainer.EventValueType;
+import com.android.ddmlib.log.EventValueDescription.ValueType;
+
+import java.io.Serializable;
+
+/**
+ * Exception thrown when associating an {@link EventValueType} with an incompatible
+ * {@link ValueType}.
+ */
+public final class InvalidValueTypeException extends Exception {
+
+    /**
+     * Needed by {@link Serializable}.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructs a new exception with the default detail message.
+     * @see java.lang.Exception
+     */
+    public InvalidValueTypeException() {
+        super("Invalid Type");
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message.
+     * @param message the detail message. The detail message is saved for later retrieval
+     * by the {@link Throwable#getMessage()} method.
+     * @see java.lang.Exception
+     */
+    public InvalidValueTypeException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new exception with the specified cause and a detail message of
+     * <code>(cause==null ? null : cause.toString())</code> (which typically contains
+     * the class and detail message of cause).
+     * @param cause the cause (which is saved for later retrieval by the
+     * {@link Throwable#getCause()} method). (A <code>null</code> value is permitted,
+     * and indicates that the cause is nonexistent or unknown.)
+     * @see java.lang.Exception
+     */
+    public InvalidValueTypeException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructs a new exception with the specified detail message and cause.
+     * @param message the detail message. The detail message is saved for later retrieval
+     * by the {@link Throwable#getMessage()} method.
+     * @param cause the cause (which is saved for later retrieval by the
+     * {@link Throwable#getCause()} method). (A <code>null</code> value is permitted,
+     * and indicates that the cause is nonexistent or unknown.)
+     * @see java.lang.Exception
+     */
+    public InvalidValueTypeException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/LogReceiver.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/LogReceiver.java
new file mode 100644
index 0000000..b49f025
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/log/LogReceiver.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib.log;
+
+
+import com.android.ddmlib.utils.ArrayHelper;
+
+import java.security.InvalidParameterException;
+
+/**
+ * Receiver able to provide low level parsing for device-side log services.
+ */
+public final class LogReceiver {
+
+    private final static int ENTRY_HEADER_SIZE = 20; // 2*2 + 4*4; see LogEntry.
+
+    /**
+     * Represents a log entry and its raw data.
+     */
+    public final static class LogEntry {
+        /*
+         * See //device/include/utils/logger.h
+         */
+        /** 16bit unsigned: length of the payload. */
+        public int  len; /* This is normally followed by a 16 bit padding */
+        /** pid of the process that generated this {@link LogEntry} */
+        public int   pid;
+        /** tid of the process that generated this {@link LogEntry} */
+        public int   tid;
+        /** Seconds since epoch. */
+        public int   sec;
+        /** nanoseconds. */
+        public int   nsec;
+        /** The entry's raw data. */
+        public byte[] data;
+    };
+
+    /**
+     * Classes which implement this interface provide a method that deals
+     * with {@link LogEntry} objects coming from log service through a {@link LogReceiver}.
+     * <p/>This interface provides two methods.
+     * <ul>
+     * <li>{@link #newEntry(com.android.ddmlib.log.LogReceiver.LogEntry)} provides a
+     * first level of parsing, extracting {@link LogEntry} objects out of the log service output.</li>
+     * <li>{@link #newData(byte[], int, int)} provides a way to receive the raw information
+     * coming directly from the log service.</li>
+     * </ul>
+     */
+    public interface ILogListener {
+        /**
+         * Sent when a new {@link LogEntry} has been parsed by the {@link LogReceiver}.
+         * @param entry the new log entry.
+         */
+        public void newEntry(LogEntry entry);
+        
+        /**
+         * Sent when new raw data is coming from the log service.
+         * @param data the raw data buffer.
+         * @param offset the offset into the buffer signaling the beginning of the new data.
+         * @param length the length of the new data.
+         */
+        public void newData(byte[] data, int offset, int length);
+    }
+
+    /** Current {@link LogEntry} being read, before sending it to the listener. */
+    private LogEntry mCurrentEntry;
+
+    /** Temp buffer to store partial entry headers. */
+    private byte[] mEntryHeaderBuffer = new byte[ENTRY_HEADER_SIZE];
+    /** Offset in the partial header buffer */
+    private int mEntryHeaderOffset = 0;
+    /** Offset in the partial entry data */
+    private int mEntryDataOffset = 0;
+    
+    /** Listener waiting for receive fully read {@link LogEntry} objects */
+    private ILogListener mListener;
+
+    private boolean mIsCancelled = false;
+    
+    /**
+     * Creates a {@link LogReceiver} with an {@link ILogListener}.
+     * <p/>
+     * The {@link ILogListener} will receive new log entries as they are parsed, in the form 
+     * of {@link LogEntry} objects.
+     * @param listener the listener to receive new log entries.
+     */
+    public LogReceiver(ILogListener listener) {
+        mListener = listener;
+    }
+    
+
+    /**
+     * Parses new data coming from the log service.
+     * @param data the data buffer
+     * @param offset the offset into the buffer signaling the beginning of the new data.
+     * @param length the length of the new data.
+     */
+    public void parseNewData(byte[] data, int offset, int length) {
+        // notify the listener of new raw data
+        if (mListener != null) {
+            mListener.newData(data, offset, length);
+        }
+
+        // loop while there is still data to be read and the receiver has not be cancelled.
+        while (length > 0 && mIsCancelled == false) {
+            // first check if we have no current entry.
+            if (mCurrentEntry == null) {
+                if (mEntryHeaderOffset + length < ENTRY_HEADER_SIZE) {
+                    // if we don't have enough data to finish the header, save
+                    // the data we have and return
+                    System.arraycopy(data, offset, mEntryHeaderBuffer, mEntryHeaderOffset, length);
+                    mEntryHeaderOffset += length;
+                    return;
+                } else {
+                    // we have enough to fill the header, let's do it.
+                    // did we store some part at the beginning of the header?
+                    if (mEntryHeaderOffset != 0) {
+                        // copy the rest of the entry header into the header buffer
+                        int size = ENTRY_HEADER_SIZE - mEntryHeaderOffset; 
+                        System.arraycopy(data, offset, mEntryHeaderBuffer, mEntryHeaderOffset,
+                                size);
+                        
+                        // create the entry from the header buffer
+                        mCurrentEntry = createEntry(mEntryHeaderBuffer, 0);
+    
+                        // since we used the whole entry header buffer, we reset  the offset
+                        mEntryHeaderOffset = 0;
+                        
+                        // adjust current offset and remaining length to the beginning
+                        // of the entry data
+                        offset += size;
+                        length -= size;
+                    } else {
+                        // create the entry directly from the data array
+                        mCurrentEntry = createEntry(data, offset);
+                        
+                        // adjust current offset and remaining length to the beginning
+                        // of the entry data
+                        offset += ENTRY_HEADER_SIZE;
+                        length -= ENTRY_HEADER_SIZE;
+                    }
+                }
+            }
+            
+            // at this point, we have an entry, and offset/length have been updated to skip
+            // the entry header.
+    
+            // if we have enough data for this entry or more, we'll need to end this entry
+            if (length >= mCurrentEntry.len - mEntryDataOffset) {
+                // compute and save the size of the data that we have to read for this entry,
+                // based on how much we may already have read.
+                int dataSize = mCurrentEntry.len - mEntryDataOffset;  
+    
+                // we only read what we need, and put it in the entry buffer.
+                System.arraycopy(data, offset, mCurrentEntry.data, mEntryDataOffset, dataSize);
+                
+                // notify the listener of a new entry
+                if (mListener != null) {
+                    mListener.newEntry(mCurrentEntry);
+                }
+    
+                // reset some flags: we have read 0 data of the current entry.
+                // and we have no current entry being read.
+                mEntryDataOffset = 0;
+                mCurrentEntry = null;
+                
+                // and update the data buffer info to the end of the current entry / start
+                // of the next one.
+                offset += dataSize;
+                length -= dataSize;
+            } else {
+                // we don't have enough data to fill this entry, so we store what we have
+                // in the entry itself.
+                System.arraycopy(data, offset, mCurrentEntry.data, mEntryDataOffset, length);
+                
+                // save the amount read for the data.
+                mEntryDataOffset += length;
+                return;
+            }
+        }
+    }
+
+    /**
+     * Returns whether this receiver is canceling the remote service.
+     */
+    public boolean isCancelled() {
+        return mIsCancelled;
+    }
+    
+    /**
+     * Cancels the current remote service.
+     */
+    public void cancel() {
+        mIsCancelled = true;
+    }
+    
+    /**
+     * Creates a {@link LogEntry} from the array of bytes. This expects the data buffer size
+     * to be at least <code>offset + {@link #ENTRY_HEADER_SIZE}</code>.
+     * @param data the data buffer the entry is read from.
+     * @param offset the offset of the first byte from the buffer representing the entry.
+     * @return a new {@link LogEntry} or <code>null</code> if some error happened.
+     */
+    private LogEntry createEntry(byte[] data, int offset) {
+        if (data.length < offset + ENTRY_HEADER_SIZE) {
+            throw new InvalidParameterException(
+                    "Buffer not big enough to hold full LoggerEntry header");
+        }
+
+        // create the new entry and fill it.
+        LogEntry entry = new LogEntry();
+        entry.len = ArrayHelper.swapU16bitFromArray(data, offset);
+        
+        // we've read only 16 bits, but since there's also a 16 bit padding,
+        // we can skip right over both.
+        offset += 4;
+        
+        entry.pid = ArrayHelper.swap32bitFromArray(data, offset);
+        offset += 4;
+        entry.tid = ArrayHelper.swap32bitFromArray(data, offset);
+        offset += 4;
+        entry.sec = ArrayHelper.swap32bitFromArray(data, offset);
+        offset += 4;
+        entry.nsec = ArrayHelper.swap32bitFromArray(data, offset);
+        offset += 4;
+        
+        // allocate the data
+        entry.data = new byte[entry.len];
+        
+        return entry;
+    }
+    
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java
new file mode 100644
index 0000000..b61a698
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib.testrunner;
+
+/**
+ * Receives event notifications during instrumentation test runs. 
+ * Patterned after {@link junit.runner.TestRunListener}.
+ */
+public interface ITestRunListener {
+
+    /**
+     *  Types of test failures.
+     */
+    enum TestFailure {
+        /** Test failed due to unanticipated uncaught exception. */
+        ERROR,
+        /** Test failed due to a false assertion. */
+        FAILURE
+    }
+
+    /** 
+     * Reports the start of a test run.
+     * 
+     * @param testCount total number of tests in test run
+     */
+    public void testRunStarted(int testCount);
+    
+    /**
+     * Reports end of test run.
+     * 
+     * @param elapsedTime device reported elapsed time, in milliseconds
+     */
+    public void testRunEnded(long elapsedTime);
+
+    /**
+     * Reports test run stopped before completion.
+     * 
+     * @param elapsedTime device reported elapsed time, in milliseconds
+     */
+    public void testRunStopped(long elapsedTime);
+
+    /**
+     * Reports the start of an individual test case.
+     * 
+     * @param test identifies the test
+     */
+    public void testStarted(TestIdentifier test);
+
+    /**
+     * Reports the execution end of an individual test case.
+     * If {@link #testFailed} was not invoked, this test passed.
+     * 
+     * @param test identifies the test
+     */
+    public void testEnded(TestIdentifier test);
+
+    /**
+     * Reports the failure of a individual test case.
+     * Will be called between testStarted and testEnded.
+     * 
+     * @param status failure type
+     * @param test identifies the test
+     * @param trace stack trace of failure
+     */
+    public void testFailed(TestFailure status, TestIdentifier test, String trace);
+    
+    /** 
+     * Reports test run failed to execute due to a fatal error.
+     */
+    public void testRunFailed(String errorMessage);
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java
new file mode 100755
index 0000000..bc1834f
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java
@@ -0,0 +1,369 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib.testrunner;
+
+import com.android.ddmlib.IShellOutputReceiver;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.MultiLineReceiver;
+
+/**
+ * Parses the 'raw output mode' results of an instrumentation test run from shell and informs a 
+ * ITestRunListener of the results.
+ * 
+ * <p>Expects the following output:
+ * 
+ * <p>If fatal error occurred when attempted to run the tests:
+ * <pre> INSTRUMENTATION_FAILED: </pre>  
+ * 
+ * <p>Otherwise, expect a series of test results, each one containing a set of status key/value
+ * pairs, delimited by a start(1)/pass(0)/fail(-2)/error(-1) status code result. At end of test 
+ * run, expects that the elapsed test time in seconds will be displayed  
+ * 
+ * <p>For example:
+ * <pre>
+ * INSTRUMENTATION_STATUS_CODE: 1
+ * INSTRUMENTATION_STATUS: class=com.foo.FooTest
+ * INSTRUMENTATION_STATUS: test=testFoo
+ * INSTRUMENTATION_STATUS: numtests=2
+ * INSTRUMENTATION_STATUS: stack=com.foo.FooTest#testFoo:312
+ *    com.foo.X
+ * INSTRUMENTATION_STATUS_CODE: -2   
+ * ... 
+ * 
+ * Time: X
+ * </pre>
+ * <p>Note that the "value" portion of the key-value pair may wrap over several text lines
+ */
+public class InstrumentationResultParser extends MultiLineReceiver {
+    
+    /** Relevant test status keys. */
+    private static class StatusKeys {
+        private static final String TEST = "test";
+        private static final String CLASS = "class";
+        private static final String STACK = "stack";
+        private static final String NUMTESTS = "numtests";
+    }
+    
+    /** Test result status codes. */
+    private static class StatusCodes {
+        private static final int FAILURE = -2;
+        private static final int START = 1;
+        private static final int ERROR = -1;
+        private static final int OK = 0;
+    }
+
+    /** Prefixes used to identify output. */
+    private static class Prefixes {
+        private static final String STATUS = "INSTRUMENTATION_STATUS: ";
+        private static final String STATUS_CODE = "INSTRUMENTATION_STATUS_CODE: ";
+        private static final String STATUS_FAILED = "INSTRUMENTATION_FAILED: ";
+        private static final String TIME_REPORT = "Time: ";
+    }
+    
+    private final ITestRunListener mTestListener;
+
+    /** 
+     * Test result data
+     */
+    private static class TestResult {
+        private Integer mCode = null;
+        private String mTestName = null;
+        private String mTestClass = null;
+        private String mStackTrace = null;
+        private Integer mNumTests = null;
+        
+        /** Returns true if all expected values have been parsed */
+        boolean isComplete() {
+            return mCode != null && mTestName != null && mTestClass != null;
+        }
+    }
+    
+    /** Stores the status values for the test result currently being parsed */
+    private TestResult mCurrentTestResult = null;
+    
+    /** Stores the current "key" portion of the status key-value being parsed. */
+    private String mCurrentKey = null;
+    
+    /** Stores the current "value" portion of the status key-value being parsed. */
+    private StringBuilder mCurrentValue = null;
+    
+    /** True if start of test has already been reported to listener. */
+    private boolean mTestStartReported = false;
+    
+    /** The elapsed time of the test run, in milliseconds. */
+    private long mTestTime = 0;
+    
+    /** True if current test run has been canceled by user. */
+    private boolean mIsCancelled = false;
+    
+    private static final String LOG_TAG = "InstrumentationResultParser";
+    
+    /**
+     * Creates the InstrumentationResultParser.
+     * 
+     * @param listener informed of test results as the tests are executing
+     */
+    public InstrumentationResultParser(ITestRunListener listener) {
+        mTestListener = listener;
+    }
+    
+    /**
+     * Processes the instrumentation test output from shell.
+     * 
+     * @see MultiLineReceiver#processNewLines
+     */
+    @Override
+    public void processNewLines(String[] lines) {
+        for (String line : lines) {
+            parse(line);
+        }
+    }
+    
+    /**
+     * Parse an individual output line. Expects a line that is one of:
+     * <ul>
+     * <li> 
+     * The start of a new status line (starts with Prefixes.STATUS or Prefixes.STATUS_CODE), 
+     * and thus there is a new key=value pair to parse, and the previous key-value pair is 
+     * finished. 
+     * </li>
+     * <li>
+     * A continuation of the previous status (the "value" portion of the key has wrapped
+     * to the next line).
+     * </li>  
+     * <li> A line reporting a fatal error in the test run (Prefixes.STATUS_FAILED) </li>
+     * <li> A line reporting the total elapsed time of the test run. (Prefixes.TIME_REPORT) </li>  
+     * </ul>
+     *    
+     * @param line  Text output line
+     */
+    private void parse(String line) {
+        if (line.startsWith(Prefixes.STATUS_CODE)) {
+            // Previous status key-value has been collected. Store it.
+            submitCurrentKeyValue();
+            parseStatusCode(line);
+        } else if (line.startsWith(Prefixes.STATUS)) {
+            // Previous status key-value has been collected. Store it.
+            submitCurrentKeyValue();
+            parseKey(line, Prefixes.STATUS.length());
+        } else if (line.startsWith(Prefixes.STATUS_FAILED)) {
+            Log.e(LOG_TAG, "test run failed " + line);
+            mTestListener.testRunFailed(line);
+        } else if (line.startsWith(Prefixes.TIME_REPORT)) {
+            parseTime(line, Prefixes.TIME_REPORT.length());
+        } else {
+            if (mCurrentValue != null) {
+                // this is a value that has wrapped to next line. 
+                mCurrentValue.append("\r\n");
+                mCurrentValue.append(line);
+            } else {
+                Log.w(LOG_TAG, "unrecognized line " + line);
+            }
+        }
+    }
+    
+    /**
+     * Stores the currently parsed key-value pair into mCurrentTestInfo.
+     */
+    private void submitCurrentKeyValue() {
+        if (mCurrentKey != null && mCurrentValue != null) {
+            TestResult testInfo = getCurrentTestInfo();
+            String statusValue = mCurrentValue.toString();
+
+            if (mCurrentKey.equals(StatusKeys.CLASS)) {
+                testInfo.mTestClass = statusValue.trim();
+            }
+            else if (mCurrentKey.equals(StatusKeys.TEST)) {
+                testInfo.mTestName = statusValue.trim();
+            }
+            else if (mCurrentKey.equals(StatusKeys.NUMTESTS)) {
+                try {
+                    testInfo.mNumTests = Integer.parseInt(statusValue);
+                }
+                catch (NumberFormatException e) {
+                    Log.e(LOG_TAG, "Unexpected integer number of tests, received " + statusValue);
+                }
+            }
+            else if (mCurrentKey.equals(StatusKeys.STACK)) {
+                testInfo.mStackTrace = statusValue;
+            }
+
+            mCurrentKey = null;
+            mCurrentValue = null;
+        }
+    }
+    
+    private TestResult getCurrentTestInfo() {
+        if (mCurrentTestResult == null) {
+            mCurrentTestResult = new TestResult();
+        }
+        return mCurrentTestResult;
+    }
+    
+    private void clearCurrentTestInfo() {
+        mCurrentTestResult = null;
+    }
+    
+    /**
+     * Parses the key from the current line.
+     * Expects format of "key=value".
+     *  
+     * @param line full line of text to parse 
+     * @param keyStartPos the starting position of the key in the given line
+     */
+    private void parseKey(String line, int keyStartPos) {
+        int endKeyPos = line.indexOf('=', keyStartPos);
+        if (endKeyPos != -1) {
+            mCurrentKey = line.substring(keyStartPos, endKeyPos).trim();
+            parseValue(line, endKeyPos+1);
+        }
+    }
+    
+    /**
+     * Parses the start of a key=value pair.
+     *  
+     * @param line - full line of text to parse 
+     * @param valueStartPos - the starting position of the value in the given line
+     */
+    private void parseValue(String line, int valueStartPos) {
+        mCurrentValue = new StringBuilder();
+        mCurrentValue.append(line.substring(valueStartPos));
+    }
+    
+    /**
+     * Parses out a status code result. 
+     */
+    private void parseStatusCode(String line) {
+        String value = line.substring(Prefixes.STATUS_CODE.length()).trim();
+        TestResult testInfo = getCurrentTestInfo();
+        try {
+            testInfo.mCode = Integer.parseInt(value);    
+        }
+        catch (NumberFormatException e) {
+            Log.e(LOG_TAG, "Expected integer status code, received: " + value);
+        }
+        
+        // this means we're done with current test result bundle
+        reportResult(testInfo);
+        clearCurrentTestInfo();
+    }
+    
+    /**
+     * Returns true if test run canceled.
+     * 
+     * @see IShellOutputReceiver#isCancelled()
+     */
+    public boolean isCancelled() {
+        return mIsCancelled;
+    }
+    
+    /**
+     * Requests cancellation of test run.
+     */
+    public void cancel() {
+        mIsCancelled = true;
+    }
+    
+    /**
+     * Reports a test result to the test run listener. Must be called when a individual test
+     * result has been fully parsed. 
+     * 
+     * @param statusMap key-value status pairs of test result
+     */
+    private void reportResult(TestResult testInfo) {
+        if (!testInfo.isComplete()) {
+            Log.e(LOG_TAG, "invalid instrumentation status bundle " + testInfo.toString());
+            return;
+        }
+        reportTestRunStarted(testInfo);
+        TestIdentifier testId = new TestIdentifier(testInfo.mTestClass, testInfo.mTestName);
+
+        switch (testInfo.mCode) {
+            case StatusCodes.START:
+                mTestListener.testStarted(testId);
+                break;
+            case StatusCodes.FAILURE:
+                mTestListener.testFailed(ITestRunListener.TestFailure.FAILURE, testId, 
+                        getTrace(testInfo));
+                mTestListener.testEnded(testId);
+                break;
+            case StatusCodes.ERROR:
+                mTestListener.testFailed(ITestRunListener.TestFailure.ERROR, testId, 
+                        getTrace(testInfo));
+                mTestListener.testEnded(testId);
+                break;
+            case StatusCodes.OK:
+                mTestListener.testEnded(testId);
+                break;
+            default:
+                Log.e(LOG_TAG, "Unknown status code received: " + testInfo.mCode);
+                mTestListener.testEnded(testId);
+            break;
+        }
+
+    }
+    
+    /**
+     * Reports the start of a test run, and the total test count, if it has not been previously 
+     * reported.
+     * 
+     * @param testInfo current test status values
+     */
+    private void reportTestRunStarted(TestResult testInfo) {
+        // if start test run not reported yet
+        if (!mTestStartReported && testInfo.mNumTests != null) {
+            mTestListener.testRunStarted(testInfo.mNumTests);
+            mTestStartReported = true;
+        }
+    }
+    
+    /**
+     * Returns the stack trace of the current failed test, from the provided testInfo.
+     */
+    private String getTrace(TestResult testInfo) {
+        if (testInfo.mStackTrace != null) {
+            return testInfo.mStackTrace;    
+        }
+        else {
+            Log.e(LOG_TAG, "Could not find stack trace for failed test ");
+            return new Throwable("Unknown failure").toString();
+        }
+    }
+    
+    /**
+     * Parses out and store the elapsed time.
+     */
+    private void parseTime(String line, int startPos) {
+        String timeString = line.substring(startPos);
+        try {
+            float timeSeconds = Float.parseFloat(timeString);
+            mTestTime = (long)(timeSeconds * 1000); 
+        }
+        catch (NumberFormatException e) {
+            Log.e(LOG_TAG, "Unexpected time format " + timeString);
+        }
+    }
+    
+    /**
+     * Called by parent when adb session is complete. 
+     */
+    @Override
+    public void done() {
+        super.done();
+        mTestListener.testRunEnded(mTestTime);
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java
new file mode 100644
index 0000000..4edbbbb
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib.testrunner;
+
+
+import com.android.ddmlib.IDevice;
+import com.android.ddmlib.Log;
+
+import java.io.IOException;
+
+/**
+ * Runs a Android test command remotely and reports results.
+ */
+public class RemoteAndroidTestRunner  {
+
+    private static final char CLASS_SEPARATOR = ',';
+    private static final char METHOD_SEPARATOR = '#';
+    private static final char RUNNER_SEPARATOR = '/';
+    private String mClassArg;
+    private final String mPackageName;
+    private final  String mRunnerName;
+    private String mExtraArgs;
+    private boolean mLogOnlyMode;
+    private IDevice mRemoteDevice;
+    private InstrumentationResultParser mParser;
+
+    private static final String LOG_TAG = "RemoteAndroidTest";
+    private static final String DEFAULT_RUNNER_NAME = 
+        "android.test.InstrumentationTestRunner";
+    
+    /**
+     * Creates a remote Android test runner.
+     * 
+     * @param packageName the Android application package that contains the tests to run 
+     * @param runnerName the instrumentation test runner to execute. If null, will use default
+     *   runner 
+     * @param remoteDevice the Android device to execute tests on
+     */
+    public RemoteAndroidTestRunner(String packageName, 
+                                   String runnerName,
+                                   IDevice remoteDevice) {
+        
+        mPackageName = packageName;
+        mRunnerName = runnerName;
+        mRemoteDevice = remoteDevice;  
+        mClassArg = null;
+        mExtraArgs = "";
+        mLogOnlyMode = false;
+    }
+    
+    /**
+     * Alternate constructor. Uses default instrumentation runner.
+     * 
+     * @param packageName the Android application package that contains the tests to run 
+     * @param remoteDevice the Android device to execute tests on
+     */
+    public RemoteAndroidTestRunner(String packageName, 
+                                   IDevice remoteDevice) {
+        this(packageName, null, remoteDevice);
+    }
+    
+    /**
+     * Returns the application package name.
+     */
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * Returns the runnerName.
+     */
+    public String getRunnerName() {
+        if (mRunnerName == null) {
+            return DEFAULT_RUNNER_NAME;
+        }
+        return mRunnerName;
+    }
+    
+    /**
+     * Returns the complete instrumentation component path.
+     */
+    private String getRunnerPath() {
+        return getPackageName() + RUNNER_SEPARATOR + getRunnerName();
+    }
+    
+    /**
+     * Sets to run only tests in this class
+     * Must be called before 'run'.
+     * 
+     * @param className fully qualified class name (eg x.y.z)
+     */
+    public void setClassName(String className) {
+        mClassArg = className;
+    }
+
+    /**
+     * Sets to run only tests in the provided classes
+     * Must be called before 'run'.
+     * <p>
+     * If providing more than one class, requires a InstrumentationTestRunner that supports 
+     * the multiple class argument syntax.
+     * 
+     * @param classNames array of fully qualified class names (eg x.y.z)
+     */
+    public void setClassNames(String[] classNames) {
+        StringBuilder classArgBuilder = new StringBuilder();
+        
+        for (int i=0; i < classNames.length; i++) {
+            if (i != 0) {
+                classArgBuilder.append(CLASS_SEPARATOR);
+            }
+            classArgBuilder.append(classNames[i]);
+        }
+        mClassArg = classArgBuilder.toString();
+    }
+    
+    /**
+     * Sets to run only specified test method
+     * Must be called before 'run'.
+     * 
+     * @param className fully qualified class name (eg x.y.z)
+     * @param testName method name
+     */
+    public void setMethodName(String className, String testName) {
+        mClassArg = className + METHOD_SEPARATOR + testName;
+    }
+    
+    /**
+     * Sets extra arguments to include in instrumentation command.
+     * Must be called before 'run'.
+     * 
+     * @param instrumentationArgs must not be null
+     */
+    public void setExtraArgs(String instrumentationArgs) {
+        if (instrumentationArgs == null) {
+            throw new IllegalArgumentException("instrumentationArgs cannot be null");
+        }
+        mExtraArgs = instrumentationArgs;  
+    }
+    
+    /**
+     * Returns the extra instrumentation arguments.
+     */
+    public String getExtraArgs() {
+        return mExtraArgs;
+    }
+    
+    /**
+     * Sets this test run to log only mode - skips test execution.
+     */
+    public void setLogOnly(boolean logOnly) {
+        mLogOnlyMode = logOnly;
+    }
+    
+    /**
+     * Execute this test run.
+     * 
+     * @param listener listens for test results
+     */
+    public void run(ITestRunListener listener) {
+        final String runCaseCommandStr = "am instrument -w -r "
+            + getClassCmd() + " " + getLogCmd() + " " + getExtraArgs() + " " + getRunnerPath();
+        Log.d(LOG_TAG, runCaseCommandStr);
+        mParser = new InstrumentationResultParser(listener);
+        
+        try {
+            mRemoteDevice.executeShellCommand(runCaseCommandStr, mParser);
+        } catch (IOException e) {
+            Log.e(LOG_TAG, e);
+            listener.testRunFailed(e.toString());
+        }
+    }
+    
+    /**
+     * Requests cancellation of this test run.
+     */
+    public void cancel() {
+        if (mParser != null) {
+            mParser.cancel();
+        }
+    }
+    
+    /**
+     * Returns the test class argument.
+     */
+    private String getClassArg() {
+        return mClassArg;
+    }
+    
+    /**
+     * Returns the full instrumentation command which specifies the test classes to execute. 
+     * Returns an empty string if no classes were specified.
+     */
+    private String getClassCmd() {
+        String classArg = getClassArg();
+        if (classArg != null) {
+            return "-e class " + classArg;
+        }
+        return "";
+    }
+
+    /**
+     * Returns the full command to enable log only mode - if specified. Otherwise returns an 
+     * empty string.
+     */
+    private String getLogCmd() {
+        if (mLogOnlyMode) {
+            return "-e log true";
+        }
+        else {
+            return "";
+        }
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/TestIdentifier.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/TestIdentifier.java
new file mode 100644
index 0000000..4d3b108
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/TestIdentifier.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib.testrunner;
+
+/**
+ * Identifies a parsed instrumentation test 
+ */
+public class TestIdentifier {
+
+    private final String mClassName;
+    private final String mTestName;
+    
+    /**
+     * Creates a test identifier
+     * 
+     * @param className fully qualified class name of the test. Cannot be null.
+     * @param testName name of the test. Cannot be null.
+     */
+    public TestIdentifier(String className, String testName) {
+        if (className == null || testName == null) {
+            throw new IllegalArgumentException("className and testName must " + 
+                    "be non-null");
+        }
+        mClassName = className;
+        mTestName = testName;
+    }
+    
+    /**
+     * Returns the fully qualified class name of the test
+     */
+    public String getClassName() {
+        return mClassName;
+    }
+
+    /**
+     * Returns the name of the test
+     */
+    public String getTestName() {
+        return mTestName;
+    }
+    
+    /**
+     * Tests equality by comparing class and method name
+     */
+    @Override
+    public boolean equals(Object other) {
+        if (!(other instanceof TestIdentifier)) {
+            return false;
+        }
+        TestIdentifier otherTest = (TestIdentifier)other;
+        return getClassName().equals(otherTest.getClassName())  && 
+                getTestName().equals(otherTest.getTestName());
+    }
+    
+    /**
+     * Generates hashCode based on class and method name.
+     */
+    @Override
+    public int hashCode() {
+        return getClassName().hashCode() * 31 + getTestName().hashCode();
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/utils/ArrayHelper.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/utils/ArrayHelper.java
new file mode 100644
index 0000000..8167e5d
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/utils/ArrayHelper.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib.utils;
+
+/**
+ * Utility class providing array to int/long conversion for data received from devices through adb. 
+ */
+public final class ArrayHelper {
+
+    /**
+     * Swaps an unsigned value around, and puts the result in an array that can be sent to a device.
+     * @param value The value to swap.
+     * @param dest the destination array
+     * @param offset the offset in the array where to put the swapped value.
+     *      Array length must be at least offset + 4
+     */
+    public static void swap32bitsToArray(int value, byte[] dest, int offset) {
+        dest[offset] = (byte)(value & 0x000000FF);
+        dest[offset + 1] = (byte)((value & 0x0000FF00) >> 8);
+        dest[offset + 2] = (byte)((value & 0x00FF0000) >> 16);
+        dest[offset + 3] = (byte)((value & 0xFF000000) >> 24);
+    }
+
+    /**
+     * Reads a signed 32 bit integer from an array coming from a device.
+     * @param value the array containing the int
+     * @param offset the offset in the array at which the int starts
+     * @return the integer read from the array
+     */
+    public static int swap32bitFromArray(byte[] value, int offset) {
+        int v = 0;
+        v |= ((int)value[offset]) & 0x000000FF;
+        v |= (((int)value[offset + 1]) & 0x000000FF) << 8;
+        v |= (((int)value[offset + 2]) & 0x000000FF) << 16;
+        v |= (((int)value[offset + 3]) & 0x000000FF) << 24;
+
+        return v;
+    }
+    
+    /**
+     * Reads an unsigned 16 bit integer from an array coming from a device,
+     * and returns it as an 'int'
+     * @param value the array containing the 16 bit int (2 byte).
+     * @param offset the offset in the array at which the int starts
+     *      Array length must be at least offset + 2
+     * @return the integer read from the array.
+     */
+    public static int swapU16bitFromArray(byte[] value, int offset) {
+        int v = 0;
+        v |= ((int)value[offset]) & 0x000000FF;
+        v |= (((int)value[offset + 1]) & 0x000000FF) << 8;
+
+        return v;
+    }
+    
+    /**
+     * Reads a signed 64 bit integer from an array coming from a device.
+     * @param value the array containing the int
+     * @param offset the offset in the array at which the int starts
+     *      Array length must be at least offset + 8
+     * @return the integer read from the array
+     */
+    public static long swap64bitFromArray(byte[] value, int offset) {
+        long v = 0;
+        v |= ((long)value[offset]) & 0x00000000000000FFL;
+        v |= (((long)value[offset + 1]) & 0x00000000000000FFL) << 8;
+        v |= (((long)value[offset + 2]) & 0x00000000000000FFL) << 16;
+        v |= (((long)value[offset + 3]) & 0x00000000000000FFL) << 24;
+        v |= (((long)value[offset + 4]) & 0x00000000000000FFL) << 32;
+        v |= (((long)value[offset + 5]) & 0x00000000000000FFL) << 40;
+        v |= (((long)value[offset + 6]) & 0x00000000000000FFL) << 48;
+        v |= (((long)value[offset + 7]) & 0x00000000000000FFL) << 56;
+
+        return v;
+    }
+}
diff --git a/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java b/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java
new file mode 100644
index 0000000..77d10c1
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib.testrunner;
+
+import junit.framework.TestCase;
+
+
+/**
+ * Tests InstrumentationResultParser.
+ */
+public class InstrumentationResultParserTest extends TestCase {
+
+    private InstrumentationResultParser mParser;
+    private VerifyingTestResult mTestResult;
+
+    // static dummy test names to use for validation
+    private static final String CLASS_NAME = "com.test.FooTest";
+    private static final String TEST_NAME = "testFoo";
+    private static final String STACK_TRACE = "java.lang.AssertionFailedException";
+
+    /**
+     * @param name - test name
+     */
+    public InstrumentationResultParserTest(String name) {
+        super(name);
+    }
+
+    /**
+     * @see junit.framework.TestCase#setUp()
+     */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTestResult = new VerifyingTestResult();
+        mParser = new InstrumentationResultParser(mTestResult);
+    }
+
+    /**
+     * Tests that the test run started and test start events is sent on first
+     * bundle received.
+     */
+    public void testTestStarted() {
+        StringBuilder output = buildCommonResult();
+        addStartCode(output);
+
+        injectTestString(output.toString());
+        assertCommonAttributes();
+        assertEquals(0, mTestResult.mNumTestsRun);
+    }
+
+    /**
+     * Tests that a single successful test execution.
+     */
+    public void testTestSuccess() {
+        StringBuilder output = buildCommonResult();
+        addStartCode(output);
+        addCommonStatus(output);
+        addSuccessCode(output);
+
+        injectTestString(output.toString());
+        assertCommonAttributes();
+        assertEquals(1, mTestResult.mNumTestsRun);
+        assertEquals(null, mTestResult.mTestStatus);
+    }
+
+    /**
+     * Test basic parsing of failed test case.
+     */
+    public void testTestFailed() {
+        StringBuilder output = buildCommonResult();
+        addStartCode(output);
+        addCommonStatus(output);
+        addStackTrace(output);
+        addFailureCode(output);
+
+        injectTestString(output.toString());
+        assertCommonAttributes();
+
+        assertEquals(1, mTestResult.mNumTestsRun);
+        assertEquals(ITestRunListener.TestFailure.FAILURE, mTestResult.mTestStatus);
+        assertEquals(STACK_TRACE, mTestResult.mTrace);
+    }
+    
+    /**
+     * Test basic parsing and conversion of time from output.
+     */
+    public void testTimeParsing() {
+        final String timeString = "Time: 4.9";
+        injectTestString(timeString);
+        assertEquals(4900, mTestResult.mTestTime);
+    }
+
+    /**
+     * builds a common test result using TEST_NAME and TEST_CLASS.
+     */
+    private StringBuilder buildCommonResult() {
+        StringBuilder output = new StringBuilder();
+        // add test start bundle
+        addCommonStatus(output);
+        addStatusCode(output, "1");
+        // add end test bundle, without status
+        addCommonStatus(output);
+        return output;
+    }
+
+    /**
+     * Adds common status results to the provided output.
+     */
+    private void addCommonStatus(StringBuilder output) {
+        addStatusKey(output, "stream", "\r\n" + CLASS_NAME);
+        addStatusKey(output, "test", TEST_NAME);
+        addStatusKey(output, "class", CLASS_NAME);
+        addStatusKey(output, "current", "1");
+        addStatusKey(output, "numtests", "1");
+        addStatusKey(output, "id", "InstrumentationTestRunner");
+    }
+
+    /**
+     * Adds a stack trace status bundle to output.
+     */
+    private void addStackTrace(StringBuilder output) {
+        addStatusKey(output, "stack", STACK_TRACE);
+
+    }
+
+    /**
+     * Helper method to add a status key-value bundle.
+     */
+    private void addStatusKey(StringBuilder outputBuilder, String key,
+            String value) {
+        outputBuilder.append("INSTRUMENTATION_STATUS: ");
+        outputBuilder.append(key);
+        outputBuilder.append('=');
+        outputBuilder.append(value);
+        outputBuilder.append("\r\n");
+    }
+
+    private void addStartCode(StringBuilder outputBuilder) {
+        addStatusCode(outputBuilder, "1");
+    }
+
+    private void addSuccessCode(StringBuilder outputBuilder) {
+        addStatusCode(outputBuilder, "0");
+    }
+
+    private void addFailureCode(StringBuilder outputBuilder) {
+        addStatusCode(outputBuilder, "-2");
+    }
+
+    private void addStatusCode(StringBuilder outputBuilder, String value) {
+        outputBuilder.append("INSTRUMENTATION_STATUS_CODE: ");
+        outputBuilder.append(value);
+        outputBuilder.append("\r\n");
+    }
+
+    /**
+     * inject a test string into the result parser.
+     * 
+     * @param result
+     */
+    private void injectTestString(String result) {
+        byte[] data = result.getBytes();
+        mParser.addOutput(data, 0, data.length);
+        mParser.flush();
+    }
+
+    private void assertCommonAttributes() {
+        assertEquals(CLASS_NAME, mTestResult.mSuiteName);
+        assertEquals(1, mTestResult.mTestCount);
+        assertEquals(TEST_NAME, mTestResult.mTestName);
+    }
+
+    /**
+     * A specialized test listener that stores a single test events.
+     */
+    private class VerifyingTestResult implements ITestRunListener {
+
+        String mSuiteName;
+        int mTestCount;
+        int mNumTestsRun;
+        String mTestName;
+        long mTestTime;
+        TestFailure mTestStatus;
+        String mTrace;
+        boolean mStopped;
+
+        VerifyingTestResult() {
+            mNumTestsRun = 0;
+            mTestStatus = null;
+            mStopped = false;
+        }
+
+        public void testEnded(TestIdentifier test) {
+            mNumTestsRun++;
+            assertEquals("Unexpected class name", mSuiteName, test.getClassName());
+            assertEquals("Unexpected test ended", mTestName, test.getTestName());
+
+        }
+
+        public void testFailed(TestFailure status, TestIdentifier test, String trace) {
+            mTestStatus = status;
+            mTrace = trace;
+            assertEquals("Unexpected class name", mSuiteName, test.getClassName());
+            assertEquals("Unexpected test ended", mTestName, test.getTestName());
+        }
+
+        public void testRunEnded(long elapsedTime) {
+            mTestTime = elapsedTime;
+
+        }
+
+        public void testRunStarted(int testCount) {
+            mTestCount = testCount;
+        }
+
+        public void testRunStopped(long elapsedTime) {
+            mTestTime = elapsedTime;
+            mStopped = true;
+        }
+
+        public void testStarted(TestIdentifier test) {
+            mSuiteName = test.getClassName();
+            mTestName = test.getTestName();
+        }
+
+        public void testRunFailed(String errorMessage) {
+            // ignored
+        }
+    }
+
+}
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
new file mode 100644
index 0000000..9acaaf9
--- /dev/null
+++ b/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmlib.testrunner;
+
+import com.android.ddmlib.Client;
+import com.android.ddmlib.FileListingService;
+import com.android.ddmlib.IDevice;
+import com.android.ddmlib.IShellOutputReceiver;
+import com.android.ddmlib.RawImage;
+import com.android.ddmlib.SyncService;
+import com.android.ddmlib.Device.DeviceState;
+import com.android.ddmlib.log.LogReceiver;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Tests RemoteAndroidTestRunner.
+ */
+public class RemoteAndroidTestRunnerTest extends TestCase {
+
+    private RemoteAndroidTestRunner mRunner;
+    private MockDevice mMockDevice;
+
+    private static final String TEST_PACKAGE = "com.test";
+    private static final String TEST_RUNNER = "com.test.InstrumentationTestRunner";
+
+    /**
+     * @see junit.framework.TestCase#setUp()
+     */
+    @Override
+    protected void setUp() throws Exception {
+        mMockDevice = new MockDevice();
+        mRunner = new RemoteAndroidTestRunner(TEST_PACKAGE, TEST_RUNNER, mMockDevice);
+    }
+
+    /**
+     * Test the basic case building of the instrumentation runner command with no arguments.
+     */
+    public void testRun() {
+        mRunner.run(new EmptyListener());
+        assertStringsEquals(String.format("am instrument -w -r %s/%s", TEST_PACKAGE, TEST_RUNNER),
+                mMockDevice.getLastShellCommand());
+    }
+
+    /**
+     * Test the building of the instrumentation runner command with log set.
+     */
+    public void testRunWithLog() {
+        mRunner.setLogOnly(true);
+        mRunner.run(new EmptyListener());
+        assertStringsEquals(String.format("am instrument -w -r -e log true %s/%s", TEST_PACKAGE,
+                TEST_RUNNER), mMockDevice.getLastShellCommand());
+    }
+
+    /**
+     * Test the building of the instrumentation runner command with method set.
+     */
+    public void testRunWithMethod() {
+        final String className = "FooTest";
+        final String testName = "fooTest";
+        mRunner.setMethodName(className, testName);
+        mRunner.run(new EmptyListener());
+        assertStringsEquals(String.format("am instrument -w -r -e class %s#%s %s/%s", className,
+                testName, TEST_PACKAGE, TEST_RUNNER), mMockDevice.getLastShellCommand());
+    }
+
+    /**
+     * Test the building of the instrumentation runner command with extra args set.
+     */
+    public void testRunWithExtraArgs() {
+        final String extraArgs = "blah";
+        mRunner.setExtraArgs(extraArgs);
+        mRunner.run(new EmptyListener());
+        assertStringsEquals(String.format("am instrument -w -r %s %s/%s", extraArgs,
+                TEST_PACKAGE, TEST_RUNNER), mMockDevice.getLastShellCommand());
+    }
+
+
+    /**
+     * Assert two strings are equal ignoring whitespace.
+     */
+    private void assertStringsEquals(String str1, String str2) {
+        String strippedStr1 = str1.replaceAll(" ", "");
+        String strippedStr2 = str2.replaceAll(" ", "");
+        assertEquals(strippedStr1, strippedStr2);
+    }
+
+    /**
+     * A dummy device that does nothing except store the provided executed shell command for
+     * later retrieval.
+     */
+    private static class MockDevice implements IDevice {
+
+        private String mLastShellCommand;
+
+        /**
+         * Stores the provided command for later retrieval from getLastShellCommand.
+         */
+        public void executeShellCommand(String command,
+                IShellOutputReceiver receiver) throws IOException {
+            mLastShellCommand = command;
+        }
+
+        /**
+         * Get the last command provided to executeShellCommand.
+         */
+        public String getLastShellCommand() {
+            return mLastShellCommand;
+        }
+
+        public boolean createForward(int localPort, int remotePort) {
+            throw new UnsupportedOperationException();
+        }
+
+        public Client getClient(String applicationName) {
+            throw new UnsupportedOperationException();
+        }
+
+        public String getClientName(int pid) {
+            throw new UnsupportedOperationException();
+        }
+
+        public Client[] getClients() {
+            throw new UnsupportedOperationException();
+        }
+
+        public FileListingService getFileListingService() {
+            throw new UnsupportedOperationException();
+        }
+
+        public Map<String, String> getProperties() {
+            throw new UnsupportedOperationException();
+        }
+
+        public String getProperty(String name) {
+            throw new UnsupportedOperationException();
+        }
+
+        public int getPropertyCount() {
+            throw new UnsupportedOperationException();
+        }
+
+        public RawImage getScreenshot() throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        public String getSerialNumber() {
+            throw new UnsupportedOperationException();
+        }
+
+        public DeviceState getState() {
+            throw new UnsupportedOperationException();
+        }
+
+        public SyncService getSyncService() {
+            throw new UnsupportedOperationException();
+        }
+
+        public boolean hasClients() {
+            throw new UnsupportedOperationException();
+        }
+
+        public boolean isBootLoader() {
+            throw new UnsupportedOperationException();
+        }
+
+        public boolean isEmulator() {
+            throw new UnsupportedOperationException();
+        }
+
+        public boolean isOffline() {
+            throw new UnsupportedOperationException();
+        }
+
+        public boolean isOnline() {
+            throw new UnsupportedOperationException();
+        }
+
+        public boolean removeForward(int localPort, int remotePort) {
+            throw new UnsupportedOperationException();
+        }
+
+        public void runEventLogService(LogReceiver receiver) throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        public void runLogService(String logname, LogReceiver receiver) throws IOException {
+            throw new UnsupportedOperationException();
+        }
+
+        public String getAvdName() {
+            return "";
+        }
+
+    }
+
+    /**
+     * An empty implementation of ITestRunListener.
+     */
+    private static class EmptyListener implements ITestRunListener {
+
+        public void testEnded(TestIdentifier test) {
+            // ignore
+        }
+
+        public void testFailed(TestFailure status, TestIdentifier test, String trace) {
+            // ignore
+        }
+
+        public void testRunEnded(long elapsedTime) {
+            // ignore
+        }
+
+        public void testRunFailed(String errorMessage) {
+            // ignore
+        }
+
+        public void testRunStarted(int testCount) {
+            // ignore
+        }
+
+        public void testRunStopped(long elapsedTime) {
+            // ignore
+        }
+
+        public void testStarted(TestIdentifier test) {
+            // ignore
+        }
+
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/.classpath b/tools/ddms/libs/ddmuilib/.classpath
new file mode 100644
index 0000000..ce7e7f0
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/.classpath
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry excluding="Makefile|resources" kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_SWT"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/ANDROID_JFREECHART"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/ddms/libs/ddmuilib/.project b/tools/ddms/libs/ddmuilib/.project
new file mode 100644
index 0000000..29cb2f2
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>ddmuilib</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/ddms/libs/ddmuilib/Android.mk b/tools/ddms/libs/ddmuilib/Android.mk
new file mode 100644
index 0000000..7059e5e
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/Android.mk
@@ -0,0 +1,4 @@
+# Copyright 2007 The Android Open Source Project
+#
+DDMUILIB_LOCAL_DIR := $(call my-dir)
+include $(DDMUILIB_LOCAL_DIR)/src/Android.mk
diff --git a/tools/ddms/libs/ddmuilib/README b/tools/ddms/libs/ddmuilib/README
new file mode 100644
index 0000000..d66b84a
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/README
@@ -0,0 +1,11 @@
+Using the Eclipse projects for ddmuilib.
+
+ddmuilib requires SWT to compile.
+
+SWT is available in the depot under prebuild/<platform>/swt
+
+Because the build path cannot contain relative path that are not inside the project directory,
+the .classpath file references a user library called ANDROID_SWT.
+
+In order to compile the project, make a user library called ANDROID_SWT containing the jar
+available at prebuild/<platform>/swt.
\ No newline at end of file
diff --git a/tools/ddms/libs/ddmuilib/src/Android.mk b/tools/ddms/libs/ddmuilib/src/Android.mk
new file mode 100644
index 0000000..acbda44
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/Android.mk
@@ -0,0 +1,22 @@
+# Copyright 2007 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_JAVA_RESOURCE_DIRS := resources
+
+LOCAL_JAVA_LIBRARIES := \
+	ddmlib \
+	swt \
+	org.eclipse.jface_3.2.0.I20060605-1400 \
+	org.eclipse.equinox.common_3.2.0.v20060603 \
+	org.eclipse.core.commands_3.2.0.I20060605-1400 \
+	jcommon-1.0.12 \
+	jfreechart-1.0.9 \
+	jfreechart-1.0.9-swt
+	
+LOCAL_MODULE := ddmuilib
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/Addr2Line.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/Addr2Line.java
new file mode 100644
index 0000000..a2f12d5
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/Addr2Line.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.*;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Collection;
+import java.util.HashMap;
+
+/**
+ * Represents an addr2line process to get filename/method information from a
+ * memory address.<br>
+ * Each process can only handle one library, which should be provided when
+ * creating a new process.<br>
+ * <br>
+ * The processes take some time to load as they need to parse the library files.
+ * For this reason, processes cannot be manually started. Instead the class
+ * keeps an internal list of processes and one asks for a process for a specific
+ * library, using <code>getProcess(String library)<code>.<br></br>
+ * Internally, the processes are started in pipe mode to be able to query them
+ * with multiple addresses.
+ */
+public class Addr2Line {
+
+    /**
+     * Loaded processes list. This is also used as a locking object for any
+     * methods dealing with starting/stopping/creating processes/querying for
+     * method.
+     */
+    private static final HashMap<String, Addr2Line> sProcessCache =
+            new HashMap<String, Addr2Line>();
+
+    /**
+     * byte array representing a carriage return. Used to push addresses in the
+     * process pipes.
+     */
+    private static final byte[] sCrLf = {
+        '\n'
+    };
+
+    /** Path to the library */
+    private String mLibrary;
+
+    /** the command line process */
+    private Process mProcess;
+
+    /** buffer to read the result of the command line process from */
+    private BufferedReader mResultReader;
+
+    /**
+     * output stream to provide new addresses to decode to the command line
+     * process
+     */
+    private BufferedOutputStream mAddressWriter;
+
+    /**
+     * Returns the instance of a Addr2Line process for the specified library.
+     * <br>The library should be in a format that makes<br>
+     * <code>$ANDROID_PRODUCT_OUT + "/symbols" + library</code> a valid file.
+     *
+     * @param library the library in which to look for addresses.
+     * @return a new Addr2Line object representing a started process, ready to
+     *         be queried for addresses. If any error happened when launching a
+     *         new process, <code>null</code> will be returned.
+     */
+    public static Addr2Line getProcess(final String library) {
+        // synchronize around the hashmap object
+        if (library != null) {
+            synchronized (sProcessCache) {
+                // look for an existing process
+                Addr2Line process = sProcessCache.get(library);
+
+                // if we don't find one, we create it
+                if (process == null) {
+                    process = new Addr2Line(library);
+
+                    // then we start it
+                    boolean status = process.start();
+
+                    if (status) {
+                        // if starting the process worked, then we add it to the
+                        // list.
+                        sProcessCache.put(library, process);
+                    } else {
+                        // otherwise we just drop the object, to return null
+                        process = null;
+                    }
+                }
+                // return the process
+                return process;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Construct the object with a library name.
+     * <br>The library should be in a format that makes<br>
+     * <code>$ANDROID_PRODUCT_OUT + "/symbols" + library</code> a valid file.
+     *
+     * @param library the library in which to look for address.
+     */
+    private Addr2Line(final String library) {
+        mLibrary = library;
+    }
+
+    /**
+     * Starts the command line process.
+     *
+     * @return true if the process was started, false if it failed to start, or
+     *         if there was any other errors.
+     */
+    private boolean start() {
+        // because this is only called from getProcess() we know we don't need
+        // to synchronize this code.
+
+        // get the output directory.
+        String symbols = DdmUiPreferences.getSymbolDirectory();
+
+        // build the command line
+        String[] command = new String[5];
+        command[0] = DdmUiPreferences.getAddr2Line();
+        command[1] = "-C";
+        command[2] = "-f";
+        command[3] = "-e";
+        command[4] = symbols + mLibrary.replaceAll("libc\\.so", "libc_debug\\.so");
+
+        try {
+            // attempt to start the process
+            mProcess = Runtime.getRuntime().exec(command);
+
+            if (mProcess != null) {
+                // get the result reader
+                InputStreamReader is = new InputStreamReader(mProcess
+                        .getInputStream());
+                mResultReader = new BufferedReader(is);
+
+                // get the outstream to write the addresses
+                mAddressWriter = new BufferedOutputStream(mProcess
+                        .getOutputStream());
+
+                // check our streams are here
+                if (mResultReader == null || mAddressWriter == null) {
+                    // not here? stop the process and return false;
+                    mProcess.destroy();
+                    mProcess = null;
+                    return false;
+                }
+
+                // return a success
+                return true;
+            }
+
+        } catch (IOException e) {
+            // log the error
+            String msg = String.format(
+                    "Error while trying to start %1$s process for library %2$s",
+                    DdmUiPreferences.getAddr2Line(), mLibrary);
+            Log.e("ddm-Addr2Line", msg);
+
+            // drop the process just in case
+            if (mProcess != null) {
+                mProcess.destroy();
+                mProcess = null;
+            }
+        }
+
+        // we can be here either cause the allocation of mProcess failed, or we
+        // caught an exception
+        return false;
+    }
+
+    /**
+     * Stops the command line process.
+     */
+    public void stop() {
+        synchronized (sProcessCache) {
+            if (mProcess != null) {
+                // remove the process from the list
+                sProcessCache.remove(mLibrary);
+
+                // then stops the process
+                mProcess.destroy();
+
+                // set the reference to null.
+                // this allows to make sure another thread calling getAddress()
+                // will not query a stopped thread
+                mProcess = null;
+            }
+        }
+    }
+
+    /**
+     * Stops all current running processes.
+     */
+    public static void stopAll() {
+        // because of concurrent access (and our use of HashMap.values()), we
+        // can't rely on the synchronized inside stop(). We need to put one
+        // around the whole loop.
+        synchronized (sProcessCache) {
+            // just a basic loop on all the values in the hashmap and call to
+            // stop();
+            Collection<Addr2Line> col = sProcessCache.values();
+            for (Addr2Line a2l : col) {
+                a2l.stop();
+            }
+        }
+    }
+
+    /**
+     * Looks up an address and returns method name, source file name, and line
+     * number.
+     *
+     * @param addr the address to look up
+     * @return a BacktraceInfo object containing the method/filename/linenumber
+     *         or null if the process we stopped before the query could be
+     *         processed, or if an IO exception happened.
+     */
+    public NativeStackCallInfo getAddress(long addr) {
+        // even though we don't access the hashmap object, we need to
+        // synchronized on it to prevent
+        // another thread from stopping the process we're going to query.
+        synchronized (sProcessCache) {
+            // check the process is still alive/allocated
+            if (mProcess != null) {
+                // prepare to the write the address to the output buffer.
+
+                // first, conversion to a string containing the hex value.
+                String tmp = Long.toString(addr, 16);
+
+                try {
+                    // write the address to the buffer
+                    mAddressWriter.write(tmp.getBytes());
+
+                    // add CR-LF
+                    mAddressWriter.write(sCrLf);
+
+                    // flush it all.
+                    mAddressWriter.flush();
+
+                    // read the result. We need to read 2 lines
+                    String method = mResultReader.readLine();
+                    String source = mResultReader.readLine();
+
+                    // make the backtrace object and return it
+                    if (method != null && source != null) {
+                        return new NativeStackCallInfo(mLibrary, method, source);
+                    }
+                } catch (IOException e) {
+                    // log the error
+                    Log.e("ddms",
+                            "Error while trying to get information for addr: "
+                                    + tmp + " in library: " + mLibrary);
+                    // we'll return null later
+                }
+            }
+        }
+        return null;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/AllocationPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/AllocationPanel.java
new file mode 100644
index 0000000..45d45ff
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/AllocationPanel.java
@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.AllocationInfo;
+import com.android.ddmlib.Client;
+import com.android.ddmlib.ClientData;
+import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Sash;
+import org.eclipse.swt.widgets.Table;
+
+/**
+ * Base class for our information panels.
+ */
+public class AllocationPanel extends TablePanel {
+
+    private final static String PREFS_ALLOC_COL_SIZE = "allocPanel.Col0"; //$NON-NLS-1$
+    private final static String PREFS_ALLOC_COL_CLASS = "allocPanel.Col1"; //$NON-NLS-1$
+    private final static String PREFS_ALLOC_COL_THREAD = "allocPanel.Col2"; //$NON-NLS-1$
+    private final static String PREFS_ALLOC_COL_TRACE_CLASS = "allocPanel.Col3"; //$NON-NLS-1$
+    private final static String PREFS_ALLOC_COL_TRACE_METHOD = "allocPanel.Col4"; //$NON-NLS-1$
+    
+    private final static String PREFS_ALLOC_SASH = "allocPanel.sash"; //$NON-NLS-1$
+
+    private static final String PREFS_STACK_COL_CLASS = "allocPanel.stack.col0"; //$NON-NLS-1$
+    private static final String PREFS_STACK_COL_METHOD = "allocPanel.stack.col1"; //$NON-NLS-1$
+    private static final String PREFS_STACK_COL_FILE = "allocPanel.stack.col2"; //$NON-NLS-1$
+    private static final String PREFS_STACK_COL_LINE = "allocPanel.stack.col3"; //$NON-NLS-1$
+    private static final String PREFS_STACK_COL_NATIVE = "allocPanel.stack.col4"; //$NON-NLS-1$
+    
+    private Composite mAllocationBase;
+    private Table mAllocationTable;
+    private TableViewer mAllocationViewer;
+
+    private StackTracePanel mStackTracePanel;
+    private Table mStackTraceTable;
+    private Button mEnableButton;
+    private Button mRequestButton;
+
+    /**
+     * Content Provider to display the allocations of a client.
+     * Expected input is a {@link Client} object, elements used in the table are of type
+     * {@link AllocationInfo}.
+     */
+    private static class AllocationContentProvider implements IStructuredContentProvider {
+        public Object[] getElements(Object inputElement) {
+            if (inputElement instanceof Client) {
+                AllocationInfo[] allocs = ((Client)inputElement).getClientData().getAllocations();
+                if (allocs != null) {
+                    return allocs;
+                }
+            }
+
+            return new Object[0];
+        }
+
+        public void dispose() {
+            // pass
+        }
+
+        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+            // pass
+        }
+    }
+
+    /**
+     * A Label Provider to use with {@link AllocationContentProvider}. It expects the elements to be
+     * of type {@link AllocationInfo}.
+     */
+    private static class AllocationLabelProvider implements ITableLabelProvider {
+
+        public Image getColumnImage(Object element, int columnIndex) {
+            return null;
+        }
+
+        public String getColumnText(Object element, int columnIndex) {
+            if (element instanceof AllocationInfo) {
+                AllocationInfo alloc = (AllocationInfo)element;
+                switch (columnIndex) {
+                    case 0:
+                        return Integer.toString(alloc.getSize());
+                    case 1:
+                        return alloc.getAllocatedClass();
+                    case 2:
+                        return Short.toString(alloc.getThreadId());
+                    case 3:
+                        StackTraceElement[] traces = alloc.getStackTrace();
+                        if (traces.length > 0) {
+                            return traces[0].getClassName();
+                        }
+                        break;
+                    case 4:
+                        traces = alloc.getStackTrace();
+                        if (traces.length > 0) {
+                            return traces[0].getMethodName();
+                        }
+                        break;
+                }
+            }
+
+            return null;
+        }
+
+        public void addListener(ILabelProviderListener listener) {
+            // pass
+        }
+
+        public void dispose() {
+            // pass
+        }
+
+        public boolean isLabelProperty(Object element, String property) {
+            // pass
+            return false;
+        }
+
+        public void removeListener(ILabelProviderListener listener) {
+            // pass
+        }
+    }
+
+    /**
+     * Create our control(s).
+     */
+    @Override
+    protected Control createControl(Composite parent) {
+        final IPreferenceStore store = DdmUiPreferences.getStore();
+
+        // base composite for selected client with enabled thread update.
+        mAllocationBase = new Composite(parent, SWT.NONE);
+        mAllocationBase.setLayout(new FormLayout());
+        
+        // table above the sash
+        Composite topParent = new Composite(mAllocationBase, SWT.NONE);
+        topParent.setLayout(new GridLayout(2, false));
+        
+        mEnableButton = new Button(topParent, SWT.PUSH);
+        mEnableButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                Client current = getCurrentClient();
+                int status = current.getClientData().getAllocationStatus();
+                if (status == ClientData.ALLOCATION_TRACKING_ON) {
+                    current.enableAllocationTracker(false);
+                } else {
+                    current.enableAllocationTracker(true);
+                }
+                current.requestAllocationStatus();
+            }
+        });
+
+        mRequestButton = new Button(topParent, SWT.PUSH);
+        mRequestButton.setText("Get Allocations");
+        mRequestButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                getCurrentClient().requestAllocationDetails();
+            }
+        });
+        
+        setUpButtons(false /* enabled */, ClientData.ALLOCATION_TRACKING_OFF /* trackingStatus */);
+
+        mAllocationTable = new Table(topParent, SWT.MULTI | SWT.FULL_SELECTION);
+        GridData gridData;
+        mAllocationTable.setLayoutData(gridData = new GridData(GridData.FILL_BOTH));
+        gridData.horizontalSpan = 2;
+        mAllocationTable.setHeaderVisible(true);
+        mAllocationTable.setLinesVisible(true);
+
+        TableHelper.createTableColumn(
+                mAllocationTable,
+                "Allocation Size",
+                SWT.RIGHT,
+                "888", //$NON-NLS-1$
+                PREFS_ALLOC_COL_SIZE, store);
+
+        TableHelper.createTableColumn(
+                mAllocationTable,
+                "Allocated Class",
+                SWT.LEFT,
+                "Allocated Class", //$NON-NLS-1$
+                PREFS_ALLOC_COL_CLASS, store);
+
+        TableHelper.createTableColumn(
+                mAllocationTable,
+                "Thread Id",
+                SWT.LEFT,
+                "999", //$NON-NLS-1$
+                PREFS_ALLOC_COL_THREAD, store);
+
+        TableHelper.createTableColumn(
+                mAllocationTable,
+                "Allocated in",
+                SWT.LEFT,
+                "utime", //$NON-NLS-1$
+                PREFS_ALLOC_COL_TRACE_CLASS, store);
+
+        TableHelper.createTableColumn(
+                mAllocationTable,
+                "Allocated in",
+                SWT.LEFT,
+                "utime", //$NON-NLS-1$
+                PREFS_ALLOC_COL_TRACE_METHOD, store);
+        
+        mAllocationViewer = new TableViewer(mAllocationTable);
+        mAllocationViewer.setContentProvider(new AllocationContentProvider());
+        mAllocationViewer.setLabelProvider(new AllocationLabelProvider());
+
+        mAllocationViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+            public void selectionChanged(SelectionChangedEvent event) {
+                AllocationInfo selectedAlloc = getAllocationSelection(event.getSelection());
+                updateAllocationStackTrace(selectedAlloc);
+            }
+        });
+        
+        // the separating sash
+        final Sash sash = new Sash(mAllocationBase, SWT.HORIZONTAL);
+        Color darkGray = parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
+        sash.setBackground(darkGray);
+        
+        // the UI below the sash
+        mStackTracePanel = new StackTracePanel();
+        mStackTraceTable = mStackTracePanel.createPanel(mAllocationBase,
+                PREFS_STACK_COL_CLASS,
+                PREFS_STACK_COL_METHOD,
+                PREFS_STACK_COL_FILE,
+                PREFS_STACK_COL_LINE,
+                PREFS_STACK_COL_NATIVE,
+                store);
+        
+        // now setup the sash.
+        // form layout data
+        FormData data = new FormData();
+        data.top = new FormAttachment(0, 0);
+        data.bottom = new FormAttachment(sash, 0);
+        data.left = new FormAttachment(0, 0);
+        data.right = new FormAttachment(100, 0);
+        topParent.setLayoutData(data);
+
+        final FormData sashData = new FormData();
+        if (store != null && store.contains(PREFS_ALLOC_SASH)) {
+            sashData.top = new FormAttachment(0, store.getInt(PREFS_ALLOC_SASH));
+        } else {
+            sashData.top = new FormAttachment(50,0); // 50% across
+        }
+        sashData.left = new FormAttachment(0, 0);
+        sashData.right = new FormAttachment(100, 0);
+        sash.setLayoutData(sashData);
+
+        data = new FormData();
+        data.top = new FormAttachment(sash, 0);
+        data.bottom = new FormAttachment(100, 0);
+        data.left = new FormAttachment(0, 0);
+        data.right = new FormAttachment(100, 0);
+        mStackTraceTable.setLayoutData(data);
+
+        // allow resizes, but cap at minPanelWidth
+        sash.addListener(SWT.Selection, new Listener() {
+            public void handleEvent(Event e) {
+                Rectangle sashRect = sash.getBounds();
+                Rectangle panelRect = mAllocationBase.getClientArea();
+                int bottom = panelRect.height - sashRect.height - 100;
+                e.y = Math.max(Math.min(e.y, bottom), 100);
+                if (e.y != sashRect.y) {
+                    sashData.top = new FormAttachment(0, e.y);
+                    store.setValue(PREFS_ALLOC_SASH, e.y);
+                    mAllocationBase.layout();
+                }
+            }
+        });
+
+        return mAllocationBase;
+    }
+    
+    /**
+     * Sets the focus to the proper control inside the panel.
+     */
+    @Override
+    public void setFocus() {
+        mAllocationTable.setFocus();
+    }
+
+    /**
+     * Sent when an existing client information changed.
+     * <p/>
+     * This is sent from a non UI thread.
+     * @param client the updated client.
+     * @param changeMask the bit mask describing the changed properties. It can contain
+     * any of the following values: {@link Client#CHANGE_INFO}, {@link Client#CHANGE_NAME}
+     * {@link Client#CHANGE_DEBUGGER_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) {
+        if (client == getCurrentClient()) {
+            if ((changeMask & Client.CHANGE_HEAP_ALLOCATIONS) != 0) {
+                try {
+                    mAllocationTable.getDisplay().asyncExec(new Runnable() {
+                        public void run() {
+                            mAllocationViewer.refresh();
+                            updateAllocationStackCall();
+                        }
+                    });
+                } catch (SWTException e) {
+                    // widget is disposed, we do nothing
+                }
+            } else if ((changeMask & Client.CHANGE_HEAP_ALLOCATION_STATUS) != 0) {
+                try {
+                    mAllocationTable.getDisplay().asyncExec(new Runnable() {
+                        public void run() {
+                            setUpButtons(true, client.getClientData().getAllocationStatus());
+                        }
+                    });
+                } catch (SWTException e) {
+                    // widget is disposed, we do nothing
+                }
+            }
+        }
+    }
+
+    /**
+     * Sent when a new device is selected. The new device can be accessed
+     * with {@link #getCurrentDevice()}.
+     */
+    @Override
+    public void deviceSelected() {
+        // pass
+    }
+
+    /**
+     * Sent when a new client is selected. The new client can be accessed
+     * with {@link #getCurrentClient()}.
+     */
+    @Override
+    public void clientSelected() {
+        if (mAllocationTable.isDisposed()) {
+            return;
+        }
+
+        Client client = getCurrentClient();
+        
+        mStackTracePanel.setCurrentClient(client);
+        mStackTracePanel.setViewerInput(null); // always empty on client selection change.
+
+        if (client != null) {
+            setUpButtons(true /* enabled */, client.getClientData().getAllocationStatus());
+        } else {
+            setUpButtons(false /* enabled */,
+                    ClientData.ALLOCATION_TRACKING_OFF /* trackingStatus */);
+        }
+
+        mAllocationViewer.setInput(client);
+    }
+    
+    /**
+     * Updates the stack call of the currently selected thread.
+     * <p/>
+     * This <b>must</b> be called from the UI thread.
+     */
+    private void updateAllocationStackCall() {
+        Client client = getCurrentClient();
+        if (client != null) {
+            // get the current selection in the ThreadTable
+            AllocationInfo selectedAlloc = getAllocationSelection(null);
+            
+            if (selectedAlloc != null) {
+                updateAllocationStackTrace(selectedAlloc);
+            } else {
+                updateAllocationStackTrace(null);
+            }
+        }
+    }
+
+    /**
+     * updates the stackcall of the specified allocation. If <code>null</code> the UI is emptied
+     * of current data.
+     * @param thread
+     */
+    private void updateAllocationStackTrace(AllocationInfo alloc) {
+        mStackTracePanel.setViewerInput(alloc);
+    }
+
+    @Override
+    protected void setTableFocusListener() {
+        addTableToFocusListener(mAllocationTable);
+        addTableToFocusListener(mStackTraceTable);
+    }
+
+    /**
+     * Returns the current allocation selection or <code>null</code> if none is found.
+     * If a {@link ISelection} object is specified, the first {@link AllocationInfo} from this
+     * selection is returned, otherwise, the <code>ISelection</code> returned by
+     * {@link TableViewer#getSelection()} is used.
+     * @param selection the {@link ISelection} to use, or <code>null</code>
+     */
+    private AllocationInfo getAllocationSelection(ISelection selection) {
+        if (selection == null) {
+            selection = mAllocationViewer.getSelection();
+        }
+        
+        if (selection instanceof IStructuredSelection) {
+            IStructuredSelection structuredSelection = (IStructuredSelection)selection;
+            Object object = structuredSelection.getFirstElement();
+            if (object instanceof AllocationInfo) {
+                return (AllocationInfo)object;
+            }
+        }
+        
+        return null;
+    }
+
+    /**
+     * 
+     * @param enabled
+     * @param trackingStatus
+     */
+    private void setUpButtons(boolean enabled, int trackingStatus) {
+        if (enabled) {
+            switch (trackingStatus) {
+                case ClientData.ALLOCATION_TRACKING_UNKNOWN:
+                    mEnableButton.setText("?");
+                    mEnableButton.setEnabled(false);
+                    mRequestButton.setEnabled(false);
+                    break;
+                case ClientData.ALLOCATION_TRACKING_OFF:
+                    mEnableButton.setText("Start Tracking");
+                    mEnableButton.setEnabled(true);
+                    mRequestButton.setEnabled(false);
+                    break;
+                case ClientData.ALLOCATION_TRACKING_ON:
+                    mEnableButton.setText("Stop Tracking");
+                    mEnableButton.setEnabled(true);
+                    mRequestButton.setEnabled(true);
+                    break;
+            }
+        } else {
+            mEnableButton.setEnabled(false);
+            mRequestButton.setEnabled(false);
+            mEnableButton.setText("Start Tracking");
+        }
+    }
+}
+
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/BackgroundThread.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/BackgroundThread.java
new file mode 100644
index 0000000..0ed4c95
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/BackgroundThread.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.Log;
+
+/**
+ * base background thread class. The class provides a synchronous quit method
+ * which sets a quitting flag to true. Inheriting classes should regularly test
+ * this flag with <code>isQuitting()</code> and should finish if the flag is
+ * true.
+ */
+public abstract class BackgroundThread extends Thread {
+    private boolean mQuit = false;
+
+    /**
+     * Tell the thread to exit. This is usually called from the UI thread. The
+     * call is synchronous and will only return once the thread has terminated
+     * itself.
+     */
+    public final void quit() {
+        mQuit = true;
+        Log.d("ddms", "Waiting for BackgroundThread to quit");
+        try {
+            this.join();
+        } catch (InterruptedException ie) {
+            ie.printStackTrace();
+        }
+    }
+
+    /** returns if the thread was asked to quit. */
+    protected final boolean isQuitting() {
+        return mQuit;
+    }
+
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/BaseHeapPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/BaseHeapPanel.java
new file mode 100644
index 0000000..3e66ea5
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/BaseHeapPanel.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.HeapSegment;
+import com.android.ddmlib.ClientData.HeapData;
+import com.android.ddmlib.HeapSegment.HeapSegmentElement;
+
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.PaletteData;
+
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+
+/**
+ * Base Panel for heap panels.
+ */
+public abstract class BaseHeapPanel extends TablePanel {
+
+    /** store the processed heap segment, so that we don't recompute Image for nothing */
+    protected byte[] mProcessedHeapData;
+    private Map<Integer, ArrayList<HeapSegmentElement>> mHeapMap;
+
+    /**
+     * Serialize the heap data into an array. The resulting array is available through
+     * <code>getSerializedData()</code>.
+     * @param heapData The heap data to serialize
+     * @return true if the data changed.
+     */
+    protected boolean serializeHeapData(HeapData heapData) {
+        Collection<HeapSegment> heapSegments;
+
+        // Atomically get and clear the heap data.
+        synchronized (heapData) {
+            // get the segments
+            heapSegments = heapData.getHeapSegments();
+            
+            
+            if (heapSegments != null) {
+                // if they are not null, we never processed them.
+                // Before we process then, we drop them from the HeapData
+                heapData.clearHeapData();
+
+                // process them into a linear byte[]
+                doSerializeHeapData(heapSegments);
+                heapData.setProcessedHeapData(mProcessedHeapData);
+                heapData.setProcessedHeapMap(mHeapMap);
+                
+            } else {
+                // the heap segments are null. Let see if the heapData contains a 
+                // list that is already processed.
+                
+                byte[] pixData = heapData.getProcessedHeapData();
+                
+                // and compare it to the one we currently have in the panel.
+                if (pixData == mProcessedHeapData) {
+                    // looks like its the same
+                    return false;
+                } else {
+                    mProcessedHeapData = pixData;
+                }
+                
+                Map<Integer, ArrayList<HeapSegmentElement>> heapMap =
+                    heapData.getProcessedHeapMap();
+                mHeapMap = heapMap;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns the serialized heap data
+     */
+    protected byte[] getSerializedData() {
+        return mProcessedHeapData;
+    }
+
+    /**
+     * Processes and serialize the heapData.
+     * <p/>
+     * The resulting serialized array is {@link #mProcessedHeapData}.
+     * <p/>
+     * the resulting map is {@link #mHeapMap}.
+     * @param heapData the collection of {@link HeapSegment} that forms the heap data.
+     */
+    private void doSerializeHeapData(Collection<HeapSegment> heapData) {
+        mHeapMap = new TreeMap<Integer, ArrayList<HeapSegmentElement>>();
+
+        Iterator<HeapSegment> iterator;
+        ByteArrayOutputStream out;
+
+        out = new ByteArrayOutputStream(4 * 1024);
+
+        iterator = heapData.iterator();
+        while (iterator.hasNext()) {
+            HeapSegment hs = iterator.next();
+
+            HeapSegmentElement e = null;
+            while (true) {
+                int v;
+
+                e = hs.getNextElement(null);
+                if (e == null) {
+                    break;
+                }
+                
+                if (e.getSolidity() == HeapSegmentElement.SOLIDITY_FREE) {
+                    v = 1;
+                } else {
+                    v = e.getKind() + 2;
+                }
+                
+                // put the element in the map
+                ArrayList<HeapSegmentElement> elementList = mHeapMap.get(v);
+                if (elementList == null) {
+                    elementList = new ArrayList<HeapSegmentElement>();
+                    mHeapMap.put(v, elementList);
+                }
+                elementList.add(e);
+
+
+                int len = e.getLength() / 8;
+                while (len > 0) {
+                    out.write(v);
+                    --len;
+                }
+            }
+        }
+        mProcessedHeapData = out.toByteArray();
+        
+        // sort the segment element in the heap info.
+        Collection<ArrayList<HeapSegmentElement>> elementLists = mHeapMap.values();
+        for (ArrayList<HeapSegmentElement> elementList : elementLists) {
+            Collections.sort(elementList);
+        }
+    }
+    
+    /**
+     * Creates a linear image of the heap data.
+     * @param pixData
+     * @param h
+     * @param palette
+     * @return
+     */
+    protected ImageData createLinearHeapImage(byte[] pixData, int h, PaletteData palette) {
+        int w = pixData.length / h;
+        if (pixData.length % h != 0) {
+            w++;
+        }
+
+        // Create the heap image.
+        ImageData id = new ImageData(w, h, 8, palette);
+
+        int x = 0;
+        int y = 0;
+        for (byte b : pixData) {
+            if (b >= 0) {
+                id.setPixel(x, y, b);
+            }
+
+            y++;
+            if (y >= h) {
+                y = 0;
+                x++;
+            }
+        }
+
+        return id;
+    }
+
+
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ClientDisplayPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ClientDisplayPanel.java
new file mode 100644
index 0000000..a711933
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ClientDisplayPanel.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
+
+public abstract class ClientDisplayPanel extends SelectionDependentPanel
+        implements IClientChangeListener {
+
+    @Override
+    protected void postCreation() {
+        AndroidDebugBridge.addClientChangeListener(this);
+    }
+
+    public void dispose() {
+        AndroidDebugBridge.removeClientChangeListener(this);
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DdmUiPreferences.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DdmUiPreferences.java
new file mode 100644
index 0000000..f832a4e
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DdmUiPreferences.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * Preference entry point for ddmuilib. Allows the lib to access a preference
+ * store (org.eclipse.jface.preference.IPreferenceStore) defined by the
+ * application that includes the lib.
+ */
+public final class DdmUiPreferences {
+
+    public static final int DEFAULT_THREAD_REFRESH_INTERVAL = 4;  // seconds
+
+    private static int sThreadRefreshInterval = DEFAULT_THREAD_REFRESH_INTERVAL;
+    
+    private static IPreferenceStore mStore;
+    
+    private static String sSymbolLocation =""; //$NON-NLS-1$
+    private static String sAddr2LineLocation =""; //$NON-NLS-1$
+    private static String sTraceviewLocation =""; //$NON-NLS-1$
+
+    public static void setStore(IPreferenceStore store) {
+        mStore = store;
+    }
+    
+    public static IPreferenceStore getStore() {
+        return mStore;
+    }
+
+    public static int getThreadRefreshInterval() {
+        return sThreadRefreshInterval;
+    }
+
+    public static void setThreadRefreshInterval(int port) {
+        sThreadRefreshInterval = port;
+    }
+    
+    static String getSymbolDirectory() {
+        return sSymbolLocation;
+    }
+
+    public static void setSymbolsLocation(String location) {
+        sSymbolLocation = location;
+    }
+
+    static String getAddr2Line() {
+        return sAddr2LineLocation;
+    }
+
+    public static void setAddr2LineLocation(String location) {
+        sAddr2LineLocation = location;
+    }
+
+    public static String getTraceview() {
+        return sTraceviewLocation;
+    }
+
+    public static void setTraceviewLocation(String location) {
+        sTraceviewLocation = location;
+    }
+
+
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DevicePanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DevicePanel.java
new file mode 100644
index 0000000..81b757e
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DevicePanel.java
@@ -0,0 +1,744 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.Client;
+import com.android.ddmlib.ClientData;
+import com.android.ddmlib.DdmPreferences;
+import com.android.ddmlib.Device;
+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 org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreePath;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+
+import java.util.ArrayList;
+
+/**
+ * A display of both the devices and their clients.
+ */
+public final class DevicePanel extends Panel implements IDebugBridgeChangeListener,
+        IDeviceChangeListener, IClientChangeListener {
+
+    private final static String PREFS_COL_NAME_SERIAL = "devicePanel.Col0"; //$NON-NLS-1$
+    private final static String PREFS_COL_PID_STATE = "devicePanel.Col1"; //$NON-NLS-1$
+    private final static String PREFS_COL_PORT_BUILD = "devicePanel.Col4"; //$NON-NLS-1$
+
+    private final static int DEVICE_COL_SERIAL = 0;
+    private final static int DEVICE_COL_STATE = 1;
+    // col 2, 3 not used.
+    private final static int DEVICE_COL_BUILD = 4;
+
+    private final static int CLIENT_COL_NAME = 0;
+    private final static int CLIENT_COL_PID = 1;
+    private final static int CLIENT_COL_THREAD = 2;
+    private final static int CLIENT_COL_HEAP = 3;
+    private final static int CLIENT_COL_PORT = 4;
+    
+    public final static int ICON_WIDTH = 16;
+    public final static String ICON_THREAD = "thread.png"; //$NON-NLS-1$
+    public final static String ICON_HEAP = "heap.png"; //$NON-NLS-1$
+    public final static String ICON_HALT = "halt.png"; //$NON-NLS-1$
+    public final static String ICON_GC = "gc.png"; //$NON-NLS-1$
+
+    private Device mCurrentDevice;
+    private Client mCurrentClient;
+    
+    private Tree mTree;
+    private TreeViewer mTreeViewer;
+
+    private Image mDeviceImage;
+    private Image mEmulatorImage;
+
+    private Image mThreadImage;
+    private Image mHeapImage;
+    private Image mWaitingImage;
+    private Image mDebuggerImage;
+    private Image mDebugErrorImage;
+
+    private final ArrayList<IUiSelectionListener> mListeners = new ArrayList<IUiSelectionListener>();
+    
+    private final ArrayList<Device> mDevicesToExpand = new ArrayList<Device>();
+
+    private IImageLoader mLoader;
+
+    private boolean mAdvancedPortSupport;
+
+    /**
+     * A Content provider for the {@link TreeViewer}.
+     * <p/>
+     * The input is a {@link AndroidDebugBridge}. First level elements are {@link Device} 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();
+            }
+            return new Object[0];
+        }
+
+        public Object getParent(Object element) {
+            if (element instanceof Client) {
+                return ((Client)element).getDevice();
+            }
+            return null;
+        }
+
+        public boolean hasChildren(Object element) {
+            if (element instanceof Device) {
+                return ((Device)element).hasClients();
+            }
+
+            // Clients never have children.
+            return false;
+        }
+
+        public Object[] getElements(Object inputElement) {
+            if (inputElement instanceof AndroidDebugBridge) {
+                return ((AndroidDebugBridge)inputElement).getDevices();
+            }
+            return new Object[0];
+        }
+
+        public void dispose() {
+            // pass
+        }
+
+        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+            // pass
+        }
+    }
+
+    /**
+     * A Label Provider for the {@link TreeViewer} in {@link DevicePanel}. It provides
+     * labels and images for {@link Device} 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 (device.isEmulator()) {
+                    return mEmulatorImage;
+                }
+
+                return mDeviceImage;
+            } else if (element instanceof Client) {
+                Client client = (Client)element;
+                ClientData cd = client.getClientData();
+
+                switch (columnIndex) {
+                    case CLIENT_COL_NAME:
+                        switch (cd.getDebuggerConnectionStatus()) {
+                            case ClientData.DEBUGGER_DEFAULT:
+                                return null;
+                            case ClientData.DEBUGGER_WAITING:
+                                return mWaitingImage;
+                            case ClientData.DEBUGGER_ATTACHED:
+                                return mDebuggerImage;
+                            case ClientData.DEBUGGER_ERROR:
+                                return mDebugErrorImage;
+                        }
+                        return null;
+                    case CLIENT_COL_THREAD:
+                        if (client.isThreadUpdateEnabled()) {
+                            return mThreadImage;
+                        }
+                        return null;
+                    case CLIENT_COL_HEAP:
+                        if (client.isHeapUpdateEnabled()) {
+                            return mHeapImage;
+                        }
+                        return null;
+                }
+            }
+            return null;
+        }
+
+        public String getColumnText(Object element, int columnIndex) {
+            if (element instanceof Device) {
+                Device device = (Device)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);
+                        if (version != null) {
+                            String debuggable = device.getProperty(Device.PROP_DEBUGGABLE);
+                            if (device.isEmulator()) {
+                                String avdName = device.getAvdName();
+                                if (avdName == null) {
+                                    avdName = "?"; // the device is probably not online yet, so
+                                                   // we don't know its AVD name just yet.
+                                }
+                                if (debuggable != null && debuggable.equals("1")) { //$NON-NLS-1$
+                                    return String.format("%1$s [%2$s, debug]", avdName,
+                                            version);
+                                } else {
+                                    return String.format("%1$s [%2$s]", avdName, version); //$NON-NLS-1$
+                                }
+                            } else {
+                                if (debuggable != null && debuggable.equals("1")) { //$NON-NLS-1$
+                                    return String.format("%1$s, debug", version);
+                                } else {
+                                    return String.format("%1$s", version); //$NON-NLS-1$
+                                }
+                            }
+                        } else {
+                            return "unknown";
+                        }
+                    }
+                }
+            } else if (element instanceof Client) {
+                Client client = (Client)element;
+                ClientData cd = client.getClientData();
+
+                switch (columnIndex) {
+                    case CLIENT_COL_NAME:
+                        String name = cd.getClientDescription();
+                        if (name != null) {
+                            return name;
+                        }
+                        return "?";
+                    case CLIENT_COL_PID:
+                        return Integer.toString(cd.getPid());
+                    case CLIENT_COL_PORT:
+                        if (mAdvancedPortSupport) {
+                            int port = client.getDebuggerListenPort();
+                            String portString = "?";
+                            if (port != 0) {
+                                portString = Integer.toString(port);
+                            }
+                            if (client.isSelectedClient()) {
+                                return String.format("%1$s / %2$d", portString, //$NON-NLS-1$
+                                        DdmPreferences.getSelectedDebugPort());
+                            }
+
+                            return portString;
+                        }
+                }
+            }
+            return null;
+        }
+
+        public void addListener(ILabelProviderListener listener) {
+            // pass
+        }
+
+        public void dispose() {
+            // pass
+        }
+
+        public boolean isLabelProperty(Object element, String property) {
+            // pass
+            return false;
+        }
+
+        public void removeListener(ILabelProviderListener listener) {
+            // pass
+        }
+    }
+
+    /**
+     * Classes which implement this interface provide methods that deals
+     * with {@link Device} and {@link Client} selection changes coming from the ui.
+     */
+    public interface IUiSelectionListener {
+        /**
+         * Sent when a new {@link Device} 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);
+    }
+
+    /**
+     * Creates the {@link DevicePanel} object.
+     * @param loader
+     * @param advancedPortSupport if true the device panel will add support for selected client port
+     * and display the ports in the ui.
+     */
+    public DevicePanel(IImageLoader loader, boolean advancedPortSupport) {
+        mLoader = loader;
+        mAdvancedPortSupport = advancedPortSupport;
+    }
+
+    public void addSelectionListener(IUiSelectionListener listener) {
+        mListeners.add(listener);
+    }
+
+    public void removeSelectionListener(IUiSelectionListener listener) {
+        mListeners.remove(listener);
+    }
+
+    @Override
+    protected Control createControl(Composite parent) {
+        loadImages(parent.getDisplay(), mLoader);
+
+        parent.setLayout(new FillLayout());
+
+        // create the tree and its column
+        mTree = new Tree(parent, SWT.SINGLE | SWT.FULL_SELECTION);
+        mTree.setHeaderVisible(true);
+        mTree.setLinesVisible(true);
+
+        IPreferenceStore store = DdmUiPreferences.getStore();
+
+        TableHelper.createTreeColumn(mTree, "Name", SWT.LEFT,
+                "com.android.home", //$NON-NLS-1$
+                PREFS_COL_NAME_SERIAL, store);
+        TableHelper.createTreeColumn(mTree, "", SWT.LEFT, //$NON-NLS-1$
+                "Offline", //$NON-NLS-1$
+                PREFS_COL_PID_STATE, store);
+
+        TreeColumn col = new TreeColumn(mTree, SWT.NONE);
+        col.setWidth(ICON_WIDTH + 8);
+        col.setResizable(false);
+        col = new TreeColumn(mTree, SWT.NONE);
+        col.setWidth(ICON_WIDTH + 8);
+        col.setResizable(false);
+
+        TableHelper.createTreeColumn(mTree, "", SWT.LEFT, //$NON-NLS-1$
+                "9999-9999", //$NON-NLS-1$
+                PREFS_COL_PORT_BUILD, store);
+
+        // create the tree viewer
+        mTreeViewer = new TreeViewer(mTree);
+
+        // make the device auto expanded.
+        mTreeViewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS);
+
+        // set up the content and label providers.
+        mTreeViewer.setContentProvider(new ContentProvider());
+        mTreeViewer.setLabelProvider(new LabelProvider());
+
+        mTree.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                notifyListeners();
+            }
+        });
+
+        return mTree;
+    }
+    
+    /**
+     * Sets the focus to the proper control inside the panel.
+     */
+    @Override
+    public void setFocus() {
+        mTree.setFocus();
+    }
+
+    @Override
+    protected void postCreation() {
+        // ask for notification of changes in AndroidDebugBridge (a new one is created when
+        // adb is restarted from a different location), Device and Client objects.
+        AndroidDebugBridge.addDebugBridgeChangeListener(this);
+        AndroidDebugBridge.addDeviceChangeListener(this);
+        AndroidDebugBridge.addClientChangeListener(this);
+    }
+
+    public void dispose() {
+        AndroidDebugBridge.removeDebugBridgeChangeListener(this);
+        AndroidDebugBridge.removeDeviceChangeListener(this);
+        AndroidDebugBridge.removeClientChangeListener(this);
+    }
+
+    /**
+     * Returns the selected {@link Client}. May be null.
+     */
+    public Client getSelectedClient() {
+        return mCurrentClient;
+    }
+
+    /**
+     * Returns the selected {@link Device}. If a {@link Client} is selected, it returns the
+     * Device object containing the client.
+     */
+    public Device getSelectedDevice() {
+        return mCurrentDevice;
+    }
+
+    /**
+     * Kills the selected {@link Client} by sending its VM a halt command.
+     */
+    public void killSelectedClient() {
+        if (mCurrentClient != null) {
+            Client client = mCurrentClient;
+            
+            // reset the selection to the device.
+            TreePath treePath = new TreePath(new Object[] { mCurrentDevice });
+            TreeSelection treeSelection = new TreeSelection(treePath);
+            mTreeViewer.setSelection(treeSelection);
+
+            client.kill();
+        }
+    }
+    
+    /**
+     * Forces a GC on the selected {@link Client}.
+     */
+    public void forceGcOnSelectedClient() {
+        if (mCurrentClient != null) {
+            mCurrentClient.executeGarbageCollector();
+        }
+    }
+    
+    public void setEnabledHeapOnSelectedClient(boolean enable) {
+        if (mCurrentClient != null) {
+            mCurrentClient.setHeapUpdateEnabled(enable);
+        }
+    }
+    
+    public void setEnabledThreadOnSelectedClient(boolean enable) {
+        if (mCurrentClient != null) {
+            mCurrentClient.setThreadUpdateEnabled(enable);
+        }
+    }
+
+    /**
+     * Sent when a new {@link AndroidDebugBridge} is started.
+     * <p/>
+     * This is sent from a non UI thread.
+     * @param bridge the new {@link AndroidDebugBridge} object.
+     *
+     * @see IDebugBridgeChangeListener#serverChanged(AndroidDebugBridge)
+     */
+    public void bridgeChanged(final AndroidDebugBridge bridge) {
+        if (mTree.isDisposed() == false) {
+            exec(new Runnable() {
+                public void run() {
+                    if (mTree.isDisposed() == false) {
+                        // set up the data source.
+                        mTreeViewer.setInput(bridge);
+
+                        // notify the listener of a possible selection change.
+                        notifyListeners();
+                    } else {
+                        // tree is disposed, we need to do something.
+                        // lets remove ourselves from the listener.
+                        AndroidDebugBridge.removeDebugBridgeChangeListener(DevicePanel.this);
+                        AndroidDebugBridge.removeDeviceChangeListener(DevicePanel.this);
+                        AndroidDebugBridge.removeClientChangeListener(DevicePanel.this);
+                    }
+                }
+            });
+        }
+
+        // all current devices are obsolete
+        synchronized (mDevicesToExpand) {
+            mDevicesToExpand.clear();
+        }
+    }
+
+    /**
+     * Sent when the a device is connected to the {@link AndroidDebugBridge}.
+     * <p/>
+     * This is sent from a non UI thread.
+     * @param device the new device.
+     *
+     * @see IDeviceChangeListener#deviceConnected(Device)
+     */
+    public void deviceConnected(Device device) {
+        exec(new Runnable() {
+            public void run() {
+                if (mTree.isDisposed() == false) {
+                    // refresh all
+                    mTreeViewer.refresh();
+
+                    // notify the listener of a possible selection change.
+                    notifyListeners();
+                } else {
+                    // tree is disposed, we need to do something.
+                    // lets remove ourselves from the listener.
+                    AndroidDebugBridge.removeDebugBridgeChangeListener(DevicePanel.this);
+                    AndroidDebugBridge.removeDeviceChangeListener(DevicePanel.this);
+                    AndroidDebugBridge.removeClientChangeListener(DevicePanel.this);
+                }
+            }
+        });
+
+        // if it doesn't have clients yet, it'll need to be manually expanded when it gets them.
+        if (device.hasClients() == false) {
+            synchronized (mDevicesToExpand) {
+                mDevicesToExpand.add(device);
+            }
+        }
+    }
+
+    /**
+     * Sent when the a device is connected to the {@link AndroidDebugBridge}.
+     * <p/>
+     * This is sent from a non UI thread.
+     * @param device the new device.
+     *
+     * @see IDeviceChangeListener#deviceDisconnected(Device)
+     */
+    public void deviceDisconnected(Device device) {
+        deviceConnected(device);
+        
+        // just in case, we remove it from the list of devices to expand.
+        synchronized (mDevicesToExpand) {
+            mDevicesToExpand.remove(device);
+        }
+    }
+
+    /**
+     * Sent when a device data changed, or when clients are started/terminated on the device.
+     * <p/>
+     * This is sent from a non UI thread.
+     * @param device the device that was updated.
+     * @param changeMask the mask indicating what changed.
+     *
+     * @see IDeviceChangeListener#deviceChanged(Device)
+     */
+    public void deviceChanged(final Device device, int changeMask) {
+        boolean expand = false;
+        synchronized (mDevicesToExpand) {
+            int index = mDevicesToExpand.indexOf(device);
+            if (device.hasClients() && index != -1) {
+                mDevicesToExpand.remove(index);
+                expand = true;
+            }
+        }
+        
+        final boolean finalExpand = expand;
+
+        exec(new Runnable() {
+            public void run() {
+                if (mTree.isDisposed() == false) {
+                    // look if the current device is selected. This is done in case the current
+                    // client of this particular device was killed. In this case, we'll need to
+                    // manually reselect the device.
+                    
+                    Device selectedDevice = getSelectedDevice();
+
+                    // refresh the device
+                    mTreeViewer.refresh(device);
+                    
+                    // if the selected device was the changed device and the new selection is
+                    // empty, we reselect the device.
+                    if (selectedDevice == device && mTreeViewer.getSelection().isEmpty()) {
+                        mTreeViewer.setSelection(new TreeSelection(new TreePath(
+                                new Object[] { device })));
+                    }
+                    
+                    // notify the listener of a possible selection change.
+                    notifyListeners();
+                    
+                    if (finalExpand) {
+                        mTreeViewer.setExpandedState(device, true);
+                    }
+                } else {
+                    // tree is disposed, we need to do something.
+                    // lets remove ourselves from the listener.
+                    AndroidDebugBridge.removeDebugBridgeChangeListener(DevicePanel.this);
+                    AndroidDebugBridge.removeDeviceChangeListener(DevicePanel.this);
+                    AndroidDebugBridge.removeClientChangeListener(DevicePanel.this);
+                }
+            }
+        });
+    }
+
+    /**
+     * Sent when an existing client information changed.
+     * <p/>
+     * This is sent from a non UI thread.
+     * @param client the updated client.
+     * @param changeMask the bit mask describing the changed properties. It can contain
+     * any of the following values: {@link Client#CHANGE_INFO},
+     * {@link Client#CHANGE_DEBUGGER_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, final int changeMask) {
+        exec(new Runnable() {
+            public void run() {
+                if (mTree.isDisposed() == false) {
+                    // refresh the client
+                    mTreeViewer.refresh(client);
+
+                    if ((changeMask & Client.CHANGE_DEBUGGER_INTEREST) ==
+                            Client.CHANGE_DEBUGGER_INTEREST &&
+                            client.getClientData().getDebuggerConnectionStatus() ==
+                                ClientData.DEBUGGER_WAITING) {
+                        // make sure the device is expanded. Normally the setSelection below
+                        // will auto expand, but the children of device may not already exist
+                        // at this time. Forcing an expand will make the TreeViewer create them.
+                        Device device = client.getDevice();
+                        if (mTreeViewer.getExpandedState(device) == false) {
+                            mTreeViewer.setExpandedState(device, true);
+                        }
+
+                        // create and set the selection
+                        TreePath treePath = new TreePath(new Object[] { device, client});
+                        TreeSelection treeSelection = new TreeSelection(treePath);
+                        mTreeViewer.setSelection(treeSelection);
+                        
+                        if (mAdvancedPortSupport) {
+                            client.setAsSelectedClient();
+                        }
+                        
+                        // notify the listener of a possible selection change.
+                        notifyListeners(device, client);
+                    }
+                } else {
+                    // tree is disposed, we need to do something.
+                    // lets remove ourselves from the listener.
+                    AndroidDebugBridge.removeDebugBridgeChangeListener(DevicePanel.this);
+                    AndroidDebugBridge.removeDeviceChangeListener(DevicePanel.this);
+                    AndroidDebugBridge.removeClientChangeListener(DevicePanel.this);
+                }
+            }
+        });
+    }
+
+    private void loadImages(Display display, IImageLoader loader) {
+        if (mDeviceImage == null) {
+            mDeviceImage = ImageHelper.loadImage(loader, display, "device.png", //$NON-NLS-1$
+                    ICON_WIDTH, ICON_WIDTH,
+                    display.getSystemColor(SWT.COLOR_RED));
+        }
+        if (mEmulatorImage == null) {
+            mEmulatorImage = ImageHelper.loadImage(loader, display,
+                    "emulator.png", ICON_WIDTH, ICON_WIDTH, //$NON-NLS-1$
+                    display.getSystemColor(SWT.COLOR_BLUE));
+        }
+        if (mThreadImage == null) {
+            mThreadImage = ImageHelper.loadImage(loader, display, ICON_THREAD,
+                    ICON_WIDTH, ICON_WIDTH,
+                    display.getSystemColor(SWT.COLOR_YELLOW));
+        }
+        if (mHeapImage == null) {
+            mHeapImage = ImageHelper.loadImage(loader, display, ICON_HEAP,
+                    ICON_WIDTH, ICON_WIDTH,
+                    display.getSystemColor(SWT.COLOR_BLUE));
+        }
+        if (mWaitingImage == null) {
+            mWaitingImage = ImageHelper.loadImage(loader, display,
+                    "debug-wait.png", ICON_WIDTH, ICON_WIDTH, //$NON-NLS-1$
+                    display.getSystemColor(SWT.COLOR_RED));
+        }
+        if (mDebuggerImage == null) {
+            mDebuggerImage = ImageHelper.loadImage(loader, display,
+                    "debug-attach.png", ICON_WIDTH, ICON_WIDTH, //$NON-NLS-1$
+                    display.getSystemColor(SWT.COLOR_GREEN));
+        }
+        if (mDebugErrorImage == null) {
+            mDebugErrorImage = ImageHelper.loadImage(loader, display,
+                    "debug-error.png", ICON_WIDTH, ICON_WIDTH, //$NON-NLS-1$
+                    display.getSystemColor(SWT.COLOR_RED));
+        }
+    }
+
+    /**
+     * Returns a display string representing the state of the device.
+     * @param d the device
+     */
+    private static String getStateString(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 "??";
+    }
+
+    /**
+     * Executes the {@link Runnable} in the UI thread.
+     * @param runnable the runnable to execute.
+     */
+    private void exec(Runnable runnable) {
+        try {
+            Display display = mTree.getDisplay();
+            display.asyncExec(runnable);
+        } catch (SWTException e) {
+            // tree is disposed, we need to do something. lets remove ourselves from the listener.
+            AndroidDebugBridge.removeDebugBridgeChangeListener(this);
+            AndroidDebugBridge.removeDeviceChangeListener(this);
+            AndroidDebugBridge.removeClientChangeListener(this);
+        }
+    }
+    
+    private void notifyListeners() {
+        // get the selection
+        TreeItem[] items = mTree.getSelection();
+
+        Client client = null;
+        Device 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;
+            }
+        }
+
+        notifyListeners(device, client);
+    }
+    
+    private void notifyListeners(Device selectedDevice, Client selectedClient) {
+        if (selectedDevice != mCurrentDevice || selectedClient != mCurrentClient) {
+            mCurrentDevice = selectedDevice;
+            mCurrentClient = selectedClient;
+        
+            for (IUiSelectionListener listener : mListeners) {
+                // notify the listener with a try/catch-all to make sure this thread won't die
+                // because of an uncaught exception before all the listeners were notified.
+                try {
+                    listener.selectionChanged(selectedDevice, selectedClient);
+                } catch (Exception e) {
+                }
+            }
+        }
+    }
+    
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/EmulatorControlPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/EmulatorControlPanel.java
new file mode 100644
index 0000000..5583760
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/EmulatorControlPanel.java
@@ -0,0 +1,1454 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.Device;
+import com.android.ddmlib.EmulatorConsole;
+import com.android.ddmlib.EmulatorConsole.GsmMode;
+import com.android.ddmlib.EmulatorConsole.GsmStatus;
+import com.android.ddmlib.EmulatorConsole.NetworkStatus;
+import com.android.ddmuilib.location.CoordinateControls;
+import com.android.ddmuilib.location.GpxParser;
+import com.android.ddmuilib.location.KmlParser;
+import com.android.ddmuilib.location.TrackContentProvider;
+import com.android.ddmuilib.location.TrackLabelProvider;
+import com.android.ddmuilib.location.TrackPoint;
+import com.android.ddmuilib.location.WayPoint;
+import com.android.ddmuilib.location.WayPointContentProvider;
+import com.android.ddmuilib.location.WayPointLabelProvider;
+import com.android.ddmuilib.location.GpxParser.Track;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Panel to control the emulator using EmulatorConsole objects.
+ */
+public class EmulatorControlPanel extends SelectionDependentPanel {
+
+    // default location: Patio outside Charlie's
+    private final static double DEFAULT_LONGITUDE = -122.084095;
+    private final static double DEFAULT_LATITUDE = 37.422006;
+    
+    private final static String SPEED_FORMAT = "Speed: %1$dX";
+
+
+    /**
+     * Map between the display gsm mode and the internal tag used by the display.
+     */
+    private final static String[][] GSM_MODES = new String[][] {
+        { "unregistered", GsmMode.UNREGISTERED.getTag() },
+        { "home", GsmMode.HOME.getTag() },
+        { "roaming", GsmMode.ROAMING.getTag() },
+        { "searching", GsmMode.SEARCHING.getTag() },
+        { "denied", GsmMode.DENIED.getTag() },
+    };
+
+    private final static String[] NETWORK_SPEEDS = new String[] {
+        "Full",
+        "GSM",
+        "HSCSD",
+        "GPRS",
+        "EDGE",
+        "UMTS",
+        "HSDPA",
+    };
+
+    private final static String[] NETWORK_LATENCIES = new String[] {
+        "None",
+        "GPRS",
+        "EDGE",
+        "UMTS",
+    };
+    
+    private final static int[] PLAY_SPEEDS = new int[] { 1, 2, 5, 10, 20, 50 };
+
+    private final static String RE_PHONE_NUMBER = "^[+#0-9]+$"; //$NON-NLS-1$
+    private final static String PREFS_WAYPOINT_COL_NAME = "emulatorControl.waypoint.name"; //$NON-NLS-1$
+    private final static String PREFS_WAYPOINT_COL_LONGITUDE = "emulatorControl.waypoint.longitude"; //$NON-NLS-1$
+    private final static String PREFS_WAYPOINT_COL_LATITUDE = "emulatorControl.waypoint.latitude"; //$NON-NLS-1$
+    private final static String PREFS_WAYPOINT_COL_ELEVATION = "emulatorControl.waypoint.elevation"; //$NON-NLS-1$
+    private final static String PREFS_WAYPOINT_COL_DESCRIPTION = "emulatorControl.waypoint.desc"; //$NON-NLS-1$
+    private final static String PREFS_TRACK_COL_NAME = "emulatorControl.track.name"; //$NON-NLS-1$
+    private final static String PREFS_TRACK_COL_COUNT = "emulatorControl.track.count"; //$NON-NLS-1$
+    private final static String PREFS_TRACK_COL_FIRST = "emulatorControl.track.first"; //$NON-NLS-1$
+    private final static String PREFS_TRACK_COL_LAST = "emulatorControl.track.last"; //$NON-NLS-1$
+    private final static String PREFS_TRACK_COL_COMMENT = "emulatorControl.track.comment"; //$NON-NLS-1$
+
+    private IImageLoader mImageLoader;
+
+    private EmulatorConsole mEmulatorConsole;
+
+    private Composite mParent;
+
+    private Label mVoiceLabel;
+    private Combo mVoiceMode;
+    private Label mDataLabel;
+    private Combo mDataMode;
+    private Label mSpeedLabel;
+    private Combo mNetworkSpeed;
+    private Label mLatencyLabel;
+    private Combo mNetworkLatency;
+
+    private Label mNumberLabel;
+    private Text mPhoneNumber;
+
+    private Button mVoiceButton;
+    private Button mSmsButton;
+
+    private Label mMessageLabel;
+    private Text mSmsMessage;
+
+    private Button mCallButton;
+    private Button mCancelButton;
+
+    private TabFolder mLocationFolders;
+    
+    private Button mDecimalButton;
+    private Button mSexagesimalButton;
+    private CoordinateControls mLongitudeControls;
+    private CoordinateControls mLatitudeControls;
+    private Button mGpxUploadButton;
+    private Table mGpxWayPointTable;
+    private Table mGpxTrackTable;
+    private Button mKmlUploadButton;
+    private Table mKmlWayPointTable;
+
+    private Button mPlayGpxButton;
+    private Button mGpxBackwardButton;
+    private Button mGpxForwardButton;
+    private Button mGpxSpeedButton;
+    private Button mPlayKmlButton;
+    private Button mKmlBackwardButton;
+    private Button mKmlForwardButton;
+    private Button mKmlSpeedButton;
+
+    private Image mPlayImage;
+    private Image mPauseImage;
+
+    private Thread mPlayingThread;
+    private boolean mPlayingTrack;
+    private int mPlayDirection = 1;
+    private int mSpeed;
+    private int mSpeedIndex;
+    
+    private final SelectionAdapter mDirectionButtonAdapter = new SelectionAdapter() {
+        @Override
+        public void widgetSelected(SelectionEvent e) {
+            Button b = (Button)e.getSource();
+            if (b.getSelection() == false) {
+                // basically the button was unselected, which we don't allow.
+                // so we reselect it.
+                b.setSelection(true);
+                return;
+            }
+            
+            // now handle selection change.
+            if (b == mGpxForwardButton || b == mKmlForwardButton) {
+                mGpxBackwardButton.setSelection(false);
+                mGpxForwardButton.setSelection(true);
+                mKmlBackwardButton.setSelection(false);
+                mKmlForwardButton.setSelection(true);
+                mPlayDirection = 1;
+                
+            } else {
+                mGpxBackwardButton.setSelection(true);
+                mGpxForwardButton.setSelection(false);
+                mKmlBackwardButton.setSelection(true);
+                mKmlForwardButton.setSelection(false);
+                mPlayDirection = -1;
+            }
+        }
+    };
+    
+    private final SelectionAdapter mSpeedButtonAdapter = new SelectionAdapter() {
+        @Override
+        public void widgetSelected(SelectionEvent e) {
+            mSpeedIndex = (mSpeedIndex+1) % PLAY_SPEEDS.length;
+            mSpeed = PLAY_SPEEDS[mSpeedIndex];
+            
+            mGpxSpeedButton.setText(String.format(SPEED_FORMAT, mSpeed));
+            mGpxPlayControls.pack();
+            mKmlSpeedButton.setText(String.format(SPEED_FORMAT, mSpeed));
+            mKmlPlayControls.pack();
+            
+            if (mPlayingThread != null) {
+                mPlayingThread.interrupt();
+            }
+        } 
+     };
+    private Composite mKmlPlayControls;
+    private Composite mGpxPlayControls;
+
+    
+    public EmulatorControlPanel(IImageLoader imageLoader) {
+        mImageLoader = imageLoader;
+    }
+
+    /**
+     * Sent when a new device is selected. The new device can be accessed
+     * with {@link #getCurrentDevice()}
+     */
+    @Override
+    public void deviceSelected() {
+        handleNewDevice(getCurrentDevice());
+    }
+
+    /**
+     * Sent when a new client is selected. The new client can be accessed
+     * with {@link #getCurrentClient()}
+     */
+    @Override
+    public void clientSelected() {
+        // pass
+    }
+
+    /**
+     * Creates a control capable of displaying some information.  This is
+     * called once, when the application is initializing, from the UI thread.
+     */
+    @Override
+    protected Control createControl(Composite parent) {
+        mParent = parent;
+
+        final ScrolledComposite scollingParent = new ScrolledComposite(parent, SWT.V_SCROLL);
+        scollingParent.setExpandVertical(true);
+        scollingParent.setExpandHorizontal(true);
+        scollingParent.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        final Composite top = new Composite(scollingParent, SWT.NONE);
+        scollingParent.setContent(top);
+        top.setLayout(new GridLayout(1, false));
+
+        // set the resize for the scrolling to work (why isn't that done automatically?!?)
+        scollingParent.addControlListener(new ControlAdapter() {
+            @Override
+            public void controlResized(ControlEvent e) {
+                Rectangle r = scollingParent.getClientArea();
+                scollingParent.setMinSize(top.computeSize(r.width, SWT.DEFAULT));
+            }
+        });
+        
+        createRadioControls(top);
+
+        createCallControls(top);
+        
+        createLocationControls(top);
+
+        doEnable(false);
+
+        top.layout();
+        Rectangle r = scollingParent.getClientArea();
+        scollingParent.setMinSize(top.computeSize(r.width, SWT.DEFAULT));
+
+        return scollingParent;
+    }
+
+    /**
+     * Create Radio (on/off/roaming, for voice/data) controls.
+     * @param top
+     */
+    private void createRadioControls(final Composite top) {
+        Group g1 = new Group(top, SWT.NONE);
+        g1.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        g1.setLayout(new GridLayout(2, false));
+        g1.setText("Telephony Status");
+
+        // the inside of the group is 2 composite so that all the column of the controls (mainly
+        // combos) have the same width, while not taking the whole screen width
+        Composite insideGroup = new Composite(g1, SWT.NONE);
+        GridLayout gl = new GridLayout(4, false);
+        gl.marginBottom = gl.marginHeight = gl.marginLeft = gl.marginRight = 0;
+        insideGroup.setLayout(gl);
+
+        mVoiceLabel = new Label(insideGroup, SWT.NONE);
+        mVoiceLabel.setText("Voice:");
+        mVoiceLabel.setAlignment(SWT.RIGHT);
+
+        mVoiceMode = new Combo(insideGroup, SWT.READ_ONLY);
+        mVoiceMode.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        for (String[] mode : GSM_MODES) {
+            mVoiceMode.add(mode[0]);
+        }
+        mVoiceMode.addSelectionListener(new SelectionAdapter() {
+            // called when selection changes
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                setVoiceMode(mVoiceMode.getSelectionIndex());
+            }
+        });
+
+        mSpeedLabel = new Label(insideGroup, SWT.NONE);
+        mSpeedLabel.setText("Speed:");
+        mSpeedLabel.setAlignment(SWT.RIGHT);
+
+        mNetworkSpeed = new Combo(insideGroup, SWT.READ_ONLY);
+        mNetworkSpeed.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        for (String mode : NETWORK_SPEEDS) {
+            mNetworkSpeed.add(mode);
+        }
+        mNetworkSpeed.addSelectionListener(new SelectionAdapter() {
+            // called when selection changes
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                setNetworkSpeed(mNetworkSpeed.getSelectionIndex());
+            }
+        });
+
+        mDataLabel = new Label(insideGroup, SWT.NONE);
+        mDataLabel.setText("Data:");
+        mDataLabel.setAlignment(SWT.RIGHT);
+
+        mDataMode = new Combo(insideGroup, SWT.READ_ONLY);
+        mDataMode.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        for (String[] mode : GSM_MODES) {
+            mDataMode.add(mode[0]);
+        }
+        mDataMode.addSelectionListener(new SelectionAdapter() {
+            // called when selection changes
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                setDataMode(mDataMode.getSelectionIndex());
+            }
+        });
+
+        mLatencyLabel = new Label(insideGroup, SWT.NONE);
+        mLatencyLabel.setText("Latency:");
+        mLatencyLabel.setAlignment(SWT.RIGHT);
+
+        mNetworkLatency = new Combo(insideGroup, SWT.READ_ONLY);
+        mNetworkLatency.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        for (String mode : NETWORK_LATENCIES) {
+            mNetworkLatency.add(mode);
+        }
+        mNetworkLatency.addSelectionListener(new SelectionAdapter() {
+            // called when selection changes
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                setNetworkLatency(mNetworkLatency.getSelectionIndex());
+            }
+        });
+
+        // now an empty label to take the rest of the width of the group
+        Label l = new Label(g1, SWT.NONE);
+        l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    }
+    
+    /**
+     * Create Voice/SMS call/hang up controls
+     * @param top
+     */
+    private void createCallControls(final Composite top) {
+        GridLayout gl;
+        Group g2 = new Group(top, SWT.NONE);
+        g2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        g2.setLayout(new GridLayout(1, false));
+        g2.setText("Telephony Actions");
+
+        // horizontal composite for label + text field
+        Composite phoneComp = new Composite(g2, SWT.NONE);
+        phoneComp.setLayoutData(new GridData(GridData.FILL_BOTH));
+        gl = new GridLayout(2, false);
+        gl.marginBottom = gl.marginHeight = gl.marginLeft = gl.marginRight = 0;
+        phoneComp.setLayout(gl);
+
+        mNumberLabel = new Label(phoneComp, SWT.NONE);
+        mNumberLabel.setText("Incoming number:");
+
+        mPhoneNumber = new Text(phoneComp, SWT.BORDER | SWT.LEFT | SWT.SINGLE);
+        mPhoneNumber.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mPhoneNumber.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                // Reenable the widgets based on the content of the text.
+                // doEnable checks the validity of the phone number to enable/disable some
+                // widgets.
+                // Looks like we're getting a callback at creation time, so we can't
+                // suppose that we are enabled when the text is modified...
+                doEnable(mEmulatorConsole != null);
+            }
+        });
+
+        mVoiceButton = new Button(phoneComp, SWT.RADIO);
+        GridData gd = new GridData();
+        gd.horizontalSpan = 2;
+        mVoiceButton.setText("Voice");
+        mVoiceButton.setLayoutData(gd);
+        mVoiceButton.setEnabled(false);
+        mVoiceButton.setSelection(true);
+        mVoiceButton.addSelectionListener(new SelectionAdapter() {
+            // called when selection changes
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                doEnable(true);
+
+                if (mVoiceButton.getSelection()) {
+                    mCallButton.setText("Call");
+                } else {
+                    mCallButton.setText("Send");
+                }
+            }
+        });
+
+        mSmsButton = new Button(phoneComp, SWT.RADIO);
+        mSmsButton.setText("SMS");
+        gd = new GridData();
+        gd.horizontalSpan = 2;
+        mSmsButton.setLayoutData(gd);
+        mSmsButton.setEnabled(false);
+        // Since there are only 2 radio buttons, we can put a listener on only one (they
+        // are both called on select and unselect event.
+
+        mMessageLabel = new Label(phoneComp, SWT.NONE);
+        gd = new GridData();
+        gd.verticalAlignment = SWT.TOP;
+        mMessageLabel.setLayoutData(gd);
+        mMessageLabel.setText("Message:");
+        mMessageLabel.setEnabled(false);
+
+        mSmsMessage = new Text(phoneComp, SWT.BORDER | SWT.LEFT | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
+        mSmsMessage.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
+        gd.heightHint = 70;
+        mSmsMessage.setEnabled(false);
+
+        // composite to put the 2 buttons horizontally
+        Composite g2ButtonComp = new Composite(g2, SWT.NONE);
+        g2ButtonComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        gl = new GridLayout(2, false);
+        gl.marginWidth = gl.marginHeight = 0;
+        g2ButtonComp.setLayout(gl);
+
+        // now a button below the phone number
+        mCallButton = new Button(g2ButtonComp, SWT.PUSH);
+        mCallButton.setText("Call");
+        mCallButton.setEnabled(false);
+        mCallButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                if (mEmulatorConsole != null) {
+                    if (mVoiceButton.getSelection()) {
+                        processCommandResult(mEmulatorConsole.call(mPhoneNumber.getText().trim()));
+                    } else {
+                        // we need to encode the message. We need to replace the carriage return
+                        // character by the 2 character string \n.
+                        // Because of this the \ character needs to be escaped as well.
+                        // ReplaceAll() expects regexp so \ char are escaped twice.
+                        String message = mSmsMessage.getText();
+                        message = message.replaceAll("\\\\", //$NON-NLS-1$
+                                "\\\\\\\\"); //$NON-NLS-1$
+
+                        // While the normal line delimiter is returned by Text.getLineDelimiter()
+                        // it seems copy pasting text coming from somewhere else could have another
+                        // delimited. For this reason, we'll replace is several steps
+
+                        // replace the dual CR-LF
+                        message = message.replaceAll("\r\n", "\\\\n"); //$NON-NLS-1$ //$NON-NLS-1$
+
+                        // replace remaining stand alone \n
+                        message = message.replaceAll("\n", "\\\\n"); //$NON-NLS-1$ //$NON-NLS-1$
+
+                        // replace remaining stand alone \r
+                        message = message.replaceAll("\r", "\\\\n"); //$NON-NLS-1$ //$NON-NLS-1$
+
+                        processCommandResult(mEmulatorConsole.sendSms(mPhoneNumber.getText().trim(),
+                                message));
+                    }
+                }
+            }
+        });
+
+        mCancelButton = new Button(g2ButtonComp, SWT.PUSH);
+        mCancelButton.setText("Hang Up");
+        mCancelButton.setEnabled(false);
+        mCancelButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                if (mEmulatorConsole != null) {
+                    if (mVoiceButton.getSelection()) {
+                        processCommandResult(mEmulatorConsole.cancelCall(
+                                mPhoneNumber.getText().trim()));
+                    }
+                }
+            }
+        });
+    }
+    
+    /**
+     * Create Location controls.
+     * @param top
+     */
+    private void createLocationControls(final Composite top) {
+        Label l = new Label(top, SWT.NONE);
+        l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        l.setText("Location Controls");
+        
+        mLocationFolders = new TabFolder(top, SWT.NONE);
+        mLocationFolders.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        
+        Composite manualLocationComp = new Composite(mLocationFolders, SWT.NONE);
+        TabItem item = new TabItem(mLocationFolders, SWT.NONE);
+        item.setText("Manual");
+        item.setControl(manualLocationComp);
+        
+        createManualLocationControl(manualLocationComp);
+
+        mPlayImage = mImageLoader.loadImage("play.png", mParent.getDisplay()); // $NON-NLS-1$
+        mPauseImage = mImageLoader.loadImage("pause.png", mParent.getDisplay()); // $NON-NLS-1$
+
+        Composite gpxLocationComp = new Composite(mLocationFolders, SWT.NONE);
+        item = new TabItem(mLocationFolders, SWT.NONE);
+        item.setText("GPX");
+        item.setControl(gpxLocationComp);
+        
+        createGpxLocationControl(gpxLocationComp);
+
+        Composite kmlLocationComp = new Composite(mLocationFolders, SWT.NONE);
+        kmlLocationComp.setLayout(new FillLayout());
+        item = new TabItem(mLocationFolders, SWT.NONE);
+        item.setText("KML");
+        item.setControl(kmlLocationComp);
+        
+        createKmlLocationControl(kmlLocationComp);
+    }
+
+    private void createManualLocationControl(Composite manualLocationComp) {
+        final StackLayout sl;
+        GridLayout gl;
+        Label label;
+
+        manualLocationComp.setLayout(new GridLayout(1, false));
+        mDecimalButton = new Button(manualLocationComp, SWT.RADIO);
+        mDecimalButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mDecimalButton.setText("Decimal");
+        mSexagesimalButton = new Button(manualLocationComp, SWT.RADIO);
+        mSexagesimalButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mSexagesimalButton.setText("Sexagesimal");
+
+        // composite to hold and switching between the 2 modes.
+        final Composite content = new Composite(manualLocationComp, SWT.NONE);
+        content.setLayout(sl = new StackLayout());
+        
+        // decimal display
+        final Composite decimalContent = new Composite(content, SWT.NONE);
+        decimalContent.setLayout(gl = new GridLayout(2, false));
+        gl.marginHeight = gl.marginWidth = 0;
+        
+        mLongitudeControls = new CoordinateControls();
+        mLatitudeControls = new CoordinateControls();
+        
+        label = new Label(decimalContent, SWT.NONE);
+        label.setText("Longitude");
+        
+        mLongitudeControls.createDecimalText(decimalContent);
+        
+        label = new Label(decimalContent, SWT.NONE);
+        label.setText("Latitude");
+        
+        mLatitudeControls.createDecimalText(decimalContent);
+
+        // sexagesimal content
+        final Composite sexagesimalContent = new Composite(content, SWT.NONE);
+        sexagesimalContent.setLayout(gl = new GridLayout(7, false));
+        gl.marginHeight = gl.marginWidth = 0;
+        
+        label = new Label(sexagesimalContent, SWT.NONE);
+        label.setText("Longitude");
+        
+        mLongitudeControls.createSexagesimalDegreeText(sexagesimalContent);
+        
+        label = new Label(sexagesimalContent, SWT.NONE);
+        label.setText("\u00B0"); // degree character
+        
+        mLongitudeControls.createSexagesimalMinuteText(sexagesimalContent);
+        
+        label = new Label(sexagesimalContent, SWT.NONE);
+        label.setText("'");
+
+        mLongitudeControls.createSexagesimalSecondText(sexagesimalContent);
+        
+        label = new Label(sexagesimalContent, SWT.NONE);
+        label.setText("\"");
+
+        label = new Label(sexagesimalContent, SWT.NONE);
+        label.setText("Latitude");
+        
+        mLatitudeControls.createSexagesimalDegreeText(sexagesimalContent);
+        
+        label = new Label(sexagesimalContent, SWT.NONE);
+        label.setText("\u00B0");
+        
+        mLatitudeControls.createSexagesimalMinuteText(sexagesimalContent);
+        
+        label = new Label(sexagesimalContent, SWT.NONE);
+        label.setText("'");
+
+        mLatitudeControls.createSexagesimalSecondText(sexagesimalContent);
+        
+        label = new Label(sexagesimalContent, SWT.NONE);
+        label.setText("\"");
+
+        // set the default display to decimal
+        sl.topControl = decimalContent;
+        mDecimalButton.setSelection(true);
+
+        mDecimalButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                if (mDecimalButton.getSelection()) {
+                    sl.topControl = decimalContent;
+                } else {
+                    sl.topControl = sexagesimalContent;
+                }
+                content.layout();
+            }
+        });
+        
+        Button sendButton = new Button(manualLocationComp, SWT.PUSH);
+        sendButton.setText("Send");
+        sendButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                if (mEmulatorConsole != null) {
+                    processCommandResult(mEmulatorConsole.sendLocation(
+                            mLongitudeControls.getValue(), mLatitudeControls.getValue(), 0));
+                }
+            }
+        });
+        
+        mLongitudeControls.setValue(DEFAULT_LONGITUDE);
+        mLatitudeControls.setValue(DEFAULT_LATITUDE);
+    }
+
+    private void createGpxLocationControl(Composite gpxLocationComp) {
+        GridData gd;
+
+        IPreferenceStore store = DdmUiPreferences.getStore();
+
+        gpxLocationComp.setLayout(new GridLayout(1, false));
+
+        mGpxUploadButton = new Button(gpxLocationComp, SWT.PUSH);
+        mGpxUploadButton.setText("Load GPX...");
+
+        // Table for way point
+        mGpxWayPointTable = new Table(gpxLocationComp,
+                SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION);
+        mGpxWayPointTable.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
+        gd.heightHint = 100;
+        mGpxWayPointTable.setHeaderVisible(true);
+        mGpxWayPointTable.setLinesVisible(true);
+        
+        TableHelper.createTableColumn(mGpxWayPointTable, "Name", SWT.LEFT,
+                "Some Name",
+                PREFS_WAYPOINT_COL_NAME, store);
+        TableHelper.createTableColumn(mGpxWayPointTable, "Longitude", SWT.LEFT,
+                "-199.999999",
+                PREFS_WAYPOINT_COL_LONGITUDE, store);
+        TableHelper.createTableColumn(mGpxWayPointTable, "Latitude", SWT.LEFT,
+                "-199.999999",
+                PREFS_WAYPOINT_COL_LATITUDE, store);
+        TableHelper.createTableColumn(mGpxWayPointTable, "Elevation", SWT.LEFT,
+                "99999.9",
+                PREFS_WAYPOINT_COL_ELEVATION, store);
+        TableHelper.createTableColumn(mGpxWayPointTable, "Description", SWT.LEFT,
+                "Some Description",
+                PREFS_WAYPOINT_COL_DESCRIPTION, store);
+
+        final TableViewer gpxWayPointViewer = new TableViewer(mGpxWayPointTable);
+        gpxWayPointViewer.setContentProvider(new WayPointContentProvider());
+        gpxWayPointViewer.setLabelProvider(new WayPointLabelProvider());
+        
+        gpxWayPointViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+            public void selectionChanged(SelectionChangedEvent event) {
+                ISelection selection = event.getSelection();
+                if (selection instanceof IStructuredSelection) {
+                    IStructuredSelection structuredSelection = (IStructuredSelection)selection;
+                    Object selectedObject = structuredSelection.getFirstElement();
+                    if (selectedObject instanceof WayPoint) {
+                        WayPoint wayPoint = (WayPoint)selectedObject;
+                        
+                        if (mEmulatorConsole != null && mPlayingTrack == false) {
+                            processCommandResult(mEmulatorConsole.sendLocation(
+                                    wayPoint.getLongitude(), wayPoint.getLatitude(),
+                                    wayPoint.getElevation()));
+                        }
+                    }
+                }
+            }
+        });
+
+        // table for tracks.
+        mGpxTrackTable = new Table(gpxLocationComp,
+                SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION);
+        mGpxTrackTable.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
+        gd.heightHint = 100;
+        mGpxTrackTable.setHeaderVisible(true);
+        mGpxTrackTable.setLinesVisible(true);
+
+        TableHelper.createTableColumn(mGpxTrackTable, "Name", SWT.LEFT,
+                "Some very long name",
+                PREFS_TRACK_COL_NAME, store);
+        TableHelper.createTableColumn(mGpxTrackTable, "Point Count", SWT.RIGHT,
+                "9999",
+                PREFS_TRACK_COL_COUNT, store);
+        TableHelper.createTableColumn(mGpxTrackTable, "First Point Time", SWT.LEFT,
+                "999-99-99T99:99:99Z",
+                PREFS_TRACK_COL_FIRST, store);
+        TableHelper.createTableColumn(mGpxTrackTable, "Last Point Time", SWT.LEFT,
+                "999-99-99T99:99:99Z",
+                PREFS_TRACK_COL_LAST, store);
+        TableHelper.createTableColumn(mGpxTrackTable, "Comment", SWT.LEFT,
+                "-199.999999",
+                PREFS_TRACK_COL_COMMENT, store);
+
+        final TableViewer gpxTrackViewer = new TableViewer(mGpxTrackTable);
+        gpxTrackViewer.setContentProvider(new TrackContentProvider());
+        gpxTrackViewer.setLabelProvider(new TrackLabelProvider());
+        
+        gpxTrackViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+            public void selectionChanged(SelectionChangedEvent event) {
+                ISelection selection = event.getSelection();
+                if (selection instanceof IStructuredSelection) {
+                    IStructuredSelection structuredSelection = (IStructuredSelection)selection;
+                    Object selectedObject = structuredSelection.getFirstElement();
+                    if (selectedObject instanceof Track) {
+                        Track track = (Track)selectedObject;
+                        
+                        if (mEmulatorConsole != null && mPlayingTrack == false) {
+                            TrackPoint[] points = track.getPoints();
+                            processCommandResult(mEmulatorConsole.sendLocation(
+                                    points[0].getLongitude(), points[0].getLatitude(),
+                                    points[0].getElevation()));
+                        }
+                        
+                        mPlayGpxButton.setEnabled(true);
+                        mGpxBackwardButton.setEnabled(true);
+                        mGpxForwardButton.setEnabled(true);
+                        mGpxSpeedButton.setEnabled(true);
+                        
+                        return;
+                    }
+                }
+
+                mPlayGpxButton.setEnabled(false);
+                mGpxBackwardButton.setEnabled(false);
+                mGpxForwardButton.setEnabled(false);
+                mGpxSpeedButton.setEnabled(false);
+            }
+        });
+        
+        mGpxUploadButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                FileDialog fileDialog = new FileDialog(mParent.getShell(), SWT.OPEN);
+
+                fileDialog.setText("Load GPX File");
+                fileDialog.setFilterExtensions(new String[] { "*.gpx" } );
+
+                String fileName = fileDialog.open();
+                if (fileName != null) {
+                    GpxParser parser = new GpxParser(fileName);
+                    if (parser.parse()) {
+                        gpxWayPointViewer.setInput(parser.getWayPoints());
+                        gpxTrackViewer.setInput(parser.getTracks());
+                    }
+                }
+            }
+        });
+        
+        mGpxPlayControls = new Composite(gpxLocationComp, SWT.NONE);
+        GridLayout gl;
+        mGpxPlayControls.setLayout(gl = new GridLayout(5, false));
+        gl.marginHeight = gl.marginWidth = 0;
+        mGpxPlayControls.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        mPlayGpxButton = new Button(mGpxPlayControls, SWT.PUSH | SWT.FLAT);
+        mPlayGpxButton.setImage(mPlayImage);
+        mPlayGpxButton.addSelectionListener(new SelectionAdapter() {
+           @Override
+            public void widgetSelected(SelectionEvent e) {
+               if (mPlayingTrack == false) {
+                   ISelection selection = gpxTrackViewer.getSelection();
+                   if (selection.isEmpty() == false && selection instanceof IStructuredSelection) {
+                       IStructuredSelection structuredSelection = (IStructuredSelection)selection;
+                       Object selectedObject = structuredSelection.getFirstElement();
+                       if (selectedObject instanceof Track) {
+                           Track track = (Track)selectedObject;
+                           playTrack(track);
+                       }
+                   }
+               } else {
+                   // if we're playing, then we pause
+                   mPlayingTrack = false;
+                   if (mPlayingThread != null) {
+                       mPlayingThread.interrupt();
+                   }
+               }
+            } 
+        });
+        
+        Label separator = new Label(mGpxPlayControls, SWT.SEPARATOR | SWT.VERTICAL);
+        separator.setLayoutData(gd = new GridData(
+                GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
+        gd.heightHint = 0;
+        
+        mGpxBackwardButton = new Button(mGpxPlayControls, SWT.TOGGLE | SWT.FLAT);
+        mGpxBackwardButton.setImage(mImageLoader.loadImage("backward.png", mParent.getDisplay())); // $NON-NLS-1$
+        mGpxBackwardButton.setSelection(false);
+        mGpxBackwardButton.addSelectionListener(mDirectionButtonAdapter);
+        mGpxForwardButton = new Button(mGpxPlayControls, SWT.TOGGLE | SWT.FLAT);
+        mGpxForwardButton.setImage(mImageLoader.loadImage("forward.png", mParent.getDisplay())); // $NON-NLS-1$
+        mGpxForwardButton.setSelection(true);
+        mGpxForwardButton.addSelectionListener(mDirectionButtonAdapter);
+
+        mGpxSpeedButton = new Button(mGpxPlayControls, SWT.PUSH | SWT.FLAT);
+
+        mSpeedIndex = 0;
+        mSpeed = PLAY_SPEEDS[mSpeedIndex];
+
+        mGpxSpeedButton.setText(String.format(SPEED_FORMAT, mSpeed));
+        mGpxSpeedButton.addSelectionListener(mSpeedButtonAdapter);
+        
+        mPlayGpxButton.setEnabled(false);
+        mGpxBackwardButton.setEnabled(false);
+        mGpxForwardButton.setEnabled(false);
+        mGpxSpeedButton.setEnabled(false);
+
+    }
+
+    private void createKmlLocationControl(Composite kmlLocationComp) {
+        GridData gd;
+
+        IPreferenceStore store = DdmUiPreferences.getStore();
+
+        kmlLocationComp.setLayout(new GridLayout(1, false));
+
+        mKmlUploadButton = new Button(kmlLocationComp, SWT.PUSH);
+        mKmlUploadButton.setText("Load KML...");
+
+        // Table for way point
+        mKmlWayPointTable = new Table(kmlLocationComp,
+                SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION);
+        mKmlWayPointTable.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
+        gd.heightHint = 200;
+        mKmlWayPointTable.setHeaderVisible(true);
+        mKmlWayPointTable.setLinesVisible(true);
+        
+        TableHelper.createTableColumn(mKmlWayPointTable, "Name", SWT.LEFT,
+                "Some Name",
+                PREFS_WAYPOINT_COL_NAME, store);
+        TableHelper.createTableColumn(mKmlWayPointTable, "Longitude", SWT.LEFT,
+                "-199.999999",
+                PREFS_WAYPOINT_COL_LONGITUDE, store);
+        TableHelper.createTableColumn(mKmlWayPointTable, "Latitude", SWT.LEFT,
+                "-199.999999",
+                PREFS_WAYPOINT_COL_LATITUDE, store);
+        TableHelper.createTableColumn(mKmlWayPointTable, "Elevation", SWT.LEFT,
+                "99999.9",
+                PREFS_WAYPOINT_COL_ELEVATION, store);
+        TableHelper.createTableColumn(mKmlWayPointTable, "Description", SWT.LEFT,
+                "Some Description",
+                PREFS_WAYPOINT_COL_DESCRIPTION, store);
+
+        final TableViewer kmlWayPointViewer = new TableViewer(mKmlWayPointTable);
+        kmlWayPointViewer.setContentProvider(new WayPointContentProvider());
+        kmlWayPointViewer.setLabelProvider(new WayPointLabelProvider());
+
+        mKmlUploadButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                FileDialog fileDialog = new FileDialog(mParent.getShell(), SWT.OPEN);
+
+                fileDialog.setText("Load KML File");
+                fileDialog.setFilterExtensions(new String[] { "*.kml" } );
+
+                String fileName = fileDialog.open();
+                if (fileName != null) {
+                    KmlParser parser = new KmlParser(fileName);
+                    if (parser.parse()) {
+                        kmlWayPointViewer.setInput(parser.getWayPoints());
+                        
+                        mPlayKmlButton.setEnabled(true);
+                        mKmlBackwardButton.setEnabled(true);
+                        mKmlForwardButton.setEnabled(true);
+                        mKmlSpeedButton.setEnabled(true);
+                    }
+                }
+            }
+        });
+        
+        kmlWayPointViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+            public void selectionChanged(SelectionChangedEvent event) {
+                ISelection selection = event.getSelection();
+                if (selection instanceof IStructuredSelection) {
+                    IStructuredSelection structuredSelection = (IStructuredSelection)selection;
+                    Object selectedObject = structuredSelection.getFirstElement();
+                    if (selectedObject instanceof WayPoint) {
+                        WayPoint wayPoint = (WayPoint)selectedObject;
+                        
+                        if (mEmulatorConsole != null && mPlayingTrack == false) {
+                            processCommandResult(mEmulatorConsole.sendLocation(
+                                    wayPoint.getLongitude(), wayPoint.getLatitude(),
+                                    wayPoint.getElevation()));
+                        }
+                    }
+                }
+            }
+        });
+        
+        
+        
+        mKmlPlayControls = new Composite(kmlLocationComp, SWT.NONE);
+        GridLayout gl;
+        mKmlPlayControls.setLayout(gl = new GridLayout(5, false));
+        gl.marginHeight = gl.marginWidth = 0;
+        mKmlPlayControls.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        mPlayKmlButton = new Button(mKmlPlayControls, SWT.PUSH | SWT.FLAT);
+        mPlayKmlButton.setImage(mPlayImage);
+        mPlayKmlButton.addSelectionListener(new SelectionAdapter() {
+           @Override
+            public void widgetSelected(SelectionEvent e) {
+               if (mPlayingTrack == false) {
+                   Object input = kmlWayPointViewer.getInput();
+                   if (input instanceof WayPoint[]) {
+                       playKml((WayPoint[])input);
+                   }
+               } else {
+                   // if we're playing, then we pause
+                   mPlayingTrack = false;
+                   if (mPlayingThread != null) {
+                       mPlayingThread.interrupt();
+                   }
+               }
+            } 
+        });
+        
+        Label separator = new Label(mKmlPlayControls, SWT.SEPARATOR | SWT.VERTICAL);
+        separator.setLayoutData(gd = new GridData(
+                GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
+        gd.heightHint = 0;
+        
+        mKmlBackwardButton = new Button(mKmlPlayControls, SWT.TOGGLE | SWT.FLAT);
+        mKmlBackwardButton.setImage(mImageLoader.loadImage("backward.png", mParent.getDisplay())); // $NON-NLS-1$
+        mKmlBackwardButton.setSelection(false);
+        mKmlBackwardButton.addSelectionListener(mDirectionButtonAdapter);
+        mKmlForwardButton = new Button(mKmlPlayControls, SWT.TOGGLE | SWT.FLAT);
+        mKmlForwardButton.setImage(mImageLoader.loadImage("forward.png", mParent.getDisplay())); // $NON-NLS-1$
+        mKmlForwardButton.setSelection(true);
+        mKmlForwardButton.addSelectionListener(mDirectionButtonAdapter);
+
+        mKmlSpeedButton = new Button(mKmlPlayControls, SWT.PUSH | SWT.FLAT);
+
+        mSpeedIndex = 0;
+        mSpeed = PLAY_SPEEDS[mSpeedIndex];
+
+        mKmlSpeedButton.setText(String.format(SPEED_FORMAT, mSpeed));
+        mKmlSpeedButton.addSelectionListener(mSpeedButtonAdapter);
+        
+        mPlayKmlButton.setEnabled(false);
+        mKmlBackwardButton.setEnabled(false);
+        mKmlForwardButton.setEnabled(false);
+        mKmlSpeedButton.setEnabled(false);
+    }
+
+    /**
+     * Sets the focus to the proper control inside the panel.
+     */
+    @Override
+    public void setFocus() {
+    }
+
+    @Override
+    protected void postCreation() {
+        // pass
+    }
+
+    private synchronized void setDataMode(int selectionIndex) {
+        if (mEmulatorConsole != null) {
+            processCommandResult(mEmulatorConsole.setGsmDataMode(
+                    GsmMode.getEnum(GSM_MODES[selectionIndex][1])));
+        }
+    }
+
+    private synchronized void setVoiceMode(int selectionIndex) {
+        if (mEmulatorConsole != null) {
+            processCommandResult(mEmulatorConsole.setGsmVoiceMode(
+                    GsmMode.getEnum(GSM_MODES[selectionIndex][1])));
+        }
+    }
+
+    private synchronized void setNetworkLatency(int selectionIndex) {
+        if (mEmulatorConsole != null) {
+            processCommandResult(mEmulatorConsole.setNetworkLatency(selectionIndex));
+        }
+    }
+
+    private synchronized void setNetworkSpeed(int selectionIndex) {
+        if (mEmulatorConsole != null) {
+            processCommandResult(mEmulatorConsole.setNetworkSpeed(selectionIndex));
+        }
+    }
+
+
+    /**
+     * Callback on device selection change.
+     * @param device the new selected device
+     */
+    public void handleNewDevice(Device device) {
+        if (mParent.isDisposed()) {
+            return;
+        }
+        // unlink to previous console.
+        synchronized (this) {
+            mEmulatorConsole = null;
+        }
+
+        try {
+            // get the emulator console for this device
+            // First we need the device itself
+            if (device != null) {
+                GsmStatus gsm = null;
+                NetworkStatus netstatus = null;
+
+                synchronized (this) {
+                    mEmulatorConsole = EmulatorConsole.getConsole(device);
+                    if (mEmulatorConsole != null) {
+                        // get the gsm status
+                        gsm = mEmulatorConsole.getGsmStatus();
+                        netstatus = mEmulatorConsole.getNetworkStatus();
+                        
+                        if (gsm == null || netstatus == null) {
+                            mEmulatorConsole = null;
+                        }
+                    }
+                }
+
+                if (gsm != null && netstatus != null) {
+                    Display d = mParent.getDisplay();
+                    if (d.isDisposed() == false) {
+                        final GsmStatus f_gsm = gsm;
+                        final NetworkStatus f_netstatus = netstatus;
+                        
+                        d.asyncExec(new Runnable() {
+                            public void run() {
+                                if (f_gsm.voice != GsmMode.UNKNOWN) {
+                                    mVoiceMode.select(getGsmComboIndex(f_gsm.voice));
+                                } else {
+                                    mVoiceMode.clearSelection();
+                                }
+                                if (f_gsm.data != GsmMode.UNKNOWN) {
+                                    mDataMode.select(getGsmComboIndex(f_gsm.data));
+                                } else {
+                                    mDataMode.clearSelection();
+                                }
+
+                                if (f_netstatus.speed != -1) {
+                                    mNetworkSpeed.select(f_netstatus.speed);
+                                } else {
+                                    mNetworkSpeed.clearSelection();
+                                }
+
+                                if (f_netstatus.latency != -1) {
+                                    mNetworkLatency.select(f_netstatus.latency);
+                                } else {
+                                    mNetworkLatency.clearSelection();
+                                }
+                            }
+                        });
+                    }
+                }
+            }
+        } finally {
+            // enable/disable the ui
+            boolean enable = false;
+            synchronized (this) {
+                enable = mEmulatorConsole != null;
+            }
+            
+            enable(enable);
+        }
+    }
+
+    /**
+     * Enable or disable the ui. Can be called from non ui threads.
+     * @param enabled
+     */
+    private void enable(final boolean enabled) {
+        try {
+            Display d = mParent.getDisplay();
+            d.asyncExec(new Runnable() {
+                public void run() {
+                    if (mParent.isDisposed() == false) {
+                        doEnable(enabled);
+                    }
+                }
+            });
+        } catch (SWTException e) {
+            // disposed. do nothing
+        }
+    }
+
+    private boolean isValidPhoneNumber() {
+        String number = mPhoneNumber.getText().trim();
+
+        return number.matches(RE_PHONE_NUMBER);
+    }
+
+    /**
+     * Enable or disable the ui. Cannot be called from non ui threads.
+     * @param enabled
+     */
+    protected void doEnable(boolean enabled) {
+        mVoiceLabel.setEnabled(enabled);
+        mVoiceMode.setEnabled(enabled);
+
+        mDataLabel.setEnabled(enabled);
+        mDataMode.setEnabled(enabled);
+
+        mSpeedLabel.setEnabled(enabled);
+        mNetworkSpeed.setEnabled(enabled);
+
+        mLatencyLabel.setEnabled(enabled);
+        mNetworkLatency.setEnabled(enabled);
+
+        // Calling setEnabled on a text field will trigger a modifyText event, so we don't do it
+        // if we don't need to.
+        if (mPhoneNumber.isEnabled() != enabled) {
+            mNumberLabel.setEnabled(enabled);
+            mPhoneNumber.setEnabled(enabled);
+        }
+
+        boolean valid = isValidPhoneNumber();
+
+        mVoiceButton.setEnabled(enabled && valid);
+        mSmsButton.setEnabled(enabled && valid);
+
+        boolean smsValid = enabled && valid && mSmsButton.getSelection();
+
+        // Calling setEnabled on a text field will trigger a modifyText event, so we don't do it
+        // if we don't need to.
+        if (mSmsMessage.isEnabled() != smsValid) {
+            mMessageLabel.setEnabled(smsValid);
+            mSmsMessage.setEnabled(smsValid);
+        }
+        if (enabled == false) {
+            mSmsMessage.setText(""); //$NON-NLs-1$
+        }
+
+        mCallButton.setEnabled(enabled && valid);
+        mCancelButton.setEnabled(enabled && valid && mVoiceButton.getSelection());
+
+        if (enabled == false) {
+            mVoiceMode.clearSelection();
+            mDataMode.clearSelection();
+            mNetworkSpeed.clearSelection();
+            mNetworkLatency.clearSelection();
+            if (mPhoneNumber.getText().length() > 0) {
+                mPhoneNumber.setText(""); //$NON-NLS-1$
+            }
+        }
+
+        // location controls
+        mLocationFolders.setEnabled(enabled);
+
+        mDecimalButton.setEnabled(enabled);
+        mSexagesimalButton.setEnabled(enabled);
+        mLongitudeControls.setEnabled(enabled);
+        mLatitudeControls.setEnabled(enabled);
+
+        mGpxUploadButton.setEnabled(enabled);
+        mGpxWayPointTable.setEnabled(enabled);
+        mGpxTrackTable.setEnabled(enabled);
+        mKmlUploadButton.setEnabled(enabled);
+        mKmlWayPointTable.setEnabled(enabled);
+    }
+
+    /**
+     * Returns the index of the combo item matching a specific GsmMode.
+     * @param mode
+     */
+    private int getGsmComboIndex(GsmMode mode) {
+        for (int i = 0 ; i < GSM_MODES.length; i++) {
+            String[] modes = GSM_MODES[i];
+            if (mode.getTag().equals(modes[1])) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Processes the result of a command sent to the console.
+     * @param result the result of the command.
+     */
+    private boolean processCommandResult(final String result) {
+        if (result != EmulatorConsole.RESULT_OK) {
+            try {
+                mParent.getDisplay().asyncExec(new Runnable() {
+                    public void run() {
+                        if (mParent.isDisposed() == false) {
+                            MessageDialog.openError(mParent.getShell(), "Emulator Console",
+                                    result);
+                        }
+                    }
+                });
+            } catch (SWTException e) {
+                // we're quitting, just ignore
+            }
+            
+            return false;
+        }
+        
+        return true;
+    }
+
+    /**
+     * @param track
+     */
+    private void playTrack(final Track track) {
+        // no need to synchronize this check, the worst that can happen, is we start the thread
+        // for nothing.
+        if (mEmulatorConsole != null) {
+            mPlayGpxButton.setImage(mPauseImage);
+            mPlayKmlButton.setImage(mPauseImage);
+            mPlayingTrack = true;
+
+            mPlayingThread = new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        TrackPoint[] trackPoints = track.getPoints();
+                        int count = trackPoints.length;
+                        
+                        // get the start index.
+                        int start = 0;
+                        if (mPlayDirection == -1) {
+                            start = count - 1;
+                        }
+                        
+                        for (int p = start; p >= 0 && p < count; p += mPlayDirection) {
+                            if (mPlayingTrack == false) {
+                                return;
+                            }
+
+                            // get the current point and send its location to
+                            // the emulator.
+                            final TrackPoint trackPoint = trackPoints[p];
+
+                            synchronized (EmulatorControlPanel.this) {
+                                if (mEmulatorConsole == null ||
+                                        processCommandResult(mEmulatorConsole.sendLocation(
+                                                trackPoint.getLongitude(), trackPoint.getLatitude(),
+                                                trackPoint.getElevation())) == false) {
+                                    return;
+                                }
+                            }
+
+                            // if this is not the final point, then get the next one and
+                            // compute the delta time
+                            int nextIndex = p + mPlayDirection;
+                            if (nextIndex >=0 && nextIndex < count) {
+                                TrackPoint nextPoint = trackPoints[nextIndex];
+
+                                long delta = nextPoint.getTime() - trackPoint.getTime();
+                                if (delta < 0) {
+                                    delta = -delta;
+                                }
+                                
+                                long startTime = System.currentTimeMillis();
+
+                                try {
+                                    sleep(delta / mSpeed);
+                                } catch (InterruptedException e) {
+                                    if (mPlayingTrack == false) {
+                                        return;
+                                    }
+                                    
+                                    // we got interrupted, lets make sure we can play
+                                    do {
+                                        long waited = System.currentTimeMillis() - startTime;
+                                        long needToWait = delta / mSpeed;
+                                        if (waited < needToWait) {
+                                            try {
+                                                sleep(needToWait - waited);
+                                            } catch (InterruptedException e1) {
+                                                // we'll just loop and wait again if needed.
+                                                // unless we're supposed to stop
+                                                if (mPlayingTrack == false) {
+                                                    return;
+                                                }
+                                            }
+                                        } else {
+                                            break;
+                                        }
+                                    } while (true);
+                                }
+                            }
+                        }
+                    } finally {
+                        mPlayingTrack = false;
+                        try {
+                            mParent.getDisplay().asyncExec(new Runnable() {
+                                public void run() {
+                                    if (mPlayGpxButton.isDisposed() == false) {
+                                        mPlayGpxButton.setImage(mPlayImage);
+                                        mPlayKmlButton.setImage(mPlayImage);
+                                    }
+                                }
+                            });
+                        } catch (SWTException e) {
+                            // we're quitting, just ignore
+                        }
+                    }
+                }
+            };
+
+            mPlayingThread.start();
+        }
+    }
+    
+    private void playKml(final WayPoint[] trackPoints) {
+        // no need to synchronize this check, the worst that can happen, is we start the thread
+        // for nothing.
+        if (mEmulatorConsole != null) {
+            mPlayGpxButton.setImage(mPauseImage);
+            mPlayKmlButton.setImage(mPauseImage);
+            mPlayingTrack = true;
+
+            mPlayingThread = new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        int count = trackPoints.length;
+                        
+                        // get the start index.
+                        int start = 0;
+                        if (mPlayDirection == -1) {
+                            start = count - 1;
+                        }
+                        
+                        for (int p = start; p >= 0 && p < count; p += mPlayDirection) {
+                            if (mPlayingTrack == false) {
+                                return;
+                            }
+
+                            // get the current point and send its location to
+                            // the emulator.
+                            WayPoint trackPoint = trackPoints[p];
+
+                            synchronized (EmulatorControlPanel.this) {
+                                if (mEmulatorConsole == null ||
+                                        processCommandResult(mEmulatorConsole.sendLocation(
+                                                trackPoint.getLongitude(), trackPoint.getLatitude(),
+                                                trackPoint.getElevation())) == false) {
+                                    return;
+                                }
+                            }
+
+                            // if this is not the final point, then get the next one and
+                            // compute the delta time
+                            int nextIndex = p + mPlayDirection;
+                            if (nextIndex >=0 && nextIndex < count) {
+
+                                long delta = 1000; // 1 second
+                                if (delta < 0) {
+                                    delta = -delta;
+                                }
+                                
+                                long startTime = System.currentTimeMillis();
+
+                                try {
+                                    sleep(delta / mSpeed);
+                                } catch (InterruptedException e) {
+                                    if (mPlayingTrack == false) {
+                                        return;
+                                    }
+                                    
+                                    // we got interrupted, lets make sure we can play
+                                    do {
+                                        long waited = System.currentTimeMillis() - startTime;
+                                        long needToWait = delta / mSpeed;
+                                        if (waited < needToWait) {
+                                            try {
+                                                sleep(needToWait - waited);
+                                            } catch (InterruptedException e1) {
+                                                // we'll just loop and wait again if needed.
+                                                // unless we're supposed to stop
+                                                if (mPlayingTrack == false) {
+                                                    return;
+                                                }
+                                            }
+                                        } else {
+                                            break;
+                                        }
+                                    } while (true);
+                                }
+                            }
+                        }
+                    } finally {
+                        mPlayingTrack = false;
+                        try {
+                            mParent.getDisplay().asyncExec(new Runnable() {
+                                public void run() {
+                                    if (mPlayGpxButton.isDisposed() == false) {
+                                        mPlayGpxButton.setImage(mPlayImage);
+                                        mPlayKmlButton.setImage(mPlayImage);
+                                    }
+                                }
+                            });
+                        } catch (SWTException e) {
+                            // we're quitting, just ignore
+                        }
+                    }
+                }
+            };
+
+            mPlayingThread.start();
+        }        
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/HeapPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/HeapPanel.java
new file mode 100644
index 0000000..977203b
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/HeapPanel.java
@@ -0,0 +1,1294 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.Client;
+import com.android.ddmlib.ClientData;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
+import com.android.ddmlib.HeapSegment.HeapSegmentElement;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.CategoryAxis;
+import org.jfree.chart.axis.CategoryLabelPositions;
+import org.jfree.chart.labels.CategoryToolTipGenerator;
+import org.jfree.chart.plot.CategoryPlot;
+import org.jfree.chart.plot.Plot;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.renderer.category.CategoryItemRenderer;
+import org.jfree.chart.title.TextTitle;
+import org.jfree.data.category.CategoryDataset;
+import org.jfree.data.category.DefaultCategoryDataset;
+import org.jfree.experimental.chart.swt.ChartComposite;
+import org.jfree.experimental.swt.SWTUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * Base class for our information panels.
+ */
+public final class HeapPanel extends BaseHeapPanel {
+    private static final String PREFS_STATS_COL_TYPE = "heapPanel.col0"; //$NON-NLS-1$
+    private static final String PREFS_STATS_COL_COUNT = "heapPanel.col1"; //$NON-NLS-1$
+    private static final String PREFS_STATS_COL_SIZE = "heapPanel.col2"; //$NON-NLS-1$
+    private static final String PREFS_STATS_COL_SMALLEST = "heapPanel.col3"; //$NON-NLS-1$
+    private static final String PREFS_STATS_COL_LARGEST = "heapPanel.col4"; //$NON-NLS-1$
+    private static final String PREFS_STATS_COL_MEDIAN = "heapPanel.col5"; //$NON-NLS-1$
+    private static final String PREFS_STATS_COL_AVERAGE = "heapPanel.col6"; //$NON-NLS-1$
+
+    /* args to setUpdateStatus() */
+    private static final int NOT_SELECTED   = 0;
+    private static final int NOT_ENABLED    = 1;
+    private static final int ENABLED        = 2;
+
+    /** color palette and map legend. NATIVE is the last enum is a 0 based enum list, so we need
+     * Native+1 at least. We also need 2 more entries for free area and expansion area.  */
+    private static final int NUM_PALETTE_ENTRIES = HeapSegmentElement.KIND_NATIVE+2 +1;
+    private static final String[] mMapLegend = new String[NUM_PALETTE_ENTRIES];
+    private static final PaletteData mMapPalette = createPalette();
+
+    private static final boolean DISPLAY_HEAP_BITMAP = false;
+    private static final boolean DISPLAY_HILBERT_BITMAP = false;
+
+    private static final int PLACEHOLDER_HILBERT_SIZE = 200;
+    private static final int PLACEHOLDER_LINEAR_V_SIZE = 100;
+    private static final int PLACEHOLDER_LINEAR_H_SIZE = 300;
+
+    private static final int[] ZOOMS = {100, 50, 25};
+    
+    private static final NumberFormat sByteFormatter = NumberFormat.getInstance();
+    private static final NumberFormat sLargeByteFormatter = NumberFormat.getInstance();
+    private static final NumberFormat sCountFormatter = NumberFormat.getInstance();
+    
+    static {
+        sByteFormatter.setMinimumFractionDigits(0);
+        sByteFormatter.setMaximumFractionDigits(1);
+        sLargeByteFormatter.setMinimumFractionDigits(3);
+        sLargeByteFormatter.setMaximumFractionDigits(3);
+
+        sCountFormatter.setGroupingUsed(true);
+    }
+
+    private Display mDisplay;
+
+    private Composite mTop; // real top
+    private Label mUpdateStatus;
+    private Table mHeapSummary;
+    private Combo mDisplayMode;
+
+    //private ScrolledComposite mScrolledComposite;
+
+    private Composite mDisplayBase; // base of the displays.
+    private StackLayout mDisplayStack;
+
+    private Composite mStatisticsBase;
+    private Table mStatisticsTable;
+    private JFreeChart mChart;
+    private ChartComposite mChartComposite;
+    private Button mGcButton;
+    private DefaultCategoryDataset mAllocCountDataSet;
+
+    private Composite mLinearBase;
+    private Label mLinearHeapImage;
+
+    private Composite mHilbertBase;
+    private Label mHilbertHeapImage;
+    private Group mLegend;
+    private Combo mZoom;
+
+    /** Image used for the hilbert display. Since we recreate a new image every time, we
+     * keep this one around to dispose it. */
+    private Image mHilbertImage;
+    private Image mLinearImage;
+    private Composite[] mLayout;
+
+    /*
+     * Create color palette for map.  Set up titles for legend.
+     */
+    private static PaletteData createPalette() {
+        RGB colors[] = new RGB[NUM_PALETTE_ENTRIES];
+        colors[0]
+                = new RGB(192, 192, 192); // non-heap pixels are gray
+        mMapLegend[0]
+                = "(heap expansion area)";
+
+        colors[1]
+                = new RGB(0, 0, 0);       // free chunks are black
+        mMapLegend[1]
+                = "free";
+
+        colors[HeapSegmentElement.KIND_OBJECT + 2]
+                = new RGB(0, 0, 255);     // objects are blue
+        mMapLegend[HeapSegmentElement.KIND_OBJECT + 2]
+                = "data object";
+
+        colors[HeapSegmentElement.KIND_CLASS_OBJECT + 2]
+                = new RGB(0, 255, 0);     // class objects are green
+        mMapLegend[HeapSegmentElement.KIND_CLASS_OBJECT + 2]
+                = "class object";
+
+        colors[HeapSegmentElement.KIND_ARRAY_1 + 2]
+                = new RGB(255, 0, 0);     // byte/bool arrays are red
+        mMapLegend[HeapSegmentElement.KIND_ARRAY_1 + 2]
+                = "1-byte array (byte[], boolean[])";
+
+        colors[HeapSegmentElement.KIND_ARRAY_2 + 2]
+                = new RGB(255, 128, 0);   // short/char arrays are orange
+        mMapLegend[HeapSegmentElement.KIND_ARRAY_2 + 2]
+                = "2-byte array (short[], char[])";
+
+        colors[HeapSegmentElement.KIND_ARRAY_4 + 2]
+                = new RGB(255, 255, 0);   // obj/int/float arrays are yellow
+        mMapLegend[HeapSegmentElement.KIND_ARRAY_4 + 2]
+                = "4-byte array (object[], int[], float[])";
+
+        colors[HeapSegmentElement.KIND_ARRAY_8 + 2]
+                = new RGB(255, 128, 128); // long/double arrays are pink
+        mMapLegend[HeapSegmentElement.KIND_ARRAY_8 + 2]
+                = "8-byte array (long[], double[])";
+
+        colors[HeapSegmentElement.KIND_UNKNOWN + 2]
+                = new RGB(255, 0, 255);   // unknown objects are cyan
+        mMapLegend[HeapSegmentElement.KIND_UNKNOWN + 2]
+                = "unknown object";
+
+        colors[HeapSegmentElement.KIND_NATIVE + 2]
+                = new RGB(64, 64, 64);    // native objects are dark gray
+        mMapLegend[HeapSegmentElement.KIND_NATIVE + 2]
+                = "non-Java object";
+
+        return new PaletteData(colors);
+    }
+
+    /**
+     * Sent when an existing client information changed.
+     * <p/>
+     * This is sent from a non UI thread.
+     * @param client the updated client.
+     * @param changeMask the bit mask describing the changed properties. It can contain
+     * any of the following values: {@link Client#CHANGE_INFO}, {@link Client#CHANGE_NAME}
+     * {@link Client#CHANGE_DEBUGGER_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) {
+        if (client == getCurrentClient()) {
+            if ((changeMask & Client.CHANGE_HEAP_MODE) == Client.CHANGE_HEAP_MODE ||
+                    (changeMask & Client.CHANGE_HEAP_DATA) == Client.CHANGE_HEAP_DATA) {
+                try {
+                    mTop.getDisplay().asyncExec(new Runnable() {
+                        public void run() {
+                            clientSelected();
+                        }
+                    });
+                } catch (SWTException e) {
+                    // display is disposed (app is quitting most likely), we do nothing.
+                }
+            }
+        }
+    }
+
+    /**
+     * Sent when a new device is selected. The new device can be accessed
+     * with {@link #getCurrentDevice()}
+     */
+    @Override
+    public void deviceSelected() {
+        // pass
+    }
+
+    /**
+     * Sent when a new client is selected. The new client can be accessed
+     * with {@link #getCurrentClient()}.
+     */
+    @Override
+    public void clientSelected() {
+        if (mTop.isDisposed())
+            return;
+
+        Client client = getCurrentClient();
+
+        Log.d("ddms", "HeapPanel: changed " + client);
+
+        if (client != null) {
+            ClientData cd = client.getClientData();
+
+            if (client.isHeapUpdateEnabled()) {
+                mGcButton.setEnabled(true);
+                mDisplayMode.setEnabled(true);
+                setUpdateStatus(ENABLED);
+            } else {
+                setUpdateStatus(NOT_ENABLED);
+                mGcButton.setEnabled(false);
+                mDisplayMode.setEnabled(false);
+            }
+
+            fillSummaryTable(cd);
+            
+            int mode = mDisplayMode.getSelectionIndex();
+            if (mode == 0) {
+                fillDetailedTable(client, false /* forceRedraw */);
+            } else {
+                if (DISPLAY_HEAP_BITMAP) {
+                    renderHeapData(cd, mode - 1, false /* forceRedraw */);
+                }
+            }
+        } else {
+            mGcButton.setEnabled(false);
+            mDisplayMode.setEnabled(false);
+            fillSummaryTable(null);
+            fillDetailedTable(null, true);
+            setUpdateStatus(NOT_SELECTED);
+        }
+
+        // sizes of things change frequently, so redo layout
+        //mScrolledComposite.setMinSize(mDisplayStack.topControl.computeSize(SWT.DEFAULT,
+        //        SWT.DEFAULT));
+        mDisplayBase.layout();
+        //mScrolledComposite.redraw();
+    }
+
+    /**
+     * Create our control(s).
+     */
+    @Override
+    protected Control createControl(Composite parent) {
+        mDisplay = parent.getDisplay();
+
+        GridLayout gl;
+
+        mTop = new Composite(parent, SWT.NONE);
+        mTop.setLayout(new GridLayout(1, false));
+        mTop.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        mUpdateStatus = new Label(mTop, SWT.NONE);
+        setUpdateStatus(NOT_SELECTED);
+
+        Composite summarySection = new Composite(mTop, SWT.NONE);
+        summarySection.setLayout(gl = new GridLayout(2, false));
+        gl.marginHeight = gl.marginWidth = 0;
+
+        mHeapSummary = createSummaryTable(summarySection);
+        mGcButton = new Button(summarySection, SWT.PUSH);
+        mGcButton.setText("Cause GC");
+        mGcButton.setEnabled(false);
+        mGcButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                Client client = getCurrentClient();
+                if (client != null) {
+                    client.executeGarbageCollector();
+                }
+            }
+        });
+
+        Composite comboSection = new Composite(mTop, SWT.NONE);
+        gl = new GridLayout(2, false);
+        gl.marginHeight = gl.marginWidth = 0;
+        comboSection.setLayout(gl);
+
+        Label displayLabel = new Label(comboSection, SWT.NONE);
+        displayLabel.setText("Display: ");
+
+        mDisplayMode = new Combo(comboSection, SWT.READ_ONLY);
+        mDisplayMode.setEnabled(false);
+        mDisplayMode.add("Stats");
+        if (DISPLAY_HEAP_BITMAP) {
+            mDisplayMode.add("Linear");
+            if (DISPLAY_HILBERT_BITMAP) {
+                mDisplayMode.add("Hilbert");
+            }
+        }
+
+        // the base of the displays.
+        mDisplayBase = new Composite(mTop, SWT.NONE);
+        mDisplayBase.setLayoutData(new GridData(GridData.FILL_BOTH));
+        mDisplayStack = new StackLayout();
+        mDisplayBase.setLayout(mDisplayStack);
+
+        // create the statistics display
+        mStatisticsBase = new Composite(mDisplayBase, SWT.NONE);
+        //mStatisticsBase.setLayoutData(new GridData(GridData.FILL_BOTH));
+        mStatisticsBase.setLayout(gl = new GridLayout(1, false));
+        gl.marginHeight = gl.marginWidth = 0;
+        mDisplayStack.topControl = mStatisticsBase;
+        
+        mStatisticsTable = createDetailedTable(mStatisticsBase);
+        mStatisticsTable.setLayoutData(new GridData(GridData.FILL_BOTH));
+        
+        createChart();
+
+        //create the linear composite
+        mLinearBase = new Composite(mDisplayBase, SWT.NONE);
+        //mLinearBase.setLayoutData(new GridData());
+        gl = new GridLayout(1, false);
+        gl.marginHeight = gl.marginWidth = 0;
+        mLinearBase.setLayout(gl);
+
+        {
+            mLinearHeapImage = new Label(mLinearBase, SWT.NONE);
+            mLinearHeapImage.setLayoutData(new GridData());
+            mLinearHeapImage.setImage(ImageHelper.createPlaceHolderArt(mDisplay,
+                    PLACEHOLDER_LINEAR_H_SIZE, PLACEHOLDER_LINEAR_V_SIZE,
+                    mDisplay.getSystemColor(SWT.COLOR_BLUE)));
+
+            // create a composite to contain the bottom part (legend)
+            Composite bottomSection = new Composite(mLinearBase, SWT.NONE);
+            gl = new GridLayout(1, false);
+            gl.marginHeight = gl.marginWidth = 0;
+            bottomSection.setLayout(gl);
+
+            createLegend(bottomSection);
+        }
+
+/*        
+        mScrolledComposite = new ScrolledComposite(mTop, SWT.H_SCROLL | SWT.V_SCROLL);
+        mScrolledComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+        mScrolledComposite.setExpandHorizontal(true);
+        mScrolledComposite.setExpandVertical(true);
+        mScrolledComposite.setContent(mDisplayBase);
+*/
+
+
+        // create the hilbert display.
+        mHilbertBase = new Composite(mDisplayBase, SWT.NONE);
+        //mHilbertBase.setLayoutData(new GridData());
+        gl = new GridLayout(2, false);
+        gl.marginHeight = gl.marginWidth = 0;
+        mHilbertBase.setLayout(gl);
+
+        if (DISPLAY_HILBERT_BITMAP) {
+            mHilbertHeapImage = new Label(mHilbertBase, SWT.NONE);
+            mHilbertHeapImage.setLayoutData(new GridData());
+            mHilbertHeapImage.setImage(ImageHelper.createPlaceHolderArt(mDisplay,
+                    PLACEHOLDER_HILBERT_SIZE, PLACEHOLDER_HILBERT_SIZE,
+                    mDisplay.getSystemColor(SWT.COLOR_BLUE)));
+
+            // create a composite to contain the right part (legend + zoom)
+            Composite rightSection = new Composite(mHilbertBase, SWT.NONE);
+            gl = new GridLayout(1, false);
+            gl.marginHeight = gl.marginWidth = 0;
+            rightSection.setLayout(gl);
+
+            Composite zoomComposite = new Composite(rightSection, SWT.NONE);
+            gl = new GridLayout(2, false);
+            zoomComposite.setLayout(gl);
+
+            Label l = new Label(zoomComposite, SWT.NONE);
+            l.setText("Zoom:");
+            mZoom = new Combo(zoomComposite, SWT.READ_ONLY);
+            for (int z : ZOOMS) {
+                mZoom.add(String.format("%1$d%%", z)); // $NON-NLS-1$
+            }
+
+            mZoom.select(0);
+            mZoom.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    setLegendText(mZoom.getSelectionIndex());
+                    Client client = getCurrentClient();
+                    if (client != null) {
+                        renderHeapData(client.getClientData(), 1, true);
+                        mTop.pack();
+                    }
+                }
+            });
+
+            createLegend(rightSection);
+        }
+        mHilbertBase.pack();
+
+        mLayout = new Composite[] { mStatisticsBase, mLinearBase, mHilbertBase };
+        mDisplayMode.select(0);
+        mDisplayMode.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                int index = mDisplayMode.getSelectionIndex();
+                Client client = getCurrentClient();
+
+                if (client != null) {
+                    if (index == 0) {
+                        fillDetailedTable(client, true /* forceRedraw */);
+                    } else {
+                        renderHeapData(client.getClientData(), index-1, true /* forceRedraw */);
+                    }
+                }
+
+                mDisplayStack.topControl = mLayout[index];
+                //mScrolledComposite.setMinSize(mDisplayStack.topControl.computeSize(SWT.DEFAULT,
+                //        SWT.DEFAULT));
+                mDisplayBase.layout();
+                //mScrolledComposite.redraw();
+            }
+        });
+
+        //mScrolledComposite.setMinSize(mDisplayStack.topControl.computeSize(SWT.DEFAULT,
+        //        SWT.DEFAULT));
+        mDisplayBase.layout();
+        //mScrolledComposite.redraw();
+
+        return mTop;
+    }
+
+    /**
+     * Sets the focus to the proper control inside the panel.
+     */
+    @Override
+    public void setFocus() {
+        mHeapSummary.setFocus();
+    }
+    
+
+    private Table createSummaryTable(Composite base) {
+        Table tab = new Table(base, SWT.SINGLE | SWT.FULL_SELECTION);
+        tab.setHeaderVisible(true);
+        tab.setLinesVisible(true);
+
+        TableColumn col;
+
+        col = new TableColumn(tab, SWT.RIGHT);
+        col.setText("ID");
+        col.pack();
+
+        col = new TableColumn(tab, SWT.RIGHT);
+        col.setText("000.000WW"); // $NON-NLS-1$
+        col.pack();
+        col.setText("Heap Size");
+
+        col = new TableColumn(tab, SWT.RIGHT);
+        col.setText("000.000WW"); // $NON-NLS-1$
+        col.pack();
+        col.setText("Allocated");
+
+        col = new TableColumn(tab, SWT.RIGHT);
+        col.setText("000.000WW"); // $NON-NLS-1$
+        col.pack();
+        col.setText("Free");
+
+        col = new TableColumn(tab, SWT.RIGHT);
+        col.setText("000.00%"); // $NON-NLS-1$
+        col.pack();
+        col.setText("% Used");
+
+        col = new TableColumn(tab, SWT.RIGHT);
+        col.setText("000,000,000"); // $NON-NLS-1$
+        col.pack();
+        col.setText("# Objects");
+
+        return tab;
+    }
+    
+    private Table createDetailedTable(Composite base) {
+        IPreferenceStore store = DdmUiPreferences.getStore();
+        
+        Table tab = new Table(base, SWT.SINGLE | SWT.FULL_SELECTION);
+        tab.setHeaderVisible(true);
+        tab.setLinesVisible(true);
+
+        TableHelper.createTableColumn(tab, "Type", SWT.LEFT,
+                "4-byte array (object[], int[], float[])", //$NON-NLS-1$
+                PREFS_STATS_COL_TYPE, store);
+
+        TableHelper.createTableColumn(tab, "Count", SWT.RIGHT,
+                "00,000", //$NON-NLS-1$
+                PREFS_STATS_COL_COUNT, store);
+
+        TableHelper.createTableColumn(tab, "Total Size", SWT.RIGHT,
+                "000.000 WW", //$NON-NLS-1$
+                PREFS_STATS_COL_SIZE, store);
+
+        TableHelper.createTableColumn(tab, "Smallest", SWT.RIGHT,
+                "000.000 WW", //$NON-NLS-1$
+                PREFS_STATS_COL_SMALLEST, store);
+
+        TableHelper.createTableColumn(tab, "Largest", SWT.RIGHT,
+                "000.000 WW", //$NON-NLS-1$
+                PREFS_STATS_COL_LARGEST, store);
+
+        TableHelper.createTableColumn(tab, "Median", SWT.RIGHT,
+                "000.000 WW", //$NON-NLS-1$
+                PREFS_STATS_COL_MEDIAN, store);
+
+        TableHelper.createTableColumn(tab, "Average", SWT.RIGHT,
+                "000.000 WW", //$NON-NLS-1$
+                PREFS_STATS_COL_AVERAGE, store);
+
+        tab.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                
+                Client client = getCurrentClient();
+                if (client != null) {
+                    int index = mStatisticsTable.getSelectionIndex();
+                    TableItem item = mStatisticsTable.getItem(index);
+                    
+                    if (item != null) {
+                        Map<Integer, ArrayList<HeapSegmentElement>> heapMap =
+                            client.getClientData().getVmHeapData().getProcessedHeapMap();
+                        
+                        ArrayList<HeapSegmentElement> list = heapMap.get(item.getData());
+                        if (list != null) {
+                            showChart(list);
+                        }
+                    }
+                }
+
+            }
+        });
+        
+        return tab;
+    }
+    
+    /**
+     * Creates the chart below the statistics table
+     */
+    private void createChart() {
+        mAllocCountDataSet = new DefaultCategoryDataset();
+        mChart = ChartFactory.createBarChart(null, "Size", "Count", mAllocCountDataSet,
+                PlotOrientation.VERTICAL, false, true, false);
+        
+        // get the font to make a proper title. We need to convert the swt font,
+        // into an awt font.
+        Font f = mStatisticsBase.getFont();
+        FontData[] fData = f.getFontData();
+        
+        // event though on Mac OS there could be more than one fontData, we'll only use
+        // the first one.
+        FontData firstFontData = fData[0];
+        
+        java.awt.Font awtFont = SWTUtils.toAwtFont(mStatisticsBase.getDisplay(),
+                firstFontData, true /* ensureSameSize */);
+
+        mChart.setTitle(new TextTitle("Allocation count per size", awtFont));
+        
+        Plot plot = mChart.getPlot();
+        if (plot instanceof CategoryPlot) {
+            // get the plot
+            CategoryPlot categoryPlot = (CategoryPlot)plot;
+            
+            // set the domain axis to draw labels that are displayed even with many values.
+            CategoryAxis domainAxis = categoryPlot.getDomainAxis();
+            domainAxis.setCategoryLabelPositions(CategoryLabelPositions.DOWN_90);
+            
+            CategoryItemRenderer renderer = categoryPlot.getRenderer();
+            renderer.setBaseToolTipGenerator(new CategoryToolTipGenerator() {
+                public String generateToolTip(CategoryDataset dataset, int row, int column) {
+                    // get the key for the size of the allocation
+                    ByteLong columnKey = (ByteLong)dataset.getColumnKey(column);
+                    String rowKey = (String)dataset.getRowKey(row);
+                    Number value = dataset.getValue(rowKey, columnKey);
+                    
+                    return String.format("%1$d %2$s of %3$d bytes", value.intValue(), rowKey, 
+                            columnKey.getValue());
+                }
+            });
+        }
+        mChartComposite = new ChartComposite(mStatisticsBase, SWT.BORDER, mChart,
+                ChartComposite.DEFAULT_WIDTH,
+                ChartComposite.DEFAULT_HEIGHT,
+                ChartComposite.DEFAULT_MINIMUM_DRAW_WIDTH,
+                ChartComposite.DEFAULT_MINIMUM_DRAW_HEIGHT,
+                3000, // max draw width. We don't want it to zoom, so we put a big number
+                3000, // max draw height. We don't want it to zoom, so we put a big number
+                true,  // off-screen buffer
+                true,  // properties
+                true,  // save
+                true,  // print
+                false,  // zoom
+                true);   // tooltips
+
+        mChartComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+    }
+
+    private static String prettyByteCount(long bytes) {
+        double fracBytes = bytes;
+        String units = " B";
+        if (fracBytes < 1024) {
+            return sByteFormatter.format(fracBytes) + units;
+        } else {
+            fracBytes /= 1024;
+            units = " KB";
+        }
+        if (fracBytes >= 1024) {
+            fracBytes /= 1024;
+            units = " MB";
+        }
+        if (fracBytes >= 1024) {
+            fracBytes /= 1024;
+            units = " GB";
+        }
+
+        return sLargeByteFormatter.format(fracBytes) + units;
+    }
+
+    private static String approximateByteCount(long bytes) {
+        double fracBytes = bytes;
+        String units = "";
+        if (fracBytes >= 1024) {
+            fracBytes /= 1024;
+            units = "K";
+        }
+        if (fracBytes >= 1024) {
+            fracBytes /= 1024;
+            units = "M";
+        }
+        if (fracBytes >= 1024) {
+            fracBytes /= 1024;
+            units = "G";
+        }
+
+        return sByteFormatter.format(fracBytes) + units;
+    }
+
+    private static String addCommasToNumber(long num) {
+        return sCountFormatter.format(num);
+    }
+
+    private static String fractionalPercent(long num, long denom) {
+        double val = (double)num / (double)denom;
+        val *= 100;
+
+        NumberFormat nf = NumberFormat.getInstance();
+        nf.setMinimumFractionDigits(2);
+        nf.setMaximumFractionDigits(2);
+        return nf.format(val) + "%";
+    }
+
+    private void fillSummaryTable(ClientData cd) {
+        if (mHeapSummary.isDisposed()) {
+            return;
+        }
+
+        mHeapSummary.setRedraw(false);
+        mHeapSummary.removeAll();
+
+        if (cd != null) {
+            synchronized (cd) {
+                Iterator<Integer> iter = cd.getVmHeapIds();
+    
+                while (iter.hasNext()) {
+                    Integer id = iter.next();
+                    Map<String, Long> heapInfo = cd.getVmHeapInfo(id);
+                    if (heapInfo == null) {
+                        continue;
+                    }
+                    long sizeInBytes = heapInfo.get(ClientData.HEAP_SIZE_BYTES);
+                    long bytesAllocated = heapInfo.get(ClientData.HEAP_BYTES_ALLOCATED);
+                    long objectsAllocated = heapInfo.get(ClientData.HEAP_OBJECTS_ALLOCATED);
+    
+                    TableItem item = new TableItem(mHeapSummary, SWT.NONE);
+                    item.setText(0, id.toString());
+    
+                    item.setText(1, prettyByteCount(sizeInBytes));
+                    item.setText(2, prettyByteCount(bytesAllocated));
+                    item.setText(3, prettyByteCount(sizeInBytes - bytesAllocated));
+                    item.setText(4, fractionalPercent(bytesAllocated, sizeInBytes));
+                    item.setText(5, addCommasToNumber(objectsAllocated));
+                }
+            }
+        }
+
+        mHeapSummary.pack();
+        mHeapSummary.setRedraw(true);
+    }
+    
+    private void fillDetailedTable(Client client, boolean forceRedraw) {
+        // first check if the client is invalid or heap updates are not enabled.
+        if (client == null || client.isHeapUpdateEnabled() == false) {
+            mStatisticsTable.removeAll();
+            showChart(null);
+            return;
+        }
+        
+        ClientData cd = client.getClientData();
+
+        Map<Integer, ArrayList<HeapSegmentElement>> heapMap;
+
+        // Atomically get and clear the heap data.
+        synchronized (cd) {
+            if (serializeHeapData(cd.getVmHeapData()) == false && forceRedraw == false) {
+                // no change, we return.
+                return;
+            }
+            
+            heapMap = cd.getVmHeapData().getProcessedHeapMap();
+        }
+        
+        // we have new data, lets display it.
+        
+        // First, get the current selection, and its key.
+        int index = mStatisticsTable.getSelectionIndex();
+        Integer selectedKey = null;
+        if (index != -1) {
+            selectedKey = (Integer)mStatisticsTable.getItem(index).getData();
+        }
+
+        // disable redraws and remove all from the table.
+        mStatisticsTable.setRedraw(false);
+        mStatisticsTable.removeAll();
+        
+        if (heapMap != null) {
+            int selectedIndex = -1;
+            ArrayList<HeapSegmentElement> selectedList = null;
+            
+            // get the keys
+            Set<Integer> keys = heapMap.keySet();
+            int iter = 0; // use a manual iter int because Set<?> doesn't have an index
+            // based accessor.
+            for (Integer key : keys) {
+                ArrayList<HeapSegmentElement> list = heapMap.get(key);
+
+                // check if this is the key that is supposed to be selected
+                if (key.equals(selectedKey)) {
+                    selectedIndex = iter;
+                    selectedList = list;
+                }
+                iter++;
+
+                TableItem item = new TableItem(mStatisticsTable, SWT.NONE);
+                item.setData(key);
+
+                // get the type
+                item.setText(0, mMapLegend[key]);
+                
+                // set the count, smallest, largest
+                int count = list.size();
+                item.setText(1, addCommasToNumber(count));
+                
+                if (count > 0) {
+                    item.setText(3, prettyByteCount(list.get(0).getLength()));
+                    item.setText(4, prettyByteCount(list.get(count-1).getLength()));
+
+                    int median = count / 2;
+                    HeapSegmentElement element = list.get(median);
+                    long size = element.getLength();
+                    item.setText(5, prettyByteCount(size));
+
+                    long totalSize = 0;
+                    for (int i = 0 ; i < count; i++) {
+                        element = list.get(i);
+                        
+                        size = element.getLength();
+                        totalSize += size;
+                    }
+                    
+                    // set the average and total
+                    item.setText(2, prettyByteCount(totalSize));
+                    item.setText(6, prettyByteCount(totalSize / count));
+                }
+            }
+
+            mStatisticsTable.setRedraw(true);
+            
+            if (selectedIndex != -1) {
+                mStatisticsTable.setSelection(selectedIndex);
+                showChart(selectedList);
+            } else {
+                showChart(null);
+            }
+        } else {
+            mStatisticsTable.setRedraw(true);
+        }
+    }
+    
+    private static class ByteLong implements Comparable<ByteLong> {
+        private long mValue;
+        
+        private ByteLong(long value) {
+            mValue = value;
+        }
+        
+        public long getValue() {
+            return mValue;
+        }
+
+        @Override
+        public String toString() {
+            return approximateByteCount(mValue);
+        }
+
+        public int compareTo(ByteLong other) {
+            if (mValue != other.mValue) {
+                return mValue < other.mValue ? -1 : 1;
+            }
+            return 0;
+        }
+        
+    }
+    
+    /**
+     * Fills the chart with the content of the list of {@link HeapSegmentElement}.
+     */
+    private void showChart(ArrayList<HeapSegmentElement> list) {
+        mAllocCountDataSet.clear();
+
+        if (list != null) {
+            String rowKey = "Alloc Count";
+    
+            long currentSize = -1;
+            int currentCount = 0;
+            for (HeapSegmentElement element : list) {
+                if (element.getLength() != currentSize) {
+                    if (currentSize != -1) {
+                        ByteLong columnKey = new ByteLong(currentSize);
+                        mAllocCountDataSet.addValue(currentCount, rowKey, columnKey);
+                    }
+                    
+                    currentSize = element.getLength();
+                    currentCount = 1;
+                } else {
+                    currentCount++;
+                }
+            }
+            
+            // add the last item
+            if (currentSize != -1) {
+                ByteLong columnKey = new ByteLong(currentSize);
+                mAllocCountDataSet.addValue(currentCount, rowKey, columnKey);
+            }
+        }
+    }
+
+    /*
+     * Add a color legend to the specified table.
+     */
+    private void createLegend(Composite parent) {
+        mLegend = new Group(parent, SWT.NONE);
+        mLegend.setText(getLegendText(0));
+
+        mLegend.setLayout(new GridLayout(2, false));
+
+        RGB[] colors = mMapPalette.colors;
+
+        for (int i = 0; i < NUM_PALETTE_ENTRIES; i++) {
+            Image tmpImage = createColorRect(parent.getDisplay(), colors[i]);
+
+            Label l = new Label(mLegend, SWT.NONE);
+            l.setImage(tmpImage);
+
+            l = new Label(mLegend, SWT.NONE);
+            l.setText(mMapLegend[i]);
+        }
+    }
+
+    private String getLegendText(int level) {
+        int bytes = 8 * (100 / ZOOMS[level]);
+
+        return String.format("Key (1 pixel = %1$d bytes)", bytes);
+    }
+
+    private void setLegendText(int level) {
+        mLegend.setText(getLegendText(level));
+
+    }
+
+    /*
+     * Create a nice rectangle in the specified color.
+     */
+    private Image createColorRect(Display display, RGB color) {
+        int width = 32;
+        int height = 16;
+
+        Image img = new Image(display, width, height);
+        GC gc = new GC(img);
+        gc.setBackground(new Color(display, color));
+        gc.fillRectangle(0, 0, width, height);
+        gc.dispose();
+        return img;
+    }
+
+
+    /*
+     * Are updates enabled?
+     */
+    private void setUpdateStatus(int status) {
+        switch (status) {
+            case NOT_SELECTED:
+                mUpdateStatus.setText("Select a client to see heap updates");
+                break;
+            case NOT_ENABLED:
+                mUpdateStatus.setText("Heap updates are " +
+                                      "NOT ENABLED for this client");
+                break;
+            case ENABLED:
+                mUpdateStatus.setText("Heap updates will happen after " +
+                                      "every GC for this client");
+                break;
+            default:
+                throw new RuntimeException();
+        }
+
+        mUpdateStatus.pack();
+    }
+
+
+    /**
+     * Return the closest power of two greater than or equal to value.
+     *
+     * @param value the return value will be >= value
+     * @return a power of two >= value.  If value > 2^31, 2^31 is returned.
+     */
+//xxx use Integer.highestOneBit() or numberOfLeadingZeros().
+    private int nextPow2(int value) {
+        for (int i = 31; i >= 0; --i) {
+            if ((value & (1<<i)) != 0) {
+                if (i < 31) {
+                    return 1<<(i + 1);
+                } else {
+                    return 1<<31;
+                }
+            }
+        }
+        return 0;
+    }
+
+    private int zOrderData(ImageData id, byte pixData[]) {
+        int maxX = 0;
+        for (int i = 0; i < pixData.length; i++) {
+            /* Tread the pixData index as a z-order curve index and
+             * decompose into Cartesian coordinates.
+             */
+            int x = (i & 1) |
+                    ((i >>> 2) & 1) << 1 |
+                    ((i >>> 4) & 1) << 2 |
+                    ((i >>> 6) & 1) << 3 |
+                    ((i >>> 8) & 1) << 4 |
+                    ((i >>> 10) & 1) << 5 |
+                    ((i >>> 12) & 1) << 6 |
+                    ((i >>> 14) & 1) << 7 |
+                    ((i >>> 16) & 1) << 8 |
+                    ((i >>> 18) & 1) << 9 |
+                    ((i >>> 20) & 1) << 10 |
+                    ((i >>> 22) & 1) << 11 |
+                    ((i >>> 24) & 1) << 12 |
+                    ((i >>> 26) & 1) << 13 |
+                    ((i >>> 28) & 1) << 14 |
+                    ((i >>> 30) & 1) << 15;
+            int y = ((i >>> 1) & 1) << 0 |
+                    ((i >>> 3) & 1) << 1 |
+                    ((i >>> 5) & 1) << 2 |
+                    ((i >>> 7) & 1) << 3 |
+                    ((i >>> 9) & 1) << 4 |
+                    ((i >>> 11) & 1) << 5 |
+                    ((i >>> 13) & 1) << 6 |
+                    ((i >>> 15) & 1) << 7 |
+                    ((i >>> 17) & 1) << 8 |
+                    ((i >>> 19) & 1) << 9 |
+                    ((i >>> 21) & 1) << 10 |
+                    ((i >>> 23) & 1) << 11 |
+                    ((i >>> 25) & 1) << 12 |
+                    ((i >>> 27) & 1) << 13 |
+                    ((i >>> 29) & 1) << 14 |
+                    ((i >>> 31) & 1) << 15;
+            try {
+                id.setPixel(x, y, pixData[i]);
+                if (x > maxX) {
+                    maxX = x;
+                }
+            } catch (IllegalArgumentException ex) {
+                System.out.println("bad pixels: i " + i +
+                        ", w " + id.width +
+                        ", h " + id.height +
+                        ", x " + x +
+                        ", y " + y);
+                throw ex;
+            }
+        }
+        return maxX;
+    }
+
+    private final static int HILBERT_DIR_N = 0;
+    private final static int HILBERT_DIR_S = 1;
+    private final static int HILBERT_DIR_E = 2;
+    private final static int HILBERT_DIR_W = 3;
+
+    private void hilbertWalk(ImageData id, InputStream pixData,
+                             int order, int x, int y, int dir)
+                             throws IOException {
+        if (x >= id.width || y >= id.height) {
+            return;
+        } else if (order == 0) {
+            try {
+                int p = pixData.read();
+                if (p >= 0) {
+                    // flip along x=y axis;  assume width == height
+                    id.setPixel(y, x, p);
+
+                    /* Skanky; use an otherwise-unused ImageData field
+                     * to keep track of the max x,y used. Note that x and y are inverted.
+                     */
+                    if (y > id.x) {
+                        id.x = y;
+                    }
+                    if (x > id.y) {
+                        id.y = x;
+                    }
+                }
+//xxx just give up; don't bother walking the rest of the image
+            } catch (IllegalArgumentException ex) {
+                System.out.println("bad pixels: order " + order +
+                        ", dir " + dir +
+                        ", w " + id.width +
+                        ", h " + id.height +
+                        ", x " + x +
+                        ", y " + y);
+                throw ex;
+            }
+        } else {
+            order--;
+            int delta = 1 << order;
+            int nextX = x + delta;
+            int nextY = y + delta;
+
+            switch (dir) {
+            case HILBERT_DIR_E:
+                hilbertWalk(id, pixData, order,     x,     y, HILBERT_DIR_N);
+                hilbertWalk(id, pixData, order,     x, nextY, HILBERT_DIR_E);
+                hilbertWalk(id, pixData, order, nextX, nextY, HILBERT_DIR_E);
+                hilbertWalk(id, pixData, order, nextX,     y, HILBERT_DIR_S);
+                break;
+            case HILBERT_DIR_N:
+                hilbertWalk(id, pixData, order,     x,     y, HILBERT_DIR_E);
+                hilbertWalk(id, pixData, order, nextX,     y, HILBERT_DIR_N);
+                hilbertWalk(id, pixData, order, nextX, nextY, HILBERT_DIR_N);
+                hilbertWalk(id, pixData, order,     x, nextY, HILBERT_DIR_W);
+                break;
+            case HILBERT_DIR_S:
+                hilbertWalk(id, pixData, order, nextX, nextY, HILBERT_DIR_W);
+                hilbertWalk(id, pixData, order,     x, nextY, HILBERT_DIR_S);
+                hilbertWalk(id, pixData, order,     x,     y, HILBERT_DIR_S);
+                hilbertWalk(id, pixData, order, nextX,     y, HILBERT_DIR_E);
+                break;
+            case HILBERT_DIR_W:
+                hilbertWalk(id, pixData, order, nextX, nextY, HILBERT_DIR_S);
+                hilbertWalk(id, pixData, order, nextX,     y, HILBERT_DIR_W);
+                hilbertWalk(id, pixData, order,     x,     y, HILBERT_DIR_W);
+                hilbertWalk(id, pixData, order,     x, nextY, HILBERT_DIR_N);
+                break;
+            default:
+                throw new RuntimeException("Unexpected Hilbert direction " +
+                                           dir);
+            }
+        }
+    }
+
+    private Point hilbertOrderData(ImageData id, byte pixData[]) {
+
+        int order = 0;
+        for (int n = 1; n < id.width; n *= 2) {
+            order++;
+        }
+        /* Skanky; use an otherwise-unused ImageData field
+         * to keep track of maxX.
+         */
+        Point p = new Point(0,0);
+        int oldIdX = id.x;
+        int oldIdY = id.y;
+        id.x = id.y = 0;
+        try {
+            hilbertWalk(id, new ByteArrayInputStream(pixData),
+                        order, 0, 0, HILBERT_DIR_E);
+            p.x = id.x;
+            p.y = id.y;
+        } catch (IOException ex) {
+            System.err.println("Exception during hilbertWalk()");
+            p.x = id.height;
+            p.y = id.width;
+        }
+        id.x = oldIdX;
+        id.y = oldIdY;
+        return p;
+    }
+
+    private ImageData createHilbertHeapImage(byte pixData[]) {
+        int w, h;
+
+        // Pick an image size that the largest of heaps will fit into.
+        w = (int)Math.sqrt((double)((16 * 1024 * 1024)/8));
+
+        // Space-filling curves require a power-of-2 width.
+        w = nextPow2(w);
+        h = w;
+
+        // Create the heap image.
+        ImageData id = new ImageData(w, h, 8, mMapPalette);
+
+        // Copy the data into the image
+        //int maxX = zOrderData(id, pixData);
+        Point maxP = hilbertOrderData(id, pixData);
+
+        // update the max size to make it a round number once the zoom is applied
+        int factor = 100 / ZOOMS[mZoom.getSelectionIndex()];
+        if (factor != 1) {
+            int tmp = maxP.x % factor;
+            if (tmp != 0) {
+                maxP.x += factor - tmp;
+            }
+
+            tmp = maxP.y % factor;
+            if (tmp != 0) {
+                maxP.y += factor - tmp;
+            }
+        }
+
+        if (maxP.y < id.height) {
+            // Crop the image down to the interesting part.
+            id = new ImageData(id.width, maxP.y, id.depth, id.palette,
+                               id.scanlinePad, id.data);
+        }
+
+        if (maxP.x < id.width) {
+            // crop the image again. A bit trickier this time.
+           ImageData croppedId = new ImageData(maxP.x, id.height, id.depth, id.palette);
+
+           int[] buffer = new int[maxP.x];
+           for (int l = 0 ; l < id.height; l++) {
+               id.getPixels(0, l, maxP.x, buffer, 0);
+               croppedId.setPixels(0, l, maxP.x, buffer, 0);
+           }
+
+           id = croppedId;
+        }
+
+        // apply the zoom
+        if (factor != 1) {
+            id = id.scaledTo(id.width / factor, id.height / factor);
+        }
+
+        return id;
+    }
+
+    /**
+     * Convert the raw heap data to an image.  We know we're running in
+     * the UI thread, so we can issue graphics commands directly.
+     *
+     * http://help.eclipse.org/help31/nftopic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/graphics/GC.html
+     *
+     * @param cd The client data
+     * @param mode The display mode. 0 = linear, 1 = hilbert.
+     * @param forceRedraw
+     */
+    private void renderHeapData(ClientData cd, int mode, boolean forceRedraw) {
+        Image image;
+
+        byte[] pixData;
+
+        // Atomically get and clear the heap data.
+        synchronized (cd) {
+            if (serializeHeapData(cd.getVmHeapData()) == false && forceRedraw == false) {
+                // no change, we return.
+                return;
+            }
+
+            pixData = getSerializedData();
+        }
+
+        if (pixData != null) {
+            ImageData id;
+            if (mode == 1) {
+                id = createHilbertHeapImage(pixData);
+            } else {
+                id = createLinearHeapImage(pixData, 200, mMapPalette);
+            }
+
+            image = new Image(mDisplay, id);
+        } else {
+            // Render a placeholder image.
+            int width, height;
+            if (mode == 1) {
+                width = height = PLACEHOLDER_HILBERT_SIZE;
+            } else {
+                width = PLACEHOLDER_LINEAR_H_SIZE;
+                height = PLACEHOLDER_LINEAR_V_SIZE;
+            }
+            image = new Image(mDisplay, width, height);
+            GC gc = new GC(image);
+            gc.setForeground(mDisplay.getSystemColor(SWT.COLOR_RED));
+            gc.drawLine(0, 0, width-1, height-1);
+            gc.dispose();
+            gc = null;
+        }
+
+        // set the new image
+
+        if (mode == 1) {
+            if (mHilbertImage != null) {
+                mHilbertImage.dispose();
+            }
+
+            mHilbertImage = image;
+            mHilbertHeapImage.setImage(mHilbertImage);
+            mHilbertHeapImage.pack(true);
+            mHilbertBase.layout();
+            mHilbertBase.pack(true);
+        } else {
+            if (mLinearImage != null) {
+                mLinearImage.dispose();
+            }
+
+            mLinearImage = image;
+            mLinearHeapImage.setImage(mLinearImage);
+            mLinearHeapImage.pack(true);
+            mLinearBase.layout();
+            mLinearBase.pack(true);
+        }
+    }
+
+    @Override
+    protected void setTableFocusListener() {
+        addTableToFocusListener(mHeapSummary);
+    }
+}
+
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/IImageLoader.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/IImageLoader.java
new file mode 100644
index 0000000..bcbf612
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/IImageLoader.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Interface defining an image loader. jar app/lib and plugin have different packaging method
+ * so each implementation will be different.
+ * The implementation should implement at least one of the methods, and preferably both if possible.
+ *
+ */
+public interface IImageLoader {
+
+    /**
+     * Load an image from the resource from a filename
+     * @param filename
+     * @param display
+     */
+    public Image loadImage(String filename, Display display);
+
+    /**
+     * Load an ImageDescriptor from the resource from a filename
+     * @param filename
+     * @param display
+     */
+    public ImageDescriptor loadDescriptor(String filename, Display display);
+
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ITableFocusListener.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ITableFocusListener.java
new file mode 100644
index 0000000..bf425d9
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ITableFocusListener.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import org.eclipse.swt.dnd.Clipboard;
+
+/**
+ * An object listening to focus change in Table objects.<br>
+ * For application not relying on a RCP to provide menu changes based on focus,
+ * this class allows to get monitor the focus change of several Table widget
+ * and update the menu action accordingly.
+ */
+public interface ITableFocusListener {
+
+	public interface IFocusedTableActivator {
+		public void copy(Clipboard clipboard);
+
+		public void selectAll();
+	}
+
+	public void focusGained(IFocusedTableActivator activator);
+
+	public void focusLost(IFocusedTableActivator activator);
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ImageHelper.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ImageHelper.java
new file mode 100644
index 0000000..d65978b
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ImageHelper.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.Log;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+public class ImageHelper {
+
+    /**
+     * Loads an image from a resource. This method used a class to locate the
+     * resources, and then load the filename from /images inside the resources.<br>
+     * Extra parameters allows for creation of a replacement image of the
+     * loading failed.
+     *
+     * @param loader the image loader used.
+     * @param display the Display object
+     * @param fileName the file name
+     * @param width optional width to create replacement Image. If -1, null be
+     *            be returned if the loading fails.
+     * @param height optional height to create replacement Image. If -1, null be
+     *            be returned if the loading fails.
+     * @param phColor optional color to create replacement Image. If null, Blue
+     *            color will be used.
+     * @return a new Image or null if the loading failed and the optional
+     *         replacement size was -1
+     */
+    public static Image loadImage(IImageLoader loader, Display display,
+            String fileName, int width, int height, Color phColor) {
+
+        Image img = null;
+        if (loader != null) {
+            img = loader.loadImage(fileName, display);
+        }
+
+        if (img == null) {
+            Log.w("ddms", "Couldn't load " + fileName);
+            // if we had the extra parameter to create replacement image then we
+            // create and return it.
+            if (width != -1 && height != -1) {
+                return createPlaceHolderArt(display, width, height,
+                        phColor != null ? phColor : display
+                                .getSystemColor(SWT.COLOR_BLUE));
+            }
+
+            // otherwise, just return null
+            return null;
+        }
+
+        return img;
+    }
+
+    /**
+     * Create place-holder art with the specified color.
+     */
+    public static Image createPlaceHolderArt(Display display, int width,
+            int height, Color color) {
+        Image img = new Image(display, width, height);
+        GC gc = new GC(img);
+        gc.setForeground(color);
+        gc.drawLine(0, 0, width, height);
+        gc.drawLine(0, height - 1, width, -1);
+        gc.dispose();
+        return img;
+    }
+
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ImageLoader.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ImageLoader.java
new file mode 100644
index 0000000..76f2285
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ImageLoader.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+import java.io.InputStream;
+
+/**
+ * Image loader for an normal standalone app.
+ */
+public class ImageLoader implements IImageLoader {
+
+    /** class used as reference to get the reources */
+    private Class<?> mClass;
+
+    /**
+     * Creates a loader for a specific class. The class allows java to figure
+     * out which .jar file to search for the image.
+     *
+     * @param theClass
+     */
+    public ImageLoader(Class<?> theClass) {
+        mClass = theClass;
+    }
+
+    public ImageDescriptor loadDescriptor(String filename, Display display) {
+        // we don't support ImageDescriptor
+        return null;
+    }
+
+    public Image loadImage(String filename, Display display) {
+
+        String tmp = "/images/" + filename;
+        InputStream imageStream = mClass.getResourceAsStream(tmp);
+
+        if (imageStream != null) {
+            Image img = new Image(display, imageStream);
+            if (img == null)
+                throw new NullPointerException("couldn't load " + tmp);
+            return img;
+        }
+
+        return null;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/InfoPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/InfoPanel.java
new file mode 100644
index 0000000..72cbb4a
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/InfoPanel.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.Client;
+import com.android.ddmlib.ClientData;
+import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * Display client info in a two-column format.
+ */
+public class InfoPanel extends TablePanel {
+    private Table mTable;
+    private TableColumn mCol2;
+
+    private static final String mLabels[] = {
+        "DDM-aware?",
+        "App description:",
+        "VM version:",
+        "Process ID:",
+    };
+    private static final int ENT_DDM_AWARE = 0;
+    private static final int ENT_APP_DESCR = 1;
+    private static final int ENT_VM_VERSION = 2;
+    private static final int ENT_PROCESS_ID = 3;
+
+    /**
+     * Create our control(s).
+     */
+    @Override
+    protected Control createControl(Composite parent) {
+        mTable = new Table(parent, SWT.MULTI | SWT.FULL_SELECTION);
+        mTable.setHeaderVisible(false);
+        mTable.setLinesVisible(false);
+
+        TableColumn col1 = new TableColumn(mTable, SWT.RIGHT);
+        col1.setText("name");
+        mCol2 = new TableColumn(mTable, SWT.LEFT);
+        mCol2.setText("PlaceHolderContentForWidth");
+
+        TableItem item;
+        for (int i = 0; i < mLabels.length; i++) {
+            item = new TableItem(mTable, SWT.NONE);
+            item.setText(0, mLabels[i]);
+            item.setText(1, "-");
+        }
+
+        col1.pack();
+        mCol2.pack();
+
+        return mTable;
+    }
+    
+    /**
+     * Sets the focus to the proper control inside the panel.
+     */
+    @Override
+    public void setFocus() {
+        mTable.setFocus();
+    }
+
+
+    /**
+     * Sent when an existing client information changed.
+     * <p/>
+     * This is sent from a non UI thread.
+     * @param client the updated client.
+     * @param changeMask the bit mask describing the changed properties. It can contain
+     * any of the following values: {@link Client#CHANGE_PORT}, {@link Client#CHANGE_NAME}
+     * {@link Client#CHANGE_DEBUGGER_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) {
+        if (client == getCurrentClient()) {
+            if ((changeMask & Client.CHANGE_INFO) == Client.CHANGE_INFO) {
+                if (mTable.isDisposed())
+                    return;
+
+                mTable.getDisplay().asyncExec(new Runnable() {
+                    public void run() {
+                        clientSelected();
+                    }
+                });
+            }
+        }
+    }
+
+
+    /**
+     * Sent when a new device is selected. The new device can be accessed
+     * with {@link #getCurrentDevice()}
+     */
+    @Override
+    public void deviceSelected() {
+        // pass
+    }
+
+    /**
+     * Sent when a new client is selected. The new client can be accessed
+     * with {@link #getCurrentClient()}
+     */
+    @Override
+    public void clientSelected() {
+        if (mTable.isDisposed())
+            return;
+
+        Client client = getCurrentClient();
+
+        if (client == null) {
+            for (int i = 0; i < mLabels.length; i++) {
+                TableItem item = mTable.getItem(i);
+                item.setText(1, "-");
+            }
+        } else {
+            TableItem item;
+            String clientDescription, vmIdentifier, isDdmAware,
+                pid;
+
+            ClientData cd = client.getClientData();
+            synchronized (cd) {
+                clientDescription = (cd.getClientDescription() != null) ?
+                        cd.getClientDescription() : "?";
+                vmIdentifier = (cd.getVmIdentifier() != null) ?
+                        cd.getVmIdentifier() : "?";
+                isDdmAware = cd.isDdmAware() ?
+                        "yes" : "no";
+                pid = (cd.getPid() != 0) ?
+                        String.valueOf(cd.getPid()) : "?";
+            }
+
+            item = mTable.getItem(ENT_APP_DESCR);
+            item.setText(1, clientDescription);
+            item = mTable.getItem(ENT_VM_VERSION);
+            item.setText(1, vmIdentifier);
+            item = mTable.getItem(ENT_DDM_AWARE);
+            item.setText(1, isDdmAware);
+            item = mTable.getItem(ENT_PROCESS_ID);
+            item.setText(1, pid);
+        }
+
+        mCol2.pack();
+
+        //Log.i("ddms", "InfoPanel: changed " + client);
+    }
+
+    @Override
+    protected void setTableFocusListener() {
+        addTableToFocusListener(mTable);
+    }
+}
+
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java
new file mode 100644
index 0000000..46461bf
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java
@@ -0,0 +1,1633 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.Client;
+import com.android.ddmlib.ClientData;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.NativeAllocationInfo;
+import com.android.ddmlib.NativeLibraryMapInfo;
+import com.android.ddmlib.NativeStackCallInfo;
+import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
+import com.android.ddmlib.HeapSegment.HeapSegmentElement;
+import com.android.ddmuilib.annotation.WorkerThread;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Sash;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * Panel with native heap information.
+ */
+public final class NativeHeapPanel extends BaseHeapPanel {
+
+    /** color palette and map legend. NATIVE is the last enum is a 0 based enum list, so we need
+     * Native+1 at least. We also need 2 more entries for free area and expansion area.  */
+    private static final int NUM_PALETTE_ENTRIES = HeapSegmentElement.KIND_NATIVE+2 +1;
+    private static final String[] mMapLegend = new String[NUM_PALETTE_ENTRIES];
+    private static final PaletteData mMapPalette = createPalette();
+    
+    private static final int ALLOC_DISPLAY_ALL = 0;
+    private static final int ALLOC_DISPLAY_PRE_ZYGOTE = 1;
+    private static final int ALLOC_DISPLAY_POST_ZYGOTE = 2;
+
+    private Display mDisplay;
+
+    private Composite mBase;
+
+    private Label mUpdateStatus;
+
+    /** combo giving choice of what to display: all, pre-zygote, post-zygote */
+    private Combo mAllocDisplayCombo;
+
+    private Button mFullUpdateButton;
+
+    // see CreateControl()
+    //private Button mDiffUpdateButton;
+
+    private Combo mDisplayModeCombo;
+
+    /** stack composite for mode (1-2) & 3 */
+    private Composite mTopStackComposite;
+
+    private StackLayout mTopStackLayout;
+
+    /** stack composite for mode 1 & 2 */
+    private Composite mAllocationStackComposite;
+
+    private StackLayout mAllocationStackLayout;
+
+    /** top level container for mode 1 & 2 */
+    private Composite mTableModeControl;
+
+    /** top level object for the allocation mode */
+    private Control mAllocationModeTop;
+
+    /** top level for the library mode */
+    private Control mLibraryModeTopControl;
+
+    /** composite for page UI and total memory display */
+    private Composite mPageUIComposite;
+
+    private Label mTotalMemoryLabel;
+
+    private Label mPageLabel;
+
+    private Button mPageNextButton;
+
+    private Button mPagePreviousButton;
+
+    private Table mAllocationTable;
+
+    private Table mLibraryTable;
+
+    private Table mLibraryAllocationTable;
+
+    private Table mDetailTable;
+
+    private Label mImage;
+    
+    private int mAllocDisplayMode = ALLOC_DISPLAY_ALL;
+
+    /**
+     * pointer to current stackcall thread computation in order to quit it if
+     * required (new update requested)
+     */
+    private StackCallThread mStackCallThread;
+
+    /** Current Library Allocation table fill thread. killed if selection changes */
+    private FillTableThread mFillTableThread;
+
+    /**
+     * current client data. Used to access the malloc info when switching pages
+     * or selecting allocation to show stack call
+     */
+    private ClientData mClientData;
+
+    /**
+     * client data from a previous display. used when asking for an "update & diff"
+     */
+    private ClientData mBackUpClientData;
+
+    /** list of NativeAllocationInfo objects filled with the list from ClientData */
+    private final ArrayList<NativeAllocationInfo> mAllocations =
+        new ArrayList<NativeAllocationInfo>();
+    
+    /** list of the {@link NativeAllocationInfo} being displayed based on the selection
+     * of {@link #mAllocDisplayCombo}.
+     */
+    private final ArrayList<NativeAllocationInfo> mDisplayedAllocations =
+        new ArrayList<NativeAllocationInfo>();
+
+    /** list of NativeAllocationInfo object kept as backup when doing an "update & diff" */
+    private final ArrayList<NativeAllocationInfo> mBackUpAllocations =
+        new ArrayList<NativeAllocationInfo>();
+
+    /** back up of the total memory, used when doing an "update & diff" */
+    private int mBackUpTotalMemory;
+
+    private int mCurrentPage = 0;
+
+    private int mPageCount = 0;
+
+    /**
+     * list of allocation per Library. This is created from the list of
+     * NativeAllocationInfo objects that is stored in the ClientData object. Since we
+     * don't keep this list around, it is recomputed everytime the client
+     * changes.
+     */
+    private final ArrayList<LibraryAllocations> mLibraryAllocations =
+        new ArrayList<LibraryAllocations>();
+
+    /* args to setUpdateStatus() */
+    private static final int NOT_SELECTED = 0;
+
+    private static final int NOT_ENABLED = 1;
+
+    private static final int ENABLED = 2;
+
+    private static final int DISPLAY_PER_PAGE = 20;
+
+    private static final String PREFS_ALLOCATION_SASH = "NHallocSash"; //$NON-NLS-1$
+    private static final String PREFS_LIBRARY_SASH = "NHlibrarySash"; //$NON-NLS-1$
+    private static final String PREFS_DETAIL_ADDRESS = "NHdetailAddress"; //$NON-NLS-1$
+    private static final String PREFS_DETAIL_LIBRARY = "NHdetailLibrary"; //$NON-NLS-1$
+    private static final String PREFS_DETAIL_METHOD = "NHdetailMethod"; //$NON-NLS-1$
+    private static final String PREFS_DETAIL_FILE = "NHdetailFile"; //$NON-NLS-1$
+    private static final String PREFS_DETAIL_LINE = "NHdetailLine"; //$NON-NLS-1$
+    private static final String PREFS_ALLOC_TOTAL = "NHallocTotal"; //$NON-NLS-1$
+    private static final String PREFS_ALLOC_COUNT = "NHallocCount"; //$NON-NLS-1$
+    private static final String PREFS_ALLOC_SIZE = "NHallocSize"; //$NON-NLS-1$
+    private static final String PREFS_ALLOC_LIBRARY = "NHallocLib"; //$NON-NLS-1$
+    private static final String PREFS_ALLOC_METHOD = "NHallocMethod"; //$NON-NLS-1$
+    private static final String PREFS_ALLOC_FILE = "NHallocFile"; //$NON-NLS-1$
+    private static final String PREFS_LIB_LIBRARY = "NHlibLibrary"; //$NON-NLS-1$
+    private static final String PREFS_LIB_SIZE = "NHlibSize"; //$NON-NLS-1$
+    private static final String PREFS_LIB_COUNT = "NHlibCount"; //$NON-NLS-1$
+    private static final String PREFS_LIBALLOC_TOTAL = "NHlibAllocTotal"; //$NON-NLS-1$
+    private static final String PREFS_LIBALLOC_COUNT = "NHlibAllocCount"; //$NON-NLS-1$
+    private static final String PREFS_LIBALLOC_SIZE = "NHlibAllocSize"; //$NON-NLS-1$
+    private static final String PREFS_LIBALLOC_METHOD = "NHlibAllocMethod"; //$NON-NLS-1$
+
+    /** static formatter object to format all numbers as #,### */
+    private static DecimalFormat sFormatter;
+    static {
+        sFormatter = (DecimalFormat)NumberFormat.getInstance();
+        if (sFormatter != null)
+            sFormatter = new DecimalFormat("#,###");
+        else
+            sFormatter.applyPattern("#,###");
+    }
+
+
+    /**
+     * caching mechanism to avoid recomputing the backtrace for a particular
+     * address several times.
+     */
+    private HashMap<Long, NativeStackCallInfo> mSourceCache =
+        new HashMap<Long,NativeStackCallInfo>();
+    private long mTotalSize;
+    private Button mSaveButton;
+    private Button mSymbolsButton;
+
+    /**
+     * thread class to convert the address call into method, file and line
+     * number in the background.
+     */
+    private class StackCallThread extends BackgroundThread {
+        private ClientData mClientData;
+
+        public StackCallThread(ClientData cd) {
+            mClientData = cd;
+        }
+
+        public ClientData getClientData() {
+            return mClientData;
+        }
+
+        @Override
+        public void run() {
+            // loop through all the NativeAllocationInfo and init them
+            Iterator<NativeAllocationInfo> iter = mAllocations.iterator();
+            int total = mAllocations.size();
+            int count = 0;
+            while (iter.hasNext()) {
+
+                if (isQuitting())
+                    return;
+
+                NativeAllocationInfo info = iter.next();
+                if (info.isStackCallResolved() == false) {
+                    final Long[] list = info.getStackCallAddresses();
+                    final int size = list.length;
+                    
+                    ArrayList<NativeStackCallInfo> resolvedStackCall =
+                        new ArrayList<NativeStackCallInfo>(); 
+
+                    for (int i = 0; i < size; i++) {
+                        long addr = list[i];
+
+                        // first check if the addr has already been converted.
+                        NativeStackCallInfo source = mSourceCache.get(addr);
+
+                        // if not we convert it
+                        if (source == null) {
+                            source = sourceForAddr(addr);
+                            mSourceCache.put(addr, source);
+                        }
+
+                        resolvedStackCall.add(source);
+                    }
+                    
+                    info.setResolvedStackCall(resolvedStackCall);
+                }
+                // after every DISPLAY_PER_PAGE we ask for a ui refresh, unless
+                // we reach total, since we also do it after the loop
+                // (only an issue in case we have a perfect number of page)
+                count++;
+                if ((count % DISPLAY_PER_PAGE) == 0 && count != total) {
+                    if (updateNHAllocationStackCalls(mClientData, count) == false) {
+                        // looks like the app is quitting, so we just
+                        // stopped the thread
+                        return;
+                    }
+                }
+            }
+
+            updateNHAllocationStackCalls(mClientData, count);
+        }
+
+        private NativeStackCallInfo sourceForAddr(long addr) {
+            NativeLibraryMapInfo library = getLibraryFor(addr);
+
+            if (library != null) {
+
+                Addr2Line process = Addr2Line.getProcess(library.getLibraryName());
+                if (process != null) {
+                    // remove the base of the library address
+                    long value = addr - library.getStartAddress();
+                    NativeStackCallInfo info = process.getAddress(value);
+                    if (info != null) {
+                        return info;
+                    }
+                }
+            }
+
+            return new NativeStackCallInfo(library != null ? library.getLibraryName() : null,
+                    Long.toHexString(addr), "");
+        }
+
+        private NativeLibraryMapInfo getLibraryFor(long addr) {
+            Iterator<NativeLibraryMapInfo> it = mClientData.getNativeLibraryMapInfo();
+
+            while (it.hasNext()) {
+                NativeLibraryMapInfo info = it.next();
+
+                if (info.isWithinLibrary(addr)) {
+                    return info;
+                }
+            }
+
+            Log.d("ddm-nativeheap", "Failed finding Library for " + Long.toHexString(addr));
+            return null;
+        }
+
+        /**
+         * update the Native Heap panel with the amount of allocation for which the
+         * stack call has been computed. This is called from a non UI thread, but
+         * will be executed in the UI thread.
+         *
+         * @param count the amount of allocation
+         * @return false if the display was disposed and the update couldn't happen
+         */
+        private boolean updateNHAllocationStackCalls(final ClientData clientData, final int count) {
+            if (mDisplay.isDisposed() == false) {
+                mDisplay.asyncExec(new Runnable() {
+                    public void run() {
+                        updateAllocationStackCalls(clientData, count);
+                    }
+                });
+                return true;
+            }
+            return false;
+        }
+    }
+
+    private class FillTableThread extends BackgroundThread {
+        private LibraryAllocations mLibAlloc;
+
+        private int mMax;
+
+        public FillTableThread(LibraryAllocations liballoc, int m) {
+            mLibAlloc = liballoc;
+            mMax = m;
+        }
+
+        @Override
+        public void run() {
+            for (int i = mMax; i > 0 && isQuitting() == false; i -= 10) {
+                updateNHLibraryAllocationTable(mLibAlloc, mMax - i, mMax - i + 10);
+            }
+        }
+
+        /**
+         * updates the library allocation table in the Native Heap panel. This is
+         * called from a non UI thread, but will be executed in the UI thread.
+         *
+         * @param liballoc the current library allocation object being displayed
+         * @param start start index of items that need to be displayed
+         * @param end end index of the items that need to be displayed
+         */
+        private void updateNHLibraryAllocationTable(final LibraryAllocations libAlloc,
+                final int start, final int end) {
+            if (mDisplay.isDisposed() == false) {
+                mDisplay.asyncExec(new Runnable() {
+                    public void run() {
+                        updateLibraryAllocationTable(libAlloc, start, end);
+                    }
+                });
+            }
+
+        }
+    }
+
+    /** class to aggregate allocations per library */
+    public static class LibraryAllocations {
+        private String mLibrary;
+
+        private final ArrayList<NativeAllocationInfo> mLibAllocations =
+            new ArrayList<NativeAllocationInfo>();
+
+        private int mSize;
+
+        private int mCount;
+
+        /** construct the aggregate object for a library */
+        public LibraryAllocations(final String lib) {
+            mLibrary = lib;
+        }
+
+        /** get the library name */
+        public String getLibrary() {
+            return mLibrary;
+        }
+
+        /** add a NativeAllocationInfo object to this aggregate object */
+        public void addAllocation(NativeAllocationInfo info) {
+            mLibAllocations.add(info);
+        }
+
+        /** get an iterator on the NativeAllocationInfo objects */
+        public Iterator<NativeAllocationInfo> getAllocations() {
+            return mLibAllocations.iterator();
+        }
+
+        /** get a NativeAllocationInfo object by index */
+        public NativeAllocationInfo getAllocation(int index) {
+            return mLibAllocations.get(index);
+        }
+
+        /** returns the NativeAllocationInfo object count */
+        public int getAllocationSize() {
+            return mLibAllocations.size();
+        }
+
+        /** returns the total allocation size */
+        public int getSize() {
+            return mSize;
+        }
+
+        /** returns the number of allocations */
+        public int getCount() {
+            return mCount;
+        }
+
+        /**
+         * compute the allocation count and size for allocation objects added
+         * through <code>addAllocation()</code>, and sort the objects by
+         * total allocation size.
+         */
+        public void computeAllocationSizeAndCount() {
+            mSize = 0;
+            mCount = 0;
+            for (NativeAllocationInfo info : mLibAllocations) {
+                mCount += info.getAllocationCount();
+                mSize += info.getAllocationCount() * info.getSize();
+            }
+            Collections.sort(mLibAllocations, new Comparator<NativeAllocationInfo>() {
+                public int compare(NativeAllocationInfo o1, NativeAllocationInfo o2) {
+                    return o2.getAllocationCount() * o2.getSize() -
+                        o1.getAllocationCount() * o1.getSize();
+                }
+            });
+        }
+    }
+
+    /**
+     * Create our control(s).
+     */
+    @Override
+    protected Control createControl(Composite parent) {
+
+        mDisplay = parent.getDisplay();
+
+        mBase = new Composite(parent, SWT.NONE);
+        GridLayout gl = new GridLayout(1, false);
+        gl.horizontalSpacing = 0;
+        gl.verticalSpacing = 0;
+        mBase.setLayout(gl);
+        mBase.setLayoutData(new GridData(GridData.FILL_BOTH));
+        
+        // composite for <update btn> <status>
+        Composite tmp = new Composite(mBase, SWT.NONE);
+        tmp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        tmp.setLayout(gl = new GridLayout(2, false));
+        gl.marginWidth = gl.marginHeight = 0;
+
+        mFullUpdateButton = new Button(tmp, SWT.NONE);
+        mFullUpdateButton.setText("Full Update");
+        mFullUpdateButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mBackUpClientData = null;
+                mDisplayModeCombo.setEnabled(false);
+                mSaveButton.setEnabled(false);
+                emptyTables();
+                // if we already have a stack call computation for this
+                // client
+                // we stop it
+                if (mStackCallThread != null &&
+                        mStackCallThread.getClientData() == mClientData) {
+                    mStackCallThread.quit();
+                    mStackCallThread = null;
+                }
+                mLibraryAllocations.clear();
+                Client client = getCurrentClient();
+                if (client != null) {
+                    client.requestNativeHeapInformation();
+                }
+            }
+        });
+
+        mUpdateStatus = new Label(tmp, SWT.NONE);
+        mUpdateStatus.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        // top layout for the combos and oter controls on the right.
+        Composite top_layout = new Composite(mBase, SWT.NONE);
+        top_layout.setLayout(gl = new GridLayout(4, false));
+        gl.marginWidth = gl.marginHeight = 0;
+        
+        new Label(top_layout, SWT.NONE).setText("Show:");
+        
+        mAllocDisplayCombo = new Combo(top_layout, SWT.DROP_DOWN | SWT.READ_ONLY);
+        mAllocDisplayCombo.setLayoutData(new GridData(
+                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
+        mAllocDisplayCombo.add("All Allocations");
+        mAllocDisplayCombo.add("Pre-Zygote Allocations");
+        mAllocDisplayCombo.add("Zygote Child Allocations (Z)");
+        mAllocDisplayCombo.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                onAllocDisplayChange();
+            }
+        });
+        mAllocDisplayCombo.select(0);
+        
+        // separator
+        Label separator = new Label(top_layout, SWT.SEPARATOR | SWT.VERTICAL);
+        GridData gd;
+        separator.setLayoutData(gd = new GridData(
+                GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
+        gd.heightHint = 0;
+        gd.verticalSpan = 2;
+
+        mSaveButton = new Button(top_layout, SWT.PUSH);
+        mSaveButton.setText("Save...");
+        mSaveButton.setEnabled(false);
+        mSaveButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                FileDialog fileDialog = new FileDialog(mBase.getShell(), SWT.SAVE);
+
+                fileDialog.setText("Save Allocations");
+                fileDialog.setFileName("allocations.txt");
+
+                String fileName = fileDialog.open();
+                if (fileName != null) {
+                    saveAllocations(fileName);
+                }
+            }
+        });
+        
+        /*
+         * TODO: either fix the diff mechanism or remove it altogether.
+        mDiffUpdateButton = new Button(top_layout, SWT.NONE);
+        mDiffUpdateButton.setText("Update && Diff");
+        mDiffUpdateButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // since this is an update and diff, we need to store the
+                // current list
+                // of mallocs
+                mBackUpAllocations.clear();
+                mBackUpAllocations.addAll(mAllocations);
+                mBackUpClientData = mClientData;
+                mBackUpTotalMemory = mClientData.getTotalNativeMemory();
+
+                mDisplayModeCombo.setEnabled(false);
+                emptyTables();
+                // if we already have a stack call computation for this
+                // client
+                // we stop it
+                if (mStackCallThread != null &&
+                        mStackCallThread.getClientData() == mClientData) {
+                    mStackCallThread.quit();
+                    mStackCallThread = null;
+                }
+                mLibraryAllocations.clear();
+                Client client = getCurrentClient();
+                if (client != null) {
+                    client.requestNativeHeapInformation();
+                }
+            }
+        });
+        */
+
+        Label l = new Label(top_layout, SWT.NONE);
+        l.setText("Display:");
+
+        mDisplayModeCombo = new Combo(top_layout, SWT.DROP_DOWN | SWT.READ_ONLY);
+        mDisplayModeCombo.setLayoutData(new GridData(
+                GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
+        mDisplayModeCombo.setItems(new String[] { "Allocation List", "By Libraries" });
+        mDisplayModeCombo.select(0);
+        mDisplayModeCombo.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                switchDisplayMode();
+            }
+        });
+        mDisplayModeCombo.setEnabled(false);
+        
+        mSymbolsButton = new Button(top_layout, SWT.PUSH);
+        mSymbolsButton.setText("Load Symbols");
+        mSymbolsButton.setEnabled(false);
+
+
+        // create a composite that will contains the actual content composites,
+        // in stack mode layout.
+        // This top level composite contains 2 other composites.
+        // * one for both Allocations and Libraries mode
+        // * one for flat mode (which is gone for now)
+
+        mTopStackComposite = new Composite(mBase, SWT.NONE);
+        mTopStackComposite.setLayout(mTopStackLayout = new StackLayout());
+        mTopStackComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        // create 1st and 2nd modes
+        createTableDisplay(mTopStackComposite);
+
+        mTopStackLayout.topControl = mTableModeControl;
+        mTopStackComposite.layout();
+
+        setUpdateStatus(NOT_SELECTED);
+
+        // Work in progress
+        // TODO add image display of native heap.
+        //mImage = new Label(mBase, SWT.NONE);
+
+        mBase.pack();
+
+        return mBase;
+    }
+    
+    /**
+     * Sets the focus to the proper control inside the panel.
+     */
+    @Override
+    public void setFocus() {
+        // TODO
+    }
+
+
+    /**
+     * Sent when an existing client information changed.
+     * <p/>
+     * This is sent from a non UI thread.
+     * @param client the updated client.
+     * @param changeMask the bit mask describing the changed properties. It can contain
+     * any of the following values: {@link Client#CHANGE_INFO}, {@link Client#CHANGE_NAME}
+     * {@link Client#CHANGE_DEBUGGER_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) {
+        if (client == getCurrentClient()) {
+            if ((changeMask & Client.CHANGE_NATIVE_HEAP_DATA) == Client.CHANGE_NATIVE_HEAP_DATA) {
+                if (mBase.isDisposed())
+                    return;
+
+                mBase.getDisplay().asyncExec(new Runnable() {
+                    public void run() {
+                        clientSelected();
+                    }
+                });
+            }
+        }
+    }
+
+    /**
+     * Sent when a new device is selected. The new device can be accessed
+     * with {@link #getCurrentDevice()}.
+     */
+    @Override
+    public void deviceSelected() {
+        // pass
+    }
+
+    /**
+     * Sent when a new client is selected. The new client can be accessed
+     * with {@link #getCurrentClient()}.
+     */
+    @Override
+    public void clientSelected() {
+        if (mBase.isDisposed())
+            return;
+
+        Client client = getCurrentClient();
+
+        mDisplayModeCombo.setEnabled(false);
+        emptyTables();
+
+        Log.d("ddms", "NativeHeapPanel: changed " + client);
+
+        if (client != null) {
+            ClientData cd = client.getClientData();
+            mClientData = cd;
+
+            // if (cd.getShowHeapUpdates())
+            setUpdateStatus(ENABLED);
+            // else
+            // setUpdateStatus(NOT_ENABLED);
+
+            initAllocationDisplay();
+
+            //renderBitmap(cd);
+        } else {
+            mClientData = null;
+            setUpdateStatus(NOT_SELECTED);
+        }
+
+        mBase.pack();
+    }
+
+    /**
+     * Update the UI with the newly compute stack calls, unless the UI switched
+     * to a different client.
+     *
+     * @param cd the ClientData for which the stack call are being computed.
+     * @param count the current count of allocations for which the stack calls
+     *            have been computed.
+     */
+    @WorkerThread
+    public void updateAllocationStackCalls(ClientData cd, int count) {
+        // we have to check that the panel still shows the same clientdata than
+        // the thread is computing for.
+        if (cd == mClientData) {
+
+            int total = mAllocations.size();
+
+            if (count == total) {
+                // we're done: do something
+                mDisplayModeCombo.setEnabled(true);
+                mSaveButton.setEnabled(true);
+                
+                mStackCallThread = null;
+            } else {
+                // work in progress, update the progress bar.
+//                mUiThread.setStatusLine("Computing stack call: " + count
+//                        + "/" + total);
+            }
+
+            // FIXME: attempt to only update when needed.
+            // Because the number of pages is not related to mAllocations.size() anymore
+            // due to pre-zygote/post-zygote display, update all the time.
+            // At some point we should remove the pages anyway, since it's getting computed
+            // really fast now.
+//            if ((mCurrentPage + 1) * DISPLAY_PER_PAGE == count
+//                    || (count == total && mCurrentPage == mPageCount - 1)) {
+            try {
+                // get the current selection of the allocation
+                int index = mAllocationTable.getSelectionIndex();
+                NativeAllocationInfo info = null;
+                
+                if (index != -1) {
+                    info = (NativeAllocationInfo)mAllocationTable.getItem(index).getData();
+                }
+
+                // empty the table
+                emptyTables();
+
+                // fill it again
+                fillAllocationTable();
+
+                // reselect
+                mAllocationTable.setSelection(index);
+
+                // display detail table if needed
+                if (info != null) {
+                    fillDetailTable(info);
+                }
+            } catch (SWTException e) {
+                if (mAllocationTable.isDisposed()) {
+                    // looks like the table is disposed. Let's ignore it.
+                } else {
+                    throw e;
+                }
+            }
+
+        } else {
+            // old client still running. doesn't really matter.
+        }
+    }
+
+    @Override
+    protected void setTableFocusListener() {
+        addTableToFocusListener(mAllocationTable);
+        addTableToFocusListener(mLibraryTable);
+        addTableToFocusListener(mLibraryAllocationTable);
+        addTableToFocusListener(mDetailTable);
+    }
+    
+    protected void onAllocDisplayChange() {
+        mAllocDisplayMode = mAllocDisplayCombo.getSelectionIndex();
+        
+        // create the new list
+        updateAllocDisplayList();
+        
+        updateTotalMemoryDisplay();
+
+        // reset the ui.
+        mCurrentPage = 0;
+        updatePageUI();
+        switchDisplayMode();
+    }
+    
+    private void updateAllocDisplayList() {
+        mTotalSize = 0;
+        mDisplayedAllocations.clear();
+        for (NativeAllocationInfo info : mAllocations) {
+            if (mAllocDisplayMode == ALLOC_DISPLAY_ALL ||
+                    (mAllocDisplayMode == ALLOC_DISPLAY_PRE_ZYGOTE ^ info.isZygoteChild())) {
+                mDisplayedAllocations.add(info);
+                mTotalSize += info.getSize() * info.getAllocationCount();
+            } else {
+                // skip this item
+                continue;
+            }
+        }
+        
+        int count = mDisplayedAllocations.size();
+        
+        mPageCount = count / DISPLAY_PER_PAGE;
+
+        // need to add a page for the rest of the div
+        if ((count % DISPLAY_PER_PAGE) > 0) {
+            mPageCount++;
+        }
+    }
+    
+    private void updateTotalMemoryDisplay() {
+        switch (mAllocDisplayMode) {
+            case ALLOC_DISPLAY_ALL:
+                mTotalMemoryLabel.setText(String.format("Total Memory: %1$s Bytes",
+                        sFormatter.format(mTotalSize)));
+                break;
+            case ALLOC_DISPLAY_PRE_ZYGOTE:
+                mTotalMemoryLabel.setText(String.format("Zygote Memory: %1$s Bytes",
+                        sFormatter.format(mTotalSize)));
+                break;
+            case ALLOC_DISPLAY_POST_ZYGOTE:
+                mTotalMemoryLabel.setText(String.format("Post-zygote Memory: %1$s Bytes",
+                        sFormatter.format(mTotalSize)));
+                break;
+        }
+    }
+
+
+    private void switchDisplayMode() {
+        switch (mDisplayModeCombo.getSelectionIndex()) {
+            case 0: {// allocations
+                mTopStackLayout.topControl = mTableModeControl;
+                mAllocationStackLayout.topControl = mAllocationModeTop;
+                mAllocationStackComposite.layout();
+                mTopStackComposite.layout();
+                emptyTables();
+                fillAllocationTable();
+            }
+                break;
+            case 1: {// libraries
+                mTopStackLayout.topControl = mTableModeControl;
+                mAllocationStackLayout.topControl = mLibraryModeTopControl;
+                mAllocationStackComposite.layout();
+                mTopStackComposite.layout();
+                emptyTables();
+                fillLibraryTable();
+            }
+                break;
+        }
+    }
+
+    private void initAllocationDisplay() {
+        mAllocations.clear();
+        mAllocations.addAll(mClientData.getNativeAllocationList());
+        
+        updateAllocDisplayList();
+
+        // if we have a previous clientdata and it matches the current one. we
+        // do a diff between the new list and the old one.
+        if (mBackUpClientData != null && mBackUpClientData == mClientData) {
+
+            ArrayList<NativeAllocationInfo> add = new ArrayList<NativeAllocationInfo>();
+
+            // we go through the list of NativeAllocationInfo in the new list and check if
+            // there's one with the same exact data (size, allocation, count and
+            // stackcall addresses) in the old list.
+            // if we don't find any, we add it to the "add" list
+            for (NativeAllocationInfo mi : mAllocations) {
+                boolean found = false;
+                for (NativeAllocationInfo old_mi : mBackUpAllocations) {
+                    if (mi.equals(old_mi)) {
+                        found = true;
+                        break;
+                    }
+                }
+                if (found == false) {
+                    add.add(mi);
+                }
+            }
+
+            // put the result in mAllocations
+            mAllocations.clear();
+            mAllocations.addAll(add);
+
+            // display the difference in memory usage. This is computed
+            // calculating the memory usage of the objects in mAllocations.
+            int count = 0;
+            for (NativeAllocationInfo allocInfo : mAllocations) {
+                count += allocInfo.getSize() * allocInfo.getAllocationCount();
+            }
+
+            mTotalMemoryLabel.setText(String.format("Memory Difference: %1$s Bytes",
+                    sFormatter.format(count)));
+        }
+        else {
+            // display the full memory usage
+            updateTotalMemoryDisplay();
+            //mDiffUpdateButton.setEnabled(mClientData.getTotalNativeMemory() > 0);
+        }
+        mTotalMemoryLabel.pack();
+
+        // update the page ui
+        mDisplayModeCombo.select(0);
+
+        mLibraryAllocations.clear();
+
+        // reset to first page
+        mCurrentPage = 0;
+
+        // update the label
+        updatePageUI();
+
+        // now fill the allocation Table with the current page
+        switchDisplayMode();
+
+        // start the thread to compute the stack calls
+        if (mAllocations.size() > 0) {
+            mStackCallThread = new StackCallThread(mClientData);
+            mStackCallThread.start();
+        }
+    }
+
+    private void updatePageUI() {
+
+        // set the label and pack to update the layout, otherwise
+        // the label will be cut off if the new size is bigger
+        if (mPageCount == 0) {
+            mPageLabel.setText("0 of 0 allocations.");
+        } else {
+            StringBuffer buffer = new StringBuffer();
+            // get our starting index
+            int start = (mCurrentPage * DISPLAY_PER_PAGE) + 1;
+            // end index, taking into account the last page can be half full
+            int count = mDisplayedAllocations.size();
+            int end = Math.min(start + DISPLAY_PER_PAGE - 1, count);
+            buffer.append(sFormatter.format(start));
+            buffer.append(" - ");
+            buffer.append(sFormatter.format(end));
+            buffer.append(" of ");
+            buffer.append(sFormatter.format(count));
+            buffer.append(" allocations.");
+            mPageLabel.setText(buffer.toString());
+        }
+
+        // handle the button enabled state.
+        mPagePreviousButton.setEnabled(mCurrentPage > 0);
+        // reminder: mCurrentPage starts at 0.
+        mPageNextButton.setEnabled(mCurrentPage < mPageCount - 1);
+
+        mPageLabel.pack();
+        mPageUIComposite.pack();
+
+    }
+
+    private void fillAllocationTable() {
+        // get the count
+        int count = mDisplayedAllocations.size();
+
+        // get our starting index
+        int start = mCurrentPage * DISPLAY_PER_PAGE;
+
+        // loop for DISPLAY_PER_PAGE or till we reach count
+        int end = start + DISPLAY_PER_PAGE;
+
+        for (int i = start; i < end && i < count; i++) {
+            NativeAllocationInfo info = mDisplayedAllocations.get(i);
+
+            TableItem item = null;
+
+            if (mAllocDisplayMode == ALLOC_DISPLAY_ALL)  {
+                item = new TableItem(mAllocationTable, SWT.NONE);
+                item.setText(0, (info.isZygoteChild() ? "Z " : "") +
+                        sFormatter.format(info.getSize() * info.getAllocationCount()));
+                item.setText(1, sFormatter.format(info.getAllocationCount()));
+                item.setText(2, sFormatter.format(info.getSize()));
+            } else if (mAllocDisplayMode == ALLOC_DISPLAY_PRE_ZYGOTE ^ info.isZygoteChild()) {
+                item = new TableItem(mAllocationTable, SWT.NONE);
+                item.setText(0, sFormatter.format(info.getSize() * info.getAllocationCount()));
+                item.setText(1, sFormatter.format(info.getAllocationCount()));
+                item.setText(2, sFormatter.format(info.getSize()));
+            } else {
+                // skip this item
+                continue;
+            }
+
+            item.setData(info);
+
+            NativeStackCallInfo bti = info.getRelevantStackCallInfo();
+            if (bti != null) {
+                String lib = bti.getLibraryName();
+                String method = bti.getMethodName();
+                String source = bti.getSourceFile();
+                if (lib != null)
+                    item.setText(3, lib);
+                if (method != null)
+                    item.setText(4, method);
+                if (source != null)
+                    item.setText(5, source);
+            }
+        }
+    }
+
+    private void fillLibraryTable() {
+        // fill the library table
+        sortAllocationsPerLibrary();
+
+        for (LibraryAllocations liballoc : mLibraryAllocations) {
+            if (liballoc != null) {
+                TableItem item = new TableItem(mLibraryTable, SWT.NONE);
+                String lib = liballoc.getLibrary();
+                item.setText(0, lib != null ? lib : "");
+                item.setText(1, sFormatter.format(liballoc.getSize()));
+                item.setText(2, sFormatter.format(liballoc.getCount()));
+            }
+        }
+    }
+
+    private void fillLibraryAllocationTable() {
+        mLibraryAllocationTable.removeAll();
+        mDetailTable.removeAll();
+        int index = mLibraryTable.getSelectionIndex();
+        if (index != -1) {
+            LibraryAllocations liballoc = mLibraryAllocations.get(index);
+            // start a thread that will fill table 10 at a time to keep the ui
+            // responsive, but first we kill the previous one if there was one
+            if (mFillTableThread != null) {
+                mFillTableThread.quit();
+            }
+            mFillTableThread = new FillTableThread(liballoc,
+                    liballoc.getAllocationSize());
+            mFillTableThread.start();
+        }
+    }
+
+    public void updateLibraryAllocationTable(LibraryAllocations liballoc,
+            int start, int end) {
+        try {
+            if (mLibraryTable.isDisposed() == false) {
+                int index = mLibraryTable.getSelectionIndex();
+                if (index != -1) {
+                    LibraryAllocations newliballoc = mLibraryAllocations.get(
+                            index);
+                    if (newliballoc == liballoc) {
+                        int count = liballoc.getAllocationSize();
+                        for (int i = start; i < end && i < count; i++) {
+                            NativeAllocationInfo info = liballoc.getAllocation(i);
+
+                            TableItem item = new TableItem(
+                                    mLibraryAllocationTable, SWT.NONE);
+                            item.setText(0, sFormatter.format(
+                                    info.getSize() * info.getAllocationCount()));
+                            item.setText(1, sFormatter.format(info.getAllocationCount()));
+                            item.setText(2, sFormatter.format(info.getSize()));
+
+                            NativeStackCallInfo stackCallInfo = info.getRelevantStackCallInfo();
+                            if (stackCallInfo != null) {
+                                item.setText(3, stackCallInfo.getMethodName());
+                            }
+                        }
+                    } else {
+                        // we should quit the thread
+                        if (mFillTableThread != null) {
+                            mFillTableThread.quit();
+                            mFillTableThread = null;
+                        }
+                    }
+                }
+            }
+        } catch (SWTException e) {
+            Log.e("ddms", "error when updating the library allocation table");
+        }
+    }
+
+    private void fillDetailTable(final NativeAllocationInfo mi) {
+        mDetailTable.removeAll();
+        mDetailTable.setRedraw(false);
+        
+        try {
+            // populate the detail Table with the back trace
+            Long[] addresses = mi.getStackCallAddresses();
+            NativeStackCallInfo[] resolvedStackCall = mi.getResolvedStackCall();
+            
+            if (resolvedStackCall == null) {
+                return;
+            }
+
+            for (int i = 0 ; i < resolvedStackCall.length ; i++) {
+                if (addresses[i] == null || addresses[i].longValue() == 0) {
+                    continue;
+                }
+                
+                long addr = addresses[i].longValue();
+                NativeStackCallInfo source = resolvedStackCall[i];
+                
+                TableItem item = new TableItem(mDetailTable, SWT.NONE);
+                item.setText(0, String.format("%08x", addr)); //$NON-NLS-1$
+    
+                String libraryName = source.getLibraryName();
+                String methodName = source.getMethodName();
+                String sourceFile = source.getSourceFile();
+                int lineNumber = source.getLineNumber();
+                
+                if (libraryName != null)
+                    item.setText(1, libraryName);
+                if (methodName != null)
+                    item.setText(2, methodName);
+                if (sourceFile != null)
+                    item.setText(3, sourceFile);
+                if (lineNumber != -1)
+                    item.setText(4, Integer.toString(lineNumber));
+            }
+        } finally {
+            mDetailTable.setRedraw(true);
+        }
+    }
+
+    /*
+     * Are updates enabled?
+     */
+    private void setUpdateStatus(int status) {
+        switch (status) {
+            case NOT_SELECTED:
+                mUpdateStatus.setText("Select a client to see heap info");
+                mAllocDisplayCombo.setEnabled(false);
+                mFullUpdateButton.setEnabled(false);
+                //mDiffUpdateButton.setEnabled(false);
+                break;
+            case NOT_ENABLED:
+                mUpdateStatus.setText("Heap updates are " + "NOT ENABLED for this client");
+                mAllocDisplayCombo.setEnabled(false);
+                mFullUpdateButton.setEnabled(false);
+                //mDiffUpdateButton.setEnabled(false);
+                break;
+            case ENABLED:
+                mUpdateStatus.setText("Press 'Full Update' to retrieve " + "latest data");
+                mAllocDisplayCombo.setEnabled(true);
+                mFullUpdateButton.setEnabled(true);
+                //mDiffUpdateButton.setEnabled(true);
+                break;
+            default:
+                throw new RuntimeException();
+        }
+
+        mUpdateStatus.pack();
+    }
+
+    /**
+     * Create the Table display. This includes a "detail" Table in the bottom
+     * half and 2 modes in the top half: allocation Table and
+     * library+allocations Tables.
+     *
+     * @param base the top parent to create the display into
+     */
+    private void createTableDisplay(Composite base) {
+        final int minPanelWidth = 60;
+
+        final IPreferenceStore prefs = DdmUiPreferences.getStore();
+
+        // top level composite for mode 1 & 2
+        mTableModeControl = new Composite(base, SWT.NONE);
+        GridLayout gl = new GridLayout(1, false);
+        gl.marginLeft = gl.marginRight = gl.marginTop = gl.marginBottom = 0;
+        mTableModeControl.setLayout(gl);
+        mTableModeControl.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        mTotalMemoryLabel = new Label(mTableModeControl, SWT.NONE);
+        mTotalMemoryLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mTotalMemoryLabel.setText("Total Memory: 0 Bytes");
+
+        // the top half of these modes is dynamic
+
+        final Composite sash_composite = new Composite(mTableModeControl,
+                SWT.NONE);
+        sash_composite.setLayout(new FormLayout());
+        sash_composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        // create the stacked composite
+        mAllocationStackComposite = new Composite(sash_composite, SWT.NONE);
+        mAllocationStackLayout = new StackLayout();
+        mAllocationStackComposite.setLayout(mAllocationStackLayout);
+        mAllocationStackComposite.setLayoutData(new GridData(
+                GridData.FILL_BOTH));
+
+        // create the top half for mode 1
+        createAllocationTopHalf(mAllocationStackComposite);
+
+        // create the top half for mode 2
+        createLibraryTopHalf(mAllocationStackComposite);
+
+        final Sash sash = new Sash(sash_composite, SWT.HORIZONTAL);
+
+        // bottom half of these modes is the same: detail table
+        createDetailTable(sash_composite);
+
+        // init value for stack
+        mAllocationStackLayout.topControl = mAllocationModeTop;
+
+        // form layout data
+        FormData data = new FormData();
+        data.top = new FormAttachment(mTotalMemoryLabel, 0);
+        data.bottom = new FormAttachment(sash, 0);
+        data.left = new FormAttachment(0, 0);
+        data.right = new FormAttachment(100, 0);
+        mAllocationStackComposite.setLayoutData(data);
+
+        final FormData sashData = new FormData();
+        if (prefs != null && prefs.contains(PREFS_ALLOCATION_SASH)) {
+            sashData.top = new FormAttachment(0,
+                    prefs.getInt(PREFS_ALLOCATION_SASH));
+        } else {
+            sashData.top = new FormAttachment(50, 0); // 50% across
+        }
+        sashData.left = new FormAttachment(0, 0);
+        sashData.right = new FormAttachment(100, 0);
+        sash.setLayoutData(sashData);
+
+        data = new FormData();
+        data.top = new FormAttachment(sash, 0);
+        data.bottom = new FormAttachment(100, 0);
+        data.left = new FormAttachment(0, 0);
+        data.right = new FormAttachment(100, 0);
+        mDetailTable.setLayoutData(data);
+
+        // allow resizes, but cap at minPanelWidth
+        sash.addListener(SWT.Selection, new Listener() {
+            public void handleEvent(Event e) {
+                Rectangle sashRect = sash.getBounds();
+                Rectangle panelRect = sash_composite.getClientArea();
+                int bottom = panelRect.height - sashRect.height - minPanelWidth;
+                e.y = Math.max(Math.min(e.y, bottom), minPanelWidth);
+                if (e.y != sashRect.y) {
+                    sashData.top = new FormAttachment(0, e.y);
+                    prefs.setValue(PREFS_ALLOCATION_SASH, e.y);
+                    sash_composite.layout();
+                }
+            }
+        });
+    }
+
+    private void createDetailTable(Composite base) {
+
+        final IPreferenceStore prefs = DdmUiPreferences.getStore();
+
+        mDetailTable = new Table(base, SWT.MULTI | SWT.FULL_SELECTION);
+        mDetailTable.setLayoutData(new GridData(GridData.FILL_BOTH));
+        mDetailTable.setHeaderVisible(true);
+        mDetailTable.setLinesVisible(true);
+
+        TableHelper.createTableColumn(mDetailTable, "Address", SWT.RIGHT,
+                "00000000", PREFS_DETAIL_ADDRESS, prefs); //$NON-NLS-1$
+        TableHelper.createTableColumn(mDetailTable, "Library", SWT.LEFT,
+                "abcdefghijklmnopqrst", PREFS_DETAIL_LIBRARY, prefs); //$NON-NLS-1$
+        TableHelper.createTableColumn(mDetailTable, "Method", SWT.LEFT,
+                "abcdefghijklmnopqrst", PREFS_DETAIL_METHOD, prefs); //$NON-NLS-1$
+        TableHelper.createTableColumn(mDetailTable, "File", SWT.LEFT,
+                "abcdefghijklmnopqrstuvwxyz", PREFS_DETAIL_FILE, prefs); //$NON-NLS-1$
+        TableHelper.createTableColumn(mDetailTable, "Line", SWT.RIGHT,
+                "9,999", PREFS_DETAIL_LINE, prefs); //$NON-NLS-1$
+    }
+
+    private void createAllocationTopHalf(Composite b) {
+        final IPreferenceStore prefs = DdmUiPreferences.getStore();
+
+        Composite base = new Composite(b, SWT.NONE);
+        mAllocationModeTop = base;
+        GridLayout gl = new GridLayout(1, false);
+        gl.marginLeft = gl.marginRight = gl.marginTop = gl.marginBottom = 0;
+        gl.verticalSpacing = 0;
+        base.setLayout(gl);
+        base.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        // horizontal layout for memory total and pages UI
+        mPageUIComposite = new Composite(base, SWT.NONE);
+        mPageUIComposite.setLayoutData(new GridData(
+                GridData.HORIZONTAL_ALIGN_BEGINNING));
+        gl = new GridLayout(3, false);
+        gl.marginLeft = gl.marginRight = gl.marginTop = gl.marginBottom = 0;
+        gl.horizontalSpacing = 0;
+        mPageUIComposite.setLayout(gl);
+
+        // Page UI
+        mPagePreviousButton = new Button(mPageUIComposite, SWT.NONE);
+        mPagePreviousButton.setText("<");
+        mPagePreviousButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mCurrentPage--;
+                updatePageUI();
+                emptyTables();
+                fillAllocationTable();
+            }
+        });
+
+        mPageNextButton = new Button(mPageUIComposite, SWT.NONE);
+        mPageNextButton.setText(">");
+        mPageNextButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mCurrentPage++;
+                updatePageUI();
+                emptyTables();
+                fillAllocationTable();
+            }
+        });
+
+        mPageLabel = new Label(mPageUIComposite, SWT.NONE);
+        mPageLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        updatePageUI();
+
+        mAllocationTable = new Table(base, SWT.MULTI | SWT.FULL_SELECTION);
+        mAllocationTable.setLayoutData(new GridData(GridData.FILL_BOTH));
+        mAllocationTable.setHeaderVisible(true);
+        mAllocationTable.setLinesVisible(true);
+
+        TableHelper.createTableColumn(mAllocationTable, "Total", SWT.RIGHT,
+                "9,999,999", PREFS_ALLOC_TOTAL, prefs); //$NON-NLS-1$
+        TableHelper.createTableColumn(mAllocationTable, "Count", SWT.RIGHT,
+                "9,999", PREFS_ALLOC_COUNT, prefs); //$NON-NLS-1$
+        TableHelper.createTableColumn(mAllocationTable, "Size", SWT.RIGHT,
+                "999,999", PREFS_ALLOC_SIZE, prefs); //$NON-NLS-1$
+        TableHelper.createTableColumn(mAllocationTable, "Library", SWT.LEFT,
+                "abcdefghijklmnopqrst", PREFS_ALLOC_LIBRARY, prefs); //$NON-NLS-1$
+        TableHelper.createTableColumn(mAllocationTable, "Method", SWT.LEFT,
+                "abcdefghijklmnopqrst", PREFS_ALLOC_METHOD, prefs); //$NON-NLS-1$
+        TableHelper.createTableColumn(mAllocationTable, "File", SWT.LEFT,
+                "abcdefghijklmnopqrstuvwxyz", PREFS_ALLOC_FILE, prefs); //$NON-NLS-1$
+
+        mAllocationTable.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // get the selection index
+                int index = mAllocationTable.getSelectionIndex();
+                TableItem item = mAllocationTable.getItem(index);
+                if (item != null && item.getData() instanceof NativeAllocationInfo) {
+                    fillDetailTable((NativeAllocationInfo)item.getData());
+                }
+            }
+        });
+    }
+
+    private void createLibraryTopHalf(Composite base) {
+        final int minPanelWidth = 60;
+
+        final IPreferenceStore prefs = DdmUiPreferences.getStore();
+
+        // create a composite that'll contain 2 tables horizontally
+        final Composite top = new Composite(base, SWT.NONE);
+        mLibraryModeTopControl = top;
+        top.setLayout(new FormLayout());
+        top.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        // first table: library
+        mLibraryTable = new Table(top, SWT.MULTI | SWT.FULL_SELECTION);
+        mLibraryTable.setLayoutData(new GridData(GridData.FILL_BOTH));
+        mLibraryTable.setHeaderVisible(true);
+        mLibraryTable.setLinesVisible(true);
+
+        TableHelper.createTableColumn(mLibraryTable, "Library", SWT.LEFT,
+                "abcdefghijklmnopqrstuvwxyz", PREFS_LIB_LIBRARY, prefs); //$NON-NLS-1$
+        TableHelper.createTableColumn(mLibraryTable, "Size", SWT.RIGHT,
+                "9,999,999", PREFS_LIB_SIZE, prefs); //$NON-NLS-1$
+        TableHelper.createTableColumn(mLibraryTable, "Count", SWT.RIGHT,
+                "9,999", PREFS_LIB_COUNT, prefs); //$NON-NLS-1$
+
+        mLibraryTable.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                fillLibraryAllocationTable();
+            }
+        });
+
+        final Sash sash = new Sash(top, SWT.VERTICAL);
+
+        // 2nd table: allocation per library
+        mLibraryAllocationTable = new Table(top, SWT.MULTI | SWT.FULL_SELECTION);
+        mLibraryAllocationTable.setLayoutData(new GridData(GridData.FILL_BOTH));
+        mLibraryAllocationTable.setHeaderVisible(true);
+        mLibraryAllocationTable.setLinesVisible(true);
+
+        TableHelper.createTableColumn(mLibraryAllocationTable, "Total",
+                SWT.RIGHT, "9,999,999", PREFS_LIBALLOC_TOTAL, prefs); //$NON-NLS-1$
+        TableHelper.createTableColumn(mLibraryAllocationTable, "Count",
+                SWT.RIGHT, "9,999", PREFS_LIBALLOC_COUNT, prefs); //$NON-NLS-1$
+        TableHelper.createTableColumn(mLibraryAllocationTable, "Size",
+                SWT.RIGHT, "999,999", PREFS_LIBALLOC_SIZE, prefs); //$NON-NLS-1$
+        TableHelper.createTableColumn(mLibraryAllocationTable, "Method",
+                SWT.LEFT, "abcdefghijklmnopqrst", PREFS_LIBALLOC_METHOD, prefs); //$NON-NLS-1$
+
+        mLibraryAllocationTable.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // get the index of the selection in the library table
+                int index1 = mLibraryTable.getSelectionIndex();
+                // get the index in the library allocation table
+                int index2 = mLibraryAllocationTable.getSelectionIndex();
+                // get the MallocInfo object
+                LibraryAllocations liballoc = mLibraryAllocations.get(index1);
+                NativeAllocationInfo info = liballoc.getAllocation(index2);
+                fillDetailTable(info);
+            }
+        });
+
+        // form layout data
+        FormData data = new FormData();
+        data.top = new FormAttachment(0, 0);
+        data.bottom = new FormAttachment(100, 0);
+        data.left = new FormAttachment(0, 0);
+        data.right = new FormAttachment(sash, 0);
+        mLibraryTable.setLayoutData(data);
+
+        final FormData sashData = new FormData();
+        if (prefs != null && prefs.contains(PREFS_LIBRARY_SASH)) {
+            sashData.left = new FormAttachment(0,
+                    prefs.getInt(PREFS_LIBRARY_SASH));
+        } else {
+            sashData.left = new FormAttachment(50, 0);
+        }
+        sashData.bottom = new FormAttachment(100, 0);
+        sashData.top = new FormAttachment(0, 0); // 50% across
+        sash.setLayoutData(sashData);
+
+        data = new FormData();
+        data.top = new FormAttachment(0, 0);
+        data.bottom = new FormAttachment(100, 0);
+        data.left = new FormAttachment(sash, 0);
+        data.right = new FormAttachment(100, 0);
+        mLibraryAllocationTable.setLayoutData(data);
+
+        // allow resizes, but cap at minPanelWidth
+        sash.addListener(SWT.Selection, new Listener() {
+            public void handleEvent(Event e) {
+                Rectangle sashRect = sash.getBounds();
+                Rectangle panelRect = top.getClientArea();
+                int right = panelRect.width - sashRect.width - minPanelWidth;
+                e.x = Math.max(Math.min(e.x, right), minPanelWidth);
+                if (e.x != sashRect.x) {
+                    sashData.left = new FormAttachment(0, e.x);
+                    prefs.setValue(PREFS_LIBRARY_SASH, e.y);
+                    top.layout();
+                }
+            }
+        });
+    }
+
+    private void emptyTables() {
+        mAllocationTable.removeAll();
+        mLibraryTable.removeAll();
+        mLibraryAllocationTable.removeAll();
+        mDetailTable.removeAll();
+    }
+
+    private void sortAllocationsPerLibrary() {
+        if (mClientData != null) {
+            mLibraryAllocations.clear();
+            
+            // create a hash map of LibraryAllocations to access aggregate
+            // objects already created
+            HashMap<String, LibraryAllocations> libcache =
+                new HashMap<String, LibraryAllocations>();
+
+            // get the allocation count
+            int count = mDisplayedAllocations.size();
+            for (int i = 0; i < count; i++) {
+                NativeAllocationInfo allocInfo = mDisplayedAllocations.get(i);
+
+                NativeStackCallInfo stackCallInfo = allocInfo.getRelevantStackCallInfo();
+                if (stackCallInfo != null) {
+                    String libraryName = stackCallInfo.getLibraryName();
+                    LibraryAllocations liballoc = libcache.get(libraryName);
+                    if (liballoc == null) {
+                        // didn't find a library allocation object already
+                        // created so we create one
+                        liballoc = new LibraryAllocations(libraryName);
+                        // add it to the cache
+                        libcache.put(libraryName, liballoc);
+                        // add it to the list
+                        mLibraryAllocations.add(liballoc);
+                    }
+                    // add the MallocInfo object to it.
+                    liballoc.addAllocation(allocInfo);
+                }
+            }
+            // now that the list is created, we need to compute the size and
+            // sort it by size. This will also sort the MallocInfo objects
+            // inside each LibraryAllocation objects.
+            for (LibraryAllocations liballoc : mLibraryAllocations) {
+                liballoc.computeAllocationSizeAndCount();
+            }
+
+            // now we sort it
+            Collections.sort(mLibraryAllocations,
+                    new Comparator<LibraryAllocations>() {
+                public int compare(LibraryAllocations o1,
+                        LibraryAllocations o2) {
+                    return o2.getSize() - o1.getSize();
+                }
+            });
+        }
+    }
+
+    private void renderBitmap(ClientData cd) {
+        byte[] pixData;
+
+        // Atomically get and clear the heap data.
+        synchronized (cd) {
+            if (serializeHeapData(cd.getVmHeapData()) == false) {
+                // no change, we return.
+                return;
+            }
+
+            pixData = getSerializedData();
+
+            ImageData id = createLinearHeapImage(pixData, 200, mMapPalette);
+            Image image = new Image(mBase.getDisplay(), id);
+            mImage.setImage(image);
+            mImage.pack(true);
+        }
+    }
+
+    /*
+     * Create color palette for map.  Set up titles for legend.
+     */
+    private static PaletteData createPalette() {
+        RGB colors[] = new RGB[NUM_PALETTE_ENTRIES];
+        colors[0]
+                = new RGB(192, 192, 192); // non-heap pixels are gray
+        mMapLegend[0]
+                = "(heap expansion area)";
+
+        colors[1]
+                = new RGB(0, 0, 0);       // free chunks are black
+        mMapLegend[1]
+                = "free";
+
+        colors[HeapSegmentElement.KIND_OBJECT + 2]
+                = new RGB(0, 0, 255);     // objects are blue
+        mMapLegend[HeapSegmentElement.KIND_OBJECT + 2]
+                = "data object";
+
+        colors[HeapSegmentElement.KIND_CLASS_OBJECT + 2]
+                = new RGB(0, 255, 0);     // class objects are green
+        mMapLegend[HeapSegmentElement.KIND_CLASS_OBJECT + 2]
+                = "class object";
+
+        colors[HeapSegmentElement.KIND_ARRAY_1 + 2]
+                = new RGB(255, 0, 0);     // byte/bool arrays are red
+        mMapLegend[HeapSegmentElement.KIND_ARRAY_1 + 2]
+                = "1-byte array (byte[], boolean[])";
+
+        colors[HeapSegmentElement.KIND_ARRAY_2 + 2]
+                = new RGB(255, 128, 0);   // short/char arrays are orange
+        mMapLegend[HeapSegmentElement.KIND_ARRAY_2 + 2]
+                = "2-byte array (short[], char[])";
+
+        colors[HeapSegmentElement.KIND_ARRAY_4 + 2]
+                = new RGB(255, 255, 0);   // obj/int/float arrays are yellow
+        mMapLegend[HeapSegmentElement.KIND_ARRAY_4 + 2]
+                = "4-byte array (object[], int[], float[])";
+
+        colors[HeapSegmentElement.KIND_ARRAY_8 + 2]
+                = new RGB(255, 128, 128); // long/double arrays are pink
+        mMapLegend[HeapSegmentElement.KIND_ARRAY_8 + 2]
+                = "8-byte array (long[], double[])";
+
+        colors[HeapSegmentElement.KIND_UNKNOWN + 2]
+                = new RGB(255, 0, 255);   // unknown objects are cyan
+        mMapLegend[HeapSegmentElement.KIND_UNKNOWN + 2]
+                = "unknown object";
+
+        colors[HeapSegmentElement.KIND_NATIVE + 2]
+                = new RGB(64, 64, 64);    // native objects are dark gray
+        mMapLegend[HeapSegmentElement.KIND_NATIVE + 2]
+                = "non-Java object";
+
+        return new PaletteData(colors);
+    }
+    
+    private void saveAllocations(String fileName) {
+        try {
+            PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));
+    
+            for (NativeAllocationInfo alloc : mAllocations) {
+                out.println(alloc.toString());
+            }
+            out.close();
+        } catch (IOException e) {
+            Log.e("Native", e);
+        }
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/Panel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/Panel.java
new file mode 100644
index 0000000..d910cc7
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/Panel.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+
+/**
+ * Base class for our information panels.
+ */
+public abstract class Panel {
+
+    public final Control createPanel(Composite parent) {
+        Control panelControl = createControl(parent);
+
+        postCreation();
+
+        return panelControl;
+    }
+
+    protected abstract void postCreation();
+
+    /**
+     * Creates a control capable of displaying some information.  This is
+     * called once, when the application is initializing, from the UI thread.
+     */
+    protected abstract Control createControl(Composite parent);
+    
+    /**
+     * Sets the focus to the proper control inside the panel.
+     */
+    public abstract void setFocus();
+}
+
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/PortFieldEditor.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/PortFieldEditor.java
new file mode 100644
index 0000000..533372e
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/PortFieldEditor.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import org.eclipse.jface.preference.IntegerFieldEditor;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Edit an integer field, validating it as a port number.
+ */
+public class PortFieldEditor extends IntegerFieldEditor {
+
+    public boolean mRecursiveCheck = false;
+
+    public PortFieldEditor(String name, String label, Composite parent) {
+        super(name, label, parent);
+        setValidateStrategy(VALIDATE_ON_KEY_STROKE);
+    }
+
+    /*
+     * Get the current value of the field, as an integer.
+     */
+    public int getCurrentValue() {
+        int val;
+        try {
+            val = Integer.parseInt(getStringValue());
+        }
+        catch (NumberFormatException nfe) {
+            val = -1;
+        }
+        return val;
+    }
+
+    /*
+     * Check the validity of the field.
+     */
+    @Override
+    protected boolean checkState() {
+        if (super.checkState() == false) {
+            return false;
+        }
+        //Log.i("ddms", "check state " + getStringValue());
+        boolean err = false;
+        int val = getCurrentValue();
+        if (val < 1024 || val > 32767) {
+            setErrorMessage("Port must be between 1024 and 32767");
+            err = true;
+        } else {
+            setErrorMessage(null);
+            err = false;
+        }
+        showErrorMessage();
+        return !err;
+    }
+
+    protected void updateCheckState(PortFieldEditor pfe) {
+        pfe.refreshValidState();
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java
new file mode 100644
index 0000000..dad54dc
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ScreenShotDialog.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.Device;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.RawImage;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.ImageLoader;
+import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+
+import java.io.IOException;
+
+
+/**
+ * Gather a screen shot from the device and save it to a file.
+ */
+public class ScreenShotDialog extends Dialog {
+
+    private Label mBusyLabel;
+    private Label mImageLabel;
+    private Button mSave;
+    private Device mDevice;
+
+
+    /**
+     * Create with default style.
+     */
+    public ScreenShotDialog(Shell parent) {
+        this(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
+    }
+
+    /**
+     * Create with app-defined style.
+     */
+    public ScreenShotDialog(Shell parent, int style) {
+        super(parent, style);
+    }
+
+    /**
+     * Prepare and display the dialog.
+     * @param device The {@link Device} from which to get the screenshot.
+     */
+    public void open(Device device) {
+        mDevice = device;
+
+        Shell parent = getParent();
+        Shell shell = new Shell(parent, getStyle());
+        shell.setText("Device Screen Capture");
+
+        createContents(shell);
+        shell.pack();
+        shell.open();
+
+        updateDeviceImage(shell);
+
+        Display display = parent.getDisplay();
+        while (!shell.isDisposed()) {
+            if (!display.readAndDispatch())
+                display.sleep();
+        }
+
+    }
+
+    /*
+     * Create the screen capture dialog contents.
+     */
+    private void createContents(final Shell shell) {
+        GridData data;
+
+        shell.setLayout(new GridLayout(3, true));
+
+        // title/"capturing" label
+        mBusyLabel = new Label(shell, SWT.NONE);
+        mBusyLabel.setText("Preparing...");
+        data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
+        data.horizontalSpan = 3;
+        mBusyLabel.setLayoutData(data);
+
+        // space for the image
+        mImageLabel = new Label(shell, SWT.BORDER);
+        data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+        data.horizontalSpan = 3;
+        mImageLabel.setLayoutData(data);
+        Display display = shell.getDisplay();
+        mImageLabel.setImage(ImageHelper.createPlaceHolderArt(display, 50, 50, display.getSystemColor(SWT.COLOR_BLUE)));
+
+        // "refresh" button
+        Button refresh = new Button(shell, SWT.PUSH);
+        refresh.setText("Refresh");
+        data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+        data.widthHint = 80;
+        refresh.setLayoutData(data);
+        refresh.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                updateDeviceImage(shell);
+            }
+        });
+
+        // "save" button
+        mSave = new Button(shell, SWT.PUSH);
+        mSave.setText("Save");
+        data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+        data.widthHint = 80;
+        mSave.setLayoutData(data);
+        mSave.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                saveImage(shell);
+            }
+        });
+
+        // "done" button
+        Button done = new Button(shell, SWT.PUSH);
+        done.setText("Done");
+        data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+        data.widthHint = 80;
+        done.setLayoutData(data);
+        done.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                shell.close();
+            }
+        });
+
+        shell.setDefaultButton(done);
+    }
+
+    /*
+     * Capture a new image from the device.
+     */
+    private void updateDeviceImage(Shell shell) {
+        mBusyLabel.setText("Capturing...");     // no effect
+
+        shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
+
+        Image image = getDeviceImage();
+        if (image == null) {
+            Display display = shell.getDisplay();
+            image = ImageHelper.createPlaceHolderArt(display, 320, 240, display.getSystemColor(SWT.COLOR_BLUE));
+            mSave.setEnabled(false);
+            mBusyLabel.setText("Screen not available");
+        } else {
+            mSave.setEnabled(true);
+            mBusyLabel.setText("Captured image:");
+        }
+
+        mImageLabel.setImage(image);
+        mImageLabel.pack();
+        shell.pack();
+
+        // there's no way to restore old cursor; assume it's ARROW
+        shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_ARROW));
+    }
+
+    /*
+     * Grab an image from an ADB-connected device.
+     */
+    private Image getDeviceImage() {
+        RawImage rawImage;
+
+        try {
+            rawImage = mDevice.getScreenshot();
+        }
+        catch (IOException ioe) {
+            Log.w("ddms", "Unable to get frame buffer: " + ioe.getMessage());
+            return null;
+        }
+
+        // device/adb not available?
+        if (rawImage == null)
+            return null;
+
+        // convert raw data to an Image
+        assert rawImage.bpp == 16;
+        PaletteData palette = new PaletteData(0xf800, 0x07e0, 0x001f);
+        ImageData imageData = new ImageData(rawImage.width, rawImage.height,
+            rawImage.bpp, palette, 1, rawImage.data);
+
+        return new Image(getParent().getDisplay(), imageData);
+    }
+
+    /*
+     * Prompt the user to save the image to disk.
+     */
+    private void saveImage(Shell shell) {
+        FileDialog dlg = new FileDialog(shell, SWT.SAVE);
+        String fileName;
+
+        dlg.setText("Save image...");
+        dlg.setFileName("device.png");
+        dlg.setFilterPath(DdmUiPreferences.getStore().getString("lastImageSaveDir"));
+        dlg.setFilterNames(new String[] {
+            "PNG Files (*.png)"
+        });
+        dlg.setFilterExtensions(new String[] {
+            "*.png" //$NON-NLS-1$
+        });
+
+        fileName = dlg.open();
+        if (fileName != null) {
+            DdmUiPreferences.getStore().setValue("lastImageSaveDir", dlg.getFilterPath());
+
+            Log.i("ddms", "Saving image to " + fileName);
+            ImageData imageData = mImageLabel.getImage().getImageData();
+
+            try {
+                WritePng.savePng(fileName, imageData);
+            }
+            catch (IOException ioe) {
+                Log.w("ddms", "Unable to save " + fileName + ": " + ioe);
+            }
+
+            if (false) {
+                ImageLoader loader = new ImageLoader();
+                loader.data = new ImageData[] { imageData };
+                // PNG writing not available until 3.3?  See bug at:
+                //  https://bugs.eclipse.org/bugs/show_bug.cgi?id=24697
+                // GIF writing only works for 8 bits
+                // JPEG uses lossy compression
+                // BMP has screwed-up colors
+                loader.save(fileName, SWT.IMAGE_JPEG);
+            }
+        }
+    }
+
+}
+
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SelectionDependentPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SelectionDependentPanel.java
new file mode 100644
index 0000000..4b5fe56
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SelectionDependentPanel.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.Client;
+import com.android.ddmlib.Device;
+
+/**
+ * A Panel that requires {@link Device}/{@link Client} selection notifications.
+ */
+public abstract class SelectionDependentPanel extends Panel {
+    private Device 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() {
+        return mCurrentDevice;
+    }
+
+    /**
+     * Returns the current {@link Client}.
+     * @return the current client or null if none are selected.
+     */
+    protected final Client getCurrentClient() {
+        return mCurrentClient;
+    }
+
+    /**
+     * Sent when a new device is selected.
+     * @param selectedDevice the selected device.
+     */
+    public final void deviceSelected(Device selectedDevice) {
+        if (selectedDevice != mCurrentDevice) {
+            mCurrentDevice = selectedDevice;
+            deviceSelected();
+        }
+    }
+
+    /**
+     * Sent when a new client is selected.
+     * @param selectedClient the selected client.
+     */
+    public final void clientSelected(Client selectedClient) {
+        if (selectedClient != mCurrentClient) {
+            mCurrentClient = selectedClient;
+            clientSelected();
+        }
+    }
+
+    /**
+     * Sent when a new device is selected. The new device can be accessed
+     * with {@link #getCurrentDevice()}.
+     */
+    public abstract void deviceSelected();
+
+    /**
+     * Sent when a new client is selected. The new client can be accessed
+     * with {@link #getCurrentClient()}.
+     */
+    public abstract void clientSelected();
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/StackTracePanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/StackTracePanel.java
new file mode 100644
index 0000000..3358962
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/StackTracePanel.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.Client;
+import com.android.ddmlib.IStackTraceInfo;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+
+/**
+ * Stack Trace Panel.
+ * <p/>This is not a panel in the regular sense. Instead this is just an object around the creation
+ * and management of a Stack Trace display.
+ * <p/>UI creation is done through
+ * {@link #createPanel(Composite, String, String, String, String, String, IPreferenceStore)}.
+ *
+ */
+public final class StackTracePanel {
+
+    private static ISourceRevealer sSourceRevealer;
+
+    private Table mStackTraceTable;
+    private TableViewer mStackTraceViewer;
+
+    private Client mCurrentClient;
+    
+    
+    /**
+     * Content Provider to display the stack trace of a thread.
+     * Expected input is a {@link IStackTraceInfo} object.
+     */
+    private static class StackTraceContentProvider implements IStructuredContentProvider {
+        public Object[] getElements(Object inputElement) {
+            if (inputElement instanceof IStackTraceInfo) {
+                // getElement cannot return null, so we return an empty array
+                // if there's no stack trace
+                StackTraceElement trace[] = ((IStackTraceInfo)inputElement).getStackTrace();
+                if (trace != null) {
+                    return trace;
+                }
+            }
+
+            return new Object[0];
+        }
+
+        public void dispose() {
+            // pass
+        }
+
+        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+            // pass
+        }
+    }
+    
+
+    /**
+     * A Label Provider to use with {@link StackTraceContentProvider}. It expects the elements to be
+     * of type {@link StackTraceElement}.
+     */
+    private static class StackTraceLabelProvider implements ITableLabelProvider {
+
+        public Image getColumnImage(Object element, int columnIndex) {
+            return null;
+        }
+
+        public String getColumnText(Object element, int columnIndex) {
+            if (element instanceof StackTraceElement) {
+                StackTraceElement traceElement = (StackTraceElement)element;
+                switch (columnIndex) {
+                    case 0:
+                        return traceElement.getClassName();
+                    case 1:
+                        return traceElement.getMethodName();
+                    case 2:
+                        return traceElement.getFileName();
+                    case 3:
+                        return Integer.toString(traceElement.getLineNumber());
+                    case 4:
+                        return Boolean.toString(traceElement.isNativeMethod());
+                }
+            }
+
+            return null;
+        }
+
+        public void addListener(ILabelProviderListener listener) {
+            // pass
+        }
+
+        public void dispose() {
+            // pass
+        }
+
+        public boolean isLabelProperty(Object element, String property) {
+            // pass
+            return false;
+        }
+
+        public void removeListener(ILabelProviderListener listener) {
+            // pass
+        }
+    }
+    
+    /**
+     * Classes which implement this interface provide a method that is able to reveal a method
+     * in a source editor
+     */
+    public interface ISourceRevealer {
+        /**
+         * Sent to reveal a particular line in a source editor
+         * @param applicationName the name of the application running the source.
+         * @param className the fully qualified class name
+         * @param line the line to reveal
+         */
+        public void reveal(String applicationName, String className, int line);
+    }
+    
+    
+    /**
+     * Sets the {@link ISourceRevealer} object able to reveal source code in a source editor.
+     * @param revealer
+     */
+    public static void setSourceRevealer(ISourceRevealer revealer) {
+        sSourceRevealer = revealer;
+    }
+    
+    /**
+     * Creates the controls for the StrackTrace display.
+     * <p/>This method will set the parent {@link Composite} to use a {@link GridLayout} with
+     * 2 columns.
+     * @param parent the parent composite.
+     * @param prefs_stack_col_class 
+     * @param prefs_stack_col_method 
+     * @param prefs_stack_col_file 
+     * @param prefs_stack_col_line 
+     * @param prefs_stack_col_native 
+     * @param store
+     */
+    public Table createPanel(Composite parent, String prefs_stack_col_class,
+            String prefs_stack_col_method, String prefs_stack_col_file, String prefs_stack_col_line,
+            String prefs_stack_col_native, IPreferenceStore store) {
+        
+        mStackTraceTable = new Table(parent, SWT.MULTI | SWT.FULL_SELECTION);
+        mStackTraceTable.setHeaderVisible(true);
+        mStackTraceTable.setLinesVisible(true);
+        
+        TableHelper.createTableColumn(
+                mStackTraceTable,
+                "Class",
+                SWT.LEFT,
+                "SomeLongClassName", //$NON-NLS-1$
+                prefs_stack_col_class, store);
+
+        TableHelper.createTableColumn(
+                mStackTraceTable,
+                "Method",
+                SWT.LEFT,
+                "someLongMethod", //$NON-NLS-1$
+                prefs_stack_col_method, store);
+
+        TableHelper.createTableColumn(
+                mStackTraceTable,
+                "File",
+                SWT.LEFT,
+                "android/somepackage/someotherpackage/somefile.class", //$NON-NLS-1$
+                prefs_stack_col_file, store);
+
+        TableHelper.createTableColumn(
+                mStackTraceTable,
+                "Line",
+                SWT.RIGHT,
+                "99999", //$NON-NLS-1$
+                prefs_stack_col_line, store);
+
+        TableHelper.createTableColumn(
+                mStackTraceTable,
+                "Native",
+                SWT.LEFT,
+                "Native", //$NON-NLS-1$
+                prefs_stack_col_native, store);
+        
+        mStackTraceViewer = new TableViewer(mStackTraceTable);
+        mStackTraceViewer.setContentProvider(new StackTraceContentProvider());
+        mStackTraceViewer.setLabelProvider(new StackTraceLabelProvider());
+        
+        mStackTraceViewer.addDoubleClickListener(new IDoubleClickListener() {
+            public void doubleClick(DoubleClickEvent event) {
+                if (sSourceRevealer != null && mCurrentClient != null) {
+                    // get the selected stack trace element
+                    ISelection selection = mStackTraceViewer.getSelection();
+                    
+                    if (selection instanceof IStructuredSelection) {
+                        IStructuredSelection structuredSelection = (IStructuredSelection)selection;
+                        Object object = structuredSelection.getFirstElement();
+                        if (object instanceof StackTraceElement) {
+                            StackTraceElement traceElement = (StackTraceElement)object;
+                            
+                            if (traceElement.isNativeMethod() == false) {
+                                sSourceRevealer.reveal(
+                                        mCurrentClient.getClientData().getClientDescription(), 
+                                        traceElement.getClassName(),
+                                        traceElement.getLineNumber());
+                            }
+                        }
+                    }
+                }
+            }
+        });
+
+        return mStackTraceTable;
+    }
+    
+    /**
+     * Sets the input for the {@link TableViewer}.
+     * @param input the {@link IStackTraceInfo} that will provide the viewer with the list of
+     * {@link StackTraceElement}
+     */
+    public void setViewerInput(IStackTraceInfo input) {
+        mStackTraceViewer.setInput(input);
+        mStackTraceViewer.refresh();
+    }
+    
+    /**
+     * Sets the current client running the stack trace.
+     * @param currentClient the {@link Client}.
+     */
+    public void setCurrentClient(Client currentClient) {
+        mCurrentClient = currentClient;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SysinfoPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SysinfoPanel.java
new file mode 100644
index 0000000..8ef237c
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/SysinfoPanel.java
@@ -0,0 +1,582 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.Client;
+import com.android.ddmlib.IShellOutputReceiver;
+import com.android.ddmlib.Log;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.data.general.DefaultPieDataset;
+import org.jfree.experimental.chart.swt.ChartComposite;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Displays system information graphs obtained from a bugreport file or device.
+ */
+public class SysinfoPanel extends TablePanel implements IShellOutputReceiver {
+
+    // UI components
+    private Label mLabel;
+    private Button mFetchButton;
+    private Combo mDisplayMode;
+
+    private DefaultPieDataset mDataset;
+
+    // The bugreport file to process
+    private File mDataFile;
+
+    // To get output from adb commands
+    private FileOutputStream mTempStream;
+
+    // Selects the current display: MODE_CPU, etc.
+    private int mMode = 0;
+
+    private static final int MODE_CPU = 0;
+    private static final int MODE_ALARM = 1;
+    private static final int MODE_WAKELOCK = 2;
+    private static final int MODE_MEMINFO = 3;
+    private static final int MODE_SYNC = 4;
+
+    // argument to dumpsys; section in the bugreport holding the data
+    private static final String BUGREPORT_SECTION[] = {"cpuinfo", "alarm",
+            "batteryinfo", "MEMORY INFO", "content"};
+
+    private static final String DUMP_COMMAND[] = {"dumpsys cpuinfo",
+            "dumpsys alarm", "dumpsys batteryinfo", "cat /proc/meminfo ; procrank",
+            "dumpsys content"};
+
+    private static final String CAPTIONS[] = {"CPU load", "Alarms",
+            "Wakelocks", "Memory usage", "Sync"};
+
+    /**
+     * Generates the dataset to display.
+     *
+     * @param file The bugreport file to process.
+     */
+    public void generateDataset(File file) {
+        mDataset.clear();
+        mLabel.setText("");
+        if (file == null) {
+            return;
+        }
+        try {
+            BufferedReader br = getBugreportReader(file);
+            if (mMode == MODE_CPU) {
+                readCpuDataset(br);
+            } else if (mMode == MODE_ALARM) {
+                readAlarmDataset(br);
+            } else if (mMode == MODE_WAKELOCK) {
+                readWakelockDataset(br);
+            } else if (mMode == MODE_MEMINFO) {
+                readMeminfoDataset(br);
+            } else if (mMode == MODE_SYNC) {
+                readSyncDataset(br);
+            }
+        } catch (IOException e) {
+            Log.e("DDMS", e);
+        }
+    }
+
+    /**
+     * Sent when a new device is selected. The new device can be accessed with
+     * {@link #getCurrentDevice()}
+     */
+    @Override
+    public void deviceSelected() {
+        if (getCurrentDevice() != null) {
+            mFetchButton.setEnabled(true);
+            loadFromDevice();
+        } else {
+            mFetchButton.setEnabled(false);
+        }
+    }
+
+    /**
+     * Sent when a new client is selected. The new client can be accessed with
+     * {@link #getCurrentClient()}.
+     */
+    @Override
+    public void clientSelected() {
+    }
+
+    /**
+     * Sets the focus to the proper control inside the panel.
+     */
+    @Override
+    public void setFocus() {
+        mDisplayMode.setFocus();
+    }
+
+    /**
+     * Fetches a new bugreport from the device and updates the display.
+     * Fetching is asynchronous.  See also addOutput, flush, and isCancelled.
+     */
+    private void loadFromDevice() {
+        try {
+            initShellOutputBuffer();
+            if (mMode == MODE_MEMINFO) {
+                // Hack to add bugreport-style section header for meminfo
+                mTempStream.write("------ MEMORY INFO ------\n".getBytes());
+            }
+            getCurrentDevice().executeShellCommand(
+                    DUMP_COMMAND[mMode], this);
+        } catch (IOException e) {
+            Log.e("DDMS", e);
+        }
+    }
+
+    /**
+     * Initializes temporary output file for executeShellCommand().
+     *
+     * @throws IOException on file error
+     */
+    void initShellOutputBuffer() throws IOException {
+        mDataFile = File.createTempFile("ddmsfile", ".txt");
+        mDataFile.deleteOnExit();
+        mTempStream = new FileOutputStream(mDataFile);
+    }
+
+    /**
+     * Adds output to the temp file. IShellOutputReceiver method. Called by
+     * executeShellCommand().
+     */
+    public void addOutput(byte[] data, int offset, int length) {
+        try {
+            mTempStream.write(data, offset, length);
+        }
+        catch (IOException e) {
+            Log.e("DDMS", e);
+        }
+    }
+
+    /**
+     * Processes output from shell command. IShellOutputReceiver method. The
+     * output is passed to generateDataset(). Called by executeShellCommand() on
+     * completion.
+     */
+    public void flush() {
+        if (mTempStream != null) {
+            try {
+                mTempStream.close();
+                generateDataset(mDataFile);
+                mTempStream = null;
+                mDataFile = null;
+            } catch (IOException e) {
+                Log.e("DDMS", e);
+            }
+        }
+    }
+
+    /**
+     * IShellOutputReceiver method.
+     *
+     * @return false - don't cancel
+     */
+    public boolean isCancelled() {
+        return false;
+    }
+
+    /**
+     * Create our controls for the UI panel.
+     */
+    @Override
+    protected Control createControl(Composite parent) {
+        Composite top = new Composite(parent, SWT.NONE);
+        top.setLayout(new GridLayout(1, false));
+        top.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        Composite buttons = new Composite(top, SWT.NONE);
+        buttons.setLayout(new RowLayout());
+
+        mDisplayMode = new Combo(buttons, SWT.PUSH);
+        for (String mode : CAPTIONS) {
+            mDisplayMode.add(mode);
+        }
+        mDisplayMode.select(mMode);
+        mDisplayMode.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mMode = mDisplayMode.getSelectionIndex();
+                if (mDataFile != null) {
+                    generateDataset(mDataFile);
+                } else if (getCurrentDevice() != null) {
+                    loadFromDevice();
+                }
+            }
+        });
+
+        final Button loadButton = new Button(buttons, SWT.PUSH);
+        loadButton.setText("Load from File");
+        loadButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                FileDialog fileDialog = new FileDialog(loadButton.getShell(),
+                        SWT.OPEN);
+                fileDialog.setText("Load bugreport");
+                String filename = fileDialog.open();
+                if (filename != null) {
+                    mDataFile = new File(filename);
+                    generateDataset(mDataFile);
+                }
+            }
+        });
+
+        mFetchButton = new Button(buttons, SWT.PUSH);
+        mFetchButton.setText("Update from Device");
+        mFetchButton.setEnabled(false);
+        mFetchButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                loadFromDevice();
+            }
+        });
+
+        mLabel = new Label(top, SWT.NONE);
+        mLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        mDataset = new DefaultPieDataset();
+        JFreeChart chart = ChartFactory.createPieChart("", mDataset, false
+                /* legend */, true/* tooltips */, false /* urls */);
+
+        ChartComposite chartComposite = new ChartComposite(top,
+                SWT.BORDER, chart,
+                ChartComposite.DEFAULT_HEIGHT,
+                ChartComposite.DEFAULT_HEIGHT,
+                ChartComposite.DEFAULT_MINIMUM_DRAW_WIDTH,
+                ChartComposite.DEFAULT_MINIMUM_DRAW_HEIGHT,
+                3000,
+                // max draw width. We don't want it to zoom, so we put a big number
+                3000,
+                // max draw height. We don't want it to zoom, so we put a big number
+                true,  // off-screen buffer
+                true,  // properties
+                true,  // save
+                true,  // print
+                false,  // zoom
+                true);
+        chartComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+        return top;
+    }
+
+    public void clientChanged(final Client client, int changeMask) {
+        // Don't care
+    }
+
+    /**
+     * Helper to open a bugreport and skip to the specified section.
+     *
+     * @param file File to open
+     * @return Reader to bugreport file
+     * @throws java.io.IOException on file error
+     */
+    private BufferedReader getBugreportReader(File file) throws
+            IOException {
+        BufferedReader br = new BufferedReader(new FileReader(file));
+        // Skip over the unwanted bugreport sections
+        while (true) {
+            String line = br.readLine();
+            if (line == null) {
+                Log.d("DDMS", "Service not found " + line);
+                break;
+            }
+            if ((line.startsWith("DUMP OF SERVICE ") || line.startsWith("-----")) &&
+                    line.indexOf(BUGREPORT_SECTION[mMode]) > 0) {
+                break;
+            }
+        }
+        return br;
+    }
+
+    /**
+     * Parse the time string generated by BatteryStats.
+     * A typical new-format string is "11d 13h 45m 39s 999ms".
+     * A typical old-format string is "12.3 sec".
+     * @return time in ms
+     */
+    private static long parseTimeMs(String s) {
+        long total = 0;
+        // Matches a single component e.g. "12.3 sec" or "45ms"
+        Pattern p = Pattern.compile("([\\d\\.]+)\\s*([a-z]+)");
+        Matcher m = p.matcher(s);
+        while (m.find()) {
+            String label = m.group(2);
+            if ("sec".equals(label)) {
+                // Backwards compatibility with old time format
+                total += (long) (Double.parseDouble(m.group(1)) * 1000);
+                continue;
+            }
+            long value = Integer.parseInt(m.group(1));
+            if ("d".equals(label)) {
+                total += value * 24 * 60 * 60 * 1000;
+            } else if ("h".equals(label)) {
+                total += value * 60 * 60 * 1000;
+            } else if ("m".equals(label)) {
+                total += value * 60 * 1000;
+            } else if ("s".equals(label)) {
+                total += value * 1000;
+            } else if ("ms".equals(label)) {
+                total += value;
+            }
+        }
+        return total;
+    }
+    /**
+     * Processes wakelock information from bugreport. Updates mDataset with the
+     * new data.
+     *
+     * @param br Reader providing the content
+     * @throws IOException if error reading file
+     */
+    void readWakelockDataset(BufferedReader br) throws IOException {
+        Pattern lockPattern = Pattern.compile("Wake lock (\\S+): (.+) partial");
+        Pattern totalPattern = Pattern.compile("Total: (.+) uptime");
+        double total = 0;
+        boolean inCurrent = false;
+
+        while (true) {
+            String line = br.readLine();
+            if (line == null || line.startsWith("DUMP OF SERVICE")) {
+                // Done, or moved on to the next service
+                break;
+            }
+            if (line.startsWith("Current Battery Usage Statistics")) {
+                inCurrent = true;
+            } else if (inCurrent) {
+                Matcher m = lockPattern.matcher(line);
+                if (m.find()) {
+                    double value = parseTimeMs(m.group(2)) / 1000.;
+                    mDataset.setValue(m.group(1), value);
+                    total -= value;
+                } else {
+                    m = totalPattern.matcher(line);
+                    if (m.find()) {
+                        total += parseTimeMs(m.group(1)) / 1000.;
+                    }
+                }
+            }
+        }
+        if (total > 0) {
+            mDataset.setValue("Unlocked", total);
+        }
+    }
+
+    /**
+     * Processes alarm information from bugreport. Updates mDataset with the new
+     * data.
+     *
+     * @param br Reader providing the content
+     * @throws IOException if error reading file
+     */
+    void readAlarmDataset(BufferedReader br) throws IOException {
+        Pattern pattern = Pattern
+                .compile("(\\d+) alarms: Intent .*\\.([^. ]+) flags");
+
+        while (true) {
+            String line = br.readLine();
+            if (line == null || line.startsWith("DUMP OF SERVICE")) {
+                // Done, or moved on to the next service
+                break;
+            }
+            Matcher m = pattern.matcher(line);
+            if (m.find()) {
+                long count = Long.parseLong(m.group(1));
+                String name = m.group(2);
+                mDataset.setValue(name, count);
+            }
+        }
+    }
+
+    /**
+     * Processes cpu load information from bugreport. Updates mDataset with the
+     * new data.
+     *
+     * @param br Reader providing the content
+     * @throws IOException if error reading file
+     */
+    void readCpuDataset(BufferedReader br) throws IOException {
+        Pattern pattern = Pattern
+                .compile("(\\S+): (\\S+)% = (.+)% user . (.+)% kernel");
+
+        while (true) {
+            String line = br.readLine();
+            if (line == null || line.startsWith("DUMP OF SERVICE")) {
+                // Done, or moved on to the next service
+                break;
+            }
+            if (line.startsWith("Load:")) {
+                mLabel.setText(line);
+                continue;
+            }
+            Matcher m = pattern.matcher(line);
+            if (m.find()) {
+                String name = m.group(1);
+                long both = Long.parseLong(m.group(2));
+                long user = Long.parseLong(m.group(3));
+                long kernel = Long.parseLong(m.group(4));
+                if ("TOTAL".equals(name)) {
+                    if (both < 100) {
+                        mDataset.setValue("Idle", (100 - both));
+                    }
+                } else {
+                    // Try to make graphs more useful even with rounding;
+                    // log often has 0% user + 0% kernel = 1% total
+                    // We arbitrarily give extra to kernel
+                    if (user > 0) {
+                        mDataset.setValue(name + " (user)", user);
+                    }
+                    if (kernel > 0) {
+                        mDataset.setValue(name + " (kernel)" , both - user);
+                    }
+                    if (user == 0 && kernel == 0 && both > 0) {
+                        mDataset.setValue(name, both);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Processes meminfo information from bugreport. Updates mDataset with the
+     * new data.
+     *
+     * @param br Reader providing the content
+     * @throws IOException if error reading file
+     */
+    void readMeminfoDataset(BufferedReader br) throws IOException {
+        Pattern valuePattern = Pattern.compile("(\\d+) kB");
+        long total = 0;
+        long other = 0;
+        mLabel.setText("PSS in kB");        
+
+        // Scan meminfo
+        while (true) {
+            String line = br.readLine();
+            if (line == null) {
+                // End of file
+                break;
+            }
+            Matcher m = valuePattern.matcher(line);
+            if (m.find()) {
+                long kb = Long.parseLong(m.group(1));
+                if (line.startsWith("MemTotal")) {
+                    total = kb;
+                } else if (line.startsWith("MemFree")) {
+                    mDataset.setValue("Free", kb);
+                    total -= kb;
+                } else if (line.startsWith("Slab")) {
+                    mDataset.setValue("Slab", kb);
+                    total -= kb;
+                } else if (line.startsWith("PageTables")) {
+                    mDataset.setValue("PageTables", kb);
+                    total -= kb;
+                } else if (line.startsWith("Buffers") && kb > 0) {
+                    mDataset.setValue("Buffers", kb);
+                    total -= kb;
+                } else if (line.startsWith("Inactive")) {
+                    mDataset.setValue("Inactive", kb);
+                    total -= kb;
+                } else if (line.startsWith("MemFree")) {
+                    mDataset.setValue("Free", kb);
+                    total -= kb;
+                }
+            } else {
+                break;
+            }
+        }
+        // Scan procrank
+        while (true) {
+            String line = br.readLine();
+            if (line == null) {
+                break;
+            }
+            if (line.indexOf("PROCRANK") >= 0 || line.indexOf("PID") >= 0) {
+                // procrank header
+                continue;
+            }
+            if  (line.indexOf("----") >= 0) {
+                //end of procrank section
+                break;
+            }
+            // Extract pss field from procrank output
+            long pss = Long.parseLong(line.substring(23, 31).trim());
+            String cmdline = line.substring(43).trim().replace("/system/bin/", "");
+            // Arbitrary minimum size to display
+            if (pss > 2000) {
+                mDataset.setValue(cmdline, pss);
+            } else {
+                other += pss;
+            }
+            total -= pss;
+        }
+        mDataset.setValue("Other", other);
+        mDataset.setValue("Unknown", total);
+    }
+
+    /**
+     * Processes sync information from bugreport. Updates mDataset with the new
+     * data.
+     *
+     * @param br Reader providing the content
+     * @throws IOException if error reading file
+     */
+    void readSyncDataset(BufferedReader br) throws IOException {
+        while (true) {
+            String line = br.readLine();
+            if (line == null || line.startsWith("DUMP OF SERVICE")) {
+                // Done, or moved on to the next service
+                break;
+            }
+            if (line.startsWith(" |") && line.length() > 70) {
+                String authority = line.substring(3, 18).trim();
+                String duration = line.substring(61, 70).trim();
+                // Duration is MM:SS or HH:MM:SS (DateUtils.formatElapsedTime)
+                String durParts[] = duration.split(":");
+                if (durParts.length == 2) {
+                    long dur = Long.parseLong(durParts[0]) * 60 + Long
+                            .parseLong(durParts[1]);
+                    mDataset.setValue(authority, dur);
+                } else if (duration.length() == 3) {
+                    long dur = Long.parseLong(durParts[0]) * 3600
+                            + Long.parseLong(durParts[1]) * 60 + Long
+                            .parseLong(durParts[2]);
+                    mDataset.setValue(authority, dur);
+                }
+            }
+        }
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/TableHelper.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/TableHelper.java
new file mode 100644
index 0000000..f8d457e
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/TableHelper.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+
+/**
+ * Utility class to help using Table objects.
+ *
+ */
+public final class TableHelper {
+    /**
+     * Create a TableColumn with the specified parameters. If a
+     * <code>PreferenceStore</code> object and a preference entry name String
+     * object are provided then the column will listen to change in its width
+     * and update the preference store accordingly.
+     *
+     * @param parent The Table parent object
+     * @param header The header string
+     * @param style The column style
+     * @param sample_text A sample text to figure out column width if preference
+     *            value is missing
+     * @param pref_name The preference entry name for column width
+     * @param prefs The preference store
+     * @return The TableColumn object that was created
+     */
+    public static TableColumn createTableColumn(Table parent, String header,
+            int style, String sample_text, final String pref_name,
+            final IPreferenceStore prefs) {
+
+        // create the column
+        TableColumn col = new TableColumn(parent, style);
+
+        // if there is no pref store or the entry is missing, we use the sample
+        // text and pack the column.
+        // Otherwise we just read the width from the prefs and apply it.
+        if (prefs == null || prefs.contains(pref_name) == false) {
+            col.setText(sample_text);
+            col.pack();
+
+            // init the prefs store with the current value
+            if (prefs != null) {
+                prefs.setValue(pref_name, col.getWidth());
+            }
+        } else {
+            col.setWidth(prefs.getInt(pref_name));
+        }
+
+        // set the header
+        col.setText(header);
+
+        // if there is a pref store and a pref entry name, then we setup a
+        // listener to catch column resize to put store the new width value.
+        if (prefs != null && pref_name != null) {
+            col.addControlListener(new ControlListener() {
+                public void controlMoved(ControlEvent e) {
+                }
+
+                public void controlResized(ControlEvent e) {
+                    // get the new width
+                    int w = ((TableColumn)e.widget).getWidth();
+
+                    // store in pref store
+                    prefs.setValue(pref_name, w);
+                }
+            });
+        }
+
+        return col;
+    }
+
+    /**
+     * Create a TreeColumn with the specified parameters. If a
+     * <code>PreferenceStore</code> object and a preference entry name String
+     * object are provided then the column will listen to change in its width
+     * and update the preference store accordingly.
+     *
+     * @param parent The Table parent object
+     * @param header The header string
+     * @param style The column style
+     * @param sample_text A sample text to figure out column width if preference
+     *            value is missing
+     * @param pref_name The preference entry name for column width
+     * @param prefs The preference store
+     */
+    public static void createTreeColumn(Tree parent, String header, int style,
+            String sample_text, final String pref_name,
+            final IPreferenceStore prefs) {
+
+        // create the column
+        TreeColumn col = new TreeColumn(parent, style);
+
+        // if there is no pref store or the entry is missing, we use the sample
+        // text and pack the column.
+        // Otherwise we just read the width from the prefs and apply it.
+        if (prefs == null || prefs.contains(pref_name) == false) {
+            col.setText(sample_text);
+            col.pack();
+
+            // init the prefs store with the current value
+            if (prefs != null) {
+                prefs.setValue(pref_name, col.getWidth());
+            }
+        } else {
+            col.setWidth(prefs.getInt(pref_name));
+        }
+
+        // set the header
+        col.setText(header);
+
+        // if there is a pref store and a pref entry name, then we setup a
+        // listener to catch column resize to put store the new width value.
+        if (prefs != null && pref_name != null) {
+            col.addControlListener(new ControlListener() {
+                public void controlMoved(ControlEvent e) {
+                }
+
+                public void controlResized(ControlEvent e) {
+                    // get the new width
+                    int w = ((TreeColumn)e.widget).getWidth();
+
+                    // store in pref store
+                    prefs.setValue(pref_name, w);
+                }
+            });
+        }
+    }
+
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/TablePanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/TablePanel.java
new file mode 100644
index 0000000..b037193
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/TablePanel.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmuilib.ITableFocusListener.IFocusedTableActivator;
+
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+import java.util.Arrays;
+
+/**
+ * Base class for panel containing Table that need to support copy-paste-selectAll
+ */
+public abstract class TablePanel extends ClientDisplayPanel {
+    private ITableFocusListener mGlobalListener;
+
+    /**
+     * Sets a TableFocusListener which will be notified when one of the tables
+     * gets or loses focus.
+     *
+     * @param listener
+     */
+    public final void setTableFocusListener(ITableFocusListener listener) {
+        // record the global listener, to make sure table created after
+        // this call will still be setup.
+        mGlobalListener = listener;
+
+        setTableFocusListener();
+    }
+
+    /**
+     * Sets up the Table of object of the panel to work with the global listener.<br>
+     * Default implementation does nothing.
+     */
+    protected void setTableFocusListener() {
+
+    }
+
+    /**
+     * Sets up a Table object to notify the global Table Focus listener when it
+     * gets or loses the focus.
+     *
+     * @param table the Table object.
+     * @param colStart
+     * @param colEnd
+     */
+    protected final void addTableToFocusListener(final Table table,
+            final int colStart, final int colEnd) {
+        // create the activator for this table
+        final IFocusedTableActivator activator = new IFocusedTableActivator() {
+            public void copy(Clipboard clipboard) {
+                int[] selection = table.getSelectionIndices();
+
+                // we need to sort the items to be sure.
+                Arrays.sort(selection);
+
+                // all lines must be concatenated.
+                StringBuilder sb = new StringBuilder();
+
+                // loop on the selection and output the file.
+                for (int i : selection) {
+                    TableItem item = table.getItem(i);
+                    for (int c = colStart ; c <= colEnd ; c++) {
+                        sb.append(item.getText(c));
+                        sb.append('\t');
+                    }
+                    sb.append('\n');
+                }
+
+                // now add that to the clipboard if the string has content
+                String data = sb.toString();
+                if (data != null || data.length() > 0) {
+                    clipboard.setContents(
+                            new Object[] { data },
+                            new Transfer[] { TextTransfer.getInstance() });
+                }
+            }
+
+            public void selectAll() {
+                table.selectAll();
+            }
+        };
+
+        // add the focus listener on the table to notify the global listener
+        table.addFocusListener(new FocusListener() {
+            public void focusGained(FocusEvent e) {
+                mGlobalListener.focusGained(activator);
+            }
+
+            public void focusLost(FocusEvent e) {
+                mGlobalListener.focusLost(activator);
+            }
+        });
+    }
+
+    /**
+     * Sets up a Table object to notify the global Table Focus listener when it
+     * gets or loses the focus.<br>
+     * When the copy method is invoked, all columns are put in the clipboard, separated
+     * by tabs
+     *
+     * @param table the Table object.
+     */
+    protected final void addTableToFocusListener(final Table table) {
+        addTableToFocusListener(table, 0, table.getColumnCount()-1);
+    }
+
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ThreadPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ThreadPanel.java
new file mode 100644
index 0000000..a034063
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/ThreadPanel.java
@@ -0,0 +1,572 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.Client;
+import com.android.ddmlib.ThreadInfo;
+import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Sash;
+import org.eclipse.swt.widgets.Table;
+
+import java.util.Date;
+
+/**
+ * Base class for our information panels.
+ */
+public class ThreadPanel extends TablePanel {
+    
+    private final static String PREFS_THREAD_COL_ID = "threadPanel.Col0"; //$NON-NLS-1$
+    private final static String PREFS_THREAD_COL_TID = "threadPanel.Col1"; //$NON-NLS-1$
+    private final static String PREFS_THREAD_COL_STATUS = "threadPanel.Col2"; //$NON-NLS-1$
+    private final static String PREFS_THREAD_COL_UTIME = "threadPanel.Col3"; //$NON-NLS-1$
+    private final static String PREFS_THREAD_COL_STIME = "threadPanel.Col4"; //$NON-NLS-1$
+    private final static String PREFS_THREAD_COL_NAME = "threadPanel.Col5"; //$NON-NLS-1$
+    
+    private final static String PREFS_THREAD_SASH = "threadPanel.sash"; //$NON-NLS-1$
+
+    private static final String PREFS_STACK_COL_CLASS = "threadPanel.stack.col0"; //$NON-NLS-1$
+    private static final String PREFS_STACK_COL_METHOD = "threadPanel.stack.col1"; //$NON-NLS-1$
+    private static final String PREFS_STACK_COL_FILE = "threadPanel.stack.col2"; //$NON-NLS-1$
+    private static final String PREFS_STACK_COL_LINE = "threadPanel.stack.col3"; //$NON-NLS-1$
+    private static final String PREFS_STACK_COL_NATIVE = "threadPanel.stack.col4"; //$NON-NLS-1$
+    
+    private Display mDisplay;
+    private Composite mBase;
+    private Label mNotEnabled;
+    private Label mNotSelected;
+    
+    private Composite mThreadBase;
+    private Table mThreadTable;
+    private TableViewer mThreadViewer;
+
+    private Composite mStackTraceBase;
+    private Button mRefreshStackTraceButton;
+    private Label mStackTraceTimeLabel;
+    private StackTracePanel mStackTracePanel;
+    private Table mStackTraceTable;
+
+    /** Indicates if a timer-based Runnable is current requesting thread updates regularly. */
+    private boolean mMustStopRecurringThreadUpdate = false;
+    /** Flag to tell the recurring thread update to stop running */
+    private boolean mRecurringThreadUpdateRunning = false;
+
+    private Object mLock = new Object();
+
+    private static final String[] THREAD_STATUS = {
+        "zombie", "running", "timed-wait", "monitor",
+        "wait", "init", "start", "native", "vmwait"
+    };
+    
+    /**
+     * Content Provider to display the threads of a client.
+     * Expected input is a {@link Client} object.
+     */
+    private static class ThreadContentProvider implements IStructuredContentProvider {
+        public Object[] getElements(Object inputElement) {
+            if (inputElement instanceof Client) {
+                return ((Client)inputElement).getClientData().getThreads();
+            }
+
+            return new Object[0];
+        }
+
+        public void dispose() {
+            // pass
+        }
+
+        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+            // pass
+        }
+    }
+    
+
+    /**
+     * A Label Provider to use with {@link ThreadContentProvider}. It expects the elements to be
+     * of type {@link ThreadInfo}.
+     */
+    private static class ThreadLabelProvider implements ITableLabelProvider {
+
+        public Image getColumnImage(Object element, int columnIndex) {
+            return null;
+        }
+
+        public String getColumnText(Object element, int columnIndex) {
+            if (element instanceof ThreadInfo) {
+                ThreadInfo thread = (ThreadInfo)element;
+                switch (columnIndex) {
+                    case 0:
+                        return (thread.isDaemon() ? "*" : "") + //$NON-NLS-1$ //$NON-NLS-2$
+                            String.valueOf(thread.getThreadId());
+                    case 1:
+                        return String.valueOf(thread.getTid());
+                    case 2:
+                        if (thread.getStatus() >= 0 && thread.getStatus() < THREAD_STATUS.length)
+                            return THREAD_STATUS[thread.getStatus()];
+                        return "unknown";
+                    case 3:
+                        return String.valueOf(thread.getUtime());
+                    case 4:
+                        return String.valueOf(thread.getStime());
+                    case 5:
+                        return thread.getThreadName();
+                }
+            }
+
+            return null;
+        }
+
+        public void addListener(ILabelProviderListener listener) {
+            // pass
+        }
+
+        public void dispose() {
+            // pass
+        }
+
+        public boolean isLabelProperty(Object element, String property) {
+            // pass
+            return false;
+        }
+
+        public void removeListener(ILabelProviderListener listener) {
+            // pass
+        }
+    }
+
+    /**
+     * Create our control(s).
+     */
+    @Override
+    protected Control createControl(Composite parent) {
+        mDisplay = parent.getDisplay();
+
+        final IPreferenceStore store = DdmUiPreferences.getStore();
+
+        mBase = new Composite(parent, SWT.NONE);
+        mBase.setLayout(new StackLayout());
+
+        // UI for thread not enabled
+        mNotEnabled = new Label(mBase, SWT.CENTER | SWT.WRAP);
+        mNotEnabled.setText("Thread updates not enabled for selected client\n"
+            + "(use toolbar button to enable)");
+
+        // UI for not client selected
+        mNotSelected = new Label(mBase, SWT.CENTER | SWT.WRAP);
+        mNotSelected.setText("no client is selected");
+
+        // base composite for selected client with enabled thread update.
+        mThreadBase = new Composite(mBase, SWT.NONE);
+        mThreadBase.setLayout(new FormLayout());
+        
+        // table above the sash
+        mThreadTable = new Table(mThreadBase, SWT.MULTI | SWT.FULL_SELECTION);
+        mThreadTable.setHeaderVisible(true);
+        mThreadTable.setLinesVisible(true);
+
+        TableHelper.createTableColumn(
+                mThreadTable,
+                "ID",
+                SWT.RIGHT,
+                "888", //$NON-NLS-1$
+                PREFS_THREAD_COL_ID, store);
+
+        TableHelper.createTableColumn(
+                mThreadTable,
+                "Tid",
+                SWT.RIGHT,
+                "88888", //$NON-NLS-1$
+                PREFS_THREAD_COL_TID, store);
+
+        TableHelper.createTableColumn(
+                mThreadTable,
+                "Status",
+                SWT.LEFT,
+                "timed-wait", //$NON-NLS-1$
+                PREFS_THREAD_COL_STATUS, store);
+
+        TableHelper.createTableColumn(
+                mThreadTable,
+                "utime",
+                SWT.RIGHT,
+                "utime", //$NON-NLS-1$
+                PREFS_THREAD_COL_UTIME, store);
+
+        TableHelper.createTableColumn(
+                mThreadTable,
+                "stime",
+                SWT.RIGHT,
+                "utime", //$NON-NLS-1$
+                PREFS_THREAD_COL_STIME, store);
+
+        TableHelper.createTableColumn(
+                mThreadTable,
+                "Name",
+                SWT.LEFT,
+                "android.class.ReallyLongClassName.MethodName", //$NON-NLS-1$
+                PREFS_THREAD_COL_NAME, store);
+        
+        mThreadViewer = new TableViewer(mThreadTable);
+        mThreadViewer.setContentProvider(new ThreadContentProvider());
+        mThreadViewer.setLabelProvider(new ThreadLabelProvider());
+
+        mThreadViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+            public void selectionChanged(SelectionChangedEvent event) {
+                ThreadInfo selectedThread = getThreadSelection(event.getSelection());
+                updateThreadStackTrace(selectedThread);
+            }
+        });
+        mThreadViewer.addDoubleClickListener(new IDoubleClickListener() {
+            public void doubleClick(DoubleClickEvent event) {
+                ThreadInfo selectedThread = getThreadSelection(event.getSelection());
+                if (selectedThread != null) {
+                    Client client = (Client)mThreadViewer.getInput();
+                    
+                    if (client != null) {
+                        client.requestThreadStackTrace(selectedThread.getThreadId());
+                    }
+                }
+            }
+        });
+        
+        // the separating sash
+        final Sash sash = new Sash(mThreadBase, SWT.HORIZONTAL);
+        Color darkGray = parent.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
+        sash.setBackground(darkGray);
+        
+        // the UI below the sash
+        mStackTraceBase = new Composite(mThreadBase, SWT.NONE);
+        mStackTraceBase.setLayout(new GridLayout(2, false));
+
+        mRefreshStackTraceButton = new Button(mStackTraceBase, SWT.PUSH);
+        mRefreshStackTraceButton.setText("Refresh");
+        mRefreshStackTraceButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                ThreadInfo selectedThread = getThreadSelection(null);
+                if (selectedThread != null) {
+                    Client currentClient = getCurrentClient();
+                    if (currentClient != null) {
+                        currentClient.requestThreadStackTrace(selectedThread.getThreadId());
+                    }
+                }
+            }
+        });
+        
+        mStackTraceTimeLabel = new Label(mStackTraceBase, SWT.NONE);
+        mStackTraceTimeLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        mStackTracePanel = new StackTracePanel();
+        mStackTraceTable = mStackTracePanel.createPanel(mStackTraceBase,
+                PREFS_STACK_COL_CLASS,
+                PREFS_STACK_COL_METHOD,
+                PREFS_STACK_COL_FILE,
+                PREFS_STACK_COL_LINE,
+                PREFS_STACK_COL_NATIVE,
+                store);
+        
+        GridData gd;
+        mStackTraceTable.setLayoutData(gd = new GridData(GridData.FILL_BOTH));
+        gd.horizontalSpan = 2;
+        
+        // now setup the sash.
+        // form layout data
+        FormData data = new FormData();
+        data.top = new FormAttachment(0, 0);
+        data.bottom = new FormAttachment(sash, 0);
+        data.left = new FormAttachment(0, 0);
+        data.right = new FormAttachment(100, 0);
+        mThreadTable.setLayoutData(data);
+
+        final FormData sashData = new FormData();
+        if (store != null && store.contains(PREFS_THREAD_SASH)) {
+            sashData.top = new FormAttachment(0, store.getInt(PREFS_THREAD_SASH));
+        } else {
+            sashData.top = new FormAttachment(50,0); // 50% across
+        }
+        sashData.left = new FormAttachment(0, 0);
+        sashData.right = new FormAttachment(100, 0);
+        sash.setLayoutData(sashData);
+
+        data = new FormData();
+        data.top = new FormAttachment(sash, 0);
+        data.bottom = new FormAttachment(100, 0);
+        data.left = new FormAttachment(0, 0);
+        data.right = new FormAttachment(100, 0);
+        mStackTraceBase.setLayoutData(data);
+
+        // allow resizes, but cap at minPanelWidth
+        sash.addListener(SWT.Selection, new Listener() {
+            public void handleEvent(Event e) {
+                Rectangle sashRect = sash.getBounds();
+                Rectangle panelRect = mThreadBase.getClientArea();
+                int bottom = panelRect.height - sashRect.height - 100;
+                e.y = Math.max(Math.min(e.y, bottom), 100);
+                if (e.y != sashRect.y) {
+                    sashData.top = new FormAttachment(0, e.y);
+                    store.setValue(PREFS_THREAD_SASH, e.y);
+                    mThreadBase.layout();
+                }
+            }
+        });
+
+        ((StackLayout)mBase.getLayout()).topControl = mNotSelected;
+
+        return mBase;
+    }
+    
+    /**
+     * Sets the focus to the proper control inside the panel.
+     */
+    @Override
+    public void setFocus() {
+        mThreadTable.setFocus();
+    }
+
+    /**
+     * Sent when an existing client information changed.
+     * <p/>
+     * This is sent from a non UI thread.
+     * @param client the updated client.
+     * @param changeMask the bit mask describing the changed properties. It can contain
+     * any of the following values: {@link Client#CHANGE_INFO}, {@link Client#CHANGE_NAME}
+     * {@link Client#CHANGE_DEBUGGER_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) {
+        if (client == getCurrentClient()) {
+            if ((changeMask & Client.CHANGE_THREAD_MODE) != 0 ||
+                    (changeMask & Client.CHANGE_THREAD_DATA) != 0) {
+                try {
+                    mThreadTable.getDisplay().asyncExec(new Runnable() {
+                        public void run() {
+                            clientSelected();
+                        }
+                    });
+                } catch (SWTException e) {
+                    // widget is disposed, we do nothing
+                }
+            } else if ((changeMask & Client.CHANGE_THREAD_STACKTRACE) != 0) {
+                try {
+                    mThreadTable.getDisplay().asyncExec(new Runnable() {
+                        public void run() {
+                            updateThreadStackCall();
+                        }
+                    });
+                } catch (SWTException e) {
+                    // widget is disposed, we do nothing
+                }
+            }
+        }
+    }
+
+    /**
+     * Sent when a new device is selected. The new device can be accessed
+     * with {@link #getCurrentDevice()}.
+     */
+    @Override
+    public void deviceSelected() {
+        // pass
+    }
+
+    /**
+     * Sent when a new client is selected. The new client can be accessed
+     * with {@link #getCurrentClient()}.
+     */
+    @Override
+    public void clientSelected() {
+        if (mThreadTable.isDisposed()) {
+            return;
+        }
+
+        Client client = getCurrentClient();
+        
+        mStackTracePanel.setCurrentClient(client);
+
+        if (client != null) {
+            if (!client.isThreadUpdateEnabled()) {
+                ((StackLayout)mBase.getLayout()).topControl = mNotEnabled;
+                mThreadViewer.setInput(null);
+
+                // if we are currently updating the thread, stop doing it.
+                mMustStopRecurringThreadUpdate = true;
+            } else {
+                ((StackLayout)mBase.getLayout()).topControl = mThreadBase;
+                mThreadViewer.setInput(client);
+
+                synchronized (mLock) {
+                    // if we're not updating we start the process
+                    if (mRecurringThreadUpdateRunning == false) {
+                        startRecurringThreadUpdate();
+                    } else if (mMustStopRecurringThreadUpdate) {
+                        // else if there's a runnable that's still going to get called, lets
+                        // simply cancel the stop, and keep going
+                        mMustStopRecurringThreadUpdate = false;
+                    }
+                }
+            }
+        } else {
+            ((StackLayout)mBase.getLayout()).topControl = mNotSelected;
+            mThreadViewer.setInput(null);
+        }
+
+        mBase.layout();
+    }
+    
+    /**
+     * Updates the stack call of the currently selected thread.
+     * <p/>
+     * This <b>must</b> be called from the UI thread.
+     */
+    private void updateThreadStackCall() {
+        Client client = getCurrentClient();
+        if (client != null) {
+            // get the current selection in the ThreadTable
+            ThreadInfo selectedThread = getThreadSelection(null);
+            
+            if (selectedThread != null) {
+                updateThreadStackTrace(selectedThread);
+            } else {
+                updateThreadStackTrace(null);
+            }
+        }
+    }
+    
+    /**
+     * updates the stackcall of the specified thread. If <code>null</code> the UI is emptied
+     * of current data.
+     * @param thread
+     */
+    private void updateThreadStackTrace(ThreadInfo thread) {
+        mStackTracePanel.setViewerInput(thread);
+        
+        if (thread != null) {
+            mRefreshStackTraceButton.setEnabled(true);
+            long stackcallTime = thread.getStackCallTime();
+            if (stackcallTime != 0) {
+                String label = new Date(stackcallTime).toString();
+                mStackTraceTimeLabel.setText(label);
+            } else {
+                mStackTraceTimeLabel.setText(""); //$NON-NLS-1$
+            }
+        } else {
+            mRefreshStackTraceButton.setEnabled(true);
+            mStackTraceTimeLabel.setText(""); //$NON-NLS-1$
+        }
+    }
+
+    @Override
+    protected void setTableFocusListener() {
+        addTableToFocusListener(mThreadTable);
+        addTableToFocusListener(mStackTraceTable);
+    }
+
+    /**
+     * Initiate recurring events. We use a shorter "initialWait" so we do the
+     * first execution sooner. We don't do it immediately because we want to
+     * give the clients a chance to get set up.
+     */
+    private void startRecurringThreadUpdate() {
+        mRecurringThreadUpdateRunning = true;
+        int initialWait = 1000;
+
+        mDisplay.timerExec(initialWait, new Runnable() {
+            public void run() {
+                synchronized (mLock) {
+                    // lets check we still want updates.
+                    if (mMustStopRecurringThreadUpdate == false) {
+                        Client client = getCurrentClient();
+                        if (client != null) {
+                            client.requestThreadUpdate();
+
+                            mDisplay.timerExec(
+                                    DdmUiPreferences.getThreadRefreshInterval() * 1000, this);
+                        } else {
+                            // we don't have a Client, which means the runnable is not
+                            // going to be called through the timer. We reset the running flag.
+                            mRecurringThreadUpdateRunning = false;
+                        }
+                    } else {
+                        // else actually stops (don't call the timerExec) and reset the flags.
+                        mRecurringThreadUpdateRunning = false;
+                        mMustStopRecurringThreadUpdate = false;
+                    }
+                }
+            }
+        });
+    }
+    
+    /**
+     * Returns the current thread selection or <code>null</code> if none is found.
+     * If a {@link ISelection} object is specified, the first {@link ThreadInfo} from this selection
+     * is returned, otherwise, the <code>ISelection</code> returned by
+     * {@link TableViewer#getSelection()} is used.
+     * @param selection the {@link ISelection} to use, or <code>null</code>
+     */
+    private ThreadInfo getThreadSelection(ISelection selection) {
+        if (selection == null) {
+            selection = mThreadViewer.getSelection();
+        }
+        
+        if (selection instanceof IStructuredSelection) {
+            IStructuredSelection structuredSelection = (IStructuredSelection)selection;
+            Object object = structuredSelection.getFirstElement();
+            if (object instanceof ThreadInfo) {
+                return (ThreadInfo)object;
+            }
+        }
+        
+        return null;
+    }
+
+}
+
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/WritePng.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/WritePng.java
new file mode 100644
index 0000000..f65dafe
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/WritePng.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib;
+
+import com.android.ddmlib.Log;
+
+import org.eclipse.swt.graphics.ImageData;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.zip.CRC32;
+import java.util.zip.Deflater;
+
+/**
+ * Compensate for SWT issues by writing our own PNGs from ImageData.
+ */
+public class WritePng {
+    private WritePng() {}
+
+    private static final byte[] PNG_MAGIC =
+        new byte[] { -119, 80, 78, 71, 13, 10, 26, 10 };
+
+    public static void savePng(String fileName, ImageData imageData)
+        throws IOException {
+
+        try {
+            FileOutputStream out = new FileOutputStream(fileName);
+
+            Log.d("ddms", "Saving to PNG, width=" + imageData.width
+                + ", height=" + imageData.height
+                + ", depth=" + imageData.depth
+                + ", bpl=" + imageData.bytesPerLine);
+
+            savePng(out, imageData);
+
+            // need to do that on, or the file is empty on windows!
+            out.flush();
+            out.close();
+        } catch (Exception e) {
+            Log.e("writepng", e);
+        }
+    }
+
+    /*
+     * Supply functionality missing from our version of SWT.
+     */
+    private static void savePng(OutputStream out, ImageData imageData)
+        throws IOException {
+
+        int width = imageData.width;
+        int height = imageData.height;
+        byte[] out24;
+
+        Log.i("ddms-png", "Convert to 24bit from " + imageData.depth);
+
+        if (imageData.depth == 24 || imageData.depth == 32) {
+            out24 = convertTo24ForPng(imageData.data, width, height,
+                imageData.depth, imageData.bytesPerLine);
+        } else if (imageData.depth == 16) {
+            out24 = convert16to24(imageData);
+        } else {
+            return;
+        }
+
+        // Create the compressed form.  I'm taking the low road here and
+        // just creating a large buffer, which should always be enough to
+        // hold the compressed output.
+        byte[] compPixels = new byte[out24.length + 16384];
+        Deflater compressor = new Deflater();
+        compressor.setLevel(Deflater.BEST_COMPRESSION);
+        compressor.setInput(out24);
+        compressor.finish();
+        int compLen;
+        do {        // must do this in a loop to satisfy java.util.Zip
+            compLen = compressor.deflate(compPixels);
+            assert compLen != 0 || !compressor.needsInput();
+        } while (compLen == 0);
+        Log.d("ddms", "Compressed image data from " + out24.length
+            + " to " + compLen);
+
+        // Write the PNG magic
+        out.write(PNG_MAGIC);
+
+        ByteBuffer buf;
+        CRC32 crc;
+
+        // Write the IHDR chunk (13 bytes)
+        byte[] header = new byte[8 + 13 + 4];
+        buf = ByteBuffer.wrap(header);
+        buf.order(ByteOrder.BIG_ENDIAN);
+
+        putChunkHeader(buf, 13, "IHDR");
+        buf.putInt(width);
+        buf.putInt(height);
+        buf.put((byte) 8);       // 8pp
+        buf.put((byte) 2);       // direct color used
+        buf.put((byte) 0);       // compression method == deflate
+        buf.put((byte) 0);       // filter method (none)
+        buf.put((byte) 0);       // interlace method (none)
+
+        crc = new CRC32();
+        crc.update(header, 4, 4+13);
+        buf.putInt((int)crc.getValue());
+
+        out.write(header);
+
+        // Write the IDAT chunk
+        byte[] datHdr = new byte[8 + 0 + 4];
+        buf = ByteBuffer.wrap(datHdr);
+        buf.order(ByteOrder.BIG_ENDIAN);
+
+        putChunkHeader(buf, compLen, "IDAT");
+        crc = new CRC32();
+        crc.update(datHdr, 4, 4+0);
+        crc.update(compPixels, 0, compLen);
+        buf.putInt((int) crc.getValue());
+
+        out.write(datHdr, 0, 8);
+        out.write(compPixels, 0, compLen);
+        out.write(datHdr, 8, 4);
+
+        // Write the IEND chunk (0 bytes)
+        byte[] trailer = new byte[8 + 0 + 4];
+
+        buf = ByteBuffer.wrap(trailer);
+        buf.order(ByteOrder.BIG_ENDIAN);
+        putChunkHeader(buf, 0, "IEND");
+
+        crc = new CRC32();
+        crc.update(trailer, 4, 4+0);
+        buf.putInt((int)crc.getValue());
+
+        out.write(trailer);
+    }
+
+    /*
+     * Output a chunk header.
+     */
+    private static void putChunkHeader(ByteBuffer buf, int length,
+        String typeStr) {
+
+        int type = 0;
+
+        if (typeStr.length() != 4)
+            throw new RuntimeException();
+
+        for (int i = 0; i < 4; i++) {
+            type <<= 8;
+            type |= (byte) typeStr.charAt(i);
+        }
+
+        buf.putInt(length);
+        buf.putInt(type);
+    }
+
+    /*
+     * Convert raw pixels to 24-bit RGB with a "filter" byte at the start
+     * of each row.
+     */
+    private static byte[] convertTo24ForPng(byte[] in, int width, int height,
+        int depth, int stride) {
+
+        assert depth == 24 || depth == 32;
+        assert stride == width * (depth/8);
+
+        // 24 bit pixels plus one byte per line for "filter"
+        byte[] out24 = new byte[width * height * 3 + height];
+        int y;
+
+        int inOff = 0;
+        int outOff = 0;
+        for (y = 0; y < height; y++) {
+            out24[outOff++] = 0;           // filter flag
+
+            if (depth == 24) {
+                System.arraycopy(in, inOff, out24, outOff, width * 3);
+                outOff += width * 3;
+            } else if (depth == 32) {
+                int tmpOff = inOff;
+                for (int x = 0; x < width; x++) {
+                    tmpOff++;       // ignore alpha
+                    out24[outOff++] = in[tmpOff++];
+                    out24[outOff++] = in[tmpOff++];
+                    out24[outOff++] = in[tmpOff++];
+                }
+            }
+
+            inOff += stride;
+        }
+
+        assert outOff == out24.length;
+
+        return out24;
+    }
+
+    private static byte[] convert16to24(ImageData imageData) {
+        int width = imageData.width;
+        int height = imageData.height;
+
+        int redShift = imageData.palette.redShift;
+        int greenShift = imageData.palette.greenShift;
+        int blueShift = imageData.palette.blueShift;
+
+        int redMask = imageData.palette.redMask;
+        int greenMask = imageData.palette.greenMask;
+        int blueMask = imageData.palette.blueMask;
+
+        // 24 bit pixels plus one byte per line for "filter"
+        byte[] out24 = new byte[width * height * 3 + height];
+        int outOff = 0;
+
+
+        int[] line = new int[width];
+        for (int y = 0; y < height; y++) {
+            imageData.getPixels(0, y, width, line, 0);
+
+            out24[outOff++] = 0; // filter flag
+            for (int x = 0; x < width; x++) {
+                int pixelValue = line[x];
+                out24[outOff++] = byteChannelValue(pixelValue, redMask, redShift);
+                out24[outOff++] = byteChannelValue(pixelValue, greenMask, greenShift);
+                out24[outOff++] = byteChannelValue(pixelValue, blueMask, blueShift);
+            }
+        }
+
+        return out24;
+    }
+
+    private static byte byteChannelValue(int value, int mask, int shift) {
+        int bValue = value & mask;
+        if (shift < 0) {
+            bValue = bValue >>> -shift;
+        } else {
+            bValue = bValue << shift;
+        }
+
+        return (byte)bValue;
+
+    }
+
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/actions/ICommonAction.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/actions/ICommonAction.java
new file mode 100644
index 0000000..856b874
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/actions/ICommonAction.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.actions;
+
+/**
+ * Common interface for basic action handling. This allows the common ui
+ * components to access ToolItem or Action the same way.
+ */
+public interface ICommonAction {
+    /**
+     * Sets the enabled state of this action.
+     * @param enabled <code>true</code> to enable, and
+     *   <code>false</code> to disable
+     */
+    public void setEnabled(boolean enabled);
+
+    /**
+     * Sets the checked status of this action.
+     * @param checked the new checked status
+     */
+    public void setChecked(boolean checked);
+    
+    /**
+     * Sets the {@link Runnable} that will be executed when the action is triggered.
+     */
+    public void setRunnable(Runnable runnable);
+}
+
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/actions/ToolItemAction.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/actions/ToolItemAction.java
new file mode 100644
index 0000000..bc1598f
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/actions/ToolItemAction.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.actions;
+
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+/**
+ * Wrapper around {@link ToolItem} to implement {@link ICommonAction}
+ */
+public class ToolItemAction implements ICommonAction {
+    public ToolItem item;
+
+    public ToolItemAction(ToolBar parent, int style) {
+        item = new ToolItem(parent, style);
+    }
+
+    /**
+     * Sets the enabled state of this action.
+     * @param enabled <code>true</code> to enable, and
+     *   <code>false</code> to disable
+     * @see ICommonAction#setChecked(boolean)
+     */
+    public void setChecked(boolean checked) {
+        item.setSelection(checked);
+    }
+
+    /**
+     * Sets the enabled state of this action.
+     * @param enabled <code>true</code> to enable, and
+     *   <code>false</code> to disable
+     * @see ICommonAction#setEnabled(boolean)
+     */
+    public void setEnabled(boolean enabled) {
+        item.setEnabled(enabled);
+    }
+
+    /**
+     * Sets the {@link Runnable} that will be executed when the action is triggered (through
+     * {@link SelectionListener#widgetSelected(SelectionEvent)} on the wrapped {@link ToolItem}).
+     * @see ICommonAction#setRunnable(Runnable)
+     */
+    public void setRunnable(final Runnable runnable) {
+        item.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                runnable.run();
+            }
+        });
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/annotation/UiThread.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/annotation/UiThread.java
new file mode 100644
index 0000000..8e9e11b
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/annotation/UiThread.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.annotation;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Simple utility annotation used only to mark methods that are executed on the UI thread.
+ * This annotation's sole purpose is to help reading the source code. It has no additional effect.
+ */
+@Target({ ElementType.METHOD })
+@Retention(RetentionPolicy.SOURCE)
+public @interface UiThread {
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/annotation/WorkerThread.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/annotation/WorkerThread.java
new file mode 100644
index 0000000..e767eda
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/annotation/WorkerThread.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.annotation;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Simple utility annotation used only to mark methods that are not executed on the UI thread.
+ * This annotation's sole purpose is to help reading the source code. It has no additional effect.
+ */
+@Target({ ElementType.METHOD })
+@Retention(RetentionPolicy.SOURCE)
+public @interface WorkerThread {
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/console/DdmConsole.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/console/DdmConsole.java
new file mode 100644
index 0000000..4df4376
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/console/DdmConsole.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.console;
+
+
+/**
+ * Static Console used to ouput messages. By default outputs the message to System.out and
+ * System.err, but can receive a IDdmConsole object which will actually do something.
+ */
+public class DdmConsole {
+
+    private static IDdmConsole mConsole;
+
+    /**
+     * Prints a message to the android console.
+     * @param message the message to print
+     * @param forceDisplay if true, this force the console to be displayed.
+     */
+    public static void printErrorToConsole(String message) {
+        if (mConsole != null) {
+            mConsole.printErrorToConsole(message);
+        } else {
+            System.err.println(message);
+        }
+    }
+
+    /**
+     * Prints several messages to the android console.
+     * @param messages the messages to print
+     * @param forceDisplay if true, this force the console to be displayed.
+     */
+    public static void printErrorToConsole(String[] messages) {
+        if (mConsole != null) {
+            mConsole.printErrorToConsole(messages);
+        } else {
+            for (String message : messages) {
+                System.err.println(message);
+            }
+        }
+    }
+
+    /**
+     * Prints a message to the android console.
+     * @param message the message to print
+     * @param forceDisplay if true, this force the console to be displayed.
+     */
+    public static void printToConsole(String message) {
+        if (mConsole != null) {
+            mConsole.printToConsole(message);
+        } else {
+            System.out.println(message);
+        }
+    }
+
+    /**
+     * Prints several messages to the android console.
+     * @param messages the messages to print
+     * @param forceDisplay if true, this force the console to be displayed.
+     */
+    public static void printToConsole(String[] messages) {
+        if (mConsole != null) {
+            mConsole.printToConsole(messages);
+        } else {
+            for (String message : messages) {
+                System.out.println(message);
+            }
+        }
+    }
+
+    /**
+     * Sets a IDdmConsole to override the default behavior of the console
+     * @param console The new IDdmConsole
+     * **/
+    public static void setConsole(IDdmConsole console) {
+        mConsole = console;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/console/IDdmConsole.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/console/IDdmConsole.java
new file mode 100644
index 0000000..3679d41
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/console/IDdmConsole.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.console;
+
+
+/**
+ * DDMS console interface.
+ */
+public interface IDdmConsole {
+    /**
+     * Prints a message to the android console.
+     * @param message the message to print
+     */
+    public void printErrorToConsole(String message);
+
+    /**
+     * Prints several messages to the android console.
+     * @param messages the messages to print
+     */
+    public void printErrorToConsole(String[] messages);
+
+    /**
+     * Prints a message to the android console.
+     * @param message the message to print
+     */
+    public void printToConsole(String message);
+
+    /**
+     * Prints several messages to the android console.
+     * @param messages the messages to print
+     */
+    public void printToConsole(String[] messages);
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceContentProvider.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceContentProvider.java
new file mode 100644
index 0000000..75c19fe
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceContentProvider.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.explorer;
+
+import com.android.ddmlib.FileListingService;
+import com.android.ddmlib.FileListingService.FileEntry;
+import com.android.ddmlib.FileListingService.IListingReceiver;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Tree;
+
+/**
+ * Content provider class for device Explorer.
+ */
+class DeviceContentProvider implements ITreeContentProvider {
+
+    private TreeViewer mViewer;
+    private FileListingService mFileListingService;
+    private FileEntry mRootEntry;
+
+    private IListingReceiver sListingReceiver = new IListingReceiver() {
+        public void setChildren(final FileEntry entry, FileEntry[] children) {
+            final Tree t = mViewer.getTree();
+            if (t != null && t.isDisposed() == false) {
+                Display display = t.getDisplay();
+                if (display.isDisposed() == false) {
+                    display.asyncExec(new Runnable() {
+                        public void run() {
+                            if (t.isDisposed() == false) {
+                                // refresh the entry.
+                                mViewer.refresh(entry);
+
+                                // force it open, since on linux and windows
+                                // when getChildren() returns null, the node is
+                                // not considered expanded.
+                                mViewer.setExpandedState(entry, true);
+                            }
+                        }
+                    });
+                }
+            }
+        }
+
+        public void refreshEntry(final FileEntry entry) {
+            final Tree t = mViewer.getTree();
+            if (t != null && t.isDisposed() == false) {
+                Display display = t.getDisplay();
+                if (display.isDisposed() == false) {
+                    display.asyncExec(new Runnable() {
+                        public void run() {
+                            if (t.isDisposed() == false) {
+                                // refresh the entry.
+                                mViewer.refresh(entry);
+                            }
+                        }
+                    });
+                }
+            }
+        }
+    };
+
+    /**
+     *
+     */
+    public DeviceContentProvider() {
+    }
+
+    public void setListingService(FileListingService fls) {
+        mFileListingService = fls;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+     */
+    public Object[] getChildren(Object parentElement) {
+        if (parentElement instanceof FileEntry) {
+            FileEntry parentEntry = (FileEntry)parentElement;
+
+            Object[] oldEntries = parentEntry.getCachedChildren();
+            Object[] newEntries = mFileListingService.getChildren(parentEntry,
+                    true, sListingReceiver);
+
+            if (newEntries != null) {
+                return newEntries;
+            } else {
+                // if null was returned, this means the cache was not valid,
+                // and a thread was launched for ls. sListingReceiver will be
+                // notified with the new entries.
+                return oldEntries;
+            }
+        }
+        return new Object[0];
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+     */
+    public Object getParent(Object element) {
+        if (element instanceof FileEntry) {
+            FileEntry entry = (FileEntry)element;
+
+            return entry.getParent();
+        }
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+     */
+    public boolean hasChildren(Object element) {
+        if (element instanceof FileEntry) {
+            FileEntry entry = (FileEntry)element;
+
+            return entry.getType() == FileListingService.TYPE_DIRECTORY;
+        }
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+     */
+    public Object[] getElements(Object inputElement) {
+        if (inputElement instanceof FileEntry) {
+            FileEntry entry = (FileEntry)inputElement;
+            if (entry.isRoot()) {
+                return getChildren(mRootEntry);
+            }
+        }
+
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+     */
+    public void dispose() {
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+     */
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+        if (viewer instanceof TreeViewer) {
+            mViewer = (TreeViewer)viewer;
+        }
+        if (newInput instanceof FileEntry) {
+            mRootEntry = (FileEntry)newInput;
+        }
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java
new file mode 100644
index 0000000..ba0f555
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/DeviceExplorer.java
@@ -0,0 +1,833 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.explorer;
+
+import com.android.ddmlib.Device;
+import com.android.ddmlib.FileListingService;
+import com.android.ddmlib.IShellOutputReceiver;
+import com.android.ddmlib.SyncService;
+import com.android.ddmlib.FileListingService.FileEntry;
+import com.android.ddmlib.SyncService.ISyncProgressMonitor;
+import com.android.ddmlib.SyncService.SyncResult;
+import com.android.ddmuilib.DdmUiPreferences;
+import com.android.ddmuilib.Panel;
+import com.android.ddmuilib.TableHelper;
+import com.android.ddmuilib.actions.ICommonAction;
+import com.android.ddmuilib.console.DdmConsole;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerDropAdapter;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.DirectoryDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Device filesystem explorer class.
+ */
+public class DeviceExplorer extends Panel {
+
+    private final static String TRACE_KEY_EXT = ".key"; // $NON-NLS-1S
+    private final static String TRACE_DATA_EXT = ".data"; // $NON-NLS-1S
+
+    private static Pattern mKeyFilePattern = Pattern.compile(
+            "(.+)\\" + TRACE_KEY_EXT); // $NON-NLS-1S
+    private static Pattern mDataFilePattern = Pattern.compile(
+            "(.+)\\" + TRACE_DATA_EXT); // $NON-NLS-1S
+
+    public static String COLUMN_NAME = "android.explorer.name"; //$NON-NLS-1S
+    public static String COLUMN_SIZE = "android.explorer.size"; //$NON-NLS-1S
+    public static String COLUMN_DATE = "android.explorer.data"; //$NON-NLS-1S
+    public static String COLUMN_TIME = "android.explorer.time"; //$NON-NLS-1S
+    public static String COLUMN_PERMISSIONS = "android.explorer.permissions"; // $NON-NLS-1S
+    public static String COLUMN_INFO = "android.explorer.info"; // $NON-NLS-1S
+
+    private Composite mParent;
+    private TreeViewer mTreeViewer;
+    private Tree mTree;
+    private DeviceContentProvider mContentProvider;
+
+    private ICommonAction mPushAction;
+    private ICommonAction mPullAction;
+    private ICommonAction mDeleteAction;
+
+    private Image mFileImage;
+    private Image mFolderImage;
+    private Image mPackageImage;
+    private Image mOtherImage;
+
+    private Device mCurrentDevice;
+
+    private String mDefaultSave;
+
+    /**
+     * Implementation of the SyncService.ISyncProgressMonitor. It wraps a jFace IProgressMonitor
+     * and just forward the calls to the jFace object.
+     */
+    private static class SyncProgressMonitor implements ISyncProgressMonitor {
+
+        private IProgressMonitor mMonitor;
+        private String mName;
+
+        SyncProgressMonitor(IProgressMonitor monitor, String name) {
+            mMonitor = monitor;
+            mName = name;
+        }
+
+        public void start(int totalWork) {
+            mMonitor.beginTask(mName, totalWork);
+        }
+
+        public void stop() {
+            mMonitor.done();
+        }
+
+        public void advance(int work) {
+            mMonitor.worked(work);
+        }
+
+        public boolean isCanceled() {
+            return mMonitor.isCanceled();
+        }
+
+        public void startSubTask(String name) {
+            mMonitor.subTask(name);
+        }
+    }
+
+    public DeviceExplorer() {
+
+    }
+
+    /**
+     * Sets the images for the listview
+     * @param fileImage
+     * @param folderImage
+     * @param otherImage
+     */
+    public void setImages(Image fileImage, Image folderImage, Image packageImage,
+            Image otherImage) {
+        mFileImage = fileImage;
+        mFolderImage = folderImage;
+        mPackageImage = packageImage;
+        mOtherImage = otherImage;
+    }
+
+    /**
+     * Sets the actions so that the device explorer can enable/disable them based on the current
+     * selection
+     * @param pushAction
+     * @param pullAction
+     * @param deleteAction
+     */
+    public void setActions(ICommonAction pushAction, ICommonAction pullAction,
+            ICommonAction deleteAction) {
+        mPushAction = pushAction;
+        mPullAction = pullAction;
+        mDeleteAction = deleteAction;
+    }
+
+    /**
+     * Creates a control capable of displaying some information.  This is
+     * called once, when the application is initializing, from the UI thread.
+     */
+    @Override
+    protected Control createControl(Composite parent) {
+        mParent = parent;
+        parent.setLayout(new FillLayout());
+
+        mTree = new Tree(parent, SWT.MULTI | SWT.FULL_SELECTION | SWT.VIRTUAL);
+        mTree.setHeaderVisible(true);
+
+        IPreferenceStore store = DdmUiPreferences.getStore();
+
+        // create columns
+        TableHelper.createTreeColumn(mTree, "Name", SWT.LEFT,
+                "0000drwxrwxrwx", COLUMN_NAME, store); //$NON-NLS-1$
+        TableHelper.createTreeColumn(mTree, "Size", SWT.RIGHT,
+                "000000", COLUMN_SIZE, store); //$NON-NLS-1$
+        TableHelper.createTreeColumn(mTree, "Date", SWT.LEFT,
+                "2007-08-14", COLUMN_DATE, store); //$NON-NLS-1$
+        TableHelper.createTreeColumn(mTree, "Time", SWT.LEFT,
+                "20:54", COLUMN_TIME, store); //$NON-NLS-1$
+        TableHelper.createTreeColumn(mTree, "Permissions", SWT.LEFT,
+                "drwxrwxrwx", COLUMN_PERMISSIONS, store); //$NON-NLS-1$
+        TableHelper.createTreeColumn(mTree, "Info", SWT.LEFT,
+                "drwxrwxrwx", COLUMN_INFO, store); //$NON-NLS-1$
+
+        // create the jface wrapper
+        mTreeViewer = new TreeViewer(mTree);
+
+        // setup data provider
+        mContentProvider = new DeviceContentProvider();
+        mTreeViewer.setContentProvider(mContentProvider);
+        mTreeViewer.setLabelProvider(new FileLabelProvider(mFileImage,
+                mFolderImage, mPackageImage, mOtherImage));
+
+        // setup a listener for selection
+        mTreeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+            public void selectionChanged(SelectionChangedEvent event) {
+                ISelection sel = event.getSelection();
+                if (sel.isEmpty()) {
+                    mPullAction.setEnabled(false);
+                    mPushAction.setEnabled(false);
+                    mDeleteAction.setEnabled(false);
+                    return;
+                }
+                if (sel instanceof IStructuredSelection) {
+                    IStructuredSelection selection = (IStructuredSelection) sel;
+                    Object element = selection.getFirstElement();
+                    if (element == null)
+                        return;
+                    if (element instanceof FileEntry) {
+                        mPullAction.setEnabled(true);
+                        mPushAction.setEnabled(selection.size() == 1);
+                        if (selection.size() == 1) {
+                            setDeleteEnabledState((FileEntry)element);
+                        } else {
+                            mDeleteAction.setEnabled(false);
+                        }
+                    }
+                }
+            }
+        });
+
+        // add support for double click
+        mTreeViewer.addDoubleClickListener(new IDoubleClickListener() {
+            public void doubleClick(DoubleClickEvent event) {
+                ISelection sel = event.getSelection();
+
+                if (sel instanceof IStructuredSelection) {
+                    IStructuredSelection selection = (IStructuredSelection) sel;
+
+                    if (selection.size() == 1) {
+                        FileEntry entry = (FileEntry)selection.getFirstElement();
+                        String name = entry.getName();
+
+                        FileEntry parentEntry = entry.getParent();
+
+                        // can't really do anything with no parent
+                        if (parentEntry == null) {
+                            return;
+                        }
+
+                        // check this is a file like we want.
+                        Matcher m = mKeyFilePattern.matcher(name);
+                        if (m.matches()) {
+                            // get the name w/o the extension
+                            String baseName = m.group(1);
+
+                            // add the data extension
+                            String dataName = baseName + TRACE_DATA_EXT;
+
+                            FileEntry dataEntry = parentEntry.findChild(dataName);
+
+                            handleTraceDoubleClick(baseName, entry, dataEntry);
+
+                        } else {
+                            m = mDataFilePattern.matcher(name);
+                            if (m.matches()) {
+                                // get the name w/o the extension
+                                String baseName = m.group(1);
+
+                                // add the key extension
+                                String keyName = baseName + TRACE_KEY_EXT;
+
+                                FileEntry keyEntry = parentEntry.findChild(keyName);
+
+                                handleTraceDoubleClick(baseName, keyEntry, entry);
+                            }
+                        }
+                    }
+                }
+            }
+        });
+
+        // setup drop listener
+        mTreeViewer.addDropSupport(DND.DROP_COPY | DND.DROP_MOVE,
+                new Transfer[] { FileTransfer.getInstance() },
+                new ViewerDropAdapter(mTreeViewer) {
+            @Override
+            public boolean performDrop(Object data) {
+                // get the item on which we dropped the item(s)
+                FileEntry target = (FileEntry)getCurrentTarget();
+
+                // in case we drop at the same level as root
+                if (target == null) {
+                    return false;
+                }
+
+                // if the target is not a directory, we get the parent directory
+                if (target.isDirectory() == false) {
+                    target = target.getParent();
+                }
+
+                if (target == null) {
+                    return false;
+                }
+
+                // get the list of files to drop
+                String[] files = (String[])data;
+
+                // do the drop
+                pushFiles(files, target);
+
+                // we need to finish with a refresh
+                refresh(target);
+
+                return true;
+            }
+
+            @Override
+            public boolean validateDrop(Object target, int operation, TransferData transferType) {
+                if (target == null) {
+                    return false;
+                }
+
+                // convert to the real item
+                FileEntry targetEntry = (FileEntry)target;
+
+                // if the target is not a directory, we get the parent directory
+                if (targetEntry.isDirectory() == false) {
+                    target = targetEntry.getParent();
+                }
+
+                if (target == null) {
+                    return false;
+                }
+
+                return true;
+            }
+        });
+
+        // create and start the refresh thread
+        new Thread("Device Ls refresher") {
+            @Override
+            public void run() {
+                while (true) {
+                    try {
+                        sleep(FileListingService.REFRESH_RATE);
+                    } catch (InterruptedException e) {
+                        return;
+                    }
+
+                    if (mTree != null && mTree.isDisposed() == false) {
+                        Display display = mTree.getDisplay();
+                        if (display.isDisposed() == false) {
+                            display.asyncExec(new Runnable() {
+                                public void run() {
+                                    if (mTree.isDisposed() == false) {
+                                        mTreeViewer.refresh(true);
+                                    }
+                                }
+                            });
+                        } else {
+                            return;
+                        }
+                    } else {
+                        return;
+                    }
+                }
+
+            }
+        }.start();
+        
+        return mTree;
+    }
+    
+    @Override
+    protected void postCreation() {
+        
+    }
+
+    /**
+     * Sets the focus to the proper control inside the panel.
+     */
+    @Override
+    public void setFocus() {
+        mTree.setFocus();
+    }
+
+    /**
+     * Processes a double click on a trace file
+     * @param baseName the base name of the 2 files.
+     * @param keyEntry The FileEntry for the .key file.
+     * @param dataEntry The FileEntry for the .data file.
+     */
+    private void handleTraceDoubleClick(String baseName, FileEntry keyEntry,
+            FileEntry dataEntry) {
+        // first we need to download the files.
+        File keyFile;
+        File dataFile;
+        String path;
+        try {
+            // create a temp file for keyFile
+            File f = File.createTempFile(baseName, ".trace");
+            f.delete();
+            f.mkdir();
+
+            path = f.getAbsolutePath();
+
+            keyFile = new File(path + File.separator + keyEntry.getName());
+            dataFile = new File(path + File.separator + dataEntry.getName());
+        } catch (IOException e) {
+            return;
+        }
+
+        // download the files
+        SyncService sync = mCurrentDevice.getSyncService();
+        if (sync != null) {
+            ISyncProgressMonitor monitor = SyncService.getNullProgressMonitor();
+            SyncResult result = sync.pullFile(keyEntry, keyFile.getAbsolutePath(), monitor);
+            if (result.getCode() != SyncService.RESULT_OK) {
+                DdmConsole.printErrorToConsole(String.format(
+                        "Failed to pull %1$s: %2$s", keyEntry.getName(), result.getMessage()));
+                return;
+            }
+
+            result = sync.pullFile(dataEntry, dataFile.getAbsolutePath(), monitor);
+            if (result.getCode() != SyncService.RESULT_OK) {
+                DdmConsole.printErrorToConsole(String.format(
+                        "Failed to pull %1$s: %2$s", dataEntry.getName(), result.getMessage()));
+                return;
+            }
+
+            // now that we have the file, we need to launch traceview
+            String[] command = new String[2];
+            command[0] = DdmUiPreferences.getTraceview();
+            command[1] = path + File.separator + baseName;
+
+            try {
+                final Process p = Runtime.getRuntime().exec(command);
+
+                // create a thread for the output
+                new Thread("Traceview output") {
+                    @Override
+                    public void run() {
+                        // create a buffer to read the stderr output
+                        InputStreamReader is = new InputStreamReader(p.getErrorStream());
+                        BufferedReader resultReader = new BufferedReader(is);
+
+                        // read the lines as they come. if null is returned, it's
+                        // because the process finished
+                        try {
+                            while (true) {
+                                String line = resultReader.readLine();
+                                if (line != null) {
+                                    DdmConsole.printErrorToConsole("Traceview: " + line);
+                                } else {
+                                    break;
+                                }
+                            }
+                            // get the return code from the process
+                            p.waitFor();
+                        } catch (IOException e) {
+                        } catch (InterruptedException e) {
+
+                        }
+                    }
+                }.start();
+
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    /**
+     * Pull the current selection on the local drive. This method displays
+     * a dialog box to let the user select where to store the file(s) and
+     * folder(s).
+     */
+    public void pullSelection() {
+        // get the selection
+        TreeItem[] items = mTree.getSelection();
+
+        // name of the single file pull, or null if we're pulling a directory
+        // or more than one object.
+        String filePullName = null;
+        FileEntry singleEntry = null;
+
+        // are we pulling a single file?
+        if (items.length == 1) {
+            singleEntry = (FileEntry)items[0].getData();
+            if (singleEntry.getType() == FileListingService.TYPE_FILE) {
+                filePullName = singleEntry.getName();
+            }
+        }
+
+        // where do we save by default?
+        String defaultPath = mDefaultSave;
+        if (defaultPath == null) {
+            defaultPath = System.getProperty("user.home"); //$NON-NLS-1$
+        }
+
+        if (filePullName != null) {
+            FileDialog fileDialog = new FileDialog(mParent.getShell(), SWT.SAVE);
+
+            fileDialog.setText("Get Device File");
+            fileDialog.setFileName(filePullName);
+            fileDialog.setFilterPath(defaultPath);
+
+            String fileName = fileDialog.open();
+            if (fileName != null) {
+                mDefaultSave = fileDialog.getFilterPath();
+
+                pullFile(singleEntry, fileName);
+            }
+        } else {
+            DirectoryDialog directoryDialog = new DirectoryDialog(mParent.getShell(), SWT.SAVE);
+
+            directoryDialog.setText("Get Device Files/Folders");
+            directoryDialog.setFilterPath(defaultPath);
+
+            String directoryName = directoryDialog.open();
+            if (directoryName != null) {
+                pullSelection(items, directoryName);
+            }
+        }
+    }
+
+    /**
+     * Push new file(s) and folder(s) into the current selection. Current
+     * selection must be single item. If the current selection is not a
+     * directory, the parent directory is used.
+     * This method displays a dialog to let the user choose file to push to
+     * the device.
+     */
+    public void pushIntoSelection() {
+        // get the name of the object we're going to pull
+        TreeItem[] items = mTree.getSelection();
+
+        if (items.length == 0) {
+            return;
+        }
+
+        FileDialog dlg = new FileDialog(mParent.getShell(), SWT.OPEN);
+        String fileName;
+
+        dlg.setText("Put File on Device");
+
+        // There should be only one.
+        FileEntry entry = (FileEntry)items[0].getData();
+        dlg.setFileName(entry.getName());
+
+        String defaultPath = mDefaultSave;
+        if (defaultPath == null) {
+            defaultPath = System.getProperty("user.home"); //$NON-NLS-1$
+        }
+        dlg.setFilterPath(defaultPath);
+
+        fileName = dlg.open();
+        if (fileName != null) {
+            mDefaultSave = dlg.getFilterPath();
+
+            // we need to figure out the remote path based on the current selection type.
+            String remotePath;
+            FileEntry toRefresh = entry;
+            if (entry.isDirectory()) {
+                remotePath = entry.getFullPath();
+            } else {
+                toRefresh = entry.getParent();
+                remotePath = toRefresh.getFullPath();
+            }
+
+            pushFile(fileName, remotePath);
+            mTreeViewer.refresh(toRefresh);
+        }
+    }
+
+    public void deleteSelection() {
+        // get the name of the object we're going to pull
+        TreeItem[] items = mTree.getSelection();
+
+        if (items.length != 1) {
+            return;
+        }
+
+        FileEntry entry = (FileEntry)items[0].getData();
+        final FileEntry parentEntry = entry.getParent();
+
+        // create the delete command
+        String command = "rm " + entry.getFullEscapedPath(); //$NON-NLS-1$
+
+        try {
+            mCurrentDevice.executeShellCommand(command, new IShellOutputReceiver() {
+                public void addOutput(byte[] data, int offset, int length) {
+                    // pass
+                    // TODO get output to display errors if any.
+                }
+
+                public void flush() {
+                    mTreeViewer.refresh(parentEntry);
+                }
+
+                public boolean isCancelled() {
+                    return false;
+                }
+            });
+        } catch (IOException e) {
+            // adb failed somehow, we do nothing. We should be displaying the error from the output
+            // of the shell command.
+        }
+
+    }
+
+    /**
+     * Force a full refresh of the explorer.
+     */
+    public void refresh() {
+        mTreeViewer.refresh(true);
+    }
+
+    /**
+     * Sets the new device to explorer
+     */
+    public void switchDevice(final Device device) {
+        if (device != mCurrentDevice) {
+            mCurrentDevice = device;
+            // now we change the input. but we need to do that in the
+            // ui thread.
+            if (mTree.isDisposed() == false) {
+                Display d = mTree.getDisplay();
+                d.asyncExec(new Runnable() {
+                    public void run() {
+                        if (mTree.isDisposed() == false) {
+                            // new service
+                            if (mCurrentDevice != null) {
+                                FileListingService fls = mCurrentDevice.getFileListingService();
+                                mContentProvider.setListingService(fls);
+                                mTreeViewer.setInput(fls.getRoot());
+                            }
+                        }
+                    }
+                });
+            }
+        }
+    }
+
+    /**
+     * Refresh an entry from a non ui thread.
+     * @param entry the entry to refresh.
+     */
+    private void refresh(final FileEntry entry) {
+        Display d = mTreeViewer.getTree().getDisplay();
+        d.asyncExec(new Runnable() {
+            public void run() {
+                mTreeViewer.refresh(entry);
+            }
+        });
+    }
+
+    /**
+     * Pulls the selection from a device.
+     * @param items the tree selection the remote file on the device
+     * @param localDirector the local directory in which to save the files.
+     */
+    private void pullSelection(TreeItem[] items, final String localDirectory) {
+        final SyncService sync = mCurrentDevice.getSyncService();
+        if (sync != null) {
+            // make a list of the FileEntry.
+            ArrayList<FileEntry> entries = new ArrayList<FileEntry>();
+            for (TreeItem item : items) {
+                Object data = item.getData();
+                if (data instanceof FileEntry) {
+                    entries.add((FileEntry)data);
+                }
+            }
+            final FileEntry[] entryArray = entries.toArray(
+                    new FileEntry[entries.size()]);
+
+            // get a progressdialog
+            try {
+                new ProgressMonitorDialog(mParent.getShell()).run(true, true,
+                        new IRunnableWithProgress() {
+                    public void run(IProgressMonitor monitor)
+                            throws InvocationTargetException,
+                            InterruptedException {
+                        // create a monitor wrapper around the jface monitor
+                        SyncResult result = sync.pull(entryArray, localDirectory,
+                                new SyncProgressMonitor(monitor,
+                                        "Pulling file(s) from the device"));
+
+                        if (result.getCode() != SyncService.RESULT_OK) {
+                            DdmConsole.printErrorToConsole(String.format(
+                                    "Failed to pull selection: %1$s", result.getMessage()));
+                        }
+                        sync.close();
+                    }
+                });
+            } catch (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());
+            }
+        }
+    }
+
+    /**
+     * Pulls a file from a device.
+     * @param remote the remote file on the device
+     * @param local the destination filepath
+     */
+    private void pullFile(final FileEntry remote, final String local) {
+        final SyncService sync = mCurrentDevice.getSyncService();
+        if (sync != null) {
+            try {
+                new ProgressMonitorDialog(mParent.getShell()).run(true, true,
+                        new IRunnableWithProgress() {
+                    public void run(IProgressMonitor monitor)
+                            throws InvocationTargetException,
+                            InterruptedException {
+                        SyncResult result = sync.pullFile(remote, local, new SyncProgressMonitor(
+                                monitor, String.format("Pulling %1$s from the device",
+                                        remote.getName())));
+                        if (result.getCode() != SyncService.RESULT_OK) {
+                            DdmConsole.printErrorToConsole(String.format(
+                                    "Failed to pull %1$s: %2$s", remote, result.getMessage()));
+                        }
+
+                        sync.close();
+                    }
+                });
+            } catch (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());
+            }
+        }
+    }
+
+    /**
+     * Pushes several files and directory into a remote directory.
+     * @param localFiles
+     * @param remoteDirectory
+     */
+    private void pushFiles(final String[] localFiles, final FileEntry remoteDirectory) {
+        final SyncService sync = mCurrentDevice.getSyncService();
+        if (sync != null) {
+            try {
+                new ProgressMonitorDialog(mParent.getShell()).run(true, true,
+                        new IRunnableWithProgress() {
+                    public void run(IProgressMonitor monitor)
+                            throws InvocationTargetException,
+                            InterruptedException {
+                        SyncResult result = sync.push(localFiles, remoteDirectory,
+                                    new SyncProgressMonitor(monitor,
+                                            "Pushing file(s) to the device"));
+                        if (result.getCode() != SyncService.RESULT_OK) {
+                            DdmConsole.printErrorToConsole(String.format(
+                                    "Failed to push the items: %1$s", result.getMessage()));
+                        }
+
+                        sync.close();
+                    }
+                });
+            } catch (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;
+        }
+    }
+
+    /**
+     * Pushes a file on a device.
+     * @param local the local filepath of the file to push
+     * @param remoteDirectory the remote destination directory on the device
+     */
+    private void pushFile(final String local, final String remoteDirectory) {
+        final SyncService sync = mCurrentDevice.getSyncService();
+        if (sync != null) {
+            try {
+                new ProgressMonitorDialog(mParent.getShell()).run(true, true,
+                        new IRunnableWithProgress() {
+                    public void run(IProgressMonitor monitor)
+                            throws InvocationTargetException,
+                            InterruptedException {
+                        // get the file name
+                        String[] segs = local.split(Pattern.quote(File.separator));
+                        String name = segs[segs.length-1];
+                        String remoteFile = remoteDirectory + FileListingService.FILE_SEPARATOR
+                                + name;
+
+                        SyncResult result = sync.pushFile(local, remoteFile,
+                                    new SyncProgressMonitor(monitor,
+                                            String.format("Pushing %1$s to the device.", name)));
+                        if (result.getCode() != SyncService.RESULT_OK) {
+                            DdmConsole.printErrorToConsole(String.format(
+                                    "Failed to push %1$s on %2$s: %3$s",
+                                    name, mCurrentDevice.getSerialNumber(), result.getMessage()));
+                        }
+
+                        sync.close();
+                    }
+                });
+            } catch (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;
+        }
+    }
+
+    /**
+     * Sets the enabled state based on a FileEntry properties
+     * @param element The selected FileEntry
+     */
+    protected void setDeleteEnabledState(FileEntry element) {
+        mDeleteAction.setEnabled(element.getType() == FileListingService.TYPE_FILE);
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/FileLabelProvider.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/FileLabelProvider.java
new file mode 100644
index 0000000..1dca962
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/explorer/FileLabelProvider.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.explorer;
+
+import com.android.ddmlib.FileListingService;
+import com.android.ddmlib.FileListingService.FileEntry;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Label provider for the FileEntry.
+ */
+class FileLabelProvider implements ILabelProvider, ITableLabelProvider {
+
+    private Image mFileImage;
+    private Image mFolderImage;
+    private Image mPackageImage;
+    private Image mOtherImage;
+
+    /**
+     * Creates Label provider with custom images.
+     * @param fileImage the Image to represent a file
+     * @param folderImage the Image to represent a folder
+     * @param packageImage the Image to represent a .apk file. If null,
+     *      fileImage is used instead.
+     * @param otherImage the Image to represent all other entry type.
+     */
+    public FileLabelProvider(Image fileImage, Image folderImage,
+            Image packageImage, Image otherImage) {
+        mFileImage = fileImage;
+        mFolderImage = folderImage;
+        mOtherImage = otherImage;
+        if (packageImage != null) {
+            mPackageImage = packageImage;
+        } else {
+            mPackageImage = fileImage;
+        }
+    }
+
+    /**
+     * Creates a label provider with default images.
+     *
+     */
+    public FileLabelProvider() {
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+     */
+    public Image getImage(Object element) {
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+     */
+    public String getText(Object element) {
+        return null;
+    }
+
+    public Image getColumnImage(Object element, int columnIndex) {
+        if (columnIndex == 0) {
+            if (element instanceof FileEntry) {
+                FileEntry entry = (FileEntry)element;
+                switch (entry.getType()) {
+                    case FileListingService.TYPE_FILE:
+                    case FileListingService.TYPE_LINK:
+                        // get the name and extension
+                        if (entry.isApplicationPackage()) {
+                            return mPackageImage;
+                        }
+                        return mFileImage;
+                    case FileListingService.TYPE_DIRECTORY:
+                    case FileListingService.TYPE_DIRECTORY_LINK:
+                        return mFolderImage;
+                }
+            }
+
+            // default case return a different image.
+            return mOtherImage;
+        }
+        return null;
+    }
+
+    public String getColumnText(Object element, int columnIndex) {
+        if (element instanceof FileEntry) {
+            FileEntry entry = (FileEntry)element;
+
+            switch (columnIndex) {
+                case 0:
+                    return entry.getName();
+                case 1:
+                    return entry.getSize();
+                case 2:
+                    return entry.getDate();
+                case 3:
+                    return entry.getTime();
+                case 4:
+                    return entry.getPermissions();
+                case 5:
+                    return entry.getInfo();
+            }
+        }
+        return null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
+     */
+    public void addListener(ILabelProviderListener listener) {
+        // we don't need listeners.
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
+     */
+    public void dispose() {
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
+     */
+    public boolean isLabelProperty(Object element, String property) {
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
+     */
+    public void removeListener(ILabelProviderListener listener) {
+        // we don't need listeners
+    }
+
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/CoordinateControls.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/CoordinateControls.java
new file mode 100644
index 0000000..578a7ac
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/CoordinateControls.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.location;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Encapsulation of controls handling a location coordinate in decimal and sexagesimal.
+ * <p/>This handle the conversion between both modes automatically by using a {@link ModifyListener}
+ * on all the {@link Text} widgets.
+ * <p/>To get/set the coordinate, use {@link #setValue(double)} and {@link #getValue()} (preceded by
+ * a call to {@link #isValueValid()})
+ */
+public final class CoordinateControls {
+    private double mValue;
+    private boolean mValueValidity = false;
+    private Text mDecimalText;
+    private Text mSexagesimalDegreeText;
+    private Text mSexagesimalMinuteText;
+    private Text mSexagesimalSecondText;
+    
+    /** Internal flag to prevent {@link ModifyEvent} to be sent when {@link Text#setText(String)}
+     * is called. This is an int instead of a boolean to act as a counter. */
+    private int mManualTextChange = 0;
+    
+    /**
+     * ModifyListener for the 3 {@link Text} controls of the sexagesimal mode.
+     */
+    private ModifyListener mSexagesimalListener = new ModifyListener() {
+        public void modifyText(ModifyEvent event) {
+            if (mManualTextChange > 0) {
+                return;
+            }
+            try {
+                mValue = getValueFromSexagesimalControls();
+                setValueIntoDecimalControl(mValue);
+                mValueValidity = true;
+            } catch (NumberFormatException e) {
+                // wrong format empty the decimal controls.
+                mValueValidity = false;
+                resetDecimalControls();
+            }
+        }
+    };
+    
+    /**
+     * Creates the {@link Text} control for the decimal display of the coordinate.
+     * <p/>The control is expected to be placed in a Composite using a {@link GridLayout}.
+     * @param parent The {@link Composite} parent of the control.
+     */
+    public void createDecimalText(Composite parent) {
+        mDecimalText = createTextControl(parent, "-199.999999", new ModifyListener() {
+            public void modifyText(ModifyEvent event) {
+                if (mManualTextChange > 0) {
+                    return;
+                }
+                try {
+                    mValue = Double.parseDouble(mDecimalText.getText());
+                    setValueIntoSexagesimalControl(mValue);
+                    mValueValidity = true;
+                } catch (NumberFormatException e) {
+                    // wrong format empty the sexagesimal controls.
+                    mValueValidity = false;
+                    resetSexagesimalControls();
+                }
+            }
+        });
+    }
+    
+    /**
+     * Creates the {@link Text} control for the "degree" display of the coordinate in sexagesimal
+     * mode.
+     * <p/>The control is expected to be placed in a Composite using a {@link GridLayout}.
+     * @param parent The {@link Composite} parent of the control.
+     */
+    public void createSexagesimalDegreeText(Composite parent) {
+        mSexagesimalDegreeText = createTextControl(parent, "-199", mSexagesimalListener); //$NON-NLS-1$
+    }
+    
+    /**
+     * Creates the {@link Text} control for the "minute" display of the coordinate in sexagesimal
+     * mode.
+     * <p/>The control is expected to be placed in a Composite using a {@link GridLayout}.
+     * @param parent The {@link Composite} parent of the control.
+     */
+    public void createSexagesimalMinuteText(Composite parent) {
+        mSexagesimalMinuteText = createTextControl(parent, "99", mSexagesimalListener); //$NON-NLS-1$
+    }
+
+    /**
+     * Creates the {@link Text} control for the "second" display of the coordinate in sexagesimal
+     * mode.
+     * <p/>The control is expected to be placed in a Composite using a {@link GridLayout}.
+     * @param parent The {@link Composite} parent of the control.
+     */
+    public void createSexagesimalSecondText(Composite parent) {
+        mSexagesimalSecondText = createTextControl(parent, "99.999", mSexagesimalListener); //$NON-NLS-1$
+    }
+    
+    /**
+     * Sets the coordinate into the {@link Text} controls.
+     * @param value the coordinate value to set.
+     */
+    public void setValue(double value) {
+        mValue = value;
+        mValueValidity = true;
+        setValueIntoDecimalControl(value);
+        setValueIntoSexagesimalControl(value);
+    }
+    
+    /**
+     * Returns whether the value in the control(s) is valid.
+     */
+    public boolean isValueValid() {
+        return mValueValidity;
+    }
+
+    /**
+     * Returns the current value set in the control(s).
+     * <p/>This value can be erroneous, and a check with {@link #isValueValid()} should be performed
+     * before any call to this method.
+     */
+    public double getValue() {
+        return mValue;
+    }
+    
+    /**
+     * Enables or disables all the {@link Text} controls.
+     * @param enabled the enabled state.
+     */
+    public void setEnabled(boolean enabled) {
+        mDecimalText.setEnabled(enabled);
+        mSexagesimalDegreeText.setEnabled(enabled);
+        mSexagesimalMinuteText.setEnabled(enabled);
+        mSexagesimalSecondText.setEnabled(enabled);
+    }
+    
+    private void resetDecimalControls() {
+        mManualTextChange++;
+        mDecimalText.setText(""); //$NON-NLS-1$
+        mManualTextChange--;
+    }
+
+    private void resetSexagesimalControls() {
+        mManualTextChange++;
+        mSexagesimalDegreeText.setText(""); //$NON-NLS-1$
+        mSexagesimalMinuteText.setText(""); //$NON-NLS-1$
+        mSexagesimalSecondText.setText(""); //$NON-NLS-1$
+        mManualTextChange--;
+    }
+    
+    /**
+     * Creates a {@link Text} with a given parent, default string and a {@link ModifyListener}
+     * @param parent the parent {@link Composite}.
+     * @param defaultString the default string to be used to compute the {@link Text} control
+     * size hint.
+     * @param listener the {@link ModifyListener} to be called when the {@link Text} control is
+     * modified.
+     */
+    private Text createTextControl(Composite parent, String defaultString,
+            ModifyListener listener) {
+        // create the control
+        Text text = new Text(parent, SWT.BORDER | SWT.LEFT | SWT.SINGLE);
+        
+        // add the standard listener to it.
+        text.addModifyListener(listener);
+        
+        // compute its size/
+        mManualTextChange++;
+        text.setText(defaultString);
+        text.pack();
+        Point size = text.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+        text.setText(""); //$NON-NLS-1$
+        mManualTextChange--;
+        
+        GridData gridData = new GridData();
+        gridData.widthHint = size.x;
+        text.setLayoutData(gridData);
+        
+        return text;
+    }
+    
+    private double getValueFromSexagesimalControls() throws NumberFormatException {
+        double degrees = Double.parseDouble(mSexagesimalDegreeText.getText());
+        double minutes = Double.parseDouble(mSexagesimalMinuteText.getText());
+        double seconds = Double.parseDouble(mSexagesimalSecondText.getText());
+        
+        boolean isPositive = (degrees >= 0.);
+        degrees = Math.abs(degrees);
+
+        double value = degrees + minutes / 60. + seconds / 3600.; 
+        return isPositive ? value : - value;
+    }
+
+    private void setValueIntoDecimalControl(double value) {
+        mManualTextChange++;
+        mDecimalText.setText(String.format("%.6f", value));
+        mManualTextChange--;
+    }
+    
+    private void setValueIntoSexagesimalControl(double value) {
+        // get the sign and make the number positive no matter what.
+        boolean isPositive = (value >= 0.);
+        value = Math.abs(value);
+        
+        // get the degree
+        double degrees = Math.floor(value);
+        
+        // get the minutes
+        double minutes = Math.floor((value - degrees) * 60.);
+        
+        // get the seconds.
+        double seconds = (value - degrees) * 3600. - minutes * 60.;
+        
+        mManualTextChange++;
+        mSexagesimalDegreeText.setText(
+                Integer.toString(isPositive ? (int)degrees : (int)- degrees));
+        mSexagesimalMinuteText.setText(Integer.toString((int)minutes));
+        mSexagesimalSecondText.setText(String.format("%.3f", seconds)); //$NON-NLS-1$
+        mManualTextChange--;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/GpxParser.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/GpxParser.java
new file mode 100644
index 0000000..a30337a
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/GpxParser.java
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.location;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+/**
+ * A very basic GPX parser to meet the need of the emulator control panel.
+ * <p/>
+ * It parses basic waypoint information, and tracks (merging segments).
+ */
+public class GpxParser {
+    
+    private final static String NS_GPX = "http://www.topografix.com/GPX/1/1";  //$NON-NLS-1$
+        
+    private final static String NODE_WAYPOINT = "wpt"; //$NON-NLS-1$
+    private final static String NODE_TRACK = "trk"; //$NON-NLS-1$
+    private final static String NODE_TRACK_SEGMENT = "trkseg"; //$NON-NLS-1$
+    private final static String NODE_TRACK_POINT = "trkpt"; //$NON-NLS-1$
+    private final static String NODE_NAME = "name"; //$NON-NLS-1$
+    private final static String NODE_TIME = "time"; //$NON-NLS-1$
+    private final static String NODE_ELEVATION = "ele"; //$NON-NLS-1$
+    private final static String NODE_DESCRIPTION = "desc"; //$NON-NLS-1$
+    private final static String ATTR_LONGITUDE = "lon"; //$NON-NLS-1$
+    private final static String ATTR_LATITUDE = "lat"; //$NON-NLS-1$
+    
+    private static SAXParserFactory sParserFactory;
+    
+    static {
+        sParserFactory = SAXParserFactory.newInstance();
+        sParserFactory.setNamespaceAware(true);
+    }
+
+    private String mFileName;
+
+    private GpxHandler mHandler;
+    
+    /** Pattern to parse time with optional sub-second precision, and optional
+     * Z indicating the time is in UTC. */
+    private final static Pattern ISO8601_TIME =
+        Pattern.compile("(\\d{4})-(\\d\\d)-(\\d\\d)T(\\d\\d):(\\d\\d):(\\d\\d)(?:(\\.\\d+))?(Z)?"); //$NON-NLS-1$
+    
+    /**
+     * Handler for the SAX parser.
+     */
+    private static class GpxHandler extends DefaultHandler {
+        // --------- parsed data --------- 
+        List<WayPoint> mWayPoints;
+        List<Track> mTrackList;
+        
+        // --------- state for parsing --------- 
+        Track mCurrentTrack;
+        TrackPoint mCurrentTrackPoint;
+        WayPoint mCurrentWayPoint;
+        final StringBuilder mStringAccumulator = new StringBuilder();
+        
+        boolean mSuccess = true;
+
+        @Override
+        public void startElement(String uri, String localName, String name, Attributes attributes)
+                throws SAXException {
+            // we only care about the standard GPX nodes.
+            try {
+                if (NS_GPX.equals(uri)) {
+                    if (NODE_WAYPOINT.equals(localName)) {
+                        if (mWayPoints == null) {
+                            mWayPoints = new ArrayList<WayPoint>();
+                        }
+                        
+                        mWayPoints.add(mCurrentWayPoint = new WayPoint());
+                        handleLocation(mCurrentWayPoint, attributes);
+                    } else if (NODE_TRACK.equals(localName)) {
+                        if (mTrackList == null) {
+                            mTrackList = new ArrayList<Track>();
+                        }
+                        
+                        mTrackList.add(mCurrentTrack = new Track());
+                    } else if (NODE_TRACK_SEGMENT.equals(localName)) {
+                        // for now we do nothing here. This will merge all the segments into
+                        // a single TrackPoint list in the Track.
+                    } else if (NODE_TRACK_POINT.equals(localName)) {
+                        if (mCurrentTrack != null) {
+                            mCurrentTrack.addPoint(mCurrentTrackPoint = new TrackPoint());
+                            handleLocation(mCurrentTrackPoint, attributes);
+                        }
+                    }
+                }
+            } finally {
+                // no matter the node, we empty the StringBuilder accumulator when we start
+                // a new node.
+                mStringAccumulator.setLength(0);
+            }
+        }
+
+        /**
+         * Processes new characters for the node content. The characters are simply stored,
+         * and will be processed when {@link #endElement(String, String, String)} is called.
+         */
+        @Override
+        public void characters(char[] ch, int start, int length) throws SAXException {
+            mStringAccumulator.append(ch, start, length);
+        }
+        
+        @Override
+        public void endElement(String uri, String localName, String name) throws SAXException {
+            if (NS_GPX.equals(uri)) {
+                if (NODE_WAYPOINT.equals(localName)) {
+                    mCurrentWayPoint = null;
+                } else if (NODE_TRACK.equals(localName)) {
+                    mCurrentTrack = null;
+                } else if (NODE_TRACK_POINT.equals(localName)) {
+                    mCurrentTrackPoint = null;
+                } else if (NODE_NAME.equals(localName)) {
+                    if (mCurrentTrack != null) {
+                        mCurrentTrack.setName(mStringAccumulator.toString());
+                    } else if (mCurrentWayPoint != null) {
+                        mCurrentWayPoint.setName(mStringAccumulator.toString());
+                    }
+                } else if (NODE_TIME.equals(localName)) {
+                    if (mCurrentTrackPoint != null) {
+                        mCurrentTrackPoint.setTime(computeTime(mStringAccumulator.toString()));
+                    }
+                } else if (NODE_ELEVATION.equals(localName)) {
+                    if (mCurrentTrackPoint != null) {
+                        mCurrentTrackPoint.setElevation(
+                                Double.parseDouble(mStringAccumulator.toString()));
+                    } else if (mCurrentWayPoint != null) {
+                        mCurrentWayPoint.setElevation(
+                                Double.parseDouble(mStringAccumulator.toString()));
+                    }
+                } else if (NODE_DESCRIPTION.equals(localName)) {
+                    if (mCurrentWayPoint != null) {
+                        mCurrentWayPoint.setDescription(mStringAccumulator.toString());
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void error(SAXParseException e) throws SAXException {
+            mSuccess = false;
+        }
+
+        @Override
+        public void fatalError(SAXParseException e) throws SAXException {
+            mSuccess = false;
+        }
+        
+        /**
+         * Converts the string description of the time into milliseconds since epoch.
+         * @param timeString the string data.
+         * @return date in milliseconds.
+         */
+        private long computeTime(String timeString) {
+            // Time looks like: 2008-04-05T19:24:50Z
+            Matcher m = ISO8601_TIME.matcher(timeString);
+            if (m.matches()) {
+                // get the various elements and reconstruct time as a long.
+                try {
+                    int year = Integer.parseInt(m.group(1));
+                    int month = Integer.parseInt(m.group(2));
+                    int date = Integer.parseInt(m.group(3));
+                    int hourOfDay = Integer.parseInt(m.group(4));
+                    int minute = Integer.parseInt(m.group(5));
+                    int second = Integer.parseInt(m.group(6));
+                    
+                    // handle the optional parameters.
+                    int milliseconds = 0;
+
+                    String subSecondGroup = m.group(7);
+                    if (subSecondGroup != null) {
+                        milliseconds = (int)(1000 * Double.parseDouble(subSecondGroup));
+                    }
+                    
+                    boolean utcTime = m.group(8) != null;
+
+                    // now we convert into milliseconds since epoch.
+                    Calendar c;
+                    if (utcTime) {
+                        c = Calendar.getInstance(TimeZone.getTimeZone("GMT")); //$NON-NLS-1$
+                    } else {
+                        c = Calendar.getInstance();
+                    }
+                    
+                    c.set(year, month, date, hourOfDay, minute, second);
+                    
+                    return c.getTimeInMillis() + milliseconds;
+                } catch (NumberFormatException e) {
+                    // format is invalid, we'll return -1 below.
+                }
+                
+            }
+
+            // invalid time!
+            return -1;
+        }
+        
+        /**
+         * Handles the location attributes and store them into a {@link LocationPoint}.
+         * @param locationNode the {@link LocationPoint} to receive the location data.
+         * @param attributes the attributes from the XML node.
+         */
+        private void handleLocation(LocationPoint locationNode, Attributes attributes) {
+            try {
+                double longitude = Double.parseDouble(attributes.getValue(ATTR_LONGITUDE));
+                double latitude = Double.parseDouble(attributes.getValue(ATTR_LATITUDE));
+                
+                locationNode.setLocation(longitude, latitude);
+            } catch (NumberFormatException e) {
+                // wrong data, do nothing.
+            }
+        }
+
+        WayPoint[] getWayPoints() {
+            if (mWayPoints != null) {
+                return mWayPoints.toArray(new WayPoint[mWayPoints.size()]);
+            }
+
+            return null;
+        }
+
+        Track[] getTracks() {
+            if (mTrackList != null) {
+                return mTrackList.toArray(new Track[mTrackList.size()]);
+            }
+
+            return null;
+        }
+        
+        boolean getSuccess() {
+            return mSuccess;
+        }
+    }
+
+    /**
+     * A GPS track.
+     * <p/>A track is composed of a list of {@link TrackPoint} and optional name and comment.
+     */
+    public final static class Track {
+        private String mName;
+        private String mComment;
+        private List<TrackPoint> mPoints = new ArrayList<TrackPoint>();
+
+        void setName(String name) {
+            mName = name;
+        }
+        
+        public String getName() {
+            return mName;
+        }
+        
+        void setComment(String comment) {
+            mComment = comment;
+        }
+        
+        public String getComment() {
+            return mComment;
+        }
+        
+        void addPoint(TrackPoint trackPoint) {
+            mPoints.add(trackPoint);
+        }
+        
+        public TrackPoint[] getPoints() {
+            return mPoints.toArray(new TrackPoint[mPoints.size()]);
+        }
+        
+        public long getFirstPointTime() {
+            if (mPoints.size() > 0) {
+                return mPoints.get(0).getTime();
+            }
+            
+            return -1;
+        }
+
+        public long getLastPointTime() {
+            if (mPoints.size() > 0) {
+                return mPoints.get(mPoints.size()-1).getTime();
+            }
+            
+            return -1;
+        }
+        
+        public int getPointCount() {
+            return mPoints.size();
+        }
+    }
+    
+    /**
+     * Creates a new GPX parser for a file specified by its full path.
+     * @param fileName The full path of the GPX file to parse.
+     */
+    public GpxParser(String fileName) {
+        mFileName = fileName;
+    }
+
+    /**
+     * Parses the GPX file.
+     * @return <code>true</code> if success.
+     */
+    public boolean parse() {
+        try {
+            SAXParser parser = sParserFactory.newSAXParser();
+
+            mHandler = new GpxHandler();
+
+            parser.parse(new InputSource(new FileReader(mFileName)), mHandler);
+            
+            return mHandler.getSuccess();
+        } catch (ParserConfigurationException e) {
+        } catch (SAXException e) {
+        } catch (IOException e) {
+        } finally {
+        }
+
+        return false;
+    }
+    
+    /**
+     * Returns the parsed {@link WayPoint} objects, or <code>null</code> if none were found (or
+     * if the parsing failed.
+     */
+    public WayPoint[] getWayPoints() {
+        if (mHandler != null) {
+            return mHandler.getWayPoints();
+        }
+        
+        return null;
+    }
+    
+    /**
+     * Returns the parsed {@link Track} objects, or <code>null</code> if none were found (or
+     * if the parsing failed.
+     */
+    public Track[] getTracks() {
+        if (mHandler != null) {
+            return mHandler.getTracks();
+        }
+        
+        return null;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/KmlParser.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/KmlParser.java
new file mode 100644
index 0000000..af485ac
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/KmlParser.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.location;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+/**
+ * A very basic KML parser to meet the need of the emulator control panel.
+ * <p/>
+ * It parses basic Placemark information.
+ */
+public class KmlParser {
+    
+    private final static String NS_KML_2 = "http://earth.google.com/kml/2.";  //$NON-NLS-1$
+        
+    private final static String NODE_PLACEMARK = "Placemark"; //$NON-NLS-1$
+    private final static String NODE_NAME = "name"; //$NON-NLS-1$
+    private final static String NODE_COORDINATES = "coordinates"; //$NON-NLS-1$
+    
+    private final static Pattern sLocationPattern = Pattern.compile("([^,]+),([^,]+)(?:,([^,]+))?");
+    
+    private static SAXParserFactory sParserFactory;
+    
+    static {
+        sParserFactory = SAXParserFactory.newInstance();
+        sParserFactory.setNamespaceAware(true);
+    }
+
+    private String mFileName;
+
+    private KmlHandler mHandler;
+    
+    /**
+     * Handler for the SAX parser.
+     */
+    private static class KmlHandler extends DefaultHandler {
+        // --------- parsed data --------- 
+        List<WayPoint> mWayPoints;
+        
+        // --------- state for parsing --------- 
+        WayPoint mCurrentWayPoint;
+        final StringBuilder mStringAccumulator = new StringBuilder();
+
+        boolean mSuccess = true;
+
+        @Override
+        public void startElement(String uri, String localName, String name, Attributes attributes)
+                throws SAXException {
+            // we only care about the standard GPX nodes.
+            try {
+                if (uri.startsWith(NS_KML_2)) {
+                    if (NODE_PLACEMARK.equals(localName)) {
+                        if (mWayPoints == null) {
+                            mWayPoints = new ArrayList<WayPoint>();
+                        }
+                        
+                        mWayPoints.add(mCurrentWayPoint = new WayPoint());
+                    }
+                }
+            } finally {
+                // no matter the node, we empty the StringBuilder accumulator when we start
+                // a new node.
+                mStringAccumulator.setLength(0);
+            }
+        }
+
+        /**
+         * Processes new characters for the node content. The characters are simply stored,
+         * and will be processed when {@link #endElement(String, String, String)} is called.
+         */
+        @Override
+        public void characters(char[] ch, int start, int length) throws SAXException {
+            mStringAccumulator.append(ch, start, length);
+        }
+        
+        @Override
+        public void endElement(String uri, String localName, String name) throws SAXException {
+            if (uri.startsWith(NS_KML_2)) {
+                if (NODE_PLACEMARK.equals(localName)) {
+                    mCurrentWayPoint = null;
+                } else if (NODE_NAME.equals(localName)) {
+                    if (mCurrentWayPoint != null) {
+                        mCurrentWayPoint.setName(mStringAccumulator.toString());
+                    }
+                } else if (NODE_COORDINATES.equals(localName)) {
+                    if (mCurrentWayPoint != null) {
+                        parseLocation(mCurrentWayPoint, mStringAccumulator.toString());
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void error(SAXParseException e) throws SAXException {
+            mSuccess = false;
+        }
+
+        @Override
+        public void fatalError(SAXParseException e) throws SAXException {
+            mSuccess = false;
+        }
+        
+        /**
+         * Parses the location string and store the information into a {@link LocationPoint}.
+         * @param locationNode the {@link LocationPoint} to receive the location data.
+         * @param location The string containing the location info.
+         */
+        private void parseLocation(LocationPoint locationNode, String location) {
+            Matcher m = sLocationPattern.matcher(location);
+            if (m.matches()) {
+                try {
+                    double longitude = Double.parseDouble(m.group(1));
+                    double latitude = Double.parseDouble(m.group(2));
+                    
+                    locationNode.setLocation(longitude, latitude);
+                    
+                    if (m.groupCount() == 3) {
+                        // looks like we have elevation data.
+                        locationNode.setElevation(Double.parseDouble(m.group(3)));
+                    }
+                } catch (NumberFormatException e) {
+                    // wrong data, do nothing.
+                }
+            }
+        }
+        
+        WayPoint[] getWayPoints() {
+            if (mWayPoints != null) {
+                return mWayPoints.toArray(new WayPoint[mWayPoints.size()]);
+            }
+
+            return null;
+        }
+
+        boolean getSuccess() {
+            return mSuccess;
+        }
+    }
+
+    /**
+     * Creates a new GPX parser for a file specified by its full path.
+     * @param fileName The full path of the GPX file to parse.
+     */
+    public KmlParser(String fileName) {
+        mFileName = fileName;
+    }
+
+    /**
+     * Parses the GPX file.
+     * @return <code>true</code> if success.
+     */
+    public boolean parse() {
+        try {
+            SAXParser parser = sParserFactory.newSAXParser();
+
+            mHandler = new KmlHandler();
+
+            parser.parse(new InputSource(new FileReader(mFileName)), mHandler);
+            
+            return mHandler.getSuccess();
+        } catch (ParserConfigurationException e) {
+        } catch (SAXException e) {
+        } catch (IOException e) {
+        } finally {
+        }
+
+        return false;
+    }
+    
+    /**
+     * Returns the parsed {@link WayPoint} objects, or <code>null</code> if none were found (or
+     * if the parsing failed.
+     */
+    public WayPoint[] getWayPoints() {
+        if (mHandler != null) {
+            return mHandler.getWayPoints();
+        }
+        
+        return null;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/LocationPoint.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/LocationPoint.java
new file mode 100644
index 0000000..dbb8f41
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/LocationPoint.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.location;
+
+/**
+ * Base class for Location aware points.
+ */
+class LocationPoint {
+    private double mLongitude;
+    private double mLatitude;
+    private boolean mHasElevation = false;
+    private double mElevation;
+
+    final void setLocation(double longitude, double latitude) {
+        mLongitude = longitude;
+        mLatitude = latitude;
+    }
+    
+    public final double getLongitude() {
+        return mLongitude;
+    }
+    
+    public final double getLatitude() {
+        return mLatitude;
+    }
+
+    final void setElevation(double elevation) {
+        mElevation = elevation;
+        mHasElevation = true;
+    }
+    
+    public final boolean hasElevation() {
+        return mHasElevation;
+    }
+    
+    public final double getElevation() {
+        return mElevation;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackContentProvider.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackContentProvider.java
new file mode 100644
index 0000000..7fb37ce
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackContentProvider.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.location;
+
+import com.android.ddmuilib.location.GpxParser.Track;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Content provider to display {@link Track} objects in a Table.
+ * <p/>The expected type for the input is {@link Track}<code>[]</code>. 
+ */
+public class TrackContentProvider implements IStructuredContentProvider {
+
+    public Object[] getElements(Object inputElement) {
+        if (inputElement instanceof Track[]) {
+            return (Track[])inputElement;
+        }
+
+        return new Object[0];
+    }
+
+    public void dispose() {
+        // pass
+    }
+
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+        // pass
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackLabelProvider.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackLabelProvider.java
new file mode 100644
index 0000000..81d1f7d
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackLabelProvider.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.location;
+
+import com.android.ddmuilib.location.GpxParser.Track;
+
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Table;
+
+import java.util.Date;
+
+/**
+ * Label Provider for {@link Table} objects displaying {@link Track} objects.
+ */
+public class TrackLabelProvider implements ITableLabelProvider {
+
+    public Image getColumnImage(Object element, int columnIndex) {
+        return null;
+    }
+
+    public String getColumnText(Object element, int columnIndex) {
+        if (element instanceof Track) {
+            Track track = (Track)element;
+            switch (columnIndex) {
+                case 0:
+                    return track.getName();
+                case 1:
+                    return Integer.toString(track.getPointCount());
+                case 2:
+                    long time = track.getFirstPointTime();
+                    if (time != -1) {
+                        return new Date(time).toString();
+                    }
+                    break;
+                case 3:
+                    time = track.getLastPointTime();
+                    if (time != -1) {
+                        return new Date(time).toString();
+                    }
+                    break;
+                case 4:
+                    return track.getComment();
+            }
+        }
+
+        return null;
+    }
+
+    public void addListener(ILabelProviderListener listener) {
+        // pass
+    }
+
+    public void dispose() {
+        // pass
+    }
+
+    public boolean isLabelProperty(Object element, String property) {
+        // pass
+        return false;
+    }
+
+    public void removeListener(ILabelProviderListener listener) {
+        // pass
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackPoint.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackPoint.java
new file mode 100644
index 0000000..527f4bf
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/TrackPoint.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.location;
+
+
+/**
+ * A Track Point.
+ * <p/>A track point is a point in time and space.
+ */
+public class TrackPoint extends LocationPoint {
+    private long mTime;
+
+    void setTime(long time) {
+        mTime = time;
+    }
+    
+    public long getTime() {
+        return mTime;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPoint.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPoint.java
new file mode 100644
index 0000000..32880bd
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPoint.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.location;
+
+/**
+ * A GPS/KML way point.
+ * <p/>A waypoint is a user specified location, with a name and an optional description.
+ */
+public final class WayPoint extends LocationPoint {
+    private String mName;
+    private String mDescription;
+
+    void setName(String name) {
+        mName = name;
+    }
+    
+    public String getName() {
+        return mName;
+    }
+
+    void setDescription(String description) {
+        mDescription = description;
+    }
+
+    public String getDescription() {
+        return mDescription;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPointContentProvider.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPointContentProvider.java
new file mode 100644
index 0000000..fced777
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPointContentProvider.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.location;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Content provider to display {@link WayPoint} objects in a Table.
+ * <p/>The expected type for the input is {@link WayPoint}<code>[]</code>. 
+ */
+public class WayPointContentProvider implements IStructuredContentProvider {
+
+    public Object[] getElements(Object inputElement) {
+        if (inputElement instanceof WayPoint[]) {
+            return (WayPoint[])inputElement;
+        }
+
+        return new Object[0];
+    }
+
+    public void dispose() {
+        // pass
+    }
+
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+        // pass
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPointLabelProvider.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPointLabelProvider.java
new file mode 100644
index 0000000..f5e6f1b
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/WayPointLabelProvider.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.location;
+
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Table;
+
+/**
+ * Label Provider for {@link Table} objects displaying {@link WayPoint} objects.
+ */
+public class WayPointLabelProvider implements ITableLabelProvider {
+
+    public Image getColumnImage(Object element, int columnIndex) {
+        return null;
+    }
+
+    public String getColumnText(Object element, int columnIndex) {
+        if (element instanceof WayPoint) {
+            WayPoint wayPoint = (WayPoint)element;
+            switch (columnIndex) {
+                case 0:
+                    return wayPoint.getName();
+                case 1:
+                    return String.format("%.6f", wayPoint.getLongitude());
+                case 2:
+                    return String.format("%.6f", wayPoint.getLatitude());
+                case 3:
+                    if (wayPoint.hasElevation()) {
+                        return String.format("%.1f", wayPoint.getElevation());
+                    } else {
+                        return "-";
+                    }
+                case 4:
+                    return wayPoint.getDescription();
+            }
+        }
+
+        return null;
+    }
+
+    public void addListener(ILabelProviderListener listener) {
+        // pass
+    }
+
+    public void dispose() {
+        // pass
+    }
+
+    public boolean isLabelProperty(Object element, String property) {
+        // pass
+        return false;
+    }
+
+    public void removeListener(ILabelProviderListener listener) {
+        // pass
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/BugReportImporter.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/BugReportImporter.java
new file mode 100644
index 0000000..9de1ac7
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/BugReportImporter.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.log.event;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+
+public class BugReportImporter {
+    
+    private final static String TAG_HEADER = "------ EVENT LOG TAGS ------";
+    private final static String LOG_HEADER = "------ EVENT LOG ------";
+    private final static String HEADER_TAG = "------";
+    
+    private String[] mTags;
+    private String[] mLog;
+    
+    public BugReportImporter(String filePath) throws FileNotFoundException {
+        BufferedReader reader = new BufferedReader(
+                new InputStreamReader(new FileInputStream(filePath)));
+
+        try {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                if (TAG_HEADER.equals(line)) {
+                    readTags(reader);
+                    return;
+                }
+            }
+        } catch (IOException e) {
+        }
+    }
+    
+    public String[] getTags() {
+        return mTags;
+    }
+    
+    public String[] getLog() {
+        return mLog;
+    }
+
+    private void readTags(BufferedReader reader) throws IOException {
+        String line;
+        
+        ArrayList<String> content = new ArrayList<String>();
+        while ((line = reader.readLine()) != null) {
+            if (LOG_HEADER.equals(line)) {
+                mTags = content.toArray(new String[content.size()]);
+                readLog(reader);
+                return;
+            } else {
+                content.add(line);
+            }
+        }
+    }
+
+    private void readLog(BufferedReader reader) throws IOException {
+        String line;
+
+        ArrayList<String> content = new ArrayList<String>();
+        while ((line = reader.readLine()) != null) {
+            if (line.startsWith(HEADER_TAG) == false) {
+                content.add(line);
+            } else {
+                break;
+            }
+        }
+        
+        mLog = content.toArray(new String[content.size()]);
+    }
+    
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayFilteredLog.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayFilteredLog.java
new file mode 100644
index 0000000..473387a
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayFilteredLog.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.log.event;
+
+import com.android.ddmlib.log.EventContainer;
+import com.android.ddmlib.log.EventLogParser;
+
+import java.util.ArrayList;
+
+public class DisplayFilteredLog extends DisplayLog {
+
+    public DisplayFilteredLog(String name) {
+        super(name);
+    }
+
+    /**
+     * Adds event to the display.
+     */
+    @Override
+    void newEvent(EventContainer event, EventLogParser logParser) {
+        ArrayList<ValueDisplayDescriptor> valueDescriptors =
+                new ArrayList<ValueDisplayDescriptor>();
+
+        ArrayList<OccurrenceDisplayDescriptor> occurrenceDescriptors =
+                new ArrayList<OccurrenceDisplayDescriptor>();
+
+        if (filterEvent(event, valueDescriptors, occurrenceDescriptors)) {
+            addToLog(event, logParser, valueDescriptors, occurrenceDescriptors);
+        }
+    }
+
+    /**
+     * Gets display type
+     *
+     * @return display type as an integer
+     */
+    @Override
+    int getDisplayType() {
+        return DISPLAY_TYPE_FILTERED_LOG;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayGraph.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayGraph.java
new file mode 100644
index 0000000..0cffd7e
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayGraph.java
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.log.event;
+
+import com.android.ddmlib.log.EventContainer;
+import com.android.ddmlib.log.EventLogParser;
+import com.android.ddmlib.log.EventValueDescription;
+import com.android.ddmlib.log.InvalidTypeException;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.jfree.chart.axis.AxisLocation;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.AbstractXYItemRenderer;
+import org.jfree.chart.renderer.xy.XYAreaRenderer;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.data.time.Millisecond;
+import org.jfree.data.time.TimeSeries;
+import org.jfree.data.time.TimeSeriesCollection;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+public class DisplayGraph extends EventDisplay {
+
+    public DisplayGraph(String name) {
+        super(name);
+    }
+
+    /**
+     * Resets the display.
+     */
+    @Override
+    void resetUI() {
+        Collection<TimeSeriesCollection> datasets = mValueTypeDataSetMap.values();
+        for (TimeSeriesCollection dataset : datasets) {
+            dataset.removeAllSeries();
+        }
+        if (mOccurrenceDataSet != null) {
+            mOccurrenceDataSet.removeAllSeries();
+        }
+        mValueDescriptorSeriesMap.clear();
+        mOcurrenceDescriptorSeriesMap.clear();
+    }
+
+    /**
+     * Creates the UI for the event display.
+     * @param parent the parent composite.
+     * @param logParser the current log parser.
+     * @return the created control (which may have children).
+     */
+    @Override
+    public Control createComposite(final Composite parent, EventLogParser logParser,
+            final ILogColumnListener listener) {
+        String title = getChartTitle(logParser);
+        return createCompositeChart(parent, logParser, title);
+    }
+
+    /**
+     * Adds event to the display.
+     */
+    @Override
+    void newEvent(EventContainer event, EventLogParser logParser) {
+        ArrayList<ValueDisplayDescriptor> valueDescriptors =
+                new ArrayList<ValueDisplayDescriptor>();
+
+        ArrayList<OccurrenceDisplayDescriptor> occurrenceDescriptors =
+                new ArrayList<OccurrenceDisplayDescriptor>();
+
+        if (filterEvent(event, valueDescriptors, occurrenceDescriptors)) {
+            updateChart(event, logParser, valueDescriptors, occurrenceDescriptors);
+        }
+    }
+
+     /**
+     * Updates the chart with the {@link EventContainer} by adding the values/occurrences defined
+     * by the {@link ValueDisplayDescriptor} and {@link OccurrenceDisplayDescriptor} objects from
+     * the two lists.
+     * <p/>This method is only called when at least one of the descriptor list is non empty.
+     * @param event
+     * @param logParser
+     * @param valueDescriptors
+     * @param occurrenceDescriptors
+     */
+    private void updateChart(EventContainer event, EventLogParser logParser,
+            ArrayList<ValueDisplayDescriptor> valueDescriptors,
+            ArrayList<OccurrenceDisplayDescriptor> occurrenceDescriptors) {
+        Map<Integer, String> tagMap = logParser.getTagMap();
+
+        Millisecond millisecondTime = null;
+        long msec = -1;
+
+        // If the event container is a cpu container (tag == 2721), and there is no descriptor
+        // for the total CPU load, then we do accumulate all the values.
+        boolean accumulateValues = false;
+        double accumulatedValue = 0;
+
+        if (event.mTag == 2721) {
+            accumulateValues = true;
+            for (ValueDisplayDescriptor descriptor : valueDescriptors) {
+                accumulateValues &= (descriptor.valueIndex != 0);
+            }
+        }
+
+        for (ValueDisplayDescriptor descriptor : valueDescriptors) {
+            try {
+                // get the hashmap for this descriptor
+                HashMap<Integer, TimeSeries> map = mValueDescriptorSeriesMap.get(descriptor);
+
+                // if it's not there yet, we create it.
+                if (map == null) {
+                    map = new HashMap<Integer, TimeSeries>();
+                    mValueDescriptorSeriesMap.put(descriptor, map);
+                }
+
+                // get the TimeSeries for this pid
+                TimeSeries timeSeries = map.get(event.pid);
+
+                // if it doesn't exist yet, we create it
+                if (timeSeries == null) {
+                    // get the series name
+                    String seriesFullName = null;
+                    String seriesLabel = getSeriesLabel(event, descriptor);
+
+                    switch (mValueDescriptorCheck) {
+                        case EVENT_CHECK_SAME_TAG:
+                            seriesFullName = String.format("%1$s / %2$s", seriesLabel,
+                                    descriptor.valueName);
+                            break;
+                        case EVENT_CHECK_SAME_VALUE:
+                            seriesFullName = String.format("%1$s", seriesLabel);
+                            break;
+                        default:
+                            seriesFullName = String.format("%1$s / %2$s: %3$s", seriesLabel,
+                                    tagMap.get(descriptor.eventTag),
+                                    descriptor.valueName);
+                            break;
+                    }
+
+                    // get the data set for this ValueType
+                    TimeSeriesCollection dataset = getValueDataset(
+                            logParser.getEventInfoMap().get(event.mTag)[descriptor.valueIndex]
+                                                                        .getValueType(),
+                            accumulateValues);
+
+                    // create the series
+                    timeSeries = new TimeSeries(seriesFullName, Millisecond.class);
+                    if (mMaximumChartItemAge != -1) {
+                        timeSeries.setMaximumItemAge(mMaximumChartItemAge * 1000);
+                    }
+
+                    dataset.addSeries(timeSeries);
+
+                    // add it to the map.
+                    map.put(event.pid, timeSeries);
+                }
+
+                // update the timeSeries.
+
+                // get the value from the event
+                double value = event.getValueAsDouble(descriptor.valueIndex);
+
+                // accumulate the values if needed.
+                if (accumulateValues) {
+                    accumulatedValue += value;
+                    value = accumulatedValue;
+                }
+
+                // get the time
+                if (millisecondTime == null) {
+                    msec = (long)event.sec * 1000L + (event.nsec / 1000000L);
+                    millisecondTime = new Millisecond(new Date(msec));
+                }
+
+                // add the value to the time series
+                timeSeries.addOrUpdate(millisecondTime, value);
+            } catch (InvalidTypeException e) {
+                // just ignore this descriptor if there's a type mismatch
+            }
+        }
+
+        for (OccurrenceDisplayDescriptor descriptor : occurrenceDescriptors) {
+            try {
+                // get the hashmap for this descriptor
+                HashMap<Integer, TimeSeries> map = mOcurrenceDescriptorSeriesMap.get(descriptor);
+
+                // if it's not there yet, we create it.
+                if (map == null) {
+                    map = new HashMap<Integer, TimeSeries>();
+                    mOcurrenceDescriptorSeriesMap.put(descriptor, map);
+                }
+
+                // get the TimeSeries for this pid
+                TimeSeries timeSeries = map.get(event.pid);
+
+                // if it doesn't exist yet, we create it.
+                if (timeSeries == null) {
+                    String seriesLabel = getSeriesLabel(event, descriptor);
+
+                    String seriesFullName = String.format("[%1$s:%2$s]",
+                            tagMap.get(descriptor.eventTag), seriesLabel);
+
+                    timeSeries = new TimeSeries(seriesFullName, Millisecond.class);
+                    if (mMaximumChartItemAge != -1) {
+                        timeSeries.setMaximumItemAge(mMaximumChartItemAge);
+                    }
+
+                    getOccurrenceDataSet().addSeries(timeSeries);
+
+                    map.put(event.pid, timeSeries);
+                }
+
+                // update the series
+
+                // get the time
+                if (millisecondTime == null) {
+                    msec = (long)event.sec * 1000L + (event.nsec / 1000000L);
+                    millisecondTime = new Millisecond(new Date(msec));
+                }
+
+                // add the value to the time series
+                timeSeries.addOrUpdate(millisecondTime, 0); // the value is unused
+            } catch (InvalidTypeException e) {
+                // just ignore this descriptor if there's a type mismatch
+            }
+        }
+
+        // go through all the series and remove old values.
+        if (msec != -1 && mMaximumChartItemAge != -1) {
+            Collection<HashMap<Integer, TimeSeries>> pidMapValues =
+                mValueDescriptorSeriesMap.values();
+
+            for (HashMap<Integer, TimeSeries> pidMapValue : pidMapValues) {
+                Collection<TimeSeries> seriesCollection = pidMapValue.values();
+
+                for (TimeSeries timeSeries : seriesCollection) {
+                    timeSeries.removeAgedItems(msec, true);
+                }
+            }
+
+            pidMapValues = mOcurrenceDescriptorSeriesMap.values();
+            for (HashMap<Integer, TimeSeries> pidMapValue : pidMapValues) {
+                Collection<TimeSeries> seriesCollection = pidMapValue.values();
+
+                for (TimeSeries timeSeries : seriesCollection) {
+                    timeSeries.removeAgedItems(msec, true);
+                }
+            }
+        }
+    }
+
+       /**
+     * Returns a {@link TimeSeriesCollection} for a specific {@link com.android.ddmlib.log.EventValueDescription.ValueType}.
+     * If the data set is not yet created, it is first allocated and set up into the
+     * {@link org.jfree.chart.JFreeChart} object.
+     * @param type the {@link com.android.ddmlib.log.EventValueDescription.ValueType} of the data set.
+     * @param accumulateValues
+     */
+    private TimeSeriesCollection getValueDataset(EventValueDescription.ValueType type, boolean accumulateValues) {
+        TimeSeriesCollection dataset = mValueTypeDataSetMap.get(type);
+        if (dataset == null) {
+            // create the data set and store it in the map
+            dataset = new TimeSeriesCollection();
+            mValueTypeDataSetMap.put(type, dataset);
+
+            // create the renderer and configure it depending on the ValueType
+            AbstractXYItemRenderer renderer;
+            if (type == EventValueDescription.ValueType.PERCENT && accumulateValues) {
+                renderer = new XYAreaRenderer();
+            } else {
+                XYLineAndShapeRenderer r = new XYLineAndShapeRenderer();
+                r.setBaseShapesVisible(type != EventValueDescription.ValueType.PERCENT);
+
+                renderer = r;
+            }
+
+            // set both the dataset and the renderer in the plot object.
+            XYPlot xyPlot = mChart.getXYPlot();
+            xyPlot.setDataset(mDataSetCount, dataset);
+            xyPlot.setRenderer(mDataSetCount, renderer);
+
+            // put a new axis label, and configure it.
+            NumberAxis axis = new NumberAxis(type.toString());
+
+            if (type == EventValueDescription.ValueType.PERCENT) {
+                // force percent range to be (0,100) fixed.
+                axis.setAutoRange(false);
+                axis.setRange(0., 100.);
+            }
+
+            // for the index, we ignore the occurrence dataset
+            int count = mDataSetCount;
+            if (mOccurrenceDataSet != null) {
+                count--;
+            }
+
+            xyPlot.setRangeAxis(count, axis);
+            if ((count % 2) == 0) {
+                xyPlot.setRangeAxisLocation(count, AxisLocation.BOTTOM_OR_LEFT);
+            } else {
+                xyPlot.setRangeAxisLocation(count, AxisLocation.TOP_OR_RIGHT);
+            }
+
+            // now we link the dataset and the axis
+            xyPlot.mapDatasetToRangeAxis(mDataSetCount, count);
+
+            mDataSetCount++;
+        }
+
+        return dataset;
+    }
+
+    /**
+     * Return the series label for this event. This only contains the pid information.
+     * @param event the {@link EventContainer}
+     * @param descriptor the {@link OccurrenceDisplayDescriptor}
+     * @return the series label.
+     * @throws InvalidTypeException
+     */
+    private String getSeriesLabel(EventContainer event, OccurrenceDisplayDescriptor descriptor)
+            throws InvalidTypeException {
+        if (descriptor.seriesValueIndex != -1) {
+            if (descriptor.includePid == false) {
+                return event.getValueAsString(descriptor.seriesValueIndex);
+            } else {
+                return String.format("%1$s (%2$d)",
+                        event.getValueAsString(descriptor.seriesValueIndex), event.pid);
+            }
+        }
+
+        return Integer.toString(event.pid);
+    }
+
+    /**
+     * Returns the {@link TimeSeriesCollection} for the occurrence display. If the data set is not
+     * yet created, it is first allocated and set up into the {@link org.jfree.chart.JFreeChart} object.
+     */
+    private TimeSeriesCollection getOccurrenceDataSet() {
+        if (mOccurrenceDataSet == null) {
+            mOccurrenceDataSet = new TimeSeriesCollection();
+
+            XYPlot xyPlot = mChart.getXYPlot();
+            xyPlot.setDataset(mDataSetCount, mOccurrenceDataSet);
+
+            OccurrenceRenderer renderer = new OccurrenceRenderer();
+            renderer.setBaseShapesVisible(false);
+            xyPlot.setRenderer(mDataSetCount, renderer);
+
+            mDataSetCount++;
+        }
+
+        return mOccurrenceDataSet;
+    }
+
+    /**
+     * Gets display type
+     *
+     * @return display type as an integer
+     */
+    @Override
+    int getDisplayType() {
+        return DISPLAY_TYPE_GRAPH;
+    }
+
+    /**
+     * Sets the current {@link EventLogParser} object.
+     */
+    @Override
+    protected void setNewLogParser(EventLogParser logParser) {
+        if (mChart != null) {
+            mChart.setTitle(getChartTitle(logParser));
+        }
+    }
+    /**
+     * Returns a meaningful chart title based on the value of {@link #mValueDescriptorCheck}.
+     *
+     * @param logParser the logParser.
+     * @return the chart title.
+     */
+    private String getChartTitle(EventLogParser logParser) {
+        if (mValueDescriptors.size() > 0) {
+            String chartDesc = null;
+            switch (mValueDescriptorCheck) {
+                case EVENT_CHECK_SAME_TAG:
+                    if (logParser != null) {
+                        chartDesc = logParser.getTagMap().get(mValueDescriptors.get(0).eventTag);
+                    }
+                    break;
+                case EVENT_CHECK_SAME_VALUE:
+                    if (logParser != null) {
+                        chartDesc = String.format("%1$s / %2$s",
+                                logParser.getTagMap().get(mValueDescriptors.get(0).eventTag),
+                                mValueDescriptors.get(0).valueName);
+                    }
+                    break;
+            }
+
+            if (chartDesc != null) {
+                return String.format("%1$s - %2$s", mName, chartDesc);
+            }
+        }
+
+        return mName;
+    }
+}
\ No newline at end of file
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayLog.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayLog.java
new file mode 100644
index 0000000..26296f3
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplayLog.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.log.event;
+
+import com.android.ddmlib.log.EventContainer;
+import com.android.ddmlib.log.EventLogParser;
+import com.android.ddmlib.log.EventValueDescription;
+import com.android.ddmlib.log.InvalidTypeException;
+import com.android.ddmuilib.DdmUiPreferences;
+import com.android.ddmuilib.TableHelper;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.ScrollBar;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+
+public class DisplayLog extends EventDisplay {
+    public DisplayLog(String name) {
+        super(name);
+    }
+
+    private final static String PREFS_COL_DATE = "EventLogPanel.log.Col1"; //$NON-NLS-1$
+    private final static String PREFS_COL_PID = "EventLogPanel.log.Col2"; //$NON-NLS-1$
+    private final static String PREFS_COL_EVENTTAG = "EventLogPanel.log.Col3"; //$NON-NLS-1$
+    private final static String PREFS_COL_VALUENAME = "EventLogPanel.log.Col4"; //$NON-NLS-1$
+    private final static String PREFS_COL_VALUE = "EventLogPanel.log.Col5"; //$NON-NLS-1$
+    private final static String PREFS_COL_TYPE = "EventLogPanel.log.Col6"; //$NON-NLS-1$
+
+    /**
+     * Resets the display.
+     */
+    @Override
+    void resetUI() {
+        mLogTable.removeAll();
+    }
+
+    /**
+     * Adds event to the display.
+     */
+    @Override
+    void newEvent(EventContainer event, EventLogParser logParser) {
+        addToLog(event, logParser);
+    }
+
+    /**
+     * Creates the UI for the event display.
+     *
+     * @param parent    the parent composite.
+     * @param logParser the current log parser.
+     * @return the created control (which may have children).
+     */
+    @Override
+    Control createComposite(Composite parent, EventLogParser logParser, ILogColumnListener listener) {
+        return createLogUI(parent, listener);
+    }
+
+    /**
+     * Adds an {@link EventContainer} to the log.
+     *
+     * @param event     the event.
+     * @param logParser the log parser.
+     */
+    private void addToLog(EventContainer event, EventLogParser logParser) {
+        ScrollBar bar = mLogTable.getVerticalBar();
+        boolean scroll = bar.getMaximum() == bar.getSelection() + bar.getThumb();
+
+        // get the date.
+        Calendar c = Calendar.getInstance();
+        long msec = (long) event.sec * 1000L;
+        c.setTimeInMillis(msec);
+
+        // convert the time into a string
+        String date = String.format("%1$tF %1$tT", c);
+
+        String eventName = logParser.getTagMap().get(event.mTag);
+        String pidName = Integer.toString(event.pid);
+
+        // get the value description
+        EventValueDescription[] valueDescription = logParser.getEventInfoMap().get(event.mTag);
+        if (valueDescription != null) {
+            for (int i = 0; i < valueDescription.length; i++) {
+                EventValueDescription description = valueDescription[i];
+                try {
+                    String value = event.getValueAsString(i);
+
+                    logValue(date, pidName, eventName, description.getName(), value,
+                            description.getEventValueType(), description.getValueType());
+                } catch (InvalidTypeException e) {
+                    logValue(date, pidName, eventName, description.getName(), e.getMessage(),
+                            description.getEventValueType(), description.getValueType());
+                }
+            }
+
+            // scroll if needed, by showing the last item
+            if (scroll) {
+                int itemCount = mLogTable.getItemCount();
+                if (itemCount > 0) {
+                    mLogTable.showItem(mLogTable.getItem(itemCount - 1));
+                }
+            }
+        }
+    }
+
+    /**
+     * Adds an {@link EventContainer} to the log. Only add the values/occurrences defined by
+     * the list of descriptors. If an event is configured to be displayed by value and occurrence,
+     * only the values are displayed (as they mark an event occurrence anyway).
+     * <p/>This method is only called when at least one of the descriptor list is non empty.
+     *
+     * @param event
+     * @param logParser
+     * @param valueDescriptors
+     * @param occurrenceDescriptors
+     */
+    protected void addToLog(EventContainer event, EventLogParser logParser,
+            ArrayList<ValueDisplayDescriptor> valueDescriptors,
+            ArrayList<OccurrenceDisplayDescriptor> occurrenceDescriptors) {
+        ScrollBar bar = mLogTable.getVerticalBar();
+        boolean scroll = bar.getMaximum() == bar.getSelection() + bar.getThumb();
+
+        // get the date.
+        Calendar c = Calendar.getInstance();
+        long msec = (long) event.sec * 1000L;
+        c.setTimeInMillis(msec);
+
+        // convert the time into a string
+        String date = String.format("%1$tF %1$tT", c);
+
+        String eventName = logParser.getTagMap().get(event.mTag);
+        String pidName = Integer.toString(event.pid);
+
+        if (valueDescriptors.size() > 0) {
+            for (ValueDisplayDescriptor descriptor : valueDescriptors) {
+                logDescriptor(event, descriptor, date, pidName, eventName, logParser);
+            }
+        } else {
+            // we display the event. Since the StringBuilder contains the header (date, event name,
+            // pid) at this point, there isn't anything else to display.
+        }
+
+        // scroll if needed, by showing the last item
+        if (scroll) {
+            int itemCount = mLogTable.getItemCount();
+            if (itemCount > 0) {
+                mLogTable.showItem(mLogTable.getItem(itemCount - 1));
+            }
+        }
+    }
+
+
+    /**
+     * Logs a value in the ui.
+     *
+     * @param date
+     * @param pid
+     * @param event
+     * @param valueName
+     * @param value
+     * @param eventValueType
+     * @param valueType
+     */
+    private void logValue(String date, String pid, String event, String valueName,
+            String value, EventContainer.EventValueType eventValueType, EventValueDescription.ValueType valueType) {
+
+        TableItem item = new TableItem(mLogTable, SWT.NONE);
+        item.setText(0, date);
+        item.setText(1, pid);
+        item.setText(2, event);
+        item.setText(3, valueName);
+        item.setText(4, value);
+
+        String type;
+        if (valueType != EventValueDescription.ValueType.NOT_APPLICABLE) {
+            type = String.format("%1$s, %2$s", eventValueType.toString(), valueType.toString());
+        } else {
+            type = eventValueType.toString();
+        }
+
+        item.setText(5, type);
+    }
+
+    /**
+     * Logs a value from an {@link EventContainer} as defined by the {@link ValueDisplayDescriptor}.
+     *
+     * @param event      the EventContainer
+     * @param descriptor the ValueDisplayDescriptor defining which value to display.
+     * @param date       the date of the event in a string.
+     * @param pidName
+     * @param eventName
+     * @param logParser
+     */
+    private void logDescriptor(EventContainer event, ValueDisplayDescriptor descriptor,
+            String date, String pidName, String eventName, EventLogParser logParser) {
+
+        String value;
+        try {
+            value = event.getValueAsString(descriptor.valueIndex);
+        } catch (InvalidTypeException e) {
+            value = e.getMessage();
+        }
+
+        EventValueDescription[] values = logParser.getEventInfoMap().get(event.mTag);
+
+        EventValueDescription valueDescription = values[descriptor.valueIndex];
+
+        logValue(date, pidName, eventName, descriptor.valueName, value,
+                valueDescription.getEventValueType(), valueDescription.getValueType());
+    }
+
+    /**
+     * Creates the UI for a log display.
+     *
+     * @param parent   the parent {@link Composite}
+     * @param listener the {@link ILogColumnListener} to notify on column resize events.
+     * @return the top Composite of the UI.
+     */
+    private Control createLogUI(Composite parent, final ILogColumnListener listener) {
+        Composite mainComp = new Composite(parent, SWT.NONE);
+        GridLayout gl;
+        mainComp.setLayout(gl = new GridLayout(1, false));
+        gl.marginHeight = gl.marginWidth = 0;
+        mainComp.addDisposeListener(new DisposeListener() {
+            public void widgetDisposed(DisposeEvent e) {
+                mLogTable = null;
+            }
+        });
+
+        Label l = new Label(mainComp, SWT.CENTER);
+        l.setText(mName);
+        l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        mLogTable = new Table(mainComp, SWT.MULTI | SWT.FULL_SELECTION | SWT.V_SCROLL |
+                SWT.BORDER);
+        mLogTable.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        IPreferenceStore store = DdmUiPreferences.getStore();
+
+        TableColumn col = TableHelper.createTableColumn(
+                mLogTable, "Time",
+                SWT.LEFT, "0000-00-00 00:00:00", PREFS_COL_DATE, store); //$NON-NLS-1$
+        col.addControlListener(new ControlAdapter() {
+            @Override
+            public void controlResized(ControlEvent e) {
+                Object source = e.getSource();
+                if (source instanceof TableColumn) {
+                    listener.columnResized(0, (TableColumn) source);
+                }
+            }
+        });
+
+        col = TableHelper.createTableColumn(
+                mLogTable, "pid",
+                SWT.LEFT, "0000", PREFS_COL_PID, store); //$NON-NLS-1$
+        col.addControlListener(new ControlAdapter() {
+            @Override
+            public void controlResized(ControlEvent e) {
+                Object source = e.getSource();
+                if (source instanceof TableColumn) {
+                    listener.columnResized(1, (TableColumn) source);
+                }
+            }
+        });
+
+        col = TableHelper.createTableColumn(
+                mLogTable, "Event",
+                SWT.LEFT, "abcdejghijklmno", PREFS_COL_EVENTTAG, store); //$NON-NLS-1$
+        col.addControlListener(new ControlAdapter() {
+            @Override
+            public void controlResized(ControlEvent e) {
+                Object source = e.getSource();
+                if (source instanceof TableColumn) {
+                    listener.columnResized(2, (TableColumn) source);
+                }
+            }
+        });
+
+        col = TableHelper.createTableColumn(
+                mLogTable, "Name",
+                SWT.LEFT, "Process Name", PREFS_COL_VALUENAME, store); //$NON-NLS-1$
+        col.addControlListener(new ControlAdapter() {
+            @Override
+            public void controlResized(ControlEvent e) {
+                Object source = e.getSource();
+                if (source instanceof TableColumn) {
+                    listener.columnResized(3, (TableColumn) source);
+                }
+            }
+        });
+
+        col = TableHelper.createTableColumn(
+                mLogTable, "Value",
+                SWT.LEFT, "0000000", PREFS_COL_VALUE, store); //$NON-NLS-1$
+        col.addControlListener(new ControlAdapter() {
+            @Override
+            public void controlResized(ControlEvent e) {
+                Object source = e.getSource();
+                if (source instanceof TableColumn) {
+                    listener.columnResized(4, (TableColumn) source);
+                }
+            }
+        });
+
+        col = TableHelper.createTableColumn(
+                mLogTable, "Type",
+                SWT.LEFT, "long, seconds", PREFS_COL_TYPE, store); //$NON-NLS-1$
+        col.addControlListener(new ControlAdapter() {
+            @Override
+            public void controlResized(ControlEvent e) {
+                Object source = e.getSource();
+                if (source instanceof TableColumn) {
+                    listener.columnResized(5, (TableColumn) source);
+                }
+            }
+        });
+
+        mLogTable.setHeaderVisible(true);
+        mLogTable.setLinesVisible(true);
+
+        return mainComp;
+    }
+
+    /**
+     * Resizes the <code>index</code>-th column of the log {@link Table} (if applicable).
+     * <p/>
+     * This does nothing if the <code>Table</code> object is <code>null</code> (because the display
+     * type does not use a column) or if the <code>index</code>-th column is in fact the originating
+     * column passed as argument.
+     *
+     * @param index        the index of the column to resize
+     * @param sourceColumn the original column that was resize, and on which we need to sync the
+     *                     index-th column width.
+     */
+    @Override
+    void resizeColumn(int index, TableColumn sourceColumn) {
+        if (mLogTable != null) {
+            TableColumn col = mLogTable.getColumn(index);
+            if (col != sourceColumn) {
+                col.setWidth(sourceColumn.getWidth());
+            }
+        }
+    }
+
+    /**
+     * Gets display type
+     *
+     * @return display type as an integer
+     */
+    @Override
+    int getDisplayType() {
+        return DISPLAY_TYPE_LOG_ALL;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySync.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySync.java
new file mode 100644
index 0000000..82cc7a4
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySync.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.log.event;
+
+import com.android.ddmlib.log.EventContainer;
+import com.android.ddmlib.log.EventLogParser;
+import com.android.ddmlib.log.InvalidTypeException;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.jfree.chart.labels.CustomXYToolTipGenerator;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.XYBarRenderer;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.data.time.FixedMillisecond;
+import org.jfree.data.time.SimpleTimePeriod;
+import org.jfree.data.time.TimePeriodValues;
+import org.jfree.data.time.TimePeriodValuesCollection;
+import org.jfree.data.time.TimeSeries;
+import org.jfree.data.time.TimeSeriesCollection;
+import org.jfree.util.ShapeUtilities;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Scanner;
+import java.util.regex.Pattern;
+
+public class DisplaySync extends SyncCommon {
+
+    // Information to graph for each authority
+    private TimePeriodValues mDatasetsSync[];
+    private List<String> mTooltipsSync[];
+    private CustomXYToolTipGenerator mTooltipGenerators[];
+    private TimeSeries mDatasetsSyncTickle[];
+
+    // Dataset of error events to graph
+    private TimeSeries mDatasetError;
+
+    public DisplaySync(String name) {
+        super(name);
+    }
+
+    /**
+     * Creates the UI for the event display.
+     * @param parent the parent composite.
+     * @param logParser the current log parser.
+     * @return the created control (which may have children).
+     */
+    @Override
+    public Control createComposite(final Composite parent, EventLogParser logParser,
+            final ILogColumnListener listener) {
+        Control composite = createCompositeChart(parent, logParser, "Sync Status");
+        resetUI();
+        return composite;
+    }
+
+    /**
+     * Resets the display.
+     */
+    @Override
+    void resetUI() {
+        super.resetUI();
+        XYPlot xyPlot = mChart.getXYPlot();
+
+        XYBarRenderer br = new XYBarRenderer();
+        mDatasetsSync = new TimePeriodValues[NUM_AUTHS];
+        mTooltipsSync = new List[NUM_AUTHS];
+        mTooltipGenerators = new CustomXYToolTipGenerator[NUM_AUTHS];
+
+        TimePeriodValuesCollection tpvc = new TimePeriodValuesCollection();
+        xyPlot.setDataset(tpvc);
+        xyPlot.setRenderer(0, br);
+
+        XYLineAndShapeRenderer ls = new XYLineAndShapeRenderer();
+        ls.setBaseLinesVisible(false);
+        mDatasetsSyncTickle = new TimeSeries[NUM_AUTHS];
+        TimeSeriesCollection tsc = new TimeSeriesCollection();
+        xyPlot.setDataset(1, tsc);
+        xyPlot.setRenderer(1, ls);
+
+        mDatasetError = new TimeSeries("Errors", FixedMillisecond.class);
+        xyPlot.setDataset(2, new TimeSeriesCollection(mDatasetError));
+        XYLineAndShapeRenderer errls = new XYLineAndShapeRenderer();
+        errls.setBaseLinesVisible(false);
+        errls.setSeriesPaint(0, Color.RED);
+        xyPlot.setRenderer(2, errls);
+
+        for (int i = 0; i < NUM_AUTHS; i++) {
+            br.setSeriesPaint(i, AUTH_COLORS[i]);
+            ls.setSeriesPaint(i, AUTH_COLORS[i]);
+            mDatasetsSync[i] = new TimePeriodValues(AUTH_NAMES[i]);
+            tpvc.addSeries(mDatasetsSync[i]);
+            mTooltipsSync[i] = new ArrayList<String>();
+            mTooltipGenerators[i] = new CustomXYToolTipGenerator();
+            br.setSeriesToolTipGenerator(i, mTooltipGenerators[i]);
+            mTooltipGenerators[i].addToolTipSeries(mTooltipsSync[i]);
+
+            mDatasetsSyncTickle[i] = new TimeSeries(AUTH_NAMES[i] + " tickle",
+                    FixedMillisecond.class);
+            tsc.addSeries(mDatasetsSyncTickle[i]);
+            ls.setSeriesShape(i, ShapeUtilities.createUpTriangle(2.5f));
+        }
+    }
+
+    /**
+     * Updates the display with a new event.
+     *
+     * @param event     The event
+     * @param logParser The parser providing the event.
+     */
+    @Override
+    void newEvent(EventContainer event, EventLogParser logParser) {
+        super.newEvent(event, logParser); // Handle sync operation
+        try {
+            if (event.mTag == EVENT_TICKLE) {
+                int auth = getAuth(event.getValueAsString(0));
+                if (auth >= 0) {
+                    long msec = (long)event.sec * 1000L + (event.nsec / 1000000L);
+                    mDatasetsSyncTickle[auth].addOrUpdate(new FixedMillisecond(msec), -1);
+                }
+            }
+        } catch (InvalidTypeException e) {
+        }
+    }
+
+    /**
+     * Generate the height for an event.
+     * Height is somewhat arbitrarily the count of "things" that happened
+     * during the sync.
+     * When network traffic measurements are available, code should be modified
+     * to use that instead.
+     * @param details The details string associated with the event
+     * @return The height in arbirary units (0-100)
+     */
+    private int getHeightFromDetails(String details) {
+        if (details == null) {
+            return 1; // Arbitrary
+        }
+        int total = 0;
+        String parts[] = details.split("[a-zA-Z]");
+        for (String part : parts) {
+            if ("".equals(part)) continue;
+            total += Integer.parseInt(part);
+        }
+        if (total == 0) {
+            total = 1;
+        }
+        return total;
+    }
+
+    /**
+     * Generates the tooltips text for an event.
+     * This method decodes the cryptic details string.
+     * @param auth The authority associated with the event
+     * @param details The details string
+     * @param eventSource server, poll, etc.
+     * @return The text to display in the tooltips
+     */
+    private String getTextFromDetails(int auth, String details, int eventSource) {
+
+        StringBuffer sb = new StringBuffer();
+        sb.append(AUTH_NAMES[auth]).append(": \n");
+
+        Scanner scanner = new Scanner(details);
+        Pattern charPat = Pattern.compile("[a-zA-Z]");
+        Pattern numPat = Pattern.compile("[0-9]+");
+        while (scanner.hasNext()) {
+            String key = scanner.findInLine(charPat);
+            int val = Integer.parseInt(scanner.findInLine(numPat));
+            if (auth == GMAIL && "M".equals(key)) {
+                sb.append("messages from server: ").append(val).append("\n");
+            } else if (auth == GMAIL && "L".equals(key)) {
+                sb.append("labels from server: ").append(val).append("\n");
+            } else if (auth == GMAIL && "C".equals(key)) {
+                sb.append("check conversation requests from server: ").append(val).append("\n");
+            } else if (auth == GMAIL && "A".equals(key)) {
+                sb.append("attachments from server: ").append(val).append("\n");
+            } else if (auth == GMAIL && "U".equals(key)) {
+                sb.append("op updates from server: ").append(val).append("\n");
+            } else if (auth == GMAIL && "u".equals(key)) {
+                sb.append("op updates to server: ").append(val).append("\n");
+            } else if (auth == GMAIL && "S".equals(key)) {
+                sb.append("send/receive cycles: ").append(val).append("\n");
+            } else if ("Q".equals(key)) {
+                sb.append("queries to server: ").append(val).append("\n");
+            } else if ("E".equals(key)) {
+                sb.append("entries from server: ").append(val).append("\n");
+            } else if ("u".equals(key)) {
+                sb.append("updates from client: ").append(val).append("\n");
+            } else if ("i".equals(key)) {
+                sb.append("inserts from client: ").append(val).append("\n");
+            } else if ("d".equals(key)) {
+                sb.append("deletes from client: ").append(val).append("\n");
+            } else if ("f".equals(key)) {
+                sb.append("full sync requested\n");
+            } else if ("r".equals(key)) {
+                sb.append("partial sync unavailable\n");
+            } else if ("X".equals(key)) {
+                sb.append("hard error\n");
+            } else if ("e".equals(key)) {
+                sb.append("number of parse exceptions: ").append(val).append("\n");
+            } else if ("c".equals(key)) {
+                sb.append("number of conflicts: ").append(val).append("\n");
+            } else if ("a".equals(key)) {
+                sb.append("number of auth exceptions: ").append(val).append("\n");
+            } else if ("D".equals(key)) {
+                sb.append("too many deletions\n");
+            } else if ("R".equals(key)) {
+                sb.append("too many retries: ").append(val).append("\n");
+            } else if ("b".equals(key)) {
+                sb.append("database error\n");
+            } else if ("x".equals(key)) {
+                sb.append("soft error\n");
+            } else if ("l".equals(key)) {
+                sb.append("sync already in progress\n");
+            } else if ("I".equals(key)) {
+                sb.append("io exception\n");
+            } else if (auth == CONTACTS && "p".equals(key)) {
+                sb.append("photos uploaded from client: ").append(val).append("\n");
+            } else if (auth == CONTACTS && "P".equals(key)) {
+                sb.append("photos downloaded from server: ").append(val).append("\n");
+            } else if (auth == CALENDAR && "F".equals(key)) {
+                sb.append("server refresh\n");
+            } else if (auth == CALENDAR && "s".equals(key)) {
+                sb.append("server diffs fetched\n");
+            } else {
+                sb.append(key).append("=").append(val);
+            }
+        }
+        if (eventSource == 0) {
+            sb.append("(server)");
+        } else if (eventSource == 1) {
+            sb.append("(local)");
+        } else if (eventSource == 2) {
+            sb.append("(poll)");
+        } else if (eventSource == 3) {
+            sb.append("(user)");
+        }
+        return sb.toString();
+    }
+
+
+    /**
+     * Callback to process a sync event.
+     */
+    @Override
+    void processSyncEvent(EventContainer event, int auth, long startTime, long stopTime,
+            String details, boolean newEvent, int syncSource) {
+        if (!newEvent) {
+            // Details arrived for a previous sync event
+            // Remove event before reinserting.
+            int lastItem = mDatasetsSync[auth].getItemCount();
+            mDatasetsSync[auth].delete(lastItem-1, lastItem-1);
+            mTooltipsSync[auth].remove(lastItem-1);
+        }
+        double height = getHeightFromDetails(details);
+        height = height / (stopTime - startTime + 1) * 10000;
+        if (height > 30) {
+            height = 30;
+        }
+        mDatasetsSync[auth].add(new SimpleTimePeriod(startTime, stopTime), height);
+        mTooltipsSync[auth].add(getTextFromDetails(auth, details, syncSource));
+        mTooltipGenerators[auth].addToolTipSeries(mTooltipsSync[auth]);
+        if (details.indexOf('x') >= 0 || details.indexOf('X') >= 0) {
+            long msec = (long)event.sec * 1000L + (event.nsec / 1000000L);
+            mDatasetError.addOrUpdate(new FixedMillisecond(msec), -1);
+        }
+    }
+
+    /**
+     * Gets display type
+     *
+     * @return display type as an integer
+     */
+    @Override
+    int getDisplayType() {
+        return DISPLAY_TYPE_SYNC;
+    }
+}
\ No newline at end of file
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySyncHistogram.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySyncHistogram.java
new file mode 100644
index 0000000..36d90ce
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySyncHistogram.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.log.event;
+
+import com.android.ddmlib.log.EventContainer;
+import com.android.ddmlib.log.EventLogParser;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.AbstractXYItemRenderer;
+import org.jfree.chart.renderer.xy.XYBarRenderer;
+import org.jfree.data.time.RegularTimePeriod;
+import org.jfree.data.time.SimpleTimePeriod;
+import org.jfree.data.time.TimePeriodValues;
+import org.jfree.data.time.TimePeriodValuesCollection;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TimeZone;
+
+public class DisplaySyncHistogram extends SyncCommon {
+
+    Map<SimpleTimePeriod, Integer> mTimePeriodMap[];
+
+    // Information to graph for each authority
+    private TimePeriodValues mDatasetsSyncHist[];
+
+    public DisplaySyncHistogram(String name) {
+        super(name);
+    }
+
+    /**
+     * Creates the UI for the event display.
+     * @param parent the parent composite.
+     * @param logParser the current log parser.
+     * @return the created control (which may have children).
+     */
+    @Override
+    public Control createComposite(final Composite parent, EventLogParser logParser,
+            final ILogColumnListener listener) {
+        Control composite = createCompositeChart(parent, logParser, "Sync Histogram");
+        resetUI();
+        return composite;
+    }
+
+    /**
+     * Resets the display.
+     */
+    @Override
+    void resetUI() {
+        super.resetUI();
+        XYPlot xyPlot = mChart.getXYPlot();
+
+        AbstractXYItemRenderer br = new XYBarRenderer();
+        mDatasetsSyncHist = new TimePeriodValues[NUM_AUTHS+1];
+        mTimePeriodMap = new HashMap[NUM_AUTHS + 1];
+
+        TimePeriodValuesCollection tpvc = new TimePeriodValuesCollection();
+        xyPlot.setDataset(tpvc);
+        xyPlot.setRenderer(br);
+
+        for (int i = 0; i < NUM_AUTHS + 1; i++) {
+            br.setSeriesPaint(i, AUTH_COLORS[i]);
+            mDatasetsSyncHist[i] = new TimePeriodValues(AUTH_NAMES[i]);
+            tpvc.addSeries(mDatasetsSyncHist[i]);
+            mTimePeriodMap[i] = new HashMap<SimpleTimePeriod, Integer>();
+
+        }
+    }
+
+    /**
+     * Callback to process a sync event.
+     *
+     * @param event      The sync event
+     * @param startTime Start time (ms) of events
+     * @param stopTime Stop time (ms) of events
+     * @param details Details associated with the event.
+     * @param newEvent True if this event is a new sync event.  False if this event
+     * @param syncSource
+     */
+    @Override
+    void processSyncEvent(EventContainer event, int auth, long startTime, long stopTime,
+            String details, boolean newEvent, int syncSource) {
+        if (newEvent) {
+            if (details.indexOf('x') >= 0 || details.indexOf('X') >= 0) {
+                auth = ERRORS;
+            }
+            double delta = (stopTime - startTime) * 100. / 1000 / 3600; // Percent of hour
+            addHistEvent(0, auth, delta);
+        } else {
+            // sync_details arrived for an event that has already been graphed.
+            if (details.indexOf('x') >= 0 || details.indexOf('X') >= 0) {
+                // Item turns out to be in error, so transfer time from old auth to error.
+                double delta = (stopTime - startTime) * 100. / 1000 / 3600; // Percent of hour
+                addHistEvent(0, auth, -delta);
+                addHistEvent(0, ERRORS, delta);
+            }
+        }
+    }
+
+    /**
+     * Helper to add an event to the data series.
+     * Also updates error series if appropriate (x or X in details).
+     * @param stopTime Time event ends
+     * @param auth Sync authority
+     * @param value Value to graph for event
+     */
+    private void addHistEvent(long stopTime, int auth, double value) {
+        SimpleTimePeriod hour = getTimePeriod(stopTime, mHistWidth);
+
+        // Loop over all datasets to do the stacking.
+        for (int i = auth; i <= ERRORS; i++) {
+            addToPeriod(mDatasetsSyncHist, i, hour, value);
+        }
+    }
+
+    private void addToPeriod(TimePeriodValues tpv[], int auth, SimpleTimePeriod period,
+            double value) {
+        int index;
+        if (mTimePeriodMap[auth].containsKey(period)) {
+            index = mTimePeriodMap[auth].get(period);
+            double oldValue = tpv[auth].getValue(index).doubleValue();
+            tpv[auth].update(index, oldValue + value);
+        } else {
+            index = tpv[auth].getItemCount();
+            mTimePeriodMap[auth].put(period, index);
+            tpv[auth].add(period, value);
+        }
+    }
+
+    /**
+     * Creates a multiple-hour time period for the histogram.
+     * @param time Time in milliseconds.
+     * @param numHoursWide: should divide into a day.
+     * @return SimpleTimePeriod covering the number of hours and containing time.
+     */
+    private SimpleTimePeriod getTimePeriod(long time, long numHoursWide) {
+        Date date = new Date(time);
+        TimeZone zone = RegularTimePeriod.DEFAULT_TIME_ZONE;
+        Calendar calendar = Calendar.getInstance(zone);
+        calendar.setTime(date);
+        long hoursOfYear = calendar.get(Calendar.HOUR_OF_DAY) +
+                calendar.get(Calendar.DAY_OF_YEAR) * 24;
+        int year = calendar.get(Calendar.YEAR);
+        hoursOfYear = (hoursOfYear / numHoursWide) * numHoursWide;
+        calendar.clear();
+        calendar.set(year, 0, 1, 0, 0); // Jan 1
+        long start = calendar.getTimeInMillis() + hoursOfYear * 3600 * 1000;
+        return new SimpleTimePeriod(start, start + numHoursWide * 3600 * 1000);
+    }
+
+    /**
+     * Gets display type
+     *
+     * @return display type as an integer
+     */
+    @Override
+    int getDisplayType() {
+        return DISPLAY_TYPE_SYNC_HIST;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySyncPerf.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySyncPerf.java
new file mode 100644
index 0000000..9ce7045
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/DisplaySyncPerf.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.ddmuilib.log.event;
+
+import com.android.ddmlib.log.EventContainer;
+import com.android.ddmlib.log.EventLogParser;
+import com.android.ddmlib.log.InvalidTypeException;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.jfree.chart.labels.CustomXYToolTipGenerator;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.XYBarRenderer;
+import org.jfree.data.time.SimpleTimePeriod;
+import org.jfree.data.time.TimePeriodValues;
+import org.jfree.data.time.TimePeriodValuesCollection;
+
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DisplaySyncPerf extends SyncCommon {
+
+    CustomXYToolTipGenerator mTooltipGenerator;
+    List mTooltips[];
+
+    // The series number for each graphed item.
+    // sync authorities are 0-3
+    private static final int DB_QUERY = 4;
+    private static final int DB_WRITE = 5;
+    private static final int HTTP_NETWORK = 6;
+    private static final int HTTP_PROCESSING = 7;
+    private static final int NUM_SERIES = (HTTP_PROCESSING + 1);
+    private static final String SERIES_NAMES[] = {"Calendar", "Gmail", "Feeds", "Contacts",
+            "DB Query", "DB Write", "HTTP Response", "HTTP Processing",};
+    private static final Color SERIES_COLORS[] = {Color.MAGENTA, Color.GREEN, Color.BLUE,
+            Color.ORANGE, Color.RED, Color.CYAN, Color.PINK, Color.DARK_GRAY};
+    private static final double SERIES_YCOORD[] = {0, 0, 0, 0, 1, 1, 2, 2};
+
+    // Values from data/etc/event-log-tags
+    private static final int EVENT_DB_OPERATION = 52000;
+    private static final int EVENT_HTTP_STATS = 52001;
+    // op types for EVENT_DB_OPERATION
+    final int EVENT_DB_QUERY = 0;
+    final int EVENT_DB_WRITE = 1;
+
+    // Information to graph for each authority
+    private TimePeriodValues mDatasets[];
+
+    /**
+     * TimePeriodValuesCollection that supports Y intervals.  This allows the
+     * creation of "floating" bars, rather than bars rooted to the axis.
+     */
+    class YIntervalTimePeriodValuesCollection extends TimePeriodValuesCollection {
+        /** default serial UID */
+        private static final long serialVersionUID = 1L;
+
+        private double yheight;
+
+        /**
+         * Constructs a collection of bars with a fixed Y height.
+         *
+         * @param yheight The height of the bars.
+         */
+        YIntervalTimePeriodValuesCollection(double yheight) {
+            this.yheight = yheight;
+        }
+
+        /**
+         * Returns ending Y value that is a fixed amount greater than the starting value.
+         *
+         * @param series the series (zero-based index).
+         * @param item   the item (zero-based index).
+         * @return The ending Y value for the specified series and item.
+         */
+        @Override
+        public Number getEndY(int series, int item) {
+            return getY(series, item).doubleValue() + yheight;
+        }
+    }
+
+    /**
+     * Constructs a graph of network and database stats.
+     *
+     * @param name The name of this graph in the graph list.
+     */
+    public DisplaySyncPerf(String name) {
+        super(name);
+    }
+
+    /**
+     * Creates the UI for the event display.
+     *
+     * @param parent    the parent composite.
+     * @param logParser the current log parser.
+     * @return the created control (which may have children).
+     */
+    @Override
+    public Control createComposite(final Composite parent, EventLogParser logParser,
+            final ILogColumnListener listener) {
+        Control composite = createCompositeChart(parent, logParser, "Sync Performance");
+        resetUI();
+        return composite;
+    }
+
+    /**
+     * Resets the display.
+     */
+    @Override
+    void resetUI() {
+        super.resetUI();
+        XYPlot xyPlot = mChart.getXYPlot();
+        xyPlot.getRangeAxis().setVisible(false);
+        mTooltipGenerator = new CustomXYToolTipGenerator();
+        mTooltips = new List[NUM_SERIES];
+
+        XYBarRenderer br = new XYBarRenderer();
+        br.setUseYInterval(true);
+        mDatasets = new TimePeriodValues[NUM_SERIES];
+
+        TimePeriodValuesCollection tpvc = new YIntervalTimePeriodValuesCollection(1);
+        xyPlot.setDataset(tpvc);
+        xyPlot.setRenderer(br);
+
+        for (int i = 0; i < NUM_SERIES; i++) {
+            br.setSeriesPaint(i, SERIES_COLORS[i]);
+            mDatasets[i] = new TimePeriodValues(SERIES_NAMES[i]);
+            tpvc.addSeries(mDatasets[i]);
+            mTooltips[i] = new ArrayList<String>();
+            mTooltipGenerator.addToolTipSeries(mTooltips[i]);
+            br.setSeriesToolTipGenerator(i, mTooltipGenerator);
+        }
+    }
+
+    /**
+     * Updates the display with a new event.
+     *
+     * @param event     The event
+     * @param logParser The parser providing the event.
+     */
+    @Override
+    void newEvent(EventContainer event, EventLogParser logParser) {
+        super.newEvent(event, logParser); // Handle sync operation
+        try {
+            if (event.mTag == EVENT_DB_OPERATION) {
+                // 52000 db_operation (name|3),(op_type|1|5),(time|2|3)
+                String tip = event.getValueAsString(0);
+                long endTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
+                int opType = Integer.parseInt(event.getValueAsString(1));
+                long duration = Long.parseLong(event.getValueAsString(2));
+
+                if (opType == EVENT_DB_QUERY) {
+                    mDatasets[DB_QUERY].add(new SimpleTimePeriod(endTime - duration, endTime),
+                            SERIES_YCOORD[DB_QUERY]);
+                    mTooltips[DB_QUERY].add(tip);
+                } else if (opType == EVENT_DB_WRITE) {
+                    mDatasets[DB_WRITE].add(new SimpleTimePeriod(endTime - duration, endTime),
+                            SERIES_YCOORD[DB_WRITE]);
+                    mTooltips[DB_WRITE].add(tip);
+                }
+            } else if (event.mTag == EVENT_HTTP_STATS) {
+                // 52001 http_stats (useragent|3),(response|2|3),(processing|2|3),(tx|1|2),(rx|1|2)
+                String tip = event.getValueAsString(0) + ", tx:" + event.getValueAsString(3) +
+                        ", rx: " + event.getValueAsString(4);
+                long endTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
+                long netEndTime = endTime - Long.parseLong(event.getValueAsString(2));
+                long netStartTime = netEndTime - Long.parseLong(event.getValueAsString(1));
+                mDatasets[HTTP_NETWORK].add(new SimpleTimePeriod(netStartTime, netEndTime),
+                        SERIES_YCOORD[HTTP_NETWORK]);
+                mDatasets[HTTP_PROCESSING].add(new SimpleTimePeriod(netEndTime, endTime),
+                        SERIES_YCOORD[HTTP_PROCESSING]);
+                mTooltips[HTTP_NETWORK].add(tip);
+                mTooltips[HTTP_PROCESSING].add(tip);
+            }
+        } catch (InvalidTypeException e) {
+        }
+    }
+
+    /**
+     * Callback from super.newEvent to process a sync event.
+     *
+     * @param event      The sync event
+     * @param startTime  Start time (ms) of events
+     * @param stopTime   Stop time (ms) of events
+     * @param details    Details associated with the event.
+     * @param newEvent   True if this event is a new sync event.  False if this event
+     * @param syncSource
+     */
+    @Override
+    void processSyncEvent(EventContainer event, int auth, long startTime, long stopTime,
+            String details, boolean newEvent, int syncSource) {
+        if (newEvent) {
+            mDatasets[auth].add(new SimpleTimePeriod(startTime, stopTime), SERIES_YCOORD[auth]);
+        }
+    }
+
+    /**
+     * Gets display type
+     *
+     * @return display type as an integer
+     */
+    @Override
+    int getDisplayType() {
+        return DISPLAY_TYPE_SYNC_PERF;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventDisplay.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventDisplay.java
new file mode 100644
index 0000000..2223a4d
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventDisplay.java
@@ -0,0 +1,971 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.log.event;
+
+import com.android.ddmlib.Log;
+import com.android.ddmlib.log.EventContainer;
+import com.android.ddmlib.log.EventContainer.CompareMethod;
+import com.android.ddmlib.log.EventContainer.EventValueType;
+import com.android.ddmlib.log.EventLogParser;
+import com.android.ddmlib.log.EventValueDescription.ValueType;
+import com.android.ddmlib.log.InvalidTypeException;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.event.ChartChangeEvent;
+import org.jfree.chart.event.ChartChangeEventType;
+import org.jfree.chart.event.ChartChangeListener;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.title.TextTitle;
+import org.jfree.data.time.Millisecond;
+import org.jfree.data.time.TimeSeries;
+import org.jfree.data.time.TimeSeriesCollection;
+import org.jfree.experimental.chart.swt.ChartComposite;
+import org.jfree.experimental.swt.SWTUtils;
+
+import java.security.InvalidParameterException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ * Represents a custom display of one or more events.
+ */
+abstract class EventDisplay {
+
+    private final static String DISPLAY_DATA_STORAGE_SEPARATOR = ":"; //$NON-NLS-1$
+    private final static String PID_STORAGE_SEPARATOR = ","; //$NON-NLS-1$
+    private final static String DESCRIPTOR_STORAGE_SEPARATOR = "$"; //$NON-NLS-1$
+    private final static String DESCRIPTOR_DATA_STORAGE_SEPARATOR = "!"; //$NON-NLS-1$
+
+    private final static String FILTER_VALUE_NULL = "<null>"; //$NON-NLS-1$
+
+    public final static int DISPLAY_TYPE_LOG_ALL = 0;
+    public final static int DISPLAY_TYPE_FILTERED_LOG = 1;
+    public final static int DISPLAY_TYPE_GRAPH = 2;
+    public final static int DISPLAY_TYPE_SYNC = 3;
+    public final static int DISPLAY_TYPE_SYNC_HIST = 4;
+    public final static int DISPLAY_TYPE_SYNC_PERF = 5;
+
+    private final static int EVENT_CHECK_FAILED = 0;
+    protected final static int EVENT_CHECK_SAME_TAG = 1;
+    protected final static int EVENT_CHECK_SAME_VALUE = 2;
+
+    /**
+     * Creates the appropriate EventDisplay subclass.
+     *
+     * @param type the type of display (DISPLAY_TYPE_LOG_ALL, etc)
+     * @param name the name of the display
+     * @return the created object
+     */
+    public static EventDisplay eventDisplayFactory(int type, String name) {
+        switch (type) {
+            case DISPLAY_TYPE_LOG_ALL:
+                return new DisplayLog(name);
+            case DISPLAY_TYPE_FILTERED_LOG:
+                return new DisplayFilteredLog(name);
+            case DISPLAY_TYPE_SYNC:
+                return new DisplaySync(name);
+            case DISPLAY_TYPE_SYNC_HIST:
+                return new DisplaySyncHistogram(name);
+            case DISPLAY_TYPE_GRAPH:
+                return new DisplayGraph(name);
+            case DISPLAY_TYPE_SYNC_PERF:
+                return new DisplaySyncPerf(name);
+            default:
+                throw new InvalidParameterException("Unknown Display Type " + type); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Adds event to the display.
+     * @param event The event
+     * @param logParser The log parser.
+     */
+    abstract void newEvent(EventContainer event, EventLogParser logParser);
+
+    /**
+     * Resets the display.
+     */
+    abstract void resetUI();
+
+    /**
+     * Gets display type
+     *
+     * @return display type as an integer
+     */
+    abstract int getDisplayType();
+
+    /**
+     * Creates the UI for the event display.
+     *
+     * @param parent    the parent composite.
+     * @param logParser the current log parser.
+     * @return the created control (which may have children).
+     */
+    abstract Control createComposite(final Composite parent, EventLogParser logParser,
+            final ILogColumnListener listener);
+
+    interface ILogColumnListener {
+        void columnResized(int index, TableColumn sourceColumn);
+    }
+
+    /**
+     * Describes an event to be displayed.
+     */
+    static class OccurrenceDisplayDescriptor {
+
+        int eventTag = -1;
+        int seriesValueIndex = -1;
+        boolean includePid = false;
+        int filterValueIndex = -1;
+        CompareMethod filterCompareMethod = CompareMethod.EQUAL_TO;
+        Object filterValue = null;
+
+        OccurrenceDisplayDescriptor() {
+        }
+
+        OccurrenceDisplayDescriptor(OccurrenceDisplayDescriptor descriptor) {
+            replaceWith(descriptor);
+        }
+
+        OccurrenceDisplayDescriptor(int eventTag) {
+            this.eventTag = eventTag;
+        }
+
+        OccurrenceDisplayDescriptor(int eventTag, int seriesValueIndex) {
+            this.eventTag = eventTag;
+            this.seriesValueIndex = seriesValueIndex;
+        }
+
+        void replaceWith(OccurrenceDisplayDescriptor descriptor) {
+            eventTag = descriptor.eventTag;
+            seriesValueIndex = descriptor.seriesValueIndex;
+            includePid = descriptor.includePid;
+            filterValueIndex = descriptor.filterValueIndex;
+            filterCompareMethod = descriptor.filterCompareMethod;
+            filterValue = descriptor.filterValue;
+        }
+
+        /**
+         * Loads the descriptor parameter from a storage string. The storage string must have
+         * been generated with {@link #getStorageString()}.
+         *
+         * @param storageString the storage string
+         */
+        final void loadFrom(String storageString) {
+            String[] values = storageString.split(Pattern.quote(DESCRIPTOR_DATA_STORAGE_SEPARATOR));
+            loadFrom(values, 0);
+        }
+
+        /**
+         * Loads the parameters from an array of strings.
+         *
+         * @param storageStrings the strings representing each parameter.
+         * @param index          the starting index in the array of strings.
+         * @return the new index in the array.
+         */
+        protected int loadFrom(String[] storageStrings, int index) {
+            eventTag = Integer.parseInt(storageStrings[index++]);
+            seriesValueIndex = Integer.parseInt(storageStrings[index++]);
+            includePid = Boolean.parseBoolean(storageStrings[index++]);
+            filterValueIndex = Integer.parseInt(storageStrings[index++]);
+            try {
+                filterCompareMethod = CompareMethod.valueOf(storageStrings[index++]);
+            } catch (IllegalArgumentException e) {
+                // if the name does not match any known CompareMethod, we init it to the default one
+                filterCompareMethod = CompareMethod.EQUAL_TO;
+            }
+            String value = storageStrings[index++];
+            if (filterValueIndex != -1 && FILTER_VALUE_NULL.equals(value) == false) {
+                filterValue = EventValueType.getObjectFromStorageString(value);
+            }
+
+            return index;
+        }
+
+        /**
+         * Returns the storage string for the receiver.
+         */
+        String getStorageString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(eventTag);
+            sb.append(DESCRIPTOR_DATA_STORAGE_SEPARATOR);
+            sb.append(seriesValueIndex);
+            sb.append(DESCRIPTOR_DATA_STORAGE_SEPARATOR);
+            sb.append(Boolean.toString(includePid));
+            sb.append(DESCRIPTOR_DATA_STORAGE_SEPARATOR);
+            sb.append(filterValueIndex);
+            sb.append(DESCRIPTOR_DATA_STORAGE_SEPARATOR);
+            sb.append(filterCompareMethod.name());
+            sb.append(DESCRIPTOR_DATA_STORAGE_SEPARATOR);
+            if (filterValue != null) {
+                String value = EventValueType.getStorageString(filterValue);
+                if (value != null) {
+                    sb.append(value);
+                } else {
+                    sb.append(FILTER_VALUE_NULL);
+                }
+            } else {
+                sb.append(FILTER_VALUE_NULL);
+            }
+
+            return sb.toString();
+        }
+    }
+
+    /**
+     * Describes an event value to be displayed.
+     */
+    static final class ValueDisplayDescriptor extends OccurrenceDisplayDescriptor {
+        String valueName;
+        int valueIndex = -1;
+
+        ValueDisplayDescriptor() {
+            super();
+        }
+
+        ValueDisplayDescriptor(ValueDisplayDescriptor descriptor) {
+            super();
+            replaceWith(descriptor);
+        }
+
+        ValueDisplayDescriptor(int eventTag, String valueName, int valueIndex) {
+            super(eventTag);
+            this.valueName = valueName;
+            this.valueIndex = valueIndex;
+        }
+
+        ValueDisplayDescriptor(int eventTag, String valueName, int valueIndex,
+                int seriesValueIndex) {
+            super(eventTag, seriesValueIndex);
+            this.valueName = valueName;
+            this.valueIndex = valueIndex;
+        }
+
+        @Override
+        void replaceWith(OccurrenceDisplayDescriptor descriptor) {
+            super.replaceWith(descriptor);
+            if (descriptor instanceof ValueDisplayDescriptor) {
+                ValueDisplayDescriptor valueDescriptor = (ValueDisplayDescriptor) descriptor;
+                valueName = valueDescriptor.valueName;
+                valueIndex = valueDescriptor.valueIndex;
+            }
+        }
+
+        /**
+         * Loads the parameters from an array of strings.
+         *
+         * @param storageStrings the strings representing each parameter.
+         * @param index          the starting index in the array of strings.
+         * @return the new index in the array.
+         */
+        @Override
+        protected int loadFrom(String[] storageStrings, int index) {
+            index = super.loadFrom(storageStrings, index);
+            valueName = storageStrings[index++];
+            valueIndex = Integer.parseInt(storageStrings[index++]);
+            return index;
+        }
+
+        /**
+         * Returns the storage string for the receiver.
+         */
+        @Override
+        String getStorageString() {
+            String superStorage = super.getStorageString();
+
+            StringBuilder sb = new StringBuilder();
+            sb.append(superStorage);
+            sb.append(DESCRIPTOR_DATA_STORAGE_SEPARATOR);
+            sb.append(valueName);
+            sb.append(DESCRIPTOR_DATA_STORAGE_SEPARATOR);
+            sb.append(valueIndex);
+
+            return sb.toString();
+        }
+    }
+
+    /* ==================
+     * Event Display parameters.
+     * ================== */
+    protected String mName;
+
+    private boolean mPidFiltering = false;
+
+    private ArrayList<Integer> mPidFilterList = null;
+
+    protected final ArrayList<ValueDisplayDescriptor> mValueDescriptors =
+            new ArrayList<ValueDisplayDescriptor>();
+    private final ArrayList<OccurrenceDisplayDescriptor> mOccurrenceDescriptors =
+            new ArrayList<OccurrenceDisplayDescriptor>();
+
+    /* ==================
+     * Event Display members for display purpose.
+     * ================== */
+    // chart objects
+    /**
+     * This is a map of (descriptor, map2) where map2 is a map of (pid, chart-series)
+     */
+    protected final HashMap<ValueDisplayDescriptor, HashMap<Integer, TimeSeries>> mValueDescriptorSeriesMap =
+            new HashMap<ValueDisplayDescriptor, HashMap<Integer, TimeSeries>>();
+    /**
+     * This is a map of (descriptor, map2) where map2 is a map of (pid, chart-series)
+     */
+    protected final HashMap<OccurrenceDisplayDescriptor, HashMap<Integer, TimeSeries>> mOcurrenceDescriptorSeriesMap =
+            new HashMap<OccurrenceDisplayDescriptor, HashMap<Integer, TimeSeries>>();
+
+    /**
+     * This is a map of (ValueType, dataset)
+     */
+    protected final HashMap<ValueType, TimeSeriesCollection> mValueTypeDataSetMap =
+            new HashMap<ValueType, TimeSeriesCollection>();
+
+    protected JFreeChart mChart;
+    protected TimeSeriesCollection mOccurrenceDataSet;
+    protected int mDataSetCount;
+    private ChartComposite mChartComposite;
+    protected long mMaximumChartItemAge = -1;
+    protected long mHistWidth = 1;
+
+    // log objects.
+    protected Table mLogTable;
+
+    /* ==================
+     * Misc data.
+     * ================== */
+    protected int mValueDescriptorCheck = EVENT_CHECK_FAILED;
+
+    EventDisplay(String name) {
+        mName = name;
+    }
+
+    static EventDisplay clone(EventDisplay from) {
+        EventDisplay ed = eventDisplayFactory(from.getDisplayType(), from.getName());
+        ed.mName = from.mName;
+        ed.mPidFiltering = from.mPidFiltering;
+        ed.mMaximumChartItemAge = from.mMaximumChartItemAge;
+        ed.mHistWidth = from.mHistWidth;
+
+        if (from.mPidFilterList != null) {
+            ed.mPidFilterList = new ArrayList<Integer>();
+            ed.mPidFilterList.addAll(from.mPidFilterList);
+        }
+
+        for (ValueDisplayDescriptor desc : from.mValueDescriptors) {
+            ed.mValueDescriptors.add(new ValueDisplayDescriptor(desc));
+        }
+        ed.mValueDescriptorCheck = from.mValueDescriptorCheck;
+
+        for (OccurrenceDisplayDescriptor desc : from.mOccurrenceDescriptors) {
+            ed.mOccurrenceDescriptors.add(new OccurrenceDisplayDescriptor(desc));
+        }
+        return ed;
+    }
+
+    /**
+     * Returns the parameters of the receiver as a single String for storage.
+     */
+    String getStorageString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(mName);
+        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
+        sb.append(getDisplayType());
+        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
+        sb.append(Boolean.toString(mPidFiltering));
+        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
+        sb.append(getPidStorageString());
+        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
+        sb.append(getDescriptorStorageString(mValueDescriptors));
+        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
+        sb.append(getDescriptorStorageString(mOccurrenceDescriptors));
+        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
+        sb.append(mMaximumChartItemAge);
+        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
+        sb.append(mHistWidth);
+        sb.append(DISPLAY_DATA_STORAGE_SEPARATOR);
+
+        return sb.toString();
+    }
+
+    void setName(String name) {
+        mName = name;
+    }
+
+    String getName() {
+        return mName;
+    }
+
+    void setPidFiltering(boolean filterByPid) {
+        mPidFiltering = filterByPid;
+    }
+
+    boolean getPidFiltering() {
+        return mPidFiltering;
+    }
+
+    void setPidFilterList(ArrayList<Integer> pids) {
+        if (mPidFiltering == false) {
+            new InvalidParameterException();
+        }
+
+        mPidFilterList = pids;
+    }
+
+    ArrayList<Integer> getPidFilterList() {
+        return mPidFilterList;
+    }
+
+    void addPidFiler(int pid) {
+        if (mPidFiltering == false) {
+            new InvalidParameterException();
+        }
+
+        if (mPidFilterList == null) {
+            mPidFilterList = new ArrayList<Integer>();
+        }
+
+        mPidFilterList.add(pid);
+    }
+
+    /**
+     * Returns an iterator to the list of {@link ValueDisplayDescriptor}.
+     */
+    Iterator<ValueDisplayDescriptor> getValueDescriptors() {
+        return mValueDescriptors.iterator();
+    }
+
+    /**
+     * Update checks on the descriptors. Must be called whenever a descriptor is modified outside
+     * of this class.
+     */
+    void updateValueDescriptorCheck() {
+        mValueDescriptorCheck = checkDescriptors();
+    }
+
+    /**
+     * Returns an iterator to the list of {@link OccurrenceDisplayDescriptor}.
+     */
+    Iterator<OccurrenceDisplayDescriptor> getOccurrenceDescriptors() {
+        return mOccurrenceDescriptors.iterator();
+    }
+
+    /**
+     * Adds a descriptor. This can be a {@link OccurrenceDisplayDescriptor} or a
+     * {@link ValueDisplayDescriptor}.
+     *
+     * @param descriptor the descriptor to be added.
+     */
+    void addDescriptor(OccurrenceDisplayDescriptor descriptor) {
+        if (descriptor instanceof ValueDisplayDescriptor) {
+            mValueDescriptors.add((ValueDisplayDescriptor) descriptor);
+            mValueDescriptorCheck = checkDescriptors();
+        } else {
+            mOccurrenceDescriptors.add(descriptor);
+        }
+    }
+
+    /**
+     * Returns a descriptor by index and class (extending {@link OccurrenceDisplayDescriptor}).
+     *
+     * @param descriptorClass the class of the descriptor to return.
+     * @param index           the index of the descriptor to return.
+     * @return either a {@link OccurrenceDisplayDescriptor} or a {@link ValueDisplayDescriptor}
+     *         or <code>null</code> if <code>descriptorClass</code> is another class.
+     */
+    OccurrenceDisplayDescriptor getDescriptor(
+            Class<? extends OccurrenceDisplayDescriptor> descriptorClass, int index) {
+
+        if (descriptorClass == OccurrenceDisplayDescriptor.class) {
+            return mOccurrenceDescriptors.get(index);
+        } else if (descriptorClass == ValueDisplayDescriptor.class) {
+            return mValueDescriptors.get(index);
+        }
+
+        return null;
+    }
+
+    /**
+     * Removes a descriptor based on its class and index.
+     *
+     * @param descriptorClass the class of the descriptor.
+     * @param index           the index of the descriptor to be removed.
+     */
+    void removeDescriptor(Class<? extends OccurrenceDisplayDescriptor> descriptorClass, int index) {
+        if (descriptorClass == OccurrenceDisplayDescriptor.class) {
+            mOccurrenceDescriptors.remove(index);
+        } else if (descriptorClass == ValueDisplayDescriptor.class) {
+            mValueDescriptors.remove(index);
+            mValueDescriptorCheck = checkDescriptors();
+        }
+    }
+
+    Control createCompositeChart(final Composite parent, EventLogParser logParser,
+            String title) {
+        mChart = ChartFactory.createTimeSeriesChart(
+                null,
+                null /* timeAxisLabel */,
+                null /* valueAxisLabel */,
+                null, /* dataset. set below */
+                true /* legend */,
+                false /* tooltips */,
+                false /* urls */);
+
+        // get the font to make a proper title. We need to convert the swt font,
+        // into an awt font.
+        Font f = parent.getFont();
+        FontData[] fData = f.getFontData();
+
+        // event though on Mac OS there could be more than one fontData, we'll only use
+        // the first one.
+        FontData firstFontData = fData[0];
+
+        java.awt.Font awtFont = SWTUtils.toAwtFont(parent.getDisplay(),
+                firstFontData, true /* ensureSameSize */);
+
+
+        mChart.setTitle(new TextTitle(title, awtFont));
+
+        final XYPlot xyPlot = mChart.getXYPlot();
+        xyPlot.setRangeCrosshairVisible(true);
+        xyPlot.setRangeCrosshairLockedOnData(true);
+        xyPlot.setDomainCrosshairVisible(true);
+        xyPlot.setDomainCrosshairLockedOnData(true);
+
+        mChart.addChangeListener(new ChartChangeListener() {
+            public void chartChanged(ChartChangeEvent event) {
+                ChartChangeEventType type = event.getType();
+                if (type == ChartChangeEventType.GENERAL) {
+                    // because the value we need (rangeCrosshair and domainCrosshair) are
+                    // updated on the draw, but the notification happens before the draw,
+                    // we process the click in a future runnable!
+                    parent.getDisplay().asyncExec(new Runnable() {
+                        public void run() {
+                            processClick(xyPlot);
+                        }
+                    });
+                }
+            }
+        });
+
+        mChartComposite = new ChartComposite(parent, SWT.BORDER, mChart,
+                ChartComposite.DEFAULT_WIDTH,
+                ChartComposite.DEFAULT_HEIGHT,
+                ChartComposite.DEFAULT_MINIMUM_DRAW_WIDTH,
+                ChartComposite.DEFAULT_MINIMUM_DRAW_HEIGHT,
+                3000, // max draw width. We don't want it to zoom, so we put a big number
+                3000, // max draw height. We don't want it to zoom, so we put a big number
+                true,  // off-screen buffer
+                true,  // properties
+                true,  // save
+                true,  // print
+                true,  // zoom
+                true);   // tooltips
+
+        mChartComposite.addDisposeListener(new DisposeListener() {
+            public void widgetDisposed(DisposeEvent e) {
+                mValueTypeDataSetMap.clear();
+                mDataSetCount = 0;
+                mOccurrenceDataSet = null;
+                mChart = null;
+                mChartComposite = null;
+                mValueDescriptorSeriesMap.clear();
+                mOcurrenceDescriptorSeriesMap.clear();
+            }
+        });
+
+        return mChartComposite;
+
+    }
+
+    private void processClick(XYPlot xyPlot) {
+        double rangeValue = xyPlot.getRangeCrosshairValue();
+        if (rangeValue != 0) {
+            double domainValue = xyPlot.getDomainCrosshairValue();
+
+            Millisecond msec = new Millisecond(new Date((long) domainValue));
+
+            // look for values in the dataset that contains data at this TimePeriod
+            Set<ValueDisplayDescriptor> descKeys = mValueDescriptorSeriesMap.keySet();
+
+            for (ValueDisplayDescriptor descKey : descKeys) {
+                HashMap<Integer, TimeSeries> map = mValueDescriptorSeriesMap.get(descKey);
+
+                Set<Integer> pidKeys = map.keySet();
+
+                for (Integer pidKey : pidKeys) {
+                    TimeSeries series = map.get(pidKey);
+
+                    Number value = series.getValue(msec);
+                    if (value != null) {
+                        // found a match. lets check against the actual value.
+                        if (value.doubleValue() == rangeValue) {
+
+                            return;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Resizes the <code>index</code>-th column of the log {@link Table} (if applicable).
+     * Subclasses can override if necessary.
+     * <p/>
+     * This does nothing if the <code>Table</code> object is <code>null</code> (because the display
+     * type does not use a column) or if the <code>index</code>-th column is in fact the originating
+     * column passed as argument.
+     *
+     * @param index        the index of the column to resize
+     * @param sourceColumn the original column that was resize, and on which we need to sync the
+     *                     index-th column width.
+     */
+    void resizeColumn(int index, TableColumn sourceColumn) {
+    }
+
+    /**
+     * Sets the current {@link EventLogParser} object.
+     * Subclasses can override if necessary.
+     */
+    protected void setNewLogParser(EventLogParser logParser) {
+    }
+
+    /**
+     * Prepares the {@link EventDisplay} for a multi event display.
+     */
+    void startMultiEventDisplay() {
+        if (mLogTable != null) {
+            mLogTable.setRedraw(false);
+        }
+    }
+
+    /**
+     * Finalizes the {@link EventDisplay} after a multi event display.
+     */
+    void endMultiEventDisplay() {
+        if (mLogTable != null) {
+            mLogTable.setRedraw(true);
+        }
+    }
+
+    /**
+     * Returns the {@link Table} object used to display events, if any.
+     *
+     * @return a Table object or <code>null</code>.
+     */
+    Table getTable() {
+        return mLogTable;
+    }
+
+    /**
+     * Loads a new {@link EventDisplay} from a storage string. The string must have been created
+     * with {@link #getStorageString()}.
+     *
+     * @param storageString the storage string
+     * @return a new {@link EventDisplay} or null if the load failed.
+     */
+    static EventDisplay load(String storageString) {
+        if (storageString.length() > 0) {
+            // the storage string is separated by ':'
+            String[] values = storageString.split(Pattern.quote(DISPLAY_DATA_STORAGE_SEPARATOR));
+
+            try {
+                int index = 0;
+
+                String name = values[index++];
+                int displayType = Integer.parseInt(values[index++]);
+                boolean pidFiltering = Boolean.parseBoolean(values[index++]);
+
+                EventDisplay ed = eventDisplayFactory(displayType, name);
+                ed.setPidFiltering(pidFiltering);
+
+                // because empty sections are removed by String.split(), we have to check
+                // the index for those.
+                if (index < values.length) {
+                    ed.loadPidFilters(values[index++]);
+                }
+
+                if (index < values.length) {
+                    ed.loadValueDescriptors(values[index++]);
+                }
+
+                if (index < values.length) {
+                    ed.loadOccurrenceDescriptors(values[index++]);
+                }
+
+                ed.updateValueDescriptorCheck();
+
+                if (index < values.length) {
+                    ed.mMaximumChartItemAge = Long.parseLong(values[index++]);
+                }
+
+                if (index < values.length) {
+                    ed.mHistWidth = Long.parseLong(values[index++]);
+                }
+
+                return ed;
+            } catch (RuntimeException re) {
+                // we'll return null below.
+                Log.e("ddms", re);
+            }
+        }
+
+        return null;
+    }
+
+    private String getPidStorageString() {
+        if (mPidFilterList != null) {
+            StringBuilder sb = new StringBuilder();
+            boolean first = true;
+            for (Integer i : mPidFilterList) {
+                if (first == false) {
+                    sb.append(PID_STORAGE_SEPARATOR);
+                } else {
+                    first = false;
+                }
+                sb.append(i);
+            }
+
+            return sb.toString();
+        }
+        return ""; //$NON-NLS-1$
+    }
+
+
+    private void loadPidFilters(String storageString) {
+        if (storageString.length() > 0) {
+            String[] values = storageString.split(Pattern.quote(PID_STORAGE_SEPARATOR));
+
+            for (String value : values) {
+                if (mPidFilterList == null) {
+                    mPidFilterList = new ArrayList<Integer>();
+                }
+                mPidFilterList.add(Integer.parseInt(value));
+            }
+        }
+    }
+
+    private String getDescriptorStorageString(
+            ArrayList<? extends OccurrenceDisplayDescriptor> descriptorList) {
+        StringBuilder sb = new StringBuilder();
+        boolean first = true;
+
+        for (OccurrenceDisplayDescriptor descriptor : descriptorList) {
+            if (first == false) {
+                sb.append(DESCRIPTOR_STORAGE_SEPARATOR);
+            } else {
+                first = false;
+            }
+            sb.append(descriptor.getStorageString());
+        }
+
+        return sb.toString();
+    }
+
+    private void loadOccurrenceDescriptors(String storageString) {
+        if (storageString.length() == 0) {
+            return;
+        }
+
+        String[] values = storageString.split(Pattern.quote(DESCRIPTOR_STORAGE_SEPARATOR));
+
+        for (String value : values) {
+            OccurrenceDisplayDescriptor desc = new OccurrenceDisplayDescriptor();
+            desc.loadFrom(value);
+            mOccurrenceDescriptors.add(desc);
+        }
+    }
+
+    private void loadValueDescriptors(String storageString) {
+        if (storageString.length() == 0) {
+            return;
+        }
+
+        String[] values = storageString.split(Pattern.quote(DESCRIPTOR_STORAGE_SEPARATOR));
+
+        for (String value : values) {
+            ValueDisplayDescriptor desc = new ValueDisplayDescriptor();
+            desc.loadFrom(value);
+            mValueDescriptors.add(desc);
+        }
+    }
+
+    /**
+     * Fills a list with {@link OccurrenceDisplayDescriptor} (or a subclass of it) from another
+     * list if they are configured to display the {@link EventContainer}
+     *
+     * @param event    the event container
+     * @param fullList the list with all the descriptors.
+     * @param outList  the list to fill.
+     */
+    @SuppressWarnings("unchecked")
+    private void getDescriptors(EventContainer event,
+            ArrayList<? extends OccurrenceDisplayDescriptor> fullList,
+            ArrayList outList) {
+        for (OccurrenceDisplayDescriptor descriptor : fullList) {
+            try {
+                // first check the event tag.
+                if (descriptor.eventTag == event.mTag) {
+                    // now check if we have a filter on a value
+                    if (descriptor.filterValueIndex == -1 ||
+                            event.testValue(descriptor.filterValueIndex, descriptor.filterValue,
+                                    descriptor.filterCompareMethod)) {
+                        outList.add(descriptor);
+                    }
+                }
+            } catch (InvalidTypeException ite) {
+                // if the filter for the descriptor was incorrect, we ignore the descriptor.
+            } catch (ArrayIndexOutOfBoundsException aioobe) {
+                // if the index was wrong (the event content may have changed since we setup the
+                // display), we do nothing but log the error
+                Log.e("Event Log", String.format(
+                        "ArrayIndexOutOfBoundsException occured when checking %1$d-th value of event %2$d", //$NON-NLS-1$
+                        descriptor.filterValueIndex, descriptor.eventTag));
+            }
+        }
+    }
+
+    /**
+     * Filters the {@link com.android.ddmlib.log.EventContainer}, and fills two list of {@link com.android.ddmuilib.log.event.EventDisplay.ValueDisplayDescriptor}
+     * and {@link com.android.ddmuilib.log.event.EventDisplay.OccurrenceDisplayDescriptor} configured to display the event.
+     *
+     * @param event
+     * @param valueDescriptors
+     * @param occurrenceDescriptors
+     * @return true if the event should be displayed.
+     */
+
+    protected boolean filterEvent(EventContainer event,
+            ArrayList<ValueDisplayDescriptor> valueDescriptors,
+            ArrayList<OccurrenceDisplayDescriptor> occurrenceDescriptors) {
+
+        // test the pid first (if needed)
+        if (mPidFiltering && mPidFilterList != null) {
+            boolean found = false;
+            for (int pid : mPidFilterList) {
+                if (pid == event.pid) {
+                    found = true;
+                    break;
+                }
+            }
+
+            if (found == false) {
+                return false;
+            }
+        }
+
+        // now get the list of matching descriptors
+        getDescriptors(event, mValueDescriptors, valueDescriptors);
+        getDescriptors(event, mOccurrenceDescriptors, occurrenceDescriptors);
+
+        // and return whether there is at least one match in either list.
+        return (valueDescriptors.size() > 0 || occurrenceDescriptors.size() > 0);
+    }
+
+    /**
+     * Checks all the {@link ValueDisplayDescriptor} for similarity.
+     * If all the event values are from the same tag, the method will return EVENT_CHECK_SAME_TAG.
+     * If all the event/value are the same, the method will return EVENT_CHECK_SAME_VALUE
+     *
+     * @return flag as described above
+     */
+    private int checkDescriptors() {
+        if (mValueDescriptors.size() < 2) {
+            return EVENT_CHECK_SAME_VALUE;
+        }
+
+        int tag = -1;
+        int index = -1;
+        for (ValueDisplayDescriptor display : mValueDescriptors) {
+            if (tag == -1) {
+                tag = display.eventTag;
+                index = display.valueIndex;
+            } else {
+                if (tag != display.eventTag) {
+                    return EVENT_CHECK_FAILED;
+                } else {
+                    if (index != -1) {
+                        if (index != display.valueIndex) {
+                            index = -1;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (index == -1) {
+            return EVENT_CHECK_SAME_TAG;
+        }
+
+        return EVENT_CHECK_SAME_VALUE;
+    }
+
+    /**
+     * Resets the time limit on the chart to be infinite.
+     */
+    void resetChartTimeLimit() {
+        mMaximumChartItemAge = -1;
+    }
+
+    /**
+     * Sets the time limit on the charts.
+     *
+     * @param timeLimit the time limit in seconds.
+     */
+    void setChartTimeLimit(long timeLimit) {
+        mMaximumChartItemAge = timeLimit;
+    }
+
+    long getChartTimeLimit() {
+        return mMaximumChartItemAge;
+    }
+
+    /**
+     * m
+     * Resets the histogram width
+     */
+    void resetHistWidth() {
+        mHistWidth = 1;
+    }
+
+    /**
+     * Sets the histogram width
+     *
+     * @param histWidth the width in hours
+     */
+    void setHistWidth(long histWidth) {
+        mHistWidth = histWidth;
+    }
+
+    long getHistWidth() {
+        return mHistWidth;
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventDisplayOptions.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventDisplayOptions.java
new file mode 100644
index 0000000..88c3cb2
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventDisplayOptions.java
@@ -0,0 +1,955 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.log.event;
+
+import com.android.ddmlib.log.EventContainer;
+import com.android.ddmlib.log.EventLogParser;
+import com.android.ddmlib.log.EventValueDescription;
+import com.android.ddmuilib.DdmUiPreferences;
+import com.android.ddmuilib.IImageLoader;
+import com.android.ddmuilib.log.event.EventDisplay.OccurrenceDisplayDescriptor;
+import com.android.ddmuilib.log.event.EventDisplay.ValueDisplayDescriptor;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+
+class EventDisplayOptions  extends Dialog {
+    private static final int DLG_WIDTH = 700;
+    private static final int DLG_HEIGHT = 700;
+    
+    private IImageLoader mImageLoader;
+
+    private Shell mParent;
+    private Shell mShell;
+    
+    private boolean mEditStatus = false;
+    private final ArrayList<EventDisplay> mDisplayList = new ArrayList<EventDisplay>();
+
+    /* LEFT LIST */
+    private List mEventDisplayList;
+    private Button mEventDisplayNewButton;
+    private Button mEventDisplayDeleteButton;
+    private Button mEventDisplayUpButton;
+    private Button mEventDisplayDownButton;
+    private Text mDisplayWidthText;
+    private Text mDisplayHeightText;
+
+    /* WIDGETS ON THE RIGHT */
+    private Text mDisplayNameText;
+    private Combo mDisplayTypeCombo;
+    private Group mChartOptions;
+    private Group mHistOptions;
+    private Button mPidFilterCheckBox;
+    private Text mPidText;
+
+    /** Map with (event-tag, event name) */
+    private Map<Integer, String> mEventTagMap;
+
+    /** Map with (event-tag, array of value info for the event) */
+    private Map<Integer, EventValueDescription[]> mEventDescriptionMap;
+
+    /** list of current pids */
+    private ArrayList<Integer> mPidList;
+
+    private EventLogParser mLogParser;
+
+    private Group mInfoGroup;
+
+    private static class SelectionWidgets {
+        private List mList;
+        private Button mNewButton;
+        private Button mEditButton;
+        private Button mDeleteButton;
+        
+        private void setEnabled(boolean enable) {
+            mList.setEnabled(enable);
+            mNewButton.setEnabled(enable);
+            mEditButton.setEnabled(enable);
+            mDeleteButton.setEnabled(enable);
+        }
+    }
+    
+    private SelectionWidgets mValueSelection;
+    private SelectionWidgets mOccurrenceSelection;
+    
+    /** flag to temporarly disable processing of {@link Text} changes, so that 
+     * {@link Text#setText(String)} can be called safely. */
+    private boolean mProcessTextChanges = true;
+    private Text mTimeLimitText;
+    private Text mHistWidthText;
+
+    EventDisplayOptions(IImageLoader imageLoader, Shell parent) {
+        super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
+        mImageLoader = imageLoader;
+    }
+
+    /**
+     * Opens the display option dialog, to edit the {@link EventDisplay} objects provided in the
+     * list.
+     * @param logParser
+     * @param displayList
+     * @param eventList
+     * @return true if the list of {@link EventDisplay} objects was updated.
+     */
+    boolean open(EventLogParser logParser, ArrayList<EventDisplay> displayList,
+            ArrayList<EventContainer> eventList) {
+        mLogParser = logParser;
+
+        if (logParser != null) {
+            // we need 2 things from the parser.
+            // the event tag / event name map
+            mEventTagMap = logParser.getTagMap();
+            
+            // the event info map
+            mEventDescriptionMap = logParser.getEventInfoMap();
+        }
+
+        // make a copy of the EventDisplay list since we'll use working copies.
+        duplicateEventDisplay(displayList);
+        
+        // build a list of pid from the list of events.
+        buildPidList(eventList);
+
+        createUI();
+
+        if (mParent == null || mShell == null) {
+            return false;
+        }
+
+        // Set the dialog size.
+        mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
+        Rectangle r = mParent.getBounds();
+        // get the center new top left.
+        int cx = r.x + r.width/2;
+        int x = cx - DLG_WIDTH / 2;
+        int cy = r.y + r.height/2;
+        int y = cy - DLG_HEIGHT / 2;
+        mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
+
+        mShell.layout();
+
+        // actually open the dialog
+        mShell.open();
+
+        // event loop until the dialog is closed.
+        Display display = mParent.getDisplay();
+        while (!mShell.isDisposed()) {
+            if (!display.readAndDispatch())
+                display.sleep();
+        }
+        
+        return mEditStatus;
+    }
+    
+    ArrayList<EventDisplay> getEventDisplays() {
+        return mDisplayList;
+    }
+    
+    private void createUI() {
+        mParent = getParent();
+        mShell = new Shell(mParent, getStyle());
+        mShell.setText("Event Display Configuration");
+
+        mShell.setLayout(new GridLayout(1, true));
+
+        final Composite topPanel = new Composite(mShell, SWT.NONE);
+        topPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
+        topPanel.setLayout(new GridLayout(2, false));
+        
+        // create the tree on the left and the controls on the right.
+        Composite leftPanel = new Composite(topPanel, SWT.NONE);
+        Composite rightPanel = new Composite(topPanel, SWT.NONE);
+
+        createLeftPanel(leftPanel);
+        createRightPanel(rightPanel);
+
+        mShell.addListener(SWT.Close, new Listener() {
+            public void handleEvent(Event event) {
+                event.doit = true;
+            }
+        });
+        
+        Label separator = new Label(mShell, SWT.SEPARATOR | SWT.HORIZONTAL);
+        separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        
+        Composite bottomButtons = new Composite(mShell, SWT.NONE);
+        bottomButtons.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        GridLayout gl;
+        bottomButtons.setLayout(gl = new GridLayout(2, true));
+        gl.marginHeight = gl.marginWidth = 0;
+        
+        Button okButton = new Button(bottomButtons, SWT.PUSH);
+        okButton.setText("OK");
+        okButton.addSelectionListener(new SelectionAdapter() {
+            /* (non-Javadoc)
+             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+             */
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mShell.close();
+            }
+        });
+
+        Button cancelButton = new Button(bottomButtons, SWT.PUSH);
+        cancelButton.setText("Cancel");
+        cancelButton.addSelectionListener(new SelectionAdapter() {
+            /* (non-Javadoc)
+             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+             */
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // cancel the modification flag.
+                mEditStatus = false;
+                
+                // and close
+                mShell.close();
+            }
+        });
+
+        enable(false);
+        
+        // fill the list with the current display
+        fillEventDisplayList();
+    }
+
+    private void createLeftPanel(Composite leftPanel) {
+        final IPreferenceStore store = DdmUiPreferences.getStore();
+
+        GridLayout gl;
+
+        leftPanel.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+        leftPanel.setLayout(gl = new GridLayout(1, false));
+        gl.verticalSpacing = 1;
+
+        mEventDisplayList = new List(leftPanel,
+                SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL | SWT.FULL_SELECTION);
+        mEventDisplayList.setLayoutData(new GridData(GridData.FILL_BOTH));
+        mEventDisplayList.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                handleEventDisplaySelection();
+            }
+        });
+
+        Composite bottomControls = new Composite(leftPanel, SWT.NONE);
+        bottomControls.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        bottomControls.setLayout(gl = new GridLayout(5, false));
+        gl.marginHeight = gl.marginWidth = 0;
+        gl.verticalSpacing = 0;
+        gl.horizontalSpacing = 0;
+
+        mEventDisplayNewButton = new Button(bottomControls, SWT.PUSH | SWT.FLAT);
+        mEventDisplayNewButton.setImage(mImageLoader.loadImage("add.png", // $NON-NLS-1$
+                leftPanel.getDisplay()));
+        mEventDisplayNewButton.setToolTipText("Adds a new event display");
+        mEventDisplayNewButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
+        mEventDisplayNewButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                createNewEventDisplay();
+            }
+        });
+        
+        mEventDisplayDeleteButton = new Button(bottomControls, SWT.PUSH | SWT.FLAT);
+        mEventDisplayDeleteButton.setImage(mImageLoader.loadImage("delete.png", // $NON-NLS-1$
+                leftPanel.getDisplay()));
+        mEventDisplayDeleteButton.setToolTipText("Deletes the selected event display");
+        mEventDisplayDeleteButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
+        mEventDisplayDeleteButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                deleteEventDisplay();
+            }
+        });
+
+        mEventDisplayUpButton = new Button(bottomControls, SWT.PUSH | SWT.FLAT);
+        mEventDisplayUpButton.setImage(mImageLoader.loadImage("up.png", // $NON-NLS-1$
+                leftPanel.getDisplay()));
+        mEventDisplayUpButton.setToolTipText("Moves the selected event display up");
+        mEventDisplayUpButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // get current selection.
+                int selection = mEventDisplayList.getSelectionIndex();
+                if (selection > 0) {
+                    // update the list of EventDisplay.
+                    EventDisplay display = mDisplayList.remove(selection);
+                    mDisplayList.add(selection - 1, display);
+                    
+                    // update the list widget
+                    mEventDisplayList.remove(selection);
+                    mEventDisplayList.add(display.getName(), selection - 1);
+                    
+                    // update the selection and reset the ui.
+                    mEventDisplayList.select(selection - 1);
+                    handleEventDisplaySelection();
+                    mEventDisplayList.showSelection();
+
+                    setModified();
+                }
+            }
+        });
+
+        mEventDisplayDownButton = new Button(bottomControls, SWT.PUSH | SWT.FLAT);
+        mEventDisplayDownButton.setImage(mImageLoader.loadImage("down.png", // $NON-NLS-1$
+                leftPanel.getDisplay()));
+        mEventDisplayDownButton.setToolTipText("Moves the selected event display down");
+        mEventDisplayDownButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // get current selection.
+                int selection = mEventDisplayList.getSelectionIndex();
+                if (selection != -1 && selection < mEventDisplayList.getItemCount() - 1) {
+                    // update the list of EventDisplay.
+                    EventDisplay display = mDisplayList.remove(selection);
+                    mDisplayList.add(selection + 1, display);
+                    
+                    // update the list widget
+                    mEventDisplayList.remove(selection);
+                    mEventDisplayList.add(display.getName(), selection + 1);
+                    
+                    // update the selection and reset the ui.
+                    mEventDisplayList.select(selection + 1);
+                    handleEventDisplaySelection();
+                    mEventDisplayList.showSelection();
+
+                    setModified();
+                }
+            }
+        });
+        
+        Group sizeGroup = new Group(leftPanel, SWT.NONE);
+        sizeGroup.setText("Display Size:");
+        sizeGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        sizeGroup.setLayout(new GridLayout(2, false));
+
+        Label l = new Label(sizeGroup, SWT.NONE);
+        l.setText("Width:");
+        
+        mDisplayWidthText = new Text(sizeGroup, SWT.LEFT | SWT.SINGLE | SWT.BORDER);
+        mDisplayWidthText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mDisplayWidthText.setText(Integer.toString(
+                store.getInt(EventLogPanel.PREFS_DISPLAY_WIDTH)));
+        mDisplayWidthText.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                String text = mDisplayWidthText.getText().trim();
+                try {
+                    store.setValue(EventLogPanel.PREFS_DISPLAY_WIDTH, Integer.parseInt(text));
+                    setModified();
+                } catch (NumberFormatException nfe) {
+                    // do something?
+                }
+            }
+        });
+
+        l = new Label(sizeGroup, SWT.NONE);
+        l.setText("Height:");
+
+        mDisplayHeightText = new Text(sizeGroup, SWT.LEFT | SWT.SINGLE | SWT.BORDER);
+        mDisplayHeightText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mDisplayHeightText.setText(Integer.toString(
+                store.getInt(EventLogPanel.PREFS_DISPLAY_HEIGHT)));
+        mDisplayHeightText.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                String text = mDisplayHeightText.getText().trim();
+                try {
+                    store.setValue(EventLogPanel.PREFS_DISPLAY_HEIGHT, Integer.parseInt(text));
+                    setModified();
+                } catch (NumberFormatException nfe) {
+                    // do something?
+                }
+            }
+        });
+    }
+
+    private void createRightPanel(Composite rightPanel) {
+        rightPanel.setLayout(new GridLayout(1, true));
+        rightPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        mInfoGroup = new Group(rightPanel, SWT.NONE);
+        mInfoGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mInfoGroup.setLayout(new GridLayout(2, false));
+        
+        Label nameLabel = new Label(mInfoGroup, SWT.LEFT);
+        nameLabel.setText("Name:");
+
+        mDisplayNameText = new Text(mInfoGroup, SWT.BORDER | SWT.LEFT | SWT.SINGLE);
+        mDisplayNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mDisplayNameText.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                if (mProcessTextChanges) {
+                    EventDisplay eventDisplay = getCurrentEventDisplay();
+                    if (eventDisplay != null) {
+                        eventDisplay.setName(mDisplayNameText.getText());
+                        int index = mEventDisplayList.getSelectionIndex();
+                        mEventDisplayList.remove(index);
+                        mEventDisplayList.add(eventDisplay.getName(), index);
+                        mEventDisplayList.select(index);
+                        handleEventDisplaySelection();
+                        setModified();
+                    }
+                }
+            }
+        });
+
+        Label displayLabel = new Label(mInfoGroup, SWT.LEFT);
+        displayLabel.setText("Type:");
+        
+        mDisplayTypeCombo = new Combo(mInfoGroup, SWT.READ_ONLY | SWT.DROP_DOWN);
+        mDisplayTypeCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        // add the combo values. This must match the values EventDisplay.DISPLAY_TYPE_*
+        mDisplayTypeCombo.add("Log All");
+        mDisplayTypeCombo.add("Filtered Log");
+        mDisplayTypeCombo.add("Graph");
+        mDisplayTypeCombo.add("Sync");
+        mDisplayTypeCombo.add("Sync Histogram");
+        mDisplayTypeCombo.add("Sync Performance");
+        mDisplayTypeCombo.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                EventDisplay eventDisplay = getCurrentEventDisplay();
+                if (eventDisplay != null && eventDisplay.getDisplayType() != mDisplayTypeCombo.getSelectionIndex()) {
+                    /* Replace the EventDisplay object with a different subclass */
+                    setModified();
+                    String name = eventDisplay.getName();
+                    EventDisplay newEventDisplay = EventDisplay.eventDisplayFactory(mDisplayTypeCombo.getSelectionIndex(), name);
+                    setCurrentEventDisplay(newEventDisplay);
+                    fillUiWith(newEventDisplay);
+                }
+            }
+        });
+        
+        mChartOptions = new Group(mInfoGroup, SWT.NONE);
+        mChartOptions.setText("Chart Options");
+        GridData gd;
+        mChartOptions.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
+        gd.horizontalSpan = 2;
+        mChartOptions.setLayout(new GridLayout(2, false));
+        
+        Label l = new Label(mChartOptions, SWT.NONE);
+        l.setText("Time Limit (seconds):");
+        
+        mTimeLimitText = new Text(mChartOptions, SWT.BORDER);
+        mTimeLimitText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mTimeLimitText.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent arg0) {
+                String text = mTimeLimitText.getText().trim();
+                EventDisplay eventDisplay = getCurrentEventDisplay();
+                if (eventDisplay != null) {
+                    try {
+                        if (text.length() == 0) {
+                            eventDisplay.resetChartTimeLimit();
+                        } else {
+                            eventDisplay.setChartTimeLimit(Long.parseLong(text));
+                        }
+                    } catch (NumberFormatException nfe) {
+                        eventDisplay.resetChartTimeLimit();
+                    } finally {
+                        setModified();
+                    }
+                }
+            }
+        });
+
+        mHistOptions = new Group(mInfoGroup, SWT.NONE);
+        mHistOptions.setText("Histogram Options");
+        GridData gdh;
+        mHistOptions.setLayoutData(gdh = new GridData(GridData.FILL_HORIZONTAL));
+        gdh.horizontalSpan = 2;
+        mHistOptions.setLayout(new GridLayout(2, false));
+        
+        Label lh = new Label(mHistOptions, SWT.NONE);
+        lh.setText("Histogram width (hours):");
+        
+        mHistWidthText = new Text(mHistOptions, SWT.BORDER);
+        mHistWidthText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mHistWidthText.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent arg0) {
+                String text = mHistWidthText.getText().trim();
+                EventDisplay eventDisplay = getCurrentEventDisplay();
+                if (eventDisplay != null) {
+                    try {
+                        if (text.length() == 0) {
+                            eventDisplay.resetHistWidth();
+                        } else {
+                            eventDisplay.setHistWidth(Long.parseLong(text));
+                        }
+                    } catch (NumberFormatException nfe) {
+                        eventDisplay.resetHistWidth();
+                    } finally {
+                        setModified();
+                    }
+                }
+            }
+        });
+
+        mPidFilterCheckBox = new Button(mInfoGroup, SWT.CHECK);
+        mPidFilterCheckBox.setText("Enable filtering by pid");
+        mPidFilterCheckBox.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
+        gd.horizontalSpan = 2;
+        mPidFilterCheckBox.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                EventDisplay eventDisplay = getCurrentEventDisplay();
+                if (eventDisplay != null) {
+                    eventDisplay.setPidFiltering(mPidFilterCheckBox.getSelection());
+                    mPidText.setEnabled(mPidFilterCheckBox.getSelection());
+                    setModified();
+                }
+            }
+        });
+
+        Label pidLabel = new Label(mInfoGroup, SWT.NONE);
+        pidLabel.setText("Pid Filter:");
+        pidLabel.setToolTipText("Enter all pids, separated by commas");
+        
+        mPidText = new Text(mInfoGroup, SWT.BORDER);
+        mPidText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mPidText.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                if (mProcessTextChanges) {
+                    EventDisplay eventDisplay = getCurrentEventDisplay();
+                    if (eventDisplay != null && eventDisplay.getPidFiltering()) {
+                        String pidText = mPidText.getText().trim();
+                        String[] pids = pidText.split("\\s*,\\s*"); //$NON-NLS-1$
+    
+                        ArrayList<Integer> list = new ArrayList<Integer>();
+                        for (String pid : pids) {
+                            try {
+                                list.add(Integer.valueOf(pid));
+                            } catch (NumberFormatException nfe) {
+                                // just ignore non valid pid
+                            }
+                        }
+                        
+                        eventDisplay.setPidFilterList(list);
+                        setModified();
+                    }
+                }
+            }
+        });
+        
+        /* ------------------
+         * EVENT VALUE/OCCURRENCE SELECTION
+         * ------------------ */
+        mValueSelection = createEventSelection(rightPanel, ValueDisplayDescriptor.class,
+                "Event Value Display");
+        mOccurrenceSelection = createEventSelection(rightPanel, OccurrenceDisplayDescriptor.class,
+                "Event Occurrence Display");
+    }
+
+    private SelectionWidgets createEventSelection(Composite rightPanel,
+            final Class<? extends OccurrenceDisplayDescriptor> descriptorClass,
+            String groupMessage) {
+
+        Group eventSelectionPanel = new Group(rightPanel, SWT.NONE);
+        eventSelectionPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
+        GridLayout gl;
+        eventSelectionPanel.setLayout(gl = new GridLayout(2, false));
+        gl.marginHeight = gl.marginWidth = 0;
+        eventSelectionPanel.setText(groupMessage);
+        
+        final SelectionWidgets widgets = new SelectionWidgets();
+        
+        widgets.mList = new List(eventSelectionPanel, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL);
+        widgets.mList.setLayoutData(new GridData(GridData.FILL_BOTH));
+        widgets.mList.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                int index = widgets.mList.getSelectionIndex();
+                if (index != -1) {
+                    widgets.mDeleteButton.setEnabled(true);
+                    widgets.mEditButton.setEnabled(true);
+                } else {
+                    widgets.mDeleteButton.setEnabled(false);
+                    widgets.mEditButton.setEnabled(false);
+                }
+            }
+        });
+
+        Composite rightControls = new Composite(eventSelectionPanel, SWT.NONE);
+        rightControls.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+        rightControls.setLayout(gl = new GridLayout(1, false));
+        gl.marginHeight = gl.marginWidth = 0;
+        gl.verticalSpacing = 0;
+        gl.horizontalSpacing = 0;
+
+        widgets.mNewButton = new Button(rightControls, SWT.PUSH | SWT.FLAT);
+        widgets.mNewButton.setText("New...");
+        widgets.mNewButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        widgets.mNewButton.setEnabled(false);
+        widgets.mNewButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // current event
+                try {
+                    EventDisplay eventDisplay = getCurrentEventDisplay();
+                    if (eventDisplay != null) {
+                        EventValueSelector dialog = new EventValueSelector(mShell);
+                        if (dialog.open(descriptorClass, mLogParser)) {
+                            eventDisplay.addDescriptor(dialog.getDescriptor());
+                            fillUiWith(eventDisplay);
+                            setModified();
+                        }
+                    }
+                } catch (Exception e1) {
+                    e1.printStackTrace();
+                }
+            }
+        });
+
+        widgets.mEditButton = new Button(rightControls, SWT.PUSH | SWT.FLAT);
+        widgets.mEditButton.setText("Edit...");
+        widgets.mEditButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        widgets.mEditButton.setEnabled(false);
+        widgets.mEditButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // current event
+                EventDisplay eventDisplay = getCurrentEventDisplay();
+                if (eventDisplay != null) {
+                    // get the current descriptor index
+                    int index = widgets.mList.getSelectionIndex();
+                    if (index != -1) {
+                        // get the descriptor itself
+                        OccurrenceDisplayDescriptor descriptor = eventDisplay.getDescriptor(
+                                descriptorClass, index);
+    
+                        // open the edit dialog.
+                        EventValueSelector dialog = new EventValueSelector(mShell);
+                        if (dialog.open(descriptor, mLogParser)) {
+                            descriptor.replaceWith(dialog.getDescriptor());
+                            eventDisplay.updateValueDescriptorCheck();
+                            fillUiWith(eventDisplay);
+
+                            // reselect the item since fillUiWith remove the selection.
+                            widgets.mList.select(index);
+                            widgets.mList.notifyListeners(SWT.Selection, null);
+                            
+                            setModified();
+                        }
+                    }
+                }
+            }
+        });
+
+        widgets.mDeleteButton = new Button(rightControls, SWT.PUSH | SWT.FLAT);
+        widgets.mDeleteButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        widgets.mDeleteButton.setText("Delete");
+        widgets.mDeleteButton.setEnabled(false);
+        widgets.mDeleteButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // current event
+                EventDisplay eventDisplay = getCurrentEventDisplay();
+                if (eventDisplay != null) {
+                    // get the current descriptor index
+                    int index = widgets.mList.getSelectionIndex();
+                    if (index != -1) {
+                        eventDisplay.removeDescriptor(descriptorClass, index);
+                        fillUiWith(eventDisplay);
+                        setModified();
+                    }
+                }
+            }
+        });
+
+        return widgets;
+    }
+   
+    
+    private void duplicateEventDisplay(ArrayList<EventDisplay> displayList) {
+        for (EventDisplay eventDisplay : displayList) {
+            mDisplayList.add(EventDisplay.clone(eventDisplay));
+        }
+    }
+    
+    private void buildPidList(ArrayList<EventContainer> eventList) {
+        mPidList = new ArrayList<Integer>();
+        for (EventContainer event : eventList) {
+            if (mPidList.indexOf(event.pid) == -1) {
+                mPidList.add(event.pid);
+            }
+        }
+    }
+
+    private void setModified() {
+        mEditStatus = true;
+    }
+
+    
+    private void enable(boolean status) {
+        mEventDisplayDeleteButton.setEnabled(status);
+
+        // enable up/down
+        int selection = mEventDisplayList.getSelectionIndex();
+        int count = mEventDisplayList.getItemCount();
+        mEventDisplayUpButton.setEnabled(status && selection > 0);
+        mEventDisplayDownButton.setEnabled(status && selection != -1 && selection < count - 1);
+
+        mDisplayNameText.setEnabled(status);
+        mDisplayTypeCombo.setEnabled(status);
+        mPidFilterCheckBox.setEnabled(status);
+
+        mValueSelection.setEnabled(status);
+        mOccurrenceSelection.setEnabled(status);
+        mValueSelection.mNewButton.setEnabled(status);
+        mOccurrenceSelection.mNewButton.setEnabled(status);
+        if (status == false) {
+            mPidText.setEnabled(false);
+        }
+    }
+    
+    private void fillEventDisplayList() {
+        for (EventDisplay eventDisplay : mDisplayList) {
+            mEventDisplayList.add(eventDisplay.getName());
+        }
+    }
+    
+    private void createNewEventDisplay() {
+        int count = mDisplayList.size();
+        
+        String name = String.format("display %1$d", count + 1);
+        
+        EventDisplay eventDisplay = EventDisplay.eventDisplayFactory(0 /* type*/, name);
+        
+        mDisplayList.add(eventDisplay);
+        mEventDisplayList.add(name);
+        
+        mEventDisplayList.select(count);
+        handleEventDisplaySelection();
+        mEventDisplayList.showSelection();
+        
+        setModified();
+    }
+    
+    private void deleteEventDisplay() {
+        int selection = mEventDisplayList.getSelectionIndex();
+        if (selection != -1) {
+            mDisplayList.remove(selection);
+            mEventDisplayList.remove(selection);
+            if (mDisplayList.size() < selection) {
+                selection--;
+            }
+            mEventDisplayList.select(selection);
+            handleEventDisplaySelection();
+
+            setModified();
+        }
+    }
+
+    private EventDisplay getCurrentEventDisplay() {
+        int selection = mEventDisplayList.getSelectionIndex();
+        if (selection != -1) {
+            return mDisplayList.get(selection);
+        }
+        
+        return null;
+    }
+
+    private void setCurrentEventDisplay(EventDisplay eventDisplay) {
+        int selection = mEventDisplayList.getSelectionIndex();
+        if (selection != -1) {
+            mDisplayList.set(selection, eventDisplay);
+        }
+    }
+    
+    private void handleEventDisplaySelection() {
+        EventDisplay eventDisplay = getCurrentEventDisplay();
+        if (eventDisplay != null) {
+            // enable the UI
+            enable(true);
+
+            // and fill it
+            fillUiWith(eventDisplay);
+        } else {
+            // disable the UI
+            enable(false);
+
+            // and empty it.
+            emptyUi();
+        }
+    }
+
+    private void emptyUi() {
+        mDisplayNameText.setText("");
+        mDisplayTypeCombo.clearSelection();
+        mValueSelection.mList.removeAll();
+        mOccurrenceSelection.mList.removeAll();
+    }
+
+    private void fillUiWith(EventDisplay eventDisplay) {
+        mProcessTextChanges = false;
+
+        mDisplayNameText.setText(eventDisplay.getName());
+        int displayMode = eventDisplay.getDisplayType();
+        mDisplayTypeCombo.select(displayMode);
+        if (displayMode == EventDisplay.DISPLAY_TYPE_GRAPH) {
+            GridData gd = (GridData) mChartOptions.getLayoutData();
+            gd.exclude = false;
+            mChartOptions.setVisible(!gd.exclude);
+            long limit = eventDisplay.getChartTimeLimit();
+            if (limit != -1) {
+                mTimeLimitText.setText(Long.toString(limit));
+            } else {
+                mTimeLimitText.setText(""); //$NON-NLS-1$
+            }
+        } else {
+            GridData gd = (GridData) mChartOptions.getLayoutData();
+            gd.exclude = true;
+            mChartOptions.setVisible(!gd.exclude);
+            mTimeLimitText.setText(""); //$NON-NLS-1$
+        }
+
+        if (displayMode == EventDisplay.DISPLAY_TYPE_SYNC_HIST) {
+            GridData gd = (GridData) mHistOptions.getLayoutData();
+            gd.exclude = false;
+            mHistOptions.setVisible(!gd.exclude);
+            long limit = eventDisplay.getHistWidth();
+            if (limit != -1) {
+                mHistWidthText.setText(Long.toString(limit));
+            } else {
+                mHistWidthText.setText(""); //$NON-NLS-1$
+            }
+        } else {
+            GridData gd = (GridData) mHistOptions.getLayoutData();
+            gd.exclude = true;
+            mHistOptions.setVisible(!gd.exclude);
+            mHistWidthText.setText(""); //$NON-NLS-1$
+        }
+        mInfoGroup.layout(true);
+        mShell.layout(true);
+        mShell.pack();
+        
+        if (eventDisplay.getPidFiltering()) {
+            mPidFilterCheckBox.setSelection(true);
+            mPidText.setEnabled(true);
+
+            // build the pid list.
+            ArrayList<Integer> list = eventDisplay.getPidFilterList();
+            if (list != null) {
+                StringBuilder sb = new StringBuilder();
+                int count = list.size();
+                for (int i = 0 ; i < count ; i++) {
+                    sb.append(list.get(i));
+                    if (i < count - 1) {
+                        sb.append(", ");//$NON-NLS-1$
+                    }
+                }
+                mPidText.setText(sb.toString());
+            } else {
+                mPidText.setText(""); //$NON-NLS-1$
+            }
+        } else {
+            mPidFilterCheckBox.setSelection(false);
+            mPidText.setEnabled(false);
+            mPidText.setText(""); //$NON-NLS-1$
+        }
+
+        mProcessTextChanges = true;
+
+        mValueSelection.mList.removeAll();
+        mOccurrenceSelection.mList.removeAll();
+        
+        if (eventDisplay.getDisplayType() == EventDisplay.DISPLAY_TYPE_FILTERED_LOG ||
+                eventDisplay.getDisplayType() == EventDisplay.DISPLAY_TYPE_GRAPH) {
+            mOccurrenceSelection.setEnabled(true);
+            mValueSelection.setEnabled(true);
+
+            Iterator<ValueDisplayDescriptor> valueIterator = eventDisplay.getValueDescriptors();
+    
+            while (valueIterator.hasNext()) {
+                ValueDisplayDescriptor descriptor = valueIterator.next();
+                mValueSelection.mList.add(String.format("%1$s: %2$s [%3$s]%4$s",
+                        mEventTagMap.get(descriptor.eventTag), descriptor.valueName,
+                        getSeriesLabelDescription(descriptor), getFilterDescription(descriptor)));
+            }
+
+            Iterator<OccurrenceDisplayDescriptor> occurrenceIterator =
+                eventDisplay.getOccurrenceDescriptors();
+    
+            while (occurrenceIterator.hasNext()) {
+                OccurrenceDisplayDescriptor descriptor = occurrenceIterator.next();
+    
+                mOccurrenceSelection.mList.add(String.format("%1$s [%2$s]%3$s",
+                        mEventTagMap.get(descriptor.eventTag),
+                        getSeriesLabelDescription(descriptor),
+                        getFilterDescription(descriptor)));
+            }
+
+            mValueSelection.mList.notifyListeners(SWT.Selection, null);
+            mOccurrenceSelection.mList.notifyListeners(SWT.Selection, null);
+        } else {
+            mOccurrenceSelection.setEnabled(false);
+            mValueSelection.setEnabled(false);
+        }
+        
+    }
+    
+    /**
+     * Returns a String describing what is used as the series label
+     * @param descriptor the descriptor of the display.
+     */
+    private String getSeriesLabelDescription(OccurrenceDisplayDescriptor descriptor) {
+        if (descriptor.seriesValueIndex != -1) {
+            if (descriptor.includePid) {
+                return String.format("%1$s + pid",
+                        mEventDescriptionMap.get(
+                                descriptor.eventTag)[descriptor.seriesValueIndex].getName());
+            } else {
+                return mEventDescriptionMap.get(descriptor.eventTag)[descriptor.seriesValueIndex]
+                                                                     .getName();
+            }
+        }
+        return "pid";
+    }
+    
+    private String getFilterDescription(OccurrenceDisplayDescriptor descriptor) {
+        if (descriptor.filterValueIndex != -1) {
+            return String.format(" [%1$s %2$s %3$s]",
+                    mEventDescriptionMap.get(
+                            descriptor.eventTag)[descriptor.filterValueIndex].getName(),
+                            descriptor.filterCompareMethod.testString(),
+                            descriptor.filterValue != null ?
+                                    descriptor.filterValue.toString() : "?"); //$NON-NLS-1$
+        }
+        return ""; //$NON-NLS-1$
+    }
+
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventLogImporter.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventLogImporter.java
new file mode 100644
index 0000000..a1303f6
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventLogImporter.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.log.event;
+
+import com.android.ddmlib.Log;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+
+/**
+ * Imports a textual event log.  Gets tags from build path.
+ */
+public class EventLogImporter {
+
+    private String[] mTags;
+    private String[] mLog;
+
+    public EventLogImporter(String filePath) throws FileNotFoundException {
+        String top = System.getenv("ANDROID_BUILD_TOP");
+        if (top == null) {
+            throw new FileNotFoundException();
+        }
+        final String tagFile = top + "/system/core/logcat/event-log-tags";
+        BufferedReader tagReader = new BufferedReader(
+                new InputStreamReader(new FileInputStream(tagFile)));
+        BufferedReader eventReader = new BufferedReader(
+                new InputStreamReader(new FileInputStream(filePath)));
+        try {
+            readTags(tagReader);
+            readLog(eventReader);
+        } catch (IOException e) {
+        }
+    }
+
+    public String[] getTags() {
+        return mTags;
+    }
+
+    public String[] getLog() {
+        return mLog;
+    }
+
+    private void readTags(BufferedReader reader) throws IOException {
+        String line;
+
+        ArrayList<String> content = new ArrayList<String>();
+        while ((line = reader.readLine()) != null) {
+            content.add(line);
+        }
+        mTags = content.toArray(new String[content.size()]);
+    }
+
+    private void readLog(BufferedReader reader) throws IOException {
+        String line;
+
+        ArrayList<String> content = new ArrayList<String>();
+        while ((line = reader.readLine()) != null) {
+            content.add(line);
+        }
+
+        mLog = content.toArray(new String[content.size()]);
+    }
+
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventLogPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventLogPanel.java
new file mode 100644
index 0000000..2621c6a
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventLogPanel.java
@@ -0,0 +1,926 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.log.event;
+
+import com.android.ddmlib.Client;
+import com.android.ddmlib.Device;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmlib.log.EventContainer;
+import com.android.ddmlib.log.EventLogParser;
+import com.android.ddmlib.log.LogReceiver;
+import com.android.ddmlib.log.LogReceiver.ILogListener;
+import com.android.ddmlib.log.LogReceiver.LogEntry;
+import com.android.ddmuilib.DdmUiPreferences;
+import com.android.ddmuilib.IImageLoader;
+import com.android.ddmuilib.TablePanel;
+import com.android.ddmuilib.actions.ICommonAction;
+import com.android.ddmuilib.annotation.UiThread;
+import com.android.ddmuilib.annotation.WorkerThread;
+import com.android.ddmuilib.log.event.EventDisplay.ILogColumnListener;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.RowData;
+import org.eclipse.swt.layout.RowLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.regex.Pattern;
+
+/**
+ * Event log viewer
+ */
+public class EventLogPanel extends TablePanel implements ILogListener,
+        ILogColumnListener {
+
+    private final static String TAG_FILE_EXT = ".tag"; //$NON-NLS-1$
+
+    private final static String PREFS_EVENT_DISPLAY = "EventLogPanel.eventDisplay"; //$NON-NLS-1$
+    private final static String EVENT_DISPLAY_STORAGE_SEPARATOR = "|"; //$NON-NLS-1$
+
+    static final String PREFS_DISPLAY_WIDTH = "EventLogPanel.width"; //$NON-NLS-1$
+    static final String PREFS_DISPLAY_HEIGHT = "EventLogPanel.height"; //$NON-NLS-1$
+
+    private final static int DEFAULT_DISPLAY_WIDTH = 500;
+    private final static int DEFAULT_DISPLAY_HEIGHT = 400;
+
+    private IImageLoader mImageLoader;
+
+    private Device mCurrentLoggedDevice;
+    private String mCurrentLogFile;
+    private LogReceiver mCurrentLogReceiver;
+    private EventLogParser mCurrentEventLogParser;
+
+    private Object mLock = new Object();
+
+    /** list of all the events. */
+    private final ArrayList<EventContainer> mEvents = new ArrayList<EventContainer>();
+
+    /** list of all the new events, that have yet to be displayed by the ui */
+    private final ArrayList<EventContainer> mNewEvents = new ArrayList<EventContainer>();
+    /** indicates a pending ui thread display */
+    private boolean mPendingDisplay = false;
+    
+    /** list of all the custom event displays */
+    private final ArrayList<EventDisplay> mEventDisplays = new ArrayList<EventDisplay>();
+
+    private final NumberFormat mFormatter = NumberFormat.getInstance();
+    private Composite mParent;
+    private ScrolledComposite mBottomParentPanel;
+    private Composite mBottomPanel;
+    private ICommonAction mOptionsAction;
+    private ICommonAction mClearAction;
+    private ICommonAction mSaveAction;
+    private ICommonAction mLoadAction;
+    private ICommonAction mImportAction;
+    
+    /** file containing the current log raw data. */
+    private File mTempFile = null;
+
+    public EventLogPanel(IImageLoader imageLoader) {
+        super();
+        mImageLoader = imageLoader;
+        mFormatter.setGroupingUsed(true);
+    }
+
+    /**
+     * Sets the external actions.
+     * <p/>This method sets up the {@link ICommonAction} objects to execute the proper code
+     * when triggered by using {@link ICommonAction#setRunnable(Runnable)}.
+     * <p/>It will also make sure they are enabled only when possible.
+     * @param optionsAction
+     * @param clearAction
+     * @param saveAction
+     * @param loadAction
+     * @param importAction
+     */
+    public void setActions(ICommonAction optionsAction, ICommonAction clearAction,
+            ICommonAction saveAction, ICommonAction loadAction, ICommonAction importAction) {
+        mOptionsAction = optionsAction;
+        mOptionsAction.setRunnable(new Runnable() {
+            public void run() {
+                openOptionPanel();
+            }
+        });
+
+        mClearAction = clearAction;
+        mClearAction.setRunnable(new Runnable() {
+            public void run() {
+                clearLog();
+            }
+        });
+
+        mSaveAction = saveAction;
+        mSaveAction.setRunnable(new Runnable() {
+            public void run() {
+                try {
+                    FileDialog fileDialog = new FileDialog(mParent.getShell(), SWT.SAVE);
+
+                    fileDialog.setText("Save Event Log");
+                    fileDialog.setFileName("event.log");
+
+                    String fileName = fileDialog.open();
+                    if (fileName != null) {
+                        saveLog(fileName);
+                    }
+                } catch (IOException e1) {
+                }
+            }
+        });
+
+        mLoadAction = loadAction;
+        mLoadAction.setRunnable(new Runnable() {
+            public void run() {
+                FileDialog fileDialog = new FileDialog(mParent.getShell(), SWT.OPEN);
+
+                fileDialog.setText("Load Event Log");
+
+                String fileName = fileDialog.open();
+                if (fileName != null) {
+                    loadLog(fileName);
+                }
+            }
+        });
+
+        mImportAction = importAction;
+        mImportAction.setRunnable(new Runnable() {
+            public void run() {
+                FileDialog fileDialog = new FileDialog(mParent.getShell(), SWT.OPEN);
+
+                fileDialog.setText("Import Bug Report");
+
+                String fileName = fileDialog.open();
+                if (fileName != null) {
+                    importBugReport(fileName);
+                }
+            }
+        });
+
+        mOptionsAction.setEnabled(false);
+        mClearAction.setEnabled(false);
+        mSaveAction.setEnabled(false);
+    }
+
+    /**
+     * Opens the option panel.
+     * </p>
+     * <b>This must be called from the UI thread</b>
+     */
+    @UiThread
+    public void openOptionPanel() {
+        try {
+            EventDisplayOptions dialog = new EventDisplayOptions(mImageLoader, mParent.getShell());
+            if (dialog.open(mCurrentEventLogParser, mEventDisplays, mEvents)) {
+                synchronized (mLock) {
+                    // get the new EventDisplay list
+                    mEventDisplays.clear();
+                    mEventDisplays.addAll(dialog.getEventDisplays());
+                    
+                    // since the list of EventDisplay changed, we store it.
+                    saveEventDisplays();
+                    
+                    rebuildUi();
+                }
+            }
+        } catch (SWTException e) {
+            Log.e("EventLog", e); //$NON-NLS-1$
+        }
+    }
+    
+    /**
+     * Clears the log.
+     * <p/>
+     * <b>This must be called from the UI thread</b>
+     */
+    public void clearLog() {
+        try {
+            synchronized (mLock) {
+                mEvents.clear();
+                mNewEvents.clear();
+                mPendingDisplay = false;
+                for (EventDisplay eventDisplay : mEventDisplays) {
+                    eventDisplay.resetUI();
+                }
+            }
+        } catch (SWTException e) {
+            Log.e("EventLog", e); //$NON-NLS-1$
+        }
+    }
+    
+    /**
+     * Saves the content of the event log into a file. The log is saved in the same
+     * binary format than on the device.
+     * @param filePath
+     * @throws IOException
+     */
+    public void saveLog(String filePath) throws IOException {
+        if (mCurrentLoggedDevice != null && mCurrentEventLogParser != null) {
+            File destFile = new File(filePath);
+            destFile.createNewFile();
+            FileInputStream fis = new FileInputStream(mTempFile);
+            FileOutputStream fos = new FileOutputStream(destFile);
+            byte[] buffer = new byte[1024];
+            
+            int count;
+            
+            while ((count = fis.read(buffer)) != -1) {
+                fos.write(buffer, 0, count);
+            }
+            
+            fos.close();
+            fis.close();
+            
+            // now we save the tag file
+            filePath = filePath + TAG_FILE_EXT;
+            mCurrentEventLogParser.saveTags(filePath);
+        }
+    }
+
+    /**
+     * Loads a binary event log (if has associated .tag file) or
+     * otherwise loads a textual event log.
+     * @param filePath Event log path (and base of potential tag file)
+     */
+    public void loadLog(String filePath) {
+        if ((new File(filePath + TAG_FILE_EXT)).exists()) {
+            startEventLogFromFiles(filePath);
+        } else {
+            try {
+                EventLogImporter importer = new EventLogImporter(filePath);
+                String[] tags = importer.getTags();
+                String[] log = importer.getLog();
+                startEventLogFromContent(tags, log);
+            } catch (FileNotFoundException e) {
+                // If this fails, display the error message from startEventLogFromFiles,
+                // and pretend we never tried EventLogImporter
+                Log.logAndDisplay(Log.LogLevel.ERROR, "EventLog",
+                        String.format("Failure to read %1$s", filePath + TAG_FILE_EXT));
+            }
+
+        }
+    }
+    
+    public void importBugReport(String filePath) {
+        try {
+            BugReportImporter importer = new BugReportImporter(filePath);
+            
+            String[] tags = importer.getTags();
+            String[] log = importer.getLog();
+            
+            startEventLogFromContent(tags, log);
+            
+        } catch (FileNotFoundException e) {
+            Log.logAndDisplay(LogLevel.ERROR, "Import",
+                    "Unable to import bug report: " + e.getMessage());
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see com.android.ddmuilib.SelectionDependentPanel#clientSelected()
+     */
+    @Override
+    public void clientSelected() {
+        // pass
+    }
+
+    /* (non-Javadoc)
+     * @see com.android.ddmuilib.SelectionDependentPanel#deviceSelected()
+     */
+    @Override
+    public void deviceSelected() {
+        startEventLog(getCurrentDevice());
+    }
+    
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.AndroidDebugBridge.IClientChangeListener#clientChanged(com.android.ddmlib.Client, int)
+     */
+    public void clientChanged(Client client, int changeMask) {
+        // pass
+    }
+
+    /* (non-Javadoc)
+     * @see com.android.ddmuilib.Panel#createControl(org.eclipse.swt.widgets.Composite)
+     */
+    @Override
+    protected Control createControl(Composite parent) {
+        mParent = parent;
+        mParent.addDisposeListener(new DisposeListener() {
+            public void widgetDisposed(DisposeEvent e) {
+                synchronized (mLock) {
+                    if (mCurrentLogReceiver != null) {
+                        mCurrentLogReceiver.cancel();
+                        mCurrentLogReceiver = null;
+                        mCurrentEventLogParser = null;
+                        mCurrentLoggedDevice = null;
+                        mEventDisplays.clear();
+                        mEvents.clear();
+                    }
+                }
+            }
+        });
+
+        final IPreferenceStore store = DdmUiPreferences.getStore();
+
+        // init some store stuff
+        store.setDefault(PREFS_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH);
+        store.setDefault(PREFS_DISPLAY_HEIGHT, DEFAULT_DISPLAY_HEIGHT);
+        
+        mBottomParentPanel = new ScrolledComposite(parent, SWT.V_SCROLL);
+        mBottomParentPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
+        mBottomParentPanel.setExpandHorizontal(true);
+        mBottomParentPanel.setExpandVertical(true);
+
+        mBottomParentPanel.addControlListener(new ControlAdapter() {
+            @Override
+            public void controlResized(ControlEvent e) {
+                if (mBottomPanel != null) {
+                    Rectangle r = mBottomParentPanel.getClientArea();
+                    mBottomParentPanel.setMinSize(mBottomPanel.computeSize(r.width,
+                        SWT.DEFAULT));
+                }
+            }
+        });
+
+        prepareDisplayUi();
+
+        // load the EventDisplay from storage.
+        loadEventDisplays();
+
+        // create the ui
+        createDisplayUi();
+        
+        return mBottomParentPanel;
+    }
+
+    /* (non-Javadoc)
+     * @see com.android.ddmuilib.Panel#postCreation()
+     */
+    @Override
+    protected void postCreation() {
+        // pass
+    }
+
+    /* (non-Javadoc)
+     * @see com.android.ddmuilib.Panel#setFocus()
+     */
+    @Override
+    public void setFocus() {
+        mBottomParentPanel.setFocus();
+    }
+    
+    /**
+     * Starts a new logcat and set mCurrentLogCat as the current receiver.
+     * @param device the device to connect logcat to.
+     */
+    private void startEventLog(final Device device) {
+        if (device == mCurrentLoggedDevice) {
+            return;
+        }
+
+        // if we have a logcat already running
+        if (mCurrentLogReceiver != null) {
+            stopEventLog(false);
+        }
+        mCurrentLoggedDevice = null;
+        mCurrentLogFile = null;
+
+        if (device != null) {
+            // create a new output receiver
+            mCurrentLogReceiver = new LogReceiver(this);
+
+            // start the logcat in a different thread
+            new Thread("EventLog")  { //$NON-NLS-1$
+                @Override
+                public void run() {
+                    while (device.isOnline() == false &&
+                            mCurrentLogReceiver != null &&
+                            mCurrentLogReceiver.isCancelled() == false) {
+                        try {
+                            sleep(2000);
+                        } catch (InterruptedException e) {
+                            return;
+                        }
+                    }
+
+                    if (mCurrentLogReceiver == null || mCurrentLogReceiver.isCancelled()) {
+                        // logcat was stopped/cancelled before the device became ready.
+                        return;
+                    }
+
+                    try {
+                        mCurrentLoggedDevice = device;
+                        synchronized (mLock) {
+                            mCurrentEventLogParser = new EventLogParser();
+                            mCurrentEventLogParser.init(device);
+                        }
+                        
+                        // update the event display with the new parser.
+                        updateEventDisplays();
+                        
+                        // prepare the temp file that will contain the raw data
+                        mTempFile = File.createTempFile("android-event-", ".log");
+
+                        device.runEventLogService(mCurrentLogReceiver);
+                    } catch (Exception e) {
+                        Log.e("EventLog", e);
+                    } finally {
+                    }
+                }
+            }.start();
+        }
+    }
+    
+    private void startEventLogFromFiles(final String fileName) {
+        // if we have a logcat already running
+        if (mCurrentLogReceiver != null) {
+            stopEventLog(false);
+        }
+        mCurrentLoggedDevice = null;
+        mCurrentLogFile = null;
+
+        // create a new output receiver
+        mCurrentLogReceiver = new LogReceiver(this);
+        
+        mSaveAction.setEnabled(false);
+
+        // start the logcat in a different thread
+        new Thread("EventLog")  { //$NON-NLS-1$
+            @Override
+            public void run() {
+                try {
+                    mCurrentLogFile = fileName;
+                    synchronized (mLock) {
+                        mCurrentEventLogParser = new EventLogParser();
+                        if (mCurrentEventLogParser.init(fileName + TAG_FILE_EXT) == false) {
+                            mCurrentEventLogParser = null;
+                            Log.logAndDisplay(LogLevel.ERROR, "EventLog",
+                                    String.format("Failure to read %1$s", fileName + TAG_FILE_EXT));
+                            return;
+                        }
+                    }
+                    
+                    // update the event display with the new parser.
+                    updateEventDisplays();
+                    
+                    runLocalEventLogService(fileName, mCurrentLogReceiver);
+                } catch (Exception e) {
+                    Log.e("EventLog", e);
+                } finally {
+                }
+            }
+        }.start();
+    }
+
+    private void startEventLogFromContent(final String[] tags, final String[] log) {
+        // if we have a logcat already running
+        if (mCurrentLogReceiver != null) {
+            stopEventLog(false);
+        }
+        mCurrentLoggedDevice = null;
+        mCurrentLogFile = null;
+
+        // create a new output receiver
+        mCurrentLogReceiver = new LogReceiver(this);
+        
+        mSaveAction.setEnabled(false);
+
+        // start the logcat in a different thread
+        new Thread("EventLog")  { //$NON-NLS-1$
+            @Override
+            public void run() {
+                try {
+                    synchronized (mLock) {
+                        mCurrentEventLogParser = new EventLogParser();
+                        if (mCurrentEventLogParser.init(tags) == false) {
+                            mCurrentEventLogParser = null;
+                            return;
+                        }
+                    }
+                    
+                    // update the event display with the new parser.
+                    updateEventDisplays();
+                    
+                    runLocalEventLogService(log, mCurrentLogReceiver);
+                } catch (Exception e) {
+                    Log.e("EventLog", e);
+                } finally {
+                }
+            }
+        }.start();
+    }
+
+
+    public void stopEventLog(boolean inUiThread) {
+        if (mCurrentLogReceiver != null) {
+            mCurrentLogReceiver.cancel();
+
+            // when the thread finishes, no one will reference that object
+            // and it'll be destroyed
+            synchronized (mLock) {
+                mCurrentLogReceiver = null;
+                mCurrentEventLogParser = null;
+
+                mCurrentLoggedDevice = null;
+                mEvents.clear();
+                mNewEvents.clear();
+                mPendingDisplay = false;
+            }
+
+            resetUI(inUiThread);
+        }
+        
+        if (mTempFile != null) {
+            mTempFile.delete();
+            mTempFile = null;
+        }
+    }
+
+    private void resetUI(boolean inUiThread) {
+        mEvents.clear();
+
+        // the ui is static we just empty it.
+        if (inUiThread) {
+            resetUiFromUiThread();
+        } else {
+            try {
+                Display d = mBottomParentPanel.getDisplay();
+
+                // run sync as we need to update right now.
+                d.syncExec(new Runnable() {
+                    public void run() {
+                        if (mBottomParentPanel.isDisposed() == false) {
+                            resetUiFromUiThread();
+                        }
+                    }
+                });
+            } catch (SWTException e) {
+                // display is disposed, we're quitting. Do nothing.
+            }
+        }
+    }
+    
+    private void resetUiFromUiThread() {
+        synchronized(mLock) {
+            for (EventDisplay eventDisplay : mEventDisplays) {
+                eventDisplay.resetUI();
+            }
+        }
+        mOptionsAction.setEnabled(false);
+        mClearAction.setEnabled(false);
+        mSaveAction.setEnabled(false);
+    }
+
+    private void prepareDisplayUi() {
+        mBottomPanel = new Composite(mBottomParentPanel, SWT.NONE);
+        mBottomParentPanel.setContent(mBottomPanel);
+    }
+
+    private void createDisplayUi() {
+        RowLayout rowLayout = new RowLayout();
+        rowLayout.wrap = true;
+        rowLayout.pack = false;
+        rowLayout.justify = true;
+        rowLayout.fill = true;
+        rowLayout.type = SWT.HORIZONTAL;
+        mBottomPanel.setLayout(rowLayout);
+        
+        IPreferenceStore store = DdmUiPreferences.getStore();
+        int displayWidth = store.getInt(PREFS_DISPLAY_WIDTH);
+        int displayHeight = store.getInt(PREFS_DISPLAY_HEIGHT);
+        
+        for (EventDisplay eventDisplay : mEventDisplays) {
+            Control c = eventDisplay.createComposite(mBottomPanel, mCurrentEventLogParser, this);
+            if (c != null) {
+                RowData rd = new RowData();
+                rd.height = displayHeight;
+                rd.width = displayWidth;
+                c.setLayoutData(rd);
+            }
+            
+            Table table = eventDisplay.getTable();
+            if (table != null) {
+                addTableToFocusListener(table);
+            }
+        }
+
+        mBottomPanel.layout();
+        mBottomParentPanel.setMinSize(mBottomPanel.computeSize(SWT.DEFAULT, SWT.DEFAULT));
+        mBottomParentPanel.layout();
+    }
+    
+    /**
+     * Rebuild the display ui.
+     */
+    @UiThread
+    private void rebuildUi() {
+        synchronized (mLock) {
+            // we need to rebuild the ui. First we get rid of it.
+            mBottomPanel.dispose();
+            mBottomPanel = null;
+            
+            prepareDisplayUi();
+            createDisplayUi();
+            
+            // and fill it
+            
+            boolean start_event = false;
+            synchronized (mNewEvents) {
+                mNewEvents.addAll(0, mEvents);
+                
+                if (mPendingDisplay == false) {
+                    mPendingDisplay = true;
+                    start_event = true;
+                }
+            }
+            
+            if (start_event) {
+                scheduleUIEventHandler();
+            }
+            
+            Rectangle r = mBottomParentPanel.getClientArea();
+            mBottomParentPanel.setMinSize(mBottomPanel.computeSize(r.width,
+                SWT.DEFAULT));
+        }
+    }
+
+
+    /**
+     * Processes a new {@link LogEntry} by parsing it with {@link EventLogParser} and displaying it.
+     * @param entry The new log entry
+     * @see LogReceiver.ILogListener#newEntry(LogEntry) 
+     */
+    @WorkerThread
+    public void newEntry(LogEntry entry) {
+        synchronized (mLock) {
+            if (mCurrentEventLogParser != null) {
+                EventContainer event = mCurrentEventLogParser.parse(entry);
+                if (event != null) {
+                    handleNewEvent(event);
+                }
+            }
+        }
+    }
+    
+    @WorkerThread
+    private void handleNewEvent(EventContainer event) {
+        // add the event to the generic list
+        mEvents.add(event);
+        
+        // add to the list of events that needs to be displayed, and trigger a
+        // new display if needed.
+        boolean start_event = false;
+        synchronized (mNewEvents) {
+            mNewEvents.add(event);
+            
+            if (mPendingDisplay == false) {
+                mPendingDisplay = true;
+                start_event = true;
+            }
+        }
+        
+        if (start_event == false) {
+            // we're done
+            return;
+        }
+
+        scheduleUIEventHandler();
+    }
+
+    /**
+     * Schedules the UI thread to execute a {@link Runnable} calling {@link #displayNewEvents()}.
+     */
+    private void scheduleUIEventHandler() {
+        try  {
+            Display d = mBottomParentPanel.getDisplay();
+            d.asyncExec(new Runnable() {
+                public void run() {
+                    if (mBottomParentPanel.isDisposed() == false) {
+                        if (mCurrentEventLogParser != null) {
+                            displayNewEvents();
+                        }
+                    }
+                }
+            });
+        } catch (SWTException e) {
+            // if the ui is disposed, do nothing 
+        }
+    }
+
+    /**
+     * Processes raw data coming from the log service.
+     * @see LogReceiver.ILogListener#newData(byte[], int, int)
+     */
+    public void newData(byte[] data, int offset, int length) {
+        if (mTempFile != null) {
+            try {
+                FileOutputStream fos = new FileOutputStream(mTempFile, true /* append */);
+                fos.write(data, offset, length);
+                fos.close();
+            } catch (FileNotFoundException e) {
+            } catch (IOException e) {
+            }
+        }
+    }
+
+    @UiThread
+    private void displayNewEvents() {
+        // never display more than 1,000 events in this loop. We can't do too much in the UI thread.
+        int count = 0;
+
+        // prepare the displays
+        for (EventDisplay eventDisplay : mEventDisplays) {
+            eventDisplay.startMultiEventDisplay();
+        }
+        
+        // display the new events
+        EventContainer event = null;
+        boolean need_to_reloop = false;
+        do {
+            // get the next event to display.
+            synchronized (mNewEvents) {
+                if (mNewEvents.size() > 0) {
+                    if (count > 200) {
+                        // there are still events to be displayed, but we don't want to hog the
+                        // UI thread for too long, so we stop this runnable, but launch a new
+                        // one to keep going.
+                        need_to_reloop = true;
+                        event = null;
+                    } else {
+                        event = mNewEvents.remove(0);
+                        count++;
+                    }
+                } else {
+                    // we're done.
+                    event = null;
+                    mPendingDisplay = false;
+                }
+            }
+
+            if (event != null) {
+                // notify the event display
+                for (EventDisplay eventDisplay : mEventDisplays) {
+                    eventDisplay.newEvent(event, mCurrentEventLogParser);
+                }
+            }
+        } while (event != null);
+
+        // we're done displaying events.
+        for (EventDisplay eventDisplay : mEventDisplays) {
+            eventDisplay.endMultiEventDisplay();
+        }
+        
+        // if needed, ask the UI thread to re-run this method.
+        if (need_to_reloop) {
+            scheduleUIEventHandler();
+        }
+    }
+
+    /**
+     * Loads the {@link EventDisplay}s from the preference store.
+     */
+    private void loadEventDisplays() {
+        IPreferenceStore store = DdmUiPreferences.getStore();
+        String storage = store.getString(PREFS_EVENT_DISPLAY);
+        
+        if (storage.length() > 0) {
+            String[] values = storage.split(Pattern.quote(EVENT_DISPLAY_STORAGE_SEPARATOR));
+            
+            for (String value : values) {
+                EventDisplay eventDisplay = EventDisplay.load(value);
+                if (eventDisplay != null) {
+                    mEventDisplays.add(eventDisplay);
+                }
+            }
+        }
+    }
+
+    /**
+     * Saves the {@link EventDisplay}s into the {@link DdmUiPreferences} store.
+     */
+    private void saveEventDisplays() {
+        IPreferenceStore store = DdmUiPreferences.getStore();
+        
+        boolean first = true;
+        StringBuilder sb = new StringBuilder();
+        
+        for (EventDisplay eventDisplay : mEventDisplays) {
+            String storage = eventDisplay.getStorageString();
+            if (storage != null) {
+                if (first == false) {
+                    sb.append(EVENT_DISPLAY_STORAGE_SEPARATOR);
+                } else {
+                    first = false;
+                }
+                
+                sb.append(storage);
+            }
+        }
+
+        store.setValue(PREFS_EVENT_DISPLAY, sb.toString());
+    }
+
+    /**
+     * Updates the {@link EventDisplay} with the new {@link EventLogParser}.
+     * <p/>
+     * This will run asynchronously in the UI thread.
+     */
+    @WorkerThread
+    private void updateEventDisplays() {
+        try {
+            Display d = mBottomParentPanel.getDisplay();
+
+            d.asyncExec(new Runnable() {
+                public void run() {
+                    if (mBottomParentPanel.isDisposed() == false) {
+                        for (EventDisplay eventDisplay : mEventDisplays) {
+                            eventDisplay.setNewLogParser(mCurrentEventLogParser);
+                        }
+                        
+                        mOptionsAction.setEnabled(true);
+                        mClearAction.setEnabled(true);
+                        if (mCurrentLogFile == null) {
+                            mSaveAction.setEnabled(true);
+                        } else {
+                            mSaveAction.setEnabled(false);
+                        }
+                    }
+                }
+            });
+        } catch (SWTException e) {
+            // display is disposed: do nothing.
+        }
+    }
+
+    @UiThread
+    public void columnResized(int index, TableColumn sourceColumn) {
+        for (EventDisplay eventDisplay : mEventDisplays) {
+            eventDisplay.resizeColumn(index, sourceColumn);
+        }
+    }
+
+    /**
+     * Runs an event log service out of a local file.
+     * @param fileName the full file name of the local file containing the event log.
+     * @param logReceiver the receiver that will handle the log
+     * @throws IOException 
+     */
+    @WorkerThread
+    private void runLocalEventLogService(String fileName, LogReceiver logReceiver)
+            throws IOException {
+        byte[] buffer = new byte[256];
+        
+        FileInputStream fis = new FileInputStream(fileName);
+        
+        int count;
+        while ((count = fis.read(buffer)) != -1) {
+            logReceiver.parseNewData(buffer, 0, count);
+        }
+    }
+    
+    @WorkerThread
+    private void runLocalEventLogService(String[] log, LogReceiver currentLogReceiver) {
+        synchronized (mLock) {
+            for (String line : log) {
+                EventContainer event = mCurrentEventLogParser.parse(line);
+                if (event != null) {
+                    handleNewEvent(event);
+                }
+            }
+        }
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventValueSelector.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventValueSelector.java
new file mode 100644
index 0000000..dd32e2c
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/EventValueSelector.java
@@ -0,0 +1,628 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.log.event;
+
+import com.android.ddmlib.log.EventLogParser;
+import com.android.ddmlib.log.EventValueDescription;
+import com.android.ddmlib.log.EventContainer.CompareMethod;
+import com.android.ddmlib.log.EventContainer.EventValueType;
+import com.android.ddmuilib.log.event.EventDisplay.OccurrenceDisplayDescriptor;
+import com.android.ddmuilib.log.event.EventDisplay.ValueDisplayDescriptor;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Set;
+
+final class EventValueSelector extends Dialog {
+    private static final int DLG_WIDTH = 400;
+    private static final int DLG_HEIGHT = 300;
+
+    private Shell mParent;
+    private Shell mShell;
+    private boolean mEditStatus;
+    private Combo mEventCombo;
+    private Combo mValueCombo;
+    private Combo mSeriesCombo;
+    private Button mDisplayPidCheckBox;
+    private Combo mFilterCombo;
+    private Combo mFilterMethodCombo;
+    private Text mFilterValue;
+    private Button mOkButton;
+
+    private EventLogParser mLogParser;
+    private OccurrenceDisplayDescriptor mDescriptor;
+    
+    /** list of event integer in the order of the combo. */
+    private Integer[] mEventTags;
+    
+    /** list of indices in the {@link EventValueDescription} array of the current event
+     * that are of type string. This lets us get back the {@link EventValueDescription} from the
+     * index in the Series {@link Combo}.
+     */
+    private final ArrayList<Integer> mSeriesIndices = new ArrayList<Integer>();
+    
+    public EventValueSelector(Shell parent) {
+        super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
+    }
+
+    /**
+     * Opens the display option dialog to edit a new descriptor.
+     * @param decriptorClass the class of the object to instantiate. Must extend
+     * {@link OccurrenceDisplayDescriptor}
+     * @param logParser
+     * @return true if the object is to be created, false if the creation was canceled.
+     */
+    boolean open(Class<? extends OccurrenceDisplayDescriptor> descriptorClass,
+            EventLogParser logParser) {
+        try {
+            OccurrenceDisplayDescriptor descriptor = descriptorClass.newInstance();
+            setModified();
+            return open(descriptor, logParser);
+        } catch (InstantiationException e) {
+            return false;
+        } catch (IllegalAccessException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Opens the display option dialog, to edit a {@link OccurrenceDisplayDescriptor} object or
+     * a {@link ValueDisplayDescriptor} object.
+     * @param descriptor The descriptor to edit.
+     * @return true if the object was modified.
+     */
+    boolean open(OccurrenceDisplayDescriptor descriptor, EventLogParser logParser) {
+        // make a copy of the descriptor as we'll use a working copy.
+        if (descriptor instanceof ValueDisplayDescriptor) {
+            mDescriptor = new ValueDisplayDescriptor((ValueDisplayDescriptor)descriptor);
+        } else if (descriptor instanceof OccurrenceDisplayDescriptor) {
+            mDescriptor = new OccurrenceDisplayDescriptor(descriptor);
+        } else {
+            return false;
+        }
+
+        mLogParser = logParser;
+
+        createUI();
+
+        if (mParent == null || mShell == null) {
+            return false;
+        }
+
+        loadValueDescriptor();
+        
+        checkValidity();
+
+        // Set the dialog size.
+        try { 
+            mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
+            Rectangle r = mParent.getBounds();
+            // get the center new top left.
+            int cx = r.x + r.width/2;
+            int x = cx - DLG_WIDTH / 2;
+            int cy = r.y + r.height/2;
+            int y = cy - DLG_HEIGHT / 2;
+            mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        mShell.layout();
+
+        // actually open the dialog
+        mShell.open();
+
+        // event loop until the dialog is closed.
+        Display display = mParent.getDisplay();
+        while (!mShell.isDisposed()) {
+            if (!display.readAndDispatch())
+                display.sleep();
+        }
+        
+        return mEditStatus;
+    }
+    
+    OccurrenceDisplayDescriptor getDescriptor() {
+        return mDescriptor;
+    }
+    
+    private void createUI() {
+        GridData gd;
+
+        mParent = getParent();
+        mShell = new Shell(mParent, getStyle());
+        mShell.setText("Event Display Configuration");
+
+        mShell.setLayout(new GridLayout(2, false));
+        
+        Label l = new Label(mShell, SWT.NONE);
+        l.setText("Event:");
+        
+        mEventCombo = new Combo(mShell, SWT.DROP_DOWN | SWT.READ_ONLY);
+        mEventCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        // the event tag / event name map
+        Map<Integer, String> eventTagMap = mLogParser.getTagMap();
+        Map<Integer, EventValueDescription[]> eventInfoMap = mLogParser.getEventInfoMap();
+        Set<Integer> keys = eventTagMap.keySet();
+        ArrayList<Integer> list = new ArrayList<Integer>();
+        for (Integer i : keys) {
+            if (eventInfoMap.get(i) != null) {
+                String eventName = eventTagMap.get(i);
+                mEventCombo.add(eventName);
+                
+                list.add(i);
+            }
+        }
+        mEventTags = list.toArray(new Integer[list.size()]);
+        
+        mEventCombo.addSelectionListener(new SelectionAdapter() {
+            /* (non-Javadoc)
+             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+             */
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                handleEventComboSelection();
+                setModified();
+            }
+        });
+
+        l = new Label(mShell, SWT.NONE);
+        l.setText("Value:");
+        
+        mValueCombo = new Combo(mShell, SWT.DROP_DOWN | SWT.READ_ONLY);
+        mValueCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mValueCombo.addSelectionListener(new SelectionAdapter() {
+            /* (non-Javadoc)
+             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+             */
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                handleValueComboSelection();
+                setModified();
+            }
+        });
+
+        l = new Label(mShell, SWT.NONE);
+        l.setText("Series Name:");
+
+        mSeriesCombo = new Combo(mShell, SWT.DROP_DOWN | SWT.READ_ONLY);
+        mSeriesCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mSeriesCombo.addSelectionListener(new SelectionAdapter() {
+            /* (non-Javadoc)
+             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+             */
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                handleSeriesComboSelection();
+                setModified();
+            }
+        });
+
+        // empty comp
+        new Composite(mShell, SWT.NONE).setLayoutData(gd = new GridData());
+        gd.heightHint = gd.widthHint = 0;
+
+        mDisplayPidCheckBox = new Button(mShell, SWT.CHECK);
+        mDisplayPidCheckBox.setText("Also Show pid");
+        mDisplayPidCheckBox.setEnabled(false);
+        mDisplayPidCheckBox.addSelectionListener(new SelectionAdapter() {
+            /* (non-Javadoc)
+             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+             */
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mDescriptor.includePid = mDisplayPidCheckBox.getSelection();
+                setModified();
+            }
+        });
+
+        l = new Label(mShell, SWT.NONE);
+        l.setText("Filter By:");
+
+        mFilterCombo = new Combo(mShell, SWT.DROP_DOWN | SWT.READ_ONLY);
+        mFilterCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mFilterCombo.addSelectionListener(new SelectionAdapter() {
+            /* (non-Javadoc)
+             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+             */
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                handleFilterComboSelection();
+                setModified();
+            }
+        });
+
+        l = new Label(mShell, SWT.NONE);
+        l.setText("Filter Method:");
+
+        mFilterMethodCombo = new Combo(mShell, SWT.DROP_DOWN | SWT.READ_ONLY);
+        mFilterMethodCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        for (CompareMethod method : CompareMethod.values()) {
+            mFilterMethodCombo.add(method.toString());
+        }
+        mFilterMethodCombo.select(0);
+        mFilterMethodCombo.addSelectionListener(new SelectionAdapter() {
+            /* (non-Javadoc)
+             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+             */
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                handleFilterMethodComboSelection();
+                setModified();
+            }
+        });
+
+        l = new Label(mShell, SWT.NONE);
+        l.setText("Filter Value:");
+        
+        mFilterValue = new Text(mShell, SWT.BORDER | SWT.SINGLE);
+        mFilterValue.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mFilterValue.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                if (mDescriptor.filterValueIndex != -1) {
+                    // get the current selection in the event combo
+                    int index = mEventCombo.getSelectionIndex();
+    
+                    if (index != -1) {
+                        // match it to an event
+                        int eventTag = mEventTags[index];
+                        mDescriptor.eventTag = eventTag;
+                        
+                        // get the EventValueDescription for this tag
+                        EventValueDescription valueDesc = mLogParser.getEventInfoMap()
+                            .get(eventTag)[mDescriptor.filterValueIndex];
+                        
+                        // let the EventValueDescription convert the String value into an object
+                        // of the proper type.
+                        mDescriptor.filterValue = valueDesc.getObjectFromString(
+                                mFilterValue.getText().trim());
+                        setModified();
+                    }
+                }
+            }
+        });
+        
+        // add a separator spanning the 2 columns
+        
+        l = new Label(mShell, SWT.SEPARATOR | SWT.HORIZONTAL);
+        gd = new GridData(GridData.FILL_HORIZONTAL);
+        gd.horizontalSpan = 2;
+        l.setLayoutData(gd);
+        
+        // add a composite to hold the ok/cancel button, no matter what the columns size are.
+        Composite buttonComp = new Composite(mShell, SWT.NONE);
+        gd = new GridData(GridData.FILL_HORIZONTAL);
+        gd.horizontalSpan = 2;
+        buttonComp.setLayoutData(gd);
+        GridLayout gl;
+        buttonComp.setLayout(gl = new GridLayout(6, true));
+        gl.marginHeight = gl.marginWidth = 0;
+
+        Composite padding = new Composite(mShell, SWT.NONE);
+        padding.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        mOkButton = new Button(buttonComp, SWT.PUSH);
+        mOkButton.setText("OK");
+        mOkButton.setLayoutData(new GridData(GridData.CENTER));
+        mOkButton.addSelectionListener(new SelectionAdapter() {
+            /* (non-Javadoc)
+             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+             */
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mShell.close();
+            }
+        });
+
+        padding = new Composite(mShell, SWT.NONE);
+        padding.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        padding = new Composite(mShell, SWT.NONE);
+        padding.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        
+        Button cancelButton = new Button(buttonComp, SWT.PUSH);
+        cancelButton.setText("Cancel");
+        cancelButton.setLayoutData(new GridData(GridData.CENTER));
+        cancelButton.addSelectionListener(new SelectionAdapter() {
+            /* (non-Javadoc)
+             * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+             */
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // cancel the edit
+                mEditStatus = false;
+                mShell.close();
+            }
+        });
+
+        padding = new Composite(mShell, SWT.NONE);
+        padding.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        
+        mShell.addListener(SWT.Close, new Listener() {
+            public void handleEvent(Event event) {
+                event.doit = true;
+            }
+        });
+    }
+
+    private void setModified() {
+        mEditStatus = true;
+    }
+
+    private void handleEventComboSelection() {
+        // get the current selection in the event combo
+        int index = mEventCombo.getSelectionIndex();
+
+        if (index != -1) {
+            // match it to an event
+            int eventTag = mEventTags[index];
+            mDescriptor.eventTag = eventTag;
+            
+            // get the EventValueDescription for this tag
+            EventValueDescription[] values = mLogParser.getEventInfoMap().get(eventTag);
+            
+            // fill the combo for the values
+            mValueCombo.removeAll();
+            if (values != null) {
+                if (mDescriptor instanceof ValueDisplayDescriptor) {
+                    ValueDisplayDescriptor valueDescriptor = (ValueDisplayDescriptor)mDescriptor;
+    
+                    mValueCombo.setEnabled(true);
+                    for (EventValueDescription value : values) {
+                        mValueCombo.add(value.toString());
+                    }
+                    
+                    if (valueDescriptor.valueIndex != -1) {
+                        mValueCombo.select(valueDescriptor.valueIndex);
+                    } else {
+                        mValueCombo.clearSelection();
+                    }
+                } else {
+                    mValueCombo.setEnabled(false);
+                }
+
+                // fill the axis combo
+                mSeriesCombo.removeAll();
+                mSeriesCombo.setEnabled(false);
+                mSeriesIndices.clear();
+                int axisIndex = 0;
+                int selectionIndex = -1;
+                for (EventValueDescription value : values) {
+                    if (value.getEventValueType() == EventValueType.STRING) {
+                        mSeriesCombo.add(value.getName());
+                        mSeriesCombo.setEnabled(true);
+                        mSeriesIndices.add(axisIndex);
+                        
+                        if (mDescriptor.seriesValueIndex != -1 &&
+                                mDescriptor.seriesValueIndex == axisIndex) {
+                            selectionIndex = axisIndex;
+                        }
+                    }
+                    axisIndex++;
+                }
+
+                if (mSeriesCombo.isEnabled()) {
+                    mSeriesCombo.add("default (pid)", 0 /* index */);
+                    mSeriesIndices.add(0 /* index */, -1 /* value */);
+
+                    // +1 because we added another item at index 0
+                    mSeriesCombo.select(selectionIndex + 1);
+                    
+                    if (selectionIndex >= 0) {
+                        mDisplayPidCheckBox.setSelection(mDescriptor.includePid);
+                        mDisplayPidCheckBox.setEnabled(true);
+                    } else {
+                        mDisplayPidCheckBox.setEnabled(false);
+                        mDisplayPidCheckBox.setSelection(false);
+                    }
+                } else {
+                    mDisplayPidCheckBox.setSelection(false);
+                    mDisplayPidCheckBox.setEnabled(false);
+                }
+                
+                // fill the filter combo
+                mFilterCombo.setEnabled(true);
+                mFilterCombo.removeAll();
+                mFilterCombo.add("(no filter)");
+                for (EventValueDescription value : values) {
+                    mFilterCombo.add(value.toString());
+                }
+                
+                // select the current filter
+                mFilterCombo.select(mDescriptor.filterValueIndex + 1);
+                mFilterMethodCombo.select(getFilterMethodIndex(mDescriptor.filterCompareMethod));
+
+                // fill the current filter value
+                if (mDescriptor.filterValueIndex != -1) {
+                    EventValueDescription valueInfo = values[mDescriptor.filterValueIndex];
+                    if (valueInfo.checkForType(mDescriptor.filterValue)) {
+                        mFilterValue.setText(mDescriptor.filterValue.toString());
+                    } else {
+                        mFilterValue.setText("");
+                    }
+                } else {
+                    mFilterValue.setText("");
+                }
+            } else {
+                disableSubCombos();
+            }
+        } else {
+            disableSubCombos();
+        }
+        
+        checkValidity();
+    }
+
+    /**
+     * 
+     */
+    private void disableSubCombos() {
+        mValueCombo.removeAll();
+        mValueCombo.clearSelection();
+        mValueCombo.setEnabled(false);
+
+        mSeriesCombo.removeAll();
+        mSeriesCombo.clearSelection();
+        mSeriesCombo.setEnabled(false);
+        
+        mDisplayPidCheckBox.setEnabled(false);
+        mDisplayPidCheckBox.setSelection(false);
+        
+        mFilterCombo.removeAll();
+        mFilterCombo.clearSelection();
+        mFilterCombo.setEnabled(false);
+        
+        mFilterValue.setEnabled(false);
+        mFilterValue.setText("");
+        mFilterMethodCombo.setEnabled(false);
+    }
+
+    private void handleValueComboSelection() {
+        ValueDisplayDescriptor valueDescriptor = (ValueDisplayDescriptor)mDescriptor;
+
+        // get the current selection in the value combo
+        int index = mValueCombo.getSelectionIndex();
+        valueDescriptor.valueIndex = index;
+        
+        // for now set the built-in name
+
+        // get the current selection in the event combo
+        int eventIndex = mEventCombo.getSelectionIndex();
+        
+        // match it to an event
+        int eventTag = mEventTags[eventIndex];
+        
+        // get the EventValueDescription for this tag
+        EventValueDescription[] values = mLogParser.getEventInfoMap().get(eventTag);
+
+        valueDescriptor.valueName = values[index].getName();
+        
+        checkValidity();
+    }
+
+    private void handleSeriesComboSelection() {
+        // get the current selection in the axis combo
+        int index = mSeriesCombo.getSelectionIndex();
+        
+        // get the actual value index from the list.
+        int valueIndex = mSeriesIndices.get(index);
+        
+        mDescriptor.seriesValueIndex = valueIndex;
+        
+        if (index > 0) {
+            mDisplayPidCheckBox.setEnabled(true);
+            mDisplayPidCheckBox.setSelection(mDescriptor.includePid);
+        } else {
+            mDisplayPidCheckBox.setSelection(false);
+            mDisplayPidCheckBox.setEnabled(false);
+        }
+    }
+
+    private void handleFilterComboSelection() {
+        // get the current selection in the axis combo
+        int index = mFilterCombo.getSelectionIndex();
+        
+        // decrement index by 1 since the item 0 means
+        // no filter (index = -1), and the rest is offset by 1
+        index--;
+
+        mDescriptor.filterValueIndex = index;
+        
+        if (index != -1) {
+            mFilterValue.setEnabled(true);
+            mFilterMethodCombo.setEnabled(true);
+            if (mDescriptor.filterValue instanceof String) {
+                mFilterValue.setText((String)mDescriptor.filterValue);
+            }
+        } else {
+            mFilterValue.setText("");
+            mFilterValue.setEnabled(false);
+            mFilterMethodCombo.setEnabled(false);
+        }
+    }
+    
+    private void handleFilterMethodComboSelection() {
+        // get the current selection in the axis combo
+        int index = mFilterMethodCombo.getSelectionIndex();
+        CompareMethod method = CompareMethod.values()[index];
+        
+        mDescriptor.filterCompareMethod = method;
+    }
+
+    /**
+     * Returns the index of the filter method
+     * @param filterCompareMethod the {@link CompareMethod} enum.
+     */
+    private int getFilterMethodIndex(CompareMethod filterCompareMethod) {
+        CompareMethod[] values = CompareMethod.values();
+        for (int i = 0 ; i < values.length ; i++) {
+            if (values[i] == filterCompareMethod) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+
+    private void loadValueDescriptor() {
+        // get the index from the eventTag.
+        int eventIndex = 0;
+        int comboIndex = -1;
+        for (int i : mEventTags) {
+            if (i == mDescriptor.eventTag) {
+                comboIndex = eventIndex;
+                break;
+            }
+            eventIndex++;
+        }
+        
+        if (comboIndex == -1) {
+            mEventCombo.clearSelection();
+        } else {
+            mEventCombo.select(comboIndex);
+        }
+
+        // get the event from the descriptor
+        handleEventComboSelection();
+    }
+    
+    private void checkValidity() {
+        mOkButton.setEnabled(mEventCombo.getSelectionIndex() != -1 &&
+                (((mDescriptor instanceof ValueDisplayDescriptor) == false) ||
+                        mValueCombo.getSelectionIndex() != -1));
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/OccurrenceRenderer.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/OccurrenceRenderer.java
new file mode 100644
index 0000000..3af1447
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/OccurrenceRenderer.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.log.event;
+
+import org.jfree.chart.axis.ValueAxis;
+import org.jfree.chart.plot.CrosshairState;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.PlotRenderingInfo;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.XYItemRendererState;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.data.time.TimeSeriesCollection;
+import org.jfree.data.xy.XYDataset;
+import org.jfree.ui.RectangleEdge;
+
+import java.awt.Graphics2D;
+import java.awt.Paint;
+import java.awt.Stroke;
+import java.awt.geom.Line2D;
+import java.awt.geom.Rectangle2D;
+
+/**
+ * Custom renderer to render event occurrence. This rendered ignores the y value, and simply
+ * draws a line from min to max at the time of the item.
+ */
+public class OccurrenceRenderer extends XYLineAndShapeRenderer {
+
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    public void drawItem(Graphics2D g2, 
+                         XYItemRendererState state,
+                         Rectangle2D dataArea,
+                         PlotRenderingInfo info,
+                         XYPlot plot, 
+                         ValueAxis domainAxis, 
+                         ValueAxis rangeAxis,
+                         XYDataset dataset, 
+                         int series, 
+                         int item,
+                         CrosshairState crosshairState, 
+                         int pass) {
+        TimeSeriesCollection timeDataSet = (TimeSeriesCollection)dataset;
+        
+        // get the x value for the series/item.
+        double x = timeDataSet.getX(series, item).doubleValue();
+
+        // get the min/max of the range axis
+        double yMin = rangeAxis.getLowerBound();
+        double yMax = rangeAxis.getUpperBound();
+
+        RectangleEdge domainEdge = plot.getDomainAxisEdge();
+        RectangleEdge rangeEdge = plot.getRangeAxisEdge();
+
+        // convert the coordinates to java2d.
+        double x2D = domainAxis.valueToJava2D(x, dataArea, domainEdge);
+        double yMin2D = rangeAxis.valueToJava2D(yMin, dataArea, rangeEdge);
+        double yMax2D = rangeAxis.valueToJava2D(yMax, dataArea, rangeEdge);
+
+        // get the paint information for the series/item
+        Paint p = getItemPaint(series, item);
+        Stroke s = getItemStroke(series, item);
+        
+        Line2D line = null;
+        PlotOrientation orientation = plot.getOrientation();
+        if (orientation == PlotOrientation.HORIZONTAL) {
+            line = new Line2D.Double(yMin2D, x2D, yMax2D, x2D);
+        }
+        else if (orientation == PlotOrientation.VERTICAL) {
+            line = new Line2D.Double(x2D, yMin2D, x2D, yMax2D);
+        }
+        g2.setPaint(p);
+        g2.setStroke(s);
+        g2.draw(line);
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/SyncCommon.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/SyncCommon.java
new file mode 100644
index 0000000..108c097
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/log/event/SyncCommon.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.log.event;
+
+import com.android.ddmlib.log.EventContainer;
+import com.android.ddmlib.log.EventLogParser;
+import com.android.ddmlib.log.InvalidTypeException;
+
+import java.awt.Color;
+
+abstract public class SyncCommon extends EventDisplay {
+
+    // State information while processing the event stream
+    private int mLastState; // 0 if event started, 1 if event stopped
+    private long mLastStartTime; // ms
+    private long mLastStopTime; //ms
+    private String mLastDetails;
+    private int mLastSyncSource; // poll, server, user, etc.
+
+    // Some common variables for sync display.  These define the sync backends
+    //and how they should be displayed.
+    protected static final int CALENDAR = 0;
+    protected static final int GMAIL = 1;
+    protected static final int FEEDS = 2;
+    protected static final int CONTACTS = 3;
+    protected static final int ERRORS = 4;
+    protected static final int NUM_AUTHS = (CONTACTS + 1);
+    protected static final String AUTH_NAMES[] = {"Calendar", "Gmail", "Feeds", "Contacts",
+            "Errors"};
+    protected static final Color AUTH_COLORS[] = {Color.MAGENTA, Color.GREEN, Color.BLUE,
+            Color.ORANGE, Color.RED};
+
+    // Values from data/etc/event-log-tags
+    final int EVENT_SYNC = 2720;
+    final int EVENT_TICKLE = 2742;
+    final int EVENT_SYNC_DETAILS = 2743;
+
+    protected SyncCommon(String name) {
+        super(name);
+    }
+
+    /**
+     * Resets the display.
+     */
+    @Override
+    void resetUI() {
+        mLastStartTime = 0;
+        mLastStopTime = 0;
+        mLastState = -1;
+        mLastSyncSource = -1;
+        mLastDetails = "";
+    }
+
+    /**
+     * Updates the display with a new event.  This is the main entry point for
+     * each event.  This method has the logic to tie together the start event,
+     * stop event, and details event into one graph item.  The combined sync event
+     * is handed to the subclass via processSycnEvent.  Note that the details
+     * can happen before or after the stop event.
+     *
+     * @param event     The event
+     * @param logParser The parser providing the event.
+     */
+    @Override
+    void newEvent(EventContainer event, EventLogParser logParser) {
+        try {
+            if (event.mTag == EVENT_SYNC) {
+                int state = Integer.parseInt(event.getValueAsString(1));
+                if (state == 0) { // start
+                    mLastStartTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
+                    mLastState = 0;
+                    mLastSyncSource = Integer.parseInt(event.getValueAsString(2));                    
+                    mLastDetails = "";
+                } else if (state == 1) { // stop
+                    if (mLastState == 0) {
+                        mLastStopTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
+                        if (mLastStartTime == 0) {
+                            // Log starts with a stop event
+                            mLastStartTime = mLastStopTime;
+                        }
+                        int auth = getAuth(event.getValueAsString(0));
+                        processSyncEvent(event, auth, mLastStartTime, mLastStopTime, mLastDetails,
+                                true, mLastSyncSource);
+                        mLastState = 1;
+                    }
+                }
+            } else if (event.mTag == EVENT_SYNC_DETAILS) {
+                mLastDetails = event.getValueAsString(3);
+                if (mLastState != 0) { // Not inside event
+                    long updateTime = (long) event.sec * 1000L + (event.nsec / 1000000L);
+                    if (updateTime - mLastStopTime <= 250) {
+                        // Got details within 250ms after event, so delete and re-insert
+                        // Details later than 250ms (arbitrary) are discarded as probably
+                        // unrelated.
+                        int auth = getAuth(event.getValueAsString(0));
+                        processSyncEvent(event, auth, mLastStartTime, mLastStopTime, mLastDetails,
+                                false, mLastSyncSource);
+                    }
+                }
+            }
+        } catch (InvalidTypeException e) {
+        }
+    }
+
+    /**
+     * Callback hook for subclass to process a sync event.  newEvent has the logic
+     * to combine start and stop events and passes a processed event to the
+     * subclass.
+     *
+     * @param event     The sync event
+     * @param auth      The sync authority
+     * @param startTime Start time (ms) of events
+     * @param stopTime  Stop time (ms) of events
+     * @param details   Details associated with the event.
+     * @param newEvent  True if this event is a new sync event.  False if this event
+     * @param syncSource Poll, user, server, etc.
+     */
+    abstract void processSyncEvent(EventContainer event, int auth, long startTime, long stopTime,
+            String details, boolean newEvent, int syncSource);
+     
+    /**
+     * Converts authority name to auth number.
+     *
+     * @param authname "calendar", etc.
+     * @return number series number associated with the authority
+     */
+    protected int getAuth(String authname) throws InvalidTypeException {
+        if ("calendar".equals(authname) || "cl".equals(authname)) {
+            return CALENDAR;
+        } else if ("contacts".equals(authname) || "cp".equals(authname)) {
+            return CONTACTS;
+        } else if ("subscribedfeeds".equals(authname)) {
+            return FEEDS;
+        } else if ("gmail-ls".equals(authname) || "mail".equals(authname)) {
+            return GMAIL;
+        } else if ("gmail-live".equals(authname)) {
+            return GMAIL;
+        } else if ("unknown".equals(authname)) {
+            return -1; // Unknown tickles; discard
+        } else {
+            throw new InvalidTypeException("Unknown authname " + authname);
+        }
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/EditFilterDialog.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/EditFilterDialog.java
new file mode 100644
index 0000000..c66fe48
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/EditFilterDialog.java
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.logcat;
+
+import com.android.ddmuilib.IImageLoader;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Small dialog box to edit a static port number.
+ */
+public class EditFilterDialog extends Dialog {
+
+    private static final int DLG_WIDTH = 400;
+    private static final int DLG_HEIGHT = 250;
+
+    private Shell mParent;
+
+    private Shell mShell;
+
+    private boolean mOk = false;
+
+    private IImageLoader mImageLoader;
+
+    /**
+     * Filter being edited or created
+     */
+    private LogFilter mFilter;
+
+    private String mName;
+    private String mTag;
+    private String mPid;
+
+    /** Log level as an index of the drop-down combo
+     * @see getLogLevel
+     * @see getComboIndex
+     */
+    private int mLogLevel;
+
+    private Button mOkButton;
+
+    private Label mPidWarning;
+
+    public EditFilterDialog(IImageLoader imageLoader, Shell parent) {
+        super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
+        mImageLoader = imageLoader;
+    }
+
+    public EditFilterDialog(IImageLoader imageLoader, Shell shell,
+            LogFilter filter) {
+        this(imageLoader, shell);
+        mFilter = filter;
+    }
+
+    /**
+     * Opens the dialog. The method will return when the user closes the dialog
+     * somehow.
+     *
+     * @return true if ok was pressed, false if cancelled.
+     */
+    public boolean open() {
+        createUI();
+
+        if (mParent == null || mShell == null) {
+            return false;
+        }
+
+        mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
+        Rectangle r = mParent.getBounds();
+        // get the center new top left.
+        int cx = r.x + r.width/2;
+        int x = cx - DLG_WIDTH / 2;
+        int cy = r.y + r.height/2;
+        int y = cy - DLG_HEIGHT / 2;
+        mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
+
+        mShell.open();
+
+        Display display = mParent.getDisplay();
+        while (!mShell.isDisposed()) {
+            if (!display.readAndDispatch())
+                display.sleep();
+        }
+
+        // we're quitting with OK.
+        // Lets update the filter if needed
+        if (mOk) {
+            // if it was a "Create filter" action we need to create it first.
+            if (mFilter == null) {
+                mFilter = new LogFilter(mName);
+            }
+
+            // setup the filter
+            mFilter.setTagMode(mTag);
+
+            if (mPid != null && mPid.length() > 0) {
+                mFilter.setPidMode(Integer.parseInt(mPid));
+            } else {
+                mFilter.setPidMode(-1);
+            }
+
+            mFilter.setLogLevel(getLogLevel(mLogLevel));
+        }
+
+        return mOk;
+    }
+
+    public LogFilter getFilter() {
+        return mFilter;
+    }
+
+    private void createUI() {
+        mParent = getParent();
+        mShell = new Shell(mParent, getStyle());
+        mShell.setText("Log Filter");
+
+        mShell.setLayout(new GridLayout(1, false));
+
+        mShell.addListener(SWT.Close, new Listener() {
+            public void handleEvent(Event event) {
+            }
+        });
+
+        // top part with the filter name
+        Composite nameComposite = new Composite(mShell, SWT.NONE);
+        nameComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
+        nameComposite.setLayout(new GridLayout(2, false));
+
+        Label l = new Label(nameComposite, SWT.NONE);
+        l.setText("Filter Name:");
+
+        final Text filterNameText = new Text(nameComposite,
+                SWT.SINGLE | SWT.BORDER);
+        if (mFilter != null) {
+            mName = mFilter.getName();
+            if (mName != null) {
+                filterNameText.setText(mName);
+            }
+        }
+        filterNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        filterNameText.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                mName = filterNameText.getText().trim();
+                validate();
+            }
+        });
+
+        // separator
+        l = new Label(mShell, SWT.SEPARATOR | SWT.HORIZONTAL);
+        l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+
+        // center part with the filter parameters
+        Composite main = new Composite(mShell, SWT.NONE);
+        main.setLayoutData(new GridData(GridData.FILL_BOTH));
+        main.setLayout(new GridLayout(3, false));
+
+        l = new Label(main, SWT.NONE);
+        l.setText("by Log Tag:");
+
+        final Text tagText = new Text(main, SWT.SINGLE | SWT.BORDER);
+        if (mFilter != null) {
+            mTag = mFilter.getTagFilter();
+            if (mTag != null) {
+                tagText.setText(mTag);
+            }
+        }
+        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+        gd.horizontalSpan = 2;
+        tagText.setLayoutData(gd);
+        tagText.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                mTag = tagText.getText().trim();
+                validate();
+            }
+        });
+
+        l = new Label(main, SWT.NONE);
+        l.setText("by pid:");
+
+        final Text pidText = new Text(main, SWT.SINGLE | SWT.BORDER);
+        if (mFilter != null) {
+            if (mFilter.getPidFilter() != -1) {
+                mPid = Integer.toString(mFilter.getPidFilter());
+            } else {
+                mPid = "";
+            }
+            pidText.setText(mPid);
+        }
+        pidText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        pidText.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                mPid = pidText.getText().trim();
+                validate();
+            }
+        });
+
+        mPidWarning = new Label(main, SWT.NONE);
+        mPidWarning.setImage(mImageLoader.loadImage("empty.png", // $NON-NLS-1$
+                mShell.getDisplay()));
+
+        l = new Label(main, SWT.NONE);
+        l.setText("by Log level:");
+
+        final Combo logCombo = new Combo(main, SWT.DROP_DOWN | SWT.READ_ONLY);
+        gd = new GridData(GridData.FILL_HORIZONTAL);
+        gd.horizontalSpan = 2;
+        logCombo.setLayoutData(gd);
+
+        // add the labels
+        logCombo.add("<none>");
+        logCombo.add("Error");
+        logCombo.add("Warning");
+        logCombo.add("Info");
+        logCombo.add("Debug");
+        logCombo.add("Verbose");
+
+        if (mFilter != null) {
+            mLogLevel = getComboIndex(mFilter.getLogLevel());
+            logCombo.select(mLogLevel);
+        } else {
+            logCombo.select(0);
+        }
+
+        logCombo.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // get the selection
+                mLogLevel = logCombo.getSelectionIndex();
+                validate();
+            }
+        });
+
+        // separator
+        l = new Label(mShell, SWT.SEPARATOR | SWT.HORIZONTAL);
+        l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        // bottom part with the ok/cancel
+        Composite bottomComp = new Composite(mShell, SWT.NONE);
+        bottomComp
+                .setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
+        bottomComp.setLayout(new GridLayout(2, true));
+
+        mOkButton = new Button(bottomComp, SWT.NONE);
+        mOkButton.setText("OK");
+        mOkButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mOk = true;
+                mShell.close();
+            }
+        });
+        mOkButton.setEnabled(false);
+        mShell.setDefaultButton(mOkButton);
+
+        Button cancelButton = new Button(bottomComp, SWT.NONE);
+        cancelButton.setText("Cancel");
+        cancelButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                mShell.close();
+            }
+        });
+
+        validate();
+    }
+
+    /**
+     * Returns the log level from a combo index.
+     * @param index the Combo index
+     * @return a log level valid for the Log class.
+     */
+    protected int getLogLevel(int index) {
+        if (index == 0) {
+            return -1;
+        }
+
+        return 7 - index;
+    }
+
+    /**
+     * Returns the index in the combo that matches the log level
+     * @param logLevel The Log level.
+     * @return the combo index
+     */
+    private int getComboIndex(int logLevel) {
+        if (logLevel == -1) {
+            return 0;
+        }
+
+        return 7 - logLevel;
+    }
+
+    /**
+     * Validates the content of the 2 text fields and enable/disable "ok", while
+     * setting up the warning/error message.
+     */
+    private void validate() {
+
+        // then we check it only contains digits.
+        if (mPid != null) {
+            if (mPid.matches("[0-9]*") == false) { // $NON-NLS-1$
+                mOkButton.setEnabled(false);
+                mPidWarning.setImage(mImageLoader.loadImage(
+                        "warning.png", // $NON-NLS-1$
+                        mShell.getDisplay()));
+                return;
+            } else {
+                mPidWarning.setImage(mImageLoader.loadImage(
+                        "empty.png", // $NON-NLS-1$
+                        mShell.getDisplay()));
+            }
+        }
+
+        if (mName == null || mName.length() == 0) {
+            mOkButton.setEnabled(false);
+            return;
+        }
+
+        mOkButton.setEnabled(true);
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogColors.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogColors.java
new file mode 100644
index 0000000..9cff656
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogColors.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.logcat;
+
+import org.eclipse.swt.graphics.Color;
+
+public class LogColors {
+    public Color infoColor;
+    public Color debugColor;
+    public Color errorColor;
+    public Color warningColor;
+    public Color verboseColor;
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogFilter.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogFilter.java
new file mode 100644
index 0000000..a32de2f
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogFilter.java
@@ -0,0 +1,555 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.logcat;
+
+import com.android.ddmlib.Log;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmuilib.annotation.UiThread;
+import com.android.ddmuilib.logcat.LogPanel.LogMessage;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.widgets.ScrollBar;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+import java.util.ArrayList;
+import java.util.regex.PatternSyntaxException;
+
+/** logcat output filter class */
+public class LogFilter {
+
+    public final static int MODE_PID = 0x01;
+    public final static int MODE_TAG = 0x02;
+    public final static int MODE_LEVEL = 0x04;
+
+    private String mName;
+
+    /**
+     * Filtering mode. Value can be a mix of MODE_PID, MODE_TAG, MODE_LEVEL
+     */
+    private int mMode = 0;
+
+    /**
+     * pid used for filtering. Only valid if mMode is MODE_PID.
+     */
+    private int mPid;
+
+    /** Single level log level as defined in Log.mLevelChar. Only valid
+     * if mMode is MODE_LEVEL */
+    private int mLogLevel;
+
+    /**
+     * log tag filtering. Only valid if mMode is MODE_TAG
+     */
+    private String mTag;
+
+    private Table mTable;
+    private TabItem mTabItem;
+    private boolean mIsCurrentTabItem = false;
+    private int mUnreadCount = 0;
+
+    /** Temp keyword filtering */
+    private String[] mTempKeywordFilters;
+
+    /** temp pid filtering */
+    private int mTempPid = -1;
+
+    /** temp tag filtering */
+    private String mTempTag;
+
+    /** temp log level filtering */
+    private int mTempLogLevel = -1;
+
+    private LogColors mColors;
+
+    private boolean mTempFilteringStatus = false;
+    
+    private final ArrayList<LogMessage> mMessages = new ArrayList<LogMessage>();
+    private final ArrayList<LogMessage> mNewMessages = new ArrayList<LogMessage>();
+
+    private boolean mSupportsDelete = true;
+    private boolean mSupportsEdit = true;
+    private int mRemovedMessageCount = 0;
+
+    /**
+     * Creates a filter with a particular mode.
+     * @param name The name to be displayed in the UI
+     */
+    public LogFilter(String name) {
+        mName = name;
+    }
+
+    public LogFilter() {
+
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(mName);
+
+        sb.append(':');
+        sb.append(mMode);
+        if ((mMode & MODE_PID) == MODE_PID) {
+            sb.append(':');
+            sb.append(mPid);
+        }
+
+        if ((mMode & MODE_LEVEL) == MODE_LEVEL) {
+            sb.append(':');
+            sb.append(mLogLevel);
+        }
+
+        if ((mMode & MODE_TAG) == MODE_TAG) {
+            sb.append(':');
+            sb.append(mTag);
+        }
+
+        return sb.toString();
+    }
+
+    public boolean loadFromString(String string) {
+        String[] segments = string.split(":"); // $NON-NLS-1$
+        int index = 0;
+
+        // get the name
+        mName = segments[index++];
+
+        // get the mode
+        mMode = Integer.parseInt(segments[index++]);
+
+        if ((mMode & MODE_PID) == MODE_PID) {
+            mPid = Integer.parseInt(segments[index++]);
+        }
+
+        if ((mMode & MODE_LEVEL) == MODE_LEVEL) {
+            mLogLevel = Integer.parseInt(segments[index++]);
+        }
+
+        if ((mMode & MODE_TAG) == MODE_TAG) {
+            mTag = segments[index++];
+        }
+
+        return true;
+    }
+
+
+    /** Sets the name of the filter. */
+    void setName(String name) {
+        mName = name;
+    }
+
+    /**
+     * Returns the UI display name.
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * Set the Table ui widget associated with this filter.
+     * @param tabItem The item in the TabFolder
+     * @param table The Table object
+     */
+    public void setWidgets(TabItem tabItem, Table table) {
+        mTable = table;
+        mTabItem = tabItem;
+    }
+
+    /**
+     * Returns true if the filter is ready for ui.
+     */
+    public boolean uiReady() {
+        return (mTable != null && mTabItem != null);
+    }
+
+    /**
+     * Returns the UI table object.
+     * @return
+     */
+    public Table getTable() {
+        return mTable;
+    }
+
+    public void dispose() {
+        mTable.dispose();
+        mTabItem.dispose();
+        mTable = null;
+        mTabItem = null;
+    }
+
+    /**
+     * Resets the filtering mode to be 0 (i.e. no filter).
+     */
+    public void resetFilteringMode() {
+        mMode = 0;
+    }
+
+    /**
+     * Returns the current filtering mode.
+     * @return A bitmask. Possible values are MODE_PID, MODE_TAG, MODE_LEVEL
+     */
+    public int getFilteringMode() {
+        return mMode;
+    }
+
+    /**
+     * Adds PID to the current filtering mode.
+     * @param pid
+     */
+    public void setPidMode(int pid) {
+        if (pid != -1) {
+            mMode |= MODE_PID;
+        } else {
+            mMode &= ~MODE_PID;
+        }
+        mPid = pid;
+    }
+
+    /** Returns the pid filter if valid, otherwise -1 */
+    public int getPidFilter() {
+        if ((mMode & MODE_PID) == MODE_PID)
+            return mPid;
+        return -1;
+    }
+
+    public void setTagMode(String tag) {
+        if (tag != null && tag.length() > 0) {
+            mMode |= MODE_TAG;
+        } else {
+            mMode &= ~MODE_TAG;
+        }
+        mTag = tag;
+    }
+
+    public String getTagFilter() {
+        if ((mMode & MODE_TAG) == MODE_TAG)
+            return mTag;
+        return null;
+    }
+
+    public void setLogLevel(int level) {
+        if (level == -1) {
+            mMode &= ~MODE_LEVEL;
+        } else {
+            mMode |= MODE_LEVEL;
+            mLogLevel = level;
+        }
+
+    }
+
+    public int getLogLevel() {
+        if ((mMode & MODE_LEVEL) == MODE_LEVEL) {
+            return mLogLevel;
+        }
+
+        return -1;
+    }
+
+
+    public boolean supportsDelete() {
+        return mSupportsDelete ;
+    }
+
+    public boolean supportsEdit() {
+        return mSupportsEdit;
+    }
+
+    /**
+     * Sets the selected state of the filter.
+     * @param selected selection state.
+     */
+    public void setSelectedState(boolean selected) {
+        if (selected) {
+            if (mTabItem != null) {
+                mTabItem.setText(mName);
+            }
+            mUnreadCount = 0;
+        }
+        mIsCurrentTabItem = selected;
+    }
+    
+    /**
+     * Adds a new message and optionally removes an old message.
+     * <p/>The new message is filtered through {@link #accept(LogMessage)}.
+     * Calls to {@link #flush()} from a UI thread will display it (and other
+     * pending messages) to the associated {@link Table}.
+     * @param logMessage the MessageData object to filter
+     * @return true if the message was accepted.
+     */
+    public boolean addMessage(LogMessage newMessage, LogMessage oldMessage) {
+        synchronized (mMessages) {
+            if (oldMessage != null) {
+                int index = mMessages.indexOf(oldMessage);
+                if (index != -1) {
+                    // TODO check that index will always be -1 or 0, as only the oldest message is ever removed.
+                    mMessages.remove(index);
+                    mRemovedMessageCount++;
+                }
+                
+                // now we look for it in mNewMessages. This can happen if the new message is added
+                // and then removed because too many messages are added between calls to #flush()
+                index = mNewMessages.indexOf(oldMessage);
+                if (index != -1) {
+                    // TODO check that index will always be -1 or 0, as only the oldest message is ever removed.
+                    mNewMessages.remove(index);
+                }
+            }
+
+            boolean filter = accept(newMessage);
+
+            if (filter) {
+                // at this point the message is accepted, we add it to the list
+                mMessages.add(newMessage);
+                mNewMessages.add(newMessage);
+            }
+
+            return filter;
+        }
+    }
+    
+    /**
+     * Removes all the items in the filter and its {@link Table}.
+     */
+    public void clear() {
+        mRemovedMessageCount = 0;
+        mNewMessages.clear();
+        mMessages.clear();
+        mTable.removeAll();
+    }
+    
+    /**
+     * Filters a message.
+     * @param logMessage the Message
+     * @return true if the message is accepted by the filter.
+     */
+    boolean accept(LogMessage logMessage) {
+        // do the regular filtering now
+        if ((mMode & MODE_PID) == MODE_PID && mPid != logMessage.data.pid) {
+            return false;
+        }
+
+        if ((mMode & MODE_TAG) == MODE_TAG && (
+                logMessage.data.tag == null ||
+                logMessage.data.tag.equals(mTag) == false)) {
+            return false;
+        }
+
+        int msgLogLevel = logMessage.data.logLevel.getPriority();
+
+        // test the temp log filtering first, as it replaces the old one
+        if (mTempLogLevel != -1) {
+            if (mTempLogLevel > msgLogLevel) {
+                return false;
+            }
+        } else if ((mMode & MODE_LEVEL) == MODE_LEVEL &&
+                mLogLevel > msgLogLevel) {
+            return false;
+        }
+
+        // do the temp filtering now.
+        if (mTempKeywordFilters != null) {
+            String msg = logMessage.msg;
+
+            for (String kw : mTempKeywordFilters) {
+                try {
+                    if (msg.contains(kw) == false && msg.matches(kw) == false) {
+                        return false;
+                    }
+                } catch (PatternSyntaxException e) {
+                    // if the string is not a valid regular expression,
+                    // this exception is thrown.
+                    return false;
+                }
+            }
+        }
+
+        if (mTempPid != -1 && mTempPid != logMessage.data.pid) {
+           return false;
+        }
+
+        if (mTempTag != null && mTempTag.length() > 0) {
+            if (mTempTag.equals(logMessage.data.tag) == false) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Takes all the accepted messages and display them.
+     * This must be called from a UI thread.
+     */
+    @UiThread
+    public void flush() {
+        // if scroll bar is at the bottom, we will scroll
+        ScrollBar bar = mTable.getVerticalBar();
+        boolean scroll = bar.getMaximum() == bar.getSelection() + bar.getThumb();
+        
+        // if we are not going to scroll, get the current first item being shown.
+        int topIndex = mTable.getTopIndex();
+
+        // disable drawing
+        mTable.setRedraw(false);
+        
+        int totalCount = mNewMessages.size();
+
+        try {
+            // remove the items of the old messages.
+            for (int i = 0 ; i < mRemovedMessageCount && mTable.getItemCount() > 0 ; i++) {
+                mTable.remove(0);
+            }
+    
+            if (mUnreadCount > mTable.getItemCount()) {
+                mUnreadCount = mTable.getItemCount();
+            }
+    
+            // add the new items
+            for (int i = 0  ; i < totalCount ; i++) {
+                LogMessage msg = mNewMessages.get(i);
+                addTableItem(msg);
+            }
+        } catch (SWTException e) {
+            // log the error and keep going. Content of the logcat table maybe unexpected
+            // but at least ddms won't crash.
+            Log.e("LogFilter", e);
+        }
+        
+        // redraw
+        mTable.setRedraw(true);
+
+        // scroll if needed, by showing the last item
+        if (scroll) {
+            totalCount = mTable.getItemCount();
+            if (totalCount > 0) {
+                mTable.showItem(mTable.getItem(totalCount-1));
+            }
+        } else if (mRemovedMessageCount > 0) {
+            // we need to make sure the topIndex is still visible.
+            // Because really old items are removed from the list, this could make it disappear
+            // if we don't change the scroll value at all.
+
+            topIndex -= mRemovedMessageCount;
+            if (topIndex < 0) {
+                // looks like it disappeared. Lets just show the first item
+                mTable.showItem(mTable.getItem(0));
+            } else {
+                mTable.showItem(mTable.getItem(topIndex));
+            }
+        }
+
+        // if this filter is not the current one, we update the tab text
+        // with the amount of unread message
+        if (mIsCurrentTabItem == false) {
+            mUnreadCount += mNewMessages.size();
+            totalCount = mTable.getItemCount();
+            if (mUnreadCount > 0) {
+                mTabItem.setText(mName + " (" // $NON-NLS-1$
+                        + (mUnreadCount > totalCount ? totalCount : mUnreadCount)
+                        + ")");  // $NON-NLS-1$
+            } else {
+                mTabItem.setText(mName);  // $NON-NLS-1$
+            }
+        }
+        
+        mNewMessages.clear();
+    }
+
+    void setColors(LogColors colors) {
+        mColors = colors;
+    }
+
+    int getUnreadCount() {
+        return mUnreadCount;
+    }
+
+    void setUnreadCount(int unreadCount) {
+        mUnreadCount = unreadCount;
+    }
+
+    void setSupportsDelete(boolean support) {
+        mSupportsDelete = support;
+    }
+
+    void setSupportsEdit(boolean support) {
+        mSupportsEdit = support;
+    }
+
+    void setTempKeywordFiltering(String[] segments) {
+        mTempKeywordFilters = segments;
+        mTempFilteringStatus = true;
+    }
+
+    void setTempPidFiltering(int pid) {
+        mTempPid = pid;
+        mTempFilteringStatus = true;
+    }
+
+    void setTempTagFiltering(String tag) {
+        mTempTag = tag;
+        mTempFilteringStatus = true;
+    }
+
+    void resetTempFiltering() {
+        if (mTempPid != -1 || mTempTag != null || mTempKeywordFilters != null) {
+            mTempFilteringStatus = true;
+        }
+
+        mTempPid = -1;
+        mTempTag = null;
+        mTempKeywordFilters = null;
+    }
+
+    void resetTempFilteringStatus() {
+        mTempFilteringStatus = false;
+    }
+
+    boolean getTempFilterStatus() {
+        return mTempFilteringStatus;
+    }
+
+
+    /**
+     * Add a TableItem for the index-th item of the buffer
+     * @param filter The index of the table in which to insert the item.
+     */
+    private void addTableItem(LogMessage msg) {
+        TableItem item = new TableItem(mTable, SWT.NONE);
+        item.setText(0, msg.data.time);
+        item.setText(1, new String(new char[] { msg.data.logLevel.getPriorityLetter() }));
+        item.setText(2, msg.data.pidString);
+        item.setText(3, msg.data.tag);
+        item.setText(4, msg.msg);
+
+        // add the buffer index as data
+        item.setData(msg);
+
+        if (msg.data.logLevel == LogLevel.INFO) {
+            item.setForeground(mColors.infoColor);
+        } else if (msg.data.logLevel == LogLevel.DEBUG) {
+            item.setForeground(mColors.debugColor);
+        } else if (msg.data.logLevel == LogLevel.ERROR) {
+            item.setForeground(mColors.errorColor);
+        } else if (msg.data.logLevel == LogLevel.WARN) {
+            item.setForeground(mColors.warningColor);
+        } else {
+            item.setForeground(mColors.verboseColor);
+        }
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java
new file mode 100644
index 0000000..bd8b75c
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/logcat/LogPanel.java
@@ -0,0 +1,1571 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.logcat;
+
+import com.android.ddmlib.Device;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.MultiLineReceiver;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmuilib.DdmUiPreferences;
+import com.android.ddmuilib.IImageLoader;
+import com.android.ddmuilib.ITableFocusListener;
+import com.android.ddmuilib.SelectionDependentPanel;
+import com.android.ddmuilib.TableHelper;
+import com.android.ddmuilib.ITableFocusListener.IFocusedTableActivator;
+import com.android.ddmuilib.actions.ICommonAction;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class LogPanel extends SelectionDependentPanel {
+
+    private static final int STRING_BUFFER_LENGTH = 10000;
+
+    /** no filtering. Only one tab with everything. */
+    public static final int FILTER_NONE = 0;
+    /** manual mode for filter. all filters are manually created. */
+    public static final int FILTER_MANUAL = 1;
+    /** automatic mode for filter (pid mode).
+     * All filters are automatically created. */
+    public static final int FILTER_AUTO_PID = 2;
+    /** automatic mode for filter (tag mode).
+     * All filters are automatically created. */
+    public static final int FILTER_AUTO_TAG = 3;
+    /** Manual filtering mode + new filter for debug app, if needed */
+    public static final int FILTER_DEBUG = 4;
+
+    public static final int COLUMN_MODE_MANUAL = 0;
+    public static final int COLUMN_MODE_AUTO = 1;
+
+    public static String PREFS_TIME;
+    public static String PREFS_LEVEL;
+    public static String PREFS_PID;
+    public static String PREFS_TAG;
+    public static String PREFS_MESSAGE;
+
+    /**
+     * This pattern is meant to parse the first line of a log message with the option
+     * 'logcat -v long'. The first line represents the date, tag, severity, etc.. while the
+     * following lines are the message (can be several line).<br>
+     * This first line looks something like<br>
+     * <code>"[ 00-00 00:00:00.000 &lt;pid&gt;:0x&lt;???&gt; &lt;severity&gt;/&lt;tag&gt;]"</code>
+     * <br>
+     * Note: severity is one of V, D, I, W, or EM<br>
+     * Note: the fraction of second value can have any number of digit.
+     * Note the tag should be trim as it may have spaces at the end.
+     */
+    private static Pattern sLogPattern = Pattern.compile(
+            "^\\[\\s(\\d\\d-\\d\\d\\s\\d\\d:\\d\\d:\\d\\d\\.\\d+)" + //$NON-NLS-1$
+            "\\s+(\\d*):(0x[0-9a-fA-F]+)\\s([VDIWE])/(.*)\\]$"); //$NON-NLS-1$
+
+    /**
+     * Interface for Storage Filter manager. Implementation of this interface
+     * provide a custom way to archive an reload filters.
+     */
+    public interface ILogFilterStorageManager {
+
+        public LogFilter[] getFilterFromStore();
+
+        public void saveFilters(LogFilter[] filters);
+
+        public boolean requiresDefaultFilter();
+    }
+
+    private Composite mParent;
+    private IPreferenceStore mStore;
+
+    /** top object in the view */
+    private TabFolder mFolders;
+
+    private LogColors mColors;
+
+    private ILogFilterStorageManager mFilterStorage;
+
+    private LogCatOuputReceiver mCurrentLogCat;
+
+    /**
+     * Circular buffer containing the logcat output. This is unfiltered.
+     * The valid content goes from <code>mBufferStart</code> to
+     * <code>mBufferEnd - 1</code>. Therefore its number of item is
+     * <code>mBufferEnd - mBufferStart</code>.
+     */
+    private LogMessage[] mBuffer = new LogMessage[STRING_BUFFER_LENGTH];
+
+    /** Represents the oldest message in the buffer */
+    private int mBufferStart = -1;
+
+    /**
+     * Represents the next usable item in the buffer to receive new message.
+     * This can be equal to mBufferStart, but when used mBufferStart will be
+     * incremented as well.
+     */
+    private int mBufferEnd = -1;
+
+    /** Filter list */
+    private LogFilter[] mFilters;
+
+    /** Default filter */
+    private LogFilter mDefaultFilter;
+
+    /** Current filter being displayed */
+    private LogFilter mCurrentFilter;
+
+    /** Filtering mode */
+    private int mFilterMode = FILTER_NONE;
+
+    /** Device currently running logcat */
+    private Device mCurrentLoggedDevice = null;
+
+    private ICommonAction mDeleteFilterAction;
+    private ICommonAction mEditFilterAction;
+
+    private ICommonAction[] mLogLevelActions;
+    
+    /** message data, separated from content for multi line messages */
+    protected static class LogMessageInfo {
+        public LogLevel logLevel;
+        public int pid;
+        public String pidString;
+        public String tag;
+        public String time;
+    }
+
+    /** pointer to the latest LogMessageInfo. this is used for multi line
+     * log message, to reuse the info regarding level, pid, etc...
+     */
+    private LogMessageInfo mLastMessageInfo = null;
+    
+    private boolean mPendingAsyncRefresh = false;
+
+    /** loader for the images. the implementation will varie between standalone
+     * app and eclipse plugin app and eclipse plugin. */
+    private IImageLoader mImageLoader;
+
+    private String mDefaultLogSave;
+
+    private int mColumnMode = COLUMN_MODE_MANUAL;
+    private Font mDisplayFont;
+
+    private ITableFocusListener mGlobalListener;
+
+    /** message data, separated from content for multi line messages */
+    protected static class LogMessage {
+        public LogMessageInfo data;
+        public String msg;
+
+        @Override
+        public String toString() {
+            return data.time + ": " //$NON-NLS-1$
+                + data.logLevel + "/" //$NON-NLS-1$
+                + data.tag + "(" //$NON-NLS-1$
+                + data.pidString + "): " //$NON-NLS-1$
+                + msg;
+        }
+    }
+
+    /**
+     * objects able to receive the output of a remote shell command,
+     * specifically a logcat command in this case
+     */
+    private final class LogCatOuputReceiver extends MultiLineReceiver {
+
+        public boolean isCancelled = false;
+
+        public LogCatOuputReceiver() {
+            super();
+
+            setTrimLine(false);
+        }
+
+        @Override
+        public void processNewLines(String[] lines) {
+            if (isCancelled == false) {
+                processLogLines(lines);
+            }
+        }
+
+        public boolean isCancelled() {
+            return isCancelled;
+        }
+    }
+
+    /**
+     * Parser class for the output of a "ps" shell command executed on a device.
+     * This class looks for a specific pid to find the process name from it.
+     * Once found, the name is used to update a filter and a tab object
+     *
+     */
+    private class PsOutputReceiver extends MultiLineReceiver {
+
+        private LogFilter mFilter;
+
+        private TabItem mTabItem;
+
+        private int mPid;
+
+        /** set to true when we've found the pid we're looking for */
+        private boolean mDone = false;
+
+        PsOutputReceiver(int pid, LogFilter filter, TabItem tabItem) {
+            mPid = pid;
+            mFilter = filter;
+            mTabItem = tabItem;
+        }
+
+        public boolean isCancelled() {
+            return mDone;
+        }
+
+        @Override
+        public void processNewLines(String[] lines) {
+            for (String line : lines) {
+                if (line.startsWith("USER")) { //$NON-NLS-1$
+                    continue;
+                }
+                // get the pid.
+                int index = line.indexOf(' ');
+                if (index == -1) {
+                    continue;
+                }
+                // look for the next non blank char
+                index++;
+                while (line.charAt(index) == ' ') {
+                    index++;
+                }
+
+                // this is the start of the pid.
+                // look for the end.
+                int index2 = line.indexOf(' ', index);
+
+                // get the line
+                String pidStr = line.substring(index, index2);
+                int pid = Integer.parseInt(pidStr);
+                if (pid != mPid) {
+                    continue;
+                } else {
+                    // get the process name
+                    index = line.lastIndexOf(' ');
+                    final String name = line.substring(index + 1);
+
+                    mFilter.setName(name);
+
+                    // update the tab
+                    Display d = mFolders.getDisplay();
+                    d.asyncExec(new Runnable() {
+                       public void run() {
+                           mTabItem.setText(name);
+                       }
+                    });
+
+                    // we're done with this ps.
+                    mDone = true;
+                    return;
+                }
+            }
+        }
+
+    }
+
+
+    /**
+     * Create the log view with some default parameters
+     * @param imageLoader the image loader.
+     * @param colors The display color object
+     * @param filterStorage the storage for user defined filters.
+     * @param mode The filtering mode
+     */
+    public LogPanel(IImageLoader imageLoader, LogColors colors,
+            ILogFilterStorageManager filterStorage, int mode) {
+        mImageLoader = imageLoader;
+        mColors = colors;
+        mFilterMode = mode;
+        mFilterStorage = filterStorage;
+        mStore = DdmUiPreferences.getStore();
+    }
+
+    public void setActions(ICommonAction deleteAction, ICommonAction editAction,
+            ICommonAction[] logLevelActions) {
+        mDeleteFilterAction = deleteAction;
+        mEditFilterAction = editAction;
+        mLogLevelActions = logLevelActions;
+    }
+
+    /**
+     * Sets the column mode. Must be called before creatUI
+     * @param mode the column mode. Valid values are COLUMN_MOD_MANUAL and
+     *  COLUMN_MODE_AUTO
+     */
+    public void setColumnMode(int mode) {
+        mColumnMode  = mode;
+    }
+
+    /**
+     * Sets the display font.
+     * @param font The display font.
+     */
+    public void setFont(Font font) {
+        mDisplayFont = font;
+
+        if (mFilters != null) {
+            for (LogFilter f : mFilters) {
+                Table table = f.getTable();
+                if (table != null) {
+                    table.setFont(font);
+                }
+            }
+        }
+
+        if (mDefaultFilter != null) {
+            Table table = mDefaultFilter.getTable();
+            if (table != null) {
+                table.setFont(font);
+            }
+        }
+    }
+
+    /**
+     * Sent when a new device is selected. The new device can be accessed
+     * with {@link #getCurrentDevice()}.
+     */
+    @Override
+    public void deviceSelected() {
+        startLogCat(getCurrentDevice());
+    }
+
+    /**
+     * Sent when a new client is selected. The new client can be accessed
+     * with {@link #getCurrentClient()}.
+     */
+    @Override
+    public void clientSelected() {
+        // pass
+    }
+
+
+    /**
+     * Creates a control capable of displaying some information.  This is
+     * called once, when the application is initializing, from the UI thread.
+     */
+    @Override
+    protected Control createControl(Composite parent) {
+        mParent = parent;
+
+        Composite top = new Composite(parent, SWT.NONE);
+        top.setLayoutData(new GridData(GridData.FILL_BOTH));
+        top.setLayout(new GridLayout(1, false));
+
+        // create the tab folder
+        mFolders = new TabFolder(top, SWT.NONE);
+        mFolders.setLayoutData(new GridData(GridData.FILL_BOTH));
+        mFolders.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                if (mCurrentFilter != null) {
+                    mCurrentFilter.setSelectedState(false);
+                }
+                mCurrentFilter = getCurrentFilter();
+                mCurrentFilter.setSelectedState(true);
+                updateColumns(mCurrentFilter.getTable());
+                if (mCurrentFilter.getTempFilterStatus()) {
+                    initFilter(mCurrentFilter);
+                }
+                selectionChanged(mCurrentFilter);
+            }
+        });
+
+
+        Composite bottom = new Composite(top, SWT.NONE);
+        bottom.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        bottom.setLayout(new GridLayout(3, false));
+
+        Label label = new Label(bottom, SWT.NONE);
+        label.setText("Filter:");
+
+        final Text filterText = new Text(bottom, SWT.SINGLE | SWT.BORDER);
+        filterText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        filterText.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent e) {
+                updateFilteringWith(filterText.getText());
+            }
+        });
+
+        /*
+        Button addFilterBtn = new Button(bottom, SWT.NONE);
+        addFilterBtn.setImage(mImageLoader.loadImage("add.png", //$NON-NLS-1$
+                addFilterBtn.getDisplay()));
+        */
+
+        // get the filters
+        createFilters();
+
+        // for each filter, create a tab.
+        int index = 0;
+
+        if (mDefaultFilter != null) {
+            createTab(mDefaultFilter, index++, false);
+        }
+
+        if (mFilters != null) {
+            for (LogFilter f : mFilters) {
+                createTab(f, index++, false);
+            }
+        }
+
+        return top;
+    }
+
+    @Override
+    protected void postCreation() {
+        // pass
+    }
+
+    /**
+     * Sets the focus to the proper object.
+     */
+    @Override
+    public void setFocus() {
+        mFolders.setFocus();
+    }
+
+
+    /**
+     * Starts a new logcat and set mCurrentLogCat as the current receiver.
+     * @param device the device to connect logcat to.
+     */
+    public void startLogCat(final Device device) {
+        if (device == mCurrentLoggedDevice) {
+            return;
+        }
+
+        // if we have a logcat already running
+        if (mCurrentLoggedDevice != null) {
+            stopLogCat(false);
+            mCurrentLoggedDevice = null;
+        }
+        
+        resetUI(false);
+
+        if (device != null) {
+            // create a new output receiver
+            mCurrentLogCat = new LogCatOuputReceiver();
+
+            // start the logcat in a different thread
+            new Thread("Logcat")  { //$NON-NLS-1$
+                @Override
+                public void run() {
+
+                    while (device.isOnline() == false &&
+                            mCurrentLogCat != null &&
+                            mCurrentLogCat.isCancelled == false) {
+                        try {
+                            sleep(2000);
+                        } catch (InterruptedException e) {
+                            return;
+                        }
+                    }
+
+                    if (mCurrentLogCat == null || mCurrentLogCat.isCancelled) {
+                        // logcat was stopped/cancelled before the device became ready.
+                        return;
+                    }
+
+                    try {
+                        mCurrentLoggedDevice = device;
+                        device.executeShellCommand("logcat -v long", mCurrentLogCat); //$NON-NLS-1$
+                    } catch (Exception e) {
+                        Log.e("Logcat", e);
+                    } finally {
+                        // at this point the command is terminated.
+                        mCurrentLogCat = null;
+                        mCurrentLoggedDevice = null;
+                    }
+                }
+            }.start();
+        }
+    }
+
+    /** Stop the current logcat */
+    public void stopLogCat(boolean inUiThread) {
+        if (mCurrentLogCat != null) {
+            mCurrentLogCat.isCancelled = true;
+
+            // when the thread finishes, no one will reference that object
+            // and it'll be destroyed
+            mCurrentLogCat = null;
+
+            // reset the content buffer
+            for (int i = 0 ; i < STRING_BUFFER_LENGTH; i++) {
+                mBuffer[i] = null;
+            }
+
+            // because it's a circular buffer, it's hard to know if
+            // the array is empty with both start/end at 0 or if it's full
+            // with both start/end at 0 as well. So to mean empty, we use -1
+            mBufferStart = -1;
+            mBufferEnd = -1;
+
+            resetFilters();
+            resetUI(inUiThread);
+        }
+    }
+
+    /**
+     * Adds a new Filter. This methods displays the UI to create the filter
+     * and set up its parameters.<br>
+     * <b>MUST</b> be called from the ui thread.
+     *
+     */
+    public void addFilter() {
+        EditFilterDialog dlg = new EditFilterDialog(mImageLoader,
+                mFolders.getShell());
+        if (dlg.open()) {
+            synchronized (mBuffer) {
+                // get the new filter in the array
+                LogFilter filter = dlg.getFilter();
+                addFilterToArray(filter);
+
+                int index = mFilters.length - 1;
+                if (mDefaultFilter != null) {
+                    index++;
+                }
+
+                if (false) {
+
+                    for (LogFilter f : mFilters) {
+                        if (f.uiReady()) {
+                            f.dispose();
+                        }
+                    }
+                    if (mDefaultFilter != null && mDefaultFilter.uiReady()) {
+                        mDefaultFilter.dispose();
+                    }
+
+                    // for each filter, create a tab.
+                    int i = 0;
+                    if (mFilters != null) {
+                        for (LogFilter f : mFilters) {
+                            createTab(f, i++, true);
+                        }
+                    }
+                    if (mDefaultFilter != null) {
+                        createTab(mDefaultFilter, i++, true);
+                    }
+                } else {
+
+                    // create ui for the filter.
+                    createTab(filter, index, true);
+
+                    // reset the default as it shouldn't contain the content of
+                    // this new filter.
+                    if (mDefaultFilter != null) {
+                        initDefaultFilter();
+                    }
+                }
+
+                // select the new filter
+                if (mCurrentFilter != null) {
+                    mCurrentFilter.setSelectedState(false);
+                }
+                mFolders.setSelection(index);
+                filter.setSelectedState(true);
+                mCurrentFilter = filter;
+
+                selectionChanged(filter);
+
+                // finally we update the filtering mode if needed
+                if (mFilterMode == FILTER_NONE) {
+                    mFilterMode = FILTER_MANUAL;
+                }
+
+                mFilterStorage.saveFilters(mFilters);
+
+            }
+        }
+    }
+
+    /**
+     * Edits the current filter. The method displays the UI to edit the filter.
+     */
+    public void editFilter() {
+        if (mCurrentFilter != null && mCurrentFilter != mDefaultFilter) {
+            EditFilterDialog dlg = new EditFilterDialog(mImageLoader,
+                    mFolders.getShell(),
+                    mCurrentFilter);
+            if (dlg.open()) {
+                synchronized (mBuffer) {
+                    // at this point the filter has been updated.
+                    // so we update its content
+                    initFilter(mCurrentFilter);
+
+                    // and the content of the "other" filter as well.
+                    if (mDefaultFilter != null) {
+                        initDefaultFilter();
+                    }
+
+                    mFilterStorage.saveFilters(mFilters);
+                }
+            }
+        }
+    }
+
+    /**
+     * Deletes the current filter.
+     */
+    public void deleteFilter() {
+        synchronized (mBuffer) {
+            if (mCurrentFilter != null && mCurrentFilter != mDefaultFilter) {
+                // remove the filter from the list
+                removeFilterFromArray(mCurrentFilter);
+                mCurrentFilter.dispose();
+
+                // select the new filter
+                mFolders.setSelection(0);
+                if (mFilters.length > 0) {
+                    mCurrentFilter = mFilters[0];
+                } else {
+                    mCurrentFilter = mDefaultFilter;
+                }
+
+                selectionChanged(mCurrentFilter);
+
+                // update the content of the "other" filter to include what was filtered out
+                // by the deleted filter.
+                if (mDefaultFilter != null) {
+                    initDefaultFilter();
+                }
+
+                mFilterStorage.saveFilters(mFilters);
+            }
+        }
+    }
+
+    /**
+     * saves the current selection in a text file.
+     * @return false if the saving failed.
+     */
+    public boolean save() {
+        synchronized (mBuffer) {
+            FileDialog dlg = new FileDialog(mParent.getShell(), SWT.SAVE);
+            String fileName;
+    
+            dlg.setText("Save log...");
+            dlg.setFileName("log.txt");
+            String defaultPath = mDefaultLogSave;
+            if (defaultPath == null) {
+                defaultPath = System.getProperty("user.home"); //$NON-NLS-1$
+            }
+            dlg.setFilterPath(defaultPath);
+            dlg.setFilterNames(new String[] {
+                "Text Files (*.txt)"
+            });
+            dlg.setFilterExtensions(new String[] {
+                "*.txt"
+            });
+    
+            fileName = dlg.open();
+            if (fileName != null) {
+                mDefaultLogSave = dlg.getFilterPath();
+
+                // get the current table and its selection
+                Table currentTable = mCurrentFilter.getTable();
+
+                int[] selection = currentTable.getSelectionIndices();
+
+                // we need to sort the items to be sure.
+                Arrays.sort(selection);
+
+                // loop on the selection and output the file.
+                try {
+                    FileWriter writer = new FileWriter(fileName);
+
+                    for (int i : selection) {
+                        TableItem item = currentTable.getItem(i);
+                        LogMessage msg = (LogMessage)item.getData();
+                        String line = msg.toString();
+                        writer.write(line);
+                        writer.write('\n');
+                    }
+                    writer.flush();
+
+                } catch (IOException e) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Empty the current circular buffer.
+     */
+    public void clear() {
+        synchronized (mBuffer) {
+            for (int i = 0 ; i < STRING_BUFFER_LENGTH; i++) {
+                mBuffer[i] = null;
+            }
+
+            mBufferStart = -1;
+            mBufferEnd = -1;
+
+            // now we clear the existing filters
+            for (LogFilter filter : mFilters) {
+                filter.clear();
+            }
+
+            // and the default one
+            if (mDefaultFilter != null) {
+                mDefaultFilter.clear();
+            }
+        }
+    }
+
+    /**
+     * Copies the current selection of the current filter as multiline text.
+     *
+     * @param clipboard The clipboard to place the copied content.
+     */
+    public void copy(Clipboard clipboard) {
+        // get the current table and its selection
+        Table currentTable = mCurrentFilter.getTable();
+
+        copyTable(clipboard, currentTable);
+    }
+
+    /**
+     * Selects all lines.
+     */
+    public void selectAll() {
+        Table currentTable = mCurrentFilter.getTable();
+        currentTable.selectAll();
+    }
+
+    /**
+     * Sets a TableFocusListener which will be notified when one of the tables
+     * gets or loses focus.
+     *
+     * @param listener
+     */
+    public void setTableFocusListener(ITableFocusListener listener) {
+        // record the global listener, to make sure table created after
+        // this call will still be setup.
+        mGlobalListener = listener;
+
+        // now we setup the existing filters
+        for (LogFilter filter : mFilters) {
+            Table table = filter.getTable();
+
+            addTableToFocusListener(table);
+        }
+
+        // and the default one
+        if (mDefaultFilter != null) {
+            addTableToFocusListener(mDefaultFilter.getTable());
+        }
+    }
+
+    /**
+     * Sets up a Table object to notify the global Table Focus listener when it
+     * gets or loses the focus.
+     *
+     * @param table the Table object.
+     */
+    private void addTableToFocusListener(final Table table) {
+        // create the activator for this table
+        final IFocusedTableActivator activator = new IFocusedTableActivator() {
+            public void copy(Clipboard clipboard) {
+                copyTable(clipboard, table);
+            }
+
+            public void selectAll() {
+                table.selectAll();
+            }
+        };
+
+        // add the focus listener on the table to notify the global listener
+        table.addFocusListener(new FocusListener() {
+            public void focusGained(FocusEvent e) {
+                mGlobalListener.focusGained(activator);
+            }
+
+            public void focusLost(FocusEvent e) {
+                mGlobalListener.focusLost(activator);
+            }
+        });
+    }
+
+    /**
+     * Copies the current selection of a Table into the provided Clipboard, as
+     * multi-line text.
+     *
+     * @param clipboard The clipboard to place the copied content.
+     * @param table The table to copy from.
+     */
+    private static void copyTable(Clipboard clipboard, Table table) {
+        int[] selection = table.getSelectionIndices();
+
+        // we need to sort the items to be sure.
+        Arrays.sort(selection);
+
+        // all lines must be concatenated.
+        StringBuilder sb = new StringBuilder();
+
+        // loop on the selection and output the file.
+        for (int i : selection) {
+            TableItem item = table.getItem(i);
+            LogMessage msg = (LogMessage)item.getData();
+            String line = msg.toString();
+            sb.append(line);
+            sb.append('\n');
+        }
+
+        // now add that to the clipboard
+        clipboard.setContents(new Object[] {
+            sb.toString()
+        }, new Transfer[] {
+            TextTransfer.getInstance()
+        });
+    }
+
+    /**
+     * Sets the log level for the current filter, but does not save it.
+     * @param i
+     */
+    public void setCurrentFilterLogLevel(int i) {
+        LogFilter filter = getCurrentFilter();
+
+        filter.setLogLevel(i);
+
+        initFilter(filter);
+    }
+
+    /**
+     * Creates a new tab in the folderTab item. Must be called from the ui
+     *      thread.
+     * @param filter The filter associated with the tab.
+     * @param index the index of the tab. if -1, the tab will be added at the
+     *          end.
+     * @param fillTable If true the table is filled with the current content of
+     *          the buffer.
+     * @return The TabItem object that was created.
+     */
+    private TabItem createTab(LogFilter filter, int index, boolean fillTable) {
+        synchronized (mBuffer) {
+            TabItem item = null;
+            if (index != -1) {
+                item = new TabItem(mFolders, SWT.NONE, index);
+            } else {
+                item = new TabItem(mFolders, SWT.NONE);
+            }
+            item.setText(filter.getName());
+
+            // set the control (the parent is the TabFolder item, always)
+            Composite top = new Composite(mFolders, SWT.NONE);
+            item.setControl(top);
+
+            top.setLayout(new FillLayout());
+
+            // create the ui, first the table
+            final Table t = new Table(top, SWT.MULTI | SWT.FULL_SELECTION);
+
+            if (mDisplayFont != null) {
+                t.setFont(mDisplayFont);
+            }
+
+            // give the ui objects to the filters.
+            filter.setWidgets(item, t);
+
+            t.setHeaderVisible(true);
+            t.setLinesVisible(false);
+
+            if (mGlobalListener != null) {
+            	addTableToFocusListener(t);
+            }
+
+            // create a controllistener that will handle the resizing of all the
+            // columns (except the last) and of the table itself.
+            ControlListener listener = null;
+            if (mColumnMode == COLUMN_MODE_AUTO) {
+                listener = new ControlListener() {
+                    public void controlMoved(ControlEvent e) {
+                    }
+
+                    public void controlResized(ControlEvent e) {
+                        Rectangle r = t.getClientArea();
+
+                        // get the size of all but the last column
+                        int total = t.getColumn(0).getWidth();
+                        total += t.getColumn(1).getWidth();
+                        total += t.getColumn(2).getWidth();
+                        total += t.getColumn(3).getWidth();
+
+                        if (r.width > total) {
+                            t.getColumn(4).setWidth(r.width-total);
+                        }
+                    }
+                };
+
+                t.addControlListener(listener);
+            }
+
+            // then its column
+            TableColumn col = TableHelper.createTableColumn(t, "Time", SWT.LEFT,
+                    "00-00 00:00:00", //$NON-NLS-1$
+                    PREFS_TIME, mStore);
+            if (mColumnMode == COLUMN_MODE_AUTO) {
+                col.addControlListener(listener);
+            }
+
+            col = TableHelper.createTableColumn(t, "", SWT.CENTER,
+                    "D", //$NON-NLS-1$
+                    PREFS_LEVEL, mStore);
+            if (mColumnMode == COLUMN_MODE_AUTO) {
+                col.addControlListener(listener);
+            }
+
+            col = TableHelper.createTableColumn(t, "pid", SWT.LEFT,
+                    "9999", //$NON-NLS-1$
+                    PREFS_PID, mStore);
+            if (mColumnMode == COLUMN_MODE_AUTO) {
+                col.addControlListener(listener);
+            }
+
+            col = TableHelper.createTableColumn(t, "tag", SWT.LEFT,
+                    "abcdefgh",  //$NON-NLS-1$
+                    PREFS_TAG, mStore);
+            if (mColumnMode == COLUMN_MODE_AUTO) {
+                col.addControlListener(listener);
+            }
+
+            col = TableHelper.createTableColumn(t, "Message", SWT.LEFT,
+                    "abcdefghijklmnopqrstuvwxyz0123456789",  //$NON-NLS-1$
+                    PREFS_MESSAGE, mStore);
+            if (mColumnMode == COLUMN_MODE_AUTO) {
+                // instead of listening on resize for the last column, we make
+                // it non resizable.
+                col.setResizable(false);
+            }
+
+            if (fillTable) {
+                initFilter(filter);
+            }
+            return item;
+        }
+    }
+
+    protected void updateColumns(Table table) {
+        if (table != null) {
+            int index = 0;
+            TableColumn col;
+
+            col = table.getColumn(index++);
+            col.setWidth(mStore.getInt(PREFS_TIME));
+
+            col = table.getColumn(index++);
+            col.setWidth(mStore.getInt(PREFS_LEVEL));
+
+            col = table.getColumn(index++);
+            col.setWidth(mStore.getInt(PREFS_PID));
+
+            col = table.getColumn(index++);
+            col.setWidth(mStore.getInt(PREFS_TAG));
+
+            col = table.getColumn(index++);
+            col.setWidth(mStore.getInt(PREFS_MESSAGE));
+        }
+    }
+
+    public void resetUI(boolean inUiThread) {
+        if (mFilterMode == FILTER_AUTO_PID || mFilterMode == FILTER_AUTO_TAG) {
+            if (inUiThread) {
+                mFolders.dispose();
+                mParent.pack(true);
+                createControl(mParent);
+            } else {
+                Display d = mFolders.getDisplay();
+
+                // run sync as we need to update right now.
+                d.syncExec(new Runnable() {
+                    public void run() {
+                        mFolders.dispose();
+                        mParent.pack(true);
+                        createControl(mParent);
+                    }
+                });
+            }
+        } else  {
+            // the ui is static we just empty it.
+            if (mFolders.isDisposed() == false) {
+                if (inUiThread) {
+                    emptyTables();
+                } else {
+                    Display d = mFolders.getDisplay();
+
+                    // run sync as we need to update right now.
+                    d.syncExec(new Runnable() {
+                        public void run() {
+                            if (mFolders.isDisposed() == false) {
+                                emptyTables();
+                            }
+                        }
+                    });
+                }
+            }
+        }
+    }
+
+    /**
+     * Process new Log lines coming from {@link LogCatOuputReceiver}. 
+     * @param lines the new lines
+     */
+    protected void processLogLines(String[] lines) {
+        // WARNING: this will not work if the string contains more line than
+        // the buffer holds.
+
+        if (lines.length > STRING_BUFFER_LENGTH) {
+            Log.e("LogCat", "Receiving more lines than STRING_BUFFER_LENGTH");
+        }
+        
+        // parse the lines and create LogMessage that are stored in a temporary list
+        final ArrayList<LogMessage> newMessages = new ArrayList<LogMessage>();
+        
+        synchronized (mBuffer) {
+            for (String line : lines) {
+                // ignore empty lines.
+                if (line.length() > 0) {
+                    // check for header lines.
+                    Matcher matcher = sLogPattern.matcher(line);
+                    if (matcher.matches()) {
+                        // this is a header line, parse the header and keep it around.
+                        mLastMessageInfo = new LogMessageInfo();
+    
+                        mLastMessageInfo.time = matcher.group(1);
+                        mLastMessageInfo.pidString = matcher.group(2);
+                        mLastMessageInfo.pid = Integer.valueOf(mLastMessageInfo.pidString);
+                        mLastMessageInfo.logLevel = LogLevel.getByLetterString(matcher.group(4));
+                        mLastMessageInfo.tag = matcher.group(5).trim();
+                    } else {
+                        // This is not a header line.
+                        // Create a new LogMessage and process it.
+                        LogMessage mc = new LogMessage();
+    
+                        if (mLastMessageInfo == null) {
+                            // The first line of output wasn't preceded
+                            // by a header line; make something up so
+                            // that users of mc.data don't NPE.
+                            mLastMessageInfo = new LogMessageInfo();
+                            mLastMessageInfo.time = "??-?? ??:??:??.???"; //$NON-NLS1$
+                            mLastMessageInfo.pidString = "<unknown>"; //$NON-NLS1$
+                            mLastMessageInfo.pid = 0;
+                            mLastMessageInfo.logLevel = LogLevel.INFO;
+                            mLastMessageInfo.tag = "<unknown>"; //$NON-NLS1$
+                        }
+    
+                        // If someone printed a log message with
+                        // embedded '\n' characters, there will
+                        // one header line followed by multiple text lines.
+                        // Use the last header that we saw.
+                        mc.data = mLastMessageInfo;
+    
+                        // tabs seem to display as only 1 tab so we replace the leading tabs
+                        // by 4 spaces.
+                        mc.msg = line.replaceAll("\t", "    "); //$NON-NLS-1$ //$NON-NLS-2$
+                        
+                        // process the new LogMessage.
+                        processNewMessage(mc);
+                        
+                        // store the new LogMessage
+                        newMessages.add(mc);
+                    }
+                }
+            }
+            
+            // if we don't have a pending Runnable that will do the refresh, we ask the Display
+            // to run one in the UI thread.
+            if (mPendingAsyncRefresh == false) {
+                mPendingAsyncRefresh = true;
+                
+                try {
+                    Display display = mFolders.getDisplay();
+                    
+                    // run in sync because this will update the buffer start/end indices
+                    display.asyncExec(new Runnable() {
+                        public void run() {
+                            asyncRefresh();
+                        }
+                    });
+                } catch (SWTException e) {
+                    // display is disposed, we're probably quitting. Let's stop.
+                    stopLogCat(false);
+                }
+            }
+        }
+    }
+
+    /**
+     * Refreshes the UI with new messages.
+     */
+    private void asyncRefresh() {
+        if (mFolders.isDisposed() == false) {
+            synchronized (mBuffer) {
+                try {
+                    // the circular buffer has been updated, let have the filter flush their
+                    // display with the new messages.
+                    if (mFilters != null) {
+                        for (LogFilter f : mFilters) {
+                            f.flush();
+                        }
+                    }
+    
+                    if (mDefaultFilter != null) {
+                        mDefaultFilter.flush();
+                    }
+                } finally {
+                    // the pending refresh is done.
+                    mPendingAsyncRefresh = false;
+                }
+            }
+        } else {
+            stopLogCat(true);
+        }
+    }
+
+    /**
+     * Processes a new Message.
+     * <p/>This adds the new message to the buffer, and gives it to the existing filters.
+     * @param newMessage
+     */
+    private void processNewMessage(LogMessage newMessage) {
+        // if we are in auto filtering mode, make sure we have
+        // a filter for this
+        if (mFilterMode == FILTER_AUTO_PID ||
+                mFilterMode == FILTER_AUTO_TAG) {
+           checkFilter(newMessage.data);
+        }
+
+        // compute the index where the message goes.
+        // was the buffer empty?
+        int messageIndex = -1;
+        if (mBufferStart == -1) {
+            messageIndex = mBufferStart = 0;
+            mBufferEnd = 1;
+        } else {
+            messageIndex = mBufferEnd;
+
+            // check we aren't overwriting start
+            if (mBufferEnd == mBufferStart) {
+                mBufferStart = (mBufferStart + 1) % STRING_BUFFER_LENGTH;
+            }
+
+            // increment the next usable slot index
+            mBufferEnd = (mBufferEnd + 1) % STRING_BUFFER_LENGTH;
+        }
+        
+        LogMessage oldMessage = null;
+
+        // record the message that was there before
+        if (mBuffer[messageIndex] != null) {
+            oldMessage = mBuffer[messageIndex];
+        }
+
+        // then add the new one
+        mBuffer[messageIndex] = newMessage;
+
+        // give the new message to every filters.
+        boolean filtered = false;
+        if (mFilters != null) {
+            for (LogFilter f : mFilters) {
+                filtered |= f.addMessage(newMessage, oldMessage);
+            }
+        }
+        if (filtered == false && mDefaultFilter != null) {
+            mDefaultFilter.addMessage(newMessage, oldMessage);
+        }
+    }
+
+    private void createFilters() {
+        if (mFilterMode == FILTER_DEBUG || mFilterMode == FILTER_MANUAL) {
+            // unarchive the filters.
+            mFilters = mFilterStorage.getFilterFromStore();
+
+            // set the colors
+            if (mFilters != null) {
+                for (LogFilter f : mFilters) {
+                    f.setColors(mColors);
+                }
+            }
+
+            if (mFilterStorage.requiresDefaultFilter()) {
+                mDefaultFilter = new LogFilter("Log");
+                mDefaultFilter.setColors(mColors);
+                mDefaultFilter.setSupportsDelete(false);
+                mDefaultFilter.setSupportsEdit(false);
+            }
+        } else if (mFilterMode == FILTER_NONE) {
+            // if the filtering mode is "none", we create a single filter that
+            // will receive all
+            mDefaultFilter = new LogFilter("Log");
+            mDefaultFilter.setColors(mColors);
+            mDefaultFilter.setSupportsDelete(false);
+            mDefaultFilter.setSupportsEdit(false);
+        }
+    }
+
+    /** Checks if there's an automatic filter for this md and if not
+     * adds the filter and the ui.
+     * This must be called from the UI!
+     * @param md
+     * @return true if the filter existed already
+     */
+    private boolean checkFilter(final LogMessageInfo md) {
+        if (true)
+            return true;
+        // look for a filter that matches the pid
+        if (mFilterMode == FILTER_AUTO_PID) {
+            for (LogFilter f : mFilters) {
+                if (f.getPidFilter() == md.pid) {
+                    return true;
+                }
+            }
+        } else if (mFilterMode == FILTER_AUTO_TAG) {
+            for (LogFilter f : mFilters) {
+                if (f.getTagFilter().equals(md.tag)) {
+                    return true;
+                }
+            }
+        }
+
+        // if we reach this point, no filter was found.
+        // create a filter with a temporary name of the pid
+        final LogFilter newFilter = new LogFilter(md.pidString);
+        String name = null;
+        if (mFilterMode == FILTER_AUTO_PID) {
+            newFilter.setPidMode(md.pid);
+
+            // ask the monitor thread if it knows the pid.
+            name = mCurrentLoggedDevice.getClientName(md.pid);
+        } else {
+            newFilter.setTagMode(md.tag);
+            name = md.tag;
+        }
+        addFilterToArray(newFilter);
+
+        final String fname = name;
+
+        // create the tabitem
+        final TabItem newTabItem = createTab(newFilter, -1, true);
+
+        // if the name is unknown
+        if (fname == null) {
+            // we need to find the process running under that pid.
+            // launch a thread do a ps on the device
+            new Thread("remote PS") { //$NON-NLS-1$
+                @Override
+                public void run() {
+                    // create the receiver
+                    PsOutputReceiver psor = new PsOutputReceiver(md.pid,
+                            newFilter, newTabItem);
+
+                    // execute ps
+                    try {
+                        mCurrentLoggedDevice.executeShellCommand("ps", psor); //$NON-NLS-1$
+                    } catch (IOException e) {
+                        // hmm...
+                    }
+                }
+            }.start();
+        }
+
+        return false;
+    }
+
+    /**
+     * Adds a new filter to the current filter array, and set its colors
+     * @param newFilter The filter to add
+     */
+    private void addFilterToArray(LogFilter newFilter) {
+        // set the colors
+        newFilter.setColors(mColors);
+
+        // add it to the array.
+        if (mFilters != null && mFilters.length > 0) {
+            LogFilter[] newFilters = new LogFilter[mFilters.length+1];
+            System.arraycopy(mFilters, 0, newFilters, 0, mFilters.length);
+            newFilters[mFilters.length] = newFilter;
+            mFilters = newFilters;
+        } else {
+            mFilters = new LogFilter[1];
+            mFilters[0] = newFilter;
+        }
+    }
+
+    private void removeFilterFromArray(LogFilter oldFilter) {
+        // look for the index
+        int index = -1;
+        for (int i = 0 ; i < mFilters.length ; i++) {
+            if (mFilters[i] == oldFilter) {
+                index = i;
+                break;
+            }
+        }
+
+        if (index != -1) {
+            LogFilter[] newFilters = new LogFilter[mFilters.length-1];
+            System.arraycopy(mFilters, 0, newFilters, 0, index);
+            System.arraycopy(mFilters, index + 1, newFilters, index,
+                    newFilters.length-index);
+            mFilters = newFilters;
+        }
+    }
+
+    /**
+     * Initialize the filter with already existing buffer.
+     * @param filter
+     */
+    private void initFilter(LogFilter filter) {
+        // is it empty
+        if (filter.uiReady() == false) {
+            return;
+        }
+
+        if (filter == mDefaultFilter) {
+            initDefaultFilter();
+            return;
+        }
+        
+        filter.clear();
+
+        if (mBufferStart != -1) {
+            int max = mBufferEnd;
+            if (mBufferEnd < mBufferStart) {
+                max += STRING_BUFFER_LENGTH;
+            }
+
+            for (int i = mBufferStart; i < max; i++) {
+                int realItemIndex = i % STRING_BUFFER_LENGTH;
+
+                filter.addMessage(mBuffer[realItemIndex], null /* old message */);
+            }
+        }
+
+        filter.flush();
+        filter.resetTempFilteringStatus();
+    }
+
+    /**
+     * Refill the default filter. Not to be called directly.
+     * @see initFilter()
+     */
+    private void initDefaultFilter() {
+        mDefaultFilter.clear();
+
+        if (mBufferStart != -1) {
+            int max = mBufferEnd;
+            if (mBufferEnd < mBufferStart) {
+                max += STRING_BUFFER_LENGTH;
+            }
+
+            for (int i = mBufferStart; i < max; i++) {
+                int realItemIndex = i % STRING_BUFFER_LENGTH;
+                LogMessage msg = mBuffer[realItemIndex];
+
+                // first we check that the other filters don't take this message
+                boolean filtered = false;
+                for (LogFilter f : mFilters) {
+                    filtered |= f.accept(msg);
+                }
+
+                if (filtered == false) {
+                    mDefaultFilter.addMessage(msg, null /* old message */);
+                }
+            }
+        }
+
+        mDefaultFilter.flush();
+        mDefaultFilter.resetTempFilteringStatus();
+    }
+
+    /**
+     * Reset the filters, to handle change in device in automatic filter mode
+     */
+    private void resetFilters() {
+        // if we are in automatic mode, then we need to rmove the current
+        // filter.
+        if (mFilterMode == FILTER_AUTO_PID || mFilterMode == FILTER_AUTO_TAG) {
+            mFilters = null;
+
+            // recreate the filters.
+            createFilters();
+        }
+    }
+
+
+    private LogFilter getCurrentFilter() {
+        int index = mFolders.getSelectionIndex();
+
+        // if mFilters is null or index is invalid, we return the default
+        // filter. It doesn't matter if that one is null as well, since we
+        // would return null anyway.
+        if (index == 0 || mFilters == null) {
+            return mDefaultFilter;
+        }
+
+        return mFilters[index-1];
+    }
+
+
+    private void emptyTables() {
+        for (LogFilter f : mFilters) {
+            f.getTable().removeAll();
+        }
+
+        if (mDefaultFilter != null) {
+            mDefaultFilter.getTable().removeAll();
+        }
+    }
+
+    protected void updateFilteringWith(String text) {
+        synchronized (mBuffer) {
+            // reset the temp filtering for all the filters
+            for (LogFilter f : mFilters) {
+                f.resetTempFiltering();
+            }
+            if (mDefaultFilter != null) {
+                mDefaultFilter.resetTempFiltering();
+            }
+    
+            // now we need to figure out the new temp filtering
+            // split each word
+            String[] segments = text.split(" "); //$NON-NLS-1$
+    
+            ArrayList<String> keywords = new ArrayList<String>(segments.length);
+    
+            // loop and look for temp id/tag
+            int tempPid = -1;
+            String tempTag = null;
+            for (int i = 0 ; i < segments.length; i++) {
+                String s = segments[i];
+                if (tempPid == -1 && s.startsWith("pid:")) { //$NON-NLS-1$
+                    // get the pid
+                    String[] seg = s.split(":"); //$NON-NLS-1$
+                    if (seg.length == 2) {
+                        if (seg[1].matches("^[0-9]*$")) { //$NON-NLS-1$
+                            tempPid = Integer.valueOf(seg[1]);
+                        }
+                    }
+                } else if (tempTag == null && s.startsWith("tag:")) { //$NON-NLS-1$
+                    String seg[] = segments[i].split(":"); //$NON-NLS-1$
+                    if (seg.length == 2) {
+                        tempTag = seg[1];
+                    }
+                } else {
+                    keywords.add(s);
+                }
+            }
+    
+            // set the temp filtering in the filters
+            if (tempPid != -1 || tempTag != null || keywords.size() > 0) {
+                String[] keywordsArray = keywords.toArray(
+                        new String[keywords.size()]);
+    
+                for (LogFilter f : mFilters) {
+                    if (tempPid != -1) {
+                        f.setTempPidFiltering(tempPid);
+                    }
+                    if (tempTag != null) {
+                        f.setTempTagFiltering(tempTag);
+                    }
+                    f.setTempKeywordFiltering(keywordsArray);
+                }
+    
+                if (mDefaultFilter != null) {
+                    if (tempPid != -1) {
+                        mDefaultFilter.setTempPidFiltering(tempPid);
+                    }
+                    if (tempTag != null) {
+                        mDefaultFilter.setTempTagFiltering(tempTag);
+                    }
+                    mDefaultFilter.setTempKeywordFiltering(keywordsArray);
+    
+                }
+            }
+    
+            initFilter(mCurrentFilter);
+        }
+    }
+
+    /**
+     * Called when the current filter selection changes.
+     * @param selectedFilter
+     */
+    private void selectionChanged(LogFilter selectedFilter) {
+        if (mLogLevelActions != null) {
+            // get the log level
+            int level = selectedFilter.getLogLevel();
+            for (int i = 0 ; i < mLogLevelActions.length; i++) {
+                ICommonAction a = mLogLevelActions[i];
+                if (i == level - 2) {
+                    a.setChecked(true);
+                } else {
+                    a.setChecked(false);
+                }
+            }
+        }
+
+        if (mDeleteFilterAction != null) {
+            mDeleteFilterAction.setEnabled(selectedFilter.supportsDelete());
+        }
+        if (mEditFilterAction != null) {
+            mEditFilterAction.setEnabled(selectedFilter.supportsEdit());
+        }
+    }
+}
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/add.png b/tools/ddms/libs/ddmuilib/src/resources/images/add.png
new file mode 100644
index 0000000..eefc2ca
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/add.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/android.png b/tools/ddms/libs/ddmuilib/src/resources/images/android.png
new file mode 100644
index 0000000..3779d4d
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/android.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/backward.png b/tools/ddms/libs/ddmuilib/src/resources/images/backward.png
new file mode 100644
index 0000000..90a9713
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/backward.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/clear.png b/tools/ddms/libs/ddmuilib/src/resources/images/clear.png
new file mode 100644
index 0000000..0009cf6
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/clear.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/d.png b/tools/ddms/libs/ddmuilib/src/resources/images/d.png
new file mode 100644
index 0000000..d45506e
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/d.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/debug-attach.png b/tools/ddms/libs/ddmuilib/src/resources/images/debug-attach.png
new file mode 100644
index 0000000..9b8a11c
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/debug-attach.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/debug-error.png b/tools/ddms/libs/ddmuilib/src/resources/images/debug-error.png
new file mode 100644
index 0000000..f22da1f
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/debug-error.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/debug-wait.png b/tools/ddms/libs/ddmuilib/src/resources/images/debug-wait.png
new file mode 100644
index 0000000..322be63
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/debug-wait.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/delete.png b/tools/ddms/libs/ddmuilib/src/resources/images/delete.png
new file mode 100644
index 0000000..db5fab8
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/delete.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/device.png b/tools/ddms/libs/ddmuilib/src/resources/images/device.png
new file mode 100644
index 0000000..7dbbbb6
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/device.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/down.png b/tools/ddms/libs/ddmuilib/src/resources/images/down.png
new file mode 100644
index 0000000..f9426cb
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/down.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/e.png b/tools/ddms/libs/ddmuilib/src/resources/images/e.png
new file mode 100644
index 0000000..dee7c97
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/e.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/edit.png b/tools/ddms/libs/ddmuilib/src/resources/images/edit.png
new file mode 100644
index 0000000..b8f65bc
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/edit.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/empty.png b/tools/ddms/libs/ddmuilib/src/resources/images/empty.png
new file mode 100644
index 0000000..f021542
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/empty.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/emulator.png b/tools/ddms/libs/ddmuilib/src/resources/images/emulator.png
new file mode 100644
index 0000000..a718042
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/emulator.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/file.png b/tools/ddms/libs/ddmuilib/src/resources/images/file.png
new file mode 100644
index 0000000..043a814
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/file.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/folder.png b/tools/ddms/libs/ddmuilib/src/resources/images/folder.png
new file mode 100644
index 0000000..7e29b1a
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/folder.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/forward.png b/tools/ddms/libs/ddmuilib/src/resources/images/forward.png
new file mode 100644
index 0000000..a97a605
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/forward.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/gc.png b/tools/ddms/libs/ddmuilib/src/resources/images/gc.png
new file mode 100644
index 0000000..5194806
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/gc.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/halt.png b/tools/ddms/libs/ddmuilib/src/resources/images/halt.png
new file mode 100644
index 0000000..10e3720
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/halt.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/heap.png b/tools/ddms/libs/ddmuilib/src/resources/images/heap.png
new file mode 100644
index 0000000..e3aa3f0
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/heap.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/i.png b/tools/ddms/libs/ddmuilib/src/resources/images/i.png
new file mode 100644
index 0000000..98385c5
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/i.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/importBug.png b/tools/ddms/libs/ddmuilib/src/resources/images/importBug.png
new file mode 100644
index 0000000..f5da179
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/importBug.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/load.png b/tools/ddms/libs/ddmuilib/src/resources/images/load.png
new file mode 100644
index 0000000..9e7bf6e
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/load.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/pause.png b/tools/ddms/libs/ddmuilib/src/resources/images/pause.png
new file mode 100644
index 0000000..19d286d
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/pause.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/play.png b/tools/ddms/libs/ddmuilib/src/resources/images/play.png
new file mode 100644
index 0000000..d54f013
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/play.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/pull.png b/tools/ddms/libs/ddmuilib/src/resources/images/pull.png
new file mode 100644
index 0000000..f48f1b1
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/pull.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/push.png b/tools/ddms/libs/ddmuilib/src/resources/images/push.png
new file mode 100644
index 0000000..6222864
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/push.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/save.png b/tools/ddms/libs/ddmuilib/src/resources/images/save.png
new file mode 100644
index 0000000..040ebda
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/save.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/thread.png b/tools/ddms/libs/ddmuilib/src/resources/images/thread.png
new file mode 100644
index 0000000..ac839e8
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/thread.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/up.png b/tools/ddms/libs/ddmuilib/src/resources/images/up.png
new file mode 100644
index 0000000..92edf5a
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/up.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/v.png b/tools/ddms/libs/ddmuilib/src/resources/images/v.png
new file mode 100644
index 0000000..8044051
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/v.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/w.png b/tools/ddms/libs/ddmuilib/src/resources/images/w.png
new file mode 100644
index 0000000..129d0f9
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/w.png
Binary files differ
diff --git a/tools/ddms/libs/ddmuilib/src/resources/images/warning.png b/tools/ddms/libs/ddmuilib/src/resources/images/warning.png
new file mode 100644
index 0000000..ca3b6ed
--- /dev/null
+++ b/tools/ddms/libs/ddmuilib/src/resources/images/warning.png
Binary files differ
diff --git a/tools/draw9patch/Android.mk b/tools/draw9patch/Android.mk
new file mode 100644
index 0000000..934495d
--- /dev/null
+++ b/tools/draw9patch/Android.mk
@@ -0,0 +1,17 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+DRAW9PATCH_LOCAL_DIR := $(call my-dir)
+include $(DRAW9PATCH_LOCAL_DIR)/etc/Android.mk
+include $(DRAW9PATCH_LOCAL_DIR)/src/Android.mk
diff --git a/tools/draw9patch/MODULE_LICENSE_APACHE2 b/tools/draw9patch/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/draw9patch/MODULE_LICENSE_APACHE2
diff --git a/tools/draw9patch/etc/Android.mk b/tools/draw9patch/etc/Android.mk
new file mode 100644
index 0000000..8d7d080
--- /dev/null
+++ b/tools/draw9patch/etc/Android.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_EXECUTABLES := draw9patch
+include $(BUILD_HOST_PREBUILT)
+
diff --git a/tools/draw9patch/etc/draw9patch b/tools/draw9patch/etc/draw9patch
new file mode 100755
index 0000000..5d272a6
--- /dev/null
+++ b/tools/draw9patch/etc/draw9patch
@@ -0,0 +1,63 @@
+#!/bin/sh
+# Copyright 2008, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+    newProg=`/bin/ls -ld "${prog}"`
+    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+    if expr "x${newProg}" : 'x/' >/dev/null; then
+        prog="${newProg}"
+    else
+        progdir=`dirname "${prog}"`
+        prog="${progdir}/${newProg}"
+    fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+jarfile=draw9patch.jar
+frameworkdir="$progdir"
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/tools/lib
+    libdir=`dirname "$progdir"`/tools/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/framework
+    libdir=`dirname "$progdir"`/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    echo `basename "$prog"`": can't find $jarfile"
+    exit 1
+fi
+
+if [ "$OSTYPE" = "cygwin" ] ; then
+    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
+    progdir=`cygpath -w  "$progdir"`
+else
+    jarpath="$frameworkdir/$jarfile"
+fi
+
+# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
+# might need more memory, e.g. -Xmx128M
+exec java -Djava.ext.dirs="$frameworkdir" -jar "$jarpath" "$@"
diff --git a/tools/draw9patch/etc/draw9patch.bat b/tools/draw9patch/etc/draw9patch.bat
new file mode 100755
index 0000000..e267b06
--- /dev/null
+++ b/tools/draw9patch/etc/draw9patch.bat
@@ -0,0 +1,41 @@
+@echo off
+rem Copyright (C) 2008 The Android Open Source Project
+rem
+rem Licensed under the Apache License, Version 2.0 (the "License");
+rem you may not use this file except in compliance with the License.
+rem You may obtain a copy of the License at
+rem
+rem      http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+
+rem don't modify the caller's environment
+setlocal
+
+rem Set up prog to be the path of this script, including following symlinks,
+rem and set up progdir to be the fully-qualified pathname of its directory.
+set prog=%~f0
+
+rem Change current directory and drive to where the script is, to avoid
+rem issues with directories containing whitespaces.
+cd /d %~dp0
+
+set jarfile=draw9patch.jar
+set frameworkdir=
+set libdir=
+
+if exist %frameworkdir%%jarfile% goto JarFileOk
+    set frameworkdir=lib\
+
+if exist %frameworkdir%%jarfile% goto JarFileOk
+    set frameworkdir=..\framework\
+
+:JarFileOk
+
+set jarpath=%frameworkdir%%jarfile%
+
+call java -Djava.ext.dirs=%frameworkdir% -jar %jarpath% %*
diff --git a/tools/draw9patch/etc/manifest.txt b/tools/draw9patch/etc/manifest.txt
new file mode 100644
index 0000000..b2e3528
--- /dev/null
+++ b/tools/draw9patch/etc/manifest.txt
@@ -0,0 +1,2 @@
+Main-Class: com.android.draw9patch.Application
+Class-Path: swing-worker-1.1.jar
diff --git a/tools/draw9patch/src/Android.mk b/tools/draw9patch/src/Android.mk
new file mode 100644
index 0000000..3dc9db4
--- /dev/null
+++ b/tools/draw9patch/src/Android.mk
@@ -0,0 +1,26 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_JAVA_RESOURCE_DIRS := resources
+
+LOCAL_JAR_MANIFEST := ../etc/manifest.txt
+LOCAL_JAVA_LIBRARIES := \
+	swing-worker-1.1
+LOCAL_MODULE := draw9patch
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/draw9patch/src/com/android/draw9patch/Application.java b/tools/draw9patch/src/com/android/draw9patch/Application.java
new file mode 100644
index 0000000..c7c6aaf
--- /dev/null
+++ b/tools/draw9patch/src/com/android/draw9patch/Application.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.draw9patch;
+
+import com.android.draw9patch.ui.MainFrame;
+
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+
+public class Application {
+    private static void initUserInterface() {
+        System.setProperty("apple.laf.useScreenMenuBar", "true");
+        System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Draw 9-patch");
+
+        try {
+            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+        } catch (InstantiationException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        } catch (UnsupportedLookAndFeelException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void main(String... args) {
+        initUserInterface();
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                MainFrame frame = new MainFrame();
+                frame.setDefaultCloseOperation(MainFrame.EXIT_ON_CLOSE);
+                frame.setLocationRelativeTo(null);
+                frame.setVisible(true);
+            }
+        });
+    }
+}
diff --git a/tools/draw9patch/src/com/android/draw9patch/graphics/GraphicsUtilities.java b/tools/draw9patch/src/com/android/draw9patch/graphics/GraphicsUtilities.java
new file mode 100644
index 0000000..c6c182c
--- /dev/null
+++ b/tools/draw9patch/src/com/android/draw9patch/graphics/GraphicsUtilities.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.draw9patch.graphics;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Graphics;
+import java.awt.Transparency;
+import java.net.URL;
+import java.io.IOException;
+
+public class GraphicsUtilities {
+    public static BufferedImage loadCompatibleImage(URL resource) throws IOException {
+        BufferedImage image = ImageIO.read(resource);
+        return toCompatibleImage(image);
+    }
+
+    public static BufferedImage createCompatibleImage(int width, int height) {
+        return getGraphicsConfiguration().createCompatibleImage(width, height);
+    }
+
+    public static BufferedImage toCompatibleImage(BufferedImage image) {
+        if (isHeadless()) {
+            return image;
+        }
+
+        if (image.getColorModel().equals(getGraphicsConfiguration().getColorModel())) {
+            return image;
+        }
+
+        BufferedImage compatibleImage = getGraphicsConfiguration().createCompatibleImage(
+                    image.getWidth(), image.getHeight(), image.getTransparency());
+        Graphics g = compatibleImage.getGraphics();
+        g.drawImage(image, 0, 0, null);
+        g.dispose();
+
+        return compatibleImage;
+    }
+
+    public static BufferedImage createCompatibleImage(BufferedImage image, int width, int height) {
+        return getGraphicsConfiguration().createCompatibleImage(width, height,
+                                                   image.getTransparency());
+    }
+
+    private static GraphicsConfiguration getGraphicsConfiguration() {
+        GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
+        return environment.getDefaultScreenDevice().getDefaultConfiguration();
+    }
+
+    private static boolean isHeadless() {
+        return GraphicsEnvironment.isHeadless();
+    }
+
+    public static BufferedImage createTranslucentCompatibleImage(int width, int height) {
+        return getGraphicsConfiguration().createCompatibleImage(width, height,
+                Transparency.TRANSLUCENT);
+    }
+
+    public static int[] getPixels(BufferedImage img, int x, int y, int w, int h, int[] pixels) {
+        if (w == 0 || h == 0) {
+            return new int[0];
+        }
+
+        if (pixels == null) {
+            pixels = new int[w * h];
+        } else if (pixels.length < w * h) {
+            throw new IllegalArgumentException("Pixels array must have a length >= w * h");
+        }
+
+        int imageType = img.getType();
+        if (imageType == BufferedImage.TYPE_INT_ARGB || imageType == BufferedImage.TYPE_INT_RGB) {
+            Raster raster = img.getRaster();
+            return (int[]) raster.getDataElements(x, y, w, h, pixels);
+        }
+
+        // Unmanages the image
+        return img.getRGB(x, y, w, h, pixels, 0, w);
+    }
+}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/GradientPanel.java b/tools/draw9patch/src/com/android/draw9patch/ui/GradientPanel.java
new file mode 100644
index 0000000..bc1465f
--- /dev/null
+++ b/tools/draw9patch/src/com/android/draw9patch/ui/GradientPanel.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.draw9patch.ui;
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Paint;
+import java.awt.GradientPaint;
+import java.awt.Color;
+import java.awt.Rectangle;
+import java.awt.BorderLayout;
+import javax.swing.JPanel;
+
+class GradientPanel extends JPanel {
+    private static final int DARK_BLUE = 0x202737;
+
+    GradientPanel() {
+        super(new BorderLayout());
+    }
+
+    @Override
+    protected void paintComponent(Graphics g) {
+        Graphics2D g2 = (Graphics2D) g;
+        Rectangle clip = g2.getClipBounds();
+        Paint paint = g2.getPaint();
+
+        g2.setPaint(new GradientPaint(0.0f, getHeight() * 0.22f, new Color(DARK_BLUE),
+                                      0.0f, getHeight() * 0.9f, Color.BLACK));
+        g2.fillRect(clip.x, clip.y, clip.width, clip.height);
+
+        g2.setPaint(paint);
+    }
+}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/ImageEditorPanel.java b/tools/draw9patch/src/com/android/draw9patch/ui/ImageEditorPanel.java
new file mode 100644
index 0000000..86c801f
--- /dev/null
+++ b/tools/draw9patch/src/com/android/draw9patch/ui/ImageEditorPanel.java
@@ -0,0 +1,1129 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.draw9patch.ui;
+
+import com.android.draw9patch.graphics.GraphicsUtilities;
+
+import javax.swing.JPanel;
+import javax.swing.JLabel;
+import javax.swing.BorderFactory;
+import javax.swing.JSlider;
+import javax.swing.JComponent;
+import javax.swing.JScrollPane;
+import javax.swing.JCheckBox;
+import javax.swing.Box;
+import javax.swing.JFileChooser;
+import javax.swing.JSplitPane;
+import javax.swing.JButton;
+import javax.swing.border.EmptyBorder;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.ChangeEvent;
+import java.awt.image.BufferedImage;
+import java.awt.image.RenderedImage;
+import java.awt.Graphics2D;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Dimension;
+import java.awt.TexturePaint;
+import java.awt.Shape;
+import java.awt.BasicStroke;
+import java.awt.RenderingHints;
+import java.awt.Rectangle;
+import java.awt.GridBagLayout;
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+import java.awt.Toolkit;
+import java.awt.AWTEvent;
+import java.awt.event.MouseMotionAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.AWTEventListener;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.Line2D;
+import java.awt.geom.Area;
+import java.awt.geom.RoundRectangle2D;
+import java.io.IOException;
+import java.io.File;
+import java.net.URL;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+class ImageEditorPanel extends JPanel {
+    private static final String EXTENSION_9PATCH = ".9.png";
+    private static final int DEFAULT_ZOOM = 8;
+    private static final float DEFAULT_SCALE = 2.0f;
+
+    private String name;
+    private BufferedImage image;
+    private boolean is9Patch;
+
+    private ImageViewer viewer;
+    private StretchesViewer stretchesViewer;
+    private JLabel xLabel;
+    private JLabel yLabel;
+
+    private TexturePaint texture;    
+
+    private List<Rectangle> patches;
+    private List<Rectangle> horizontalPatches;
+    private List<Rectangle> verticalPatches;
+    private List<Rectangle> fixed;
+    private boolean verticalStartWithPatch;
+    private boolean horizontalStartWithPatch;
+
+    private Pair<Integer> horizontalPadding;
+    private Pair<Integer> verticalPadding;    
+
+    ImageEditorPanel(MainFrame mainFrame, BufferedImage image, String name) {
+        this.image = image;
+        this.name = name;
+
+        setTransferHandler(new ImageTransferHandler(mainFrame));
+
+        checkImage();
+
+        setOpaque(false);
+        setLayout(new BorderLayout());
+
+        loadSupport();
+        buildImageViewer();
+        buildStatusPanel();
+    }
+
+    private void loadSupport() {
+        try {
+            URL resource = getClass().getResource("/images/checker.png");
+            BufferedImage checker = GraphicsUtilities.loadCompatibleImage(resource);
+            texture = new TexturePaint(checker, new Rectangle2D.Double(0, 0,
+                    checker.getWidth(), checker.getHeight()));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void buildImageViewer() {
+        viewer = new ImageViewer();
+
+        JSplitPane splitter = new JSplitPane();
+        splitter.setContinuousLayout(true);
+        splitter.setResizeWeight(0.8);
+        splitter.setBorder(null);
+
+        JScrollPane scroller = new JScrollPane(viewer);
+        scroller.setOpaque(false);
+        scroller.setBorder(null);
+        scroller.getViewport().setBorder(null);
+        scroller.getViewport().setOpaque(false);
+
+        splitter.setLeftComponent(scroller);
+        splitter.setRightComponent(buildStretchesViewer());
+
+        add(splitter);
+    }
+
+    private JComponent buildStretchesViewer() {
+        stretchesViewer = new StretchesViewer();
+        JScrollPane scroller = new JScrollPane(stretchesViewer);
+        scroller.setBorder(null);
+        scroller.getViewport().setBorder(null);
+        scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+        scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+        return scroller;
+    }
+
+    private void buildStatusPanel() {
+        JPanel status = new JPanel(new GridBagLayout());
+        status.setOpaque(false);
+
+        JLabel label = new JLabel();
+        label.setForeground(Color.WHITE);
+        label.setText("Zoom: ");
+        label.putClientProperty("JComponent.sizeVariant", "small");
+        status.add(label, new GridBagConstraints(0, 0, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_END, GridBagConstraints.NONE,
+                new Insets(0, 6, 0, 0), 0, 0));
+
+        label = new JLabel();
+        label.setForeground(Color.WHITE);
+        label.setText("100%");
+        label.putClientProperty("JComponent.sizeVariant", "small");
+        status.add(label, new GridBagConstraints(1, 0, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_END, GridBagConstraints.NONE,
+                new Insets(0, 0, 0, 0), 0, 0));
+
+        JSlider zoomSlider = new JSlider(1, 16, DEFAULT_ZOOM);
+        zoomSlider.setSnapToTicks(true);
+        zoomSlider.putClientProperty("JComponent.sizeVariant", "small");
+        zoomSlider.addChangeListener(new ChangeListener() {
+            public void stateChanged(ChangeEvent evt) {
+                viewer.setZoom(((JSlider) evt.getSource()).getValue());
+            }
+        });
+        status.add(zoomSlider, new GridBagConstraints(2, 0, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                new Insets(0, 0, 0, 0), 0, 0));
+
+        JLabel maxZoomLabel = new JLabel();
+        maxZoomLabel.setForeground(Color.WHITE);
+        maxZoomLabel.putClientProperty("JComponent.sizeVariant", "small");
+        maxZoomLabel.setText("800%");
+        status.add(maxZoomLabel, new GridBagConstraints(3, 0, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                new Insets(0, 0, 0, 0), 0, 0));
+
+        label = new JLabel();
+        label.setForeground(Color.WHITE);
+        label.setText("Patch scale: ");
+        label.putClientProperty("JComponent.sizeVariant", "small");
+        status.add(label, new GridBagConstraints(0, 1, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                new Insets(0, 6, 0, 0), 0, 0));
+
+        label = new JLabel();
+        label.setForeground(Color.WHITE);
+        label.setText("2x");
+        label.putClientProperty("JComponent.sizeVariant", "small");
+        status.add(label, new GridBagConstraints(1, 1, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_END, GridBagConstraints.NONE,
+                new Insets(0, 0, 0, 0), 0, 0));
+
+        zoomSlider = new JSlider(200, 600, (int) (DEFAULT_SCALE * 100.0f));
+        zoomSlider.setSnapToTicks(true);
+        zoomSlider.putClientProperty("JComponent.sizeVariant", "small");
+        zoomSlider.addChangeListener(new ChangeListener() {
+            public void stateChanged(ChangeEvent evt) {
+                stretchesViewer.setScale(((JSlider) evt.getSource()).getValue() / 100.0f);
+            }
+        });
+        status.add(zoomSlider, new GridBagConstraints(2, 1, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                new Insets(0, 0, 0, 0), 0, 0));
+
+        maxZoomLabel = new JLabel();
+        maxZoomLabel.setForeground(Color.WHITE);
+        maxZoomLabel.putClientProperty("JComponent.sizeVariant", "small");
+        maxZoomLabel.setText("6x");
+        status.add(maxZoomLabel, new GridBagConstraints(3, 1, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                new Insets(0, 0, 0, 0), 0, 0));
+
+        JCheckBox showLock = new JCheckBox("Show lock");
+        showLock.setOpaque(false);
+        showLock.setForeground(Color.WHITE);
+        showLock.setSelected(true);
+        showLock.putClientProperty("JComponent.sizeVariant", "small");
+        showLock.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                viewer.setLockVisible(((JCheckBox) event.getSource()).isSelected());
+            }
+        });
+        status.add(showLock, new GridBagConstraints(4, 0, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                new Insets(0, 12, 0, 0), 0, 0));
+
+        JCheckBox showPatches = new JCheckBox("Show patches");
+        showPatches.setOpaque(false);
+        showPatches.setForeground(Color.WHITE);
+        showPatches.putClientProperty("JComponent.sizeVariant", "small");
+        showPatches.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                viewer.setPatchesVisible(((JCheckBox) event.getSource()).isSelected());
+            }
+        });
+        status.add(showPatches, new GridBagConstraints(4, 1, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                new Insets(0, 12, 0, 0), 0, 0));
+
+        JCheckBox showPadding = new JCheckBox("Show content");
+        showPadding.setOpaque(false);
+        showPadding.setForeground(Color.WHITE);
+        showPadding.putClientProperty("JComponent.sizeVariant", "small");
+        showPadding.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                stretchesViewer.setPaddingVisible(((JCheckBox) event.getSource()).isSelected());
+            }
+        });
+        status.add(showPadding, new GridBagConstraints(5, 0, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                new Insets(0, 12, 0, 0), 0, 0));
+
+        status.add(Box.createHorizontalGlue(), new GridBagConstraints(6, 0, 1, 1, 1.0f, 1.0f,
+                GridBagConstraints.LINE_START, GridBagConstraints.BOTH,
+                new Insets(0, 0, 0, 0), 0, 0));
+
+        label = new JLabel("X: ");
+        label.setForeground(Color.WHITE);
+        label.putClientProperty("JComponent.sizeVariant", "small");
+        status.add(label, new GridBagConstraints(7, 0, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_END, GridBagConstraints.NONE,
+                new Insets(0, 0, 0, 0), 0, 0));
+
+        xLabel = new JLabel("0px");
+        xLabel.setForeground(Color.WHITE);
+        xLabel.putClientProperty("JComponent.sizeVariant", "small");
+        status.add(xLabel, new GridBagConstraints(8, 0, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_END, GridBagConstraints.NONE,
+                new Insets(0, 0, 0, 6), 0, 0));
+
+        label = new JLabel("Y: ");
+        label.setForeground(Color.WHITE);
+        label.putClientProperty("JComponent.sizeVariant", "small");
+        status.add(label, new GridBagConstraints(7, 1, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_END, GridBagConstraints.NONE,
+                new Insets(0, 0, 0, 0), 0, 0));
+
+        yLabel = new JLabel("0px");
+        yLabel.setForeground(Color.WHITE);
+        yLabel.putClientProperty("JComponent.sizeVariant", "small");
+        status.add(yLabel, new GridBagConstraints(8, 1, 1, 1, 0.0f, 0.0f,
+                GridBagConstraints.LINE_END, GridBagConstraints.NONE,
+                new Insets(0, 0, 0, 6), 0, 0));
+
+        add(status, BorderLayout.SOUTH);
+    }
+
+    private void checkImage() {
+        is9Patch = name.endsWith(EXTENSION_9PATCH);
+        if (!is9Patch) {
+            convertTo9Patch();
+        } else {
+            ensure9Patch();
+        }
+    }
+
+    private void ensure9Patch() {
+        int width = image.getWidth();
+        int height = image.getHeight();
+        for (int i = 0; i < width; i++) {
+            int pixel = image.getRGB(i, 0);
+            if (pixel != 0 && pixel != 0xFF000000) {
+                image.setRGB(i, 0, 0);
+            }
+            pixel = image.getRGB(i, height - 1);
+            if (pixel != 0 && pixel != 0xFF000000) {
+                image.setRGB(i, height - 1, 0);
+            }
+        }
+        for (int i = 0; i < height; i++) {
+            int pixel = image.getRGB(0, i);
+            if (pixel != 0 && pixel != 0xFF000000) {
+                image.setRGB(0, i, 0);
+            }
+            pixel = image.getRGB(width - 1, i);
+            if (pixel != 0 && pixel != 0xFF000000) {
+                image.setRGB(width - 1, i, 0);
+            }
+        }
+    }
+
+    private void convertTo9Patch() {
+        BufferedImage buffer = GraphicsUtilities.createTranslucentCompatibleImage(
+                image.getWidth() + 2, image.getHeight() + 2);
+
+        Graphics2D g2 = buffer.createGraphics();
+        g2.drawImage(image, 1, 1, null);
+        g2.dispose();
+
+        image = buffer;
+        name = name.substring(0, name.lastIndexOf('.')) + ".9.png";
+    }
+
+    File chooseSaveFile() {
+        if (is9Patch) {
+            return new File(name);
+        } else {
+            JFileChooser chooser = new JFileChooser();
+            chooser.setFileFilter(new PngFileFilter());
+            int choice = chooser.showSaveDialog(this);
+            if (choice == JFileChooser.APPROVE_OPTION) {
+                File file = chooser.getSelectedFile();
+                if (!file.getAbsolutePath().endsWith(EXTENSION_9PATCH)) {
+                    String path = file.getAbsolutePath();
+                    if (path.endsWith(".png")) {
+                        path = path.substring(0, path.lastIndexOf(".png")) + EXTENSION_9PATCH;
+                    } else {
+                        path = path + EXTENSION_9PATCH;
+                    }
+                    name = path;
+                    is9Patch = true;
+                    return new File(path);
+                }
+                is9Patch = true;
+                return file;
+            }
+        }
+        return null;
+    }
+
+    RenderedImage getImage() {
+        return image;
+    }
+
+    private class StretchesViewer extends JPanel {
+        private static final int MARGIN = 24;
+
+        private StretchView horizontal;
+        private StretchView vertical;
+        private StretchView both;
+
+        private Dimension size;
+
+        private float horizontalPatchesSum;
+        private float verticalPatchesSum;
+
+        private boolean showPadding;
+
+        StretchesViewer() {
+            setOpaque(false);
+            setLayout(new GridBagLayout());
+            setBorder(BorderFactory.createEmptyBorder(MARGIN, MARGIN, MARGIN, MARGIN));
+
+            horizontal = new StretchView();
+            vertical = new StretchView();
+            both = new StretchView();
+
+            setScale(DEFAULT_SCALE);
+            
+            add(vertical, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
+                    GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
+            add(horizontal, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
+                    GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
+            add(both, new GridBagConstraints(0, 2, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
+                    GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
+        }
+
+        @Override
+        protected void paintComponent(Graphics g) {
+            Graphics2D g2 = (Graphics2D) g.create();
+            g2.setPaint(texture);
+            g2.fillRect(0, 0, getWidth(), getHeight());
+            g2.dispose();
+        }
+
+        void setScale(float scale) {
+            int patchWidth = image.getWidth() - 2;
+            int patchHeight = image.getHeight() - 2;
+
+            int scaledWidth = (int) (patchWidth * scale);
+            int scaledHeight = (int) (patchHeight * scale);
+
+            horizontal.scaledWidth = scaledWidth;
+            vertical.scaledHeight = scaledHeight;
+            both.scaledWidth = scaledWidth;
+            both.scaledHeight = scaledHeight;
+
+            size = new Dimension(scaledWidth, scaledHeight);
+
+            computePatches();
+        }
+
+        void computePatches() {
+            boolean measuredWidth = false;
+            boolean endRow = true;
+
+            int remainderHorizontal = 0;
+            int remainderVertical = 0;
+
+            if (fixed.size() > 0) {
+                int start = fixed.get(0).y;
+                for (Rectangle rect : fixed) {
+                    if (rect.y > start) {
+                        endRow = true;
+                        measuredWidth = true;
+                    }
+                    if (!measuredWidth) {
+                        remainderHorizontal += rect.width;
+                    }
+                    if (endRow) {
+                        remainderVertical += rect.height;
+                        endRow = false;
+                        start = rect.y;
+                    }
+                }
+            }
+
+            horizontal.remainderHorizontal = horizontal.scaledWidth - remainderHorizontal;
+            vertical.remainderHorizontal = vertical.scaledWidth - remainderHorizontal;
+            both.remainderHorizontal = both.scaledWidth - remainderHorizontal;
+
+            horizontal.remainderVertical = horizontal.scaledHeight - remainderVertical;
+            vertical.remainderVertical = vertical.scaledHeight - remainderVertical;
+            both.remainderVertical = both.scaledHeight - remainderVertical;
+
+            horizontalPatchesSum = 0;
+            if (horizontalPatches.size() > 0) {
+                int start = -1;
+                for (Rectangle rect : horizontalPatches) {
+                    if (rect.x > start) {
+                        horizontalPatchesSum += rect.width;
+                        start = rect.x;
+                    }
+                }
+            }
+
+            verticalPatchesSum = 0;
+            if (verticalPatches.size() > 0) {
+                int start = -1;
+                for (Rectangle rect : verticalPatches) {
+                    if (rect.y > start) {
+                        verticalPatchesSum += rect.height;
+                        start = rect.y;
+                    }
+                }
+            }
+
+            setSize(size);
+            ImageEditorPanel.this.validate();
+            repaint();
+        }
+
+        void setPaddingVisible(boolean visible) {
+            showPadding = visible;
+            repaint();
+        }
+
+        private class StretchView extends JComponent {
+            private final Color PADDING_COLOR = new Color(0.37f, 0.37f, 1.0f, 0.5f);
+
+            int scaledWidth;
+            int scaledHeight;
+
+            int remainderHorizontal;
+            int remainderVertical;
+
+            StretchView() {
+                scaledWidth = image.getWidth();
+                scaledHeight = image.getHeight();
+            }
+
+            @Override
+            protected void paintComponent(Graphics g) {
+                int x = (getWidth() - scaledWidth) / 2;
+                int y = (getHeight() - scaledHeight) / 2;
+
+                Graphics2D g2 = (Graphics2D) g.create();
+                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+                        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+                g.translate(x, y);
+
+                x = 0;
+                y = 0;
+
+                if (patches.size() == 0 || horizontalPatches.size() == 0 ||
+                        verticalPatches.size() == 0) {
+                    g.drawImage(image, 0, 0, scaledWidth, scaledHeight, null);
+                    g2.dispose();
+                    return;
+                }
+
+                int fixedIndex = 0;
+                int horizontalIndex = 0;
+                int verticalIndex = 0;
+                int patchIndex = 0;
+
+                boolean hStretch;
+                boolean vStretch;
+
+                float vWeightSum = 1.0f;
+                float vRemainder = remainderVertical;
+
+                vStretch = verticalStartWithPatch;
+                while (y < scaledHeight - 1) {
+                    hStretch = horizontalStartWithPatch;
+
+                    int height = 0;
+                    float vExtra = 0.0f;
+
+                    float hWeightSum = 1.0f;
+                    float hRemainder = remainderHorizontal;
+
+                    while (x < scaledWidth - 1) {
+                        Rectangle r;
+                        if (!vStretch) {
+                            if (hStretch) {
+                                r = horizontalPatches.get(horizontalIndex++);
+                                float extra = r.width / horizontalPatchesSum;
+                                int width = (int) (extra * hRemainder / hWeightSum);
+                                hWeightSum -= extra;
+                                hRemainder -= width;
+                                g.drawImage(image, x, y, x + width, y + r.height, r.x, r.y,
+                                        r.x + r.width, r.y + r.height, null);
+                                x += width;
+                            } else {
+                                r = fixed.get(fixedIndex++);
+                                g.drawImage(image, x, y, x + r.width, y + r.height, r.x, r.y,
+                                        r.x + r.width, r.y + r.height, null);
+                                x += r.width;
+                            }
+                            height = r.height;
+                        } else {
+                            if (hStretch) {
+                                r = patches.get(patchIndex++);
+                                vExtra = r.height / verticalPatchesSum;
+                                height = (int) (vExtra * vRemainder / vWeightSum);
+                                float extra = r.width / horizontalPatchesSum;
+                                int width = (int) (extra * hRemainder / hWeightSum);
+                                hWeightSum -= extra;
+                                hRemainder -= width;
+                                g.drawImage(image, x, y, x + width, y + height, r.x, r.y,
+                                        r.x + r.width, r.y + r.height, null);
+                                x += width;
+                            } else {
+                                r = verticalPatches.get(verticalIndex++);
+                                vExtra = r.height / verticalPatchesSum;
+                                height = (int) (vExtra * vRemainder / vWeightSum);
+                                g.drawImage(image, x, y, x + r.width, y + height, r.x, r.y,
+                                        r.x + r.width, r.y + r.height, null);
+                                x += r.width;
+                            }
+                            
+                        }
+                        hStretch = !hStretch;
+                    }
+                    x = 0;
+                    y += height;
+                    if (vStretch) {
+                        vWeightSum -= vExtra;
+                        vRemainder -= height;
+                    }
+                    vStretch = !vStretch;
+                }
+
+                if (showPadding) {
+                    g.setColor(PADDING_COLOR);
+                    g.fillRect(horizontalPadding.first, verticalPadding.first,
+                            scaledWidth - horizontalPadding.first - horizontalPadding.second,
+                            scaledHeight - verticalPadding.first - verticalPadding.second);
+                }
+
+                g2.dispose();
+            }
+
+            @Override
+            public Dimension getPreferredSize() {
+                return size;
+            }
+        }
+    }
+
+    private class ImageViewer extends JComponent {
+        private final Color CORRUPTED_COLOR = new Color(1.0f, 0.0f, 0.0f, 0.7f);
+        private final Color LOCK_COLOR = new Color(0.0f, 0.0f, 0.0f, 0.7f);
+        private final Color STRIPES_COLOR = new Color(1.0f, 0.0f, 0.0f, 0.5f);
+        private final Color BACK_COLOR = new Color(0xc0c0c0);
+        private final Color HELP_COLOR = new Color(0xffffe1);
+        private final Color PATCH_COLOR = new Color(1.0f, 0.37f, 0.99f, 0.5f);
+        private final Color PATCH_ONEWAY_COLOR = new Color(0.37f, 1.0f, 0.37f, 0.5f);
+
+        private static final float STRIPES_WIDTH = 4.0f;
+        private static final double STRIPES_SPACING = 6.0;
+        private static final int STRIPES_ANGLE = 45;
+
+        private int zoom;
+        private boolean showPatches;
+        private boolean showLock = true;
+
+        private Dimension size;
+
+        private boolean locked;
+
+        private int[] row;
+        private int[] column;
+
+        private int lastPositionX;
+        private int lastPositionY;
+        private boolean showCursor;
+
+        private JLabel helpLabel;
+        private boolean eraseMode;
+
+        private JButton checkButton;
+        private List<Rectangle> corruptedPatches;
+        private boolean showBadPatches;
+
+        private JPanel helpPanel;
+
+        ImageViewer() {
+            setLayout(new GridBagLayout());
+            helpPanel = new JPanel(new BorderLayout());
+            helpPanel.setBorder(new EmptyBorder(0, 6, 0, 6));
+            helpPanel.setBackground(HELP_COLOR);
+            helpLabel = new JLabel("Press Shift to erase pixels");
+            helpLabel.putClientProperty("JComponent.sizeVariant", "small");            
+            helpPanel.add(helpLabel, BorderLayout.WEST);
+            checkButton = new JButton("Show bad patches");
+            checkButton.putClientProperty("JComponent.sizeVariant", "small");
+            checkButton.putClientProperty("JButton.buttonType", "roundRect");
+            helpPanel.add(checkButton, BorderLayout.EAST);
+
+            add(helpPanel, new GridBagConstraints(0, 0, 1, 1,
+                    1.0f, 1.0f, GridBagConstraints.FIRST_LINE_START, GridBagConstraints.HORIZONTAL,
+                    new Insets(0, 0, 0, 0), 0, 0));
+
+            setOpaque(true);
+
+            setZoom(DEFAULT_ZOOM);
+            findPatches();
+
+            addMouseListener(new MouseAdapter() {
+                @Override
+                public void mousePressed(MouseEvent event) {
+                    paint(event.getX(), event.getY(), event.isShiftDown() ? MouseEvent.BUTTON3 :
+                                event.getButton());
+                }
+            });
+            addMouseMotionListener(new MouseMotionAdapter() {
+                @Override
+                public void mouseDragged(MouseEvent event) {
+                    if (!checkLockedRegion(event.getX(), event.getY())) {
+                        paint(event.getX(), event.getY(), event.isShiftDown() ? MouseEvent.BUTTON3 :
+                                event.getButton());
+                    }
+                }
+
+                @Override
+                public void mouseMoved(MouseEvent event) {
+                    checkLockedRegion(event.getX(), event.getY());
+                }
+            });
+            Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
+                public void eventDispatched(AWTEvent event) {
+                    enableEraseMode((KeyEvent) event);                    
+                }
+            }, AWTEvent.KEY_EVENT_MASK);
+
+            checkButton.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent event) {
+                    if (!showBadPatches) {
+                        findBadPatches();
+                        checkButton.setText("Hide bad patches");
+                    } else {
+                        checkButton.setText("Show bad patches");
+                        corruptedPatches = null;
+                    }
+                    repaint();
+                    showBadPatches = !showBadPatches;
+                }
+            });
+        }
+
+        private void findBadPatches() {
+            corruptedPatches = new ArrayList<Rectangle>();
+
+            for (Rectangle patch : patches) {
+                if (corruptPatch(patch)) {
+                    corruptedPatches.add(patch);
+                }
+            }
+
+            for (Rectangle patch : horizontalPatches) {
+                if (corruptHorizontalPatch(patch)) {
+                    corruptedPatches.add(patch);
+                }
+            }
+
+            for (Rectangle patch : verticalPatches) {
+                if (corruptVerticalPatch(patch)) {
+                    corruptedPatches.add(patch);
+                }
+            }
+        }
+
+        private boolean corruptPatch(Rectangle patch) {
+            int[] pixels = GraphicsUtilities.getPixels(image, patch.x, patch.y,
+                    patch.width, patch.height, null);
+
+            if (pixels.length > 0) {
+                int reference = pixels[0];
+                for (int pixel : pixels) {
+                    if (pixel != reference) {
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        private boolean corruptHorizontalPatch(Rectangle patch) {
+            int[] reference = new int[patch.height];
+            int[] column = new int[patch.height];
+            reference = GraphicsUtilities.getPixels(image, patch.x, patch.y,
+                    1, patch.height, reference);
+
+            for (int i = 1; i < patch.width; i++) {
+                column = GraphicsUtilities.getPixels(image, patch.x + i, patch.y,
+                        1, patch.height, column);
+                if (!Arrays.equals(reference, column)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        private boolean corruptVerticalPatch(Rectangle patch) {
+            int[] reference = new int[patch.width];
+            int[] row = new int[patch.width];
+            reference = GraphicsUtilities.getPixels(image, patch.x, patch.y,
+                    patch.width, 1, reference);
+
+            for (int i = 1; i < patch.height; i++) {
+                row = GraphicsUtilities.getPixels(image, patch.x, patch.y + i, patch.width, 1, row);
+                if (!Arrays.equals(reference, row)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        private void enableEraseMode(KeyEvent event) {
+            boolean oldEraseMode = eraseMode;
+            eraseMode = event.isShiftDown();
+            if (eraseMode != oldEraseMode) {
+                if (eraseMode) {
+                    helpLabel.setText("Release Shift to draw pixels");
+                } else {
+                    helpLabel.setText("Press Shift to erase pixels");
+                }
+            }
+        }
+
+        private void paint(int x, int y, int button) {
+            int color;
+            switch (button) {
+                case MouseEvent.BUTTON1:
+                    color = 0xFF000000;
+                    break;
+                case MouseEvent.BUTTON3:
+                    color = 0;
+                    break;
+                default:
+                    return;
+            }
+
+            int left = (getWidth() - size.width) / 2;
+            int top = (helpPanel.getHeight() + getHeight() - size.height) / 2;
+
+            x = (x - left) / zoom;
+            y = (y - top) / zoom;
+
+            int width = image.getWidth();
+            int height = image.getHeight();
+            if (((x == 0 || x == width - 1) && (y > 0 && y < height - 1)) ||
+                    ((x > 0 && x < width - 1) && (y == 0 || y == height - 1))) {
+                image.setRGB(x, y, color);
+                findPatches();
+                stretchesViewer.computePatches();
+                if (showBadPatches) {
+                    findBadPatches();
+                }
+                repaint();
+            }
+        }
+
+        private boolean checkLockedRegion(int x, int y) {
+            int oldX = lastPositionX;
+            int oldY = lastPositionY;
+            lastPositionX = x;
+            lastPositionY = y;
+
+            int left = (getWidth() - size.width) / 2;
+            int top = (helpPanel.getHeight() + getHeight() - size.height) / 2;
+
+            x = (x - left) / zoom;
+            y = (y - top) / zoom;
+
+            int width = image.getWidth();
+            int height = image.getHeight();
+
+            xLabel.setText(Math.max(0, Math.min(x, width - 1)) + " px");
+            yLabel.setText(Math.max(0, Math.min(y, height - 1)) + " px");
+
+            boolean previousLock = locked;
+            locked = x > 0 && x < width - 1 && y > 0 && y < height - 1;
+
+            boolean previousCursor = showCursor;
+            showCursor = ((x == 0 || x == width - 1) && (y > 0 && y < height - 1)) ||
+                    ((x > 0 && x < width - 1) && (y == 0 || y == height - 1));
+
+            if (locked != previousLock) {
+                repaint();
+            } else if (showCursor || (showCursor != previousCursor)) {
+                Rectangle clip = new Rectangle(lastPositionX - 1 - zoom / 2,
+                        lastPositionY - 1 - zoom / 2, zoom + 2, zoom + 2);
+                clip = clip.union(new Rectangle(oldX - 1 - zoom / 2,
+                        oldY - 1 - zoom / 2, zoom + 2, zoom + 2));
+                repaint(clip);
+            }
+
+            return locked;
+        }
+
+        @Override
+        protected void paintComponent(Graphics g) {
+            int x = (getWidth() - size.width) / 2;
+            int y = (helpPanel.getHeight() + getHeight() - size.height) / 2;
+
+            Graphics2D g2 = (Graphics2D) g.create();
+            g2.setColor(BACK_COLOR);
+            g2.fillRect(0, 0, getWidth(), getHeight());
+
+            g2.translate(x, y);
+            g2.setPaint(texture);
+            g2.fillRect(0, 0, size.width, size.height);
+            g2.scale(zoom, zoom);
+            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                    RenderingHints.VALUE_ANTIALIAS_ON);
+            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+                    RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
+            g2.drawImage(image, 0, 0, null);
+
+            if (showPatches) {
+                g2.setColor(PATCH_COLOR);
+                for (Rectangle patch : patches) {
+                    g2.fillRect(patch.x, patch.y, patch.width, patch.height);
+                }
+                g2.setColor(PATCH_ONEWAY_COLOR);
+                for (Rectangle patch : horizontalPatches) {
+                    g2.fillRect(patch.x, patch.y, patch.width, patch.height);
+                }
+                for (Rectangle patch : verticalPatches) {
+                    g2.fillRect(patch.x, patch.y, patch.width, patch.height);
+                }
+            }
+
+            if (corruptedPatches != null) {
+                g2.setColor(CORRUPTED_COLOR);
+                g2.setStroke(new BasicStroke(3.0f / zoom));
+                for (Rectangle patch : corruptedPatches) {
+                    g2.draw(new RoundRectangle2D.Float(patch.x - 2.0f / zoom, patch.y - 2.0f / zoom,
+                            patch.width + 2.0f / zoom, patch.height + 2.0f / zoom,
+                            6.0f / zoom, 6.0f / zoom));
+                }
+            }
+
+            if (showLock && locked) {
+                int width = image.getWidth();
+                int height = image.getHeight();
+
+                g2.setColor(LOCK_COLOR);
+                g2.fillRect(1, 1, width - 2, height - 2);
+
+                g2.setColor(STRIPES_COLOR);
+                g2.translate(1, 1);
+                paintStripes(g2, width - 2, height - 2);
+                g2.translate(-1, -1);
+            }
+
+            g2.dispose();
+
+            if (showCursor) {
+                Graphics cursor = g.create();
+                cursor.setXORMode(Color.WHITE);
+                cursor.setColor(Color.BLACK);
+                cursor.drawRect(lastPositionX - zoom / 2, lastPositionY - zoom / 2, zoom, zoom);
+                cursor.dispose();
+            }
+        }
+
+        private void paintStripes(Graphics2D g, int width, int height) {
+            //draws pinstripes at the angle specified in this class
+            //and at the given distance apart
+            Shape oldClip = g.getClip();
+            Area area = new Area(new Rectangle(0, 0, width, height));
+            if(oldClip != null) {
+                area = new Area(oldClip);
+            }
+            area.intersect(new Area(new Rectangle(0,0,width,height)));
+            g.setClip(area);
+
+            g.setStroke(new BasicStroke(STRIPES_WIDTH));
+
+            double hypLength = Math.sqrt((width * width) +
+                    (height * height));
+
+            double radians = Math.toRadians(STRIPES_ANGLE);
+            g.rotate(radians);
+
+            double spacing = STRIPES_SPACING;
+            spacing += STRIPES_WIDTH;
+            int numLines = (int)(hypLength / spacing);
+
+            for (int i=0; i<numLines; i++) {
+                double x = i * spacing;
+                Line2D line = new Line2D.Double(x, -hypLength, x, hypLength);
+                g.draw(line);
+            }
+            g.setClip(oldClip);
+        }
+
+        @Override
+        public Dimension getPreferredSize() {
+            return size;
+        }
+
+        void setZoom(int value) {
+            int width = image.getWidth();
+            int height = image.getHeight();
+
+            zoom = value;
+            size = new Dimension(width * zoom, height * zoom);
+
+            setSize(size);
+            ImageEditorPanel.this.validate();
+            repaint();
+        }
+
+        void setPatchesVisible(boolean visible) {
+            showPatches = visible;
+            findPatches();
+            repaint();
+        }
+
+        private void findPatches() {
+            int width = image.getWidth();
+            int height = image.getHeight();
+
+            row = GraphicsUtilities.getPixels(image, 0, 0, width, 1, row);
+            column = GraphicsUtilities.getPixels(image, 0, 0, 1, height, column);
+
+            boolean[] result = new boolean[1];
+            Pair<List<Pair<Integer>>> left = getPatches(column, result);
+            verticalStartWithPatch = result[0];
+
+            result = new boolean[1];
+            Pair<List<Pair<Integer>>> top = getPatches(row, result);
+            horizontalStartWithPatch = result[0];
+
+            fixed = getRectangles(left.first, top.first);
+            patches = getRectangles(left.second, top.second);
+
+            if (fixed.size() > 0) {
+                horizontalPatches = getRectangles(left.first, top.second);
+                verticalPatches = getRectangles(left.second, top.first);
+            } else {
+                horizontalPatches = verticalPatches = new ArrayList<Rectangle>(0);
+            }
+
+            row = GraphicsUtilities.getPixels(image, 0, height - 1, width, 1, row);
+            column = GraphicsUtilities.getPixels(image, width - 1, 0, 1, height, column);
+
+            top = getPatches(row, result);
+            horizontalPadding = getPadding(top.first);
+
+            left = getPatches(column, result);
+            verticalPadding = getPadding(left.first);
+        }
+
+        private Pair<Integer> getPadding(List<Pair<Integer>> pairs) {
+            if (pairs.size() == 0) {
+                return new Pair<Integer>(0, 0);
+            } else if (pairs.size() == 1) {
+                if (pairs.get(0).first == 1) {
+                    return new Pair<Integer>(pairs.get(0).second - pairs.get(0).first, 0);
+                } else {
+                    return new Pair<Integer>(0, pairs.get(0).second - pairs.get(0).first);                    
+                }
+            } else {
+                int index = pairs.size() - 1;
+                return new Pair<Integer>(pairs.get(0).second - pairs.get(0).first,
+                        pairs.get(index).second - pairs.get(index).first);
+            }
+        }
+
+        private List<Rectangle> getRectangles(List<Pair<Integer>> leftPairs,
+                List<Pair<Integer>> topPairs) {
+            List<Rectangle> rectangles = new ArrayList<Rectangle>();
+            for (Pair<Integer> left : leftPairs) {
+                int y = left.first;
+                int height = left.second - left.first;
+                for (Pair<Integer> top: topPairs) {
+                    int x = top.first;
+                    int width = top.second - top.first;
+
+                    rectangles.add(new Rectangle(x, y, width, height));
+                }
+            }
+            return rectangles;
+        }
+
+        private Pair<List<Pair<Integer>>> getPatches(int[] pixels, boolean[] startWithPatch) {
+            int lastIndex = 1;
+            int lastPixel = pixels[1];
+            boolean first = true;
+
+            List<Pair<Integer>> fixed = new ArrayList<Pair<Integer>>();
+            List<Pair<Integer>> patches = new ArrayList<Pair<Integer>>();
+
+            for (int i = 1; i < pixels.length - 1; i++) {
+                int pixel = pixels[i];
+                if (pixel != lastPixel) {
+                    if (lastPixel == 0xFF000000) {
+                        if (first) startWithPatch[0] = true;
+                        patches.add(new Pair<Integer>(lastIndex, i));
+                    } else {
+                        fixed.add(new Pair<Integer>(lastIndex, i));
+                    }
+                    first = false;
+
+                    lastIndex = i;
+                    lastPixel = pixel;
+                }
+            }
+            if (lastPixel == 0xFF000000) {
+                if (first) startWithPatch[0] = true;
+                patches.add(new Pair<Integer>(lastIndex, pixels.length - 1));
+            } else {
+                fixed.add(new Pair<Integer>(lastIndex, pixels.length - 1));
+            }
+
+            if (patches.size() == 0) {
+                patches.add(new Pair<Integer>(1, pixels.length - 1));
+                startWithPatch[0] = true;
+                fixed.clear();
+            }
+            return new Pair<List<Pair<Integer>>>(fixed, patches);
+        }
+
+        void setLockVisible(boolean visible) {
+            showLock = visible;
+            repaint();
+        }
+    }
+
+    static class Pair<E> {
+        E first;
+        E second;
+
+        Pair(E first, E second) {
+            this.first = first;
+            this.second = second;
+        }
+
+        @Override
+        public String toString() {
+            return "Pair[" + first + ", " + second + "]";
+        }
+    }
+}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/ImageTransferHandler.java b/tools/draw9patch/src/com/android/draw9patch/ui/ImageTransferHandler.java
new file mode 100644
index 0000000..a62884f
--- /dev/null
+++ b/tools/draw9patch/src/com/android/draw9patch/ui/ImageTransferHandler.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.draw9patch.ui;
+
+import javax.swing.TransferHandler;
+import javax.swing.JComponent;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.net.MalformedURLException;
+
+class ImageTransferHandler extends TransferHandler {
+    private final MainFrame mainFrame;
+
+    ImageTransferHandler(MainFrame mainFrame) {
+        this.mainFrame = mainFrame;
+    }
+
+    @Override
+    public boolean importData(JComponent component, Transferable transferable) {
+        try {
+            Object data = transferable.getTransferData(DataFlavor.javaFileListFlavor);
+            //noinspection unchecked
+            final File file = ((List<File>) data).get(0);
+            mainFrame.open(file).execute();
+        } catch (UnsupportedFlavorException e) {
+            return false;
+        } catch (MalformedURLException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean canImport(JComponent component, DataFlavor[] dataFlavors) {
+        for (DataFlavor flavor : dataFlavors) {
+            if (flavor.isFlavorJavaFileListType()) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/MainFrame.java b/tools/draw9patch/src/com/android/draw9patch/ui/MainFrame.java
new file mode 100644
index 0000000..9ffd93e
--- /dev/null
+++ b/tools/draw9patch/src/com/android/draw9patch/ui/MainFrame.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.draw9patch.ui;
+
+import com.android.draw9patch.ui.action.ExitAction;
+import com.android.draw9patch.ui.action.OpenAction;
+import com.android.draw9patch.ui.action.SaveAction;
+import com.android.draw9patch.graphics.GraphicsUtilities;
+
+import javax.swing.JFrame;
+import javax.swing.JMenuBar;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.ActionMap;
+import javax.swing.JFileChooser;
+import javax.imageio.ImageIO;
+import java.awt.HeadlessException;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.util.concurrent.ExecutionException;
+
+import org.jdesktop.swingworker.SwingWorker;
+
+public class MainFrame extends JFrame {
+    private ActionMap actionsMap;
+    private JMenuItem saveMenuItem;
+    private ImageEditorPanel imageEditor;
+
+    public MainFrame() throws HeadlessException {
+        super("Draw 9-patch");
+
+        buildActions();
+        buildMenuBar();
+        buildContent();
+
+        showOpenFilePanel();
+
+        // pack();
+        setSize(1024, 600);
+    }
+
+    private void buildActions() {
+        actionsMap = new ActionMap();
+        actionsMap.put(OpenAction.ACTION_NAME, new OpenAction(this));
+        actionsMap.put(SaveAction.ACTION_NAME, new SaveAction(this));
+        actionsMap.put(ExitAction.ACTION_NAME, new ExitAction(this));
+    }
+
+    private void buildMenuBar() {
+        JMenu fileMenu = new JMenu("File");
+        JMenuItem openMenuItem = new JMenuItem();
+        saveMenuItem = new JMenuItem();
+        JMenuItem exitMenuItem = new JMenuItem();
+
+        openMenuItem.setAction(actionsMap.get(OpenAction.ACTION_NAME));
+        fileMenu.add(openMenuItem);
+
+        saveMenuItem.setAction(actionsMap.get(SaveAction.ACTION_NAME));
+        saveMenuItem.setEnabled(false);
+        fileMenu.add(saveMenuItem);
+
+        exitMenuItem.setAction(actionsMap.get(ExitAction.ACTION_NAME));
+        fileMenu.add(exitMenuItem);
+
+        JMenuBar menuBar = new JMenuBar();
+        menuBar.add(fileMenu);
+        setJMenuBar(menuBar);
+    }
+
+    private void buildContent() {
+        setContentPane(new GradientPanel());
+    }
+
+    private void showOpenFilePanel() {
+        add(new OpenFilePanel(this));
+    }
+
+    public SwingWorker<?, ?> open(File file) {
+        if (file == null) {
+            JFileChooser chooser = new JFileChooser();
+            chooser.setFileFilter(new PngFileFilter());
+            int choice = chooser.showOpenDialog(this);
+            if (choice == JFileChooser.APPROVE_OPTION) {
+                return new OpenTask(chooser.getSelectedFile());
+            } else {
+                return null;
+            }
+        } else {
+            return new OpenTask(file);
+        }
+    }
+
+    void showImageEditor(BufferedImage image, String name) {
+        getContentPane().removeAll();
+        imageEditor = new ImageEditorPanel(this, image, name);
+        add(imageEditor);
+        saveMenuItem.setEnabled(true);
+        validate();
+        repaint();
+    }
+
+    public SwingWorker<?, ?> save() {
+        if (imageEditor == null) {
+            return null;
+        }
+
+        File file = imageEditor.chooseSaveFile();
+        return file != null ? new SaveTask(file) : null;
+    }
+
+    private class SaveTask extends SwingWorker<Boolean, Void> {
+        private final File file;
+
+        SaveTask(File file) {
+            this.file = file;
+        }
+
+        protected Boolean doInBackground() throws Exception {
+            try {
+                ImageIO.write(imageEditor.getImage(), "PNG", file);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            return true;
+        }
+    }
+
+    private class OpenTask extends SwingWorker<BufferedImage, Void> {
+        private final File file;
+
+        OpenTask(File file) {
+            this.file = file;
+        }
+
+        protected BufferedImage doInBackground() throws Exception {
+            return GraphicsUtilities.loadCompatibleImage(file.toURI().toURL());
+        }
+
+        @Override
+        protected void done() {
+            try {
+                showImageEditor(get(), file.getAbsolutePath());
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            } catch (ExecutionException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/OpenFilePanel.java b/tools/draw9patch/src/com/android/draw9patch/ui/OpenFilePanel.java
new file mode 100644
index 0000000..a444332
--- /dev/null
+++ b/tools/draw9patch/src/com/android/draw9patch/ui/OpenFilePanel.java
@@ -0,0 +1,51 @@
+package com.android.draw9patch.ui;
+
+import com.android.draw9patch.graphics.GraphicsUtilities;
+
+import javax.swing.JComponent;
+import java.awt.image.BufferedImage;
+import java.awt.Graphics;
+import java.io.IOException;
+import java.net.URL;/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+class OpenFilePanel extends JComponent {
+    private BufferedImage dropHere;
+
+    OpenFilePanel(MainFrame mainFrame) {
+        setOpaque(false);
+        loadSupportImage();
+        setTransferHandler(new ImageTransferHandler(mainFrame));
+    }
+
+    private void loadSupportImage() {
+        try {
+            URL resource = getClass().getResource("/images/drop.png");
+            dropHere = GraphicsUtilities.loadCompatibleImage(resource);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    protected void paintComponent(Graphics g) {
+        int x = (getWidth() - dropHere.getWidth()) / 2;
+        int y = (getHeight() - dropHere.getHeight()) / 2;
+
+        g.drawImage(dropHere, x, y, null);
+    }
+
+}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/PngFileFilter.java b/tools/draw9patch/src/com/android/draw9patch/ui/PngFileFilter.java
new file mode 100644
index 0000000..8f8885a
--- /dev/null
+++ b/tools/draw9patch/src/com/android/draw9patch/ui/PngFileFilter.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.draw9patch.ui;
+
+import javax.swing.filechooser.FileFilter;
+import java.io.File;
+
+class PngFileFilter extends FileFilter {
+    @Override
+    public boolean accept(File f) {
+        return f.isDirectory() || f.getName().toLowerCase().endsWith(".png");
+    }
+
+    @Override
+    public String getDescription() {
+        return "PNG Image (*.png)";
+    }
+}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/action/BackgroundAction.java b/tools/draw9patch/src/com/android/draw9patch/ui/action/BackgroundAction.java
new file mode 100644
index 0000000..85d9d4f
--- /dev/null
+++ b/tools/draw9patch/src/com/android/draw9patch/ui/action/BackgroundAction.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.draw9patch.ui.action;
+
+import org.jdesktop.swingworker.SwingWorker;
+
+import javax.swing.AbstractAction;
+
+public abstract class BackgroundAction extends AbstractAction {
+    protected void executeBackgroundTask(SwingWorker<?, ?> worker) {
+        if (worker != null) {
+            worker.execute();
+        }
+    }
+}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/action/ExitAction.java b/tools/draw9patch/src/com/android/draw9patch/ui/action/ExitAction.java
new file mode 100644
index 0000000..b6f047d
--- /dev/null
+++ b/tools/draw9patch/src/com/android/draw9patch/ui/action/ExitAction.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.draw9patch.ui.action;
+
+import javax.swing.AbstractAction;
+import javax.swing.KeyStroke;
+import javax.swing.JFrame;
+import java.awt.event.KeyEvent;
+import java.awt.event.ActionEvent;
+import java.awt.Toolkit;
+
+public class ExitAction extends AbstractAction {
+    public static final String ACTION_NAME = "exit";
+    private JFrame frame;
+
+    public ExitAction(JFrame frame) {
+        putValue(NAME, "Quit");
+        putValue(SHORT_DESCRIPTION, "Quit");
+        putValue(LONG_DESCRIPTION, "Quit");
+        putValue(MNEMONIC_KEY, KeyEvent.VK_Q);
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_Q,
+                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
+        this.frame = frame;
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        frame.dispose();
+        System.exit(0);
+    }
+}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/action/OpenAction.java b/tools/draw9patch/src/com/android/draw9patch/ui/action/OpenAction.java
new file mode 100644
index 0000000..45ee5be
--- /dev/null
+++ b/tools/draw9patch/src/com/android/draw9patch/ui/action/OpenAction.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.draw9patch.ui.action;
+
+import com.android.draw9patch.ui.MainFrame;
+
+import javax.swing.KeyStroke;
+import java.awt.event.KeyEvent;
+import java.awt.event.ActionEvent;
+import java.awt.Toolkit;
+
+public class OpenAction extends BackgroundAction {
+    public static final String ACTION_NAME = "open";
+    private MainFrame frame;
+
+    public OpenAction(MainFrame frame) {
+        this.frame = frame;
+        putValue(NAME, "Open 9-patch...");
+        putValue(SHORT_DESCRIPTION, "Open...");
+        putValue(LONG_DESCRIPTION, "Open 9-patch...");
+        putValue(MNEMONIC_KEY, KeyEvent.VK_O);
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O,
+                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        executeBackgroundTask(frame.open(null));
+    }
+}
diff --git a/tools/draw9patch/src/com/android/draw9patch/ui/action/SaveAction.java b/tools/draw9patch/src/com/android/draw9patch/ui/action/SaveAction.java
new file mode 100644
index 0000000..5c1dc52
--- /dev/null
+++ b/tools/draw9patch/src/com/android/draw9patch/ui/action/SaveAction.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.draw9patch.ui.action;
+
+import com.android.draw9patch.ui.MainFrame;
+
+import javax.swing.KeyStroke;
+import java.awt.event.KeyEvent;
+import java.awt.event.ActionEvent;
+import java.awt.Toolkit;
+
+public class SaveAction extends BackgroundAction {
+    public static final String ACTION_NAME = "save";
+    private MainFrame frame;
+
+    public SaveAction(MainFrame frame) {
+        this.frame = frame;
+        putValue(NAME, "Save 9-patch...");
+        putValue(SHORT_DESCRIPTION, "Save...");
+        putValue(LONG_DESCRIPTION, "Save 9-patch...");
+        putValue(MNEMONIC_KEY, KeyEvent.VK_S);
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S,
+                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        executeBackgroundTask(frame.save());
+    }
+}
diff --git a/tools/draw9patch/src/resources/images/checker.png b/tools/draw9patch/src/resources/images/checker.png
new file mode 100644
index 0000000..78908f4
--- /dev/null
+++ b/tools/draw9patch/src/resources/images/checker.png
Binary files differ
diff --git a/tools/draw9patch/src/resources/images/drop.png b/tools/draw9patch/src/resources/images/drop.png
new file mode 100644
index 0000000..7a7436a
--- /dev/null
+++ b/tools/draw9patch/src/resources/images/drop.png
Binary files differ
diff --git a/tools/dumpeventlog/.classpath b/tools/dumpeventlog/.classpath
new file mode 100644
index 0000000..b0326c8
--- /dev/null
+++ b/tools/dumpeventlog/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/dumpeventlog/.project b/tools/dumpeventlog/.project
new file mode 100644
index 0000000..c416f4f
--- /dev/null
+++ b/tools/dumpeventlog/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>dumpeventlog</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/dumpeventlog/Android.mk b/tools/dumpeventlog/Android.mk
new file mode 100644
index 0000000..7bb870d
--- /dev/null
+++ b/tools/dumpeventlog/Android.mk
@@ -0,0 +1,5 @@
+# Copyright 2007 The Android Open Source Project
+#
+DUMPEVENTLOG_LOCAL_DIR := $(call my-dir)
+include $(DUMPEVENTLOG_LOCAL_DIR)/etc/Android.mk
+include $(DUMPEVENTLOG_LOCAL_DIR)/src/Android.mk
diff --git a/tools/dumpeventlog/etc/Android.mk b/tools/dumpeventlog/etc/Android.mk
new file mode 100644
index 0000000..8094734
--- /dev/null
+++ b/tools/dumpeventlog/etc/Android.mk
@@ -0,0 +1,8 @@
+# Copyright 2007 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_EXECUTABLES := dumpeventlog
+include $(BUILD_HOST_PREBUILT)
+
diff --git a/tools/dumpeventlog/etc/dumpeventlog b/tools/dumpeventlog/etc/dumpeventlog
new file mode 100755
index 0000000..56f8c22
--- /dev/null
+++ b/tools/dumpeventlog/etc/dumpeventlog
@@ -0,0 +1,81 @@
+#!/bin/sh
+# Copyright 2005-2007, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+    newProg=`/bin/ls -ld "${prog}"`
+    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+    if expr "x${newProg}" : 'x/' >/dev/null; then
+        prog="${newProg}"
+    else
+        progdir=`dirname "${prog}"`
+        prog="${progdir}/${newProg}"
+    fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+jarfile=dumpeventlog.jar
+frameworkdir="$progdir"
+libdir="$progdir"
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/tools/lib
+    libdir=`dirname "$progdir"`/tools/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/framework
+    libdir=`dirname "$progdir"`/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    echo `basename "$prog"`": can't find $jarfile"
+    exit 1
+fi
+
+
+# Check args.
+if [ debug = "$1" ]; then
+    # add this in for debugging
+    java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
+    shift 1
+else
+    java_debug=
+fi
+
+# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
+if [ `uname` = "Darwin" ]; then
+    os_opts="-XstartOnFirstThread"
+else
+    os_opts=
+fi
+
+if [ "$OSTYPE" = "cygwin" ] ; then
+    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
+    progdir=`cygpath -w  "$progdir"`
+else
+    jarpath="$frameworkdir/$jarfile"
+fi
+
+# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
+# might need more memory, e.g. -Xmx128M
+exec java -Xmx128M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -jar "$jarpath" "$@"
diff --git a/tools/dumpeventlog/etc/manifest.txt b/tools/dumpeventlog/etc/manifest.txt
new file mode 100644
index 0000000..0eea915
--- /dev/null
+++ b/tools/dumpeventlog/etc/manifest.txt
@@ -0,0 +1 @@
+Main-Class: com.android.dumpeventlog.DumpEventLog
diff --git a/tools/dumpeventlog/src/Android.mk b/tools/dumpeventlog/src/Android.mk
new file mode 100644
index 0000000..bf99375
--- /dev/null
+++ b/tools/dumpeventlog/src/Android.mk
@@ -0,0 +1,14 @@
+# Copyright 2007 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAR_MANIFEST := ../etc/manifest.txt
+LOCAL_JAVA_LIBRARIES := \
+	ddmlib
+LOCAL_MODULE := dumpeventlog
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java b/tools/dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java
new file mode 100644
index 0000000..6c528e1
--- /dev/null
+++ b/tools/dumpeventlog/src/com/android/dumpeventlog/DumpEventLog.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.dumpeventlog;
+
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.Device;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.Log.ILogOutput;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmlib.log.LogReceiver;
+import com.android.ddmlib.log.LogReceiver.ILogListener;
+import com.android.ddmlib.log.LogReceiver.LogEntry;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Connects to a device using ddmlib and dumps its event log as long as the device is connected. 
+ */
+public class DumpEventLog {
+
+    /**
+     * Custom {@link ILogListener} to receive and save the event log raw output.
+     */
+    private static class LogWriter implements ILogListener {
+        private FileOutputStream mOutputStream;
+        private LogReceiver mReceiver;
+
+        public LogWriter(String filePath) throws IOException {
+            mOutputStream = new FileOutputStream(filePath);
+        }
+
+        public void newData(byte[] data, int offset, int length) {
+            try {
+                mOutputStream.write(data, offset, length);
+            } catch (IOException e) {
+                if (mReceiver != null) {
+                    mReceiver.cancel();
+                }
+                System.out.println(e);
+            }
+        }
+
+        public void newEntry(LogEntry entry) {
+            // pass
+        }
+
+        public void setReceiver(LogReceiver receiver) {
+            mReceiver = receiver;
+        }
+
+        public void done() throws IOException {
+            mOutputStream.close();
+        }
+    }
+
+    public static void main(String[] args) {
+        if (args.length != 2) {
+            System.out.println("Usage: dumpeventlog <device s/n> <filepath>");
+            return;
+        }
+        
+        // redirect the log output to /dev/null
+        Log.setLogOutput(new ILogOutput() {
+            public void printAndPromptLog(LogLevel logLevel, String tag, String message) {
+                // pass
+            }
+
+            public void printLog(LogLevel logLevel, String tag, String message) {
+                // pass
+            }
+        });
+        
+        // init the lib
+        AndroidDebugBridge.init(false /* debugger support */);
+        
+        try {
+            AndroidDebugBridge bridge = AndroidDebugBridge.createBridge();
+            
+            // we can't just ask for the device list right away, as the internal thread getting
+            // them from ADB may not be done getting the first list.
+            // Since we don't really want getDevices() to be blocking, we wait here manually.
+            int count = 0;
+            while (bridge.hasInitialDeviceList() == false) {
+                try {
+                    Thread.sleep(100);
+                    count++;
+                } catch (InterruptedException e) {
+                    // pass
+                }
+                
+                // let's not wait > 10 sec.
+                if (count > 100) {
+                    System.err.println("Timeout getting device list!");
+                    return;
+                }
+            }
+
+            // now get the devices
+            Device[] devices = bridge.getDevices();
+            
+            for (Device device : devices) {
+                if (device.getSerialNumber().equals(args[0])) {
+                    try {
+                        grabLogFrom(device, args[1]);
+                    } catch (FileNotFoundException e) {
+                        e.printStackTrace();
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                    return;
+                }
+            }
+            
+            System.err.println("Could not find " + args[0]);
+        } finally {
+            AndroidDebugBridge.terminate();
+        }
+    }
+
+    private static void grabLogFrom(Device device, String filePath) throws IOException {
+        LogWriter writer = new LogWriter(filePath);
+        LogReceiver receiver = new LogReceiver(writer);
+        writer.setReceiver(receiver);
+
+        device.runEventLogService(receiver);
+        
+        writer.done();
+    }
+}
diff --git a/tools/eclipse/README_WINDOWS.txt b/tools/eclipse/README_WINDOWS.txt
new file mode 100644
index 0000000..1480f5d
--- /dev/null
+++ b/tools/eclipse/README_WINDOWS.txt
@@ -0,0 +1,32 @@
+[RM 20080623]
+
+1- To build the Eclipse plugin:
+Under Linux:
+$ cd your-device-directory
+$ tools/eclipse/scripts/build_server.sh destination-directory
+
+This will create an "android-eclipse.zip" in the selected destination directory.
+Then in Eclipse, you can use Help > Software Updates > Find and Install > Search for new Features > Next > New Archived Site > select the new android-eclipse.zip. Then with the new archive checked, click Finish/Next.
+
+
+2- To build a Windows SDK, you need two steps:
+a- First you need to create a Linux SDK:
+
+Under Linux:
+$ cd your-device-directory
+$ make sdk
+Note: if you get an error when building the javadoc, make sure you use a Java SDK 1.5
+Note: if you get an error when building layoutlib, make sure you use a Java SDK 1.5.0-b13.
+
+b- Once you have a Linux SDK, you can create a Windows SDK:
+
+You need a Windows machine with XP or Vista and Cygwin.
+- Installer at http://sources.redhat.com/cygwin/
+- Set Default Text File Type to DOS/text, not Unix/binary.
+- Select packages autoconf, gcc, g++, bison, python, zip, unzip, mingw-zlib
+- Suggested extra packages: emacs, wget, openssh, rsync
+
+Then under Cygwin:
+$ cd your-device-directory
+$ tools/buildbot/_make_windows_sdk.sh path-to-the-linux-sdk.zip destination-directory
+
diff --git a/tools/eclipse/buildConfig/allElements.xml b/tools/eclipse/buildConfig/allElements.xml
new file mode 100644
index 0000000..2c8229c
--- /dev/null
+++ b/tools/eclipse/buildConfig/allElements.xml
@@ -0,0 +1,60 @@
+<!-- ========================================================================= -->
+<!-- Feature build ant targets                                                 -->
+<!-- Template obtained from org.eclipse.pde.build/templates/headless-build     -->
+<!-- ========================================================================= -->
+<project name="allElements Delegator">
+    
+     <!-- ===================================================================== -->
+     <!-- Run a given ${target} on all elements being built                     -->
+     <!-- Replace element.id with the id of the top level element being built.    -->
+     <!-- If element.id does not exist in ${buildDirectory}/features/element.id   -->
+     <!-- or ${baseLocation}/features/element.id, then you must provide the       -->
+     <!-- location by setting the property "pluginPath"                           -->
+     <!-- Add on <ant> task for each top level element being built.             -->
+     <!-- ===================================================================== -->
+     <target name="allElementsDelegator">
+         
+         <ant antfile="${genericTargets}" target="${target}">
+             <property name="type" value="feature" />
+             <property name="id" value="com.android.ide.eclipse.ddms" />
+         </ant>
+
+         <ant antfile="${genericTargets}" target="${target}">
+             <property name="type" value="feature" />
+             <property name="id" value="com.android.ide.eclipse.adt" />
+         </ant>
+         
+        <antcall target="buildInternalFeatures"/>
+         
+     </target>
+    
+     <!-- ===================================================================== -->
+     <!-- Conditional target for building the internal features                 -->
+     <!-- Builds if property internalSite is set                                -->
+     <!-- ===================================================================== -->
+     <target name="buildInternalFeatures" if="internalSite">
+        <ant antfile="${genericTargets}" target="${target}">
+            <property name="type" value="feature" />
+            <property name="id" value="com.android.ide.eclipse.tests" />
+        </ant>
+     </target>    
+         
+     <!-- ===================================================================== -->
+     <!-- Targets to assemble the built elements for particular configurations  -->
+     <!-- These generally call the generated assemble scripts (named in         -->
+     <!-- ${assembleScriptName}) but may also add pre and post processing       -->
+     <!-- Add one target for each root element and each configuration           -->
+     <!-- Replace element.id with the id of the top level element being built   -->
+     <!-- ===================================================================== -->
+     <target name="assemble.com.android.ide.eclipse.adt">
+         <ant antfile="${assembleScriptName}" dir="${buildDirectory}"/>
+     </target>
+
+     <target name="assemble.com.android.ide.eclipse.ddms">
+         <ant antfile="${assembleScriptName}" dir="${buildDirectory}"/>
+     </target>
+    
+    <target name="assemble.com.android.ide.eclipse.tests">
+        <ant antfile="${assembleScriptName}" dir="${buildDirectory}"/>
+    </target>
+</project>
diff --git a/tools/eclipse/buildConfig/build.properties b/tools/eclipse/buildConfig/build.properties
new file mode 100644
index 0000000..cd477d8
--- /dev/null
+++ b/tools/eclipse/buildConfig/build.properties
@@ -0,0 +1,238 @@
+###############################################################################
+# Copyright (c) 2003, 2006 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# 
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+
+# This file was generated per the instructions located in Eclipse Help>Plug-in Development
+# Environment >  Guide > Tasks > Building features and customized for building the
+# Android Eclipse plugins.
+
+#####################
+# Parameters describing how and where to execute the build.
+# Typical users need only update the following properties:
+#    baseLocation - where things you are building against are installed
+#    bootclasspath - The base jars to compile against (typicaly rt.jar)
+#    configs - the list of {os, ws, arch} configurations to build.  
+#
+# Of course any of the settings here can be overridden by spec'ing 
+# them on the command line (e.g., -DbaseLocation=d:/eclipse
+
+############# PRODUCT/PACKAGING CONTROL #############
+product=/plugin or feature id/path/to/.product
+runPackager=true
+
+#Set the name of the archive that will result from the product build.
+#archiveNamePrefix=
+
+# The prefix that will be used in the generated archive.
+# override default of "eclipse" to aid for external site generation 
+archivePrefix=android-eclipse
+
+# The location underwhich all of the build output will be collected.
+collectingFolder=${archivePrefix}
+
+# The list of {os, ws, arch} configurations to build.  This 
+# value is a '&' separated list of ',' separate triples.  For example, 
+#     configs=win32,win32,x86 & linux,motif,x86
+# By default the value is *,*,*
+configs = *, *, *
+#configs=win32, win32, x86 & \
+#	linux, gtk, ppc &\
+# linux, gtk, x86 & \
+#	linux, gtk, x86_64 & \
+#	linux, motif, x86 & \
+#	solaris, motif, sparc & \
+#	solaris, gtk, sparc & \
+#	aix, motif, ppc & \
+#	hpux, motif, PA_RISC & \
+#	macosx, carbon, ppc
+
+# By default PDE creates one archive (result) per entry listed in the configs property.
+# Setting this value to try will cause PDE to only create one output containing all 
+# artifacts for all the platforms listed in the configs property.
+#groupConfigurations=true
+
+#The format of the archive. By default a zip is created using antZip.
+#The list can only contain the configuration for which the desired format is different than zip.
+#archivesFormat=win32, win32, x86 - antZip& \
+#	linux, gtk, ppc - antZip &\
+#    linux, gtk, x86 - antZip& \
+#	linux, gtk, x86_64 - antZip& \
+# linux, motif, x86 - antZip& \
+#	solaris, motif, sparc - antZip& \
+#	solaris, gtk, sparc - antZip& \
+#	aix, motif, ppc - antZip& \
+#	hpux, motif, PA_RISC - antZip& \
+#	macosx, carbon, ppc - antZip
+	
+#Set to true if you want the output to be ready for an update jar (no site.xml generated)
+outputUpdateJars = true
+
+#Set to true for Jnlp generation
+#codebase should be a URL that will be used as the root of all relative URLs in the output.
+#generateJnlp=false
+#jnlp.codebase=<codebase url>
+#jnlp.j2se=<j2se version>
+#jnlp.locale=<a locale>
+#jnlp.generateOfflineAllowed=true or false generate <offlineAllowed/> attribute in the generated features
+#jnlp.configs=${configs}			#uncomment to filter the content of the generated jnlp files based on the configuration being built
+
+#Set to true if you want to sign jars
+#signJars=false
+#sign.alias=<alias>
+#sign.keystore=<keystore location>
+#sign.storepass=<keystore password>
+
+#Arguments to send to the zip executable
+zipargs=
+
+#Arguments to send to the tar executable
+tarargs=
+
+#Control the creation of a file containing the version included in each configuration - on by default 
+#generateVersionsLists=false
+
+############## BUILD NAMING CONTROL ################
+# The directory into which the build elements are fetched and where
+# the build takes place.
+buildDirectory=.
+
+# Type of build.  Used in naming the build output.  Typically this value is
+# one of I, N, M, S, ...
+buildType=build
+
+# ID of the build.  Used in naming the build output.
+# forceContextQualifer = build label
+buildId=${forceContextQualifier}
+
+# Label for the build.  Used in naming the build output
+buildLabel=${buildId}
+
+# Timestamp for the build.  Used in naming the build output
+timestamp=007
+
+#The value to be used for the qualifier of a plugin or feature when you want to override the value computed by pde.
+#The value will only be applied to plugin or features indicating build.properties, qualifier = context 
+#forceContextQualifier=<the value for the qualifier>
+
+#Enable / disable the generation of a suffix for the features that use .qualifier. 
+#The generated suffix is computed according to the content of the feature   
+#generateFeatureVersionSuffix=true
+
+############# BASE CONTROL #############
+# Settings for the base Eclipse components and Java class libraries 
+# against which you are building.
+# Base location for anything the build needs to compile against.  For example,
+# in most RCP app or a plug-in,  the baseLocation should be the location of a previously
+# installed Eclipse against which the application or plug-in code will be compiled and the RCP delta pack.
+
+baseLocation=${ECLIPSE_HOME}
+#Os/Ws/Arch/nl of the eclipse specified by baseLocation
+baseos=linux
+basews=gtk
+basearch=x86
+
+#this property indicates whether you want the set of plug-ins and features to be considered during the build to be limited to the ones reachable from the features / plugins being built
+filteredDependencyCheck=false
+
+#this property indicates whether the resolution should be done in development mode (i.e. ignore multiple bundles with singletons)
+resolution.devMode=false
+
+#pluginPath is a list of locations in which to find plugins and features.  This list is separated by the platform file separator (; or :)
+#a location is one of:  
+#- the location of the jar or folder that is the plugin or feature : /path/to/foo.jar or /path/to/foo
+#- a directory that contains a /plugins or /features subdirectory
+#- the location of a feature.xml, or for 2.1 style plugins, the plugin.xml or fragment.xml
+#pluginPath=
+
+skipBase=true
+eclipseURL=<url for eclipse download site>
+eclipseBuildId=<Id of Eclipse build to get>
+eclipseBaseURL=${eclipseURL}/eclipse-platform-${eclipseBuildId}-win32.zip
+
+
+############# MAP FILE CONTROL ################
+# This section defines CVS tags to use when fetching the map files from the repository.
+# If you want to fetch the map file from repository / location, change the getMapFiles target in the customTargets.xml
+
+skipMaps=true
+mapsRepo=:pserver:anonymous@example.com/path/to/repo
+mapsRoot=path/to/maps
+mapsCheckoutTag=HEAD
+
+#tagMaps=true
+mapsTagTag=v${buildId}
+
+
+############ REPOSITORY CONTROL ###############
+# This section defines properties parameterizing the repositories where plugins, fragments
+# bundles and features are being obtained from. 
+
+# The tags to use when fetching elements to build.
+# By default thebuilder will use whatever is in the maps.  
+# This value takes the form of a comma separated list of repository identifier (like used in the map files) and the 
+# overriding value
+# For example fetchTag=CVS=HEAD, SVN=v20050101
+# fetchTag=HEAD
+skipFetch=true
+
+
+############# JAVA COMPILER OPTIONS ##############
+# The location of the Java jars to compile against.  Typically the rt.jar for your JDK/JRE
+#bootclasspath=${java.home}/lib/rt.jar
+
+# specific JRE locations to compile against. These values are used to compile bundles specifying a 
+# Bundle-RequiredExecutionEnvironment. Uncomment and set values for environments that you support
+#CDC-1.0/Foundation-1.0= /path/to/rt.jar
+#CDC-1.1/Foundation-1.1=
+#OSGi/Minimum-1.0=
+#OSGi/Minimum-1.1=
+#JRE-1.1=
+#J2SE-1.2=
+#J2SE-1.3=
+#J2SE-1.4=
+#J2SE-1.5=
+#JavaSE-1.6=
+#PersonalJava-1.1=
+#PersonalJava-1.2=
+#CDC-1.0/PersonalBasis-1.0=
+#CDC-1.0/PersonalJava-1.0=
+#CDC-1.1/PersonalBasis-1.1=
+#CDC-1.1/PersonalJava-1.1=
+
+# Specify the output format of the compiler log when eclipse jdt is used
+logExtension=.log
+
+# Whether or not to include debug info in the output jars
+javacDebugInfo=false 
+
+# Whether or not to fail the build if there are compiler errors
+javacFailOnError=true
+
+# Enable or disable verbose mode of the compiler
+javacVerbose=true
+
+# Extra arguments for the compiler. These are specific to the java compiler being used.
+#compilerArg=
+
+# Default value for the version of the source code. This value is used when compiling plug-ins that do not set the Bundle-RequiredExecutionEnvironment or set javacSource in build.properties
+javacSource=1.5
+
+# Default value for the version of the byte code targeted. This value is used when compiling plug-ins that do not set the Bundle-RequiredExecutionEnvironment or set javacTarget in build.properties.
+javacTarget=1.5
+
+################### CUSTOM PROPERTIES #######################################
+# repository location for update site
+# comment out - this is passed in from command line 
+#updateSiteSource=${buildDirectory}/sites/external
+# where to place update site build
+updateSiteRoot=${user.home}/www/no_crawl/
+updateSiteFolder=${archivePrefix}
+updateSiteDestination=${updateSiteRoot}/${updateSiteFolder}
diff --git a/tools/eclipse/buildConfig/buildUpdateSite.xml b/tools/eclipse/buildConfig/buildUpdateSite.xml
new file mode 100644
index 0000000..1ab7c99
--- /dev/null
+++ b/tools/eclipse/buildConfig/buildUpdateSite.xml
@@ -0,0 +1,13 @@
+<project name="update site">
+    <!-- ========================================================================= -->
+    <!-- Extracts feature zip for update site                                      -->
+    <!-- expected properties:                                                      -->
+    <!--    id - feature id to extract                                             -->
+    <!--    buildDirectory - base directgory where build takes place               -->
+    <!--    buildLabel - build id label                                            -->
+    <!--    updateSiteRoot - where to extract feature zip                          -->
+    <!-- ========================================================================= -->
+    <target name="extractFeature">
+        <unzip src="${buildDirectory}/${buildLabel}/${id}-${buildLabel}.zip" dest="${updateSiteRoot}"/>        
+    </target>
+</project>
diff --git a/tools/eclipse/buildConfig/customTargets.xml b/tools/eclipse/buildConfig/customTargets.xml
new file mode 100644
index 0000000..5a46bfc
--- /dev/null
+++ b/tools/eclipse/buildConfig/customTargets.xml
@@ -0,0 +1,195 @@
+<!-- ========================================================================= -->
+<!-- Eclipse template file for PDE builds -->
+<!-- template originally obtained from org.eclipse.pde.build/templates/headless-build -->
+<!-- ========================================================================= -->
+<project name="Build specific targets and properties" default="noDefault">
+
+    <!-- ===================================================================== -->
+    <!-- Run a given ${target} on all elements being built -->
+    <!-- Add on <ant> task for each top level element being built. -->
+    <!-- ===================================================================== -->
+    <property name="allElementsFile" value="${builder}/allElements.xml"/>
+    <import file="${allElementsFile}" />
+    <target name="allElements">
+        <antcall target="allElementsDelegator" />
+    </target>
+    
+    <!-- ===================================================================== -->
+    <!-- ===================================================================== -->
+    <target name="getBaseComponents" depends="checkLocalBase" unless="skipBase">
+        <get src="${eclipseBaseURL}" dest="${buildDirectory}/../temp-base.zip" />
+        <unzip dest="${base}" overwrite="true" src="${buildDirectory}/../temp-base.zip" />
+    </target>
+
+    <target name="checkLocalBase">
+        <available file="${base}" property="skipBase" />
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Check out map files from correct repository -->
+    <!-- Replace values for mapsCheckoutTag as desired. -->
+    <!-- ===================================================================== -->
+    <target name="getMapFiles" depends="checkLocalMaps" unless="skipMaps">
+        <property name="mapsCheckoutTag" value="HEAD" />
+        <cvs cvsRoot="${mapsRepo}" package="${mapsRoot}" dest="${buildDirectory}/maps" tag="${mapsCheckoutTag}" />
+    </target>
+
+    <target name="checkLocalMaps">
+        <available property="skipMaps" file="${buildDirectory}/maps" />
+    </target>
+
+    <target name="tagMapFiles" if="tagMaps">
+        <cvs dest="${buildDirectory}/maps/${mapsRoot}" command="tag ${mapsTagTag}" />
+    </target>
+
+    <!-- ===================================================================== -->
+
+    <target name="clean" unless="noclean">
+        <antcall target="allElements">
+            <param name="target" value="cleanElement" />
+        </antcall>
+    </target>
+
+    <target name="gatherLogs">
+        <mkdir dir="${buildDirectory}/${buildLabel}/compilelogs" />
+        <antcall target="allElements">
+            <param name="target" value="gatherLogs" />
+        </antcall>
+        <unzip dest="${buildDirectory}/${buildLabel}/compilelogs" overwrite="true">
+            <fileset dir="${buildDirectory}/features">
+                <include name="**/*.log.zip" />
+            </fileset>
+        </unzip>
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do before setup -->
+    <!-- ===================================================================== -->
+    <target name="preSetup">
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do after setup but before starting the build proper -->
+    <!-- ===================================================================== -->
+    <target name="postSetup">
+        <antcall target="getBaseComponents" />
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do before fetching the build elements -->
+    <!-- ===================================================================== -->
+    <target name="preFetch">
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do after fetching the build elements -->
+    <!-- ===================================================================== -->
+    <target name="postFetch">
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do before generating the build scripts. -->
+    <!-- ===================================================================== -->
+    <target name="preGenerate">
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do after generating the build scripts. -->
+    <!-- ===================================================================== -->
+    <target name="postGenerate">
+        <antcall target="clean" />
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do before running the build.xmls for the elements being built. -->
+    <!-- ===================================================================== -->
+    <target name="preProcess">
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do after running the build.xmls for the elements being built. -->
+    <!-- ===================================================================== -->
+    <target name="postProcess">
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do before running assemble. -->
+    <!-- ===================================================================== -->
+    <target name="preAssemble">
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do after  running assemble. -->
+    <!-- ===================================================================== -->
+    <target name="postAssemble">
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do before running package. -->
+    <!-- ===================================================================== -->
+    <target name="prePackage">
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do after  running package. -->
+    <!-- ===================================================================== -->
+    <target name="postPackage">
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do after the build is done. -->
+    <!-- ===================================================================== -->
+    <target name="postBuild">
+        <antcall target="gatherLogs" />
+        <!-- Added this custom target ! -->
+        <antcall target="generateUpdateSite" />
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do to test the build results -->
+    <!-- ===================================================================== -->
+    <target name="test">
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Steps to do to publish the build results -->
+    <!-- ===================================================================== -->
+    <target name="publish">
+        
+    </target>
+
+    <!-- ===================================================================== -->
+    <!-- Default target                                                        -->
+    <!-- ===================================================================== -->
+    <target name="noDefault">
+        <echo message="You must specify a target when invoking this file" />
+    </target>
+    
+    <!-- ===================================================================== -->
+    <!-- Custom target:                                                        -->
+    <!-- Steps to do to generate the update site                               -->
+    <!-- ===================================================================== -->
+    <target name="generateUpdateSite">
+        <echo message="Copying update site source ${updateSiteSource} to destination"/>
+    	
+        <copy file="${updateSiteSource}/site.xml" overwrite="true" todir="${updateSiteDestination}"/>
+        <copy file="${updateSiteSource}/index.html" overwrite="true" todir="${updateSiteDestination}"/>
+        <copy file="${updateSiteSource}/web/site.css" overwrite="true" todir="${updateSiteDestination}/web"/>
+        <copy file="${updateSiteSource}/web/site.xsl" overwrite="true" todir="${updateSiteDestination}/web"/>
+        
+        <!-- replace qualifier version references with build label -->
+        <replace file="${updateSiteDestination}/site.xml" token="qualifier" value="${buildId}"/>
+        
+        <!-- now extract each features zip to update site -->
+        <antcall target="allElements">
+            <param name="genericTargets" value="${builder}/buildUpdateSite.xml"/>
+            <param name="target" value="extractFeature" />
+        </antcall>
+        
+        <chmod perm="755" type="both">
+            <fileset dir="${updateSiteDestination}">
+            </fileset>
+        </chmod>    
+    </target>
+
+</project>
diff --git a/tools/eclipse/changes.txt b/tools/eclipse/changes.txt
new file mode 100644
index 0000000..781930c
--- /dev/null
+++ b/tools/eclipse/changes.txt
@@ -0,0 +1,214 @@
+0.9.0 (work in progress)
+- Support for the new Android SDK with support for multiple versions of the Android platform and for vendor supplied add-ons.
+    * New Project Wizard lets you choose which platform/add-on to target.
+    * Project properties (right click project in Package Explorer, then "Properties"), lets you edit project target.
+    * New Launch configuration option to choose debug deployment target.
+- Ability to export multiple apk from one project, using resource filters. See the 'android' property for Android projects.
+
+0.8.1:
+
+- Alternate Layout wizard. In the layout editor, the "create" button is now enabled to easily create alternate versions of the current layout.
+- Fixed issue with custom themes/styles in the layout editor.
+- Export Wizard: To export an application for release, and sign it with a non debug key. Accessible from the export menu, from the Android Tools contextual menu, or from the overview page of the manifest editor.
+- New XML File Wizard: To easily create new XML resources file in the /res directory.
+- New checks on launch when attempting to debug on a device.
+- Basic support for drag'n'drop in Graphical layout editor. You can add new items by drag'n'drop from the palette. There is no support for moving/resizing yet.
+- Undo/redo support in all XML form editors and Graphical layout editor.
+
+0.8.0:
+
+- Fixed issue with using custom classes implementing Parcelable in aidl files. Right click the project and choose Android Tools > Create aidl preprocess file for Parcelable Classes.
+- Added Custom Themes to theme drop down in the layout editor.
+- Customizable debug signing keystore path in preferences
+- Customizable HOME package name.
+
+0.7.1:
+
+- Layout Editor.
+
+0.6.1:
+
+- Fixed install issue when project name contains spaces (requires new emulator image)
+- Fixed setup of the New class wizard in the manifest (when clicking on "name" for a class attribute) in the cases where the class and some of its parent packages were missing.
+- Properly kill the application that is about to be reinstalled.
+- Create missing android folder automatically when building application (caused a signing error)
+- Manifest editor: support for uses-library node
+- Fixed NPE in editors.xml.descriptors.XmlDescriptors.createPreference
+- Fixed assert in MultiEditorPart.setActivePage
+- Fixed "connect to debugger" button in DeviceView. Also fixed support for custom process names.
+
+0.6.0:
+
+- new launch option for activity. Can choose to launch default activity (finds an activity configured to show up in the home screen), or specific activity, or none.
+- normal java resources (non java files placed in package folders) are now properly packaged in the final package, and can be accessed through normal java API such as ClassLoader.getResourceAsStream()
+- launch configuration now has an option to wipe emulator data on launch. This always asks for confirmation.
+- launch configuration now has an option to disable the boot animation. This will let the emulator start faster on older computers.
+- Applications are now signed with a debug key (stored in debug.keystore in ~/.android).
+- Installation of application is now more robust and will notify of installation failure. Also installation is blocking, removing issues where ADT tried to launch the activity before the app was installed.
+- Tree-based resource editor + content assist in XML editor for layout, menu, preferences, values xml files. Work in progress...
+
+
+0.4.0 (adt 0.4.0, ddms 0.3.0, editors 0.2.0, common 0.1.0)
+
+- New AndroidManifest editor.
+- True multiple device support allowing debugging apps on several device at the same time
+- New launch modes for device selection: automatic will launch an emulator if no device are present, automatically target the device if only one exists, and prompt the user if 2+ are connected. Manual mode always prompt the user.
+- New classpath container remove the dependencies on the location of android.jar making it easier to share a project through dsvn, cvs, etc... You should fix your project (right click project, choose Android > Fix Project properties)
+- Fixed a case where pm would fail and would up end outputting the "usage" text, which would in turn confuse the plugin during parsing.
+- Fixed an issue with compiling aidl file when they import project local files.
+
+0.3.4 (adt 0.3.4, ddms 0.2.3, editors 0.1.0)
+
+Internal release only.
+- Enabled device support.
+
+0.3.3 (adt 0.3.3, ddms 0.2.3, editors 0.1.0)
+
+- Support for referenced projects.
+- During launch, display if a package conflict occurs when the new application is pushed onto the device.
+- You can now change the font of the logcat view. Also indentation is now properly displayed.
+- Plugin generated files are now properly marked as derived. This will make Team plugins ignore them.
+
+0.3.2
+
+- XML Highlighting for AndroidManifest.xml (requires WebTools WST plugin)
+- Custom java editor for R.java/Manifest.java to make those files non editable. This is to replace the current locking mechanism which causes issues on Mac OS.
+- Fixed some issue in the "Restart adb" feature in the device view of ddms.
+- Better handling of aidl files and the java files generated from them.
+- Plugin now retries to launch the app on the emulator if it fails due to timing issues.
+- Skin dropdown in the Emulator/Target tabs is now build from the content of the skin directory, to support developer made skins.
+- Emulator control panel. This is a UI on top of the emulator console. it allows you to change the state of the network and gsm connection, and to initiate incoming voice call.
+
+0.3.1
+
+- Fixed issue on winXP/Eclipse 3.2 where errors in the New Project Wizard would not display.
+- Added missing intent definition in the AndroidManifest.xml file created by the New Project Wizard.
+- Fixed possible NPE in the debug action from the Process View
+- Support for Eclipse 3.4
+
+0.2.6 / 0.3.0
+
+- New Project Wizard now makes it easy to open Android sample code
+- Plugin will output a warning if the build id of the device/emulator does not match the sdk build id.
+- Java/Debug/ddms perspective now contains direct menus to open some of the ddms views, and to create a new android project. This will require you to reset your perspectives.
+- Error during builds now put an error marker on the project instead of displaying an (annoying) dialog box.
+- Custom builders now remember their build state when restarting eclipse.
+- Properly parse some aapt warnings and don't abort the build when they happen.
+- Abort launch and prompt the user if the project contains errors.
+- New silent/normal/verbose build output.
+
+0.2.5
+
+- Check compiler compliance level before compilation and abort if different from 1.5
+- Fix Project Properties will fix the project compiler compliance if needed.
+- Fixed an issue with multiple source folders.
+- Added support for new Manifest.java class (it is automatically generated with R.java if the content of the AndroidManifest.xml requires it)
+- Fixed an issue that could result in not packaging code changes.
+- Automatic fix of the Launch Configurations when the java package in the manifest is changed. Also improved Launch Config dialog and error alert for erroneous activity names in the Launch Configuration.
+- Support for external jars that are not under the project root directory.
+- New projects have a default layout.
+- Misc fixes for Windows support.
+
+0.2.4
+
+- fixed large resource corruption issue.
+
+0.2.3
+
+- fixed issue related to the integration of dx.
+- fixed issue related to the package generation that was modified for windows support. 
+
+0.2.2
+
+- Changing the SDK location in the Preferences does not require to restart Eclipse anymore.
+- New SDK-Project sync mode in Android preference pane. Default value set to true. If true, all android projects are automatically sync'ed to the SDK defined in the preferences.
+- Cases where no emulator is running but a dialog still says "An emulator is running..." should be less frequent.
+- Projects do not reference the standard desktop JRE anymore, as android.zip contains the core java library. This will solve the case where using a core class non present on the platform would not generate a compilation error.
+- Changing the package defined in the manifest now deletes the R.java class from its previous location. This will require 1 build after upgrading the plugin, before it works.
+- Project selection in the Launch Config Dialog now only shows Android projects.
+- Launching a debug/run session now checks that the project uses the SDK set in the preferences (This is for the non automatic sync mode).
+- Removed obsolete wallpaper mode in the New Project Creation Wizard.
+- dx (dalvik code conversion tool) now embedded instead of calling the external version.
+- improvements in the parsing of the aapt errors.
+- some fixes for windows support.
+
+0.2.1
+
+- fixed bug in logcat search where invalid regexp would cause a crash
+- minor improvements to the build/launch process.
+
+0.2.0
+
+- Logcat view.
+- File Explorer view.
+- Custom options for emulator. In the Launch configuration dialog you can specify custom command line emulator options. See "emulator -help" for available options.
+- Android Tools > Export Application Package is now implemented.
+- Misc incremental builder fixes.
+- Including static .jar files as library in your project will automatically include them in the final APK. Warning: only the .class content is included.
+
+0.1.10
+
+- res and assets folders now fully refresh before the build, ensuring R.java and packaged resources are always up to date. This can be disabled in the preferences under "Android" if this becomes slow due to too many files.
+
+0.1.9
+
+- New Action in the "Processes" view to debug an application that is already running. The source project for this application MUST be opened in the current workspace.
+- Building the project now force refreshes the res folder. This should help rebuilding the resources when only binary files were changed from outside eclipse.
+- Clean/full builds now compile all aidl files found in the build path (previously only incremental builds would compile them). Also, misc improvements to the incremental builders.
+- Starting a run/debug session now asks to save the files and forces a new build to ensure that the latest package is pushed on the device.
+- Plugin should be less aggressive when waiting for the emulator to be ready. This should translate in fewer failed launches.
+
+0.1.8
+
+- Fixed Debugger issue introduced in 0.1.6
+- Added Log level preferences for DDMS. Look under Android > DDMS > Advanced. Default error level is Error.
+
+0.1.7
+
+- Fixed issue where java warnings wouldn't trigger a new package. Now only errors stop the packaging like it should be.
+- Added more error output in the console during launch.
+
+0.1.6
+
+- New "Android" Console. It receives the error output from external tools such and aidl, dx, and aapt (only when they can't be parsed). Any error force the console to be displayed.
+- The Activity Manager on the device/emulator now outputs some messages in the "Android" console when asked to start an activity. This should help you figure out what is wrong if the application doesn't start.
+- Fixed a case where the .apk file would be updated with broken code. Now if there are java compile error, the .apk is not touched.
+- Added support for manifest with non fully qualified activity java name, yet not starting with a dot.
+- Fixed creation of manifest files (through New Project wizard) to use proper namespace for attributes.
+- Better error reporting for namespace issue in the manifest.
+- "Reset Adb" action from the device view. Use this is the plugin tells you  an emulator is running when there are none.
+- New "ddms" Console which receives the standard output of ddms.
+
+0.1.5
+
+- Support for new activity declaration inside AndroidManifest.xml
+- fixed issue that prevented bin/ to be removed from the buildpath when converting project.
+
+0.1.4
+
+- Changes in the Manifest, now properly trigger a new package of the resources.
+
+0.1.3
+
+- Fixed the "fix project properties" action to remove old framework libraries, just not add new ones.
+
+0.1.2
+
+- aidl builder. The Android Resources PreBuilder now also converts aidl files into java files.
+- New Project wizard now allows to make Wallpaper activities instead of gadgets (which are obsolete.)
+- Launch shortcuts. Right click in the package explorer allow you to launch the application in debug or run mode directly without creating launch configurations.
+- New project wizard and Project conversion now sets up the java doc path for android.zip
+- Package builder now supports custom application assets placed in assets/ (which is now created automatically by the New Project Wizard).
+- New action: Android Tools > Fix Project Properties, in the package explorer contextual menu. This allows you to fix the framework path (and its javadoc path) in case you change the sdk location.
+
+0.1.1
+
+- Fixed project convertor to add the framework library if missing.
+
+0.1.0
+
+- New project wizard.
+- Python script-generated project convertor.
+- Incremental builders.
+- XML validation for resource files.
+- Android Launch Configuration.
diff --git a/tools/eclipse/features/com.android.ide.eclipse.adt/.project b/tools/eclipse/features/com.android.ide.eclipse.adt/.project
new file mode 100644
index 0000000..beca599
--- /dev/null
+++ b/tools/eclipse/features/com.android.ide.eclipse.adt/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>adt-feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/eclipse/features/com.android.ide.eclipse.adt/build.properties b/tools/eclipse/features/com.android.ide.eclipse.adt/build.properties
new file mode 100644
index 0000000..64f93a9
--- /dev/null
+++ b/tools/eclipse/features/com.android.ide.eclipse.adt/build.properties
@@ -0,0 +1 @@
+bin.includes = feature.xml
diff --git a/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml b/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml
new file mode 100644
index 0000000..b9e2c7f
--- /dev/null
+++ b/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="com.android.ide.eclipse.adt"
+      label="Android Development Tools"
+      version="0.9.0.qualifier"
+      provider-name="The Android Open Source Project"
+      plugin="com.android.ide.eclipse.adt">
+
+   <description>
+      Android Developer Tools.
+   </description>
+
+   <copyright>
+      Copyright (C) 2007 The Android Open Source Project
+   </copyright>
+
+   <license url="http://www.eclipse.org/org/documents/epl-v10.php">
+      Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE (&quot;AGREEMENT&quot;). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT&apos;S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+&quot;Contribution&quot; means:
+
+a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
+
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution &apos;originates&apos; from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor&apos;s behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
+
+&quot;Contributor&quot; means any person or entity that distributes the Program.
+
+&quot;Licensed Patents&quot; mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
+
+&quot;Program&quot; means the Contributions distributed in accordance with this Agreement.
+
+&quot;Recipient&quot; means anyone who receives the Program under this Agreement, including all Contributors.
+
+2. GRANT OF RIGHTS
+
+a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient&apos;s responsibility to acquire that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained within the Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor (&quot;Commercial Contributor&quot;) hereby agrees to defend and indemnify every other Contributor (&quot;Indemnified Contributor&quot;) against any losses, damages and costs (collectively &quot;Losses&quot;) arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor&apos;s responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient&apos;s patent(s), then such Recipient&apos;s rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
+
+All Recipient&apos;s rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient&apos;s rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient&apos;s obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
+   </license>
+
+   <url>
+      <update label="Android Update Site" url="https://dl-ssl.google.com/android/eclipse/"/>
+   </url>
+
+   <requires>
+      <import plugin="com.android.ide.eclipse.ddms"/>
+      <import plugin="org.eclipse.core.runtime"/>
+      <import plugin="org.eclipse.core.resources"/>
+      <import plugin="org.eclipse.debug.core"/>
+      <import plugin="org.eclipse.debug.ui"/>
+      <import plugin="org.eclipse.jdt"/>
+      <import plugin="org.eclipse.ant.core"/>
+      <import plugin="org.eclipse.jdt.core"/>
+      <import plugin="org.eclipse.jdt.ui"/>
+      <import plugin="org.eclipse.jdt.launching"/>
+      <import plugin="org.eclipse.jface.text"/>
+      <import plugin="org.eclipse.ui.editors"/>
+      <import plugin="org.eclipse.ui.workbench.texteditor"/>
+      <import plugin="org.eclipse.ui.console"/>
+      <import plugin="org.eclipse.core.filesystem"/>
+      <import plugin="org.eclipse.ui"/>
+      <import plugin="org.eclipse.ui.ide"/>
+      <import plugin="org.eclipse.ui.forms"/>
+      <import plugin="org.eclipse.gef"/>
+      <import plugin="org.eclipse.ui.browser"/>
+      <import plugin="org.eclipse.ui.views"/>
+      <import plugin="org.eclipse.wst.sse.core"/>
+      <import plugin="org.eclipse.wst.sse.ui"/>
+      <import plugin="org.eclipse.wst.xml.core"/>
+      <import plugin="org.eclipse.wst.xml.ui"/>
+   </requires>
+
+   <plugin
+         id="com.android.ide.eclipse.adt"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/tools/eclipse/features/com.android.ide.eclipse.ddms/.project b/tools/eclipse/features/com.android.ide.eclipse.ddms/.project
new file mode 100644
index 0000000..f80ff60
--- /dev/null
+++ b/tools/eclipse/features/com.android.ide.eclipse.ddms/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>ddms-feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/eclipse/features/com.android.ide.eclipse.ddms/build.properties b/tools/eclipse/features/com.android.ide.eclipse.ddms/build.properties
new file mode 100644
index 0000000..64f93a9
--- /dev/null
+++ b/tools/eclipse/features/com.android.ide.eclipse.ddms/build.properties
@@ -0,0 +1 @@
+bin.includes = feature.xml
diff --git a/tools/eclipse/features/com.android.ide.eclipse.ddms/feature.xml b/tools/eclipse/features/com.android.ide.eclipse.ddms/feature.xml
new file mode 100644
index 0000000..dfdf985
--- /dev/null
+++ b/tools/eclipse/features/com.android.ide.eclipse.ddms/feature.xml
@@ -0,0 +1,237 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="com.android.ide.eclipse.ddms"
+      label="Android DDMS"
+      version="0.9.0.qualifier"
+      provider-name="The Android Open Source Project">
+
+   <description>
+      Android Dalvik Debug Monitor Service
+   </description>
+
+   <copyright>
+      Copyright (C) 2007 The Android Open Source Project
+   </copyright>
+
+   <license url="http://www.apache.org/licenses/LICENSE-2.0">
+      Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      &quot;License&quot; shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      &quot;Licensor&quot; shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      &quot;Legal Entity&quot; shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      &quot;control&quot; means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      &quot;You&quot; (or &quot;Your&quot;) shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      &quot;Source&quot; form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      &quot;Object&quot; form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      &quot;Work&quot; shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      &quot;Derivative Works&quot; shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      &quot;Contribution&quot; shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, &quot;submitted&quot;
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as &quot;Not a Contribution.&quot;
+
+      &quot;Contributor&quot; shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a &quot;NOTICE&quot; text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an &quot;AS IS&quot; BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets &quot;[]&quot;
+      replaced with your own identifying information. (Don&apos;t include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same &quot;printed page&quot; as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+   </license>
+
+   <url>
+      <update label="Android Update Site" url="https://dl-ssl.google.com/android/eclipse/"/>
+   </url>
+
+   <requires>
+      <import plugin="org.eclipse.ui"/>
+      <import plugin="org.eclipse.core.runtime"/>
+      <import plugin="org.eclipse.ui.console"/>
+   </requires>
+
+   <plugin
+         id="com.android.ide.eclipse.ddms"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/tools/eclipse/features/com.android.ide.eclipse.tests/.project b/tools/eclipse/features/com.android.ide.eclipse.tests/.project
new file mode 100644
index 0000000..6a16276
--- /dev/null
+++ b/tools/eclipse/features/com.android.ide.eclipse.tests/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>adt-tests-feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/eclipse/features/com.android.ide.eclipse.tests/build.properties b/tools/eclipse/features/com.android.ide.eclipse.tests/build.properties
new file mode 100644
index 0000000..64f93a9
--- /dev/null
+++ b/tools/eclipse/features/com.android.ide.eclipse.tests/build.properties
@@ -0,0 +1 @@
+bin.includes = feature.xml
diff --git a/tools/eclipse/features/com.android.ide.eclipse.tests/feature.xml b/tools/eclipse/features/com.android.ide.eclipse.tests/feature.xml
new file mode 100644
index 0000000..2a3a74f
--- /dev/null
+++ b/tools/eclipse/features/com.android.ide.eclipse.tests/feature.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="com.android.ide.eclipse.tests"
+      label="ADT Tests"
+      version="0.9.0.qualifier"
+      provider-name="The Android Open Source Project">
+
+   <copyright>
+      Copyright (C) 2007 The Android Open Source Project
+   </copyright>
+
+   <requires>
+      <import plugin="org.eclipse.ui"/>
+      <import plugin="org.eclipse.core.runtime"/>
+      <import plugin="org.eclipse.core.resources"/>
+      <import plugin="com.android.ide.eclipse.adt"/>
+      <import plugin="org.junit"/>
+      <import plugin="org.eclipse.jdt.core"/>
+      <import plugin="org.eclipse.jdt.launching"/>
+      <import plugin="org.eclipse.ui.views"/>
+   </requires>
+
+   <plugin
+         id="com.android.ide.eclipse.tests"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/tools/eclipse/plugins/README.txt b/tools/eclipse/plugins/README.txt
new file mode 100644
index 0000000..184d731
--- /dev/null
+++ b/tools/eclipse/plugins/README.txt
@@ -0,0 +1,114 @@
+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
new file mode 100644
index 0000000..c3c8c10
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/.classpath
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry excluding="Makefile|resources/" kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="lib" path="jarutils.jar"/>
+	<classpathentry kind="lib" path="androidprefs.jar"/>
+	<classpathentry kind="lib" path="sdkstats.jar"/>
+	<classpathentry kind="lib" path="kxml2-2.3.0.jar"/>
+	<classpathentry kind="lib" path="layoutlib_api.jar"/>
+	<classpathentry kind="lib" path="layoutlib_utils.jar"/>
+	<classpathentry kind="lib" path="ninepatch.jar"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/SdkUiLib"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/.project b/tools/eclipse/plugins/com.android.ide.eclipse.adt/.project
new file mode 100644
index 0000000..c7b1ad4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/.project
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>adt</name>
+	<comment></comment>
+	<projects>
+		<project>SdkLib</project>
+		<project>SdkUiLib</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF b/tools/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..a464d5c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF
@@ -0,0 +1,79 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Android Development Toolkit
+Bundle-SymbolicName: com.android.ide.eclipse.adt;singleton:=true
+Bundle-Version: 0.9.0.qualifier
+Bundle-ClassPath: .,
+ jarutils.jar,
+ androidprefs.jar,
+ sdkstats.jar,
+ kxml2-2.3.0.jar,
+ layoutlib_api.jar,
+ ninepatch.jar,
+ layoutlib_utils.jar,
+ sdklib.jar,
+ sdkuilib.jar
+Bundle-Activator: com.android.ide.eclipse.adt.AdtPlugin
+Bundle-Vendor: The Android Open Source Project
+Require-Bundle: com.android.ide.eclipse.ddms,
+ org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.debug.core,
+ org.eclipse.debug.ui,
+ org.eclipse.jdt,
+ org.eclipse.ant.core,
+ org.eclipse.jdt.core,
+ org.eclipse.jdt.ui,
+ org.eclipse.jdt.launching,
+ org.eclipse.jface.text,
+ org.eclipse.ui.editors,
+ org.eclipse.ui.workbench.texteditor,
+ org.eclipse.ui.console,
+ org.eclipse.core.filesystem,
+ org.eclipse.ui,
+ org.eclipse.ui.ide,
+ org.eclipse.ui.forms,
+ org.eclipse.gef,
+ org.eclipse.ui.browser,
+ org.eclipse.ui.views,
+ org.eclipse.wst.sse.core,
+ org.eclipse.wst.sse.ui,
+ org.eclipse.wst.xml.core,
+ org.eclipse.wst.xml.ui
+Eclipse-LazyStart: true
+Export-Package: com.android.ide.eclipse.adt,
+ com.android.ide.eclipse.adt.build;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.common,
+ com.android.ide.eclipse.common.project,
+ com.android.ide.eclipse.common.resources,
+ 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.wizards;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"
+
+
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/MODULE_LICENSE_EPL b/tools/eclipse/plugins/com.android.ide.eclipse.adt/MODULE_LICENSE_EPL
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/MODULE_LICENSE_EPL
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/NOTICE b/tools/eclipse/plugins/com.android.ide.eclipse.adt/NOTICE
new file mode 100644
index 0000000..49c101d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/NOTICE
@@ -0,0 +1,224 @@
+*Eclipse Public License - v 1.0*
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF
+THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+*1. DEFINITIONS*
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and
+documentation distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and
+are distributed by that particular Contributor. A Contribution
+'originates' from a Contributor if it was added to the Program by such
+Contributor itself or anyone acting on such Contributor's behalf.
+Contributions do not include additions to the Program which: (i) are
+separate modules of software distributed in conjunction with the Program
+under their own license agreement, and (ii) are not derivative works of
+the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which
+are necessarily infringed by the use or sale of its Contribution alone
+or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this
+Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement,
+including all Contributors.
+
+*2. GRANT OF RIGHTS*
+
+a) Subject to the terms of this Agreement, each Contributor hereby
+grants Recipient a non-exclusive, worldwide, royalty-free copyright
+license to reproduce, prepare derivative works of, publicly display,
+publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and
+object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby
+grants Recipient a non-exclusive, worldwide, royalty-free patent license
+under Licensed Patents to make, use, sell, offer to sell, import and
+otherwise transfer the Contribution of such Contributor, if any, in
+source code and object code form. This patent license shall apply to the
+combination of the Contribution and the Program if, at the time the
+Contribution is added by the Contributor, such addition of the
+Contribution causes such combination to be covered by the Licensed
+Patents. The patent license shall not apply to any other combinations
+which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the
+licenses to its Contributions set forth herein, no assurances are
+provided by any Contributor that the Program does not infringe the
+patent or other intellectual property rights of any other entity. Each
+Contributor disclaims any liability to Recipient for claims brought by
+any other entity based on infringement of intellectual property rights
+or otherwise. As a condition to exercising the rights and licenses
+granted hereunder, each Recipient hereby assumes sole responsibility to
+secure any other intellectual property rights needed, if any. For
+example, if a third party patent license is required to allow Recipient
+to distribute the Program, it is Recipient's responsibility to acquire
+that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient
+copyright rights in its Contribution, if any, to grant the copyright
+license set forth in this Agreement.
+
+*3. REQUIREMENTS*
+
+A Contributor may choose to distribute the Program in object code form
+under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties
+and conditions, express and implied, including warranties or conditions
+of title and non-infringement, and implied warranties or conditions of
+merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability for
+damages, including direct, indirect, special, incidental and
+consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are
+offered by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such
+Contributor, and informs licensees how to obtain it in a reasonable
+manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained
+within the Program.
+
+Each Contributor must identify itself as the originator of its
+Contribution, if any, in a manner that reasonably allows subsequent
+Recipients to identify the originator of the Contribution.
+
+*4. COMMERCIAL DISTRIBUTION*
+
+Commercial distributors of software may accept certain responsibilities
+with respect to end users, business partners and the like. While this
+license is intended to facilitate the commercial use of the Program, the
+Contributor who includes the Program in a commercial product offering
+should do so in a manner which does not create potential liability for
+other Contributors. Therefore, if a Contributor includes the Program in
+a commercial product offering, such Contributor ("Commercial
+Contributor") hereby agrees to defend and indemnify every other
+Contributor ("Indemnified Contributor") against any losses, damages and
+costs (collectively "Losses") arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified
+Contributor to the extent caused by the acts or omissions of such
+Commercial Contributor in connection with its distribution of the
+Program in a commercial product offering. The obligations in this
+section do not apply to any claims or Losses relating to any actual or
+alleged intellectual property infringement. In order to qualify, an
+Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial
+Contributor to control, and cooperate with the Commercial Contributor
+in, the defense and any related settlement negotiations. The Indemnified
+Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those
+performance claims and warranties, and if a court requires any other
+Contributor to pay any damages as a result, the Commercial Contributor
+must pay those damages.
+
+*5. NO WARRANTY*
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED
+ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES
+OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR
+A PARTICULAR PURPOSE. Each Recipient is solely responsible for
+determining the appropriateness of using and distributing the Program
+and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program
+errors, compliance with applicable laws, damage to or loss of data,
+programs or equipment, and unavailability or interruption of operations.
+
+*6. DISCLAIMER OF LIABILITY*
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
+ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
+DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+*7. GENERAL*
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further action
+by the parties hereto, such provision shall be reformed to the minimum
+extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including
+a cross-claim or counterclaim in a lawsuit) alleging that the Program
+itself (excluding combinations of the Program with other software or
+hardware) infringes such Recipient's patent(s), then such Recipient's
+rights granted under Section 2(b) shall terminate as of the date such
+litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails
+to comply with any of the material terms or conditions of this Agreement
+and does not cure such failure in a reasonable period of time after
+becoming aware of such noncompliance. If all Recipient's rights under
+this Agreement terminate, Recipient agrees to cease use and distribution
+of the Program as soon as reasonably practicable. However, Recipient's
+obligations under this Agreement and any licenses granted by Recipient
+relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement,
+but in order to avoid inconsistency the Agreement is copyrighted and may
+only be modified in the following manner. The Agreement Steward reserves
+the right to publish new versions (including revisions) of this
+Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the
+initial Agreement Steward. The Eclipse Foundation may assign the
+responsibility to serve as the Agreement Steward to a suitable separate
+entity. Each new version of the Agreement will be given a distinguishing
+version number. The Program (including Contributions) may always be
+distributed subject to the version of the Agreement under which it was
+received. In addition, after a new version of the Agreement is
+published, Contributor may elect to distribute the Program (including
+its Contributions) under the new version. Except as expressly stated in
+Sections 2(a) and 2(b) above, Recipient receives no rights or licenses
+to the intellectual property of any Contributor under this Agreement,
+whether expressly, by implication, estoppel or otherwise. All rights in
+the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the
+intellectual property laws of the United States of America. No party to
+this Agreement will bring a legal action under this Agreement more than
+one year after the cause of action arose. Each party waives its rights
+to a jury trial in any resulting litigation.
+
+ 
+
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/about.ini b/tools/eclipse/plugins/com.android.ide.eclipse.adt/about.ini
new file mode 100644
index 0000000..fddaef0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/about.ini
@@ -0,0 +1 @@
+featureImage=icons/android_32X32.jpg
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/build.properties b/tools/eclipse/plugins/com.android.ide.eclipse.adt/build.properties
new file mode 100644
index 0000000..c7eb749
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/build.properties
@@ -0,0 +1,17 @@
+bin.includes = plugin.xml,\
+               META-INF/,\
+               icons/,\
+               .,\
+               templates/,\
+               about.ini,\
+               jarutils.jar,\
+               androidprefs.jar,\
+               sdkstats.jar,\
+               kxml2-2.3.0.jar,\
+               layoutlib_api.jar,\
+               layoutlib_utils.jar,\
+               ninepatch.jar,\
+               sdklib.jar,\
+               sdkuilib.jar
+source.. = src/
+output.. = bin/
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/add.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/add.png
new file mode 100644
index 0000000..eefc2ca
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/add.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android.png
new file mode 100644
index 0000000..3779d4d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_32X32.jpg b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_32X32.jpg
new file mode 100644
index 0000000..823670b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_32X32.jpg
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_large.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_large.png
new file mode 100644
index 0000000..64e3601
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_large.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_project.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_project.png
new file mode 100644
index 0000000..5334568
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/android_project.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/az_sort.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/az_sort.png
new file mode 100644
index 0000000..5d92f76
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/az_sort.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/delete.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/delete.png
new file mode 100644
index 0000000..db5fab8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/delete.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/dimension.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/dimension.png
new file mode 100644
index 0000000..10057c8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/dimension.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/down.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/down.png
new file mode 100644
index 0000000..36cd223
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/down.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/dpi.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/dpi.png
new file mode 100644
index 0000000..fae5e96
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/dpi.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/error.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/error.png
new file mode 100644
index 0000000..1eecf2c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/error.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/keyboard.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/keyboard.png
new file mode 100644
index 0000000..7911a85
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/keyboard.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/language.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/language.png
new file mode 100644
index 0000000..a727dd5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/language.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mainLaunchTab.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mainLaunchTab.png
new file mode 100644
index 0000000..2540fbb
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mainLaunchTab.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/match.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/match.png
new file mode 100644
index 0000000..7e939c2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/match.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mcc.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mcc.png
new file mode 100644
index 0000000..4dc95d7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mcc.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mnc.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mnc.png
new file mode 100644
index 0000000..aefffe4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/mnc.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/navpad.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/navpad.png
new file mode 100644
index 0000000..c2bb79a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/navpad.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_adt_project.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_adt_project.png
new file mode 100644
index 0000000..0f0e883
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_adt_project.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_xml.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_xml.png
new file mode 100644
index 0000000..8273185
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_xml.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/orientation.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/orientation.png
new file mode 100644
index 0000000..423c3cd
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/orientation.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/region.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/region.png
new file mode 100644
index 0000000..9608cd6
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/region.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/text_input.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/text_input.png
new file mode 100644
index 0000000..b4ddc87
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/text_input.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/touch.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/touch.png
new file mode 100644
index 0000000..6536576
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/touch.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/up.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/up.png
new file mode 100644
index 0000000..35b9a46
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/up.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/warning.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/warning.png
new file mode 100644
index 0000000..ca3b6ed
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/icons/warning.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
new file mode 100644
index 0000000..d6c9ac1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml
@@ -0,0 +1,502 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+   <extension
+         id="com.android.ide.eclipse.common.xmlProblem"
+         name="Android XML Format Problem"
+         point="org.eclipse.core.resources.markers">
+      <super type="org.eclipse.core.resources.problemmarker"/>
+      <super type="org.eclipse.core.resources.textmarker"/>
+      <persistent value="true"/>
+   </extension>
+   <extension
+         id="com.android.ide.eclipse.common.aaptProblem"
+         name="Android AAPT Problem"
+         point="org.eclipse.core.resources.markers">
+      <super type="org.eclipse.core.resources.problemmarker"/>
+      <super type="org.eclipse.core.resources.textmarker"/>
+      <persistent value="true"/>
+   </extension>
+   <extension
+         id="com.android.ide.eclipse.common.aapt2Problem"
+         name="Android AAPT Problem"
+         point="org.eclipse.core.resources.markers">
+      <super type="org.eclipse.core.resources.problemmarker"/>
+      <super type="org.eclipse.core.resources.textmarker"/>
+      <persistent value="true"/>
+   </extension>
+   <extension
+         id="com.android.ide.eclipse.common.aidlProblem"
+         name="Android AIDL Problem"
+         point="org.eclipse.core.resources.markers">
+      <super type="org.eclipse.core.resources.problemmarker"/>
+      <super type="org.eclipse.core.resources.textmarker"/>
+      <persistent value="true"/>
+   </extension>
+   <extension
+        id="com.android.ide.eclipse.common.androidProblem"
+        name="Android XML Content Problem"
+        point="org.eclipse.core.resources.markers">
+      <super type="org.eclipse.core.resources.problemmarker"/>
+      <super type="org.eclipse.core.resources.textmarker"/>
+      <persistent value="true"/>
+   </extension>
+   <extension
+         id="ResourceManagerBuilder"
+         name="Android Resource Manager"
+         point="org.eclipse.core.resources.builders">
+      <builder
+            hasNature="true">
+         <run class="com.android.ide.eclipse.adt.build.ResourceManagerBuilder"/>
+      </builder>
+   </extension>
+   <extension
+         id="PreCompilerBuilder"
+         name="Android Pre Compiler"
+         point="org.eclipse.core.resources.builders">
+      <builder
+            hasNature="true">
+         <run class="com.android.ide.eclipse.adt.build.PreCompilerBuilder"/>
+      </builder>
+   </extension>
+   <extension
+         id="ApkBuilder"
+         name="Android Package Builder"
+         point="org.eclipse.core.resources.builders">
+      <builder
+            hasNature="true">
+         <run class="com.android.ide.eclipse.adt.build.ApkBuilder"/>
+      </builder>
+   </extension>
+   <extension
+         id="AndroidNature"
+         name="AndroidNature"
+         point="org.eclipse.core.resources.natures">
+      <runtime>
+         <run class="com.android.ide.eclipse.adt.project.AndroidNature"/>
+      </runtime>
+      <builder id="com.android.ide.eclipse.adt.ResourceManagerBuilder"/>
+      <builder id="com.android.ide.eclipse.adt.PreCompilerBuilder"/>
+      <builder id="com.android.ide.eclipse.adt.ApkBuilder"/>
+   </extension>
+   <extension
+         point="org.eclipse.ui.newWizards">
+      <category
+            id="com.android.ide.eclipse.wizards.category"
+            name="Android"/>
+      <wizard
+            canFinishEarly="false"
+            category="com.android.ide.eclipse.wizards.category"
+            class="com.android.ide.eclipse.adt.wizards.newproject.NewProjectWizard"
+            finalPerspective="org.eclipse.jdt.ui.JavaPerspective"
+            hasPages="true"
+            icon="icons/android.png"
+            id="com.android.ide.eclipse.adt.project.NewProjectWizard"
+            name="Android Project"
+            preferredPerspectives="org.eclipse.jdt.ui.JavaPerspective"
+            project="true"/>
+      <wizard
+            canFinishEarly="false"
+            category="com.android.ide.eclipse.wizards.category"
+            class="com.android.ide.eclipse.editors.wizards.NewXmlFileWizard"
+            finalPerspective="org.eclipse.jdt.ui.JavaPerspective"
+            hasPages="true"
+            icon="icons/android.png"
+            id="com.android.ide.eclipse.editors.wizards.NewXmlFileWizard"
+            name="Android XML File"
+            preferredPerspectives="org.eclipse.jdt.ui.JavaPerspective"
+            project="false">
+      </wizard>
+   </extension>
+   <extension
+         point="org.eclipse.debug.core.launchConfigurationTypes">
+      <launchConfigurationType
+            delegate="com.android.ide.eclipse.adt.debug.launching.LaunchConfigDelegate"
+            delegateDescription="The Android Application Launcher supports running and debugging remote Android applications on devices or emulators."
+            delegateName="Android Launcher"
+            id="com.android.ide.eclipse.adt.debug.LaunchConfigType"
+            modes="debug, run"
+            name="Android Application"
+            public="true"
+            sourceLocatorId="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"
+            sourcePathComputerId="org.eclipse.jdt.launching.sourceLookup.javaSourcePathComputer">
+      </launchConfigurationType>
+   </extension>
+   <extension
+         point="org.eclipse.debug.ui.launchConfigurationTypeImages">
+      <launchConfigurationTypeImage
+            configTypeID="com.android.ide.eclipse.adt.debug.LaunchConfigType"
+            icon="icons/android.png"
+            id="com.android.ide.eclipse.adt.debug.LaunchConfigTypeImage"/>
+   </extension>
+   <extension
+         point="org.eclipse.debug.ui.launchConfigurationTabGroups">
+      <launchConfigurationTabGroup
+            class="com.android.ide.eclipse.adt.debug.ui.LaunchConfigTabGroup"
+            description="Android Application"
+            id="com.android.ide.eclipse.adt.debug.LaunchConfigTabGroup"
+            type="com.android.ide.eclipse.adt.debug.LaunchConfigType"/>
+   </extension>
+   <extension
+         point="org.eclipse.debug.ui.launchShortcuts">
+      <shortcut
+            category="com.android.ide.eclipse.adt.debug.LaunchConfigType"
+            class="com.android.ide.eclipse.adt.debug.launching.LaunchShortcut"
+            icon="icons/android.png"
+            id="com.android.ide.eclipse.adt.debug.launching.LaunchShortcut"
+            label="Android Application"
+            modes="debug, run">
+        <contextualLaunch>
+           <enablement>
+             <with variable="selection">
+               <count value="1"/>
+               <iterate>
+                  <and>
+                     <test property="org.eclipse.jdt.launching.isContainer"/>
+                     <test property="org.eclipse.jdt.launching.hasProjectNature" args="com.android.ide.eclipse.adt.AndroidNature"/>
+                  </and>
+               </iterate>
+               </with>
+           </enablement>
+         </contextualLaunch>
+         <perspective id="org.eclipse.jdt.ui.JavaPerspective"/>
+         <perspective id="org.eclipse.debug.ui.DebugPerspective"/>
+         <description
+               description="Runs an Android Application"
+               mode="run">
+         </description>
+         <description
+               description="Debugs an Android Application"
+               mode="debug">
+         </description>
+      </shortcut>
+   </extension>
+   <extension
+         point="org.eclipse.ui.popupMenus">
+      <objectContribution
+            id="com.android.ide.eclipse.adt.contribution1"
+            nameFilter="*"
+            objectClass="org.eclipse.core.resources.IProject"
+            adaptable="true">
+         <menu
+               id="com.android.ide.eclipse.adt.AndroidTools"
+               label="Android Tools"
+               path="additions">
+            <separator name="group1"/>
+         </menu>
+         <visibility>
+            <not>
+            <or>
+            <objectState
+                name="projectNature"
+                value="com.android.ide.eclipse.adt.AndroidNature"/>
+            <objectState
+                name="open"
+                value="false"/>
+            </or>
+            </not>
+         </visibility>
+         <action
+               class="com.android.ide.eclipse.adt.project.ConvertToAndroidAction"
+               enablesFor="1"
+               id="com.android.ide.eclipse.adt.ConvertToAndroidAction"
+               label="Convert To Android Project"
+               menubarPath="com.android.ide.eclipse.adt.AndroidTools/group1"/>
+      </objectContribution>
+      <objectContribution
+            id="com.android.ide.eclipse.adt.contribution2"
+            nameFilter="*"
+            objectClass="org.eclipse.core.resources.IProject"
+            adaptable="true">
+         <menu
+               id="com.android.ide.eclipse.adt.AndroidTools"
+               label="Android Tools"
+               path="additions">
+            <separator name="group1"/>
+            <separator name="group2"/>
+         </menu>
+         <filter
+               name="projectNature"
+               value="com.android.ide.eclipse.adt.AndroidNature">
+         </filter>
+         <action
+               class="com.android.ide.eclipse.adt.project.CreateAidlImportAction"
+               enablesFor="1"
+               id="com.android.ide.eclipse.adt.project.CreateAidlImportAction"
+               label="Create Aidl preprocess file for Parcelable classes"
+               menubarPath="com.android.ide.eclipse.adt.AndroidTools/group1"/>
+         <action
+               class="com.android.ide.eclipse.adt.project.NewXmlFileWizardAction"
+               enablesFor="1"
+               id="com.android.ide.eclipse.adt.project.NewXmlFileWizardAction"
+               label="New Resource File..."
+               menubarPath="com.android.ide.eclipse.adt.AndroidTools/group1">
+         </action>
+         <action
+               class="com.android.ide.eclipse.adt.project.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"
+               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"
+               enablesFor="1"
+               id="com.android.ide.eclipse.adt.project.FixProjectAction"
+               label="Fix Project Properties"
+               menubarPath="com.android.ide.eclipse.adt.AndroidTools/group3"/>
+      </objectContribution>
+   </extension>
+   <extension
+         point="org.eclipse.ui.preferencePages">
+      <page
+            class="com.android.ide.eclipse.adt.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"
+            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"
+            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"
+            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"/>
+   </extension>
+   <extension
+         id="com.android.ide.eclipse.adt.adtProblem"
+         name="Android ADT Problem"
+         point="org.eclipse.core.resources.markers">
+      <super type="org.eclipse.core.resources.problemmarker"/>
+      <persistent value="true"/>
+   </extension>
+   <extension
+         id="com.android.ide.eclipse.adt.targetProblem"
+         name="Android Target Problem"
+         point="org.eclipse.core.resources.markers">
+      <super type="org.eclipse.core.resources.problemmarker"/>
+      <persistent value="false"/>
+   </extension>
+   <extension
+         point="org.eclipse.ui.perspectiveExtensions">
+      <perspectiveExtension targetID="org.eclipse.jdt.ui.JavaPerspective">
+         <newWizardShortcut id="com.android.ide.eclipse.adt.project.NewProjectWizard" />
+         <newWizardShortcut
+               id="com.android.ide.eclipse.editors.wizards.NewXmlFileWizard">
+         </newWizardShortcut>
+      </perspectiveExtension>
+      <perspectiveExtension targetID="org.eclipse.debug.ui.DebugPerspective">
+         <viewShortcut id="com.android.ide.eclipse.ddms.views.LogCatView"/>
+         <viewShortcut id="com.android.ide.eclipse.ddms.views.DeviceView"/>
+      </perspectiveExtension>
+   </extension>
+   <extension
+         point="org.eclipse.ui.ide.projectNatureImages">
+      <image
+            icon="icons/android_project.png"
+            id="com.android.ide.eclipse.adt.AndroidNature.image"
+            natureId="com.android.ide.eclipse.adt.AndroidNature">
+      </image>
+   </extension>
+   <extension
+         point="org.eclipse.jdt.core.classpathContainerInitializer">
+      <classpathContainerInitializer
+            class="com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer"
+            id="com.android.ide.eclipse.adt.project.AndroidClasspathContainerInitializer">
+      </classpathContainerInitializer>
+      <classpathContainerInitializer
+            class="com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer"
+            id="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK">
+      </classpathContainerInitializer>
+   </extension>
+   <extension
+         point="org.eclipse.ui.exportWizards">
+      <category
+            id="com.android.ide.eclipse.wizards.category"
+            name="Android">
+      </category>
+      <wizard
+            category="com.android.ide.eclipse.wizards.category"
+            class="com.android.ide.eclipse.adt.project.export.ExportWizard"
+            icon="icons/android.png"
+            id="com.android.ide.eclipse.adt.project.ExportWizard"
+            name="Export Android Application">
+      </wizard>
+   </extension>
+   <extension
+         point="org.eclipse.ui.commands">
+      <command
+            name="Debug Android Application"
+            description="Debug Android Application"
+            categoryId="org.eclipse.debug.ui.category.run"
+            id="com.android.ide.eclipse.adt.debug.launching.LaunchShortcut.debug">
+      </command>
+      <command
+            name="Run Android Application"
+            description="Run Android Application"
+            categoryId="org.eclipse.debug.ui.category.run"
+            id="com.android.ide.eclipse.adt.debug.launching.LaunchShortcut.run">
+      </command>
+      <keyBinding
+            keySequence="M3+M2+A D"
+            contextId="org.eclipse.ui.globalScope"
+            commandId="com.android.ide.eclipse.adt.debug.launching.LaunchShortcut.debug"
+            keyConfigurationId="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </keyBinding>
+      <keyBinding
+            keySequence="M3+M2+A R"
+            contextId="org.eclipse.ui.globalScope"
+            commandId="com.android.ide.eclipse.adt.debug.launching.LaunchShortcut.run"
+            keyConfigurationId="org.eclipse.ui.defaultAcceleratorConfiguration">
+      </keyBinding>
+   </extension>
+   <extension
+         point="org.eclipse.ui.decorators">
+      <decorator
+            adaptable="true"
+            class="com.android.ide.eclipse.adt.project.FolderDecorator"
+            id="com.android.ide.eclipse.adt.project.FolderDecorator"
+            label="Android Decorator"
+            lightweight="true"
+            location="TOP_RIGHT"
+            objectClass="org.eclipse.core.resources.IFolder"
+            state="true">
+      </decorator>
+   </extension>
+   <extension
+         point="org.eclipse.ui.editors">
+      <editor
+            class="com.android.ide.eclipse.editors.manifest.ManifestEditor"
+            default="true"
+            filenames="AndroidManifest.xml"
+            icon="icons/android.png"
+            id="com.android.ide.eclipse.editors.manifest.ManifestEditor"
+            name="Android Manifest Editor">
+      </editor>
+      <editor
+            class="com.android.ide.eclipse.editors.resources.ResourcesEditor"
+            default="false"
+            extensions="xml"
+            icon="icons/android.png"
+            id="com.android.ide.eclipse.editors.resources.ResourcesEditor"
+            name="Android Resource Editor">
+      </editor>
+      <editor
+            class="com.android.ide.eclipse.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"
+            name="Android Layout Editor">
+      </editor>
+      <editor
+            class="com.android.ide.eclipse.editors.menu.MenuEditor"
+            default="false"
+            extensions="xml"
+            icon="icons/android.png"
+            id="com.android.ide.eclipse.editors.menu.MenuEditor"
+            name="Android Menu Editor">
+      </editor>
+      <editor
+            class="com.android.ide.eclipse.editors.xml.XmlEditor"
+            default="false"
+            extensions="xml"
+            icon="icons/android.png"
+            id="com.android.ide.eclipse.editors.xml.XmlEditor"
+            name="Android Xml Resources Editor">
+      </editor>
+   </extension>
+   <extension
+         point="org.eclipse.ui.views">
+      <view
+            allowMultiple="false"
+            category="com.android.ide.eclipse.ddms.views.category"
+            class="com.android.ide.eclipse.editors.resources.explorer.ResourceExplorerView"
+            icon="icons/android.png"
+            id="com.android.ide.eclipse.editors.resources.explorer.ResourceExplorerView"
+            name="Resource Explorer">
+      </view>
+   </extension>
+   <extension
+         point="org.eclipse.wst.sse.ui.editorConfiguration">
+      <sourceViewerConfiguration
+            class="com.android.ide.eclipse.editors.manifest.ManifestSourceViewerConfig"
+            target="com.android.ide.eclipse.editors.manifest.ManifestEditor">
+      </sourceViewerConfiguration>
+      <sourceViewerConfiguration
+            class="com.android.ide.eclipse.editors.resources.ResourcesSourceViewerConfig"
+            target="com.android.ide.eclipse.editors.resources.ResourcesEditor">
+      </sourceViewerConfiguration>
+      <sourceViewerConfiguration
+            class="com.android.ide.eclipse.editors.layout.LayoutSourceViewerConfig"
+            target="com.android.ide.eclipse.editors.layout.LayoutEditor">
+      </sourceViewerConfiguration>
+      <sourceViewerConfiguration
+            class="com.android.ide.eclipse.editors.menu.MenuSourceViewerConfig"
+            target="com.android.ide.eclipse.editors.menu.MenuEditor">
+      </sourceViewerConfiguration>
+      <sourceViewerConfiguration
+            class="com.android.ide.eclipse.editors.xml.XmlSourceViewerConfig"
+            target="com.android.ide.eclipse.editors.xml.XmlEditor">
+      </sourceViewerConfiguration>
+   </extension>
+   <extension
+         point="org.eclipse.ui.propertyPages">
+      <page
+            adaptable="true"
+            class="com.android.ide.eclipse.adt.project.properties.AndroidPropertyPage"
+            id="com.android.ide.eclipse.adt.project.properties.AndroidPropertyPage"
+            name="Android"
+            nameFilter="*"
+            objectClass="org.eclipse.core.resources.IProject">
+         <enabledWhen>
+               <test property="org.eclipse.jdt.launching.hasProjectNature"
+                     args="com.android.ide.eclipse.adt.AndroidNature"/>
+         </enabledWhen>
+      </page>
+   </extension>
+   <extension
+         point="org.eclipse.ui.actionSets">
+      <actionSet
+            description="Android Wizards"
+            id="adt.actionSet1"
+            label="Android Wizards"
+            visible="true">
+         <action
+               class="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"
+               icon="icons/new_adt_project.png"
+               id="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"
+               label="New Android Project"
+               style="push"
+               toolbarPath="android_project"
+               tooltip="Opens a wizard to help create a new Android project">
+         </action>
+         <action
+               class="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction"
+               icon="icons/new_xml.png"
+               id="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction"
+               label="New Android XML File"
+               style="push"
+               toolbarPath="android_project"
+               tooltip="Opens a wizard to help create a new Android XML file">
+         </action>
+      </actionSet>
+   </extension>
+</plugin>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java
new file mode 100644
index 0000000..7304e5e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.project.internal.AndroidClasspathContainerInitializer;
+
+
+/**
+ * Constant definition class.<br>
+ * <br>
+ * Most constants have a prefix defining the content.
+ * <ul>
+ * <li><code>WS_</code> Workspace path constant. Those are absolute paths,
+ * from the project root.</li>
+ * <li><code>OS_</code> OS path constant. These paths are different depending on the platform.</li>
+ * <li><code>FN_</code> File name constant.</li>
+ * <li><code>FD_</code> Folder name constant.</li>
+ * <li><code>MARKER_</code> Resource Marker Ids constant.</li>
+ * <li><code>EXT_</code> File extension constant. This does NOT include a dot.</li>
+ * <li><code>DOT_</code> File extension constant. This start with a dot.</li>
+ * <li><code>RE_</code> Regexp constant.</li>
+ * <li><code>BUILD_</code> Build verbosity level constant. To use with
+ * <code>AdtPlugin.printBuildToConsole()</code></li>
+ * </ul>
+ */
+public class AdtConstants {
+    /** Generic marker for ADT errors. */
+    public final static String MARKER_ADT = AdtPlugin.PLUGIN_ID + ".adtProblem"; //$NON-NLS-1$
+
+    /** Marker for Android Target errors.
+     * This is not cleared on each like other markers. Instead, it's cleared
+     * when an {@link AndroidClasspathContainerInitializer} has succeeded in creating an
+     * AndroidClasspathContainer */
+    public final static String MARKER_TARGET = AdtPlugin.PLUGIN_ID + ".targetProblem"; //$NON-NLS-1$
+
+    /** Build verbosity "Always". Those messages are always displayed. */
+    public final static int BUILD_ALWAYS = 0;
+
+    /** Build verbosity level "Normal" */
+    public final static int BUILD_NORMAL = 1;
+
+    /** Build verbosity level "Verbose". Those messages are only displayed in verbose mode */
+    public final static int BUILD_VERBOSE = 2;
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java
new file mode 100644
index 0000000..61be3e5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java
@@ -0,0 +1,1372 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt;
+
+import com.android.ddmuilib.StackTracePanel;
+import com.android.ddmuilib.StackTracePanel.ISourceRevealer;
+import com.android.ddmuilib.console.DdmConsole;
+import com.android.ddmuilib.console.IDdmConsole;
+import com.android.ide.eclipse.adt.debug.launching.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.common.AndroidConstants;
+import com.android.ide.eclipse.common.EclipseUiHelper;
+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.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 org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarkerDelta;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
+import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleConstants;
+import org.eclipse.ui.console.MessageConsole;
+import org.eclipse.ui.console.MessageConsoleStream;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class AdtPlugin extends AbstractUIPlugin {
+    /** The plug-in ID */
+    public static final String PLUGIN_ID = "com.android.ide.eclipse.adt"; //$NON-NLS-1$
+    
+    public final static String PREFS_SDK_DIR = PLUGIN_ID + ".sdk"; //$NON-NLS-1$
+
+    public final static String PREFS_RES_AUTO_REFRESH = PLUGIN_ID + ".resAutoRefresh"; //$NON-NLS-1$
+
+    public final static String PREFS_BUILD_VERBOSITY = PLUGIN_ID + ".buildVerbosity"; //$NON-NLS-1$
+
+    public final static String PREFS_DEFAULT_DEBUG_KEYSTORE = PLUGIN_ID + ".defaultDebugKeyStore"; //$NON-NLS-1$
+
+    public final static String PREFS_CUSTOM_DEBUG_KEYSTORE = PLUGIN_ID + ".customDebugKeyStore"; //$NON-NLS-1$
+
+    public final static String PREFS_HOME_PACKAGE = PLUGIN_ID + ".homePackage"; //$NON-NLS-1$
+
+    public final static String PREFS_EMU_OPTIONS = PLUGIN_ID + ".emuOptions"; //$NON-NLS-1$
+    
+    /** singleton instance */
+    private static AdtPlugin sPlugin;
+
+    private static Image sAndroidLogo;
+    private static ImageDescriptor sAndroidLogoDesc;
+
+    /** default store, provided by eclipse */
+    private IPreferenceStore mStore;
+
+    /** cached location for the sdk folder */
+    private String mOsSdkLocation;
+
+    /** The global android console */
+    private MessageConsole mAndroidConsole;
+
+    /** Stream to write in the android console */
+    private MessageConsoleStream mAndroidConsoleStream;
+
+    /** Stream to write error messages to the android console */
+    private MessageConsoleStream mAndroidConsoleErrorStream;
+
+    /** Image loader object */
+    private ImageLoader mLoader;
+
+    /** Verbosity of the build */
+    private int mBuildVerbosity = AdtConstants.BUILD_NORMAL;
+
+    /** Color used in the error console */
+    private Color mRed;
+    
+    /** Load status of the SDK. Any access MUST be in a synchronized(mPostLoadProjects) block */
+    private LoadStatus mSdkIsLoaded = LoadStatus.LOADING;
+    /** Project to update once the SDK is loaded.
+     * Any access MUST be in a synchronized(mPostLoadProjectsToResolve) block */
+    private final ArrayList<IJavaProject> mPostLoadProjectsToResolve =
+            new ArrayList<IJavaProject>();
+    /** Project to check validity of cache vs actual once the SDK is loaded.
+     * Any access MUST be in a synchronized(mPostLoadProjectsToResolve) block */
+    private final ArrayList<IJavaProject> mPostLoadProjectsToCheck = new ArrayList<IJavaProject>();
+    
+    private ResourceMonitor mResourceMonitor;
+    private ArrayList<ITargetChangeListener> mTargetChangeListeners =
+            new ArrayList<ITargetChangeListener>();
+
+    /**
+     * Custom PrintStream for Dx output. This class overrides the method
+     * <code>println()</code> and adds the standard output tag with the
+     * date and the project name in front of every messages.
+     */
+    private static final class AndroidPrintStream extends PrintStream {
+        private IProject mProject;
+        private String mPrefix;
+
+        /**
+         * Default constructor with project and output stream.
+         * The project is used to get the project name for the output tag.
+         *
+         * @param project The Project
+         * @param prefix A prefix to be printed before the actual message. Can be null
+         * @param stream The Stream
+         */
+        public AndroidPrintStream(IProject project, String prefix, OutputStream stream) {
+            super(stream);
+            mProject = project;
+        }
+
+        @Override
+        public void println(String message) {
+            // write the date/project tag first.
+            String tag = StreamHelper.getMessageTag(mProject != null ? mProject.getName() : null);
+
+            print(tag);
+            if (mPrefix != null) {
+                print(mPrefix);
+            }
+
+            // then write the regular message
+            super.println(message);
+        }
+    }
+
+    /**
+     * An error handler for checkSdkLocationAndId() that will handle the generated error
+     * or warning message. Each method must return a boolean that will in turn be returned by
+     * checkSdkLocationAndId.
+     */
+    public static abstract class CheckSdkErrorHandler {
+        /** Handle an error message during sdk location check. Returns whatever
+         * checkSdkLocationAndId() should returns.
+         */
+        public abstract boolean handleError(String message);
+
+        /** Handle a warning message during sdk location check. Returns whatever
+         * checkSdkLocationAndId() should returns.
+         */
+        public abstract boolean handleWarning(String message);
+    }
+
+    /**
+     * The constructor
+     */
+    public AdtPlugin() {
+        sPlugin = this;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+     */
+    @Override
+    public void start(BundleContext context) throws Exception {
+        super.start(context);
+
+        Display display = getDisplay();
+
+        // set the default android console.
+        mAndroidConsole = new MessageConsole("Android", null); //$NON-NLS-1$
+        ConsolePlugin.getDefault().getConsoleManager().addConsoles(
+                new IConsole[] { mAndroidConsole });
+
+        // get the stream to write in the android console.
+        mAndroidConsoleStream = mAndroidConsole.newMessageStream();
+        mAndroidConsoleErrorStream = mAndroidConsole.newMessageStream();
+        mRed = new Color(display, 0xFF, 0x00, 0x00);
+
+        // because this can be run, in some cases, by a non ui thread, and beccause
+        // changing the console properties update the ui, we need to make this change
+        // in the ui thread.
+        display.asyncExec(new Runnable() {
+            public void run() {
+                mAndroidConsoleErrorStream.setColor(mRed);
+            }
+        });
+
+        // set up the ddms console to use this objects
+        DdmConsole.setConsole(new IDdmConsole() {
+            public void printErrorToConsole(String message) {
+                AdtPlugin.printErrorToConsole((String)null, message);
+            }
+            public void printErrorToConsole(String[] messages) {
+                AdtPlugin.printErrorToConsole((String)null, (Object[])messages);
+            }
+            public void printToConsole(String message) {
+                AdtPlugin.printToConsole((String)null, message);
+            }
+            public void printToConsole(String[] messages) {
+                AdtPlugin.printToConsole((String)null, (Object[])messages);
+            }
+        });
+
+        // get the eclipse store
+        mStore = getPreferenceStore();
+
+        // set the listener for the preference change
+        Preferences prefs = getPluginPreferences();
+        prefs.addPropertyChangeListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                // get the name of the property that changed.
+                String property = event.getProperty();
+
+                // if the SDK changed, we update the cached version
+                if (PREFS_SDK_DIR.equals(property)) {
+
+                    // get the new one from the preferences
+                    mOsSdkLocation = (String)event.getNewValue();
+
+                    // make sure it ends with a separator
+                    if (mOsSdkLocation.endsWith(File.separator) == false) {
+                        mOsSdkLocation = mOsSdkLocation + File.separator;
+                    }
+
+                    // finally restart adb, in case it's a different version
+                    DdmsPlugin.setAdb(getOsAbsoluteAdb(), true /* startAdb */);
+
+                    // get the SDK location and build id.
+                    if (checkSdkLocationAndId()) {
+                        // if sdk if valid, reparse it
+                        
+                        // add all the opened Android projects to the list of projects to be updated
+                        // after the SDK is reloaded
+                        synchronized (getSdkLockObject()) {
+                            // get the project to refresh.
+                            IJavaProject[] androidProjects = BaseProjectHelper.getAndroidProjects();
+                            mPostLoadProjectsToResolve.addAll(Arrays.asList(androidProjects));
+                        }
+    
+                        // parse the SDK resources at the new location
+                        parseSdkContent();
+                    }
+                } else if (PREFS_BUILD_VERBOSITY.equals(property)) {
+                    mBuildVerbosity = BuildPreferencePage.getBuildLevel(
+                            mStore.getString(PREFS_BUILD_VERBOSITY));
+                }
+            }
+        });
+
+        mOsSdkLocation = mStore.getString(PREFS_SDK_DIR);
+
+        // make sure it ends with a separator. Normally this is done when the preference
+        // is set. But to make sure older version still work, we fix it here as well.
+        if (mOsSdkLocation.length() > 0 && mOsSdkLocation.endsWith(File.separator) == false) {
+            mOsSdkLocation = mOsSdkLocation + File.separator;
+        }
+
+        // check the location of SDK
+        final boolean isSdkLocationValid = checkSdkLocationAndId();
+        
+        mBuildVerbosity = BuildPreferencePage.getBuildLevel(
+                mStore.getString(PREFS_BUILD_VERBOSITY));
+
+        // create the loader that's able to load the images
+        mLoader = new ImageLoader(this);
+
+        // start the DdmsPlugin by setting the adb location, only if it is set already.
+        if (mOsSdkLocation.length() > 0) {
+            DdmsPlugin.setAdb(getOsAbsoluteAdb(), true);
+        }
+
+        // and give it the debug launcher for android projects
+        DdmsPlugin.setRunningAppDebugLauncher(new DdmsPlugin.IDebugLauncher() {
+            public boolean debug(String appName, int port) {
+                // search for an android project matching the process name 
+                IProject project = ProjectHelper.findAndroidProjectByAppName(appName);
+                if (project != null) {
+                    AndroidLaunchController.debugRunningApp(project, port);
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+        });
+        
+        StackTracePanel.setSourceRevealer(new ISourceRevealer() {
+            public void reveal(String applicationName, String className, int line) {
+                IProject project = ProjectHelper.findAndroidProjectByAppName(applicationName);
+                if (project != null) {
+                    BaseProjectHelper.revealSource(project, className, line);
+                }
+            }
+        });
+        
+        // setup export callback for editors
+        ExportHelper.setCallback(new IExportCallback() {
+            public void startExportWizard(IProject project) {
+                StructuredSelection selection = new StructuredSelection(project);
+                
+                ExportWizard wizard = new ExportWizard();
+                wizard.init(PlatformUI.getWorkbench(), selection);
+                WizardDialog dialog = new WizardDialog(getDisplay().getActiveShell(),
+                        wizard);
+                dialog.open();
+            }
+        });
+        
+        // initialize editors
+        startEditors();
+
+        // Ping the usage server and parse the SDK content.
+        // This is deferred in separate jobs to avoid blocking the bundle start.
+        // We also serialize them to avoid too many parallel jobs when Eclipse starts.
+        Job pingJob = createPingUsageServerJob();
+        pingJob.addJobChangeListener(new JobChangeAdapter() {
+           @Override
+            public void done(IJobChangeEvent event) {
+                super.done(event);
+    
+                // Once the ping job is finished, start the SDK parser
+                if (isSdkLocationValid) {
+                    // parse the SDK resources.
+                    parseSdkContent();
+                }
+            } 
+        });
+        // build jobs are run after other interactive jobs
+        pingJob.setPriority(Job.BUILD); 
+        // Wait 2 seconds before starting the ping job. This leaves some time to the
+        // other bundles to initialize.
+        pingJob.schedule(2000 /*milliseconds*/);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+     */
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        super.stop(context);
+        
+        stopEditors();
+        
+        mRed.dispose();
+        synchronized (AdtPlugin.class) {
+            sPlugin = null;
+        }
+    }
+
+    /** Return the image loader for the plugin */
+    public static synchronized ImageLoader getImageLoader() {
+        if (sPlugin != null) {
+            return sPlugin.mLoader;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the shared instance
+     *
+     * @return the shared instance
+     */
+    public static synchronized AdtPlugin getDefault() {
+        return sPlugin;
+    }
+
+    public static Display getDisplay() {
+        IWorkbench bench = null;
+        synchronized (AdtPlugin.class) {
+            bench = sPlugin.getWorkbench();
+        }
+
+        if (bench != null) {
+            return bench.getDisplay();
+        }
+        return null;
+    }
+
+    /** Returns the adb path relative to the sdk folder */
+    public static String getOsRelativeAdb() {
+        return SdkConstants.OS_SDK_TOOLS_FOLDER + AndroidConstants.FN_ADB;
+    }
+
+    /** Returns the emulator path relative to the sdk folder */
+    public static String getOsRelativeEmulator() {
+        return SdkConstants.OS_SDK_TOOLS_FOLDER + AndroidConstants.FN_EMULATOR;
+    }
+
+    /** Returns the absolute adb path */
+    public static String getOsAbsoluteAdb() {
+        return getOsSdkFolder() + getOsRelativeAdb();
+    }
+
+    /** Returns the absolute traceview path */
+    public static String getOsAbsoluteTraceview() {
+        return getOsSdkFolder() + SdkConstants.OS_SDK_TOOLS_FOLDER +
+                AndroidConstants.FN_TRACEVIEW;
+    }
+
+    /** Returns the absolute emulator path */
+    public static String getOsAbsoluteEmulator() {
+        return getOsSdkFolder() + getOsRelativeEmulator();
+    }
+
+    /**
+     * Returns a Url file path to the javaDoc folder.
+     */
+    public static String getUrlDoc() {
+        return ProjectHelper.getJavaDocPath(
+                getOsSdkFolder() + AndroidConstants.WS_JAVADOC_FOLDER_LEAF);
+    }
+
+    /**
+     * Returns the SDK folder.
+     * Guaranteed to be terminated by a platform-specific path separator.
+     */
+    public static synchronized String getOsSdkFolder() {
+        if (sPlugin == null) {
+            return null;
+        }
+
+        if (sPlugin.mOsSdkLocation == null) {
+            sPlugin.mOsSdkLocation = sPlugin.mStore.getString(PREFS_SDK_DIR);
+        }
+        return sPlugin.mOsSdkLocation;
+    }
+
+    public static String getOsSdkToolsFolder() {
+        return getOsSdkFolder() + SdkConstants.OS_SDK_TOOLS_FOLDER;
+    }
+
+    public static synchronized boolean getAutoResRefresh() {
+        if (sPlugin == null) {
+            return false;
+        }
+        return sPlugin.mStore.getBoolean(PREFS_RES_AUTO_REFRESH);
+    }
+
+    public static synchronized int getBuildVerbosity() {
+        if (sPlugin != null) {
+            return sPlugin.mBuildVerbosity;
+        }
+        
+        return 0;
+    }
+
+    /**
+     * Returns an image descriptor for the image file at the given
+     * plug-in relative path
+     *
+     * @param path the path
+     * @return the image descriptor
+     */
+    public static ImageDescriptor getImageDescriptor(String path) {
+    	return imageDescriptorFromPlugin(PLUGIN_ID, path);
+    }
+
+    /**
+     * Reads and returns the content of a text file embedded in the plugin jar
+     * file.
+     * @param filepath the file path to the text file
+     * @return null if the file could not be read
+     */
+    public static String readEmbeddedTextFile(String filepath) {
+        Bundle bundle = null;
+        synchronized (AdtPlugin.class) {
+            if (sPlugin != null) {
+                bundle = sPlugin.getBundle();
+            } else {
+                return null;
+            }
+        }
+        
+        // attempt to get a file to one of the template.
+        try {
+            URL url = bundle.getEntry(AndroidConstants.WS_SEP + filepath);
+            if (url != null) {
+                BufferedReader reader = new BufferedReader(
+                        new InputStreamReader(url.openStream()));
+
+                String line;
+                StringBuilder total = new StringBuilder(reader.readLine());
+                while ((line = reader.readLine()) != null) {
+                    total.append('\n');
+                    total.append(line);
+                }
+
+                return total.toString();
+            }
+        } catch (MalformedURLException e) {
+            // we'll just return null.
+        } catch (IOException e) {
+            // we'll just return null.
+        }
+
+        return null;
+    }
+
+    /**
+     * Reads and returns the content of a binary file embedded in the plugin jar
+     * file.
+     * @param filepath the file path to the text file
+     * @return null if the file could not be read
+     */
+    public static byte[] readEmbeddedFile(String filepath) {
+        Bundle bundle = null;
+        synchronized (AdtPlugin.class) {
+            if (sPlugin != null) {
+                bundle = sPlugin.getBundle();
+            } else {
+                return null;
+            }
+        }
+
+        // attempt to get a file to one of the template.
+        try {
+            URL url = bundle.getEntry(AndroidConstants.WS_SEP + filepath);
+            if (url != null) {
+                // create a buffered reader to facilitate reading.
+                BufferedInputStream stream = new BufferedInputStream(
+                        url.openStream());
+
+                // get the size to read.
+                int avail = stream.available();
+
+                // create the buffer and reads it.
+                byte[] buffer = new byte[avail];
+                stream.read(buffer);
+
+                // and return.
+                return buffer;
+            }
+        } catch (MalformedURLException e) {
+            // we'll just return null.
+        } catch (IOException e) {
+            // we'll just return null;.
+        }
+
+        return null;
+    }
+
+    /**
+     * Displays an error dialog box. This dialog box is ran asynchronously in the ui thread,
+     * therefore this method can be called from any thread.
+     * @param title The title of the dialog box
+     * @param message The error message
+     */
+    public final static void displayError(final String title, final String message) {
+        // get the current Display
+        final Display display = getDisplay();
+
+        // dialog box only run in ui thread..
+        display.asyncExec(new Runnable() {
+            public void run() {
+                Shell shell = display.getActiveShell();
+                MessageDialog.openError(shell, title, message);
+            }
+        });
+    }
+
+    /**
+     * Displays a warning dialog box. This dialog box is ran asynchronously in the ui thread,
+     * therefore this method can be called from any thread.
+     * @param title The title of the dialog box
+     * @param message The warning message
+     */
+    public final static void displayWarning(final String title, final String message) {
+        // get the current Display
+        final Display display = getDisplay();
+
+        // dialog box only run in ui thread..
+        display.asyncExec(new Runnable() {
+            public void run() {
+                Shell shell = display.getActiveShell();
+                MessageDialog.openWarning(shell, title, message);
+            }
+        });
+    }
+
+    /**
+     * Display a yes/no question dialog box. This dialog is opened synchronously in the ui thread,
+     * therefore this message can be called from any thread.
+     * @param title The title of the dialog box
+     * @param message The error message
+     * @return true if OK was clicked.
+     */
+    public final static boolean displayPrompt(final String title, final String message) {
+        // get the current Display and Shell
+        final Display display = getDisplay();
+
+        // we need to ask the user what he wants to do.
+        final boolean[] result = new boolean[1];
+        display.syncExec(new Runnable() {
+            public void run() {
+                Shell shell = display.getActiveShell();
+                result[0] = MessageDialog.openQuestion(shell, title, message);
+            }
+        });
+        return result[0];
+    }
+    
+    /**
+     * Logs a message to the default Eclipse log.
+     * 
+     * @param severity The severity code. Valid values are: {@link IStatus#OK},
+     * {@link IStatus#ERROR}, {@link IStatus#INFO}, {@link IStatus#WARNING} or
+     * {@link IStatus#CANCEL}.
+     * @param format The format string, like for {@link String#format(String, Object...)}.
+     * @param args The arguments for the format string, like for
+     * {@link String#format(String, Object...)}.
+     */
+    public static void log(int severity, String format, Object ... args) {
+        String message = String.format(format, args);
+        Status status = new Status(severity, PLUGIN_ID, message);
+        getDefault().getLog().log(status);
+    }
+
+    /**
+     * Logs an exception to the default Eclipse log.
+     * <p/>
+     * The status severity is always set to ERROR.
+     * 
+     * @param exception the exception to log.
+     * @param format The format string, like for {@link String#format(String, Object...)}.
+     * @param args The arguments for the format string, like for
+     * {@link String#format(String, Object...)}.
+     */
+    public static void log(Throwable exception, String format, Object ... args) {
+        String message = String.format(format, args);
+        Status status = new Status(IStatus.ERROR, PLUGIN_ID, message, exception);
+        getDefault().getLog().log(status);
+    }
+    
+    /**
+     * This is a mix between log(Throwable) and printErrorToConsole.
+     * <p/>
+     * This logs the exception with an ERROR severity and the given printf-like format message.
+     * The same message is then printed on the Android error console with the associated tag.
+     * 
+     * @param exception the exception to log.
+     * @param format The format string, like for {@link String#format(String, Object...)}.
+     * @param args The arguments for the format string, like for
+     * {@link String#format(String, Object...)}.
+     */
+    public static synchronized void logAndPrintError(Throwable exception, String tag,
+            String format, Object ... args) {
+        if (sPlugin != null) {
+            String message = String.format(format, args);
+            Status status = new Status(IStatus.ERROR, PLUGIN_ID, message, exception);
+            getDefault().getLog().log(status);
+            StreamHelper.printToStream(sPlugin.mAndroidConsoleErrorStream, tag, message);
+            showAndroidConsole();
+        }
+    }
+
+    /**
+     * Prints one or more error message to the android console.
+     * @param tag A tag to be associated with the message. Can be null.
+     * @param objects the objects to print through their <code>toString</code> method.
+     */
+    public static synchronized void printErrorToConsole(String tag, Object... objects) {
+        if (sPlugin != null) {
+            StreamHelper.printToStream(sPlugin.mAndroidConsoleErrorStream, tag, objects);
+    
+            showAndroidConsole();
+        }
+    }
+
+    /**
+     * Prints one or more error message to the android console.
+     * @param objects the objects to print through their <code>toString</code> method.
+     */
+    public static void printErrorToConsole(Object... objects) {
+        printErrorToConsole((String)null, objects);
+    }
+
+    /**
+     * Prints one or more error message to the android console.
+     * @param project The project to which the message is associated. Can be null.
+     * @param objects the objects to print through their <code>toString</code> method.
+     */
+    public static void printErrorToConsole(IProject project, Object... objects) {
+        String tag = project != null ? project.getName() : null;
+        printErrorToConsole(tag, objects);
+    }
+
+    /**
+     * Prints one or more build messages to the android console, filtered by Build output verbosity.
+     * @param level Verbosity level of the message.
+     * @param project The project to which the message is associated. Can be null.
+     * @param objects the objects to print through their <code>toString</code> method.
+     * @see AdtConstants#BUILD_ALWAYS
+     * @see AdtConstants#BUILD_NORMAL
+     * @see AdtConstants#BUILD_VERBOSE
+     */
+    public static synchronized void printBuildToConsole(int level, IProject project,
+            Object... objects) {
+        if (sPlugin != null) {
+            if (level <= sPlugin.mBuildVerbosity) {
+                String tag = project != null ? project.getName() : null;
+                StreamHelper.printToStream(sPlugin.mAndroidConsoleStream, tag, objects);
+            }
+        }
+    }
+
+    /**
+     * Prints one or more message to the android console.
+     * @param tag The tag to be associated with the message. Can be null.
+     * @param objects the objects to print through their <code>toString</code> method.
+     */
+    public static synchronized void printToConsole(String tag, Object... objects) {
+        if (sPlugin != null) {
+            StreamHelper.printToStream(sPlugin.mAndroidConsoleStream, tag, objects);
+        }
+    }
+
+    /**
+     * Prints one or more message to the android console.
+     * @param project The project to which the message is associated. Can be null.
+     * @param objects the objects to print through their <code>toString</code> method.
+     */
+    public static void printToConsole(IProject project, Object... objects) {
+        String tag = project != null ? project.getName() : null;
+        printToConsole(tag, objects);
+    }
+
+    /** Force the display of the android console */
+    public static void showAndroidConsole() {
+        // first make sure the console is in the workbench
+        EclipseUiHelper.showView(IConsoleConstants.ID_CONSOLE_VIEW, true);
+        
+        // now make sure it's not docked.
+        ConsolePlugin.getDefault().getConsoleManager().showConsoleView(
+                AdtPlugin.getDefault().getAndroidConsole());
+    }
+
+    /**
+     * Returns an standard PrintStream object for a specific project.<br>
+     * This PrintStream will add a date/project at the beginning of every
+     * <code>println()</code> output.
+     *
+     * @param project The project object
+     * @param prefix The prefix to be added to the message. Can be null.
+     * @return a new PrintStream
+     */
+    public static synchronized PrintStream getOutPrintStream(IProject project, String prefix) {
+        if (sPlugin != null) {
+            return new AndroidPrintStream(project, prefix, sPlugin.mAndroidConsoleStream);
+        }
+        
+        return null;
+    }
+
+    /**
+     * Returns an error PrintStream object for a specific project.<br>
+     * This PrintStream will add a date/project at the beginning of every
+     * <code>println()</code> output.
+     *
+     * @param project The project object
+     * @param prefix The prefix to be added to the message. Can be null.
+     * @return a new PrintStream
+     */
+    public static synchronized PrintStream getErrPrintStream(IProject project, String prefix) {
+        if (sPlugin != null) {
+            return new AndroidPrintStream(project, prefix, sPlugin.mAndroidConsoleErrorStream);
+        }
+        
+        return null;
+    }
+    
+    /**
+     * Returns whether the Sdk has been loaded.
+     */
+    public final LoadStatus getSdkLoadStatus() {
+        synchronized (getSdkLockObject()) {
+            return mSdkIsLoaded;
+        }
+    }
+    
+    /**
+     * Returns the lock object for SDK loading. If you wish to do things while the SDK is loading,
+     * you must synchronize on this object.
+     */
+    public final Object getSdkLockObject() {
+        return mPostLoadProjectsToResolve;
+    }
+    
+    /**
+     * Sets the given {@link IJavaProject} to have its target resolved again once the SDK finishes
+     * to load.
+     */
+    public final void setProjectToResolve(IJavaProject javaProject) {
+        synchronized (getSdkLockObject()) {
+            mPostLoadProjectsToResolve.add(javaProject);
+        }
+    }
+    
+    /**
+     * Sets the given {@link IJavaProject} to have its target checked for consistency
+     * once the SDK finishes to load. This is used if the target is resolved using cached
+     * information while the SDK is loading.
+     */
+    public final void setProjectToCheck(IJavaProject javaProject) {
+        // only lock on 
+        synchronized (getSdkLockObject()) {
+            mPostLoadProjectsToCheck.add(javaProject);
+        }
+    }
+
+    /**
+     * Checks the location of the SDK is valid and if it is, grab the SDK API version
+     * from the SDK.
+     * @return false if the location is not correct.
+     */
+    private boolean checkSdkLocationAndId() {
+        if (mOsSdkLocation == null || mOsSdkLocation.length() == 0) {
+            displayError(Messages.Dialog_Title_SDK_Location, Messages.SDK_Not_Setup);
+            return false;
+        }
+
+        return checkSdkLocationAndId(mOsSdkLocation, new CheckSdkErrorHandler() {
+            @Override
+            public boolean handleError(String message) {
+                AdtPlugin.displayError(Messages.Dialog_Title_SDK_Location,
+                        String.format(Messages.Error_Check_Prefs, message));
+                return false;
+            }
+
+            @Override
+            public boolean handleWarning(String message) {
+                AdtPlugin.displayWarning(Messages.Dialog_Title_SDK_Location, message);
+                return true;
+            }
+        });
+    }
+
+    /**
+     * Internal helper to perform the actual sdk location and id check.
+     *
+     * @param osSdkLocation The sdk directory, an OS path.
+     * @param errorHandler An checkSdkErrorHandler that can display a warning or an error.
+     * @return False if there was an error or the result from the errorHandler invocation.
+     */
+    public boolean checkSdkLocationAndId(String osSdkLocation, CheckSdkErrorHandler errorHandler) {
+        if (osSdkLocation.endsWith(File.separator) == false) {
+            osSdkLocation = osSdkLocation + File.separator;
+        }
+
+        File osSdkFolder = new File(osSdkLocation);
+        if (osSdkFolder.isDirectory() == false) {
+            return errorHandler.handleError(
+                    String.format(Messages.Could_Not_Find_Folder, osSdkLocation));
+        }
+
+        String osTools = osSdkLocation + SdkConstants.OS_SDK_TOOLS_FOLDER;
+        File toolsFolder = new File(osTools);
+        if (toolsFolder.isDirectory() == false) {
+            return errorHandler.handleError(
+                    String.format(Messages.Could_Not_Find_Folder_In_SDK,
+                            SdkConstants.FD_TOOLS, osSdkLocation));
+        }
+
+        // check the path to various tools we use
+        String[] filesToCheck = new String[] {
+                osSdkLocation + getOsRelativeAdb(),
+                osSdkLocation + getOsRelativeEmulator()
+        };
+        for (String file : filesToCheck) {
+            if (checkFile(file) == false) {
+                return errorHandler.handleError(String.format(Messages.Could_Not_Find, file));
+            }
+        }
+
+        // check the SDK build id/version and the plugin version.
+        return VersionCheck.checkVersion(osSdkLocation, errorHandler);
+    }
+
+    /**
+     * Checks if a path reference a valid existing file.
+     * @param osPath the os path to check.
+     * @return true if the file exists and is, in fact, a file.
+     */
+    private boolean checkFile(String osPath) {
+        File file = new File(osPath);
+        if (file.isFile() == false) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Creates a job than can ping the usage server.
+     */
+    private Job createPingUsageServerJob() {
+        // In order to not block the plugin loading, so we spawn another thread.
+        Job job = new Job("Android SDK Ping") {  // Job name, visible in progress view
+            @Override
+            protected IStatus run(IProgressMonitor monitor) {
+                try {
+
+                    // 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$
+                    return new Status(IStatus.ERROR, PLUGIN_ID,
+                            "pingUsageServer failed", t);
+                }
+            }
+        };
+        return job;
+    }
+    
+    /**
+     * Parses the SDK resources.
+     */
+    private void parseSdkContent() {
+        // Perform the update in a thread (here an Eclipse runtime job)
+        // since this should never block the caller (especially the start method)
+        Job job = new Job(Messages.AdtPlugin_Android_SDK_Content_Loader) {
+            @SuppressWarnings("unchecked")
+            @Override
+            protected IStatus run(IProgressMonitor monitor) {
+                try {                    
+                    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;
+                            for (IAndroidTarget target : sdk.getTargets()) {
+                                SubMonitor p2 = progress.newChild(w);
+                                IStatus status = new AndroidTargetParser(target).run(p2);
+                                if (status.getCode() != IStatus.OK) {
+                                    synchronized (getSdkLockObject()) {
+                                        mSdkIsLoaded = LoadStatus.FAILED;
+                                        mPostLoadProjectsToResolve.clear();
+                                    }
+                                    return status;
+                                }
+                            }
+                        }
+
+                        synchronized (getSdkLockObject()) {
+                            mSdkIsLoaded = LoadStatus.LOADED;
+
+                            progress.setTaskName("Check Projects");
+
+                            // check the projects that need checking.
+                            // The method modifies the list (it removes the project that
+                            // do not need to be resolved again).
+                            AndroidClasspathContainerInitializer.checkProjectsCache(
+                                    mPostLoadProjectsToCheck);
+                            
+                            mPostLoadProjectsToResolve.addAll(mPostLoadProjectsToCheck);
+                            
+                            // update the project that needs recompiling.
+                            if (mPostLoadProjectsToResolve.size() > 0) {
+                                IJavaProject[] array = mPostLoadProjectsToResolve.toArray(
+                                        new IJavaProject[mPostLoadProjectsToResolve.size()]);
+                                AndroidClasspathContainerInitializer.updateProjects(array);
+                                mPostLoadProjectsToResolve.clear();
+                            }
+                            
+                            progress.worked(10);
+                        }
+                    }
+                        
+                    // Notify resource changed listeners
+                    progress.setTaskName("Refresh UI");
+                    progress.setWorkRemaining(mTargetChangeListeners.size());
+                    
+                    // Clone the list before iterating, to avoid Concurrent Modification
+                    // exceptions
+                    final List<ITargetChangeListener> listeners =
+                            (List<ITargetChangeListener>)mTargetChangeListeners.clone();
+                    final SubMonitor progress2 = progress;
+                    AdtPlugin.getDisplay().syncExec(new Runnable() {
+                        public void run() {
+                            for (ITargetChangeListener listener : listeners) {
+                                try {
+                                    listener.onTargetsLoaded();
+                                } catch (Exception e) {
+                                    AdtPlugin.log(e, "Failed to update a TargetChangeListener.");  //$NON-NLS-1$
+                                } finally {
+                                    progress2.worked(1);
+                                }
+                            }
+                        }
+                    });
+                } finally {
+                    if (monitor != null) {
+                        monitor.done();
+                    }
+                }
+
+                return Status.OK_STATUS;
+            }
+        };
+        job.setPriority(Job.BUILD); // build jobs are run after other interactive jobs
+        job.schedule();
+    }
+    
+    /** Returns the global android console */
+    public MessageConsole getAndroidConsole() {
+        return mAndroidConsole;
+    }
+    
+    // ----- Methods for Editors -------
+
+    public void startEditors() {
+        sAndroidLogoDesc = imageDescriptorFromPlugin(AdtPlugin.PLUGIN_ID,
+                "/icons/android.png"); //$NON-NLS-1$
+        sAndroidLogo = sAndroidLogoDesc.createImage();
+        
+        // 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();
+        mResourceMonitor = ResourceMonitor.startMonitoring(ws);
+
+        if (mResourceMonitor != null) {
+            try {
+                setupDefaultEditor(mResourceMonitor);
+                ResourceManager.setup(mResourceMonitor);
+            } catch (Throwable t) {
+                log(t, "ResourceManager.setup failed"); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /**
+     * The <code>AbstractUIPlugin</code> implementation of this <code>Plugin</code>
+     * method saves this plug-in's preference and dialog stores and shuts down 
+     * its image registry (if they are in use). Subclasses may extend this
+     * method, but must send super <b>last</b>. A try-finally statement should
+     * be used where necessary to ensure that <code>super.shutdown()</code> is
+     * always done.
+     * 
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+     */
+    public void stopEditors() {
+        sAndroidLogo.dispose();
+        
+        IconFactory.getInstance().Dispose();
+        
+        // Remove the resource listener that handles compiled resources.
+        IWorkspace ws = ResourcesPlugin.getWorkspace();
+        ResourceMonitor.stopMonitoring(ws);
+
+        mRed.dispose();
+    }
+
+    /**
+     * Returns an Image for the small Android logo.
+     * 
+     * Callers should not dispose it.
+     */
+    public static Image getAndroidLogo() {
+        return sAndroidLogo;
+    }
+
+    /**
+     * Returns an {@link ImageDescriptor} for the small Android logo.
+     * 
+     * Callers should not dispose it.
+     */
+    public static ImageDescriptor getAndroidLogoDesc() {
+        return sAndroidLogoDesc;
+    }
+    
+    /**
+     * Returns the ResourceMonitor object.
+     */
+    public ResourceMonitor getResourceMonitor() {
+        return mResourceMonitor;
+    }
+
+    /**
+     * Sets up the editor to register default editors for resource files when needed.
+     * 
+     * This is called by the {@link AdtPlugin} during initialization.
+     * 
+     * @param monitor The main Resource Monitor object.
+     */
+    public void setupDefaultEditor(ResourceMonitor monitor) {
+        monitor.addFileListener(new IFileListener() {
+
+            private static final String UNKNOWN_EDITOR = "unknown-editor"; //$NON-NLS-1$
+            
+            /* (non-Javadoc)
+             * Sent when a file changed.
+             * @param file The file that changed.
+             * @param markerDeltas The marker deltas for the file.
+             * @param kind The change kind. This is equivalent to
+             * {@link IResourceDelta#accept(IResourceDeltaVisitor)}
+             * 
+             * @see IFileListener#fileChanged
+             */
+            public void fileChanged(IFile file, IMarkerDelta[] markerDeltas, int kind) {
+                if (AndroidConstants.EXT_XML.equals(file.getFileExtension())) {
+                    // The resources files must have a file path similar to
+                    //    project/res/.../*.xml
+                    // There is no support for sub folders, so the segment count must be 4
+                    if (file.getFullPath().segmentCount() == 4) {
+                        // check if we are inside the res folder.
+                        String segment = file.getFullPath().segment(1); 
+                        if (segment.equalsIgnoreCase(SdkConstants.FD_RESOURCES)) {
+                            // we are inside a res/ folder, get the actual ResourceFolder
+                            ProjectResources resources = ResourceManager.getInstance().
+                                getProjectResources(file.getProject());
+
+                            // This happens when importing old Android projects in Eclipse
+                            // that lack the container (probably because resources fail to build
+                            // properly.)
+                            if (resources == null) {
+                                log(IStatus.INFO,
+                                        "getProjectResources failed for path %1$s in project %2$s", //$NON-NLS-1$
+                                        file.getFullPath().toOSString(),
+                                        file.getProject().getName());
+                                return;
+                            }
+
+                            ResourceFolder resFolder = resources.getResourceFolder(
+                                (IFolder)file.getParent());
+                        
+                            if (resFolder != null) {
+                                if (kind == IResourceDelta.ADDED) {
+                                    resourceAdded(file, resFolder.getType());
+                                } else if (kind == IResourceDelta.CHANGED) {
+                                    resourceChanged(file, resFolder.getType());
+                                }
+                            } else {
+                                // if the res folder is null, this means the name is invalid,
+                                // in this case we remove whatever android editors that was set
+                                // as the default editor.
+                                IEditorDescriptor desc = IDE.getDefaultEditor(file);
+                                String editorId = desc.getId();
+                                if (editorId.startsWith(AndroidConstants.EDITORS_NAMESPACE)) {
+                                    // reset the default editor.
+                                    IDE.setDefaultEditor(file, null);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            private void resourceAdded(IFile file, ResourceFolderType type) {
+                // set the default editor based on the type.
+                if (type == ResourceFolderType.LAYOUT) {
+                    IDE.setDefaultEditor(file, LayoutEditor.ID);
+                } else if (type == ResourceFolderType.DRAWABLE
+                        || type == ResourceFolderType.VALUES) {
+                    IDE.setDefaultEditor(file, ResourcesEditor.ID);
+                } else if (type == ResourceFolderType.MENU) {
+                    IDE.setDefaultEditor(file, MenuEditor.ID);
+                } else if (type == ResourceFolderType.XML) {
+                    if (XmlEditor.canHandleFile(file)) {
+                        IDE.setDefaultEditor(file, XmlEditor.ID);
+                    } else {
+                        // set a property to determine later if the XML can be handled
+                        QualifiedName qname = new QualifiedName(
+                                AdtPlugin.PLUGIN_ID,
+                                UNKNOWN_EDITOR);
+                        try {
+                            file.setPersistentProperty(qname, "1");
+                        } catch (CoreException e) {
+                            // pass
+                        }
+                    }
+                }
+            }
+
+            private void resourceChanged(IFile file, ResourceFolderType type) {
+                if (type == ResourceFolderType.XML) {
+                    IEditorDescriptor ed = IDE.getDefaultEditor(file);
+                    if (ed == null || ed.getId() != XmlEditor.ID) {
+                        QualifiedName qname = new QualifiedName(
+                                AdtPlugin.PLUGIN_ID,
+                                UNKNOWN_EDITOR);
+                        String prop = null;
+                        try {
+                            prop = file.getPersistentProperty(qname);
+                        } catch (CoreException e) {
+                            // pass
+                        }
+                        if (prop != null && XmlEditor.canHandleFile(file)) {
+                            try {
+                                // remove the property & set editor
+                                file.setPersistentProperty(qname, null);
+                                IWorkbenchPage page = PlatformUI.getWorkbench().
+                                                        getActiveWorkbenchWindow().getActivePage();
+                                
+                                IEditorPart oldEditor = page.findEditor(new FileEditorInput(file));
+                                if (oldEditor != null &&
+                                        AdtPlugin.displayPrompt("Android XML Editor",
+                                            String.format("The file you just saved as been recognized as a file that could be better handled using the Android XML Editor. Do you want to edit '%1$s' using the Android XML editor instead?",
+                                                    file.getFullPath()))) {
+                                    IDE.setDefaultEditor(file, XmlEditor.ID);
+                                    IEditorPart newEditor = page.openEditor(
+                                            new FileEditorInput(file),
+                                            XmlEditor.ID,
+                                            true, /* activate */
+                                            IWorkbenchPage.MATCH_NONE);
+                                
+                                    if (newEditor != null) {
+                                        page.closeEditor(oldEditor, true /* save */);
+                                    }
+                                }
+                            } catch (CoreException e) {
+                                // setPersistentProperty or page.openEditor may have failed
+                            }
+                        }
+                    }
+                }
+            }
+
+        }, IResourceDelta.ADDED | IResourceDelta.CHANGED);
+    }
+
+    /**
+     * Adds a new {@link ITargetChangeListener} to be notified when a new SDK is loaded, or when
+     * a project has its target changed.
+     */
+    public void addTargetListener(ITargetChangeListener listener) {
+        mTargetChangeListeners.add(listener);
+    }
+
+    /**
+     * Removes an existing {@link ITargetChangeListener}.
+     * @see #addTargetListener(ITargetChangeListener)
+     */
+    public void removeTargetListener(ITargetChangeListener listener) {
+        mTargetChangeListeners.remove(listener);
+    }
+
+    /**
+     * Updates all the {@link ITargetChangeListener} that a target has changed for a given project.
+     * <p/>Only editors related to that project should reload.
+     */
+    @SuppressWarnings("unchecked")
+    public void updateTargetListener(final IProject project) {
+        final List<ITargetChangeListener> listeners =
+            (List<ITargetChangeListener>)mTargetChangeListeners.clone();
+
+        AdtPlugin.getDisplay().asyncExec(new Runnable() {
+            public void run() {
+                for (ITargetChangeListener listener : listeners) {
+                    try {
+                        listener.onProjectTargetChange(project);
+                    } catch (Exception e) {
+                        AdtPlugin.log(e, "Failed to update a TargetChangeListener.");  //$NON-NLS-1$
+                    }
+                }
+            }
+        });
+    }
+    
+    public static synchronized OutputStream getErrorStream() {
+        return sPlugin.mAndroidConsoleErrorStream;
+    }
+}
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
new file mode 100644
index 0000000..a638810
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/Messages.java
@@ -0,0 +1,48 @@
+
+package com.android.ide.eclipse.adt;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+    private static final String BUNDLE_NAME = "com.android.ide.eclipse.adt.messages"; //$NON-NLS-1$
+
+    public static String AdtPlugin_Android_SDK_Content_Loader;
+
+    public static String AdtPlugin_Android_SDK_Resource_Parser;
+
+    public static String AdtPlugin_Failed_To_Parse_s;
+
+    public static String AdtPlugin_Failed_To_Start_s;
+
+    public static String AdtPlugin_Parsing_Resources;
+
+    public static String Could_Not_Find;
+
+    public static String Could_Not_Find_Folder;
+
+    public static String Could_Not_Find_Folder_In_SDK;
+
+    public static String Dialog_Title_SDK_Location;
+
+    public static String Error_Check_Prefs;
+
+    public static String SDK_Not_Setup;
+
+    public static String VersionCheck_Plugin_Too_Old;
+
+    public static String VersionCheck_Plugin_Version_Failed;
+
+    public static String VersionCheck_SDK_Build_Too_Low;
+
+    public static String VersionCheck_SDK_Milestone_Too_Low;
+
+    public static String VersionCheck_Unable_To_Parse_Version_s;
+
+    static {
+        // initialize resource bundle
+        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+    }
+
+    private Messages() {
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/VersionCheck.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/VersionCheck.java
new file mode 100644
index 0000000..6d85af3
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/VersionCheck.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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
new file mode 100644
index 0000000..e71ae47
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java
@@ -0,0 +1,1154 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.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") //$NON-NLS-1$
+    @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 = getFileName(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 = getFileName(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 +
+                            getFileName(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 +
+                            getFileName(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);
+            
+            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 
+     */
+    private void writeStandardResources(SignedJarBuilder jarBuilder, IJavaProject javaProject,
+            IJavaProject[] referencedJavaProjects) throws IOException {
+        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) {
+            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.
+     * @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) {
+            // 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()]);
+    }
+    
+    /**
+     * Returns the apk filename for the given project
+     * @param project The project.
+     * @param config An optional config name. Can be null.
+     */
+    private static String getFileName(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;
+    }
+
+    /**
+     * 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
new file mode 100644
index 0000000..5d6793a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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
new file mode 100644
index 0000000..e2e9728
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/BaseBuilder.java
@@ -0,0 +1,929 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.adt.sdk.Sdk;
+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 com.android.sdklib.IAndroidTarget;
+
+import org.eclipse.core.resources.IContainer;
+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.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.IStatus;
+import org.eclipse.core.runtime.Status;
+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");
+        }
+
+        // check the compiler compliance level.
+        if (ProjectHelper.checkCompilerCompliance(project) !=
+                ProjectHelper.COMPILER_COMPLIANCE_OK) {
+            // we exit silently
+            stopBuild(Messages.Compiler_Compliance_Error);
+        }
+
+        // Check that the SDK directory has been setup.
+        String osSdkFolder = AdtPlugin.getOsSdkFolder();
+
+        if (osSdkFolder == null || osSdkFolder.length() == 0) {
+            stopBuild(Messages.No_SDK_Setup_Error);
+        }
+
+        IAndroidTarget projectTarget = Sdk.getCurrent().getTarget(project);
+        if (projectTarget == null) {
+            // no target. error has been output by the container initializer:
+            // exit silently.
+            stopBuild("Project has no target");
+        }
+    }
+    
+    /**
+     * 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)));
+    }
+
+}
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
new file mode 100644
index 0000000..65ad4f5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/DexWrapper.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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
new file mode 100644
index 0000000..0100049
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/Messages.java
@@ -0,0 +1,137 @@
+
+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
new file mode 100644
index 0000000..a0e446c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java
@@ -0,0 +1,1150 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.project.ProjectHelper;
+import com.android.ide.eclipse.adt.sdk.Sdk;
+import com.android.ide.eclipse.common.AndroidConstants;
+import com.android.ide.eclipse.common.project.AndroidManifestHelper;
+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 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.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.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+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_SOURCE_FOLDER =
+        "manifestPackageSourceFolder"; //$NON-NLS-1$
+
+    private static final String PROPERTY_COMPILE_RESOURCES = "compileResources"; //$NON-NLS-1$
+
+    static final String PROPERTY_ANDROID_GENERATED = "androidGenerated"; //$NON-NLS-1$
+    static final String PROPERTY_ANDROID_CONFLICT = "androidConflict"; //$NON-NLS-1$
+
+    /**
+     * Single line aidl error<br>
+     * "&lt;path&gt;:&lt;line&gt;: &lt;error&gt;"
+     */
+    private static Pattern sAidlPattern1 = Pattern.compile("^(.+?):(\\d+):\\s(.+)$"); //$NON-NLS-1$
+
+    /**
+     * 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;
+
+    /** List of .aidl files found that are modified or new. */
+    private final ArrayList<IFile> mAidlToCompile = new ArrayList<IFile>();
+
+    /** List of .aidl files that have been removed. */
+    private final ArrayList<IFile> mAidlToRemove = new ArrayList<IFile>();
+
+    /** cache of the java package defined in the manifest */
+    private String mManifestPackage;
+
+    /** Source folder containing the java package defined in the manifest. */
+    private IFolder mManifestPackageSourceFolder;
+
+    /**
+     * 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 RefreshProgressMonitor implements IProgressMonitor {
+        private boolean mCancelled = false;
+        private IFile mNewFile;
+        private IFile mSource;
+        private boolean mDoneExecuted = false;
+        public RefreshProgressMonitor(IFile newFile, IFile source) {
+            mNewFile = newFile;
+            mSource = source;
+        }
+
+        public void beginTask(String name, int totalWork) {
+        }
+
+        public void done() {
+            if (mDoneExecuted == false) {
+                mDoneExecuted = true;
+                if (mNewFile.exists()) {
+                    ProjectHelper.saveResourceProperty(mNewFile, PROPERTY_ANDROID_GENERATED,
+                            mSource);
+                    try {
+                        mNewFile.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) {
+        }
+    }
+
+    /**
+     * Progress Monitor setting up to two files as derived once their parent is refreshed.
+     * This is used as ProgressMonitor to refresh the R.java/Manifest.java parent (to display
+     * the newly created files in the package explorer).
+     */
+    private static class DerivedProgressMonitor implements IProgressMonitor {
+        private boolean mCancelled = false;
+        private IFile mFile1;
+        private IFile mFile2;
+        private boolean mDoneExecuted = false;
+        public DerivedProgressMonitor(IFile file1, IFile file2) {
+            mFile1 = file1;
+            mFile2 = file2;
+        }
+
+        public void beginTask(String name, int totalWork) {
+        }
+
+        public void done() {
+            if (mDoneExecuted == false) {
+                if (mFile1 != null && mFile1.exists()) {
+                    mDoneExecuted = true;
+                    try {
+                        mFile1.setDerived(true);
+                    } catch (CoreException e) {
+                        // This really shouldn't happen since we check that the resource edit.
+                        // Worst case scenario, the resource isn't marked as derived.
+                    }
+                }
+                if (mFile2 != null && mFile2.exists()) {
+                    try {
+                        mFile2.setDerived(true);
+                    } catch (CoreException e) {
+                        // This really shouldn't happen since we check that the resource edit.
+                        // 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") //$NON-NLS-1$
+    @Override
+    protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
+            throws CoreException {
+        // 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> sourceList = BaseProjectHelper.getSourceClasspaths(javaProject);
+
+        PreCompilerDeltaVisitor dv = null;
+        String javaPackage = null;
+
+        if (kind == FULL_BUILD) {
+            AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
+                    Messages.Start_Full_Pre_Compiler);
+            mCompileResources = true;
+            buildAidlCompilationList(project, sourceList);
+        } 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) {
+                mCompileResources = true;
+                buildAidlCompilationList(project, sourceList);
+            } else {
+                dv = new PreCompilerDeltaVisitor(this, sourceList);
+                delta.accept(dv);
+
+                // record the state
+                mCompileResources |= dv.getCompileResources();
+                
+                // handle aidl modification
+                if (dv.getFullAidlRecompilation()) {
+                    buildAidlCompilationList(project, sourceList);
+                } else {
+                    mergeAidlFileModifications(dv.getAidlToCompile(),
+                            dv.getAidlToRemove());
+                }
+                
+                // get the java package from the visitor
+                javaPackage = dv.getManifestPackage();
+            }
+        }
+
+        // store the build status in the persistent storage
+        saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES , mCompileResources);
+        // TODO also needs to store the list of aidl to compile/remove
+
+        // 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 = AndroidManifestHelper.getManifest(project);
+
+        if (manifest == null) {
+            String msg = String.format(Messages.s_File_Missing,
+                    AndroidConstants.FN_ANDROID_MANIFEST);
+            AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, 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();
+        }
+
+        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.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
+                    msg);
+
+            // 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,
+                    mManifestPackageSourceFolder, mManifestPackage);
+            deleteObsoleteGeneratedClass(AndroidConstants.FN_MANIFEST_CLASS,
+                    mManifestPackageSourceFolder, mManifestPackage);
+
+            // record the new manifest package, and save it.
+            mManifestPackage = javaPackage;
+            saveProjectStringProperty(PROPERTY_PACKAGE, mManifestPackage);
+        }
+
+        if (mCompileResources) {
+            // we need to figure out where to store the R class.
+            // get the parent folder for R.java and update mManifestPackageSourceFolder
+            IFolder packageFolder = getManifestPackageFolder(project, sourceList);
+
+            // at this point, either we have found the package or not.
+            // if we haven't well it's time to tell the user and abort
+            if (mManifestPackageSourceFolder == null) {
+                // mark the manifest file
+                String message = String.format(Messages.Package_s_Doesnt_Exist_Error,
+                        mManifestPackage);
+                BaseProjectHelper.addMarker(manifest, AndroidConstants.MARKER_AAPT_COMPILE, message,
+                        IMarker.SEVERITY_ERROR);
+                AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, message);
+
+                // abort
+                // This interrupts the build. The next builders will not run.
+                stopBuild(message);
+            }
+
+
+            // found the folder in which to write the stuff
+
+            // get the resource folder
+            IFolder resFolder = project.getFolder(AndroidConstants.WS_RESOURCES);
+
+            // get the file system path
+            IPath outputLocation = mManifestPackageSourceFolder.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);
+                prepareFileForExternalModification(rJavaFile);
+
+                // do the same for the Manifest.java class
+                IFile manifestJavaFile = packageFolder.getFile(AndroidConstants.FN_MANIFEST_CLASS);
+                prepareFileForExternalModification(manifestJavaFile);
+
+                // 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 set the R.java/Manifest.java file as read only.
+                    finishJavaFilesAfterExternalModification(rJavaFile, manifestJavaFile);
+
+                    // build has been done. reset the state of the builder
+                    mCompileResources = false;
+
+                    // and store it
+                    saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES, mCompileResources);
+                }
+            }
+        } else {
+            // nothing to do
+        }
+
+        // now handle the aidl stuff.
+        // look for a preprocessed aidl file
+        IResource projectAidl = project.findMember("project.aidl"); //$NON-NLS-1$
+        String folderAidlPath = null;
+        if (projectAidl != null && projectAidl.exists()) {
+            folderAidlPath = projectAidl.getLocation().toOSString();
+        }
+        boolean aidlStatus = handleAidl(projectTarget, sourceList, folderAidlPath, monitor);
+
+        if (aidlStatus == false && mCompileResources == false) {
+            AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
+                    Messages.Nothing_To_Compile);
+        }
+
+        return null;
+    }
+
+    @Override
+    protected void clean(IProgressMonitor monitor) throws CoreException {
+        super.clean(monitor);
+
+        AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, getProject(),
+                Messages.Removing_Generated_Classes);
+
+        // check if we have the R.java info already.
+        if (mManifestPackageSourceFolder != null && mManifestPackage != null) {
+            deleteObsoleteGeneratedClass(AndroidConstants.FN_RESOURCE_CLASS,
+                    mManifestPackageSourceFolder, mManifestPackage);
+            deleteObsoleteGeneratedClass(AndroidConstants.FN_MANIFEST_CLASS,
+                    mManifestPackageSourceFolder, mManifestPackage);
+        }
+        
+        // FIXME: delete all java generated from aidl.
+    }
+
+    @Override
+    protected void startupOnInitialize() {
+        super.startupOnInitialize();
+
+        // load the previous IFolder and java package.
+        mManifestPackage = loadProjectStringProperty(PROPERTY_PACKAGE);
+        IResource resource = loadProjectResourceProperty(PROPERTY_SOURCE_FOLDER);
+        if (resource instanceof IFolder) {
+            mManifestPackageSourceFolder = (IFolder)resource;
+        }
+
+        // Load the current compile flag. We ask for true if not found to force a
+        // recompile.
+        mCompileResources = loadProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES, true);
+    }
+
+    /**
+     * Delete the a generated java class associated with the specified java package.
+     * @param filename Name of the generated file to remove.
+     * @param sourceFolder The source Folder containing the old java package.
+     * @param javaPackage the old java package
+     */
+    private void deleteObsoleteGeneratedClass(String filename, IFolder sourceFolder,
+            String javaPackage) {
+        if (sourceFolder == null || javaPackage == null) {
+            return;
+        }
+
+        // convert the java package into path
+        String[] segments = javaPackage.split(AndroidConstants.RE_DOT);
+
+        StringBuilder path = new StringBuilder();
+        for (String s : segments) {
+           path.append(AndroidConstants.WS_SEP_CHAR);
+           path.append(s);
+        }
+
+        // appends the name of the generated file
+        path.append(AndroidConstants.WS_SEP_CHAR);
+        path.append(filename);
+
+        Path iPath = new Path(path.toString());
+
+        // Find a matching resource object.
+        IResource javaFile = sourceFolder.findMember(iPath);
+        if (javaFile != null && javaFile.exists() && javaFile.getType() == IResource.FILE) {
+            try {
+                // remove the read-only tag
+                prepareFileForExternalModification((IFile)javaFile);
+
+                // 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, path);
+                IProject project = getProject();
+                AdtPlugin.printErrorToConsole(project, message);
+                AdtPlugin.printErrorToConsole(project, e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Looks for the folder containing the package defined in the manifest. It looks in the
+     * list of source folders for the one containing folders matching the package defined in the
+     * manifest (from the field <code>mManifestPackage</code>). It returns the final folder, which
+     * will contain the R class, and update the field <code>mManifestPackageSourceFolder</code>
+     * to be the source folder containing the full package.
+     * @param project The project.
+     * @param sourceList The list of source folders for the project.
+     * @return the package that will contain the R class or null if the folder was not found.
+     * @throws CoreException
+     */
+    private IFolder getManifestPackageFolder(IProject project, ArrayList<IPath> sourceList)
+            throws CoreException {
+        // split the package in segments
+        String[] packageSegments = mManifestPackage.split(AndroidConstants.RE_DOT);
+
+        // we look for 2 folders.
+        // 1. The source folder that contains the full java package.
+        // we will store the folder in the field mJavaSourceFolder, for reuse during
+        IFolder manifestPackageSourceFolder = null;
+        // subsequent builds. This is the folder we will give to aapt.
+        // 2. The folder actually containing the R.java files. We need this one to do a refresh
+        IFolder packageFolder = null;
+
+        for (IPath iPath : sourceList) {
+            int packageSegmentIndex = 0;
+
+            // the path is relative to the workspace. We ignore the first segment,
+            // when getting the resource from the IProject object.
+            IResource classpathEntry = project.getFolder(iPath.removeFirstSegments(1));
+
+            if (classpathEntry instanceof IFolder) {
+                IFolder classpathFolder = (IFolder)classpathEntry;
+                IFolder folder = classpathFolder;
+
+                boolean failed = false;
+                while (failed == false
+                        && packageSegmentIndex < packageSegments.length) {
+
+                    // loop on that folder content looking for folders
+                    // that match the package
+                    // defined in AndroidManifest.xml
+
+                    // get the folder content
+                    IResource[] content = folder.members();
+
+                    // this is the segment we look for
+                    String segment = packageSegments[packageSegmentIndex];
+
+                    // did we find it at this level
+                    boolean found = false;
+
+                    for (IResource r : content) {
+                        // look for the java package segment
+                        if (r instanceof IFolder) {
+                            if (r.getName().equals(segment)) {
+                                // we need to skip to the next one
+                                folder = (IFolder)r;
+                                packageSegmentIndex++;
+                                found = true;
+                                break;
+                            }
+                        }
+                    }
+
+                    // if we didn't find it at this level we just fail.
+                    if (found == false) {
+                        failed = true;
+                    }
+                }
+
+                // if we didn't fail then we found it. no point in
+                // looping through the rest
+                // or the classpathEntry
+                if (failed == false) {
+                    // save the target folder reference
+                    manifestPackageSourceFolder = classpathFolder;
+                    packageFolder = folder;
+                    break;
+                }
+            }
+        }
+
+        // save the location of the folder into the persistent storage
+        if (manifestPackageSourceFolder != mManifestPackageSourceFolder) {
+            mManifestPackageSourceFolder = manifestPackageSourceFolder;
+            saveProjectResourceProperty(PROPERTY_SOURCE_FOLDER, mManifestPackageSourceFolder);
+        }
+        return packageFolder;
+    }
+
+    /**
+     * 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 folderAidlPath 
+     * @param monitor the projess monitor
+     * @returns true if it did something
+     * @throws CoreException
+     */
+    private boolean handleAidl(IAndroidTarget projectTarget, ArrayList<IPath> sourceFolders,
+            String folderAidlPath, IProgressMonitor monitor) throws CoreException {
+        if (mAidlToCompile.size() == 0 && mAidlToRemove.size() == 0) {
+            return false;
+        }
+        
+
+        // create the command line
+        String[] command = new String[4 + sourceFolders.size() + (folderAidlPath != null ? 1 : 0)];
+        int index = 0;
+        int aidlIndex;
+        command[index++] = projectTarget.getPath(IAndroidTarget.AIDL);
+        command[aidlIndex = index++] = "-p"; //$NON-NLS-1$
+        if (folderAidlPath != null) {
+            command[index++] = "-p" + folderAidlPath; //$NON-NLS-1$
+        }
+        
+        // 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<IFile> stillNeedCompilation = new ArrayList<IFile>();
+
+        // 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 (IFile aidlFile : mAidlToRemove) {
+            int pos = mAidlToCompile.indexOf(aidlFile);
+            if (pos != -1) {
+                mAidlToCompile.remove(pos);
+            }
+        }
+        
+        // loop until we've compile them all
+        for (IFile aidlFile : mAidlToCompile) {
+            // Remove the AIDL error markers from the aidl file
+            removeMarkersFromFile(aidlFile, AndroidConstants.MARKER_AIDL);
+
+            // get the path
+            IPath iPath = aidlFile.getLocation();
+            String osPath = iPath.toOSString();
+
+            // get the parent container
+            IContainer parentContainer = aidlFile.getParent();
+
+            // replace the extension in both the full path and the
+            // last segment
+            String osJavaPath = osPath.replaceAll(AndroidConstants.RE_AIDL_EXT,
+                    AndroidConstants.DOT_JAVA);
+            String javaName = aidlFile.getName().replaceAll(AndroidConstants.RE_AIDL_EXT,
+                    AndroidConstants.DOT_JAVA);
+
+            // check if we can compile it, or if there is a conflict with a java file
+            boolean conflict = ProjectHelper.loadBooleanProperty(aidlFile,
+                    PROPERTY_ANDROID_CONFLICT, false);
+            if (conflict) {
+                String msg = String.format(Messages.AIDL_Java_Conflict, javaName,
+                        aidlFile.getName());
+
+                // put a marker
+                BaseProjectHelper.addMarker(aidlFile, AndroidConstants.MARKER_AIDL, msg,
+                        IMarker.SEVERITY_ERROR);
+
+                // output an error
+                AdtPlugin.printErrorToConsole(getProject(), msg);
+
+                stillNeedCompilation.add(aidlFile);
+
+                // move on to next file
+                continue;
+            }
+
+            // get the resource for the java file.
+            Path javaIPath = new Path(javaName);
+            IFile javaFile = parentContainer.getFile(javaIPath);
+
+            // if the file was read-only, this will make it readable.
+            prepareFileForExternalModification(javaFile);
+
+            // finish to set the command line.
+            command[aidlIndex] = "-p" + Sdk.getCurrent().getTarget(aidlFile.getProject()).getPath(
+                    IAndroidTarget.ANDROID_AIDL); //$NON-NLS-1$
+            command[index] = osPath;
+            command[index + 1] = osJavaPath;
+
+            // launch the process
+            if (execAidl(command, aidlFile) == false) {
+                // aidl failed. File should be marked. We add the file to the list
+                // of file that will need compilation again.
+                stillNeedCompilation.add(aidlFile);
+
+                // and we move on to the next one.
+                continue;
+            } else {
+                // since the exec worked, we refresh the parent, and set the
+                // file as read only.
+                finishFileAfterExternalModification(javaFile, aidlFile);
+            }
+        }
+
+        // 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 (IFile aidlFile : mAidlToRemove) {
+            // make the java filename
+            String javaName = aidlFile.getName().replaceAll(
+                    AndroidConstants.RE_AIDL_EXT,
+                    AndroidConstants.DOT_JAVA);
+
+            // get the parent container
+            IContainer ic = aidlFile.getParent();
+
+            // and get the IFile corresponding to the java file.
+            IFile javaFile = ic.getFile(new Path(javaName));
+            if (javaFile != null && javaFile.exists() ) {
+                // check if this java file has a persistent data marking it as generated by
+                // the builder.
+                // While we put the aidl path as a resource, internally it's all string anyway.
+                // We use loadStringProperty, because loadResourceProperty tries to match
+                // the string value (a path in this case) with an existing resource, but
+                // the aidl file was deleted, so it would return null, even though the property
+                // existed.
+                String aidlPath = ProjectHelper.loadStringProperty(javaFile,
+                        PROPERTY_ANDROID_GENERATED);
+
+                if (aidlPath != null) {
+                    // This confirms the java file was generated by the builder,
+                    // we can delete the aidlFile.
+                    javaFile.delete(true, null);
+
+                    // Refresh parent.
+                    ic.refreshLocal(IResource.DEPTH_ONE, monitor);
+                }
+            }
+        }
+        mAidlToRemove.clear();
+
+        return true;
+    }
+
+    /**
+     * 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 buildPaths The list of build paths.
+     */
+    private void buildAidlCompilationList(IProject project,
+            ArrayList<IPath> buildPaths) {
+        for (IPath p : buildPaths) {
+            // Because the path contains the name of the project as well, we
+            // need to remove it, to access the final folder.
+            String[] segments = p.segments();
+            IContainer folder = project;
+            for (int i = 1; i < segments.length; i++) {
+                IResource r = folder.findMember(segments[i]);
+                if (r != null && r.exists() &&
+                        r.getType() == IResource.FOLDER) {
+                    folder = (IContainer)r;
+                } else {
+                    // hmm looks like the build path is corrupted/wrong.
+                    // reset and break
+                    folder = project;
+                    break;
+                }
+            }
+
+            // did we ge a folder?
+            if (folder != project) {
+                // then we scan!
+                scanContainerForAidl(folder);
+            }
+        }
+    }
+
+    /**
+     * Scans a container and fills the list of aidl files to compile.
+     * @param container The container to scan.
+     */
+    private void scanContainerForAidl(IContainer container) {
+        try {
+            IResource[] members = container.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((IFile)r);
+                       }
+                       break;
+                   case IResource.FOLDER:
+                       // recursively go through children
+                       scanContainerForAidl((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<IFile> toCompile,
+            ArrayList<IFile> 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 (IFile 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 (IFile r : toCompile) {
+            if (mAidlToCompile.indexOf(r) == -1) {
+                mAidlToCompile.add(r);
+            }
+
+            int index = mAidlToRemove.indexOf(r);
+            if (index != -1) {
+                mAidlToRemove.remove(index);
+            }
+        }
+    }
+
+    /**
+     * Prepare an already existing file for modification. File generated from
+     * command line processed are marked as read-only. This method prepares
+     * them (mark them as read-write) before the command line process is
+     * started. A check is made to be sure the file exists.
+     * @param file The IResource object for the file to prepare.
+     * @throws CoreException
+     */
+    private void prepareFileForExternalModification(IFile file)
+            throws CoreException {
+        // file may not exist yet, so we check that.
+        if (file != null && file.exists()) {
+            // get the attributes.
+            ResourceAttributes ra = file.getResourceAttributes();
+            if (ra != null) {
+                // change the attributes
+                ra.setReadOnly(false);
+
+                // set the new attributes in the file.
+                file.setResourceAttributes(ra);
+            }
+        }
+    }
+
+    /**
+     * Finish a file created/modified by an outside command line process.
+     * The file is marked as modified by Android, and the parent folder is refreshed, so that,
+     * in case the file didn't exist beforehand, the file appears in the package explorer.
+     * @param rFile The R file to "finish".
+     * @param manifestFile The manifest file to "finish".
+     * @throws CoreException
+     */
+    private void finishJavaFilesAfterExternalModification(IFile rFile, IFile manifestFile)
+            throws CoreException {
+        IContainer parent = rFile.getParent();
+
+        IProgressMonitor monitor = new DerivedProgressMonitor(rFile, manifestFile);
+
+        // refresh the parent node in the package explorer. Once this is done the custom progress
+        // monitor will mark them as derived.
+        parent.refreshLocal(IResource.DEPTH_ONE, monitor);
+    }
+
+    /**
+     * Finish a file created/modified by an outside command line process.
+     * The file is marked as modified by Android, and the parent folder is refreshed, so that,
+     * in case the file didn't exist beforehand, the file appears in the package explorer.
+     * @param file The file to "finish".
+     * @param aidlFile The AIDL file to "finish".
+     * @throws CoreException
+     */
+    private void finishFileAfterExternalModification(IFile file, IFile aidlFile)
+            throws CoreException {
+        IContainer parent = file.getParent();
+
+        // we need to add a link to the aidl file.
+        // We need to wait for the refresh of the parent to be done, so we'll do
+        // it in the monitor. This will also set the file as derived.
+        IProgressMonitor monitor = new RefreshProgressMonitor(file, aidlFile);
+
+        // refresh the parent node in the package explorer.
+        parent.refreshLocal(IResource.DEPTH_ONE, monitor);
+    }
+}
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
new file mode 100644
index 0000000..f4778d7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.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.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.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+import java.util.ArrayList;
+
+/**
+ * Resource Delta visitor for the pre-compiler.
+ */
+class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements
+        IResourceDeltaVisitor {
+
+    // 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;
+
+    /** List of .aidl files found that are modified or new. */
+    private final ArrayList<IFile> mAidlToCompile = new ArrayList<IFile>();
+
+    /** List of .aidl files that have been removed. */
+    private final ArrayList<IFile> mAidlToRemove = new ArrayList<IFile>();
+    
+    /** Aidl forced recompilation flag. This is set to true if project.aidl is modified. */
+    private boolean mFullAidlCompilation = false;
+
+    /** Manifest check/parsing flag. */
+    private boolean mCheckedManifestXml = false;
+
+    /** Application Pacakge, gathered from the parsing of the manifest */
+    private String mJavaPackage = null;
+
+    // Internal usage fields.
+    /**
+     * In Resource folder flag. This allows us to know if we're in the
+     * resource folder.
+     */
+    private boolean mInRes = false;
+
+    /**
+     * In Source folder flag. This allows us to know if we're in a source
+     * folder.
+     */
+    private boolean mInSrc = false;
+
+    /** List of source folders. */
+    private ArrayList<IPath> mSourceFolders;
+
+
+    public PreCompilerDeltaVisitor(BaseBuilder builder, ArrayList<IPath> sourceFolders) {
+        super(builder);
+        mSourceFolders = sourceFolders;
+    }
+
+    public boolean getCompileResources() {
+        return mCompileResources;
+    }
+
+    public ArrayList<IFile> getAidlToCompile() {
+        return mAidlToCompile;
+    }
+
+    public ArrayList<IFile> getAidlToRemove() {
+        return mAidlToRemove;
+    }
+    
+    public boolean getFullAidlRecompilation() {
+        return mFullAidlCompilation;
+    }
+
+    /**
+     * 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;
+    }
+
+    /*
+     * (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) {
+            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 = mInSrc = false;
+
+            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;
+                mInSrc = false;
+                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();
+                    }
+
+                    mCheckedManifestXml = true;
+                }
+                mCompileResources = true;
+
+                // we don't want to go to the children, not like they are
+                // any for this resource anyway.
+                return false;
+            } else if (AndroidConstants.FN_PROJECT_AIDL.equalsIgnoreCase(segments[1])) {
+                // need to force recompilation of all the aidl files
+                mFullAidlCompilation = true;
+            }
+        }
+
+        // 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 (mInSrc) {
+            // 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();
+
+            if (kind == IResourceDelta.ADDED) {
+                // we only care about added files (inside the source folders), if they
+                // are aidl files.
+
+                // get the extension of the resource
+                String ext = resource.getFileExtension();
+
+                if (AndroidConstants.EXT_AIDL.equalsIgnoreCase(ext)) {
+                    // look for an already existing matching java file
+                    String javaName = resource.getName().replaceAll(
+                            AndroidConstants.RE_AIDL_EXT,
+                            AndroidConstants.DOT_JAVA);
+
+                    // get the parent container
+                    IContainer ic = resource.getParent();
+
+                    IFile javaFile = ic.getFile(new Path(javaName));
+                    if (javaFile != null && javaFile.exists()) {
+                        // check if that file was generated by the plugin. Normally those files are
+                        // deleted automatically, but it's better to check.
+                        String aidlPath = ProjectHelper.loadStringProperty(javaFile,
+                                PreCompilerBuilder.PROPERTY_ANDROID_GENERATED);
+                        if (aidlPath == null) {
+                            // mark the aidl file that it cannot be compile just yet
+                            ProjectHelper.saveBooleanProperty(file,
+                                    PreCompilerBuilder.PROPERTY_ANDROID_CONFLICT, true);
+                        }
+
+                        // we add it anyway so that we can try to compile it at every compilation
+                        // until the conflict is fixed.
+                        mAidlToCompile.add(file);
+
+                    } else {
+                        // the java file doesn't exist, we can safely add the file to the list
+                        // of files to compile.
+                        mAidlToCompile.add(file);
+                    }
+                }
+
+                return false;
+            }
+
+            // get the filename
+            String fileName = segments[segments.length - 1];
+
+            boolean outputMessage = false;
+
+            // Special case of R.java/Manifest.java.
+            // FIXME: This does not check the package. Any modification of R.java/Manifest.java in another project will trigger a new recompilation of the resources.
+            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
+                outputMessage = true;
+            } else {
+
+                // get the extension of the resource
+                String ext = resource.getFileExtension();
+
+                if (AndroidConstants.EXT_AIDL.equalsIgnoreCase(ext)) {
+                    if (kind == IResourceDelta.REMOVED) {
+                        mAidlToRemove.add(file);
+                    } else {
+                        mAidlToCompile.add(file);
+                    }
+                } else {
+                    if (kind == IResourceDelta.REMOVED) {
+                        // the file has been removed. we need to check it's a java file and that
+                        // there's a matching aidl file. We can't check its persistent storage
+                        // anymore.
+                        if (AndroidConstants.EXT_JAVA.equalsIgnoreCase(ext)) {
+                            String aidlFile = resource.getName().replaceAll(
+                                    AndroidConstants.RE_JAVA_EXT,
+                                    AndroidConstants.DOT_AIDL);
+
+                            // get the parent container
+                            IContainer ic = resource.getParent();
+
+                            IFile f = ic.getFile(new Path(aidlFile));
+                            if (f != null && f.exists() ) {
+                                // make sure that the aidl file is not in conflict anymore, in
+                                // case the java file was not generated by us.
+                                if (ProjectHelper.loadBooleanProperty(f,
+                                        PreCompilerBuilder.PROPERTY_ANDROID_CONFLICT, false)) {
+                                    ProjectHelper.saveBooleanProperty(f,
+                                            PreCompilerBuilder.PROPERTY_ANDROID_CONFLICT, false);
+                                } else {
+                                    outputMessage = true;
+                                }
+                                mAidlToCompile.add(f);
+                            }
+                        }
+                    } else {
+                        // check if it's an android generated java file.
+                        IResource aidlSource = ProjectHelper.loadResourceProperty(
+                                file, PreCompilerBuilder.PROPERTY_ANDROID_GENERATED);
+
+                        if (aidlSource != null && aidlSource.exists() &&
+                                aidlSource.getType() == IResource.FILE) {
+                            // it looks like this was a java file created from an aidl file.
+                            // we need to add the aidl file to the list of aidl file to compile
+                            mAidlToCompile.add((IFile)aidlSource);
+                            outputMessage = true;
+                        }
+                    }
+                }
+            }
+
+            if (outputMessage) {
+                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);
+                }
+            }
+
+            // 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.
+            String[] sourceFolderSegments = findMatchingSourceFolder(mSourceFolders, segments);
+            if (sourceFolderSegments != null) {
+                // we have a match!
+                mInRes = false;
+
+                // Check if the current folder is actually a source folder
+                if (sourceFolderSegments.length == segments.length) {
+                    mInSrc = true;
+                }
+                
+                // and return true to visit the content, no matter what
+                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;
+    }
+}
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
new file mode 100644
index 0000000..19d7185
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ResourceManagerBuilder.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.adt.sdk.Sdk;
+import com.android.ide.eclipse.common.AndroidConstants;
+import com.android.ide.eclipse.common.project.BaseProjectHelper;
+import com.android.sdklib.IAndroidTarget;
+
+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.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+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") //$NON-NLS-1$
+    @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 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.printBuildToConsole(AdtConstants.BUILD_VERBOSE, 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 if we have finished loading the SDK.
+        if (AdtPlugin.getDefault().getSdkLoadStatus() != LoadStatus.LOADED) {
+            // we exit silently
+            // This interrupts the build. The next builders will not run.
+            stopBuild("SDK is not loaded yet");
+        }
+        
+        // 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 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/build/build_messages.properties
new file mode 100644
index 0000000..8ba43d4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/build_messages.properties
@@ -0,0 +1,61 @@
+Start_Full_Apk_Build=Starting full Package build.
+Start_Full_Pre_Compiler=Starting full Pre Compiler.
+Start_Inc_Apk_Build=Starting incremental Package build: Checking resource changes.
+Start_Inc_Pre_Compiler=Starting incremental Pre Compiler: Checking resource changes.
+Xml_Error=Error in an XML file: aborting build.
+s_Missing_Repackaging=%1$s missing. Repackaging.
+Project_Has_Errors=Project contains error(s). Package Builder aborted.
+Failed_To_Get_Output=Failed to get project output folder\!
+Output_Missing=Output folder missing\! Make sure your project is configured properly.
+s_File_Missing=%1$s file missing\!
+Unparsed_AAPT_Errors=Unparsed aapt error(s)\! Check the console for output.
+Unparsed_AIDL_Errors=Unparsed aidl error\! Check the console for output.
+AAPT_Exec_Error=Error executing aapt. Please check aapt is present at %1$s
+Dalvik_Error_d=Conversion to Dalvik format failed with error %1$d
+DX_Jar_Error=Dx.jar is not found inside the plugin. Reinstall ADT\!
+Dalvik_Error_s=Conversion to Dalvik format failed: %1$s
+Incompatible_VM_Warning=Note: You may be using an incompatible virtual machine or class library.
+Requires_1_5_Error=This program requires JDK 1.5 compatibility.
+Final_Archive_Error_s=Error generating final archive: %1$s
+Marker_Delete_Error=Failed to delete marker '%1$s' for %2$s
+Couldnt_Locate_s_Error=Could not locate '%1$s'. This will not be added to the package.
+Compiler_Compliance_Error=Compiler compliance level not compatible: Build aborted.
+No_SDK_Setup_Error=SDK directory has not been setup. Please go to the Android preferences and enter the location of the SDK.
+s_Contains_Xml_Error=%1$s contains XML error: Build aborted.
+s_Doesnt_Declare_Package_Error=%1$s does not declare a Java package: Build aborted.
+Checking_Package_Change=Checking Java package value did not change...
+Package_s_Doesnt_Exist_Error=Package '%1$s' does not exist\!
+Preparing_Generated_Files=Preparing generated java files for update/creation.
+AAPT_Error='aapt' error. Pre Compiler Build aborted.
+Nothing_To_Compile=Nothing to pre compile\!
+Removing_Generated_Classes=Removing generated java classes.
+Delete_Obsolete_Error=Failed to delete obsolete %1$s, please delete it manually
+DexWrapper_Dex_Loader=Dex Loader
+AIDL_Java_Conflict=%1$s is in the way of %2$s, remove it or rename of one the files.
+AIDL_Exec_Error=Error executing aidl. Please check aidl is present at %1$s
+s_Removed_Recreating_s=%1$s was removed\! Recreating %1$s\!
+s_Modified_Manually_Recreating_s=%1$s was modified manually\! Reverting to generated version\!
+s_Modified_Recreating_s='%1$s' was modified, %2$s needs to be updated.
+Added_s_s_Needs_Updating=New resource file: '%1$s', %2$s needs to be updated.
+s_Removed_s_Needs_Updating='%1$s' was removed, %2$s needs to be updated.
+Requires_Compiler_Compliance_5=Android requires compiler compliance level 5.0. Please fix project properties.
+Requires_Source_Compatibility_5=Android requires source compatibility set to 5.0. Please fix project properties.
+Requires_Class_Compatibility_5=Android requires .class compatibility set to 5.0. Please fix project properties.
+Refreshing_Res=Refreshing resource folders.
+DexWrapper_s_does_not_exists=%1$s does not exist or is not a file
+DexWrapper_Failed_to_load_s=Failed to load %1$s
+DexWrapper_Unable_To_Execute_Dex_s=Unable to execute dex: %1$s
+DexWrapper_SecuryEx_Unable_To_Find_API=SecurityException: Unable to find API for dex.jar
+DexWrapper_SecuryEx_Unable_To_Find_Method=SecurityException: Unable to find method for dex.jar
+DexWrapper_SecuryEx_Unable_To_Find_Field=SecurityException: Unable to find field for dex.jar
+ApkBuilder_UnableBuild_Dex_Not_loaded=Unable to build: the file dex.jar was not loaded from the SDK folder\!
+ApkBuilder_Using_Default_Key=Using default debug key to sign package
+ApkBuilder_Using_s_To_Sign=Using '%1$s' to sign package
+ApkBuilder_Signing_Key_Creation_s=Signing Key Creation: 
+ApkBuilder_Unable_To_Gey_Key=Unable to get debug signature key
+ApkBuilder_Certificate_Expired_on_s=Debug certificate expired on %1$s\!
+ApkBuilder_Packaging_s=Packaging %1$s
+ApkBuilder_JAVA_HOME_is_s=The Java VM Home used is: %1$s
+ApkBuilder_Update_or_Execute_manually_s=Update it if necessary, or manually execute the following command:
+ApkBuilder_s_Conflict_with_file_s=%1$s conflicts with another file already put at %2$s
+ApkBuilder_Packaging_s_into_s=Packaging %1$s into %2$s
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/AndroidLaunch.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/AndroidLaunch.java
new file mode 100644
index 0000000..3d60401
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/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.debug.launching;
+
+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
+ *
+ */
+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/debug/launching/AndroidLaunchController.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/AndroidLaunchController.java
new file mode 100644
index 0000000..ac003df
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/AndroidLaunchController.java
@@ -0,0 +1,1838 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.debug.launching;
+
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.Client;
+import com.android.ddmlib.ClientData;
+import com.android.ddmlib.Device;
+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.debug.launching.DeviceChooserDialog.DeviceChooserResponse;
+import com.android.ide.eclipse.adt.debug.ui.EmulatorConfigTab;
+import com.android.ide.eclipse.adt.project.ProjectHelper;
+import com.android.ide.eclipse.adt.sdk.Sdk;
+import com.android.ide.eclipse.common.project.AndroidManifestHelper;
+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.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.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 {
+    
+    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$
+
+    private static final int MAX_ATTEMPT_COUNT = 5;
+
+    private final static Pattern sAmErrorType = Pattern.compile("Error type (\\d+)"); //$NON-NLS-1$
+
+    /**
+     * A delayed launch waiting for a device to be present or ready before the
+     * application is launched.
+     */
+    static final class DelayedLaunchInfo {
+        /** The device on which to launch the app */
+        Device mDevice = null;
+
+        /** The eclipse project */
+        IProject mProject;
+
+        /** Package name */
+        String mPackageName;
+
+        /** fully qualified name of the activity */
+        String mActivity;
+
+        /** IFile to the package (.apk) file */
+        IFile mPackageFile;
+        
+        /** Debuggable attribute of the manifest file. */
+        Boolean mDebuggable = null;
+        
+        /** Required ApiVersionNumber by the app. 0 means no requirements */
+        int mRequiredApiVersionNumber = 0;
+        
+        InstallRetryMode mRetryMode = InstallRetryMode.NEVER;
+        
+        /**
+         * Launch action. See {@link LaunchConfigDelegate#ACTION_DEFAULT},
+         * {@link LaunchConfigDelegate#ACTION_ACTIVITY},
+         * {@link LaunchConfigDelegate#ACTION_DO_NOTHING}
+         */
+        int mLaunchAction;
+
+        /** the launch object */
+        AndroidLaunch mLaunch;
+
+        /** the monitor object */
+        IProgressMonitor mMonitor;
+
+        /** debug mode flag */
+        boolean mDebugMode;
+
+        int mAttemptCount = 0;
+
+        boolean mCancelled = false;
+
+        /** Basic constructor with activity and package info. */
+        private DelayedLaunchInfo(IProject project, String packageName, String activity,
+                IFile pack, Boolean debuggable, int requiredApiVersionNumber, int launchAction,
+                AndroidLaunch launch, IProgressMonitor monitor) {
+            mProject = project;
+            mPackageName = packageName;
+            mActivity = activity;
+            mPackageFile = pack;
+            mLaunchAction = launchAction;
+            mLaunch = launch;
+            mMonitor = monitor;
+            mDebuggable = debuggable;
+            mRequiredApiVersionNumber = requiredApiVersionNumber;
+        }
+    }
+    
+    /**
+     * 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 final static HashMap<ILaunchConfiguration, Integer> sRunningAppMap =
+        new HashMap<ILaunchConfiguration, Integer>();
+
+    private final static Object sListLock = sRunningAppMap;
+
+    /**
+     * List of {@link DelayedLaunchInfo} waiting for an emulator to connect.
+     * <p>Once an emulator has connected, {@link DelayedLaunchInfo#mDevice} 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();
+    
+    enum InstallRetryMode {
+        NEVER, ALWAYS, PROMPT;  
+    }
+
+    /**
+     * Launch configuration data. This stores the result of querying the
+     * {@link ILaunchConfiguration} so that it's only done once. 
+     */
+    static final 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;
+        
+        public static final boolean AUTO_TARGET_MODE = true;
+
+        /**
+         * Target selection mode.
+         * <ul>
+         * <li><code>true</code>: automatic mode, see {@link #AUTO_TARGET_MODE}</li>
+         * <li><code>false</code>: manual mode</li>
+         * </ul>
+         */
+        public boolean 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 {
+                mTargetMode = config.getAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE,
+                        mTargetMode);
+            } 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) {
+            }
+
+            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
+            }
+        }
+    }
+
+    /**
+     * Output receiver for am process (activity Manager);
+     */
+    private final class AMReceiver extends MultiLineReceiver {
+        private DelayedLaunchInfo mLaunchInfo;
+        private Device mDevice;
+
+        /**
+         * Basic constructor.
+         * @param launchInfo The launch info associated with the am process.
+         * @param device The device on which the launch is done.
+         */
+        public AMReceiver(DelayedLaunchInfo launchInfo, Device device) {
+            mLaunchInfo = launchInfo;
+            mDevice = device;
+        }
+
+        @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.mAttemptCount < MAX_ATTEMPT_COUNT &&
+                        mLaunchInfo.mCancelled == 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.mProject, 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) {
+                                }
+
+                                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.mProject, array.toArray());
+            } else {
+                AdtPlugin.printToConsole(mLaunchInfo.mProject, array.toArray());
+            }
+
+            // if error then we cancel the launch, and remove the delayed info
+            if (error) {
+                mLaunchInfo.mLaunch.stopLaunch();
+                synchronized (sListLock) {
+                    mWaitingForReadyEmulatorList.remove(mLaunchInfo);
+                }
+            }
+        }
+
+        public boolean isCancelled() {
+            return false;
+        }
+    }
+
+    /**
+     * Output receiver for "pm install package.apk" command line.
+     */
+    private final static class InstallReceiver extends MultiLineReceiver {
+        
+        private final static String SUCCESS_OUTPUT = "Success"; //$NON-NLS-1$
+        private final static 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);
+
+                // 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);
+        
+        AndroidManifestHelper helper = new AndroidManifestHelper(project);
+        IFile manifest = helper.getManifestIFile();
+        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 debuggable the debuggable value of the app, or null if not set.
+     * @param requiredApiVersionNumber the api version required by the app, or -1 if none.
+     * @param activity the class to provide to am to launch
+     * @param config the launch configuration
+     * @param launch the launch object
+     */
+    public void launch(final IProject project, String mode, IFile apk,
+            String packageName, Boolean debuggable, int requiredApiVersionNumber, String activity,
+            final AndroidLaunchConfiguration config, final AndroidLaunch launch,
+            IProgressMonitor monitor) {
+        
+        String message;
+        if (config.mLaunchAction == LaunchConfigDelegate.ACTION_DO_NOTHING) {
+            message = String.format("Only Syncing Application Package");
+        } else {
+            message = String.format("Launching: %1$s", activity);
+        }
+        AdtPlugin.printToConsole(project, message);
+
+        // create the launch info
+        final DelayedLaunchInfo launchInfo = new DelayedLaunchInfo(project, packageName,
+                activity, apk, debuggable, requiredApiVersionNumber, config.mLaunchAction,
+                launch, monitor);
+
+        // set the debug mode
+        launchInfo.mDebugMode = mode.equals(ILaunchManager.DEBUG_MODE);
+
+        // get the SDK
+        Sdk currentSdk = Sdk.getCurrent();
+        AvdManager avdManager = currentSdk.getAvdManager();
+        
+        // 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 == AndroidLaunchConfiguration.AUTO_TARGET_MODE) {
+            // if we are in automatic target mode, we need to find the current devices
+            Device[] 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);
+                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 (Device 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<Device, AvdInfo> compatibleRunningAvds = new HashMap<Device, 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 (Device d : devices) {
+                String deviceAvd = d.getAvdName();
+                if (deviceAvd != null) { // physical devices return null.
+                    AvdInfo info = avdManager.getAvd(deviceAvd);
+                    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.getAvds();
+                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 a AVD compatible with target '%1$s'. Launch aborted.",
+                            projectTarget.getName()));
+                    launch.stopLaunch();
+                    return;
+                }
+            } else if (hasDevice == false && compatibleRunningAvds.size() == 1) {
+                Entry<Device, 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.mPackageName, projectTarget);
+                    if (dialog.open() == Dialog.OK) {
+                        AndroidLaunchController.this.continueLaunch(response, project, launch,
+                                launchInfo, config);
+                    } else {
+                        AdtPlugin.printErrorToConsole(project, "Launch canceled!");
+                        launch.stopLaunch();
+                        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));
+                    launch.stopLaunch();
+                }
+            }
+        });
+    }
+    
+    /**
+     * 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!");
+                            launch.stopLaunch();
+                            return;
+                        }
+                        
+                        return;
+                    }
+                } else if (response.getDeviceToUse() != null) {
+                    launchInfo.mDevice = response.getDeviceToUse();
+                    simpleLaunch(launchInfo, launchInfo.mDevice);
+                }
+            }
+        }.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, Device device) {
+        if (device != null) {
+            // check the app required API level versus the target device API level
+            
+            String deviceApiVersionName = device.getProperty(Device.PROP_BUILD_VERSION);
+            String value = device.getProperty(Device.PROP_BUILD_VERSION_NUMBER);
+            int deviceApiVersionNumber = 0;
+            try {
+                deviceApiVersionNumber = Integer.parseInt(value);
+            } catch (NumberFormatException e) {
+                // pass, we'll keep the deviceVersionNumber value at 0.
+            }
+            
+            if (launchInfo.mRequiredApiVersionNumber == 0) {
+                // warn the API level requirement is not set.
+                AdtPlugin.printErrorToConsole(launchInfo.mProject,
+                        "WARNING: Application does not specify an API level requirement!");
+
+                // and display the target device API level (if known)
+                if (deviceApiVersionName == null || deviceApiVersionNumber == 0) {
+                    AdtPlugin.printErrorToConsole(launchInfo.mProject,
+                            "WARNING: Unknown device API version!");
+                } else {
+                    AdtPlugin.printErrorToConsole(launchInfo.mProject, String.format(
+                            "Device API version is %1$d (Android %2$s)", deviceApiVersionNumber,
+                            deviceApiVersionName));
+                }
+            } else { // app requires a specific API level
+                if (deviceApiVersionName == null || deviceApiVersionNumber == 0) {
+                    AdtPlugin.printToConsole(launchInfo.mProject,
+                            "WARNING: Unknown device API version!");
+                } else if (deviceApiVersionNumber < launchInfo.mRequiredApiVersionNumber) {
+                    String msg = String.format(
+                            "ERROR: Application requires API version %1$d. Device API version is %2$d (Android %3$s).",
+                            launchInfo.mRequiredApiVersionNumber, deviceApiVersionNumber,
+                            deviceApiVersionName);
+                    AdtPlugin.printErrorToConsole(launchInfo.mProject, msg);
+                    
+                    // abort the launch
+                    return false;
+                }
+            }
+
+            // now checks that the device/app can be debugged (if needed)
+            if (device.isEmulator() == false && launchInfo.mDebugMode) {
+                String debuggableDevice = device.getProperty(Device.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.mDebuggable == 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.mPackageName);
+                        AdtPlugin.printErrorToConsole(launchInfo.mProject, 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.mDebugMode = false;
+                    } else if (launchInfo.mDebuggable == Boolean.FALSE) {
+                        String message = String.format("Application '%1$s' has its 'debuggable' attribute set to FALSE and cannot be debugged.",
+                                launchInfo.mPackageName);
+                        AdtPlugin.printErrorToConsole(launchInfo.mProject, 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.mDebugMode = 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, Device device) {
+        // API level check
+        if (checkBuildInfo(launchInfo, device) == false) {
+            AdtPlugin.printErrorToConsole(launchInfo.mProject, "Launch canceled!");
+            launchInfo.mLaunch.stopLaunch();
+            return false;
+        }
+
+        // sync the app
+        if (syncApp(launchInfo, device) == false) {
+            AdtPlugin.printErrorToConsole(launchInfo.mProject, "Launch canceled!");
+            launchInfo.mLaunch.stopLaunch();
+            return false;
+        }
+
+        // launch the app
+        launchApp(launchInfo, device);
+
+        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 syncApp(DelayedLaunchInfo launchInfo, Device device) {
+        SyncService sync = device.getSyncService();
+        if (sync != null) {
+            IPath path = launchInfo.mPackageFile.getLocation();
+            String message = String.format("Uploading %1$s onto device '%2$s'",
+                    path.lastSegment(), device.getSerialNumber());
+            AdtPlugin.printToConsole(launchInfo.mProject, message);
+
+            String osLocalPath = path.toOSString();
+            String apkName = launchInfo.mPackageFile.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.mProject, 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.mProject, String.format(
+                        "Failed to delete temporary package: %1$s", e.getMessage()));
+                return false;
+            }
+            
+            return installResult;
+        }
+
+        String msg = String.format(
+                "Failed to upload %1$s on device '%2$s': Unable to open sync connection!",
+                launchInfo.mPackageFile.getName(), device.getSerialNumber());
+        AdtPlugin.printErrorToConsole(launchInfo.mProject, msg);
+
+        return false;
+    }
+
+    /**
+     * 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 Device device) {
+
+        String message = String.format("Installing %1$s...", launchInfo.mPackageFile.getName());
+        AdtPlugin.printToConsole(launchInfo.mProject, 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, Device device, DelayedLaunchInfo launchInfo,
+            String remotePath, InstallRetryMode retryMode) throws IOException {
+        if (result == null) {
+            AdtPlugin.printToConsole(launchInfo.mProject, "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.mProject,
+                        "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.mProject,
+                        "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.mProject,
+                    "Installation error! The package already exists.");
+        } else if (result.equals("INSTALL_FAILED_INVALID_APK")) { //$NON-NLS-1$
+            AdtPlugin.printErrorToConsole(launchInfo.mProject,
+                "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.mProject,
+                "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.mProject,
+                String.format("Installation failed: Could not copy %1$s to its final location!",
+                        launchInfo.mPackageFile.getName()),
+                "Please check logcat output for more details.");
+        } else if (result.equals("INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES")) {
+            AdtPlugin.printErrorToConsole(launchInfo.mProject,
+                    "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.mPackageName));
+        } else {
+            AdtPlugin.printErrorToConsole(launchInfo.mProject,
+                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(Device device, DelayedLaunchInfo launchInfo) throws IOException {
+        InstallReceiver receiver = new InstallReceiver();
+        try {
+            device.executeShellCommand("pm uninstall " + launchInfo.mPackageName, //$NON-NLS-1$
+                    receiver);
+        } catch (IOException e) {
+            String msg = String.format(
+                    "Failed to uninstall %1$s: %2$s", launchInfo.mPackageName, e.getMessage());
+            AdtPlugin.printErrorToConsole(launchInfo.mProject, msg);
+            throw e;
+        }
+        
+        return receiver.getSuccess();
+    }
+
+    /**
+     * Performs the installation of an application whose package has been uploaded on the device.
+     * <p/>Before doing it, if the application is already running on the device, it is killed. 
+     * @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 Device device, boolean reinstall) throws IOException {
+        // kill running application
+        Client application = device.getClient(launchInfo.mPackageName);
+        if (application != null) {
+            application.kill();
+        }
+        
+        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.mPackageFile.getName(), device.getSerialNumber(), e.getMessage());
+            AdtPlugin.printErrorToConsole(launchInfo.mProject, msg);
+            throw e;
+        }
+        
+        return receiver.getSuccess();
+    }
+    
+    /**
+     * launches an application on a device or emulator
+     *
+     * @param info the {@link DelayedLaunchInfo} that indicates the activity to launch
+     * @param device the device or emulator to launch the application on
+     */
+    private void launchApp(final DelayedLaunchInfo info, Device device) {
+        // if we're not supposed to do anything, just stop the Launch item and return;
+        if (info.mLaunchAction == LaunchConfigDelegate.ACTION_DO_NOTHING) {
+            String msg = String.format("%1$s installed on device",
+                    info.mPackageFile.getFullPath().toOSString());
+            AdtPlugin.printToConsole(info.mProject, msg, "Done!");
+            info.mLaunch.stopLaunch();
+            return;
+        }
+        try {
+            String msg = String.format("Starting activity %1$s on device ", info.mActivity,
+                    info.mDevice);
+            AdtPlugin.printToConsole(info.mProject, msg);
+
+            // In debug mode, we need to add the info to the list of application monitoring
+            // client changes.
+            if (info.mDebugMode) {
+                synchronized (sListLock) {
+                    if (mWaitingForDebuggerApplications.contains(info) == false) {
+                        mWaitingForDebuggerApplications.add(info);
+                    }
+                }
+            }
+
+            // increment launch attempt count, to handle retries and timeouts
+            info.mAttemptCount++;
+
+            // now we actually launch the app.
+            device.executeShellCommand("am start" //$NON-NLS-1$
+                    + (info.mDebugMode ? " -D" //$NON-NLS-1$
+                            : "") //$NON-NLS-1$
+                    + " -n " //$NON-NLS-1$
+                    + info.mPackageName + "/" //$NON-NLS-1$
+                    + info.mActivity.replaceAll("\\$", "\\\\\\$"), //$NON-NLS-1$ //$NON-NLS-2$
+                    new AMReceiver(info, device));
+
+            // if the app is not a debug app, we need to do some clean up, as
+            // the process is done!
+            if (info.mDebugMode == false) {
+                // stop the launch object, since there's no debug, and it can't
+                // provide any control over the app
+                info.mLaunch.stopLaunch();
+            }
+        } catch (IOException e) {
+            // something went wrong trying to launch the app.
+            // lets stop the Launch
+            AdtPlugin.printErrorToConsole(info.mProject,
+                    String.format("Launch error: %s", e.getMessage()));
+            info.mLaunch.stopLaunch();
+
+            // and remove it from the list of app waiting for debuggers
+            synchronized (sListLock) {
+                mWaitingForDebuggerApplications.remove(info);
+            }
+        }
+    }
+
+    private boolean launchEmulator(AndroidLaunchConfiguration config, AvdInfo avdToLaunch) {
+
+        // split the custom command line in segments
+        ArrayList<String> customArgs = new ArrayList<String>();
+        boolean has_wipe_data = 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 (!has_wipe_data && s.equals(FLAG_WIPE_DATA)) {
+                        has_wipe_data = true;
+                    }
+                }
+            }
+        }
+
+        boolean needs_wipe_data = config.mWipeData && !has_wipe_data;
+        if (needs_wipe_data) {
+            if (!AdtPlugin.displayPrompt("Android Launch", "Are you sure you want to wipe all user data when starting this emulator?")) {
+                needs_wipe_data = 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 (needs_wipe_data) {
+            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 message1 = "adb server change: cancelling '%1$s' launch!";
+        String message2 = "adb server change: cancelling sync!";
+        synchronized (sListLock) {
+            for (DelayedLaunchInfo launchInfo : mWaitingForReadyEmulatorList) {
+                if (launchInfo.mLaunchAction == LaunchConfigDelegate.ACTION_DO_NOTHING) {
+                    AdtPlugin.printErrorToConsole(launchInfo.mProject, message2);
+                } else {
+                    AdtPlugin.printErrorToConsole(launchInfo.mProject,
+                            String.format(message1, launchInfo.mActivity));
+                }
+                launchInfo.mLaunch.stopLaunch();
+            }
+            for (DelayedLaunchInfo launchInfo : mWaitingForDebuggerApplications) {
+                if (launchInfo.mLaunchAction == LaunchConfigDelegate.ACTION_DO_NOTHING) {
+                    AdtPlugin.printErrorToConsole(launchInfo.mProject, message2);
+                } else {
+                    AdtPlugin.printErrorToConsole(launchInfo.mProject,
+                            String.format(message1, launchInfo.mActivity));
+                }
+                launchInfo.mLaunch.stopLaunch();
+            }
+
+            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.mDevice = device;
+
+                // and move it to the other list
+                mWaitingForReadyEmulatorList.add(launchInfo);
+                
+                // and tell the user about it
+                AdtPlugin.printToConsole(launchInfo.mProject,
+                        String.format("New emulator found: %1$s", device.getSerialNumber()));
+                AdtPlugin.printToConsole(launchInfo.mProject,
+                        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' launch!";
+        synchronized (sListLock) {
+            ArrayList<DelayedLaunchInfo> copyList =
+                (ArrayList<DelayedLaunchInfo>)mWaitingForReadyEmulatorList.clone();
+            for (DelayedLaunchInfo launchInfo : copyList) {
+                if (launchInfo.mDevice == device) {
+                    AdtPlugin.printErrorToConsole(launchInfo.mProject,
+                            String.format(message, device.getSerialNumber(), launchInfo.mActivity));
+                    launchInfo.mLaunch.stopLaunch();
+                    mWaitingForReadyEmulatorList.remove(launchInfo);
+                }
+            }
+            copyList = (ArrayList<DelayedLaunchInfo>)mWaitingForDebuggerApplications.clone();
+            for (DelayedLaunchInfo launchInfo : copyList) {
+                if (launchInfo.mDevice == device) {
+                    AdtPlugin.printErrorToConsole(launchInfo.mProject,
+                            String.format(message, device.getSerialNumber(), launchInfo.mActivity));
+                    launchInfo.mLaunch.stopLaunch();
+                    mWaitingForDebuggerApplications.remove(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
+                    Device 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.mDevice == 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.mProject,
+                                            "Launch canceled!");
+                                    launchInfo.mLaunch.stopLaunch();
+                                    return;
+                                }
+        
+                                AdtPlugin.printToConsole(launchInfo.mProject,
+                                        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.mProject,
+                                    "Launch canceled!");
+                                    launchInfo.mLaunch.stopLaunch();
+                                }
+                                
+                                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.mDevice &&
+                            applicationName.equals(launchInfo.mPackageName)) {
+                        // 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.mPackageName, client.getDebuggerListenPort());
+                        AdtPlugin.printToConsole(launchInfo.mProject, msg);
+                        
+                        new Thread("Debugger Connection") { //$NON-NLS-1$
+                            @Override
+                            public void run() {
+                                try {
+                                    if (connectRemoteDebugger(
+                                            client.getDebuggerListenPort(),
+                                            launchInfo.mLaunch, launchInfo.mMonitor) == false) {
+                                        return;
+                                    }
+                                } catch (CoreException e) {
+                                    // well something went wrong.
+                                    AdtPlugin.printErrorToConsole(launchInfo.mProject,
+                                            String.format("Launch error: %s", e.getMessage()));
+                                    // stop the launch
+                                    launchInfo.mLaunch.stopLaunch();
+                                }
+
+                                launchInfo.mMonitor.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();
+    }
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/DeviceChooserDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/DeviceChooserDialog.java
new file mode 100644
index 0000000..a260350
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/DeviceChooserDialog.java
@@ -0,0 +1,705 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.debug.launching;
+
+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.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.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;
+
+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());
+                            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());
+                            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 Device mDeviceToUse;
+        
+        public void setDeviceToUse(Device d) {
+            mDeviceToUse = d;
+            mAvdToLaunch = null;
+        }
+        
+        public void setAvdToLaunch(AvdInfo avd) {
+            mAvdToLaunch = avd;
+            mDeviceToUse = null;
+        }
+        
+        public Device 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.getAvds();
+        } 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());
+        mViewer.addDoubleClickListener(new IDoubleClickListener() {
+            public void doubleClick(DoubleClickEvent event) {
+                ISelection selection = event.getSelection();
+                if (selection instanceof IStructuredSelection) {
+                    IStructuredSelection structuredSelection = (IStructuredSelection)selection;
+                    Object object = structuredSelection.getFirstElement();
+                    if (object instanceof Device) {
+                        mResponse.setDeviceToUse((Device)object);
+                    }
+                }
+            }
+        });
+        
+        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,
+                false /*allowMultipleSelection*/);
+        mPreferredAvdSelector.setTableHeightHint(100);
+        mPreferredAvdSelector.setEnabled(false);
+        mDeviceTable.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                handleDeviceSelection();
+            }
+        });
+        
+        mPreferredAvdSelector.setSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                if (mDisableAvdSelectionChange == false) {
+                    mResponse.setAvdToLaunch(mPreferredAvdSelector.getFirstSelected());
+                    enableOkButton();
+                }
+            }
+        });
+        
+        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);
+        }
+    }
+    
+    /**
+     * 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/debug/launching/LaunchConfigDelegate.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/LaunchConfigDelegate.java
new file mode 100644
index 0000000..bbd320b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/LaunchConfigDelegate.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.debug.launching;
+
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.debug.launching.AndroidLaunchController.AndroidLaunchConfiguration;
+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 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.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 boolean DEFAULT_TARGET_MODE = true; //automatic mode
+
+    /**
+     * 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 propage 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 = 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;
+        }
+
+        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.
+            String[] 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.");
+                activityName = manifestParser.getLauncherActivity();
+                
+                // 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 (String a : activities) {
+                    if (a != null && a.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.");
+                    activityName = manifestParser.getLauncherActivity();
+            
+                    // 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) {
+            activityName = manifestParser.getLauncherActivity();
+            
+            // if there's no default activity. We revert to a sync-only launch.
+            if (activityName == null) {
+                revertToNoActionLaunch(project, config);
+            }
+        }
+
+        // everything seems fine, we ask the launch controller to handle
+        // the rest
+        controller.launch(project, mode, applicationPackage, manifestParser.getPackage(),
+                manifestParser.getDebuggable(), manifestParser.getApiLevelRequirement(),
+                activityName, 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 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.
+     */
+    private 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;
+    }
+
+    /**
+     * 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/debug/launching/LaunchShortcut.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/LaunchShortcut.java
new file mode 100644
index 0000000..92677f1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/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.debug.launching;
+
+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/debug/ui/EmulatorConfigTab.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/EmulatorConfigTab.java
new file mode 100644
index 0000000..d919c1f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/EmulatorConfigTab.java
@@ -0,0 +1,459 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.debug.ui;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.debug.launching.LaunchConfigDelegate;
+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.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();
+
+        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("Device 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:");
+        AvdInfo[] avds = new AvdInfo[0];
+        mPreferredAvdSelector = new AvdSelector(offsetComp, avds,
+                false /*allowMultipleSelection*/);
+        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();
+
+        boolean value = LaunchConfigDelegate.DEFAULT_TARGET_MODE; // true == automatic
+        try {
+            value = configuration.getAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE, value);
+        } catch (CoreException e) {
+            // let's not do anything here, we'll use the default value
+        }
+        mAutoTargetButton.setSelection(value);
+        mManualTargetButton.setSelection(!value);
+        
+        // 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.getAvds();
+        }
+
+        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);
+            mPreferredAvdSelector.setSelection(targetAvd);
+        } else {
+            mPreferredAvdSelector.setSelection(null);
+        }
+
+        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);
+        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/debug/ui/LaunchConfigTabGroup.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/LaunchConfigTabGroup.java
new file mode 100644
index 0000000..c0dbd54
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/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.debug.ui;
+
+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/debug/ui/MainLaunchConfigTab.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/MainLaunchConfigTab.java
new file mode 100644
index 0000000..6a40ed0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/MainLaunchConfigTab.java
@@ -0,0 +1,489 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.debug.ui;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.debug.launching.AndroidLaunchController;
+import com.android.ide.eclipse.adt.debug.launching.LaunchConfigDelegate;
+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.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;
+
+/**
+ * Class for the main launch configuration tab.
+ */
+public class MainLaunchConfigTab extends AbstractLaunchConfigurationTab {
+
+    protected static final String EMPTY_STRING = ""; //$NON-NLS-1$
+    
+    protected Text mProjText;
+    private Button mProjButton;
+
+    private Combo mActivityCombo;
+    private String[] mActivities;
+
+    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("mainLaunchTab.png", 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.length) {
+            configuration.setAttribute(LaunchConfigDelegate.ATTR_ACTIVITY, mActivities[selection]);
+        }
+        
+        // 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);
+
+        // get the list of projects
+        IJavaProject[] projects = mProjectChooserHelper.getAndroidProjects(null);
+
+        if (projects != null) {
+            // look for the currently selected project
+            IProject proj = null;
+            for (IJavaProject p : projects) {
+                if (p.getElementName().equals(projectName)) {
+                    proj = p.getProject();
+                    break;
+                }
+            }
+
+            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.length > 0) {
+                // look for the name of the activity in the combo.
+                boolean found = false;
+                for (int i = 0 ; i < mActivities.length ; i++) {
+                    if (activityName.equals(mActivities[i])) {
+                        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) {
+                    mActivities = manifestParser.getActivities();
+    
+                    mActivityCombo.removeAll();
+    
+                    if (mActivities.length > 0) {
+                        if (mLaunchAction == LaunchConfigDelegate.ACTION_ACTIVITY) {
+                            mActivityCombo.setEnabled(true);
+                        }
+                        for (String s : mActivities) {
+                            mActivityCombo.add(s);
+                        }
+                    } 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 = null;
+    }
+    
+    /**
+     * 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/messages.properties b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/messages.properties
new file mode 100644
index 0000000..dfb0eb2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/messages.properties
@@ -0,0 +1,16 @@
+Dialog_Title_SDK_Location=Android SDK Location
+SDK_Not_Setup=The location of the Android SDK has not been setup. Please go to Preferences > Android and set it up
+Error_Check_Prefs=%1$s\nPlease check the Android plugin's preferences.
+Could_Not_Find_Folder=Could not find SDK folder '%1$s'.
+Could_Not_Find_Folder_In_SDK=Could not find folder '%1$s' inside SDK '%2$s'.
+Could_Not_Find=Could not find %1$s\!
+VersionCheck_SDK_Milestone_Too_Low=This version of ADT requires a SDK in version M%1$d or above.\n\nCurrent version is %2$s.\n\nPlease update your SDK to the latest version.
+VersionCheck_SDK_Build_Too_Low=This version of ADT requires a SDK in version %1$d (M%2$d) or above.\n\nCurrent version is %3$s.\n\nPlease update your SDK to the latest version.
+VersionCheck_Plugin_Version_Failed=Failed to get the required ADT version number from the SDK.\n\nThe Android Developer Toolkit may not work properly.
+VersionCheck_Unable_To_Parse_Version_s=Unable to parse sdk build version: %1$s
+VersionCheck_Plugin_Too_Old=This Android SDK requires Android Developer Toolkit version %1$d.%2$d.%3$d or above.\n\nCurrent version is %4$s.\n\nPlease update ADT to the latest version.
+AdtPlugin_Failed_To_Start_s=Failed to start %1$s
+AdtPlugin_Android_SDK_Content_Loader=Android SDK Content Loader
+AdtPlugin_Parsing_Resources=Parsing Resources
+AdtPlugin_Android_SDK_Resource_Parser=Android SDK Resource Parser
+AdtPlugin_Failed_To_Parse_s=Failed to parse: 
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
new file mode 100644
index 0000000..458f78e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/AndroidPreferencePage.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 {
+
+    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() {
+
+        addField(new SdkDirectoryFieldEditor(AdtPlugin.PREFS_SDK_DIR,
+                Messages.AndroidPreferencePage_SDK_Location_, getFieldEditorParent()));
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+     */
+    public void init(IWorkbench workbench) {
+    }
+
+    /**
+     * 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*/
+                        false /*multipleSelection*/);
+                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
new file mode 100644
index 0000000..e64c2f4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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
new file mode 100644
index 0000000..8fd72c1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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
new file mode 100644
index 0000000..e0197b9
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/Messages.java
@@ -0,0 +1,43 @@
+
+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
new file mode 100644
index 0000000..2b1fb66
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/preferences/messages.properties b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/messages.properties
new file mode 100644
index 0000000..865ac19
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/messages.properties
@@ -0,0 +1,14 @@
+BuildPreferencePage_Title=Build Settings:
+BuildPreferencePage_Auto_Refresh_Resources_on_Build=Automatically refresh Resources and Assets folder on build
+BuildPreferencePage_Build_Output=Build output
+BuildPreferencePage_Silent=Silent
+BuildPreferencePage_Normal=Normal
+BuildPreferencePage_Verbose=Verbose
+BuildPreferencePage_Default_KeyStore=Default debug keystore:
+BuildPreferencePage_Custom_Keystore=Custom debug keystore:
+LaunchPreferencePage_Title=Launch Settings:
+LaunchPreferencePage_Default_Emu_Options=Default emulator options:
+LaunchPreferencePage_Default_HOME_Package=Default HOME package:
+AndroidPreferencePage_Title=Android Preferences
+AndroidPreferencePage_SDK_Location_=SDK Location:
+AndroidPreferencePage_ERROR_Reserved_Char=Reserved characters ',' and ';' cannot be used in the SDK Location.
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/AndroidNature.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/AndroidNature.java
new file mode 100644
index 0000000..9bcadaf
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/ConvertToAndroidAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/ConvertToAndroidAction.java
new file mode 100644
index 0000000..ffb2535
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/ConvertToAndroidAction.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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/CreateAidlImportAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/CreateAidlImportAction.java
new file mode 100644
index 0000000..a1b3c38
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/CreateAidlImportAction.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+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.jobs.Job;
+import org.eclipse.jdt.core.ICompilationUnit;
+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.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.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * Action going through all the source of a project and creating a pre-processed aidl file
+ * with all the custom parcelable classes.
+ */
+public class CreateAidlImportAction  implements IObjectActionDelegate {
+
+    private ISelection mSelection;
+
+    public CreateAidlImportAction() {
+        // pass
+    }
+
+    public void setActivePart(IAction action, IWorkbenchPart targetPart) {
+        // pass
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.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) {
+                    final IProject fproject = project;
+                    new Job("Aidl preprocess") {
+                        @Override
+                        protected IStatus run(IProgressMonitor monitor) {
+                            return createImportFile(fproject, monitor);
+                        }
+                    }.schedule();
+                }
+            }
+        }
+    }
+
+    public void selectionChanged(IAction action, ISelection selection) {
+        mSelection = selection;
+    }
+
+    private IStatus createImportFile(IProject project, IProgressMonitor monitor) {
+        try {
+            if (monitor != null) {
+                monitor.beginTask(String.format(
+                        "Creating aid preprocess file for %1$s", project.getName()), 1);
+            }
+            
+            ArrayList<String> parcelables = new ArrayList<String>();
+            
+            IJavaProject javaProject = JavaCore.create(project);
+            
+            IPackageFragmentRoot[] roots = javaProject.getPackageFragmentRoots();
+            
+            for (IPackageFragmentRoot root : roots) {
+                if (root.isArchive() == false && root.isExternal() == false) {
+                    parsePackageFragmentRoot(root, parcelables, monitor);
+                }
+            }
+            
+            // create the file with the parcelables
+            if (parcelables.size() > 0) {
+                IPath path = project.getLocation();
+                path = path.append(AndroidConstants.FN_PROJECT_AIDL);
+                
+                File f = new File(path.toOSString());
+                if (f.exists() == false) {
+                    if (f.createNewFile() == false) {
+                        return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+                                "Failed to create /project.aidl");
+                    }
+                }
+                
+                FileWriter fw = new FileWriter(f);
+                
+                fw.write("// This file is auto-generated by the\n");
+                fw.write("//    'Create Aidl preprocess file for Parcelable classes'\n");
+                fw.write("// action. Do not modify!\n\n");
+                
+                for (String parcelable : parcelables) {
+                    fw.write("parcelable "); //$NON-NLS-1$
+                    fw.write(parcelable);
+                    fw.append(";\n"); //$NON-NLS-1$
+                }
+                
+                fw.close();
+                
+                // need to refresh the level just below the project to make sure it's being picked
+                // up by eclipse.
+                project.refreshLocal(IResource.DEPTH_ONE, monitor);
+            }
+            
+            if (monitor != null) {
+                monitor.worked(1);
+                monitor.done();
+            }
+            
+            return Status.OK_STATUS;
+        } catch (JavaModelException e) {
+            return e.getJavaModelStatus();
+        } catch (IOException e) {
+            return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID,
+                    "Failed to create /project.aidl", e);
+        } catch (CoreException e) {
+            return e.getStatus();
+        } finally {
+            if (monitor != null) {
+                monitor.done();
+            }
+        }
+    }
+    
+    private void parsePackageFragmentRoot(IPackageFragmentRoot root,
+            ArrayList<String> parcelables, IProgressMonitor monitor) throws JavaModelException {
+        
+        IJavaElement[] elements = root.getChildren();
+        
+        for (IJavaElement element : elements) {
+            if (element instanceof IPackageFragment) {
+                ICompilationUnit[] compilationUnits =
+                    ((IPackageFragment)element).getCompilationUnits();
+                
+                for (ICompilationUnit unit : compilationUnits) {
+                    IType[] types = unit.getTypes();
+                    
+                    for (IType type : types) {
+                        parseType(type, parcelables, monitor);
+                    }
+                }
+            }
+        }
+    }
+
+    private void parseType(IType type, ArrayList<String> parcelables, IProgressMonitor monitor)
+            throws JavaModelException {
+        // first look in this type if it somehow extends parcelable.
+        ITypeHierarchy typeHierarchy = type.newSupertypeHierarchy(monitor);
+        
+        IType[] superInterfaces = typeHierarchy.getAllSuperInterfaces(type);
+        for (IType superInterface : superInterfaces) {
+            if (AndroidConstants.CLASS_PARCELABLE.equals(superInterface.getFullyQualifiedName())) {
+                parcelables.add(type.getFullyQualifiedName());
+            }
+        }
+        
+        // then look in inner types.
+        IType[] innerTypes = type.getTypes();
+        
+        for (IType innerType : innerTypes) {
+            parseType(innerType, parcelables, monitor);
+        }
+    }
+}
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
new file mode 100644
index 0000000..3d7e929
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/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.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
new file mode 100644
index 0000000..9ade490
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/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.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
new file mode 100644
index 0000000..b8a0b0c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.project;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.debug.launching.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
new file mode 100644
index 0000000..3043818
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FixProjectAction.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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
new file mode 100644
index 0000000..7fc3318
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FolderDecorator.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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");
+    }
+
+    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)) {
+                            decorate(decoration, " [Android assets]");
+                            decoration.addOverlay(mDescriptor, IDecoration.TOP_RIGHT);
+                        } else if (name.equals(SdkConstants.FD_RESOURCES)) {
+                            decorate(decoration, " [Android resources]");
+                            decoration.addOverlay(mDescriptor, IDecoration.TOP_RIGHT);
+                        } else if (name.equals(SdkConstants.FD_NATIVE_LIBS)) {
+                            decorate(decoration, " [Native Libraries]");
+                        }
+                    }
+                }
+            } catch (CoreException e) {
+                // log the error
+                AdtPlugin.log(e, "Unable to get nature of project '%s'.", project.getName());
+            }
+        }
+    }
+    
+    public void decorate(IDecoration decoration, String suffix) {
+        decoration.addOverlay(mDescriptor, IDecoration.TOP_RIGHT);
+
+        // 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.
+//        decoration.addSuffix(suffix);
+//        ITheme theme = PlatformUI.getWorkbench().getThemeManager().getCurrentTheme();
+//        ColorRegistry registry = theme.getColorRegistry();
+//        decoration.setForegroundColor(registry.get("org.eclipse.jdt.ui.ColoredLabels.decorations"));
+
+    }
+
+    public boolean isLabelProperty(Object element, String property) {
+        // at this time return false.
+        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() {
+        // nothind to dispose
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/NewXmlFileWizardAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/NewXmlFileWizardAction.java
new file mode 100644
index 0000000..c117b4e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/NewXmlFileWizardAction.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.project;
+
+import com.android.ide.eclipse.editors.wizards.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/project/ProjectHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/ProjectHelper.java
new file mode 100644
index 0000000..cbeddd7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/ProjectHelper.java
@@ -0,0 +1,668 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.AndroidManifestHelper;
+import com.android.ide.eclipse.common.project.AndroidManifestParser;
+
+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.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.launching.JavaRuntime;
+
+import java.util.ArrayList;
+
+/**
+ * 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;
+                }
+
+                AndroidManifestHelper androidManifest = new AndroidManifestHelper(p);
+                
+                // check that there is indeed a manifest file.
+                if (androidManifest.getManifestIFile() == null) {
+                    // no file? skip this project.
+                    continue;
+                }
+
+                AndroidManifestParser parser = null;
+                try {
+                    parser = AndroidManifestParser.parseForData(
+                        androidManifest.getManifestIFile());
+                } catch (CoreException e) {
+                    // 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;
+    }
+}
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
new file mode 100644
index 0000000..399eac9
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ExportWizard.java
@@ -0,0 +1,501 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.jarutils.KeystoreHelper;
+import com.android.jarutils.SignedJarBuilder;
+import com.android.jarutils.DebugKeyProvider.IKeyGenOutput;
+import com.android.jarutils.DebugKeyProvider.KeytoolException;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IAdaptable;
+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 java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+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;
+
+/**
+ * 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$
+    
+    /**
+     * 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 final 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 String mDestinationPath;
+    private String mApkFilePath;
+    private String mApkFileName;
+
+    private ExportWizardPage mKeystoreSelectionPage;
+    private ExportWizardPage mKeyCreationPage;
+    private ExportWizardPage mKeySelectionPage;
+    private ExportWizardPage mKeyCheckPage;
+
+    private boolean mKeyCreationMode;
+
+    private List<String> mExistingAliases;
+
+    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() {
+        // first we make sure export is fine if the destination file already exists
+        File f = new File(mDestinationPath);
+        if (f.isFile()) {
+            if (AdtPlugin.displayPrompt("Export Wizard",
+                    "File already exists. Do you want to overwrite it?") == false) {
+                return false;
+            }
+        }
+        
+        // save the properties
+        ProjectHelper.saveStringProperty(mProject, PROPERTY_KEYSTORE, mKeystore);
+        ProjectHelper.saveStringProperty(mProject, PROPERTY_ALIAS, mKeyAlias);
+        ProjectHelper.saveStringProperty(mProject, PROPERTY_DESTINATION, mDestinationPath);
+        
+        try {
+            if (mKeystoreCreationMode || mKeyCreationMode) {
+                final ArrayList<String> output = new ArrayList<String>();
+                if (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);
+                            }
+                        }) == 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) {
+                FileOutputStream fos = new FileOutputStream(mDestinationPath);
+                SignedJarBuilder builder = new SignedJarBuilder(fos, mPrivateKey, mCertificate);
+                
+                // get the input file.
+                FileInputStream fis = new FileInputStream(mApkFilePath);
+                try {
+                    builder.writeZip(fis, null /* filter */);
+                } finally {
+                    fis.close();
+                }
+    
+                builder.close();
+                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);
+        }
+
+        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 mApkFilePath != null &&
+                ((mPrivateKey != null && mCertificate != null)
+                        || mKeystoreCreationMode || mKeyCreationMode) &&
+                mDestinationPath != 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, String apkFilePath, String filename) {
+        mProject = project;
+        mApkFilePath = apkFilePath;
+        mApkFileName = filename;
+        
+        updatePageOnChange(ExportWizardPage.DATA_PROJECT);
+    }
+    
+    String getApkFilename() {
+        return mApkFileName;
+    }
+    
+    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(String path) {
+        mDestinationPath = path;
+    }
+    
+    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.
+     */
+    private 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
new file mode 100644
index 0000000..c64bf10
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/KeyCheckPage.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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.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 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;
+
+/**
+ * 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;
+
+    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();
+            }
+        });
+        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");
+                fileDialog.setFileName(mWizard.getApkFilename());
+        
+                String saveLocation = fileDialog.open();
+                if (saveLocation != null) {
+                    mDestination.setText(saveLocation);
+                }
+            }
+        });
+        
+        mDetailText = new FormText(composite, SWT.NONE);
+        mDetailText.setLayoutData(gd = new GridData(GridData.FILL_BOTH));
+        gd.horizontalSpan = 3;
+        
+        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();
+            
+            String destination = ProjectHelper.loadStringProperty(project,
+                    ExportWizard.PROPERTY_DESTINATION);
+            if (destination != null) {
+                mDestination.setText(destination);
+            }
+        }
+        
+        // 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);
+    
+            if (mWizard.getKeystoreCreationMode() || mWizard.getKeyCreationMode()) {
+                int validity = mWizard.getValidity();
+                StringBuilder sb = new StringBuilder(
+                        String.format("<form><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>");
+                }
+
+                sb.append("</form>");
+                mDetailText.setText(sb.toString(), true /* parseTags */, true /* expandURLs */);
+            } 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)) {
+                        mDetailText.setText(String.format(
+                                "<form><p>Certificate expired on %s</p></form>",
+                                mCertificate.getNotAfter().toString()),
+                                true /* parseTags */, true /* expandURLs */);
+                        
+                        // 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(
+                                "<form><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>");
+                        }
+                        
+                        sb.append("</form>");
+        
+                        mDetailText.setText(sb.toString(), true /* parseTags */, true /* expandURLs */);
+                    }
+                    mDetailText.getParent().layout();
+                } else {
+                    // fatal error = nothing can make the page complete.
+                    mFatalSigningError = true;
+                }
+            }
+        }
+
+        onDestinationChange();
+    }
+    
+    private void onDestinationChange() {
+        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.");
+                mWizard.setDestination(null); // this is to reset canFinish in the wizard
+                setPageComplete(false);
+                return;
+            }
+
+            File file = new File(path);
+            if (file.isDirectory()) {
+                setErrorMessage("Destination is a directory.");
+                mWizard.setDestination(null); // this is to reset canFinish in the wizard
+                setPageComplete(false);
+                return;
+            }
+
+            File parentFile = file.getParentFile();
+            if (parentFile == null || parentFile.isDirectory() == false) {
+                setErrorMessage("Not a valid directory.");
+                mWizard.setDestination(null); // this is to reset canFinish in the wizard
+                setPageComplete(false);
+                return;
+            }
+
+            // no error, set the destination in the wizard.
+            mWizard.setDestination(path);
+            setPageComplete(true);
+            
+            // However, we should also test if the file already exists.
+            if (file.isFile()) {
+                setMessage("Destination file already exists.", WARNING);
+            }
+        }
+    }
+}
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
new file mode 100644
index 0000000..d7365f7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/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.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
new file mode 100644
index 0000000..2fcd757
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/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.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
new file mode 100644
index 0000000..c5a4d47
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/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.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
new file mode 100644
index 0000000..e161e18
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ProjectCheckPage.java
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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, null, 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
+                setApkFilePathInWizard(found);
+
+                // now rebuild the error ui.
+                buildErrorUi(found);
+            } else {
+                setErrorMessage(String.format("There is no android project named '%1$s'",
+                        text));
+            }
+        }
+    }
+    
+    private void setApkFilePathInWizard(IProject project) {
+        if (project != null) {
+            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()) {
+                    mWizard.setProject(project, apkFilePath, f.getName());
+                    return;
+                }
+            }
+        }
+
+        mWizard.setProject(null, null, null);
+    }
+
+}
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
new file mode 100644
index 0000000..c7cb427
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/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.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
new file mode 100644
index 0000000..d686830
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java
@@ -0,0 +1,627 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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 PATH_ANDROID_JAR = 0;
+    private final static int PATH_ANDROID_SRC = 1;
+    private final static int PATH_ANDROID_DOCS = 2;
+    private final static int PATH_ANDROID_OPT_DOCS = 3;
+    
+    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.getFullName();
+
+                    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.printBuildToConsole(AdtConstants.BUILD_ALWAYS, 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[PATH_ANDROID_DOCS] is a URI to the javadoc, so we test it a bit differently.
+        try {
+            if (new File(paths[PATH_ANDROID_JAR]).exists() == false ||
+                    new File(new URI(paths[PATH_ANDROID_DOCS])).exists() == false) {
+                return null;
+            }
+        } catch (URISyntaxException e) {
+            return null;
+        } finally {
+            
+        }
+        
+        for (int i = 3 ; i < paths.length; i++) {
+            String path = paths[i];
+            if (path.length() > 0) {
+                File f =  new File(path);
+                if (f.exists() == false) {
+                    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[PATH_ANDROID_JAR]);
+        IPath android_src = new Path(paths[PATH_ANDROID_SRC]);
+
+        // create the java doc link.
+        IClasspathAttribute cpAttribute = JavaCore.newClasspathAttribute(
+                IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME,
+                paths[PATH_ANDROID_DOCS]);
+        
+        // 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[PATH_ANDROID_OPT_DOCS];
+            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();
+            
+            // 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[PATH_ANDROID_JAR]).equals(
+                            new File(cachedPaths[PATH_ANDROID_JAR])) == false ||
+                    new File(targetPaths[PATH_ANDROID_SRC]).equals(
+                            new File(cachedPaths[PATH_ANDROID_SRC])) == false ||
+                    new File(targetPaths[PATH_ANDROID_DOCS]).equals(
+                            new File(cachedPaths[PATH_ANDROID_DOCS])) == false) {
+                // different paths, force resolve again.
+                i++;
+                continue;
+            }
+            
+            if (cachedPaths.length > PATH_ANDROID_OPT_DOCS) {
+                // compare optional libraries javadoc
+                if (new File(targetPaths[PATH_ANDROID_OPT_DOCS]).equals(
+                        new File(cachedPaths[PATH_ANDROID_OPT_DOCS])) == 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(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
new file mode 100644
index 0000000..a4c019f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/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.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 Target");
+        
+        mSelector = new SdkTargetSelector(top, targets, false /*allowMultipleSelection*/);
+
+        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.getFirstSelected();
+                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.getFirstSelected(),
+                    mApkConfigWidget.getApkConfigs());
+        }
+        
+        return true;
+    }
+}
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
new file mode 100644
index 0000000..1f6ebf1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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
new file mode 100644
index 0000000..a8852e7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetData.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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_GADGET_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_GADGET_PROVIDER:
+                return mXmlDescriptors.getGadgetProvider();
+            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
new file mode 100644
index 0000000..04baeba
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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> xmlGadgetMap = null;
+            if (mAndroidTarget.getApiVersionNumber() >= 3) {
+                xmlGadgetMap = collectGadgetDefinitions(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,
+                    xmlGadgetMap,
+                    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 gadgetProviderInfo definition information from the attrs.xml and returns it.
+     * 
+     * @param attrsXmlParser The parser of the attrs.xml file
+     */
+    private Map<String, DeclareStyleableInfo> collectGadgetDefinitions(
+            AttrsXmlParser attrsXmlParser) {
+        Map<String, DeclareStyleableInfo> map = attrsXmlParser.getDeclareStyleableList();
+        Map<String, DeclareStyleableInfo> map2 = new HashMap<String, DeclareStyleableInfo>();
+        for (String key : new String[] { "GadgetProviderInfo" }) {  //$NON-NLS-1$
+            if (map.containsKey(key)) {
+                map2.put(key, map.get(key));
+            } else {
+                AdtPlugin.log(IStatus.WARNING,
+                        "Gadget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
+                        key, attrsXmlParser.getOsAttrsXmlPath());
+                AdtPlugin.printErrorToConsole("Android Framework Parser",
+                        String.format("Gadget 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
new file mode 100644
index 0000000..f4b10df
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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
new file mode 100644
index 0000000..35057d1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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
new file mode 100644
index 0000000..dc600d7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/LayoutParamsParser.java
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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);
+            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_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
new file mode 100644
index 0000000..6bf0272
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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
new file mode 100644
index 0000000..ba0b568
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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(errorFormat, arg));
+                }
+                
+                if (throwable != null) {
+                    logMessages.add(throwable.getMessage());
+                }
+            }
+
+            public void warning(String warningFormat, Object... arg) {
+                logMessages.add(String.format(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
new file mode 100644
index 0000000..0e60f8a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/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.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/wizards/actions/NewProjectAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewProjectAction.java
new file mode 100644
index 0000000..e0d0d5e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewProjectAction.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.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
new file mode 100644
index 0000000..8c4a115
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewXmlFileAction.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.wizards.actions;
+
+import com.android.ide.eclipse.editors.wizards.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/OpenWizardAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/OpenWizardAction.java
new file mode 100644
index 0000000..4fc9dee
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/OpenWizardAction.java
@@ -0,0 +1,139 @@
+/*
+ * 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
new file mode 100644
index 0000000..33ec2bc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectCreationPage.java
@@ -0,0 +1,1319 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.sdk.Sdk;
+import com.android.ide.eclipse.common.AndroidConstants;
+import com.android.ide.eclipse.common.project.AndroidManifestHelper;
+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 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.getFirstSelected();
+    }
+
+    /**
+     * 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());
+    }
+
+    /**
+     * 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("Target");
+        
+        // get the targets from the sdk
+        IAndroidTarget[] targets = null;
+        if (Sdk.getCurrent() != null) {
+            targets = Sdk.getCurrent().getTargets();
+        }
+
+        mSdkTargetSelector = new SdkTargetSelector(group, targets, false /*multi-selection*/);
+
+        // If there's only one target, select it
+        if (targets != null && targets.length == 1) {
+            mSdkTargetSelector.setSelection(targets[0]);
+        }
+        
+        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 ||
+                            !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();
+        AndroidManifestHelper manifest = new AndroidManifestHelper(osPath);
+        if (!manifest.exists()) {
+            return;
+        }
+        
+        String packageName = null;
+        String activityName = null;
+        String minSdkVersion = null;
+        try {
+            packageName = manifest.getPackageName();
+            activityName = manifest.getActivityName(1);
+            minSdkVersion = manifest.getMinSdkVersion();
+        } catch (Exception e) {
+            // ignore exceptions
+        }
+
+
+        if (packageName != null && packageName.length() > 0) {
+            mPackageNameField.setText(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 != null) {
+            try {
+                int sdkVersion = Integer.parseInt(minSdkVersion); 
+
+                for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
+                    if (target.getApiVersionNumber() == sdkVersion) {
+                        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 == null ? "" : 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();
+            AndroidManifestHelper manifest = new AndroidManifestHelper(osPath);
+            if (!manifest.exists()) {
+                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.
+            String packageName = manifest.getPackageName();
+            if (packageName == null || packageName.length() == 0) {
+                return setStatus(
+                        String.format("No package name defined in %1$s.", osPath),
+                        MSG_ERROR);
+            }
+
+            String activityName = manifest.getActivityName(1);
+            if (activityName == null || activityName.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 = -1;
+        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
new file mode 100644
index 0000000..cb79796
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java
@@ -0,0 +1,737 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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
+            IJavaProject javaProject = JavaCore.create(project);
+            for (String sourceFolder : sourceFolders) {
+                setupSourceFolder(javaProject, sourceFolder, monitor);
+            }
+
+            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/common/AndroidConstants.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java
new file mode 100644
index 0000000..e201132
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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$
+    public static final String FN_PROJECT_AIDL = "project.aidl"; //$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 + "/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_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_LAYOUTPARAMS = "LayoutParams"; //$NON-NLS-1$
+    public final static String CLASS_VIEWGROUP_LAYOUTPARAMS =
+        CLASS_VIEWGROUP + "$" + CLASS_LAYOUTPARAMS; //$NON-NLS-1$
+    public final static String CLASS_FRAMELAYOUT = "FrameLayout"; //$NON-NLS-1$
+    public final static String CLASS_PREFERENCE = "android.preference.Preference"; //$NON-NLS-1$
+    public final static String CLASS_PREFERENCE_SCREEN = "PreferenceScreen"; //$NON-NLS-1$
+    public final static String CLASS_PREFERENCES =
+        "android.preference." + CLASS_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$
+    
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/EclipseUiHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/EclipseUiHelper.java
new file mode 100644
index 0000000..6dc8562
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.common;
+
+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/common/Messages.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/Messages.java
new file mode 100644
index 0000000..3f1bde4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/Messages.java
@@ -0,0 +1,21 @@
+
+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
new file mode 100644
index 0000000..345c663
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/SdkStatsHelper.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.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
new file mode 100644
index 0000000..6ccf4f2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/StreamHelper.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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
new file mode 100644
index 0000000..dba6edc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/messages.properties
@@ -0,0 +1,2 @@
+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
new file mode 100644
index 0000000..58c2f40
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.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/AndroidManifestHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestHelper.java
new file mode 100644
index 0000000..cd238d2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestHelper.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.xml.sax.InputSource;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpressionException;
+
+/**
+ * Utility class that manages the AndroidManifest.xml file.
+ * <p/>
+ * All the get method work by XPath. Repeated calls to those may warrant using
+ * {@link AndroidManifestParser} instead.
+ */
+public class AndroidManifestHelper {
+    private IFile mManifestIFile;
+    private File mManifestFile;
+    private XPath mXPath;
+
+    /**
+     * Creates an AndroidManifest based on an existing Eclipse {@link IProject} object.
+     * </p>
+     * Use {@link #exists()} to check if the manifest file really exists in the project.
+     *
+     * @param project The project to search for the manifest.
+     */
+    public AndroidManifestHelper(IProject project) {
+        mXPath = AndroidXPathFactory.newXPath();
+        mManifestIFile = getManifest(project);
+    }
+    
+    /**
+     * Creates an AndroidManifest based on a file path.
+     * <p/>
+     * Use {@link #exists()} to check if the manifest file really exists.
+     *
+     * @param osManifestFilePath the os path to the AndroidManifest.xml file.
+     */
+    public AndroidManifestHelper(String osManifestFilePath) {
+        mXPath = AndroidXPathFactory.newXPath();
+        mManifestFile = new File(osManifestFilePath);
+    }
+
+
+    /**
+     * Returns the underlying {@link IFile} for the android manifest XML file, if found in the
+     * given Eclipse project.
+     *
+     * Always return null if the constructor that takes an {@link IProject} was NOT called.
+     *
+     * @return The IFile for the androidManifest.xml or null if no such file could be found.
+     */
+    public IFile getManifestIFile() {
+        return mManifestIFile;
+    }
+    
+    /**
+     * Returns the underlying {@link File} for the android manifest XML file.
+     */
+    public File getManifestFile() {
+        if (mManifestIFile != null) {
+            return mManifestIFile.getLocation().toFile();
+        }
+        
+        return mManifestFile;
+    }
+
+     /**
+     * Returns the package name defined in the manifest file.
+     *
+     * @return A String object with the package or null if any error happened.
+     */
+    public String getPackageName() {
+        try {
+            return mXPath.evaluate("/manifest/@package", getSource());  //$NON-NLS-1$
+        } catch (XPathExpressionException e1) {
+            // If the XPath failed to evaluate, we'll return null.
+        } catch (Exception e) {
+            // if this happens this is due to the resource being out of sync.
+            // so we must refresh it and do it again
+
+            // for any other kind of exception we must return null as well;
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the minSdkVersion defined in the manifest file.
+     *
+     * @return A String object with the package or null if any error happened.
+     */
+    public String getMinSdkVersion() {
+        try {
+            return mXPath.evaluate("/manifest/uses-sdk/@"                       //$NON-NLS-1$
+                    + AndroidXPathFactory.DEFAULT_NS_PREFIX
+                    + ":minSdkVersion", getSource());                           //$NON-NLS-1$
+        } catch (XPathExpressionException e1) {
+            // If the XPath failed to evaluate, we'll return null.
+        } catch (Exception e) {
+            // if this happens this is due to the resource being out of sync.
+            // so we must refresh it and do it again
+
+            // for any other kind of exception we must return null as well;
+        }
+
+        return null;
+    }
+    /**
+     * Returns the i-th activity defined in the manifest file.
+     *
+     * @param index The 1-based index of the activity to return.
+     * @return A String object with the activity or null if any error happened.
+     */
+    public String getActivityName(int index) {
+        try {
+            return mXPath.evaluate("/manifest/application/activity["            //$NON-NLS-1$
+                    + index
+                    + "]/@"                                                     //$NON-NLS-1$
+                    + AndroidXPathFactory.DEFAULT_NS_PREFIX +":name",           //$NON-NLS-1$
+                    getSource());
+        } catch (XPathExpressionException e1) {
+            // If the XPath failed to evaluate, we'll return null.
+        } catch (Exception e) {
+            // if this happens this is due to the resource being out of sync.
+            // so we must refresh it and do it again
+
+            // for any other kind of exception we must return null as well;
+        }
+        return null;
+    }
+
+    /**
+     * 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;
+        }
+    }
+    
+    
+
+    /**
+     * Returns true either if an androidManifest.xml file was found in the project
+     * or if the given file path exists.
+     */
+    public boolean exists() {
+        if (mManifestIFile != null) {
+            return mManifestIFile.exists();
+        } else if (mManifestFile != null) {
+            return mManifestFile.exists();
+        }
+        
+        return false;
+    }
+
+    /**
+     * Returns an InputSource for XPath.
+     *
+     * @throws FileNotFoundException if file does not exist.
+     * @throws CoreException if the {@link IFile} does not exist.
+     */
+    private InputSource getSource() throws FileNotFoundException, CoreException {
+        if (mManifestIFile != null) {
+            return new InputSource(mManifestIFile.getContents());
+        } else if (mManifestFile != null) {
+            return new InputSource(new FileReader(mManifestFile));
+        }
+        
+        return null;
+    }
+
+}
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
new file mode 100644
index 0000000..850c59d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java
@@ -0,0 +1,661 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 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.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.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 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 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$
+    
+    private static class ManifestHandler extends XmlErrorHandler {
+        
+        //--- data read from the parsing
+        
+        /** Application package */
+        private String mPackage;
+        /** List of all activities */
+        private final ArrayList<String> mActivities = new ArrayList<String>();
+        /** Launcher activity */
+        private String 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 0 the attribute was not present. */
+        private int mApiLevelRequirement = 0;
+
+        //--- 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 boolean mFoundMainAction = false;
+        private boolean mFoundLauncherCategory = false;
+        private String mCurrentActivity = null;
+        private Locator mLocator;
+        
+        /**
+         * 
+         * @param manifestFile
+         * @param errorListener
+         * @param gatherData
+         * @param javaProject
+         * @param markErrors
+         */
+        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.
+         */
+        String[] getActivities() {
+            return mActivities.toArray(new String[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. 
+         */
+        String 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 0 if it's not set. 
+         */
+        int getApiLevelRequirement() {
+            return mApiLevelRequirement;
+        }
+        
+        /* (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 */);
+                                }
+                            }
+                            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++;
+                            }
+                            break;
+                        case LEVEL_INTENT_FILTER:
+                            // only process this level if we are in an activity
+                            if (mCurrentActivity != null && NODE_INTENT.equals(localName)) {
+                                // if we're at the intent level, lets reset some flag to
+                                // be used when parsing the children
+                                mFoundMainAction = false;
+                                mFoundLauncherCategory = false;
+                                mValidLevel++;
+                            }
+                            break;
+                        case LEVEL_CATEGORY:
+                            if (mCurrentActivity != null && mLauncherActivity == null) {
+                                if (NODE_ACTION.equals(localName)) {
+                                    // get the name attribute
+                                    if (ACTION_MAIN.equals(
+                                            getAttributeValue(attributes, ATTRIBUTE_NAME,
+                                                    true /* hasNamespace */))) {
+                                        mFoundMainAction = true;
+                                    }
+                                } else if (NODE_CATEGORY.equals(localName)) {
+                                    if (CATEGORY_LAUNCHER.equals(
+                                            getAttributeValue(attributes, ATTRIBUTE_NAME,
+                                                    true /* hasNamespace */))) {
+                                        mFoundLauncherCategory = 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 (mCurrentActivity != null &&
+                                    mFoundMainAction && mFoundLauncherCategory) {
+                                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) {
+                mCurrentActivity = AndroidManifestHelper.combinePackageAndClassName(mPackage,
+                        activityName);
+                mActivities.add(mCurrentActivity);
+                
+                if (mMarkErrors) {
+                    checkClass(mCurrentActivity, AndroidConstants.CLASS_ACTIVITY,
+                            true /* testVisibility */);
+                }
+            } else {
+                // no activity found! Aapt will output an error,
+                // so we don't have to do anything
+                mCurrentActivity = activityName;
+            }
+            
+            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 = AndroidManifestHelper.combinePackageAndClassName(mPackage,
+                        serviceName);
+                
+                if (mMarkErrors) {
+                    checkClass(serviceName, superClassName, false /* testVisibility */);
+                }
+            }
+            
+            String processName = getAttributeValue(attributes, ATTRIBUTE_PROCESS,
+                    true /* hasNamespace */);
+            if (processName != null) {
+                addProcessName(processName);
+            }
+        }
+
+        /**
+         * 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) {
+            // 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 String[] mActivities;
+    private final String mLauncherActivity;
+    private final String[] mProcesses;
+    private final Boolean mDebuggable;
+    private final int mApiLevelRequirement;
+
+    static {
+        sParserFactory = SAXParserFactory.newInstance();
+        sParserFactory.setNamespaceAware(true);
+    }
+    
+    /**
+     * Parses the Android Manifest, and returns an object containing
+     * the result of the parsing.
+     * @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());
+        } catch (ParserConfigurationException e) {
+        } catch (SAXException e) {
+        } catch (IOException e) {
+        } finally {
+        }
+
+        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 {
+        try {
+            SAXParser parser = sParserFactory.newSAXParser();
+            
+            IFile manifestFile = AndroidManifestHelper.getManifest(javaProject.getProject());
+            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());
+            }
+        } catch (ParserConfigurationException e) {
+        } catch (SAXException e) {
+        } catch (IOException e) {
+        } finally {
+        }
+        
+        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
+     */
+    public static AndroidManifestParser parseForData(IFile manifestFile) throws CoreException {
+        return parse(null /* javaProject */, manifestFile, null /* errorListener */,
+                true /* gatherData */, false /* markErrors */);
+    }
+
+    /**
+     * 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 fully qualified class names, or empty if no activity were found.
+     */
+    public String[] 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 fully qualified name of a HOME activity or null if none were found. 
+     */
+    public String 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 0 if it's not set. 
+     */
+    public int getApiLevelRequirement() {
+        return mApiLevelRequirement;
+    }
+
+    
+    /**
+     * 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.
+     */
+    private AndroidManifestParser(String javaPackage, String[] activities,
+            String launcherActivity, String[] processes, Boolean debuggable,
+            int apiLevelRequirement) {
+        mJavaPackage = javaPackage;
+        mActivities = activities;
+        mLauncherActivity = launcherActivity;
+        mProcesses = processes;
+        mDebuggable = debuggable;
+        mApiLevelRequirement = apiLevelRequirement;
+    }
+}
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
new file mode 100644
index 0000000..0f1e255
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.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
new file mode 100644
index 0000000..bd8b444
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.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
new file mode 100644
index 0000000..4b169a1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.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
new file mode 100644
index 0000000..0c43499
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/ProjectChooserHelper.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.project.BaseProjectHelper;
+
+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;
+    }
+}
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
new file mode 100644
index 0000000..fda55c4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 {
+        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 (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
new file mode 100644
index 0000000..3875e81
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.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
new file mode 100644
index 0000000..efa5981
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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;
+        }
+
+        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
new file mode 100644
index 0000000..38b7e03
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.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
new file mode 100644
index 0000000..53d9077
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/IPathChangedListener.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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
new file mode 100644
index 0000000..3819997
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.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
new file mode 100644
index 0000000..83527f3
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.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
new file mode 100644
index 0000000..60c471e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.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
new file mode 100644
index 0000000..619e3cc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/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.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
new file mode 100644
index 0000000..a6db786
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidContentAssist.java
@@ -0,0 +1,791 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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();
+                    
+                    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();
+                }
+                
+                String nsUri = ((AttributeDescriptor)choice).getNamespaceUri();
+                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
new file mode 100644
index 0000000..c7541e9
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..ab17bef
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..bb0996b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..2c24772
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..e0ec86b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..2729565
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..9ebf5f1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..f1d62a1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..7d296f7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..5550155
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ElementDescriptor.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.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;
+    }
+
+    /**
+     * 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
new file mode 100644
index 0000000..cab9883
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..903417b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..4c115e9
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..93969e9
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..336dfe2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..8fb1c7c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..77fc067
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..2015d71
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..ed9c897
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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/BasePullParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/BasePullParser.java
new file mode 100644
index 0000000..381539b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..eb7dee6
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/GraphicalLayoutEditor.java
@@ -0,0 +1,2402 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.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.ide.eclipse.editors.wizards.ConfigurationSelector.DensityVerifier;
+import com.android.ide.eclipse.editors.wizards.ConfigurationSelector.DimensionVerifier;
+import com.android.ide.eclipse.editors.wizards.ConfigurationSelector.LanguageRegionVerifier;
+import com.android.ide.eclipse.editors.wizards.ConfigurationSelector.MobileCodeVerifier;
+import com.android.layoutlib.api.ILayoutLog;
+import com.android.layoutlib.api.ILayoutResult;
+import com.android.layoutlib.api.IResourceValue;
+import com.android.layoutlib.api.IStyleResourceValue;
+import com.android.layoutlib.api.ILayoutResult.ILayoutViewInfo;
+import com.android.sdklib.IAndroidTarget;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.draw2d.geometry.Rectangle;
+import org.eclipse.gef.DefaultEditDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.EditPartViewer;
+import org.eclipse.gef.GraphicalViewer;
+import org.eclipse.gef.SelectionManager;
+import org.eclipse.gef.dnd.TemplateTransferDragSourceListener;
+import org.eclipse.gef.dnd.TemplateTransferDropTargetListener;
+import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
+import org.eclipse.gef.palette.PaletteRoot;
+import org.eclipse.gef.requests.CreationFactory;
+import org.eclipse.gef.ui.parts.GraphicalEditorWithPalette;
+import org.eclipse.gef.ui.parts.SelectionSynchronizer;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.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 GraphicalEditorWithPalette
+        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);
+            }
+
+            // 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;
+    }
+
+    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.
+     */
+    public void selectModel(UiElementNode uiNodeModel) {
+        GraphicalViewer viewer = getGraphicalViewer();
+        
+        // Give focus to the graphical viewer (in case the outline has it)
+        viewer.getControl().forceFocus();
+        
+        Object editPart = viewer.getEditPartRegistry().get(uiNodeModel);
+        
+        if (editPart instanceof EditPart) {
+            viewer.select((EditPart)editPart);
+        }
+    }
+
+
+    //--------------
+    // Local methods
+    //--------------
+
+    public LayoutEditor getLayoutEditor() {
+        return mLayoutEditor;
+    }
+
+    private MenuManager createContextMenu(GraphicalViewer viewer) {
+        MenuManager menuManager = new MenuManager();
+        menuManager.setRemoveAllWhenShown(true);
+        menuManager.addMenuListener(new ActionMenuListener(viewer));
+        
+        return menuManager;
+    }
+
+    private class ActionMenuListener implements IMenuListener {
+        private final GraphicalViewer mViewer;
+
+        public ActionMenuListener(GraphicalViewer viewer) {
+            mViewer = viewer;
+        }
+
+        /**
+         * The menu is about to be shown. The menu manager has already been
+         * requested to remove any existing menu item. This method gets the
+         * tree selection and if it is of the appropriate type it re-creates
+         * the necessary actions.
+         */
+       public void menuAboutToShow(IMenuManager manager) {
+           ArrayList<UiElementNode> selected = new ArrayList<UiElementNode>();
+
+           // filter selected items and only keep those we can handle
+           for (Object obj : mViewer.getSelectedEditParts()) {
+               if (obj instanceof UiElementEditPart) {
+                   UiElementEditPart part = (UiElementEditPart) obj;
+                   UiElementNode uiNode = part.getUiNode();
+                   if (uiNode != null) {
+                       selected.add(uiNode);
+                   }
+               }
+           }
+           
+           if (selected.size() > 0) {
+               doCreateMenuAction(manager, mViewer, selected);
+           }
+        }
+    }
+    
+    private void doCreateMenuAction(IMenuManager manager,
+            final GraphicalViewer viewer,
+            final ArrayList<UiElementNode> selected) {
+        if (selected != null) {
+            boolean hasXml = false;
+            for (UiElementNode uiNode : selected) {
+                if (uiNode.getXmlNode() != null) {
+                    hasXml = true;
+                    break;
+                }
+            }
+
+            if (hasXml) {
+                manager.add(new CopyCutAction(mLayoutEditor, getClipboard(),
+                        null, selected, true /* cut */));
+                manager.add(new CopyCutAction(mLayoutEditor, getClipboard(),
+                        null, selected, false /* cut */));
+
+                // Can't paste with more than one element selected (the selection is the target)
+                if (selected.size() <= 1) {
+                    // Paste is not valid if it would add a second element on a terminal element
+                    // which parent is a document -- an XML document can only have one child. This
+                    // means paste is valid if the current UI node can have children or if the
+                    // parent is not a document.
+                    UiElementNode ui_root = selected.get(0).getUiRoot();
+                    if (ui_root.getDescriptor().hasChildren() ||
+                            !(ui_root.getUiParent() instanceof UiDocumentNode)) {
+                        manager.add(new PasteAction(mLayoutEditor, getClipboard(),
+                                                    selected.get(0)));
+                    }
+                }
+                manager.add(new Separator());
+            }
+        }
+
+        // Append "add" and "remove" actions. They do the same thing as the add/remove
+        // buttons on the side.
+        IconFactory factory = IconFactory.getInstance();
+        
+        final UiEditorActions uiActions = mLayoutEditor.getUiEditorActions();
+
+        // "Add" makes sense only if there's 0 or 1 item selected since the
+        // one selected item becomes the target.
+        if (selected == null || selected.size() <= 1) {
+            manager.add(new Action("Add...", factory.getImageDescriptor("add")) { //$NON-NLS-2$
+                @Override
+                public void run() {
+                    UiElementNode node = selected != null && selected.size() > 0 ? selected.get(0)
+                                                                                 : null;
+                    uiActions.doAdd(node, viewer.getControl().getShell());
+                }
+            });
+        }
+
+        if (selected != null) {
+            manager.add(new Action("Remove", factory.getImageDescriptor("delete")) { //$NON-NLS-2$
+                @Override
+                public void run() {
+                    uiActions.doRemove(selected, viewer.getControl().getShell());
+                }
+            });
+
+            manager.add(new Separator());
+            
+            manager.add(new Action("Up", factory.getImageDescriptor("up")) { //$NON-NLS-2$
+                @Override
+                public void run() {
+                    uiActions.doUp(selected);
+                }
+            });
+            manager.add(new Action("Down", factory.getImageDescriptor("down")) { //$NON-NLS-2$
+                @Override
+                public void run() {
+                    uiActions.doDown(selected);
+                }
+            });
+        }
+        
+    } 
+
+    /**
+     * Sets the UI for the edition of a new file.
+     * @param configuration the configuration of the new file.
+     */
+    public void editNewFile(FolderConfiguration configuration) {
+        // update the configuration UI
+        setConfiguration(configuration);
+        
+        // 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);
+                    
+                    // change the string if it's a custom theme to make sure we can
+                    // differentiate them
+                    if (themeIndex >= mPlatformThemeCount) {
+                        theme = "*" + theme; //$NON-NLS-1$
+                    }
+
+                    // Render a single object as described by the ViewElementDescriptor.
+                    WidgetPullParser parser = new WidgetPullParser(descriptor);
+                    ILayoutResult result = bridge.bridge.computeLayout(parser,
+                            null /* projectKey */,
+                            300 /* width */, 300 /* height */, theme,
+                            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}.
+     */
+    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
+     */
+    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 a qualifier is not present in the {@link FolderConfiguration} object, the UI control
+     * is not modified. However if the value in the control is not the default value, a warning
+     * icon is showed.
+     */
+    void setConfiguration(FolderConfiguration config) {
+        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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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)");
+    }
+
+    UiDocumentNode getModel() {
+        return mLayoutEditor.getUiRootNode();
+    }
+    
+    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);
+            
+            // 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.
+     */
+    @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();
+                            ILayoutResult result = null;
+                            if (bridge.apiLevel >= 3) {
+                                // call the new api with proper theme differentiator and
+                                // density/dpi support.
+                                boolean isProjectTheme = themeIndex >= mPlatformThemeCount;
+
+                                // FIXME pass the density/dpi from somewhere (resource config or skin).
+                                result = bridge.bridge.computeLayout(parser,
+                                        iProject /* projectKey */,
+                                        rect.width, rect.height, 160, 160.f, 160.f, 
+                                        theme, isProjectTheme,
+                                        mConfiguredProjectRes, frameworkResources, mProjectCallback,
+                                        mLogger);
+                            } else if (bridge.apiLevel == 2) {
+                                // api with boolean for separation of project/framework theme
+                                boolean isProjectTheme = themeIndex >= mPlatformThemeCount;
+
+                                result = bridge.bridge.computeLayout(parser,
+                                        iProject /* projectKey */,
+                                        rect.width, rect.height, theme, 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 (themeIndex >= mPlatformThemeCount) {
+                                    theme = "*" + theme; //$NON-NLS-1$
+                                }
+        
+                                result = bridge.bridge.computeLayout(parser,
+                                        iProject /* projectKey */,
+                                        rect.width, rect.height, theme,
+                                        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.
+     */
+    void activated() {
+        if (mNeedsRecompute || mNeedsXmlReload) {
+            recomputeLayout();
+        }
+    }
+
+    /**
+     * Responds to a page change that made the Graphical editor page the deactivated page
+     */
+    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;
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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;
+    }
+}
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
new file mode 100644
index 0000000..d4ec5e1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..9f39495
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..c4a8f5c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.layout;
+
+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 com.android.ide.eclipse.editors.wizards.ConfigurationSelector;
+import com.android.ide.eclipse.editors.wizards.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/editors/layout/LayoutEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutEditor.java
new file mode 100644
index 0000000..dabe797
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.layout;
+
+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.EclipseUiHelper;
+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 GraphicalLayoutEditor 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
new file mode 100644
index 0000000..cf20288
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..1aa1f4c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..bb075c2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..94df28f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..81fd2ed
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/ProjectCallback.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.AndroidManifestHelper;
+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.IProject;
+
+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;
+    }
+    
+    /**
+     * {@inheritDoc}
+     * 
+     * Returns the namespace for the project. The namespace contains a standard part + the
+     * application package.
+     */
+    public String getNamespace() {
+        if (mNamespace == null) {
+            AndroidManifestHelper manifest = new AndroidManifestHelper(mProject);
+            String javaPackage = manifest.getPackageName();
+            
+            mNamespace = String.format(AndroidConstants.NS_CUSTOM_RESOURCES, javaPackage);
+        }
+
+        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
new file mode 100644
index 0000000..3e0f5d8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.editors.layout;
+
+import com.android.ide.eclipse.common.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 GraphicalLayoutEditor mEditor;
+    
+    private Action mAddAction;
+    private Action mDeleteAction;
+    private Action mUpAction;
+    private Action mDownAction;
+    
+    private UiOutlineActions mUiActions = new UiOutlineActions();
+
+    public UiContentOutlinePage(GraphicalLayoutEditor editor, final EditPartViewer viewer) {
+        super(viewer);
+        mEditor = editor;
+        IconFactory factory = IconFactory.getInstance();
+        
+        mAddAction = new Action("Add...") {
+            @Override
+            public void run() {
+                List<UiElementNode> nodes = getModelSelections();
+                UiElementNode node = nodes != null && nodes.size() > 0 ? nodes.get(0) : null;
+                
+                mUiActions.doAdd(node, viewer.getControl().getShell());
+            }
+        };
+        mAddAction.setToolTipText("Adds a new element.");
+        mAddAction.setImageDescriptor(factory.getImageDescriptor("add")); //$NON-NLS-1$
+
+        mDeleteAction = new Action("Remove...") {
+            @Override
+            public void run() {
+                List<UiElementNode> nodes = getModelSelections();
+                
+                mUiActions.doRemove(nodes, viewer.getControl().getShell());
+            }
+        };
+        mDeleteAction.setToolTipText("Removes an existing selected element.");
+        mDeleteAction.setImageDescriptor(factory.getImageDescriptor("delete")); //$NON-NLS-1$
+
+        mUpAction = new Action("Up") {
+            @Override
+            public void run() {
+                List<UiElementNode> nodes = getModelSelections();
+                
+                mUiActions.doUp(nodes);
+            }
+        };
+        mUpAction.setToolTipText("Moves the selected element up");
+        mUpAction.setImageDescriptor(factory.getImageDescriptor("up")); //$NON-NLS-1$
+
+        mDownAction = new Action("Down") {
+            @Override
+            public void run() {
+                List<UiElementNode> nodes = getModelSelections();
+                
+                mUiActions.doDown(nodes);
+            }
+        };
+        mDownAction.setToolTipText("Moves the selected element down");
+        mDownAction.setImageDescriptor(factory.getImageDescriptor("down")); //$NON-NLS-1$
+
+        // all actions disabled by default.
+        mAddAction.setEnabled(false);
+        mDeleteAction.setEnabled(false);
+        mUpAction.setEnabled(false);
+        mDownAction.setEnabled(false);
+
+        addSelectionChangedListener(new ISelectionChangedListener() {
+            public void selectionChanged(SelectionChangedEvent event) {
+                ISelection selection = event.getSelection();
+                
+                // the selection is never empty. The least it'll contain is the
+                // UiDocumentTreeEditPart object.
+                if (selection instanceof StructuredSelection) {
+                    StructuredSelection structSel = (StructuredSelection)selection;
+
+                    if (structSel.size() == 1 &&
+                            structSel.getFirstElement() instanceof UiDocumentTreeEditPart) {
+                        mDeleteAction.setEnabled(false);
+                        mUpAction.setEnabled(false);
+                        mDownAction.setEnabled(false);
+                    } else {
+                        mDeleteAction.setEnabled(true);
+                        mUpAction.setEnabled(true);
+                        mDownAction.setEnabled(true);
+                    }
+
+                    // the "add" button is always enabled, in order to be able to set the
+                    // initial root node
+                    mAddAction.setEnabled(true);
+                }
+            }
+        });
+    }
+    
+
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.part.IPage#createControl(org.eclipse.swt.widgets.Composite)
+     */
+    @Override
+    public void createControl(Composite parent) {
+        // create outline viewer page
+        getViewer().createControl(parent);
+
+        // configure outline viewer
+        getViewer().setEditPartFactory(new UiElementTreeEditPartFactory());
+
+        setupOutline();
+        setupContextMenu();
+        setupTooltip();
+        setupDoubleClick();
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.eclipse.ui.part.Page#setActionBars(org.eclipse.ui.IActionBars)
+     * 
+     * Called automatically after createControl
+     */
+    @Override
+    public void setActionBars(IActionBars actionBars) {
+        IToolBarManager toolBarManager = actionBars.getToolBarManager();
+        toolBarManager.add(mAddAction);
+        toolBarManager.add(mDeleteAction);
+        toolBarManager.add(new Separator());
+        toolBarManager.add(mUpAction);
+        toolBarManager.add(mDownAction);
+        
+        IMenuManager menuManager = actionBars.getMenuManager();
+        menuManager.add(mAddAction);
+        menuManager.add(mDeleteAction);
+        menuManager.add(new Separator());
+        menuManager.add(mUpAction);
+        menuManager.add(mDownAction);
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.part.IPage#dispose()
+     */
+    @Override
+    public void dispose() {
+        breakConnectionWithEditor();
+
+        // dispose
+        super.dispose();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.ui.part.IPage#getControl()
+     */
+    @Override
+    public Control getControl() {
+        return getViewer().getControl();
+    }
+    
+    void setNewEditor(GraphicalLayoutEditor editor) {
+        mEditor = editor;
+        setupOutline();
+    }
+    
+    void breakConnectionWithEditor() {
+        // unhook outline viewer
+        mEditor.getSelectionSynchronizer().removeViewer(getViewer());
+    }
+    
+    private void setupOutline() {
+        getViewer().setEditDomain(mEditor.getEditDomain());
+
+        // hook outline viewer
+        mEditor.getSelectionSynchronizer().addViewer(getViewer());
+
+        // initialize outline viewer with model
+        getViewer().setContents(mEditor.getModel());
+    }
+
+    private void setupContextMenu() {
+        MenuManager menuManager = new MenuManager();
+        menuManager.setRemoveAllWhenShown(true);
+        menuManager.addMenuListener(new IMenuListener() {
+            /**
+             * The menu is about to be shown. The menu manager has already been
+             * requested to remove any existing menu item. This method gets the
+             * tree selection and if it is of the appropriate type it re-creates
+             * the necessary actions.
+             */
+           public void menuAboutToShow(IMenuManager manager) {
+               List<UiElementNode> selected = getModelSelections();
+               
+               if (selected != null) {
+                   doCreateMenuAction(manager, selected);
+                   return;
+               }
+               doCreateMenuAction(manager, null /* ui_node */);
+            } 
+        });
+        Control control = getControl();
+        Menu contextMenu = menuManager.createContextMenu(control);
+        control.setMenu(contextMenu);
+    }
+
+    /**
+     * Adds the menu actions to the context menu when the given UI node is selected in
+     * the tree view.
+     * 
+     * @param manager The context menu manager
+     * @param selected The UI node selected in the tree. Can be null, in which case the root
+     *                is to be modified.
+     */
+    private void doCreateMenuAction(IMenuManager manager, List<UiElementNode> selected) {
+        
+        if (selected != null) {
+            boolean hasXml = false;
+            for (UiElementNode uiNode : selected) {
+                if (uiNode.getXmlNode() != null) {
+                    hasXml = true;
+                    break;
+                }
+            }
+
+            if (hasXml) {
+                manager.add(new CopyCutAction(mEditor.getLayoutEditor(), mEditor.getClipboard(),
+                        null, selected, true /* cut */));
+                manager.add(new CopyCutAction(mEditor.getLayoutEditor(), mEditor.getClipboard(),
+                        null, selected, false /* cut */));
+
+                // Can't paste with more than one element selected (the selection is the target)
+                if (selected.size() <= 1) {
+                    // Paste is not valid if it would add a second element on a terminal element
+                    // which parent is a document -- an XML document can only have one child. This
+                    // means paste is valid if the current UI node can have children or if the parent
+                    // is not a document.
+                    UiElementNode ui_root = selected.get(0).getUiRoot();
+                    if (ui_root.getDescriptor().hasChildren() ||
+                            !(ui_root.getUiParent() instanceof UiDocumentNode)) {
+                        manager.add(new PasteAction(mEditor.getLayoutEditor(),
+                                mEditor.getClipboard(),
+                                selected.get(0)));
+                    }
+                }
+                manager.add(new Separator());
+            }
+        }
+
+        // Append "add" and "remove" actions. They do the same thing as the add/remove
+        // buttons on the side.
+        //
+        // "Add" makes sense only if there's 0 or 1 item selected since the
+        // one selected item becomes the target.
+        if (selected == null || selected.size() <= 1) {
+            manager.add(mAddAction);
+        }
+
+        if (selected != null) {
+            manager.add(mDeleteAction);
+            manager.add(new Separator());
+            
+            manager.add(mUpAction);
+            manager.add(mDownAction);
+        }
+
+        if (selected != null && selected.size() == 1) {
+            manager.add(new Separator());
+            
+            Action propertiesAction = new Action("Properties") {
+                @Override
+                public void run() {
+                    EclipseUiHelper.showView(EclipseUiHelper.PROPERTY_SHEET_VIEW_ID,
+                            true /* activate */);
+                }
+            };
+            propertiesAction.setToolTipText("Displays properties of the selected element.");
+            manager.add(propertiesAction);
+        }
+    }
+
+    /**
+     * Updates the outline view with the model of the {@link 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
new file mode 100644
index 0000000..b0e6fdb
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..8093c90
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..e62ab69
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..d5ee2ca
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..7caa50f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/descriptors/LayoutDescriptors.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.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 mDescriptor =
+        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 mDescriptor;
+    }
+    
+    /** @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 mDescriptor.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);
+            }
+        }
+
+        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);
+        ElementDescriptor[] newArray = newDescriptors.toArray(
+                new ElementDescriptor[newDescriptors.size()]);
+
+        // Link all layouts to everything else here.. recursively
+        for (ElementDescriptor layoutDesc : newLayouts) {
+            layoutDesc.setChildren(newArray);
+        }
+
+        mViewDescriptors = newViews;
+        mLayoutDescriptors  = newLayouts;
+        mDescriptor.setChildren(newArray);
+        
+        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();
+        
+        // Process all View 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 */);
+            }
+        }
+        
+        // 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_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 */);
+    }
+
+}
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
new file mode 100644
index 0000000..d718ebd
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..6e79d64
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/DropFeedback.java
@@ -0,0 +1,761 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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;
+        
+        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
new file mode 100644
index 0000000..d36d9f7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..f863037
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..55ed39b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..2f7636d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..af22afb
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..a2e05c7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..fd788dd
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..de6c404
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..18dcd9c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..43a70a5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..4359e23
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..05329f3
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..62b5e8a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..1bf5d5a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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_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
new file mode 100644
index 0000000..b40e458
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..d0f8d7b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/ManifestEditor.java
@@ -0,0 +1,387 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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
new file mode 100644
index 0000000..911faa1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..e33e1ef
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..77c08b5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java
@@ -0,0 +1,562 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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$
+
+        // -- 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) {
+                if (AndroidConstants.CLASS_ACTIVITY.equals(className)) {
+                    return new ClassAttributeDescriptor(
+                            className,
+                            PostActivityCreationAction.getAction(),
+                            xmlName, uiName + "*", //$NON-NLS-1$
+                            nsUri,
+                            tooltip,
+                            true /*mandatory */);
+                } else if (AndroidConstants.CLASS_BROADCASTRECEIVER.equals(className)) {
+                    return new ClassAttributeDescriptor(
+                            className,
+                            PostReceiverCreationAction.getAction(),
+                            xmlName, uiName + "*", //$NON-NLS-1$
+                            nsUri,
+                            tooltip,
+                            true /*mandatory */);
+                    
+                } else {
+                    return new ClassAttributeDescriptor(
+                            className,
+                            xmlName, uiName + "*", //$NON-NLS-1$
+                            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
new file mode 100644
index 0000000..eab7f09
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ApplicationAttributeDescriptor.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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);
+    }
+}
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
new file mode 100644
index 0000000..629b37c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ClassAttributeDescriptor.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.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;
+    
+    /**
+     * 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;
+    }
+
+    /**
+     * 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.
+     */
+    public ClassAttributeDescriptor(String superClassName,
+            IPostTypeCreationAction postCreationAction,
+            String xmlLocalName, String uiName, String nsUri,
+            String tooltip, boolean mandatory) {
+        super(xmlLocalName, uiName, nsUri, tooltip);
+        mSuperClassName = superClassName;
+        mPostCreationAction = postCreationAction;
+    }
+
+    /**
+     * @return A new {@link UiClassAttributeNode} linked to this descriptor.
+     */
+    @Override
+    public UiAttributeNode createUiNode(UiElementNode uiParent) {
+        return new UiClassAttributeNode(mSuperClassName, mPostCreationAction,
+                mMandatory, this, uiParent);
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/InstrumentationAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/InstrumentationAttributeDescriptor.java
new file mode 100644
index 0000000..6e589f7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/InstrumentationAttributeDescriptor.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.editors.manifest.descriptors;
+
+import com.android.ide.eclipse.common.AndroidConstants;
+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 a 'Instrumentation' class XML attribute. It is displayed by a
+ * {@link UiClassAttributeNode}, that restricts creation and selection to classes inheriting from
+ * android.app.Instrumentation.
+ */
+public class InstrumentationAttributeDescriptor extends TextAttributeDescriptor {
+
+    public InstrumentationAttributeDescriptor(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(AndroidConstants.CLASS_INSTRUMENTATION,
+                null /* postCreationAction */, true /* mandatory */, this, uiParent);
+    }
+}
+
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
new file mode 100644
index 0000000..d89292b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..34c5d0d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..3442c24
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..5a8137d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..4219007
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..f8aac1d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/model/UiClassAttributeNode.java
@@ -0,0 +1,624 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.common.AndroidConstants;
+import com.android.ide.eclipse.common.project.AndroidManifestHelper;
+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.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.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 class HierarchyTypeSelection extends TypeSelectionExtension {
+        
+        private IJavaProject mJavaProject;
+
+        public HierarchyTypeSelection(IProject project, String referenceClass) {
+            mJavaProject = JavaCore.create(project);
+            mReferenceClass = referenceClass;
+        }
+
+        @Override
+        public ITypeInfoFilterExtension getFilterExtension() {
+            return new ITypeInfoFilterExtension() {
+                public boolean select(ITypeInfoRequestor typeInfoRequestor) {
+                    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) {
+                            // 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 return false;
+                            IType superType = type;
+                            while ((superType = hierarchy.getSuperclass(superType)) != null) {
+                                if (mReferenceClass.equals(superType.getFullyQualifiedName())) {
+                                    return true;
+                                }
+                            }
+                        }
+                    } catch (JavaModelException e) {
+                    }
+                    
+                    return false;
+                }
+            };
+        }
+    }
+
+    /**
+     * 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.
+     */
+    public UiClassAttributeNode(String referenceClass, IPostTypeCreationAction postCreationAction,
+            boolean mandatory, AttributeDescriptor attributeDescriptor, UiElementNode uiParent) {
+        super(attributeDescriptor, uiParent);
+        
+        mReferenceClass = referenceClass;
+        mPostCreationAction = postCreationAction;
+        mMandatory = mandatory;
+    }
+
+    /* (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 = AndroidManifestHelper.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.
+            IJavaSearchScope scope = SearchEngine.createJavaSearchScope(
+                    getPackageFragmentRoots(project), 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) {
+            }
+        }
+    }
+
+    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) {
+            } catch (PartInitException e) {
+            }
+        }
+    }
+    
+    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
+     * @return an array of IPackageFragmentRoot.
+     */
+    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()]);
+    }
+    
+    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());
+
+        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() {
+        // 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
new file mode 100644
index 0000000..fb8f211
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..02fb44f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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() {
+        // 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
new file mode 100644
index 0000000..01b0f8f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..77527f0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..139575d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..86d0dd1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..66af84c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..026b760
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/pages/OverviewInfoPart.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.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.UiAttributeNode;
+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;
+import org.w3c.dom.Node;
+
+/**
+ * Generic info section part for overview page
+ */
+final class OverviewInfoPart extends UiElementPart {
+
+    private IManagedForm mManagedForm;
+
+    public OverviewInfoPart(Composite body, FormToolkit toolkit, ManifestEditor editor) {
+        super(body, toolkit, editor,
+                null,  // uiElementNode
+                "General Information", // 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();
+    }
+
+    /**
+     * Retrieves the uses-sdk UI node. Since this is a mandatory node, it *always*
+     * exists, even if there is no matching XML node.
+     */
+    private UiElementNode getUsesSdkUiNode(ManifestEditor editor) {
+        AndroidManifestDescriptors manifestDescriptors = editor.getManifestDescriptors();
+        if (manifestDescriptors != null) {
+            ElementDescriptor desc = manifestDescriptors.getUsesSdkElement();
+            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() {
+        createUiAttributes(mManagedForm);
+    }
+    
+    /**
+     * Overridden to add the description and the ui attributes of both the
+     * manifest and uses-sdk UI nodes.
+     * <p/>
+     * {@inheritDoc}
+     */
+    @Override
+    protected void fillTable(Composite table, IManagedForm managedForm) {
+        int n = 0;
+
+        UiElementNode uiNode = getManifestUiNode(getEditor());
+        n += insertUiAttributes(uiNode, table, managedForm);
+
+        uiNode = getUsesSdkUiNode(getEditor());
+        n += insertUiAttributes(uiNode, table, managedForm);
+
+        if (n == 0) {
+            createLabel(table, managedForm.getToolkit(),
+                    "No attributes to display, waiting for SDK to finish loading...",
+                    null /* tooltip */ );
+        }
+        
+        layoutChanged();
+    }
+
+    /**
+     * Overridden to tests whether either the manifest or uses-sdk nodes parts are dirty.
+     * <p/>
+     * {@inheritDoc}
+     * 
+     * @return <code>true</code> if the part is dirty, <code>false</code>
+     *         otherwise.
+     */
+    @Override
+    public boolean isDirty() {
+        boolean dirty = super.isDirty();
+        
+        if (!dirty) {
+            UiElementNode uiNode = getManifestUiNode(getEditor());
+            if (uiNode != null) {
+                for (UiAttributeNode ui_attr : uiNode.getUiAttributes()) {
+                    if (ui_attr.isDirty()) {
+                        markDirty();
+                        dirty = true;
+                        break;
+                    }
+                }
+            }
+        }
+
+        if (!dirty) {
+            UiElementNode uiNode = getUsesSdkUiNode(getEditor());
+            if (uiNode != null) {
+                for (UiAttributeNode ui_attr : uiNode.getUiAttributes()) {
+                    if (ui_attr.isDirty()) {
+                        markDirty();
+                        dirty = true;
+                        break;
+                    }
+                }
+            }
+        }
+
+        return dirty;
+    }
+    
+    /**
+     * Overridden to save both the manifest or uses-sdk nodes.
+     * <p/>
+     * {@inheritDoc}
+     */
+    @Override
+    public void commit(boolean onSave) {
+        final UiElementNode manifestUiNode = getManifestUiNode(getEditor());
+        final UiElementNode usesSdkUiNode = getUsesSdkUiNode(getEditor());
+
+        getEditor().editXmlModel(new Runnable() {
+            public void run() {
+                if (manifestUiNode != null && manifestUiNode.isDirty()) {
+                    for (UiAttributeNode ui_attr : manifestUiNode.getUiAttributes()) {
+                        ui_attr.commit();
+                    }
+                }
+
+                if (usesSdkUiNode != null && usesSdkUiNode.isDirty()) {
+                    for (UiAttributeNode ui_attr : usesSdkUiNode.getUiAttributes()) {
+                        ui_attr.commit();
+                    }
+
+                    if (!usesSdkUiNode.isDirty()) {
+                        // Remove the <uses-sdk> XML element if it is empty.
+                        // Rather than rely on the internal UI state, actually check that the
+                        // XML element has no attributes and no child element so that we don't
+                        // trash some user-generated content.
+                        Node element = usesSdkUiNode.prepareCommit();
+                        if (element != null &&
+                                !element.hasAttributes() &&
+                                !element.hasChildNodes()) {
+                            // Important note: we MUST NOT use usesSdkUiNode.deleteXmlNode()
+                            // here, as it would clear the UiAttribute list and thus break the
+                            // link between the controls and the ui attribute field.
+                            // Instead what we want is simply to remove the XML node and let the
+                            // UiElementNode node know.
+                            Node parent = element.getParentNode();
+                            if (parent != null) {
+                                parent.removeChild(element);
+                                usesSdkUiNode.loadFromXmlNode(null /*xml_node*/);
+                            }
+                        }
+                    }
+                }
+            }
+        });
+
+        // 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/manifest/pages/OverviewLinksPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/pages/OverviewLinksPart.java
new file mode 100644
index 0000000..d637a8f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..62954bd
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/pages/OverviewPage.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.manifest.ManifestEditor;
+
+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.ColumnLayout;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+
+
+/**
+ * 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;
+    
+    public OverviewPage(ManifestEditor editor) {
+        super(editor, PAGE_ID, "Overview");  // 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 Overview");
+        form.setImage(AdtPlugin.getAndroidLogo());
+        
+        Composite body = form.getBody();
+        FormToolkit toolkit = managedForm.getToolkit();
+        ColumnLayout cl = new ColumnLayout();
+        cl.minNumColumns = cl.maxNumColumns = 1;
+        body.setLayout(cl);
+        mOverviewPart = new OverviewInfoPart(body, toolkit, mEditor);
+        managedForm.addPart(mOverviewPart);
+        managedForm.addPart(new OverviewExportPart(this, body, toolkit, mEditor));
+        mOverviewLinkPart = new OverviewLinksPart(body, toolkit, mEditor);
+        managedForm.addPart(mOverviewLinkPart);
+    }
+
+    /**
+     * 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();
+        }
+    }
+}
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
new file mode 100644
index 0000000..41ba22e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..bf76d53
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..cff1746
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..a5e3b09
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..edbfa5e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..40a8f16
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..c9c8e17
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..46a9112
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..1804312
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..5c1b0e1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..9a61d17
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..3c3e11f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..ad232ed
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..99c3a43
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..1a2cf53
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..7e30901
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..c47bb83
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..dc4d5fa
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..0257afa
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..a2cc789
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..e30930f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..de40138
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..2390e2c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..92288ba
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..bf83d52
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..1075897
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..d1d8891
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/explorer/ResourceExplorerView.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.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 com.android.ide.eclipse.editors.wizards.ResourceContentProvider;
+import com.android.ide.eclipse.editors.wizards.ResourceLabelProvider;
+
+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
new file mode 100644
index 0000000..455c825
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/CompiledResourcesMonitor.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.editors.resources.manager;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.common.AndroidConstants;
+import com.android.ide.eclipse.common.project.AndroidManifestHelper;
+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 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);
+        
+                // 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;
+    }
+    
+    private String getRClassName(IProject project) {
+        // create the classname
+        AndroidManifestHelper manifest = new AndroidManifestHelper(project);
+        String javaPackage = manifest.getPackageName();
+        
+        return javaPackage + ".R"; //$NON-NLS-1$
+    }
+    
+}
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
new file mode 100644
index 0000000..57c17fc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..a9f80bd
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..552aec9
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..25eb112
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..3812791
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..8b6c3c1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..ba770b2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectResourceItem.java
@@ -0,0 +1,91 @@
+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
new file mode 100644
index 0000000..40e4e3b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..dd8d080
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..f927a9a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..98f5b39
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..5fc7393
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..6099008
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..59a72fb
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..32b1107
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..d99cb13
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..9ad7460
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..7e807f9
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..b35283d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..daf243d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..f0f5f2d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..b1fa3ef
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/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.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
new file mode 100644
index 0000000..29453e9
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..89649f5
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..5fb479f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..d095376
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/ErrorImageComposite.java
@@ -0,0 +1,47 @@
+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
new file mode 100644
index 0000000..ccae099
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..304dd14
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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();
+            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
new file mode 100644
index 0000000..4fc0ab3
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..409e92f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..2fe5783
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..66773bd
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..2aad217
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..8b6aa0e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..0729881
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/NewItemSelectionDialog.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.layout.descriptors.ViewElementDescriptor;
+import com.android.ide.eclipse.editors.uimodel.UiElementNode;
+
+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.dialogs.AbstractElementListSelectionDialog;
+import org.eclipse.ui.dialogs.ISelectionStatusValidator;
+
+import java.util.Arrays;
+
+/**
+ * A selection dialog to select the type of the new element node to
+ * created, 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. */
+    private ElementDescriptor[] mDescriptorFilters;
+
+    /**
+     * 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
+     * @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
+                }
+            }
+        });
+    }
+
+    /**
+     * @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()));
+    }
+
+    /**
+     * 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);
+        setSelection(getInitialElementSelections().toArray());
+        return contents;
+    }
+    
+    /**
+     * 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;
+
+        if (ui_node == mLocalRootNode && 
+                mDescriptorFilters != null &&
+                mDescriptorFilters.length != 0) {
+            setListElements(mDescriptorFilters);
+        } else {
+            setListElements(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
new file mode 100644
index 0000000..8bb4ad2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..21180b1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..15c67c3
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..9f34d9e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/UiModelTreeContentProvider.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 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;
+
+    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
new file mode 100644
index 0000000..273a30b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..fc384e8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/UiTreeBlock.java
@@ -0,0 +1,882 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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;
+    }
+
+    @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;
+
+        // 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
new file mode 100644
index 0000000..7fe44da
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..12cb31b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..4a9fbb1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..5972f22
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiAttributeNode.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.
+     * 
+     * @return A list of possible completion values or null.
+     */
+    public abstract String[] getPossibleValues();
+
+    /**
+     * 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
new file mode 100644
index 0000000..113738f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..3728886
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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(); 
+                    if (SdkConstants.NS_RESOURCES.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.
+        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) {
+            final UiAttributeNode fAttribute = attribute;
+
+            // get the current value and compare it to the new value
+            String oldValue = fAttribute.getCurrentValue();
+            final String newValue = (String)value;
+            
+            if (oldValue.equals(newValue)) {
+                return;
+            }
+            
+            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
new file mode 100644
index 0000000..ddcf0a0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiFlagAttributeNode.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.
+     */
+    @Override
+    public String[] getPossibleValues() {
+        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();
+            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
new file mode 100644
index 0000000..c5c10aa
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiListAttributeNode.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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();
+
+        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.
+     */
+    @Override
+    public String[] getPossibleValues() {
+        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 prefix = "";
+        if (SdkConstants.NS_RESOURCES.equals(descriptor.getNamespaceUri())) {
+            prefix = "android:"; //$NON-NLS-1$
+        } else if (XmlnsAttributeDescriptor.XMLNS_URI.equals(descriptor.getNamespaceUri())) {
+            prefix = "xmlns:"; //$NON-NLS-1$
+        }
+        attr_name = prefix + 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
new file mode 100644
index 0000000..1c1e1bd
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiResourceAttributeNode.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.common.resources.IResourceRepository;
+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 com.android.ide.eclipse.editors.wizards.ReferenceChooserDialog;
+import com.android.ide.eclipse.editors.wizards.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;
+
+/**
+ * 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(mType,
+                        projectRepository, systemRepository, shell);
+
+                dlg.setCurrentResource(currentValue);
+
+                if (dlg.open() == Window.OK) {
+                    return dlg.getCurrentResource();
+                }
+            } else {
+                ReferenceChooserDialog dlg = new ReferenceChooserDialog(projectRepository,
+                        shell);
+
+                dlg.setCurrentResource(currentValue);
+
+                if (dlg.open() == Window.OK) {
+                    return dlg.getCurrentResource();
+                }
+            }
+        }
+
+        return null;
+    }
+    
+    @Override
+    public String[] getPossibleValues() {
+        // TODO: compute a list of existing resources for content assist completion
+        return null;
+    }
+}
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
new file mode 100644
index 0000000..192f752
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiSeparatorAttributeNode.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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. */
+    @Override
+    public String[] getPossibleValues() {
+        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
new file mode 100644
index 0000000..4c53f4c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiTextAttributeNode.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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. */
+    @Override
+    public String[] getPossibleValues() {
+        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
new file mode 100644
index 0000000..5c1db05
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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/wizards/ConfigurationSelector.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ConfigurationSelector.java
new file mode 100644
index 0000000..4a05b1e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/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.editors.wizards;
+
+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/editors/wizards/NewXmlFileCreationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java
new file mode 100644
index 0000000..5781938
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java
@@ -0,0 +1,1159 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.wizards;
+
+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.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.ide.eclipse.editors.wizards.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.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("Gadget Provider",                             // UI name
+                "An XML file that describes a gadget provider.",    // tooltip
+                ResourceFolderType.XML,                             // folder type
+                AndroidTargetData.DESCRIPTOR_GADGET_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_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 String sResFolderAbs = AndroidConstants.WS_RESOURCES + AndroidConstants.WS_SEP;
+    /** Relative destination folder root, e.g. "res/" */
+    private static String sResFolderRel = 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;
+
+
+    // --- 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();
+        validatePage();
+    }
+
+    /**
+     * 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 = Sdk.getCurrent().getTarget(mProject);
+                AndroidTargetData data = Sdk.getCurrent().getTargetData(target);
+                
+                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.
+     */
+    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(sResFolderRel)) {
+            wsFolderPath = sResFolderAbs + wsFolderPath.substring(sResFolderRel.length());
+            
+            mInternalWsFolderPathUpdate = true;
+            mWsFolderPathTextField.setText(wsFolderPath);
+            mInternalWsFolderPathUpdate = false;
+        }
+
+        if (wsFolderPath.startsWith(sResFolderAbs)) {
+            wsFolderPath = wsFolderPath.substring(sResFolderAbs.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 = sResFolderAbs + 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(sResFolderAbs)) {
+                wsFolderPath.replaceFirst(
+                        "^(" + sResFolderAbs +")[^-]*(.*)",         //$NON-NLS-1$ //$NON-NLS-2$
+                        "\\1" + type.getResFolderName() + "\\2");   //$NON-NLS-1$ //$NON-NLS-2$
+            } else {
+                newPath = sResFolderAbs + 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(sResFolderAbs);
+                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;
+            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. gadget, 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(sResFolderAbs)) {
+                error = String.format("Target folder must start with %1$s.", sResFolderAbs);
+            }
+        }
+
+        // -- 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/editors/wizards/NewXmlFileWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileWizard.java
new file mode 100644
index 0000000..125102b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/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.editors.wizards;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.editors.IconFactory;
+import com.android.ide.eclipse.editors.wizards.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/editors/wizards/ReferenceChooserDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ReferenceChooserDialog.java
new file mode 100644
index 0000000..6913ce0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ReferenceChooserDialog.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.editors.wizards;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+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.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.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+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.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;
+
+    /**
+     * @param parent
+     */
+    public ReferenceChooserDialog(IResourceRepository resources, Shell parent) {
+        super(parent);
+
+        int shellStyle = getShellStyle();
+        setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
+
+        setTitle("Reference Dialog");
+        setMessage(String.format("Choose a resource"));
+        mResources = resources;
+        
+        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();
+        
+        return top;
+    }
+
+    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());
+        
+        TreeViewer treeViewer = mFilteredTree.getViewer();
+        Tree tree = treeViewer.getTree();
+        
+        tree.addSelectionListener(new SelectionListener() {
+            public void widgetDefaultSelected(SelectionEvent e) {
+                handleDoubleClick();
+            }
+
+            public void widgetSelected(SelectionEvent e) {
+                handleSelection();
+            }
+        });
+        
+        treeViewer.setLabelProvider(new ResourceLabelProvider());
+        treeViewer.setContentProvider(new ResourceContentProvider(false /* fullLevels */));
+        treeViewer.setInput(mResources);
+    }
+
+    protected void handleSelection() {
+        validateCurrentSelection();
+    }
+
+    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();
+    }
+    
+    /**
+     * 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));
+                
+                // 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));
+        mFilteredTree.getViewer().setExpandedState(resourceType, true /* expanded */);
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ResourceChooser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ResourceChooser.java
new file mode 100644
index 0000000..60a627b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ResourceChooser.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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.wizards;
+
+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.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+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;
+
+    // TODO: enable when we can display the system resources.
+    // private Pattern mSystemResourcePattern;
+    // private IResourceRepository mSystemResources;
+    // private Button mProjectButton;
+    // private Button mSystemButton;
+    
+    private String mCurrentResource;
+    
+    /**
+     * Creates a Resource Chooser dialog.
+     * @param type The type of the resource to choose
+     * @param project The repository for the project
+     * @param system The System resource repository
+     * @param parent the parent shell
+     */
+    public ResourceChooser(ResourceType type, IResourceRepository project,
+            IResourceRepository system, Shell parent) {
+        super(parent, new ResourceLabelProvider());
+
+        mResourceType = type;
+        mProjectResources = project;
+        // TODO: enable when we can display the system resources.
+        // mSystemResources = system;
+        
+        mProjectResourcePattern = Pattern.compile(
+                "@" + mResourceType.getName() + "/(.+)"); //$NON-NLS-1$ //$NON-NLS-2$
+        // TODO: enable when we can display the system resources.
+        // 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,
+                    // TODO: enable when we can display the system resources.
+                    false /*mSystemButton.getSelection()*/); 
+        }
+    }
+
+    @Override
+    protected Control createDialogArea(Composite parent) {
+        Composite top = (Composite)super.createDialogArea(parent);
+
+        createMessageArea(top);
+
+        // TODO: enable when we can display the system resources.
+        // createButtons(top);
+        
+        createFilterText(top);
+        createFilteredList(top);
+        
+        setupResourceListAndCurrent();
+        
+        return top;
+    }
+
+    /**
+     * Creates the radio button to switch between project and system resources.
+     * @param top the parent composite
+     */
+    /* TODO: enable when we can display the system resources.
+    private void createButtons(Composite top) {
+        mProjectButton = new Button(top, SWT.RADIO);
+        mProjectButton.setText("Project Resources");
+        mProjectButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                super.widgetSelected(e);
+                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);
+                setListElements(mSystemResources.getResources(mResourceType));
+            }
+        });
+    }
+    */
+    
+    /**
+     * Setups the current list based on the current resource.
+     */
+    private void setupResourceListAndCurrent() {
+        if (setupInitialSelection(mProjectResourcePattern, mProjectResources) == false) {
+            // if we couldn't understand the current value, we default to the project resources
+            ResourceItem[] items = mProjectResources.getResources(mResourceType); 
+            setListElements(items);
+        }
+        /*
+         * TODO: enable when we can display the system resources.
+        if (setupInitialSelection(mProjectResourcePattern, mProjectResources) == false) {
+            if (setupInitialSelection(mSystemResourcePattern, mSystemResources) == false) {
+                // if we couldn't understand the current value, we default to the project resources
+                IResourceItem[] items = mProjectResources.getResources(mResourceType); 
+                setListElements(items);
+                mProjectButton.setSelection(true);
+            } else {
+                mSystemButton.setSelection(true);
+            }
+        } else {
+            mProjectButton.setSelection(true);
+        }*/
+    }
+    
+    /**
+     * Attempts to setup the list of element from a repository if the current resource
+     * matches the provided pattern. 
+     * @param pattern the pattern to test the current value
+     * @param repository the repository to use if the pattern matches.
+     * @return true if success.
+     */
+    private boolean setupInitialSelection(Pattern pattern, IResourceRepository repository) {
+        Matcher m = pattern.matcher(mCurrentResource);
+        if (m.matches()) {
+            // we have a project resource, let's setup the list
+            ResourceItem[] items = repository.getResources(mResourceType); 
+            setListElements(items);
+            
+            // and let's look for the item we found
+            String name = m.group(1);
+
+            for (ResourceItem item : items) {
+                if (name.equals(item.getName())) {
+                    setSelection(new Object[] { item });
+                    break;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ResourceContentProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ResourceContentProvider.java
new file mode 100644
index 0000000..7c6a539
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/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.editors.wizards;
+
+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/editors/wizards/ResourceLabelProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ResourceLabelProvider.java
new file mode 100644
index 0000000..024d084
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/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.editors.wizards;
+
+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/editors/xml/XmlContentAssist.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/XmlContentAssist.java
new file mode 100644
index 0000000..f28b523
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..d7f6119
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..d25c812
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..91ce6dd
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..7929b5a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/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.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 gadget provider. */
+    private DocumentDescriptor mGadgetDescriptor = 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 gadget providers. */
+    public DocumentDescriptor getGadgetDescriptor() {
+        return mGadgetDescriptor;
+    }
+    
+    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 getGadgetProvider() {
+        return new IDescriptorProvider() {
+            public ElementDescriptor getDescriptor() {
+                return mGadgetDescriptor;
+            }
+
+            public ElementDescriptor[] getRootElementDescriptors() {
+                return mGadgetDescriptor.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 gadgetStyleMap The map style=>attributes for <gadget-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> gadgetStyleMap,
+            ViewClassInfo[] prefs, ViewClassInfo[] prefGroups) {
+
+        XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(
+                "android", //$NON-NLS-1$
+                SdkConstants.NS_RESOURCES); 
+
+        ElementDescriptor searchable = createSearchable(searchableStyleMap, xmlns);
+        ElementDescriptor gadget = createGadgetProviderInfo(gadgetStyleMap, 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 (gadget != null) {
+            list.add(gadget);
+            mGadgetDescriptor.setChildren(new ElementDescriptor[]{ gadget });
+        }
+        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 <gadget-provider>
+     */
+    private ElementDescriptor createGadgetProviderInfo(
+            Map<String, DeclareStyleableInfo> gadgetStyleMap,
+            XmlnsAttributeDescriptor xmlns) {
+
+        if (gadgetStyleMap == null) {
+            return null;
+        }
+        
+        ElementDescriptor gadget = createElement(gadgetStyleMap,
+                "GadgetProviderInfo", //$NON-NLS-1$ styleName
+                "gadget-provider", //$NON-NLS-1$ xmlName
+                "Gadget Provider", // uiName
+                null, // sdk url
+                xmlns, // extraAttribute
+                null, // childrenElements
+                false /* mandatory */ );
+        return gadget;
+    }
+
+    /**
+     * 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
new file mode 100644
index 0000000..b43e75f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="PACKAGE"
+      android:versionCode="1"
+      android:versionName="1.0">
+    <application android:icon="@drawable/icon" android:label="APPLICATION_NAME">
+ACTIVITIES
+    </application>
+USES-SDK
+</manifest> 
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/activity.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/activity.template
new file mode 100644
index 0000000..e91d602
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/activity.template
@@ -0,0 +1,7 @@
+        <activity android:name=".ACTIVITY_NAME"
+                  android:label="APPLICATION_NAME">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+INTENT_FILTERS
+            </intent-filter>
+        </activity>
\ No newline at end of file
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/icon.png b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/icon.png
new file mode 100644
index 0000000..7502484
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/icon.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/java_file.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/java_file.template
new file mode 100644
index 0000000..173ff96
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/java_file.template
@@ -0,0 +1,13 @@
+package PACKAGE;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class ACTIVITY_NAME extends Activity {
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/launcher_intent_filter.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/launcher_intent_filter.template
new file mode 100644
index 0000000..f5681be
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/launcher_intent_filter.template
@@ -0,0 +1 @@
+                <category android:name="android.intent.category.LAUNCHER" />
\ No newline at end of file
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/layout.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/layout.template
new file mode 100644
index 0000000..5f4c383
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/layout.template
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    >
+<TextView  
+    android:layout_width="fill_parent" 
+    android:layout_height="wrap_content" 
+    android:text="@string/hello"
+    />
+</LinearLayout>
+
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/preference_intent_filter.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/preference_intent_filter.template
new file mode 100644
index 0000000..609bb2c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/preference_intent_filter.template
@@ -0,0 +1 @@
+                <category android:name="android.intent.category.PREFERENCE" />
\ No newline at end of file
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/string.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/string.template
new file mode 100644
index 0000000..3a6e4b2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/string.template
@@ -0,0 +1 @@
+    <string name="STRING_NAME">STRING_CONTENT</string>
\ No newline at end of file
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/strings.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/strings.template
new file mode 100644
index 0000000..b980ace
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/strings.template
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+STRINGS
+</resources>
+
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/uses-sdk.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/uses-sdk.template
new file mode 100644
index 0000000..8adae71
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/uses-sdk.template
@@ -0,0 +1 @@
+    <uses-sdk android:minSdkVersion="MIN_SDK_VERSION" />
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/.classpath b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/.classpath
new file mode 100644
index 0000000..280621c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="lib" path="libs/jfreechart-1.0.9.jar"/>
+	<classpathentry kind="lib" path="libs/jcommon-1.0.12.jar"/>
+	<classpathentry kind="lib" path="libs/jfreechart-1.0.9-swt.jar"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/.project b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/.project
new file mode 100644
index 0000000..2e9f996
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>ddms-plugin</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/META-INF/MANIFEST.MF b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..09b8085
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/META-INF/MANIFEST.MF
@@ -0,0 +1,23 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Dalvik Debug Monitor Service
+Bundle-SymbolicName: com.android.ide.eclipse.ddms;singleton:=true
+Bundle-Version: 0.9.0.qualifier
+Bundle-Activator: com.android.ide.eclipse.ddms.DdmsPlugin
+Bundle-Vendor: The Android Open Source Project
+Bundle-Localization: plugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.ui.console
+Eclipse-LazyStart: true
+Export-Package: com.android.ddmlib,
+ com.android.ddmlib.log,
+ com.android.ddmlib.testrunner,
+ com.android.ddmuilib,
+ com.android.ddmuilib.console,
+ com.android.ide.eclipse.ddms,
+ com.android.ide.eclipse.ddms.views
+Bundle-ClassPath: libs/jcommon-1.0.12.jar,
+ libs/jfreechart-1.0.9.jar,
+ libs/jfreechart-1.0.9-swt.jar,
+ .
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/MODULE_LICENSE_APACHE2 b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/MODULE_LICENSE_APACHE2
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/build.properties b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/build.properties
new file mode 100644
index 0000000..1c4c896
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/build.properties
@@ -0,0 +1,10 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               icons/,\
+               plugin.xml,\
+               ., \
+               libs/jcommon-1.0.12.jar,\
+               libs/jfreechart-1.0.9-swt.jar,\
+               libs/jfreechart-1.0.9.jar
+
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/android.png b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/android.png
new file mode 100644
index 0000000..3779d4d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/android.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/capture.png b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/capture.png
new file mode 100644
index 0000000..d75e7a9
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/icons/capture.png
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/plugin.xml b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/plugin.xml
new file mode 100644
index 0000000..27fadf2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/plugin.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.views">
+      <category
+            name="Android"
+            id="com.android.ide.eclipse.ddms.views.category">
+      </category>
+      <view
+            allowMultiple="false"
+            category="com.android.ide.eclipse.ddms.views.category"
+            class="com.android.ide.eclipse.ddms.views.DeviceView"
+            icon="icons/device.png"
+            id="com.android.ide.eclipse.ddms.views.DeviceView"
+            name="Devices">
+      </view>
+      <view
+            allowMultiple="false"
+            category="com.android.ide.eclipse.ddms.views.category"
+            class="com.android.ide.eclipse.ddms.views.LogCatView"
+            icon="icons/android.png"
+            id="com.android.ide.eclipse.ddms.views.LogCatView"
+            name="LogCat"/>
+      <!-- Disabled for now due to AWT/SWT bridge issue on Leopard.
+      <view
+            allowMultiple="false"
+            category="com.android.ide.eclipse.ddms.views.category"
+            class="com.android.ide.eclipse.ddms.views.EventLogView"
+            icon="icons/android.png"
+            id="com.android.ide.eclipse.ddms.views.EventLogView"
+            name="Event Log"/> -->
+      <view
+            allowMultiple="false"
+            category="com.android.ide.eclipse.ddms.views.category"
+            class="com.android.ide.eclipse.ddms.views.ThreadView"
+            icon="icons/thread.png"
+            id="com.android.ide.eclipse.ddms.views.ThreadView"
+            name="Threads"/>
+      <view
+            allowMultiple="false"
+            category="com.android.ide.eclipse.ddms.views.category"
+            class="com.android.ide.eclipse.ddms.views.HeapView"
+            icon="icons/heap.png"
+            id="com.android.ide.eclipse.ddms.views.HeapView"
+            name="Heap"/>
+      <view
+            allowMultiple="false"
+            category="com.android.ide.eclipse.ddms.views.category"
+            class="com.android.ide.eclipse.ddms.views.FileExplorerView"
+            icon="icons/android.png"
+            id="com.android.ide.eclipse.ddms.views.FileExplorerView"
+            name="File Explorer"/>
+      <view
+            allowMultiple="false"
+            category="com.android.ide.eclipse.ddms.views.category"
+            class="com.android.ide.eclipse.ddms.views.EmulatorControlView"
+            icon="icons/emulator.png"
+            id="com.android.ide.eclipse.ddms.views.EmulatorControlView"
+            name="Emulator Control"/>
+   </extension>
+   <extension
+         point="org.eclipse.ui.perspectives">
+      <perspective
+            class="com.android.ide.eclipse.ddms.Perspective"
+            icon="icons/android.png"
+            id="com.android.ide.eclipse.ddms.Perspective"
+            name="DDMS"/>
+   </extension>
+   <extension
+         point="org.eclipse.core.runtime.preferences">
+      <initializer class="com.android.ide.eclipse.ddms.preferences.PreferenceInitializer"/>
+   </extension>
+   <extension
+         point="org.eclipse.ui.perspectiveExtensions">
+      <perspectiveExtension targetID="org.eclipse.jdt.ui.JavaPerspective">
+         <perspectiveShortcut id="com.android.ide.eclipse.ddms.Perspective"/>
+      </perspectiveExtension>
+      <perspectiveExtension targetID="org.eclipse.ui.resourcePerspective">
+         <perspectiveShortcut id="com.android.ide.eclipse.ddms.Perspective"/>
+      </perspectiveExtension>
+      <perspectiveExtension targetID="org.eclipse.debug.ui.DebugPerspective">
+         <perspectiveShortcut id="com.android.ide.eclipse.ddms.Perspective"/>
+         <view id="com.android.ide.eclipse.ddms.views.LogCatView"
+	         relative="org.eclipse.ui.views.ProblemView"
+	         relationship="stack" />
+      </perspectiveExtension>
+   </extension>
+   <extension
+         point="org.eclipse.ui.preferencePages">
+      <page
+            category="com.android.ide.eclipse.preferences.main"
+            class="com.android.ide.eclipse.ddms.preferences.PreferencePage"
+            id="com.android.ide.eclipse.ddms.preferences.PreferencePage"
+            name="DDMS"/>
+      <page
+            category="com.android.ide.eclipse.preferences.main"
+            class="com.android.ide.eclipse.ddms.preferences.LogCatPreferencePage"
+            id="com.android.ide.eclipse.ddms.preferences.LogCatPreferencePage"
+            name="LogCat"/>
+   </extension>
+</plugin>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/CommonAction.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/CommonAction.java
new file mode 100644
index 0000000..30ca4cb
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/CommonAction.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ide.eclipse.ddms;
+
+import com.android.ddmuilib.actions.ICommonAction;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.resource.ImageDescriptor;
+
+/**
+ * Basic action extending the jFace Action class in order to implement
+ * ICommonAction.
+ */
+public class CommonAction extends Action implements ICommonAction {
+    
+    private Runnable mRunnable;
+
+    public CommonAction() {
+        super();
+    }
+
+    public CommonAction(String text) {
+        super(text);
+    }
+
+    /**
+     * @param text
+     * @param image
+     */
+    public CommonAction(String text, ImageDescriptor image) {
+        super(text, image);
+    }
+
+    /**
+     * @param text
+     * @param style
+     */
+    public CommonAction(String text, int style) {
+        super(text, style);
+    }
+    
+    @Override
+    public void run() {
+        if (mRunnable != null) {
+            mRunnable.run();
+        }
+    }
+    
+    /**
+     * Sets the {@link Runnable}.
+     * @see ICommonAction#setRunnable(Runnable)
+     */
+    public void setRunnable(Runnable runnable) {
+        mRunnable = runnable;
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/DdmsPlugin.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/DdmsPlugin.java
new file mode 100644
index 0000000..ccadce6
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/DdmsPlugin.java
@@ -0,0 +1,565 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms;
+
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.Client;
+import com.android.ddmlib.DdmPreferences;
+import com.android.ddmlib.Device;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
+import com.android.ddmlib.Log.ILogOutput;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmuilib.DdmUiPreferences;
+import com.android.ddmuilib.DevicePanel.IUiSelectionListener;
+import com.android.ide.eclipse.ddms.preferences.PreferenceInitializer;
+import com.android.ide.eclipse.ddms.views.DeviceView;
+
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
+import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.MessageConsole;
+import org.eclipse.ui.console.MessageConsoleStream;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public final class DdmsPlugin extends AbstractUIPlugin implements IDeviceChangeListener,
+        IUiSelectionListener {
+
+    // The plug-in ID
+    public static final String PLUGIN_ID = "com.android.ide.eclipse.ddms"; // $NON-NLS-1$
+
+    private static final String ADB_LOCATION = PLUGIN_ID + ".adb"; // $NON-NLS-1$
+
+    /** The singleton instance */
+    private static DdmsPlugin sPlugin;
+
+    /** Location of the adb command line executable */
+    private static String sAdbLocation;
+
+    /**
+     * Debug Launcher for already running apps
+     */
+    private static IDebugLauncher sRunningAppDebugLauncher;
+
+    /** Console for DDMS log message */
+    private MessageConsole mDdmsConsole;
+
+    /** Image loader object */
+    private ImageLoader mLoader;
+    
+    private Device mCurrentDevice;
+    private Client mCurrentClient;
+    private boolean mListeningToUiSelection = false;
+    
+    private final ArrayList<ISelectionListener> mListeners = new ArrayList<ISelectionListener>();
+
+    private Color mRed;
+
+    private boolean mDdmlibInitialized;
+
+    /**
+     * Interface to provide debugger launcher for running apps.
+     */
+    public interface IDebugLauncher {
+        public boolean debug(String packageName, int port);
+    }
+    
+    /**
+     * Classes which implement this interface provide methods that deals
+     * with {@link Device} 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.
+         * @param selectedDevice the selected device. If null, no devices are selected.
+         */
+        public void selectionChanged(Device selectedDevice);
+    }
+
+    /**
+     * The constructor
+     */
+    public DdmsPlugin() {
+        sPlugin = this;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+     */
+    @Override
+    public void start(BundleContext context) throws Exception {
+        super.start(context);
+        
+        final Display display = getDisplay();
+
+        // get the eclipse store
+        final IPreferenceStore eclipseStore = getPreferenceStore();
+
+        AndroidDebugBridge.addDeviceChangeListener(this);
+        
+        DdmUiPreferences.setStore(eclipseStore);
+
+        //DdmUiPreferences.displayCharts();
+
+        // set the consoles.
+        mDdmsConsole = new MessageConsole("DDMS", null); // $NON-NLS-1$
+        ConsolePlugin.getDefault().getConsoleManager().addConsoles(
+                new IConsole[] {
+                    mDdmsConsole
+                });
+
+        final MessageConsoleStream consoleStream = mDdmsConsole.newMessageStream();
+        final MessageConsoleStream errorConsoleStream = mDdmsConsole.newMessageStream();
+        mRed = new Color(display, 0xFF, 0x00, 0x00);
+
+        // because this can be run, in some cases, by a non UI thread, and because
+        // changing the console properties update the UI, we need to make this change
+        // in the UI thread.
+        display.asyncExec(new Runnable() {
+            public void run() {
+                errorConsoleStream.setColor(mRed);
+            }
+        });
+
+        // set up the ddms log to use the ddms console.
+        Log.setLogOutput(new ILogOutput() {
+            public void printLog(LogLevel logLevel, String tag, String message) {
+                if (logLevel.getPriority() >= LogLevel.ERROR.getPriority()) {
+                    printToStream(errorConsoleStream, tag, message);
+                    ConsolePlugin.getDefault().getConsoleManager().showConsoleView(mDdmsConsole);
+                } else {
+                    printToStream(consoleStream, tag, message);
+                }
+            }
+
+            public void printAndPromptLog(final LogLevel logLevel, final String tag,
+                    final String message) {
+                printLog(logLevel, tag, message);
+                // dialog box only run in UI thread..
+                display.asyncExec(new Runnable() {
+                    public void run() {
+                        Shell shell = display.getActiveShell();
+                        if (logLevel == LogLevel.ERROR) {
+                            MessageDialog.openError(shell, tag, message);
+                        } else {
+                            MessageDialog.openWarning(shell, tag, message);
+                        }
+                    }
+                });
+            }
+            
+        });
+
+        // create the loader that's able to load the images
+        mLoader = new ImageLoader(this);
+        
+        // set the listener for the preference change
+        Preferences prefs = getPluginPreferences();
+        prefs.addPropertyChangeListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                // get the name of the property that changed.
+                String property = event.getProperty();
+
+                if (PreferenceInitializer.ATTR_DEBUG_PORT_BASE.equals(property)) {
+                    DdmPreferences.setDebugPortBase(
+                            eclipseStore.getInt(PreferenceInitializer.ATTR_DEBUG_PORT_BASE));
+                } else if (PreferenceInitializer.ATTR_SELECTED_DEBUG_PORT.equals(property)) {
+                    DdmPreferences.setSelectedDebugPort(
+                            eclipseStore.getInt(PreferenceInitializer.ATTR_SELECTED_DEBUG_PORT));
+                } else if (PreferenceInitializer.ATTR_THREAD_INTERVAL.equals(property)) {
+                    DdmUiPreferences.setThreadRefreshInterval(
+                            eclipseStore.getInt(PreferenceInitializer.ATTR_THREAD_INTERVAL));
+                } else if (PreferenceInitializer.ATTR_LOG_LEVEL.equals(property)) {
+                    DdmPreferences.setLogLevel(
+                            eclipseStore.getString(PreferenceInitializer.ATTR_LOG_LEVEL));
+                }
+            }
+        });
+        
+        // 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);
+
+        // start it in a thread to return from start() asap.
+        new Thread() {
+            @Override
+            public void run() {
+                // init ddmlib if needed
+                getDefault().initDdmlib();
+
+                // create and start the first bridge
+                AndroidDebugBridge.createBridge(sAdbLocation, true /* forceNewBridge */);
+            }
+        }.start();
+    }
+
+    public static Display getDisplay() {
+        IWorkbench bench = sPlugin.getWorkbench();
+        if (bench != null) {
+            return bench.getDisplay();
+        }
+        return null;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+     */
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        AndroidDebugBridge.removeDeviceChangeListener(this);
+        
+        AndroidDebugBridge.terminate();
+        
+        mRed.dispose();
+
+        sPlugin = null;
+        super.stop(context);
+    }
+
+    /**
+     * Returns the shared instance
+     *
+     * @return the shared instance
+     */
+    public static DdmsPlugin getDefault() {
+        return sPlugin;
+    }
+
+    /** Return the image loader for the plugin */
+    public static ImageLoader getImageLoader() {
+        if (sPlugin != null) {
+            return sPlugin.mLoader;
+        }
+        return null;
+    }
+
+    public static String getAdb() {
+        return sAdbLocation;
+    }
+
+    /**
+     * Set the location of the adb executable and optionally starts adb
+     * @param adb location of adb
+     * @param startAdb flag to start adb
+     */
+    public static void setAdb(String adb, boolean startAdb) {
+        sAdbLocation = adb;
+
+        // store the location for future ddms only start.
+        sPlugin.getPreferenceStore().setValue(ADB_LOCATION, sAdbLocation);
+
+        // starts the server in a thread in case this is blocking.
+        if (startAdb) {
+            new Thread() {
+                @Override
+                public void run() {
+                    // init ddmlib if needed
+                    getDefault().initDdmlib();
+
+                    // create and start the bridge
+                    AndroidDebugBridge.createBridge(sAdbLocation, false /* forceNewBridge */);
+                }
+            }.start();
+        }
+    }
+    
+    private synchronized void initDdmlib() {
+        if (mDdmlibInitialized == false) {
+            // set the preferences.
+            PreferenceInitializer.setupPreferences();
+    
+            // init the lib
+            AndroidDebugBridge.init(true /* debugger support */);
+            
+            mDdmlibInitialized = true;
+        }
+    }
+
+    /**
+     * Sets the launcher responsible for connecting the debugger to running applications.
+     * @param launcher The launcher.
+     */
+    public static void setRunningAppDebugLauncher(IDebugLauncher launcher) {
+        sRunningAppDebugLauncher = launcher;
+
+        // if the process view is already running, give it the launcher.
+        // This method could be called from a non ui thread, so we make sure to do that
+        // in the ui thread.
+        Display display = getDisplay();
+        if (display != null && display.isDisposed() == false) {
+            display.asyncExec(new Runnable() {
+                public void run() {
+                    DeviceView dv = DeviceView.getInstance();
+                    if (dv != null) {
+                        dv.setDebugLauncher(sRunningAppDebugLauncher);
+                    }
+                }
+            });
+        }
+    }
+
+    public static IDebugLauncher getRunningAppDebugLauncher() {
+        return sRunningAppDebugLauncher;
+    }
+    
+    public synchronized void addSelectionListener(ISelectionListener listener) {
+        mListeners.add(listener);
+        
+        // notify the new listener of the current selection
+       listener.selectionChanged(mCurrentDevice);
+       listener.selectionChanged(mCurrentClient);
+    }
+
+    public synchronized void removeSelectionListener(ISelectionListener listener) {
+        mListeners.remove(listener);
+    }
+
+    public synchronized void setListeningState(boolean state) {
+        mListeningToUiSelection = state;
+    }
+
+    /**
+     * Sent when the a device is connected to the {@link AndroidDebugBridge}.
+     * <p/>
+     * This is sent from a non UI thread.
+     * @param device the new device.
+     * 
+     * @see IDeviceChangeListener#deviceConnected(Device)
+     */
+    public void deviceConnected(Device device) {
+        // if we are listening to selection coming from the ui, then we do nothing, as
+        // any change in the devices/clients, will be handled by the UI, and we'll receive
+        // selection notification through our implementation of IUiSelectionListener.
+        if (mListeningToUiSelection == false) {
+            if (mCurrentDevice == null) {
+                handleDefaultSelection(device);
+            }
+        }
+    }
+
+    /**
+     * Sent when the a device is disconnected to the {@link AndroidDebugBridge}.
+     * <p/>
+     * This is sent from a non UI thread.
+     * @param device the new device.
+     * 
+     * @see IDeviceChangeListener#deviceDisconnected(Device)
+     */
+    public void deviceDisconnected(Device device) {
+        // if we are listening to selection coming from the ui, then we do nothing, as
+        // any change in the devices/clients, will be handled by the UI, and we'll receive
+        // selection notification through our implementation of IUiSelectionListener.
+        if (mListeningToUiSelection == false) {
+            // test if the disconnected device was the default selection.
+            if (mCurrentDevice == device) {
+                // try to find a new device
+                AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
+                if (bridge != null) {
+                    // get the device list
+                    Device[] devices = bridge.getDevices();
+                    
+                    // check if we still have devices
+                    if (devices.length == 0) {
+                        handleDefaultSelection((Device)null);
+                    } else {
+                        handleDefaultSelection(devices[0]);
+                    }
+                } else {
+                    handleDefaultSelection((Device)null);
+                }
+            }
+        }
+    }
+
+    /**
+     * Sent when a device data changed, or when clients are started/terminated on the device.
+     * <p/>
+     * This is sent from a non UI thread.
+     * @param device the device that was updated.
+     * @param changeMask the mask indicating what changed.
+     * 
+     * @see IDeviceChangeListener#deviceChanged(Device)
+     */
+    public void deviceChanged(Device device, int changeMask) {
+        // if we are listening to selection coming from the ui, then we do nothing, as
+        // any change in the devices/clients, will be handled by the UI, and we'll receive
+        // selection notification through our implementation of IUiSelectionListener.
+        if (mListeningToUiSelection == false) {
+            
+            // check if this is our device
+            if (device == mCurrentDevice) {
+                if (mCurrentClient == null) {
+                    handleDefaultSelection(device);
+                } else {
+                    // get the clients and make sure ours is still in there.
+                    Client[] clients = device.getClients();
+                    boolean foundClient = false;
+                    for (Client client : clients) {
+                        if (client == mCurrentClient) {
+                            foundClient = true;
+                            break;
+                        }
+                    }
+                    
+                    // if we haven't found our client, lets look for a new one
+                    if (foundClient == false) {
+                        mCurrentClient = null;
+                        handleDefaultSelection(device);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Sent when a new {@link Device} 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) {
+        if (mCurrentDevice != selectedDevice) {
+            mCurrentDevice = selectedDevice;
+
+            // notify of the new default device
+            for (ISelectionListener listener : mListeners) {
+                listener.selectionChanged(mCurrentDevice);
+            }
+        }
+
+        if (mCurrentClient != selectedClient) {
+            mCurrentClient = selectedClient;
+            
+            // notify of the new default client
+            for (ISelectionListener listener : mListeners) {
+                listener.selectionChanged(mCurrentClient);
+            }
+        }
+    }
+
+    /**
+     * Handles a default selection of a {@link Device} and {@link Client}.
+     * @param device the selected device
+     */
+    private void handleDefaultSelection(final Device device) {
+        // because the listener expect to receive this from the UI thread, and this is called
+        // from the AndroidDebugBridge notifications, we need to run this in the UI thread.
+        try {
+            Display display = getDisplay();
+            
+            display.asyncExec(new Runnable() {
+                public void run() {
+                    // set the new device if different.
+                    boolean newDevice = false;
+                    if (mCurrentDevice != device) {
+                        mCurrentDevice = device;
+                        newDevice = true;
+                
+                        // notify of the new default device
+                        for (ISelectionListener listener : mListeners) {
+                            listener.selectionChanged(mCurrentDevice);
+                        }
+                    }
+                    
+                    if (device != null) {
+                        // if this is a device switch or the same device but we didn't find a valid
+                        // client the last time, we go look for a client to use again.
+                        if (newDevice || mCurrentClient == null) {
+                            // now get the new client
+                            Client[] clients =  device.getClients();
+                            if (clients.length > 0) {
+                                handleDefaultSelection(clients[0]);
+                            } else {
+                                handleDefaultSelection((Client)null);
+                            }
+                        }
+                    } else {
+                        handleDefaultSelection((Client)null);
+                    }
+                }
+            });
+        } catch (SWTException e) {
+            // display is disposed. Do nothing since we're quitting anyway.
+        }
+    }
+    
+    private void handleDefaultSelection(Client client) {
+        mCurrentClient = client;
+        
+        // notify of the new default client
+        for (ISelectionListener listener : mListeners) {
+            listener.selectionChanged(mCurrentClient);
+        }
+    }
+    
+    /**
+     * Prints a message, associated with a project to the specified stream
+     * @param stream The stream to write to
+     * @param tag The tag associated to the message. Can be null
+     * @param message The message to print.
+     */
+    private static synchronized void printToStream(MessageConsoleStream stream, String tag,
+            String message) {
+        String dateTag = getMessageTag(tag);
+
+        stream.print(dateTag);
+        stream.println(message);
+    }
+    
+    /**
+     * Creates a string containing the current date/time, and the tag
+     * @param tag The tag associated to the message. Can be null
+     * @return The dateTag
+     */
+    private static String getMessageTag(String tag) {
+        Calendar c = Calendar.getInstance();
+
+        if (tag == null) {
+            return String.format("[%1$tF %1$tT]", c);
+        }
+
+        return String.format("[%1$tF %1$tT - %2$s]", c, tag);
+    }
+
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/ImageLoader.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/ImageLoader.java
new file mode 100644
index 0000000..a70405d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/ImageLoader.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ide.eclipse.ddms;
+
+import com.android.ddmuilib.IImageLoader;
+
+import org.eclipse.core.runtime.Plugin;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * Implementation of the IImageLoader interface for the eclipse plugin.
+ */
+public class ImageLoader implements IImageLoader  {
+
+    private URL mBaseUrl;
+
+    public ImageLoader(Plugin plugin) {
+        mBaseUrl = plugin.getBundle().getEntry("/"); // $NON-NLS-1$
+    }
+
+    /**
+     * default method. only need a filename. the 2 interface methods call this one.
+     * @param filename the filename of the image to load. The filename is searched for under /icons.
+     * @return
+     */
+    public ImageDescriptor loadDescriptor(String filename) {
+        try {
+            URL newUrl = new URL(mBaseUrl, "/icons/" + filename); // $NON-NLS-1$
+            return ImageDescriptor.createFromURL(newUrl);
+        } catch (MalformedURLException e) {
+            // we'll just return null;
+        }
+        return null;
+    }
+
+    public ImageDescriptor loadDescriptor(String filename, Display display) {
+        return loadDescriptor(filename);
+    }
+
+
+    public Image loadImage(String filename, Display display) {
+        ImageDescriptor descriptor = loadDescriptor(filename);
+        if (descriptor !=null) {
+            return descriptor.createImage();
+        }
+        return null;
+    }
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/Perspective.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/Perspective.java
new file mode 100644
index 0000000..4c01e9b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/Perspective.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ide.eclipse.ddms;
+
+import com.android.ide.eclipse.ddms.views.DeviceView;
+import com.android.ide.eclipse.ddms.views.EmulatorControlView;
+import com.android.ide.eclipse.ddms.views.FileExplorerView;
+import com.android.ide.eclipse.ddms.views.HeapView;
+import com.android.ide.eclipse.ddms.views.LogCatView;
+import com.android.ide.eclipse.ddms.views.ThreadView;
+
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+public class Perspective implements IPerspectiveFactory {
+
+    public void createInitialLayout(IPageLayout layout) {
+        // create a default layout that looks like the stand alone DDMS.
+
+        // no editor window
+        layout.setEditorAreaVisible(false);
+
+        String editorArea = layout.getEditorArea();
+        IFolderLayout folder;
+
+        folder = layout.createFolder("logcat", IPageLayout.BOTTOM, 0.8f, //$NON-NLS-1$
+                editorArea);
+        folder.addPlaceholder(LogCatView.ID + ":*"); //$NON-NLS-1$
+        folder.addView(LogCatView.ID);
+
+        folder = layout.createFolder("devices", IPageLayout.LEFT, 0.3f, //$NON-NLS-1$
+                editorArea);
+        folder.addPlaceholder(DeviceView.ID + ":*"); //$NON-NLS-1$
+        folder.addView(DeviceView.ID);
+
+        folder = layout.createFolder("emulator", IPageLayout.BOTTOM, 0.5f, //$NON-NLS-1$
+                "devices");
+        folder.addPlaceholder(EmulatorControlView.ID + ":*"); //$NON-NLS-1$
+        folder.addView(EmulatorControlView.ID);
+
+        folder = layout.createFolder("ddms-detail", IPageLayout.RIGHT, 0.5f, //$NON-NLS-1$
+                editorArea);
+        folder.addPlaceholder(ThreadView.ID + ":*"); //$NON-NLS-1$
+        folder.addView(ThreadView.ID);
+        folder.addView(HeapView.ID);
+        folder.addView(FileExplorerView.ID);
+
+        layout.addPerspectiveShortcut("org.eclipse.ui.resourcePerspective"); //$NON-NLS-1$
+        layout.addPerspectiveShortcut("org.eclipse.debug.ui.DebugPerspective"); //$NON-NLS-1$
+        layout.addPerspectiveShortcut("org.eclipse.jdt.ui.JavaPerspective"); //$NON-NLS-1$
+
+        layout.addShowViewShortcut(DeviceView.ID);
+        layout.addShowViewShortcut(FileExplorerView.ID);
+        layout.addShowViewShortcut(HeapView.ID);
+        layout.addShowViewShortcut(LogCatView.ID);
+        layout.addShowViewShortcut(ThreadView.ID);
+
+        layout.addShowViewShortcut(IPageLayout.ID_RES_NAV);
+        layout.addShowViewShortcut(IPageLayout.ID_BOOKMARKS);
+        layout.addShowViewShortcut(IPageLayout.ID_OUTLINE);
+        layout.addShowViewShortcut(IPageLayout.ID_PROP_SHEET);
+        layout.addShowViewShortcut(IPageLayout.ID_PROBLEM_VIEW);
+        layout.addShowViewShortcut(IPageLayout.ID_PROGRESS_VIEW);
+        layout.addShowViewShortcut(IPageLayout.ID_TASK_LIST);
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/LogCatPreferencePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/LogCatPreferencePage.java
new file mode 100644
index 0000000..909207d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/LogCatPreferencePage.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.preferences;
+
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.ide.eclipse.ddms.views.LogCatView;
+
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.core.runtime.Preferences.IPropertyChangeListener;
+import org.eclipse.core.runtime.Preferences.PropertyChangeEvent;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.jface.preference.FontFieldEditor;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+/**
+ * Preference Pane for LogCat.
+ */
+public class LogCatPreferencePage extends FieldEditorPreferencePage implements
+        IWorkbenchPreferencePage {
+
+    public LogCatPreferencePage() {
+        super(GRID);
+        setPreferenceStore(DdmsPlugin.getDefault().getPreferenceStore());
+    }
+
+    @Override
+    protected void createFieldEditors() {
+        FontFieldEditor ffe = new FontFieldEditor(PreferenceInitializer.ATTR_LOGCAT_FONT,
+                "Display Font:", getFieldEditorParent());
+        addField(ffe);
+
+        Preferences prefs = DdmsPlugin.getDefault().getPluginPreferences();
+        prefs.addPropertyChangeListener(new IPropertyChangeListener() {
+            public void propertyChange(PropertyChangeEvent event) {
+                // get the name of the property that changed.
+                String property = event.getProperty();
+
+                if (PreferenceInitializer.ATTR_LOGCAT_FONT.equals(property)) {
+                    try {
+                        FontData fdat = new FontData((String)event.getNewValue());
+                        LogCatView.setFont(new Font(getFieldEditorParent().getDisplay(), fdat));
+                    } catch (IllegalArgumentException e) {
+                        // Looks like the data from the store is not valid.
+                        // We do nothing (default font will be used).
+                    } catch (SWTError e2) {
+                        // Looks like the Font() constructor failed.
+                        // We do nothing in this case, the logcat view will use the default font.
+                    }
+                }
+            }
+        });
+    }
+
+    public void init(IWorkbench workbench) {
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferenceInitializer.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferenceInitializer.java
new file mode 100644
index 0000000..b53d85c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferenceInitializer.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.preferences;
+
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.ddmlib.DdmPreferences;
+import com.android.ddmuilib.DdmUiPreferences;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.FontData;
+
+/**
+ * Class used to initialize default preference values.
+ */
+public class PreferenceInitializer extends AbstractPreferenceInitializer {
+    
+    public final static String ATTR_LOG_LEVEL =
+        DdmsPlugin.PLUGIN_ID + ".logLevel"; //$NON-NLS-1$
+
+    public final static String ATTR_DEBUG_PORT_BASE =
+        DdmsPlugin.PLUGIN_ID + ".adbDebugBasePort"; //$NON-NLS-1$
+
+    public final static String ATTR_SELECTED_DEBUG_PORT =
+        DdmsPlugin.PLUGIN_ID + ".debugSelectedPort"; //$NON-NLS-1$
+
+    public final static String ATTR_DEFAULT_THREAD_UPDATE =
+        DdmsPlugin.PLUGIN_ID + ".defaultThreadUpdateEnabled"; //$NON-NLS-1$
+
+    public final static String ATTR_DEFAULT_HEAP_UPDATE =
+        DdmsPlugin.PLUGIN_ID + ".defaultHeapUpdateEnabled"; //$NON-NLS-1$
+
+    public final static String ATTR_THREAD_INTERVAL =
+        DdmsPlugin.PLUGIN_ID + ".threadStatusInterval"; //$NON-NLS-1$
+
+    public final static String ATTR_IMAGE_SAVE_DIR =
+        DdmsPlugin.PLUGIN_ID + ".imageSaveDir"; //$NON-NLS-1$
+
+    public final static String ATTR_LAST_IMAGE_SAVE_DIR =
+        DdmsPlugin.PLUGIN_ID + ".lastImageSaveDir"; //$NON-NLS-1$
+
+    public final static String ATTR_LOGCAT_FONT =
+        DdmsPlugin.PLUGIN_ID + ".logcatFont"; //$NON-NLS-1$
+    
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer
+     * #initializeDefaultPreferences()
+     */
+    @Override
+    public void initializeDefaultPreferences() {
+        IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
+
+        store.setDefault(ATTR_DEBUG_PORT_BASE, DdmPreferences.DEFAULT_DEBUG_PORT_BASE);
+
+        store.setDefault(ATTR_SELECTED_DEBUG_PORT, DdmPreferences.DEFAULT_SELECTED_DEBUG_PORT);
+
+        store.setDefault(ATTR_DEFAULT_THREAD_UPDATE, DdmPreferences.DEFAULT_INITIAL_THREAD_UPDATE);
+        store.setDefault(ATTR_DEFAULT_HEAP_UPDATE,
+                DdmPreferences.DEFAULT_INITIAL_HEAP_UPDATE);
+
+        store.setDefault(ATTR_THREAD_INTERVAL, DdmUiPreferences.DEFAULT_THREAD_REFRESH_INTERVAL);
+
+        String homeDir = System.getProperty("user.home"); //$NON-NLS-1$
+        store.setDefault(ATTR_IMAGE_SAVE_DIR, homeDir);
+
+        store.setDefault(ATTR_LOG_LEVEL, DdmPreferences.DEFAULT_LOG_LEVEL.getStringValue());
+
+        store.setDefault(ATTR_LOGCAT_FONT,
+                new FontData("Courier", 10, SWT.NORMAL).toString()); //$NON-NLS-1$
+    }
+    
+    /**
+     * Initializes the preferences of ddmlib and ddmuilib with values from the eclipse store. 
+     */
+    public synchronized static void setupPreferences() {
+        IPreferenceStore store = DdmsPlugin.getDefault().getPreferenceStore();
+        
+        DdmPreferences.setDebugPortBase(store.getInt(ATTR_DEBUG_PORT_BASE));
+        DdmPreferences.setSelectedDebugPort(store.getInt(ATTR_SELECTED_DEBUG_PORT));
+        DdmPreferences.setLogLevel(store.getString(ATTR_LOG_LEVEL));
+        DdmPreferences.setInitialThreadUpdate(store.getBoolean(ATTR_DEFAULT_THREAD_UPDATE));
+        DdmPreferences.setInitialHeapUpdate(store.getBoolean(ATTR_DEFAULT_HEAP_UPDATE));
+        DdmUiPreferences.setThreadRefreshInterval(store.getInt(ATTR_THREAD_INTERVAL));
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferencePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferencePage.java
new file mode 100644
index 0000000..86e87c7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/preferences/PreferencePage.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.preferences;
+
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmuilib.PortFieldEditor;
+
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.jface.preference.IntegerFieldEditor;
+import org.eclipse.jface.preference.RadioGroupFieldEditor;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+public class PreferencePage extends FieldEditorPreferencePage implements
+        IWorkbenchPreferencePage {
+
+    public PreferencePage() {
+        super(GRID);
+        setPreferenceStore(DdmsPlugin.getDefault().getPreferenceStore());
+    }
+
+    /**
+     * Creates the field editors. Field editors are abstractions of the common
+     * GUI blocks needed to manipulate various types of preferences. Each field
+     * editor knows how to save and restore itself.
+     */
+    @Override
+    public void createFieldEditors() {
+        IntegerFieldEditor ife;
+
+        ife = new PortFieldEditor(PreferenceInitializer.ATTR_DEBUG_PORT_BASE,
+            "ADB debugger base port:", getFieldEditorParent());
+        addField(ife);
+
+        BooleanFieldEditor bfe;
+
+        bfe = new BooleanFieldEditor(PreferenceInitializer.ATTR_DEFAULT_THREAD_UPDATE,
+            "Thread updates enabled by default", getFieldEditorParent());
+        addField(bfe);
+
+        bfe = new BooleanFieldEditor(PreferenceInitializer.ATTR_DEFAULT_HEAP_UPDATE,
+            "Heap updates enabled by default", getFieldEditorParent());
+        addField(bfe);
+
+        ife = new IntegerFieldEditor(PreferenceInitializer.ATTR_THREAD_INTERVAL,
+            "Thread status refresh interval (seconds):", getFieldEditorParent());
+        ife.setValidRange(1, 60);
+        addField(ife);
+
+        RadioGroupFieldEditor rgfe = new RadioGroupFieldEditor(PreferenceInitializer.ATTR_LOG_LEVEL,
+                "Logging Level", 1, new String[][] {
+                    { "Verbose", LogLevel.VERBOSE.getStringValue() },
+                    { "Debug", LogLevel.DEBUG.getStringValue() },
+                    { "Info", LogLevel.INFO.getStringValue() },
+                    { "Warning", LogLevel.WARN.getStringValue() },
+                    { "Error", LogLevel.ERROR.getStringValue() },
+                    { "Assert", LogLevel.ASSERT.getStringValue() }
+                    },
+                getFieldEditorParent(), true);
+        addField(rgfe);
+
+    }
+
+    public void init(IWorkbench workbench) {
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java
new file mode 100644
index 0000000..62a528a
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/DeviceView.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmlib.Client;
+import com.android.ddmlib.ClientData;
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.Device;
+import com.android.ddmuilib.DevicePanel;
+import com.android.ddmuilib.ScreenShotDialog;
+import com.android.ddmuilib.DevicePanel.IUiSelectionListener;
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.ide.eclipse.ddms.DdmsPlugin.IDebugLauncher;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+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 =
+        "com.android.ide.eclipse.ddms.views.DeviceView"; //$NON-NLS-1$
+
+    private DevicePanel mDeviceList;
+    private Action mResetAdbAction;
+    private Action mCaptureAction;
+    private Action mUpdateThreadAction;
+    private Action mUpdateHeapAction;
+    private Action mGcAction;
+    private Action mKillAppAction;
+    private Action mDebugAction;
+    private IDebugLauncher mDebugLauncher;
+
+    private static DeviceView sThis;
+
+    public DeviceView() {
+        // the view is declared with allowMultiple="false" so we
+        // can safely do this.
+        sThis = this;
+    }
+
+    public static DeviceView getInstance() {
+        return sThis;
+    }
+    
+    /**
+     * Sets the {@link IDebugLauncher}.
+     * @param debugLauncher
+     */
+    public void setDebugLauncher(DdmsPlugin.IDebugLauncher debugLauncher) {
+        mDebugLauncher = debugLauncher;
+        if (mDebugAction != null && mDeviceList != null) {
+            Client currentClient = mDeviceList.getSelectedClient();
+            if (currentClient != null) {
+                mDebugAction.setEnabled(true);
+            }
+        }
+    }
+
+    @Override
+    public void createPartControl(Composite parent) {
+        mDeviceList = new DevicePanel(DdmsPlugin.getImageLoader(), USE_SELECTED_DEBUG_PORT);
+        mDeviceList.createPanel(parent);
+        mDeviceList.addSelectionListener(this);
+        
+        DdmsPlugin plugin = DdmsPlugin.getDefault();
+        mDeviceList.addSelectionListener(plugin);
+        plugin.setListeningState(true);
+
+        mCaptureAction = new Action("Screen Capture") {
+            @Override
+            public void run() {
+                ScreenShotDialog dlg = new ScreenShotDialog(
+                        DdmsPlugin.getDisplay().getActiveShell());
+                dlg.open(mDeviceList.getSelectedDevice());
+            }
+        };
+        mCaptureAction.setToolTipText("Screen Capture");
+        mCaptureAction.setImageDescriptor(
+                DdmsPlugin.getImageLoader().loadDescriptor("capture.png")); //$NON-NLS-1$
+
+        mResetAdbAction = new Action("Reset adb") {
+            @Override
+            public void run() {
+                AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
+                if (bridge != null) {
+                    if (bridge.restart() == false) {
+                        // get the current Display
+                        final Display display = DdmsPlugin.getDisplay();
+
+                        // dialog box only run in ui thread..
+                        display.asyncExec(new Runnable() {
+                            public void run() {
+                                Shell shell = display.getActiveShell();
+                                MessageDialog.openError(shell, "Adb Error",
+                                        "Adb failed to restart!\n\nMake sure the plugin is properly configured.");
+                            }
+                        });
+                    }
+                }
+            }
+        };
+        mResetAdbAction.setToolTipText("Reset the adb host daemon");
+        mResetAdbAction.setImageDescriptor(PlatformUI.getWorkbench()
+                .getSharedImages().getImageDescriptor(
+                        ISharedImages.IMG_OBJS_WARN_TSK));
+
+        mKillAppAction = new Action() {
+            @Override
+            public void run() {
+                mDeviceList.killSelectedClient();
+            }
+        };
+
+        mKillAppAction.setText("Stop Process");
+        mKillAppAction.setToolTipText("Stop Process");
+        mKillAppAction.setImageDescriptor(DdmsPlugin.getImageLoader()
+                .loadDescriptor(DevicePanel.ICON_HALT));
+
+        mGcAction = new Action() {
+            @Override
+            public void run() {
+                mDeviceList.forceGcOnSelectedClient();
+            }
+        };
+
+        mGcAction.setText("Cause GC");
+        mGcAction.setToolTipText("Cause GC");
+        mGcAction.setImageDescriptor(DdmsPlugin.getImageLoader()
+                .loadDescriptor(DevicePanel.ICON_GC));
+
+        mUpdateHeapAction = new Action("Update Heap", IAction.AS_CHECK_BOX) {
+            @Override
+            public void run() {
+                boolean enable = mUpdateHeapAction.isChecked();
+                mDeviceList.setEnabledHeapOnSelectedClient(enable);
+            }
+        };
+        mUpdateHeapAction.setToolTipText("Update Heap");
+        mUpdateHeapAction.setImageDescriptor(DdmsPlugin.getImageLoader()
+                .loadDescriptor(DevicePanel.ICON_HEAP));
+
+        mUpdateThreadAction = new Action("Update Threads", IAction.AS_CHECK_BOX) {
+            @Override
+            public void run() {
+                boolean enable = mUpdateThreadAction.isChecked();
+                mDeviceList.setEnabledThreadOnSelectedClient(enable);
+            }
+        };
+        mUpdateThreadAction.setToolTipText("Update Threads");
+        mUpdateThreadAction.setImageDescriptor(DdmsPlugin.getImageLoader()
+                .loadDescriptor(DevicePanel.ICON_THREAD));
+
+        // check if there's already a debug launcher set up in the plugin class
+        mDebugLauncher = DdmsPlugin.getRunningAppDebugLauncher();
+
+        mDebugAction = new Action("Debug Process") {
+            @Override
+            public void run() {
+                if (mDebugLauncher != null) {
+                    Client currentClient = mDeviceList.getSelectedClient();
+                    if (currentClient != null) {
+                        ClientData clientData = currentClient.getClientData();
+
+                        // make sure the client can be debugged
+                        switch (clientData.getDebuggerConnectionStatus()) {
+                            case ClientData.DEBUGGER_ERROR: {
+                                Display display = DdmsPlugin.getDisplay();
+                                Shell shell = display.getActiveShell();
+                                MessageDialog.openError(shell, "Process Debug",
+                                        "The process debug port is already in use!");
+                                return;
+                            }
+                            case ClientData.DEBUGGER_ATTACHED: {
+                                Display display = DdmsPlugin.getDisplay();
+                                Shell shell = display.getActiveShell();
+                                MessageDialog.openError(shell, "Process Debug",
+                                        "The process is already being debugged!");
+                                return;
+                            }
+                        }
+
+                        // get the name of the client
+                        String packageName = clientData.getClientDescription();
+                        if (packageName != null) {
+                            if (mDebugLauncher.debug(packageName,
+                                    currentClient.getDebuggerListenPort()) == false) {
+    
+                                // if we get to this point, then we failed to find a project
+                                // that matched the application to debug
+                                Display display = DdmsPlugin.getDisplay();
+                                Shell shell = display.getActiveShell();
+                                MessageDialog.openError(shell, "Process Debug",
+                                        String.format(
+                                                "No opened project found for %1$s. Debug session failed!",
+                                                packageName));
+                            }
+                        }
+                    }
+                }
+            }
+        };
+        mDebugAction.setToolTipText("Debug the selected process, provided its source project is present and opened in the workspace.");
+        mDebugAction.setImageDescriptor(DdmsPlugin.getImageLoader()
+                .loadDescriptor("debug-attach.png")); //$NON-NLS-1$
+        if (mDebugLauncher == null) {
+            mDebugAction.setEnabled(false);
+        }
+        
+        placeActions();
+    }
+
+    @Override
+    public void setFocus() {
+        mDeviceList.setFocus();
+    }
+    
+    /**
+     * Sent when a new {@link Device} 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) {
+        // update the buttons
+        doSelectionChanged(selectedClient);
+        doSelectionChanged(selectedDevice);
+    }
+
+    private void doSelectionChanged(Client selectedClient) {
+        // update the buttons
+        if (selectedClient != null) {
+            if (USE_SELECTED_DEBUG_PORT) {
+                // set the client as the debug client
+                selectedClient.setAsSelectedClient();
+            }
+
+            mDebugAction.setEnabled(mDebugLauncher != null);
+            mKillAppAction.setEnabled(true);
+            mGcAction.setEnabled(true);
+            
+            mUpdateHeapAction.setEnabled(true);
+            mUpdateHeapAction.setChecked(selectedClient.isHeapUpdateEnabled());
+
+            mUpdateThreadAction.setEnabled(true);
+            mUpdateThreadAction.setChecked(selectedClient.isThreadUpdateEnabled());
+        } else {
+            if (USE_SELECTED_DEBUG_PORT) {
+                // set the client as the debug client
+                AndroidDebugBridge bridge = AndroidDebugBridge.getBridge();
+                if (bridge != null) {
+                    bridge.setSelectedClient(null);
+                }
+            }
+            
+            mDebugAction.setEnabled(false);
+            mKillAppAction.setEnabled(false);
+            mGcAction.setEnabled(false);
+            mUpdateHeapAction.setChecked(false);
+            mUpdateHeapAction.setEnabled(false);
+            mUpdateThreadAction.setEnabled(false);
+            mUpdateThreadAction.setChecked(false);
+        }
+    }
+    
+    private void doSelectionChanged(Device selectedDevice) {
+        mCaptureAction.setEnabled(selectedDevice != null);
+    }
+
+    /**
+     * Place the actions in the ui.
+     */
+    private final void placeActions() {
+        IActionBars actionBars = getViewSite().getActionBars();
+
+        // first in the menu
+        IMenuManager menuManager = actionBars.getMenuManager();
+        menuManager.add(mDebugAction);
+        menuManager.add(new Separator());
+        menuManager.add(mUpdateThreadAction);
+        menuManager.add(mUpdateHeapAction);
+        menuManager.add(new Separator());
+        menuManager.add(mGcAction);
+        menuManager.add(new Separator());
+        menuManager.add(mKillAppAction);
+        menuManager.add(new Separator());
+        menuManager.add(mCaptureAction);
+        menuManager.add(new Separator());
+        menuManager.add(mResetAdbAction);
+
+        // and then in the toolbar
+        IToolBarManager toolBarManager = actionBars.getToolBarManager();
+        toolBarManager.add(mDebugAction);
+        toolBarManager.add(new Separator());
+        toolBarManager.add(mUpdateThreadAction);
+        toolBarManager.add(mUpdateHeapAction);
+        toolBarManager.add(new Separator());
+        toolBarManager.add(mKillAppAction);
+        toolBarManager.add(new Separator());
+        toolBarManager.add(mCaptureAction);
+    }
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EmulatorControlView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EmulatorControlView.java
new file mode 100644
index 0000000..ca9a691
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EmulatorControlView.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.EmulatorControlPanel;
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+
+import org.eclipse.swt.widgets.Composite;
+
+public class EmulatorControlView extends SelectionDependentViewPart {
+
+    public static final String ID =
+        "com.android.ide.eclipse.ddms.views.EmulatorControlView"; //$NON-NLS-1$
+
+    private EmulatorControlPanel mPanel;
+
+    @Override
+    public void createPartControl(Composite parent) {
+        mPanel = new EmulatorControlPanel(DdmsPlugin.getImageLoader());
+        mPanel.createPanel(parent);
+        setSelectionDependentPanel(mPanel);
+    }
+
+    @Override
+    public void setFocus() {
+        mPanel.setFocus();
+    }
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EventLogView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EventLogView.java
new file mode 100644
index 0000000..3a74e42
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/EventLogView.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.log.event.EventLogPanel;
+import com.android.ide.eclipse.ddms.CommonAction;
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.ide.eclipse.ddms.ImageLoader;
+
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IActionBars;
+
+public class EventLogView extends SelectionDependentViewPart {
+    
+    private EventLogPanel mLogPanel;
+
+    @Override
+    public void createPartControl(Composite parent) {
+        ImageLoader loader = DdmsPlugin.getImageLoader();
+
+        // create the external actions
+        CommonAction optionsAction = new CommonAction("Options...");
+        optionsAction.setToolTipText("Opens the options panel");
+        optionsAction.setImageDescriptor(loader
+                .loadDescriptor("edit.png")); // $NON-NLS-1$
+
+        CommonAction clearLogAction = new CommonAction("Clear Log");
+        clearLogAction.setToolTipText("Clears the event log");
+        clearLogAction.setImageDescriptor(loader
+                .loadDescriptor("clear.png")); // $NON-NLS-1$
+
+        CommonAction saveAction = new CommonAction("Save Log");
+        saveAction.setToolTipText("Saves the event log");
+        saveAction.setImageDescriptor(loader
+                .loadDescriptor("save.png")); // $NON-NLS-1$
+
+        CommonAction loadAction = new CommonAction("Load Log");
+        loadAction.setToolTipText("Loads an event log");
+        loadAction.setImageDescriptor(loader
+                .loadDescriptor("load.png")); // $NON-NLS-1$
+
+        CommonAction importBugAction = new CommonAction("Import Bug Report Log");
+        importBugAction.setToolTipText("Imports a bug report.");
+        importBugAction.setImageDescriptor(loader
+                .loadDescriptor("importBug.png")); // $NON-NLS-1$
+
+        placeActions(optionsAction, clearLogAction, saveAction, loadAction, importBugAction);
+
+        mLogPanel = new EventLogPanel(DdmsPlugin.getImageLoader());
+        mLogPanel.setActions(optionsAction, clearLogAction, saveAction, loadAction, importBugAction);
+        mLogPanel.createPanel(parent);
+        setSelectionDependentPanel(mLogPanel);
+    }
+
+    @Override
+    public void setFocus() {
+        mLogPanel.setFocus();
+    }
+    
+    @Override
+    public void dispose() {
+        if (mLogPanel != null) {
+            mLogPanel.stopEventLog(true);
+        }
+    }
+    
+    /**
+     * Places the actions in the toolbar and in the menu.
+     * @param importBugAction 
+     */
+    private void placeActions(IAction optionAction, IAction clearAction, IAction saveAction,
+            IAction loadAction, CommonAction importBugAction) {
+        IActionBars actionBars = getViewSite().getActionBars();
+
+        // first in the menu
+        IMenuManager menuManager = actionBars.getMenuManager();
+        menuManager.add(clearAction);
+        menuManager.add(new Separator());
+        menuManager.add(saveAction);
+        menuManager.add(loadAction);
+        menuManager.add(importBugAction);
+        menuManager.add(new Separator());
+        menuManager.add(optionAction);
+
+        // and then in the toolbar
+        IToolBarManager toolBarManager = actionBars.getToolBarManager();
+        toolBarManager.add(clearAction);
+        toolBarManager.add(new Separator());
+        toolBarManager.add(saveAction);
+        toolBarManager.add(loadAction);
+        toolBarManager.add(importBugAction);
+        toolBarManager.add(new Separator());
+        toolBarManager.add(optionAction);
+    }
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/FileExplorerView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/FileExplorerView.java
new file mode 100644
index 0000000..4f0dd2e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/FileExplorerView.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmlib.Client;
+import com.android.ddmlib.Device;
+import com.android.ddmuilib.explorer.DeviceExplorer;
+import com.android.ide.eclipse.ddms.CommonAction;
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.ide.eclipse.ddms.DdmsPlugin.ISelectionListener;
+
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.ViewPart;
+
+public class FileExplorerView extends ViewPart implements ISelectionListener {
+
+    public static final String ID =
+        "com.android.ide.eclipse.ddms.views.FileExplorerView"; //$NON-NLS-1$
+
+    private final static String COLUMN_NAME =
+        DdmsPlugin.PLUGIN_ID + ".explorer.name"; //$NON-NLS-1S
+    private final static  String COLUMN_SIZE =
+        DdmsPlugin.PLUGIN_ID + ".explorer.size"; //$NON-NLS-1S
+    private final static String COLUMN_DATE =
+        DdmsPlugin.PLUGIN_ID + ".explorer.data"; //$NON-NLS-1S
+    private final static String COLUMN_TIME =
+        DdmsPlugin.PLUGIN_ID + ".explorer.time"; //$NON-NLS-1S
+    private final static String COLUMN_PERMISSIONS =
+        DdmsPlugin.PLUGIN_ID +".explorer.permissions"; //$NON-NLS-1S
+    private final static String COLUMN_INFO =
+        DdmsPlugin.PLUGIN_ID + ".explorer.info"; //$NON-NLS-1$
+
+    private DeviceExplorer mExplorer;
+
+    public FileExplorerView() {
+    }
+
+    @Override
+    public void createPartControl(Composite parent) {
+        DeviceExplorer.COLUMN_NAME = COLUMN_NAME;
+        DeviceExplorer.COLUMN_SIZE = COLUMN_SIZE;
+        DeviceExplorer.COLUMN_DATE = COLUMN_DATE;
+        DeviceExplorer.COLUMN_TIME = COLUMN_TIME;
+        DeviceExplorer.COLUMN_PERMISSIONS = COLUMN_PERMISSIONS;
+        DeviceExplorer.COLUMN_INFO = COLUMN_INFO;
+
+        // device explorer
+        mExplorer = new DeviceExplorer();
+
+
+        mExplorer.setImages(PlatformUI.getWorkbench()
+                .getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE),
+                PlatformUI.getWorkbench() .getSharedImages().getImage(
+                        ISharedImages.IMG_OBJ_FOLDER),
+                DdmsPlugin.getImageLoader().loadDescriptor("android.png") //$NON-NLS-1$
+                        .createImage(),
+                PlatformUI.getWorkbench() .getSharedImages().getImage(
+                        ISharedImages.IMG_OBJ_ELEMENT));
+
+        // creates the actions
+        CommonAction pushAction = new CommonAction("Push File...") {
+            @Override
+            public void run() {
+                mExplorer.pushIntoSelection();
+            }
+        };
+        pushAction.setToolTipText("Push a file onto the device");
+        pushAction.setImageDescriptor(DdmsPlugin.getImageLoader()
+                .loadDescriptor("push.png")); //$NON-NLS-1$
+        pushAction.setEnabled(false);
+
+        CommonAction pullAction = new CommonAction("Pull File...") {
+            @Override
+            public void run() {
+                mExplorer.pullSelection();
+            }
+        };
+        pullAction.setToolTipText("Pull a file from the device");
+        pullAction.setImageDescriptor(DdmsPlugin.getImageLoader()
+                .loadDescriptor("pull.png")); //$NON-NLS-1$
+        pullAction.setEnabled(false);
+
+        CommonAction deleteAction = new CommonAction("Delete") {
+            @Override
+            public void run() {
+                mExplorer.deleteSelection();
+            }
+        };
+        deleteAction.setToolTipText("Delete the selection");
+        deleteAction.setImageDescriptor(DdmsPlugin.getImageLoader()
+                .loadDescriptor("delete.png")); //$NON-NLS-1$
+        deleteAction.setEnabled(false);
+
+        // set up the actions in the explorer
+        mExplorer.setActions(pushAction, pullAction, deleteAction);
+
+        // and in the ui
+        IActionBars actionBars = getViewSite().getActionBars();
+        IMenuManager menuManager = actionBars.getMenuManager();
+        IToolBarManager toolBarManager = actionBars.getToolBarManager();
+
+        menuManager.add(pullAction);
+        menuManager.add(pushAction);
+        menuManager.add(new Separator());
+        menuManager.add(deleteAction);
+
+        toolBarManager.add(pullAction);
+        toolBarManager.add(pushAction);
+        toolBarManager.add(new Separator());
+        toolBarManager.add(deleteAction);
+        
+        mExplorer.createPanel(parent);
+
+        DdmsPlugin.getDefault().addSelectionListener(this);
+    }
+
+    @Override
+    public void setFocus() {
+        mExplorer.setFocus();
+    }
+
+    /**
+     * Sent when a new {@link Client} is selected.
+     * @param selectedClient The selected client.
+     */
+    public void selectionChanged(Client selectedClient) {
+        // pass
+    }
+    
+    /**
+     * Sent when a new {@link Device} is selected.
+     * @param selectedDevice the selected device.
+     */
+    public void selectionChanged(Device selectedDevice) {
+        mExplorer.switchDevice(selectedDevice);
+    }
+    
+    /**
+     * Sent when there is no current selection.
+     */
+    public void selectionRemoved() {
+        
+    }
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/HeapView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/HeapView.java
new file mode 100644
index 0000000..5745e8e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/HeapView.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.HeapPanel;
+
+import org.eclipse.swt.widgets.Composite;
+
+public class HeapView extends TableView {
+
+    public static final String ID = "com.android.ide.eclipse.ddms.views.HeapView"; //$NON-NLS-1$
+    private HeapPanel mPanel;
+
+    public HeapView() {
+    }
+
+    @Override
+    public void createPartControl(Composite parent) {
+        mPanel = new HeapPanel();
+        mPanel.createPanel(parent);
+
+        setSelectionDependentPanel(mPanel);
+
+        // listen to focus changes for table(s) of the panel.
+        setupTableFocusListener(mPanel, parent);
+    }
+
+    @Override
+    public void setFocus() {
+        mPanel.setFocus();
+    }
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/LogCatView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/LogCatView.java
new file mode 100644
index 0000000..d3053f1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/LogCatView.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ide.eclipse.ddms.CommonAction;
+import com.android.ide.eclipse.ddms.DdmsPlugin;
+import com.android.ide.eclipse.ddms.ImageLoader;
+import com.android.ide.eclipse.ddms.preferences.PreferenceInitializer;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmuilib.logcat.LogColors;
+import com.android.ddmuilib.logcat.LogFilter;
+import com.android.ddmuilib.logcat.LogPanel;
+import com.android.ddmuilib.logcat.LogPanel.ILogFilterStorageManager;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.actions.ActionFactory;
+
+import java.util.ArrayList;
+
+/**
+ * The log cat view displays log output from the current device selection.
+ *
+ */
+public final class LogCatView extends SelectionDependentViewPart {
+
+    public static final String ID =
+        "com.android.ide.eclipse.ddms.views.LogCatView"; // $NON-NLS-1$
+
+    private static final String PREFS_COL_TIME =
+        DdmsPlugin.PLUGIN_ID + ".logcat.time"; // $NON-NLS-1$
+    private static final String PREFS_COL_LEVEL =
+        DdmsPlugin.PLUGIN_ID + ".logcat.level"; // $NON-NLS-1$
+    private static final String PREFS_COL_PID =
+        DdmsPlugin.PLUGIN_ID + ".logcat.pid"; // $NON-NLS-1$
+    private static final String PREFS_COL_TAG =
+        DdmsPlugin.PLUGIN_ID + ".logcat.tag"; // $NON-NLS-1$
+    private static final String PREFS_COL_MESSAGE =
+        DdmsPlugin.PLUGIN_ID + ".logcat.message"; // $NON-NLS-1$
+
+    private static final String PREFS_FILTERS =
+        DdmsPlugin.PLUGIN_ID + ".logcat.filters"; // $NON-NLS-1$
+
+    private static LogCatView sThis;
+    private LogPanel mLogPanel;
+
+    private CommonAction mCreateFilterAction;
+    private CommonAction mDeleteFilterAction;
+    private CommonAction mEditFilterAction;
+    private CommonAction mExportAction;
+
+    private CommonAction[] mLogLevelActions;
+    private String[] mLogLevelIcons = {
+            "v.png", //$NON-NLS-1S
+            "d.png", //$NON-NLS-1S
+            "i.png", //$NON-NLS-1S
+            "w.png", //$NON-NLS-1S
+            "e.png", //$NON-NLS-1S
+    };
+
+    private Action mClearAction;
+
+    private Clipboard mClipboard;
+
+    /**
+     * An implementation of {@link ILogFilterStorageManager} to bridge to the eclipse preference
+     * store, and saves the log filters.
+     */
+    private final class FilterStorage implements ILogFilterStorageManager {
+
+        public LogFilter[] getFilterFromStore() {
+            String filterPrefs = DdmsPlugin.getDefault().getPreferenceStore().getString(
+                    PREFS_FILTERS);
+
+            // split in a string per filter
+            String[] filters = filterPrefs.split("\\|"); // $NON-NLS-1$
+
+            ArrayList<LogFilter> list =
+                new ArrayList<LogFilter>(filters.length);
+
+            for (String f : filters) {
+                if (f.length() > 0) {
+                    LogFilter logFilter = new LogFilter();
+                    if (logFilter.loadFromString(f)) {
+                        list.add(logFilter);
+                    }
+                }
+            }
+
+            return list.toArray(new LogFilter[list.size()]);
+        }
+
+        public void saveFilters(LogFilter[] filters) {
+            StringBuilder sb = new StringBuilder();
+            for (LogFilter f : filters) {
+                String filterString = f.toString();
+                sb.append(filterString);
+                sb.append('|');
+            }
+
+            DdmsPlugin.getDefault().getPreferenceStore().setValue(PREFS_FILTERS, sb.toString());
+        }
+
+        public boolean requiresDefaultFilter() {
+            return true;
+        }
+    }
+
+    public LogCatView() {
+        sThis = this;
+        LogPanel.PREFS_TIME = PREFS_COL_TIME;
+        LogPanel.PREFS_LEVEL = PREFS_COL_LEVEL;
+        LogPanel.PREFS_PID = PREFS_COL_PID;
+        LogPanel.PREFS_TAG = PREFS_COL_TAG;
+        LogPanel.PREFS_MESSAGE = PREFS_COL_MESSAGE;
+    }
+
+    /**
+     * Returns the singleton instance.
+     */
+    public static LogCatView getInstance() {
+        return sThis;
+    }
+
+    /**
+     * Sets the display font.
+     * @param font The font.
+     */
+    public static void setFont(Font font) {
+        if (sThis != null && sThis.mLogPanel != null) {
+            sThis.mLogPanel.setFont(font);
+        }
+    }
+
+    @Override
+    public void createPartControl(Composite parent) {
+        Display d = parent.getDisplay();
+        LogColors colors = new LogColors();
+
+        ImageLoader loader = DdmsPlugin.getImageLoader();
+
+        colors.infoColor = new Color(d, 0, 127, 0);
+        colors.debugColor = new Color(d, 0, 0, 127);
+        colors.errorColor = new Color(d, 255, 0, 0);
+        colors.warningColor = new Color(d, 255, 127, 0);
+        colors.verboseColor = new Color(d, 0, 0, 0);
+
+        mCreateFilterAction = new CommonAction("Create Filter") {
+            @Override
+            public void run() {
+                mLogPanel.addFilter();
+            }
+        };
+        mCreateFilterAction.setToolTipText("Create Filter");
+        mCreateFilterAction.setImageDescriptor(loader
+                .loadDescriptor("add.png")); // $NON-NLS-1$
+
+        mEditFilterAction = new CommonAction("Edit Filter") {
+            @Override
+            public void run() {
+                mLogPanel.editFilter();
+            }
+        };
+        mEditFilterAction.setToolTipText("Edit Filter");
+        mEditFilterAction.setImageDescriptor(loader
+                .loadDescriptor("edit.png")); // $NON-NLS-1$
+
+        mDeleteFilterAction = new CommonAction("Delete Filter") {
+            @Override
+            public void run() {
+                mLogPanel.deleteFilter();
+            }
+        };
+        mDeleteFilterAction.setToolTipText("Delete Filter");
+        mDeleteFilterAction.setImageDescriptor(loader
+                .loadDescriptor("delete.png")); // $NON-NLS-1$
+
+        mExportAction = new CommonAction("Export Selection As Text...") {
+            @Override
+            public void run() {
+                mLogPanel.save();
+            }
+        };
+        mExportAction.setToolTipText("Export Selection As Text...");
+        mExportAction.setImageDescriptor(loader.loadDescriptor("save.png")); // $NON-NLS-1$
+
+        LogLevel[] levels = LogLevel.values();
+        mLogLevelActions = new CommonAction[mLogLevelIcons.length];
+        for (int i = 0 ; i < mLogLevelActions.length; i++) {
+            String name = levels[i].getStringValue();
+            mLogLevelActions[i] = new CommonAction(name, IAction.AS_CHECK_BOX) {
+                @Override
+                public void run() {
+                    // disable the other actions and record current index
+                    for (int i = 0 ; i < mLogLevelActions.length; i++) {
+                        Action a = mLogLevelActions[i];
+                        if (a == this) {
+                            a.setChecked(true);
+
+                            // set the log level
+                            mLogPanel.setCurrentFilterLogLevel(i+2);
+                        } else {
+                            a.setChecked(false);
+                        }
+                    }
+                }
+            };
+
+            mLogLevelActions[i].setToolTipText(name);
+            mLogLevelActions[i].setImageDescriptor(loader.loadDescriptor(mLogLevelIcons[i]));
+        }
+
+        mClearAction = new Action("Clear Log") {
+            @Override
+            public void run() {
+                mLogPanel.clear();
+            }
+        };
+        mClearAction.setImageDescriptor(loader
+                .loadDescriptor("clear.png")); // $NON-NLS-1$
+
+
+        // now create the log view
+        mLogPanel = new LogPanel(loader, colors, new FilterStorage(), LogPanel.FILTER_MANUAL);
+        mLogPanel.setActions(mDeleteFilterAction, mEditFilterAction, mLogLevelActions);
+
+        // get the font
+        String fontStr = DdmsPlugin.getDefault().getPreferenceStore().getString(
+                PreferenceInitializer.ATTR_LOGCAT_FONT);
+        if (fontStr != null) {
+            FontData data = new FontData(fontStr);
+
+            if (fontStr != null) {
+                mLogPanel.setFont(new Font(parent.getDisplay(), data));
+            }
+        }
+
+        mLogPanel.createPanel(parent);
+        setSelectionDependentPanel(mLogPanel);
+
+        // place the actions.
+        placeActions();
+
+        // setup the copy action
+        mClipboard = new Clipboard(d);
+        IActionBars actionBars = getViewSite().getActionBars();
+        actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), new Action("Copy") {
+            @Override
+            public void run() {
+                mLogPanel.copy(mClipboard);
+            }
+        });
+
+        // setup the select all action
+        actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
+                new Action("Select All") {
+            @Override
+            public void run() {
+                mLogPanel.selectAll();
+            }
+        });
+    }
+
+    @Override
+    public void dispose() {
+        mLogPanel.stopLogCat(true);
+        mClipboard.dispose();
+    }
+
+    @Override
+    public void setFocus() {
+        mLogPanel.setFocus();
+    }
+
+    /**
+     * Place the actions in the ui.
+     */
+    private void placeActions() {
+        IActionBars actionBars = getViewSite().getActionBars();
+
+        // first in the menu
+        IMenuManager menuManager = actionBars.getMenuManager();
+        menuManager.add(mCreateFilterAction);
+        menuManager.add(mEditFilterAction);
+        menuManager.add(mDeleteFilterAction);
+        menuManager.add(new Separator());
+        menuManager.add(mClearAction);
+        menuManager.add(new Separator());
+        menuManager.add(mExportAction);
+
+        // and then in the toolbar
+        IToolBarManager toolBarManager = actionBars.getToolBarManager();
+        for (CommonAction a : mLogLevelActions) {
+            toolBarManager.add(a);
+        }
+        toolBarManager.add(new Separator());
+        toolBarManager.add(mCreateFilterAction);
+        toolBarManager.add(mEditFilterAction);
+        toolBarManager.add(mDeleteFilterAction);
+        toolBarManager.add(new Separator());
+        toolBarManager.add(mClearAction);
+    }
+ }
+
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/NativeHeapView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/NativeHeapView.java
new file mode 100644
index 0000000..ed5aacb
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/NativeHeapView.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.NativeHeapPanel;
+
+import org.eclipse.swt.widgets.Composite;
+
+public class NativeHeapView extends TableView {
+
+    public static final String ID =
+        "com.android.ide.eclipse.ddms.views.NativeHeapView"; // $NON-NLS-1$
+    private NativeHeapPanel mPanel;
+
+    public NativeHeapView() {
+    }
+
+    @Override
+    public void createPartControl(Composite parent) {
+        mPanel = new NativeHeapPanel();
+        mPanel.createPanel(parent);
+        
+        setSelectionDependentPanel(mPanel);
+
+        // listen to focus changes for table(s) of the panel.
+        setupTableFocusListener(mPanel, parent);
+    }
+
+    @Override
+    public void setFocus() {
+        mPanel.setFocus();
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SelectionDependentViewPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SelectionDependentViewPart.java
new file mode 100644
index 0000000..48b2689
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/SelectionDependentViewPart.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ide.eclipse.ddms.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.ui.part.ViewPart;
+
+/**
+ * A Workbench {@link ViewPart} that requires {@link Device}/{@link Client} selection notifications
+ * from {@link DdmsPlugin} through the {@link ISelectionListener} interface.
+ */
+public abstract class SelectionDependentViewPart extends ViewPart implements ISelectionListener {
+    
+    private SelectionDependentPanel mPanel;
+    
+    protected final void setSelectionDependentPanel(SelectionDependentPanel panel) {
+        // remember the panel
+        mPanel = panel;
+        
+        // and add ourself as listener of selection events.
+        DdmsPlugin.getDefault().addSelectionListener(this);
+    }
+    
+    @Override
+    public void dispose() {
+        DdmsPlugin.getDefault().removeSelectionListener(this);
+        super.dispose();
+    }
+
+    /**
+     * Sent when a new {@link Client} is selected.
+     * @param selectedClient The selected client.
+     * 
+     * @see ISelectionListener
+     */
+    public final void selectionChanged(Client selectedClient) {
+        mPanel.clientSelected(selectedClient);
+    }
+    
+    /**
+     * Sent when a new {@link Device} is selected.
+     * @param selectedDevice the selected device.
+     *
+     * @see ISelectionListener
+     */
+    public final void selectionChanged(Device selectedDevice) {
+        mPanel.deviceSelected(selectedDevice);
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/TableView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/TableView.java
new file mode 100644
index 0000000..0fda35d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/TableView.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.ITableFocusListener;
+import com.android.ddmuilib.TablePanel;
+import com.android.ddmuilib.ITableFocusListener.IFocusedTableActivator;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.actions.ActionFactory;
+
+/**
+ * Base class for view containing Table that needs to support copy, and select all.
+ */
+public abstract class TableView extends SelectionDependentViewPart {
+
+    /** Activator for the current Table that has the focus */
+    IFocusedTableActivator mActivator = null;
+
+    private Clipboard mClipboard;
+
+    private Action mCopyAction;
+    private Action mSelectAllAction;
+
+    /**
+     * Setup the listener for the Table objects of <code>Panel</code>, and setup
+     * the copy and select all actions.
+     * @param panel The panel to setup
+     * @param parent The parent composite of the Panel's content.
+     */
+    void setupTableFocusListener(TablePanel panel, Composite parent) {
+        panel.setTableFocusListener(new ITableFocusListener() {
+            public void focusGained(IFocusedTableActivator activator) {
+                mActivator = activator;
+                mCopyAction.setEnabled(true);
+                mSelectAllAction.setEnabled(true);
+            }
+
+            public void focusLost(IFocusedTableActivator activator) {
+                if (activator == mActivator) {
+                    mActivator = null;
+                    mCopyAction.setEnabled(false);
+                    mSelectAllAction.setEnabled(false);
+                }
+            }
+        });
+
+        // setup the copy action
+        mClipboard = new Clipboard(parent.getDisplay());
+        IActionBars actionBars = getViewSite().getActionBars();
+        actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(),
+                mCopyAction = new Action("Copy") {
+            @Override
+            public void run() {
+                if (mActivator != null) {
+                    mActivator.copy(mClipboard);
+                }
+            }
+        });
+
+        // setup the select all action
+        actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
+                mSelectAllAction = new Action("Select All") {
+            @Override
+            public void run() {
+                if (mActivator != null) {
+                    mActivator.selectAll();
+                }
+            }
+        });
+
+    }
+
+    @Override
+    public void dispose() {
+        super.dispose();
+        mClipboard.dispose();
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/ThreadView.java b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/ThreadView.java
new file mode 100644
index 0000000..cd24458
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.ddms/src/com/android/ide/eclipse/ddms/views/ThreadView.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.ddms.views;
+
+import com.android.ddmuilib.ThreadPanel;
+
+import org.eclipse.swt.widgets.Composite;
+
+public class ThreadView extends TableView {
+
+    public static final String ID =
+        "com.android.ide.eclipse.ddms.views.ThreadView"; // $NON-NLS-1$
+    private ThreadPanel mPanel;
+
+    public ThreadView() {
+    }
+
+    @Override
+    public void createPartControl(Composite parent) {
+        mPanel = new ThreadPanel();
+        mPanel.createPanel(parent);
+
+        setSelectionDependentPanel(mPanel);
+
+        // listen to focus changes for table(s) of the panel.
+        setupTableFocusListener(mPanel, parent);
+    }
+
+    @Override
+    public void setFocus() {
+        mPanel.setFocus();
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/.classpath b/tools/eclipse/plugins/com.android.ide.eclipse.tests/.classpath
new file mode 100644
index 0000000..4088683
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="src" path="unittests"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="lib" path="kxml2-2.3.0.jar"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/.project b/tools/eclipse/plugins/com.android.ide.eclipse.tests/.project
new file mode 100644
index 0000000..99e4964
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/.project
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>adt-tests</name>
+	<comment></comment>
+	<projects>
+		<project>SdkLib</project>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF b/tools/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..266008c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Android Plugin Tests
+Bundle-SymbolicName: com.android.ide.eclipse.tests
+Bundle-Version: 0.9.0.qualifier
+Bundle-Activator: com.android.ide.eclipse.tests.AndroidTestPlugin
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ com.android.ide.eclipse.adt,
+ org.junit,
+ org.eclipse.jdt.core,
+ org.eclipse.jdt.launching,
+ org.eclipse.ui.views,
+ com.android.ide.eclipse.ddms
+Eclipse-LazyStart: true
+Bundle-Vendor: The Android Open Source Project
+Bundle-ClassPath: kxml2-2.3.0.jar,
+ .
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/MODULE_LICENSE_EPL b/tools/eclipse/plugins/com.android.ide.eclipse.tests/MODULE_LICENSE_EPL
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/MODULE_LICENSE_EPL
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/NOTICE b/tools/eclipse/plugins/com.android.ide.eclipse.tests/NOTICE
new file mode 100644
index 0000000..49c101d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/NOTICE
@@ -0,0 +1,224 @@
+*Eclipse Public License - v 1.0*
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF
+THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+*1. DEFINITIONS*
+
+"Contribution" means:
+
+a) in the case of the initial Contributor, the initial code and
+documentation distributed under this Agreement, and
+b) in the case of each subsequent Contributor:
+
+i) changes to the Program, and
+
+ii) additions to the Program;
+
+where such changes and/or additions to the Program originate from and
+are distributed by that particular Contributor. A Contribution
+'originates' from a Contributor if it was added to the Program by such
+Contributor itself or anyone acting on such Contributor's behalf.
+Contributions do not include additions to the Program which: (i) are
+separate modules of software distributed in conjunction with the Program
+under their own license agreement, and (ii) are not derivative works of
+the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which
+are necessarily infringed by the use or sale of its Contribution alone
+or when combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this
+Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement,
+including all Contributors.
+
+*2. GRANT OF RIGHTS*
+
+a) Subject to the terms of this Agreement, each Contributor hereby
+grants Recipient a non-exclusive, worldwide, royalty-free copyright
+license to reproduce, prepare derivative works of, publicly display,
+publicly perform, distribute and sublicense the Contribution of such
+Contributor, if any, and such derivative works, in source code and
+object code form.
+
+b) Subject to the terms of this Agreement, each Contributor hereby
+grants Recipient a non-exclusive, worldwide, royalty-free patent license
+under Licensed Patents to make, use, sell, offer to sell, import and
+otherwise transfer the Contribution of such Contributor, if any, in
+source code and object code form. This patent license shall apply to the
+combination of the Contribution and the Program if, at the time the
+Contribution is added by the Contributor, such addition of the
+Contribution causes such combination to be covered by the Licensed
+Patents. The patent license shall not apply to any other combinations
+which include the Contribution. No hardware per se is licensed hereunder.
+
+c) Recipient understands that although each Contributor grants the
+licenses to its Contributions set forth herein, no assurances are
+provided by any Contributor that the Program does not infringe the
+patent or other intellectual property rights of any other entity. Each
+Contributor disclaims any liability to Recipient for claims brought by
+any other entity based on infringement of intellectual property rights
+or otherwise. As a condition to exercising the rights and licenses
+granted hereunder, each Recipient hereby assumes sole responsibility to
+secure any other intellectual property rights needed, if any. For
+example, if a third party patent license is required to allow Recipient
+to distribute the Program, it is Recipient's responsibility to acquire
+that license before distributing the Program.
+
+d) Each Contributor represents that to its knowledge it has sufficient
+copyright rights in its Contribution, if any, to grant the copyright
+license set forth in this Agreement.
+
+*3. REQUIREMENTS*
+
+A Contributor may choose to distribute the Program in object code form
+under its own license agreement, provided that:
+
+a) it complies with the terms and conditions of this Agreement; and
+
+b) its license agreement:
+
+i) effectively disclaims on behalf of all Contributors all warranties
+and conditions, express and implied, including warranties or conditions
+of title and non-infringement, and implied warranties or conditions of
+merchantability and fitness for a particular purpose;
+
+ii) effectively excludes on behalf of all Contributors all liability for
+damages, including direct, indirect, special, incidental and
+consequential damages, such as lost profits;
+
+iii) states that any provisions which differ from this Agreement are
+offered by that Contributor alone and not by any other party; and
+
+iv) states that source code for the Program is available from such
+Contributor, and informs licensees how to obtain it in a reasonable
+manner on or through a medium customarily used for software exchange.
+
+When the Program is made available in source code form:
+
+a) it must be made available under this Agreement; and
+
+b) a copy of this Agreement must be included with each copy of the Program.
+
+Contributors may not remove or alter any copyright notices contained
+within the Program.
+
+Each Contributor must identify itself as the originator of its
+Contribution, if any, in a manner that reasonably allows subsequent
+Recipients to identify the originator of the Contribution.
+
+*4. COMMERCIAL DISTRIBUTION*
+
+Commercial distributors of software may accept certain responsibilities
+with respect to end users, business partners and the like. While this
+license is intended to facilitate the commercial use of the Program, the
+Contributor who includes the Program in a commercial product offering
+should do so in a manner which does not create potential liability for
+other Contributors. Therefore, if a Contributor includes the Program in
+a commercial product offering, such Contributor ("Commercial
+Contributor") hereby agrees to defend and indemnify every other
+Contributor ("Indemnified Contributor") against any losses, damages and
+costs (collectively "Losses") arising from claims, lawsuits and other
+legal actions brought by a third party against the Indemnified
+Contributor to the extent caused by the acts or omissions of such
+Commercial Contributor in connection with its distribution of the
+Program in a commercial product offering. The obligations in this
+section do not apply to any claims or Losses relating to any actual or
+alleged intellectual property infringement. In order to qualify, an
+Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial
+Contributor to control, and cooperate with the Commercial Contributor
+in, the defense and any related settlement negotiations. The Indemnified
+Contributor may participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those
+performance claims and warranties, and if a court requires any other
+Contributor to pay any damages as a result, the Commercial Contributor
+must pay those damages.
+
+*5. NO WARRANTY*
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED
+ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES
+OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR
+A PARTICULAR PURPOSE. Each Recipient is solely responsible for
+determining the appropriateness of using and distributing the Program
+and assumes all risks associated with its exercise of rights under this
+Agreement , including but not limited to the risks and costs of program
+errors, compliance with applicable laws, damage to or loss of data,
+programs or equipment, and unavailability or interruption of operations.
+
+*6. DISCLAIMER OF LIABILITY*
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR
+ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING
+WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR
+DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
+HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+*7. GENERAL*
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further action
+by the parties hereto, such provision shall be reformed to the minimum
+extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity (including
+a cross-claim or counterclaim in a lawsuit) alleging that the Program
+itself (excluding combinations of the Program with other software or
+hardware) infringes such Recipient's patent(s), then such Recipient's
+rights granted under Section 2(b) shall terminate as of the date such
+litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails
+to comply with any of the material terms or conditions of this Agreement
+and does not cure such failure in a reasonable period of time after
+becoming aware of such noncompliance. If all Recipient's rights under
+this Agreement terminate, Recipient agrees to cease use and distribution
+of the Program as soon as reasonably practicable. However, Recipient's
+obligations under this Agreement and any licenses granted by Recipient
+relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement,
+but in order to avoid inconsistency the Agreement is copyrighted and may
+only be modified in the following manner. The Agreement Steward reserves
+the right to publish new versions (including revisions) of this
+Agreement from time to time. No one other than the Agreement Steward has
+the right to modify this Agreement. The Eclipse Foundation is the
+initial Agreement Steward. The Eclipse Foundation may assign the
+responsibility to serve as the Agreement Steward to a suitable separate
+entity. Each new version of the Agreement will be given a distinguishing
+version number. The Program (including Contributions) may always be
+distributed subject to the version of the Agreement under which it was
+received. In addition, after a new version of the Agreement is
+published, Contributor may elect to distribute the Program (including
+its Contributions) under the new version. Except as expressly stated in
+Sections 2(a) and 2(b) above, Recipient receives no rights or licenses
+to the intellectual property of any Contributor under this Agreement,
+whether expressly, by implication, estoppel or otherwise. All rights in
+the Program not expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the
+intellectual property laws of the United States of America. No party to
+this Agreement will bring a legal action under this Agreement more than
+one year after the cause of action arose. Each party waives its rights
+to a jury trial in any resulting litigation.
+
+ 
+
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/README.txt b/tools/eclipse/plugins/com.android.ide.eclipse.tests/README.txt
new file mode 100644
index 0000000..f5899e3
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/README.txt
@@ -0,0 +1,72 @@
+This project contains the tests for the Android Eclipse Plugins.
+
+You can do two things:
+1- Run the full "eclipse plugin" suite
+2- Run independent JUnit tests (not as plugin)
+
+------------------------------------------
+1- Running the full "eclipse plugin" suite
+------------------------------------------
+
+Steps to run the test suite:
+
+A- In Eclipse, import following projects from //device/tools/eclipse/plugins:
+	- adt-tests
+	- adt
+	- common
+	- editors
+
+B- Create a new "JUnit Plug-in Test" run configuration via the "Run > Open Run Dialog..." menu
+Set the launch configuration's data as follows:
+i. "Test" tab: 
+  Select "Run a single test"
+  Project: adt-tests 
+  Test class: com.android.ide.eclipse.tests.UnitTests
+  Test runner: JUnit 3
+ii. "Arguments" tab:
+ Set "VM Arguments" to 
+"-Dtest_data=<adt>/plugins/com.android.ide.eclipse.tests/unittests/data/"
+replacing "<adt>" with absolute filesystem path to the android plugin source location
+
+All other fields can be left with their default values
+
+C. Run the newly created launch configuration
+
+Running the tests will run a secondary instance of Eclipse. 
+
+Please note the following constraints to be aware of when writing tests to run within a plugin environment:
+
+a. Access restrictions: cannot access package or protected members in a different
+plugin, even if they are in the same declared package 
+b. Using classloader.getResource or getResourceAsStream to access test data will 
+likely fail in the plugin environment. Instead, use AdtTestData to access test files
+in conjunction with the "test_data" environment variable mentioned above
+
+
+-------------------------------------------
+2- Run independent JUnit tests (not plugin)
+-------------------------------------------
+
+A- In Eclipse, import following projects from //device/tools/eclipse/plugins:
+	- adt-tests
+	- adt
+	- common
+	- editors
+
+B- Select the "unittests" source folder, right-click and select
+	"Run As > JUnit Test" (i.e. not the plugin tests)
+
+This creates a debug configuration of type "JUnit Test" running all tests
+in the source folder "unittests". The runtime must be JUnit 3.
+
+Note: this method runs the tests within a regular JVM environment (ie not within
+an Eclipse instance). This method has the advantage of being quicker than running
+as a JUnit plugin test, and requires less potential set-up, but has the 
+disadvantage of not properly replicating how the tests will be run in the 
+continuous test environment. Tests that pass when run as "JUnit Tests" can
+fail when run as "JUnit Plugin Tests", due to the extra constraints imposed by
+running within an Eclipse plug-in noted in section 1.
+
+
+
+
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/build.properties b/tools/eclipse/plugins/com.android.ide.eclipse.tests/build.properties
new file mode 100644
index 0000000..cbfd993
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/build.properties
@@ -0,0 +1,10 @@
+source.. = src/,\
+           unittests/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               test.xml,\
+               prefs.template,\
+               unittest.xml,\
+               kxml2-2.3.0.jar,\
+               unittests/data/
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class1.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class1.java
new file mode 100644
index 0000000..3cf1027
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class1.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jar.example;
+
+public class Class1 {
+
+    public static final int sStaticField = 1;
+    
+    /** constructor */
+    public Class1() {
+        int a = 1;
+    }
+    
+    public static class InnerStaticClass1 {
+        
+    }
+
+    public class InnerClass2 {
+        
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class2.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class2.java
new file mode 100644
index 0000000..4d15c47
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class2.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jar.example;
+
+public class Class2 extends Class1 {
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/prefs.template b/tools/eclipse/plugins/com.android.ide.eclipse.tests/prefs.template
new file mode 100644
index 0000000..e0037de
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/prefs.template
@@ -0,0 +1,3 @@
+#Wed Feb 20 16:56:40 PST 2008
+com.android.ide.eclipse.adt.sdk=sdk_home
+eclipse.preferences.version=1
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectCreationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectCreationPage.java
new file mode 100644
index 0000000..42f8df0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectCreationPage.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License"); you
+ * may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ * 
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, 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 java.io.File;
+
+/**
+ * Stub class for project creation page Returns canned responses for creating a
+ * sample project
+ */
+public class StubSampleProjectCreationPage extends NewProjectCreationPage {
+
+    private String mSampleProjectName;
+    private String mOsSdkLocation;
+
+    public StubSampleProjectCreationPage(String pageName,
+            String sampleProjectName, String osSdkLocation) {
+        super(pageName);
+        this.mSampleProjectName = sampleProjectName;
+        this.mOsSdkLocation = osSdkLocation;
+    }
+
+    @Override
+    public String getProjectName() {
+        return mSampleProjectName;
+    }
+
+    @Override
+    public String getPackageName() {
+        return "com.android.samples";
+    }
+
+    @Override
+    public String getActivityName() {
+        return mSampleProjectName;
+    }
+
+    @Override
+    public String getApplicationName() {
+        return mSampleProjectName;
+    }
+
+    @Override
+    public boolean isNewProject() {
+        return false;
+    }
+
+    @Override
+    public String getProjectLocation() {
+        return mOsSdkLocation + File.separator + "samples" + File.separator + mSampleProjectName;
+    }
+
+    @Override
+    public String getSourceFolder() {
+        return "src";
+    }
+
+}
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
new file mode 100644
index 0000000..40cd636
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/wizards/newproject/StubSampleProjectWizard.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License"); you
+ * may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ * 
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, 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 org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.wizard.IWizardContainer;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.swt.widgets.Shell;
+
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Stub class for project creation wizard Created so project creation logic can
+ * be run without UI creation/manipulation Returns canned responses for creating
+ * a sample project
+ */
+public class StubSampleProjectWizard extends NewProjectWizard {
+
+    private final String mSampleProjectName;
+    private final String mOsSdkLocation;
+
+    /**
+     * Constructor
+     * 
+     * @param sampleProjectName
+     * @param osSdkLocation
+     */
+    public StubSampleProjectWizard(String sampleProjectName, String osSdkLocation) {
+        this.mSampleProjectName = sampleProjectName;
+        this.mOsSdkLocation = osSdkLocation;
+    }
+
+    /**
+     * Override parent to return stub page
+     */
+    @Override
+    protected NewProjectCreationPage createMainPage() {
+        return new StubSampleProjectCreationPage(MAIN_PAGE_NAME,
+                mSampleProjectName, mOsSdkLocation);
+    }
+
+    /**
+     * Overrides parent to return dummy wizard container
+     */
+    @Override
+    public IWizardContainer getContainer() {
+        return new IWizardContainer() {
+
+            public IWizardPage getCurrentPage() {
+                return null;
+            }
+
+            public Shell getShell() {
+                return null;
+            }
+
+            public void showPage(IWizardPage page) {
+                // pass
+            }
+
+            public void updateButtons() {
+                // pass
+            }
+
+            public void updateMessage() {
+                // pass
+            }
+
+            public void updateTitleBar() {
+                // pass
+            }
+
+            public void updateWindowTitle() {
+                // pass
+            }
+
+            /**
+             * Executes runnable on current thread
+             */
+            public void run(boolean fork, boolean cancelable,
+                    IRunnableWithProgress runnable)
+                    throws InvocationTargetException, InterruptedException {
+                runnable.run(new NullProgressMonitor());
+            }
+
+        };
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AdtTestData.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AdtTestData.java
new file mode 100644
index 0000000..262ef65
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AdtTestData.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.tests;
+
+import java.io.File;
+import java.net.URL;
+import java.util.logging.Logger;
+
+/**
+ * Helper class for retrieving test data
+ * 
+ * All tests which need to retrieve test data files should go through this class 
+ *
+ */
+public class AdtTestData {
+
+    /** singleton instance */
+    private static AdtTestData sInstance = null;
+    private static final Logger sLogger = Logger.getLogger(AdtTestData.class.getName());
+    
+    /** the absolute file path to the /data directory in this test 
+     * environment. 
+     */
+    private String mOsRootDataPath;
+    
+   
+    private AdtTestData() {
+        // can set test_data env variable to override default behavior of 
+        // finding data using class loader
+        // useful when running in plugin environment, where test data is inside 
+        // bundled jar, and must be extracted to temp filesystem location to be 
+        // accessed normally
+        mOsRootDataPath = System.getProperty("test_data");
+        if (mOsRootDataPath == null) {
+            sLogger.info("Cannot find test_data directory, init to class loader");
+            URL url = this.getClass().getClassLoader().getResource("data");  //$NON-NLS-1$
+            mOsRootDataPath = url.getFile();
+        }
+        if (!mOsRootDataPath.endsWith(File.separator)) {
+            sLogger.info("Fixing test_data env variable does not end with path separator");
+            mOsRootDataPath = mOsRootDataPath.concat(File.separator);
+        }
+    }
+    
+    /** Get the singleton instance of AdtTestData */
+    public static AdtTestData getInstance() {
+        if (sInstance == null) {
+            sInstance = new AdtTestData();
+        }
+        return sInstance;
+    }
+    
+    /** Returns the absolute file path to a file located in this plugins
+     * "data" directory
+     * @param osRelativePath - string path to file contained in /data. Must 
+     * use path separators appropriate to host OS
+     * @return String
+     */
+    public String getTestFilePath(String osRelativePath) {
+        return mOsRootDataPath + osRelativePath;
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java
new file mode 100644
index 0000000..fb5504c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AllTests.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License"); you
+ * may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ * 
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.ide.eclipse.tests;
+
+import junit.framework.TestSuite;
+
+
+/**
+ * Container TestSuite for all eclipse tests, both functional and unit
+ */
+public class AllTests extends TestSuite {
+
+    public AllTests() {
+        
+    }
+    
+    /**
+     * Returns a suite of test cases to be run.
+     */
+    public static TestSuite suite() {
+        TestSuite suite = new TestSuite();
+        suite.addTest(FuncTests.suite());
+        suite.addTest(UnitTests.suite());
+        return suite;
+    }
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AndroidTestPlugin.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AndroidTestPlugin.java
new file mode 100644
index 0000000..45a6fbc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/AndroidTestPlugin.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License"); you
+ * may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ * 
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.ide.eclipse.tests;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class AndroidTestPlugin extends AbstractUIPlugin {
+
+    // The plug-in ID
+    public static final String PLUGIN_ID = "com.android.ide.eclipse.adt.tests";
+
+    // The shared instance
+    private static AndroidTestPlugin sPlugin;
+
+    /**
+     * The constructor
+     */
+    public AndroidTestPlugin() {
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+     */
+    @Override
+    public void start(BundleContext context) throws Exception {
+        super.start(context);
+        sPlugin = this;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+     */
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        sPlugin = null;
+        super.stop(context);
+    }
+
+    /**
+     * Returns the shared instance
+     * 
+     * @return the shared instance
+     */
+    public static AndroidTestPlugin getDefault() {
+        return sPlugin;
+    }
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/EclipseTestCollector.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/EclipseTestCollector.java
new file mode 100644
index 0000000..29538bb
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/EclipseTestCollector.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License"); you
+ * may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ * 
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.ide.eclipse.tests;
+
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.eclipse.core.runtime.Plugin;
+
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.logging.Logger;
+
+/**
+ * Class for collecting all test cases in an eclipse plugin
+ * 
+ */
+public class EclipseTestCollector {
+
+    private static final Logger sLogger = Logger.getLogger(EclipseTestCollector.class.getName());
+    
+    /**
+     * Constructor
+     */
+    public EclipseTestCollector() {
+        
+    }
+
+    /**
+     * Searches through given plugin, adding all TestCase classes to given suite
+     * @param suite - TestSuite to add to
+     * @param plugin - Plugin to search for tests
+     * @param expectedPackage - expected package for tests. Only test classes 
+     *  that start with this package name will be added to suite
+     */
+    public void addTestCases(TestSuite suite, Plugin plugin, String expectedPackage) {
+        if (plugin != null) {
+            Enumeration entries = plugin.getBundle().findEntries("/", "*.class", true);
+    
+            while (entries.hasMoreElements()) {
+                URL entry = (URL)entries.nextElement();
+                String filePath = entry.getPath().replace(".class", "");
+                try {
+                  Class testClass = getClass(filePath, expectedPackage);
+                  if (isTestClass(testClass)) {
+                      suite.addTestSuite(testClass);
+                  }
+                } 
+                catch (ClassNotFoundException e) {
+                  // ignore, this is not the class we're looking for
+                  //sLogger.log(Level.INFO, "Could not load class " + filePath);
+              }
+            }
+        }
+    }
+    
+    /**
+     * Returns true if given class shouk\ld be added to suite
+     * @param testClass
+     * @return
+     */
+    protected boolean isTestClass(Class testClass) {
+        return TestCase.class.isAssignableFrom(testClass) &&
+          Modifier.isPublic(testClass.getModifiers()) &&
+          hasPublicConstructor(testClass);
+    }
+    
+    /**
+     * Returns true if given class has a public constructor
+     * @param testClass
+     * @return
+     */
+    protected boolean hasPublicConstructor(Class testClass) {
+        try {
+            TestSuite.getTestConstructor(testClass);
+        } catch(NoSuchMethodException e) {
+            return false;
+        }
+        return true;
+    }
+    
+    /**
+     * Load the class given by the plugin aka bundle file path
+     * @param filePath - path of class in bundle
+     * @param expectedPackage - expected package of class
+     * @return
+     * @throws ClassNotFoundException
+     */
+    protected Class getClass(String filePath, String expectedPackage) throws ClassNotFoundException {
+        String dotPath = filePath.replace('/', '.');
+        // remove the output folders, by finding where package name starts
+        int index = dotPath.indexOf(expectedPackage);
+        if (index == -1) {
+            throw new ClassNotFoundException();
+        }
+        String packagePath = dotPath.substring(index);
+        return Class.forName(packagePath);   
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTestCase.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTestCase.java
new file mode 100644
index 0000000..63f17ab
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTestCase.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.tests;
+
+import junit.framework.TestCase;
+
+/**
+ * Generic superclass for Eclipse Android functional test cases, that provides 
+ * common facilities
+ */
+public class FuncTestCase extends TestCase {
+
+    private String mOsSdkLocation;
+
+    /**
+     * Constructor
+     * 
+     * @throws IllegalArgumentException if environment variable "sdk_home" is
+     *         not set
+     */
+    protected FuncTestCase() {
+        mOsSdkLocation = System.getProperty("sdk_home");
+        if (mOsSdkLocation == null || mOsSdkLocation.length() < 1) {
+            throw new IllegalArgumentException(
+                    "Environment variable sdk_home is not set");
+        }
+    }
+
+    /**
+     * Returns the absolute file system path of the Android SDK location to use
+     * for this test
+     */
+    protected String getOsSdkLocation() {
+        return mOsSdkLocation;
+    }
+
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTests.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTests.java
new file mode 100644
index 0000000..08405e8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/FuncTests.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License"); you
+ * may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ * 
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.ide.eclipse.tests;
+
+import com.android.ide.eclipse.tests.functests.sampleProjects.SampleProjectTest;
+
+import junit.framework.TestSuite;
+
+/**
+ * Container TestSuite for all eclipse tests to be run
+ */
+
+public class FuncTests extends TestSuite {
+
+    static final String FUNC_TEST_PACKAGE = "com.android.ide.eclipse.tests.functests";
+
+    public FuncTests() {
+        
+    }
+    
+    /**
+     * Returns a suite of test cases to be run.
+     * Needed for JUnit3 compliant command line test runner
+     */
+    public static TestSuite suite() {
+        TestSuite suite = new TestSuite();
+        
+        suite.addTestSuite(SampleProjectTest.class);
+        
+        return suite;
+    }
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.java
new file mode 100644
index 0000000..ac928db
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/UnitTests.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.tests;
+
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Container TestSuite for all eclipse unit tests to be run
+ * 
+ * Uses Eclipse OSGI to find and then run all junit.junit.framework.Tests in 
+ * this plugin, excluding tests in the FuncTests.FUNC_TEST_PACKAGE package
+ * 
+ * Since it uses Eclipse OSGI, it must be run in a Eclipse plugin environment
+ * i.e. from Eclipse workbench, this suite must be run using the 
+ * "JUnit Plug-in Test" launch configuration as opposed to as a "JUnit Test"  
+ * 
+ */                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
+public class UnitTests {
+    private static final String TEST_PACKAGE = "com.android.ide.eclipse";
+    
+    public static Test suite() {
+        TestSuite suite = new TestSuite();
+        
+        UnitTestCollector collector = new UnitTestCollector();
+        collector.addTestCases(suite, AndroidTestPlugin.getDefault(), TEST_PACKAGE);
+        return suite;
+    }
+    
+    /**
+     * Specialized test collector which will skip adding functional tests
+     */
+    private static class UnitTestCollector extends EclipseTestCollector {
+        /**
+         * Override parent class to exclude functional tests
+         */
+        @Override
+        protected boolean isTestClass(Class testClass) {
+            return super.isTestClass(testClass) &&
+            !testClass.getPackage().getName().startsWith(FuncTests.FUNC_TEST_PACKAGE);
+        }
+    }
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java
new file mode 100644
index 0000000..98817c6
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/sampleProjects/SampleProjectTest.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ * 
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License"); you
+ * may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ * 
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.android.ide.eclipse.tests.functests.sampleProjects;
+
+import com.android.ide.eclipse.adt.project.ProjectHelper;
+import com.android.ide.eclipse.adt.wizards.newproject.StubSampleProjectWizard;
+import com.android.ide.eclipse.tests.FuncTestCase;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.swt.widgets.Display;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Test case that verifies all SDK sample projects can be imported, built in
+ * Eclipse
+ * 
+ * TODO: add support for deploying apps onto emulator and verifying successful
+ * execution there
+ * 
+ */
+public class SampleProjectTest extends FuncTestCase {
+    
+    private static final Logger sLogger = Logger.getLogger(SampleProjectTest.class.getName());
+
+    /**
+     * Tests the sample project with the given name
+     * 
+     * @param name - name of sample project to test
+     */
+    protected void doTestSampleProject(String name) {
+        try {
+
+            StubSampleProjectWizard newProjCreator = new StubSampleProjectWizard(
+                    name, getOsSdkLocation());
+            newProjCreator.init(null, null);
+            newProjCreator.performFinish();
+
+            IProject iproject = validateProjectExists(name);
+
+            validateNoProblems(iproject);
+
+        } 
+        catch (CoreException e) {
+            fail("Unexpected exception when creating sample project: " + e.toString());
+        }
+    }
+
+    public void testApiDemos() {
+        doTestSampleProject("ApiDemos");
+    }
+
+    public void testHelloActivity() {
+        doTestSampleProject("HelloActivity");
+    }
+
+    public void testLunarLander() {
+        doTestSampleProject("LunarLander");
+    }
+
+    public void testNotePad() {
+        doTestSampleProject("NotePad");
+    }
+
+    public void testSkeletonApp() {
+        doTestSampleProject("SkeletonApp");
+    }
+
+    public void testSnake() {
+        doTestSampleProject("Snake");
+    }
+
+    private IProject validateProjectExists(String name) {
+        IProject iproject = getIProject(name);
+        assertTrue(iproject.exists());
+        assertTrue(iproject.isOpen());
+        return iproject;
+    }
+
+    private IProject getIProject(String name) {
+        IProject iproject = ResourcesPlugin.getWorkspace().getRoot()
+                .getProject(name);
+        return iproject;
+    }
+
+    private void validateNoProblems(IProject iproject) throws CoreException {
+        waitForBuild(iproject);
+        assertFalse(ProjectHelper.hasError(iproject, true));
+    }
+
+
+    /**
+     * Waits for build to complete.
+     * 
+     * @param iproject
+     */
+    private void waitForBuild(final IProject iproject) {
+       
+        final BuiltProjectDeltaVisitor deltaVisitor = new BuiltProjectDeltaVisitor(iproject);
+        IResourceChangeListener newBuildListener = new IResourceChangeListener() {
+
+            public void resourceChanged(IResourceChangeEvent event) {
+                try {
+                    event.getDelta().accept(deltaVisitor);
+                }
+                catch (CoreException e) {
+                    fail();
+                }
+            }
+            
+        };
+        iproject.getWorkspace().addResourceChangeListener(newBuildListener, 
+          IResourceChangeEvent.POST_BUILD);
+
+        // poll build listener to determine when build is done
+        // loop max of 1200 times * 50 ms = 60 seconds
+        final int maxWait = 1200;
+        for (int i=0; i < maxWait; i++) {
+            if (deltaVisitor.isProjectBuilt()) {
+                return;
+            }
+            try {
+                Thread.sleep(50);
+            }
+            catch (InterruptedException e) {
+                
+            }
+           if (Display.getCurrent() != null) {
+               Display.getCurrent().readAndDispatch();
+           }
+        }
+        
+        sLogger.log(Level.SEVERE, "expected build event never happened?");
+        fail("expected build event never happened for " + iproject.getName());
+
+    }
+    
+    /**
+     * Scans a given IResourceDelta looking for a "build event" change for given IProject
+     * 
+     */
+    private class BuiltProjectDeltaVisitor implements IResourceDeltaVisitor {
+
+        private IProject mIProject;
+        private boolean  mIsBuilt;
+        
+        public BuiltProjectDeltaVisitor(IProject iproject) {
+            mIProject = iproject;
+            mIsBuilt = false;
+        }
+        
+        public boolean visit(IResourceDelta delta) {
+            if (mIProject.equals(delta.getResource())) {
+                setBuilt(true);
+                return false;
+            }
+            return true;
+        }
+        
+        private synchronized void setBuilt(boolean b) {
+            mIsBuilt = b;
+        }
+
+        public synchronized boolean isProjectBuilt() {
+            return mIsBuilt;
+        }
+        
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/test.xml b/tools/eclipse/plugins/com.android.ide.eclipse.tests/test.xml
new file mode 100644
index 0000000..792ebc2
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/test.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- test launcher file for Android Eclipse functional tests -->
+<project name="testsuite" default="run" basedir="."> 
+    <!--The following properties should be passed into this script, set to some default value for now -->
+    <property name="eclipse.home" value="/opt/eclipse" />
+    <property name="sdk_home" value="/tmp/sdk" />
+    <property name="eclipse_test" value="${eclipse.home}/plugins/org.eclipse.test_3.2.0" />
+	
+    <!-- eclipse scripts use an annoying mixture of eclipse-home and eclipse.home -->
+    <!-- lets define both...-->
+    <property name="eclipse-home" value="${eclipse.home}" />
+    <property name="test-folder" value="${eclipse.home}/test_folder" />
+        
+    <!-- sets the properties eclipse.home, and library-file -->
+    <property name="plugin-name" value="com.android.ide.eclipse.tests" />
+    <property name="library-file" value="${eclipse_test}/library.xml" />
+
+    <!-- location of adt preference file (within workspace) -->
+    <property name="prefs_path" value="${test-folder}/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.android.ide.eclipse.adt.prefs" />
+    <!-- location of pref template file relative to this file -->
+
+    <property name="prefs_template" value="prefs.template" />
+
+    <!-- This target holds all initialization code that needs to be done for -->
+    <!-- all tests that are to be run.         -->
+    <target name="init">
+        <tstamp />
+        <echo message="eclipse.home:  ${eclipse.home}" />
+        <echo message="libfile:  ${library-file}" />
+        
+        <!-- delete test eclipse workspace -->
+        <delete dir="${test-folder}" quiet="true" />
+    	
+    	<!-- delete test results dir -->
+    	<delete dir="${eclipse.home}/results" quiet="true" />
+
+        <!-- Copy a preference file into the test workspace. -->
+        <!-- This is done to ensure Android SDK preference is set on startup -->
+        <copy file="${prefs_template}" tofile="${prefs_path}" />
+        <!-- replace sdk path placeholder token with actual sdk path -->
+        <replace file="${prefs_path}" token="sdk_home" value="${sdk_home}" />
+        
+        <!-- if this is on windows, escape the drive and file separators -->
+        <replace file="${prefs_path}" token="\" value="\\" />
+        <replace file="${prefs_path}" token=":" value="\:" />
+    </target>
+
+    <!-- This target defines the tests that need to be run. -->
+    <target name="suite">
+        <!-- launch as ui-test ie as a test which needs Eclipse workbench -->
+        <ant target="ui-test" antfile="${library-file}" dir="${eclipse.home}">
+            <property name="data-dir" value="${test-folder}" />
+            <property name="plugin-name" value="${plugin-name}" />
+            <property name="classname" value="com.android.ide.eclipse.tests.FuncTests" />
+            <!-- pass extra vm arg to set sdk_home env variable -->
+            <property name="extraVMargs" value="-Dsdk_home=${sdk_home}" />
+        </ant>
+    </target>
+
+    <!-- This target holds code to cleanup the testing environment after -->
+    <!-- after all of the tests have been run. You can use this target to -->
+    <!-- delete temporary files that have been created. -->
+    <target name="cleanup">
+    </target>
+
+    <!-- This target runs the test suite. Any actions that need to happen -->
+    <!-- after all the tests have been run should go here. -->
+    <target name="run" depends="init,suite,cleanup">
+        <ant target="collect" antfile="${library-file}" dir="${eclipse.home}/results">
+            <property name="includes" value="com*.xml" />
+            <property name="output-file" value="${plugin-name}.xml" />
+        </ant>
+    </target>
+</project>
+
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittest.xml b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittest.xml
new file mode 100644
index 0000000..83e00ec
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittest.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- test launcher file for Android Eclipse unit tests -->
+<project name="testsuite" default="run" basedir="."> 
+    <!--The following properties should be passed into this script, set to some default value for now -->
+    <property name="eclipse.home" value="/opt/eclipse" />
+    <property name="eclipse_test" value="${eclipse.home}/plugins/org.eclipse.test_3.2.0" />
+
+    <!-- eclipse scripts use an annoying mixture of eclipse-home and eclipse.home -->
+    <!-- lets define both...-->
+    <property name="eclipse-home" value="${eclipse.home}" />
+    <property name="test-folder" value="${eclipse.home}/unittest_ws" />
+        
+    <!-- sets the properties eclipse.home, and library-file -->
+    <property name="plugin-name" value="com.android.ide.eclipse.tests" />
+    <property name="library-file" value="${eclipse_test}/library.xml" />
+	
+    <!-- This target holds all initialization code that needs to be done for -->
+    <!-- all tests that are to be run.         -->
+    <target name="init">
+    	<ant antfile="test.xml" target="init">
+    		<property name="test-folder" value="${test-folder}" />
+        </ant>
+    </target>
+
+    <!-- This target defines the tests that need to be run. -->
+    <target name="suite">
+        <!-- need to launch as ui-test since all ADT plugins depend on ui-->
+    	<!-- otherwise other plugins will not load -->
+        <ant target="ui-test" antfile="${library-file}" dir="${eclipse.home}">
+            <property name="data-dir" value="${test-folder}" />
+            <property name="plugin-name" value="${plugin-name}" />
+            <property name="classname" value="com.android.ide.eclipse.tests.UnitTests" />
+            <!-- pass extra vm arg to set test_data env variable -->
+            <property name="extraVMargs" value="-Dtest_data=${test_data}" />
+        </ant>
+    </target>
+
+    <!-- This target holds code to cleanup the testing environment after -->
+    <!-- after all of the tests have been run. You can use this target to -->
+    <!-- delete temporary files that have been created. -->
+    <target name="cleanup">
+    </target>
+
+    <!-- This target runs the test suite. Any actions that need to happen -->
+    <!-- after all the tests have been run should go here. -->
+    <target name="run" depends="init,suite,cleanup">
+        <ant target="collect" antfile="${library-file}" dir="${eclipse.home}/results">
+            <property name="includes" value="com*.xml" />
+            <property name="output-file" value="${plugin-name}.xml" />
+        </ant>
+    </target>
+</project>
+
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/build/BaseBuilderTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/build/BaseBuilderTest.java
new file mode 100644
index 0000000..0860e40
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/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.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/project/ProjectHelperTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/project/ProjectHelperTest.java
new file mode 100644
index 0000000..8c52d81
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/project/ProjectHelperTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 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
new file mode 100644
index 0000000..8af7e02
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/AndroidJarLoaderTest.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.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
new file mode 100644
index 0000000..cedf4d4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/LayoutParamsParserTest.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.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/AndroidManifestHelperTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/project/AndroidManifestHelperTest.java
new file mode 100644
index 0000000..6604264
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/project/AndroidManifestHelperTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+public class AndroidManifestHelperTest extends TestCase {
+    private File mFile;
+    private AndroidManifestHelper mManifest;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mFile = File.createTempFile("androidManifest", "xml");  //$NON-NLS-1$ //$NON-NLS-2$
+        assertNotNull(mFile);
+
+        FileWriter fw = new FileWriter(mFile);
+        fw.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");  //$NON-NLS-1$
+        fw.write("<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n");  //$NON-NLS-1$
+        fw.write("          package=\"com.android.testapp\">\n");  //$NON-NLS-1$
+        fw.write("  <application android:icon=\"@drawable/icon\">\n");  //$NON-NLS-1$
+        fw.write("    <activity android:name=\".MainActivity\" android:label=\"@string/app_name\">\n");  //$NON-NLS-1$
+        fw.write("      <intent-filter>\n");  //$NON-NLS-1$
+        fw.write("        <action android:name=\"android.intent.action.MAIN\" />\n");  //$NON-NLS-1$
+        fw.write("          <category android:name=\"android.intent.category.LAUNCHER\" />\"\n");  //$NON-NLS-1$
+        fw.write("          <category android:name=\"android.intent.category.DEFAULT\" />\n");  //$NON-NLS-1$
+        fw.write("      </intent-filter>\n");  //$NON-NLS-1$
+        fw.write("    </activity>\n");  //$NON-NLS-1$
+        fw.write("    <activity android:name=\".OptionsActivity\" android:label=\"@string/options\"\n");  //$NON-NLS-1$
+        fw.write("              android:theme=\"@style/Theme.Floating\">\n");  //$NON-NLS-1$
+        fw.write("      <intent-filter>\n");  //$NON-NLS-1$
+        fw.write("        <action android:name=\"com.android.mandelbrot.action.EDIT_OPTIONS\" />\n");  //$NON-NLS-1$
+        fw.write("        <category android:name=\"android.intent.category.PREFERENCE_CATEGORY\" />\n");  //$NON-NLS-1$
+        fw.write("      </intent-filter>\n");  //$NON-NLS-1$
+        fw.write("    </activity>\n");  //$NON-NLS-1$
+        fw.write("    <activity android:name=\".InfoActivity\" android:label=\"@string/options\"\n");  //$NON-NLS-1$
+        fw.write("             android:theme=\"@style/Theme.Floating\">\n");  //$NON-NLS-1$
+        fw.write("      <intent-filter>\n");  //$NON-NLS-1$
+        fw.write("        <action android:name=\"com.android.mandelbrot.action.DISPLAY_INFO\" />\n");  //$NON-NLS-1$
+        fw.write("      </intent-filter>\n");  //$NON-NLS-1$
+        fw.write("    </activity>\n");  //$NON-NLS-1$
+        fw.write("  </application>\n");  //$NON-NLS-1$
+        fw.write("</manifest>\n");  //$NON-NLS-1$
+        fw.flush();
+        fw.close();
+
+        mManifest = new AndroidManifestHelper(mFile.getAbsolutePath());
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        assertTrue(mFile.delete());
+        super.tearDown();
+    }
+
+    public void testExists() {
+        assertTrue(mManifest.exists());
+    }
+
+    public void testNotExists() throws IOException {
+        File f = File.createTempFile("androidManifest2", "xml");  //$NON-NLS-1$ //$NON-NLS-2$
+        assertTrue(f.delete());
+        AndroidManifestHelper manifest = new AndroidManifestHelper(f.getAbsolutePath());
+        assertFalse(manifest.exists());
+    }
+
+    public void testGetPackageName() {
+        assertEquals("com.android.testapp", mManifest.getPackageName());
+    }
+
+    public void testGetActivityName() {
+        assertEquals("", mManifest.getActivityName(0));  //$NON-NLS-1$
+        assertEquals(".MainActivity", mManifest.getActivityName(1));  //$NON-NLS-1$
+        assertEquals(".OptionsActivity", mManifest.getActivityName(2));  //$NON-NLS-1$
+        assertEquals(".InfoActivity", mManifest.getActivityName(3));  //$NON-NLS-1$
+        assertEquals("", mManifest.getActivityName(4));  //$NON-NLS-1$
+    }
+
+}
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
new file mode 100644
index 0000000..8338453
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/resources/AttrsXmlParserTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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
new file mode 100644
index 0000000..69c3ed8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/descriptors/DescriptorsUtilsTest.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.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
new file mode 100644
index 0000000..b0deda0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/layout/UiElementPullParserTest.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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
new file mode 100644
index 0000000..e75d9ef
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..b1f089b
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..d766af7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..4a9dbbd
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/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.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
new file mode 100644
index 0000000..bedaa0d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/CountryCodeQualifierTest.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.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
new file mode 100644
index 0000000..e15434e
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/KeyboardStateQualifierTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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
new file mode 100644
index 0000000..d00972f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/LanguageQualifierTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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
new file mode 100644
index 0000000..d672f1f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/NavigationMethodQualifierTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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
new file mode 100644
index 0000000..4567dff
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/NetworkCodeQualifierTest.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.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
new file mode 100644
index 0000000..2c4cd2f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/PixelDensityQualifierTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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
new file mode 100644
index 0000000..8a9e6f8
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/RegionQualifierTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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
new file mode 100644
index 0000000..681d4e0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/ScreenDimensionQualifierTest.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.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
new file mode 100644
index 0000000..28f9961
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/ScreenOrientationQualifierTest.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.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
new file mode 100644
index 0000000..28f7871
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TextInputMethodQualifierTest.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.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
new file mode 100644
index 0000000..9a788ad
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TouchScreenQualifierTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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
new file mode 100644
index 0000000..25a86c3
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/ConfigMatchTest.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 java.util.ArrayList;
+
+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;
+
+    @SuppressWarnings("unchecked")
+    @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
new file mode 100644
index 0000000..6a555a4
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/QualifierListTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY 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 java.util.ArrayList;
+
+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;
+    }
+    
+    @SuppressWarnings("unchecked")
+    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/mock/ClasspathEntryMock.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/ClasspathEntryMock.java
new file mode 100644
index 0000000..010aadf
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/ClasspathEntryMock.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.mock;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jdt.core.IAccessRule;
+import org.eclipse.jdt.core.IClasspathAttribute;
+import org.eclipse.jdt.core.IClasspathEntry;
+
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
+
+public class ClasspathEntryMock implements IClasspathEntry {
+
+    private int mKind;
+    private IPath mPath;
+
+    public ClasspathEntryMock(IPath path, int kind) {
+        mPath = path;
+        mKind = kind;
+    }
+    
+    public int getEntryKind() {
+        return mKind;
+    }
+    
+    public IPath getPath() {
+        return mPath;
+    }
+    
+    // -------- UNIMPLEMENTED METHODS ----------------
+
+    public boolean combineAccessRules() {
+        throw new NotImplementedException();
+    }
+
+    public IAccessRule[] getAccessRules() {
+        throw new NotImplementedException();
+    }
+
+    public int getContentKind() {
+        throw new NotImplementedException();
+    }
+
+    public IPath[] getExclusionPatterns() {
+        throw new NotImplementedException();
+    }
+
+    public IClasspathAttribute[] getExtraAttributes() {
+        throw new NotImplementedException();
+    }
+
+    public IPath[] getInclusionPatterns() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getOutputLocation() {
+        throw new NotImplementedException();
+    }
+
+    public IClasspathEntry getResolvedEntry() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getSourceAttachmentPath() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getSourceAttachmentRootPath() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isExported() {
+        throw new NotImplementedException();
+    }
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/FileMock.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/FileMock.java
new file mode 100644
index 0000000..a95286c
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/FileMock.java
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.mock;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFileState;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourceAttributes;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.content.IContentDescription;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.net.URI;
+import java.util.Map;
+
+/**
+ * Mock implementation of {@link IFile}.
+ * <p/>Supported methods:
+ * <ul>
+ * </ul>
+ */
+public class FileMock implements IFile {
+
+    private String mName;
+
+    public FileMock(String name) {
+        mName = name;
+    }
+
+    // -------- MOCKED METHODS ----------------
+
+    public String getName() {
+        return mName;
+    }
+    
+    // -------- UNIMPLEMENTED METHODS ----------------
+
+    public void appendContents(InputStream source, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void appendContents(InputStream source, boolean force, boolean keepHistory,
+            IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void create(InputStream source, boolean force, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void create(InputStream source, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void createLink(IPath localLocation, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void createLink(URI location, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void delete(boolean force, boolean keepHistory, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public String getCharset() throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public String getCharset(boolean checkImplicit) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public String getCharsetFor(Reader reader) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IContentDescription getContentDescription() throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public InputStream getContents() throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public InputStream getContents(boolean force) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public int getEncoding() throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IPath getFullPath() {
+        throw new NotImplementedException();
+    }
+
+    public IFileState[] getHistory(IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public boolean isReadOnly() {
+        throw new NotImplementedException();
+    }
+
+    public void move(IPath destination, boolean force, boolean keepHistory, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setCharset(String newCharset) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setCharset(String newCharset, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setContents(InputStream source, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setContents(IFileState source, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setContents(InputStream source, boolean force, boolean keepHistory,
+            IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setContents(IFileState source, boolean force, boolean keepHistory,
+            IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void accept(IResourceVisitor visitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void accept(IResourceProxyVisitor visitor, int memberFlags) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void accept(IResourceVisitor visitor, int depth, boolean includePhantoms)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void accept(IResourceVisitor visitor, int depth, int memberFlags) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void clearHistory(IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void copy(IPath destination, boolean force, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void copy(IPath destination, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void copy(IProjectDescription description, boolean force, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void copy(IProjectDescription description, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IMarker createMarker(String type) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IResourceProxy createProxy() {
+        throw new NotImplementedException();
+    }
+
+    public void delete(boolean force, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void delete(int updateFlags, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void deleteMarkers(String type, boolean includeSubtypes, int depth) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public boolean exists() {
+        throw new NotImplementedException();
+    }
+
+    public IMarker findMarker(long id) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IMarker[] findMarkers(String type, boolean includeSubtypes, int depth)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public int findMaxProblemSeverity(String type, boolean includeSubtypes, int depth)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public String getFileExtension() {
+        throw new NotImplementedException();
+    }
+
+    public long getLocalTimeStamp() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getLocation() {
+        return new Path(mName);
+    }
+
+    public URI getLocationURI() {
+        throw new NotImplementedException();
+    }
+
+    public IMarker getMarker(long id) {
+        throw new NotImplementedException();
+    }
+
+    public long getModificationStamp() {
+        throw new NotImplementedException();
+    }
+
+    public IContainer getParent() {
+        throw new NotImplementedException();
+    }
+
+    public String getPersistentProperty(QualifiedName key) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IProject getProject() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getProjectRelativePath() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getRawLocation() {
+        throw new NotImplementedException();
+    }
+
+    public URI getRawLocationURI() {
+        throw new NotImplementedException();
+    }
+
+    public ResourceAttributes getResourceAttributes() {
+        throw new NotImplementedException();
+    }
+
+    public Object getSessionProperty(QualifiedName key) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public int getType() {
+        throw new NotImplementedException();
+    }
+
+    public IWorkspace getWorkspace() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isAccessible() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isDerived() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isLinked() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isLinked(int options) {
+        throw new NotImplementedException();
+    }
+
+    public boolean isLocal(int depth) {
+        throw new NotImplementedException();
+    }
+
+    public boolean isPhantom() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isSynchronized(int depth) {
+        throw new NotImplementedException();
+    }
+
+    public boolean isTeamPrivateMember() {
+        throw new NotImplementedException();
+    }
+
+    public void move(IPath destination, boolean force, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void move(IPath destination, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void move(IProjectDescription description, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void move(IProjectDescription description, boolean force, boolean keepHistory,
+            IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void refreshLocal(int depth, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void revertModificationStamp(long value) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setDerived(boolean isDerived) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setLocal(boolean flag, int depth, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public long setLocalTimeStamp(long value) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setPersistentProperty(QualifiedName key, String value) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setReadOnly(boolean readOnly) {
+        throw new NotImplementedException();
+    }
+
+    public void setResourceAttributes(ResourceAttributes attributes) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setSessionProperty(QualifiedName key, Object value) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setTeamPrivateMember(boolean isTeamPrivate) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void touch(IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    @SuppressWarnings("unchecked")
+    public Object getAdapter(Class adapter) {
+        throw new NotImplementedException();
+    }
+
+    public boolean contains(ISchedulingRule rule) {
+        throw new NotImplementedException();
+    }
+
+    public boolean isConflicting(ISchedulingRule rule) {
+        throw new NotImplementedException();
+    }
+
+	public Map getPersistentProperties() throws CoreException {
+        throw new NotImplementedException();
+	}
+
+	public Map getSessionProperties() throws CoreException {
+        throw new NotImplementedException();
+	}
+
+	public boolean isDerived(int options) {
+        throw new NotImplementedException();
+	}
+
+	public boolean isHidden() {
+        throw new NotImplementedException();
+	}
+
+	public void setHidden(boolean isHidden) throws CoreException {
+        throw new NotImplementedException();
+	}
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/FolderMock.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/FolderMock.java
new file mode 100644
index 0000000..223deb0
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/FolderMock.java
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.mock;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourceAttributes;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
+
+import java.net.URI;
+import java.util.Map;
+
+/**
+ * Mock implementation of {@link IFolder}.
+ * <p/>Supported methods:
+ * <ul>
+ * <li>{@link #getName()}</li>
+ * <li>{@link #members()}</li>
+ * </ul>
+ */
+public final class FolderMock implements IFolder {
+    
+    private String mName;
+    private IResource[] mMembers;
+    
+    public FolderMock(String name) {
+        mName = name;
+        mMembers = new IResource[0];
+    }
+    
+    public FolderMock(String name, IResource[] members) {
+        mName = name;
+        mMembers = members;
+    }
+    
+    // -------- MOCKED METHODS ----------------
+    
+    public String getName() {
+        return mName;
+    }
+    
+    public IResource[] members() throws CoreException {
+        return mMembers;
+    }
+
+    // -------- UNIMPLEMENTED METHODS ----------------
+
+    public void create(boolean force, boolean local, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void create(int updateFlags, boolean local, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void createLink(IPath localLocation, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void createLink(URI location, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void delete(boolean force, boolean keepHistory, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IFile getFile(String name) {
+        throw new NotImplementedException();
+    }
+
+    public IFolder getFolder(String name) {
+        throw new NotImplementedException();
+    }
+
+    public void move(IPath destination, boolean force, boolean keepHistory, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public boolean exists(IPath path) {
+        throw new NotImplementedException();
+    }
+
+    public IFile[] findDeletedMembersWithHistory(int depth, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IResource findMember(String name) {
+        throw new NotImplementedException();
+    }
+
+    public IResource findMember(IPath path) {
+        throw new NotImplementedException();
+    }
+
+    public IResource findMember(String name, boolean includePhantoms) {
+        throw new NotImplementedException();
+    }
+
+    public IResource findMember(IPath path, boolean includePhantoms) {
+        throw new NotImplementedException();
+    }
+
+    public String getDefaultCharset() throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public String getDefaultCharset(boolean checkImplicit) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IFile getFile(IPath path) {
+        throw new NotImplementedException();
+    }
+
+    public IFolder getFolder(IPath path) {
+        throw new NotImplementedException();
+    }
+
+    public IResource[] members(boolean includePhantoms) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IResource[] members(int memberFlags) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setDefaultCharset(String charset) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setDefaultCharset(String charset, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void accept(IResourceVisitor visitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void accept(IResourceProxyVisitor visitor, int memberFlags) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void accept(IResourceVisitor visitor, int depth, boolean includePhantoms)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void accept(IResourceVisitor visitor, int depth, int memberFlags) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void clearHistory(IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void copy(IPath destination, boolean force, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void copy(IPath destination, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void copy(IProjectDescription description, boolean force, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void copy(IProjectDescription description, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IMarker createMarker(String type) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IResourceProxy createProxy() {
+        throw new NotImplementedException();
+    }
+
+    public void delete(boolean force, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void delete(int updateFlags, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void deleteMarkers(String type, boolean includeSubtypes, int depth) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public boolean exists() {
+        throw new NotImplementedException();
+    }
+
+    public IMarker findMarker(long id) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IMarker[] findMarkers(String type, boolean includeSubtypes, int depth)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public int findMaxProblemSeverity(String type, boolean includeSubtypes, int depth)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public String getFileExtension() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getFullPath() {
+        throw new NotImplementedException();
+    }
+
+    public long getLocalTimeStamp() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getLocation() {
+        throw new NotImplementedException();
+    }
+
+    public URI getLocationURI() {
+        throw new NotImplementedException();
+    }
+
+    public IMarker getMarker(long id) {
+        throw new NotImplementedException();
+    }
+
+    public long getModificationStamp() {
+        throw new NotImplementedException();
+    }
+
+    public IContainer getParent() {
+        throw new NotImplementedException();
+    }
+
+    public String getPersistentProperty(QualifiedName key) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IProject getProject() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getProjectRelativePath() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getRawLocation() {
+        throw new NotImplementedException();
+    }
+
+    public URI getRawLocationURI() {
+        throw new NotImplementedException();
+    }
+
+    public ResourceAttributes getResourceAttributes() {
+        throw new NotImplementedException();
+    }
+
+    public Object getSessionProperty(QualifiedName key) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public int getType() {
+        throw new NotImplementedException();
+    }
+
+    public IWorkspace getWorkspace() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isAccessible() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isDerived() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isLinked() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isLinked(int options) {
+        throw new NotImplementedException();
+    }
+
+    public boolean isLocal(int depth) {
+        throw new NotImplementedException();
+    }
+
+    public boolean isPhantom() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isReadOnly() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isSynchronized(int depth) {
+        throw new NotImplementedException();
+    }
+
+    public boolean isTeamPrivateMember() {
+        throw new NotImplementedException();
+    }
+
+    public void move(IPath destination, boolean force, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void move(IPath destination, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void move(IProjectDescription description, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void move(IProjectDescription description, boolean force, boolean keepHistory,
+            IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void refreshLocal(int depth, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void revertModificationStamp(long value) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setDerived(boolean isDerived) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setLocal(boolean flag, int depth, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public long setLocalTimeStamp(long value) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setPersistentProperty(QualifiedName key, String value) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setReadOnly(boolean readOnly) {
+        throw new NotImplementedException();
+    }
+
+    public void setResourceAttributes(ResourceAttributes attributes) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setSessionProperty(QualifiedName key, Object value) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setTeamPrivateMember(boolean isTeamPrivate) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void touch(IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    @SuppressWarnings("unchecked")
+    public Object getAdapter(Class adapter) {
+        throw new NotImplementedException();
+    }
+
+    public boolean contains(ISchedulingRule rule) {
+        throw new NotImplementedException();
+    }
+
+    public boolean isConflicting(ISchedulingRule rule) {
+        throw new NotImplementedException();
+    }
+
+	public Map getPersistentProperties() throws CoreException {
+        throw new NotImplementedException();
+	}
+
+	public Map getSessionProperties() throws CoreException {
+        throw new NotImplementedException();
+	}
+
+	public boolean isDerived(int options) {
+        throw new NotImplementedException();
+	}
+
+	public boolean isHidden() {
+        throw new NotImplementedException();
+	}
+
+	public void setHidden(boolean isHidden) throws CoreException {
+        throw new NotImplementedException();
+	}
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/JavaProjectMock.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/JavaProjectMock.java
new file mode 100644
index 0000000..f23d2c1
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/JavaProjectMock.java
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.mock;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaModel;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IOpenable;
+import org.eclipse.jdt.core.IPackageFragment;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IRegion;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeHierarchy;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.core.eval.IEvaluationContext;
+
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
+
+import java.util.Map;
+
+public class JavaProjectMock implements IJavaProject {
+    
+    private IProject mProject;
+
+    private IClasspathEntry[] mEntries;
+    private IPath mOutputLocation;
+    private String mCompilerCompliance = "1.4"; //$NON-NLS-1
+    private String mCompilerSource = "1.4"; //$NON-NLS-1
+    private String mCompilerTarget = "1.4"; //$NON-NLS-1
+
+    public JavaProjectMock(IClasspathEntry[] entries, IPath outputLocation) {
+        mEntries = entries;
+        mOutputLocation = outputLocation;
+    }
+    
+    public IProject getProject() {
+        if (mProject == null) {
+            mProject = new ProjectMock();
+        }
+
+        return mProject;
+    }
+
+    
+    public void setRawClasspath(IClasspathEntry[] entries, IProgressMonitor monitor)
+            throws JavaModelException {
+        mEntries = entries;
+    }
+
+    public void setRawClasspath(IClasspathEntry[] entries, IPath outputLocation,
+            IProgressMonitor monitor) throws JavaModelException {
+        mEntries = entries;
+        mOutputLocation = outputLocation;
+    }
+    
+    public IClasspathEntry[] getRawClasspath() throws JavaModelException {
+        return mEntries;
+    }
+    
+    public IPath getOutputLocation() throws JavaModelException {
+        return mOutputLocation;
+    }
+    
+    public String getOption(String optionName, boolean inheritJavaCoreOptions) {
+        if (optionName.equals(JavaCore.COMPILER_COMPLIANCE)) {
+            return mCompilerCompliance;
+        } else if (optionName.equals(JavaCore.COMPILER_SOURCE)) {
+            return mCompilerSource;
+        } else if (optionName.equals(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM)) {
+            return mCompilerTarget;
+        }
+        
+        return null;
+    }
+        
+    public void setOption(String optionName, String optionValue) {
+        if (optionName.equals(JavaCore.COMPILER_COMPLIANCE)) {
+            mCompilerCompliance = optionValue;
+        } else if (optionName.equals(JavaCore.COMPILER_SOURCE)) {
+            mCompilerSource = optionValue;
+        } else if (optionName.equals(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM)) {
+            mCompilerTarget = optionValue;
+        } else {
+            throw new NotImplementedException();
+        }
+    }
+
+
+    // -------- UNIMPLEMENTED METHODS ----------------
+    
+    public IClasspathEntry decodeClasspathEntry(String encodedEntry) {
+        throw new NotImplementedException();
+    }
+
+    public String encodeClasspathEntry(IClasspathEntry classpathEntry) {
+        throw new NotImplementedException();
+    }
+
+    public IJavaElement findElement(IPath path) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IJavaElement findElement(IPath path, WorkingCopyOwner owner) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IPackageFragment findPackageFragment(IPath path) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IPackageFragmentRoot findPackageFragmentRoot(IPath path) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IPackageFragmentRoot[] findPackageFragmentRoots(IClasspathEntry entry) {
+        throw new NotImplementedException();
+    }
+
+    public IType findType(String fullyQualifiedName) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IType findType(String fullyQualifiedName, IProgressMonitor progressMonitor)
+            throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IType findType(String fullyQualifiedName, WorkingCopyOwner owner)
+            throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IType findType(String packageName, String typeQualifiedName) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IType findType(String fullyQualifiedName, WorkingCopyOwner owner,
+            IProgressMonitor progressMonitor) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IType findType(String packageName, String typeQualifiedName,
+            IProgressMonitor progressMonitor) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IType findType(String packageName, String typeQualifiedName, WorkingCopyOwner owner)
+            throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IType findType(String packageName, String typeQualifiedName, WorkingCopyOwner owner,
+            IProgressMonitor progressMonitor) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IPackageFragmentRoot[] getAllPackageFragmentRoots() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public Object[] getNonJavaResources() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    @SuppressWarnings("unchecked")
+    public Map getOptions(boolean inheritJavaCoreOptions) {
+        throw new NotImplementedException();
+    }
+
+    public IPackageFragmentRoot getPackageFragmentRoot(String jarPath) {
+        throw new NotImplementedException();
+    }
+
+    public IPackageFragmentRoot getPackageFragmentRoot(IResource resource) {
+        throw new NotImplementedException();
+    }
+
+    public IPackageFragmentRoot[] getPackageFragmentRoots() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IPackageFragmentRoot[] getPackageFragmentRoots(IClasspathEntry entry) {
+        throw new NotImplementedException();
+    }
+
+    public IPackageFragment[] getPackageFragments() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public String[] getRequiredProjectNames() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IClasspathEntry[] getResolvedClasspath(boolean ignoreUnresolvedEntry)
+            throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public boolean hasBuildState() {
+        throw new NotImplementedException();
+    }
+
+    public boolean hasClasspathCycle(IClasspathEntry[] entries) {
+        throw new NotImplementedException();
+    }
+
+    public boolean isOnClasspath(IJavaElement element) {
+        throw new NotImplementedException();
+    }
+
+    public boolean isOnClasspath(IResource resource) {
+        throw new NotImplementedException();
+    }
+
+    public IEvaluationContext newEvaluationContext() {
+        throw new NotImplementedException();
+    }
+
+    public ITypeHierarchy newTypeHierarchy(IRegion region, IProgressMonitor monitor)
+            throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public ITypeHierarchy newTypeHierarchy(IRegion region, WorkingCopyOwner owner,
+            IProgressMonitor monitor) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public ITypeHierarchy newTypeHierarchy(IType type, IRegion region, IProgressMonitor monitor)
+            throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public ITypeHierarchy newTypeHierarchy(IType type, IRegion region, WorkingCopyOwner owner,
+            IProgressMonitor monitor) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IPath readOutputLocation() {
+        throw new NotImplementedException();
+    }
+
+    public IClasspathEntry[] readRawClasspath() {
+        throw new NotImplementedException();
+    }
+
+    @SuppressWarnings("unchecked")
+    public void setOptions(Map newOptions) {
+        throw new NotImplementedException();
+    }
+
+    public void setOutputLocation(IPath path, IProgressMonitor monitor) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public void setRawClasspath(IClasspathEntry[] entries, boolean canModifyResources,
+            IProgressMonitor monitor) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public void setRawClasspath(IClasspathEntry[] entries, IPath outputLocation,
+            boolean canModifyResources, IProgressMonitor monitor) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IJavaElement[] getChildren() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public boolean hasChildren() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public boolean exists() {
+        throw new NotImplementedException();
+    }
+
+    public IJavaElement getAncestor(int ancestorType) {
+        throw new NotImplementedException();
+    }
+
+    public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IResource getCorrespondingResource() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public String getElementName() {
+        throw new NotImplementedException();
+    }
+
+    public int getElementType() {
+        throw new NotImplementedException();
+    }
+
+    public String getHandleIdentifier() {
+        throw new NotImplementedException();
+    }
+
+    public IJavaModel getJavaModel() {
+        throw new NotImplementedException();
+    }
+
+    public IJavaProject getJavaProject() {
+        throw new NotImplementedException();
+    }
+
+    public IOpenable getOpenable() {
+        throw new NotImplementedException();
+    }
+
+    public IJavaElement getParent() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getPath() {
+        throw new NotImplementedException();
+    }
+
+    public IJavaElement getPrimaryElement() {
+        throw new NotImplementedException();
+    }
+
+    public IResource getResource() {
+        throw new NotImplementedException();
+    }
+
+    public ISchedulingRule getSchedulingRule() {
+        throw new NotImplementedException();
+    }
+
+    public IResource getUnderlyingResource() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public boolean isReadOnly() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isStructureKnown() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    @SuppressWarnings("unchecked")
+    public Object getAdapter(Class adapter) {
+        throw new NotImplementedException();
+    }
+
+    public void close() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public String findRecommendedLineSeparator() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public IBuffer getBuffer() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public boolean hasUnsavedChanges() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public boolean isConsistent() throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public boolean isOpen() {
+        throw new NotImplementedException();
+    }
+
+    public void makeConsistent(IProgressMonitor progress) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public void open(IProgressMonitor progress) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+    public void save(IProgressMonitor progress, boolean force) throws JavaModelException {
+        throw new NotImplementedException();
+    }
+
+	public IJavaElement findElement(String bindingKey, WorkingCopyOwner owner)
+			throws JavaModelException {
+        throw new NotImplementedException();
+	}
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/ProjectMock.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/ProjectMock.java
new file mode 100644
index 0000000..4c409dc
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/ProjectMock.java
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.mock;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourceAttributes;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IPluginDescriptor;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.core.runtime.content.IContentTypeMatcher;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
+
+import java.net.URI;
+import java.util.Map;
+
+public class ProjectMock implements IProject {
+
+    public void build(int kind, IProgressMonitor monitor) throws CoreException {
+        // pass
+    }
+
+    @SuppressWarnings("unchecked")
+    public void build(int kind, String builderName, Map args, IProgressMonitor monitor)
+            throws CoreException {
+        // pass
+    }
+    
+    // -------- UNIMPLEMENTED METHODS ----------------
+
+
+    public void close(IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void create(IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void create(IProjectDescription description, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void delete(boolean deleteContent, boolean force, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IContentTypeMatcher getContentTypeMatcher() throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IProjectDescription getDescription() throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IFile getFile(String name) {
+        throw new NotImplementedException();
+    }
+
+    public IFolder getFolder(String name) {
+        throw new NotImplementedException();
+    }
+
+    public IProjectNature getNature(String natureId) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    @SuppressWarnings("deprecation")
+    public IPath getPluginWorkingLocation(IPluginDescriptor plugin) {
+        throw new NotImplementedException();
+    }
+
+    public IProject[] getReferencedProjects() throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IProject[] getReferencingProjects() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getWorkingLocation(String id) {
+        throw new NotImplementedException();
+    }
+
+    public boolean hasNature(String natureId) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public boolean isNatureEnabled(String natureId) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public boolean isOpen() {
+        throw new NotImplementedException();
+    }
+
+    public void move(IProjectDescription description, boolean force, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void open(IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void open(int updateFlags, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setDescription(IProjectDescription description, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setDescription(IProjectDescription description, int updateFlags,
+            IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public boolean exists(IPath path) {
+        throw new NotImplementedException();
+    }
+
+    public IFile[] findDeletedMembersWithHistory(int depth, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IResource findMember(String name) {
+        throw new NotImplementedException();
+    }
+
+    public IResource findMember(IPath path) {
+        throw new NotImplementedException();
+    }
+
+    public IResource findMember(String name, boolean includePhantoms) {
+        throw new NotImplementedException();
+    }
+
+    public IResource findMember(IPath path, boolean includePhantoms) {
+        throw new NotImplementedException();
+    }
+
+    public String getDefaultCharset() throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public String getDefaultCharset(boolean checkImplicit) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IFile getFile(IPath path) {
+        throw new NotImplementedException();
+    }
+
+    public IFolder getFolder(IPath path) {
+        throw new NotImplementedException();
+    }
+
+    public IResource[] members() throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IResource[] members(boolean includePhantoms) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IResource[] members(int memberFlags) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setDefaultCharset(String charset) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setDefaultCharset(String charset, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void accept(IResourceVisitor visitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void accept(IResourceProxyVisitor visitor, int memberFlags) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void accept(IResourceVisitor visitor, int depth, boolean includePhantoms)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void accept(IResourceVisitor visitor, int depth, int memberFlags) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void clearHistory(IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void copy(IPath destination, boolean force, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void copy(IPath destination, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void copy(IProjectDescription description, boolean force, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void copy(IProjectDescription description, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IMarker createMarker(String type) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IResourceProxy createProxy() {
+        throw new NotImplementedException();
+    }
+
+    public void delete(boolean force, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void delete(int updateFlags, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void deleteMarkers(String type, boolean includeSubtypes, int depth) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public boolean exists() {
+        throw new NotImplementedException();
+    }
+
+    public IMarker findMarker(long id) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IMarker[] findMarkers(String type, boolean includeSubtypes, int depth)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public int findMaxProblemSeverity(String type, boolean includeSubtypes, int depth)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public String getFileExtension() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getFullPath() {
+        throw new NotImplementedException();
+    }
+
+    public long getLocalTimeStamp() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getLocation() {
+        throw new NotImplementedException();
+    }
+
+    public URI getLocationURI() {
+        throw new NotImplementedException();
+    }
+
+    public IMarker getMarker(long id) {
+        throw new NotImplementedException();
+    }
+
+    public long getModificationStamp() {
+        throw new NotImplementedException();
+    }
+
+    public String getName() {
+        throw new NotImplementedException();
+    }
+
+    public IContainer getParent() {
+        throw new NotImplementedException();
+    }
+
+    public String getPersistentProperty(QualifiedName key) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public IProject getProject() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getProjectRelativePath() {
+        throw new NotImplementedException();
+    }
+
+    public IPath getRawLocation() {
+        throw new NotImplementedException();
+    }
+
+    public URI getRawLocationURI() {
+        throw new NotImplementedException();
+    }
+
+    public ResourceAttributes getResourceAttributes() {
+        throw new NotImplementedException();
+    }
+
+    public Object getSessionProperty(QualifiedName key) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public int getType() {
+        throw new NotImplementedException();
+    }
+
+    public IWorkspace getWorkspace() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isAccessible() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isDerived() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isLinked() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isLinked(int options) {
+        throw new NotImplementedException();
+    }
+
+    public boolean isLocal(int depth) {
+        throw new NotImplementedException();
+    }
+
+    public boolean isPhantom() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isReadOnly() {
+        throw new NotImplementedException();
+    }
+
+    public boolean isSynchronized(int depth) {
+        throw new NotImplementedException();
+    }
+
+    public boolean isTeamPrivateMember() {
+        throw new NotImplementedException();
+    }
+
+    public void move(IPath destination, boolean force, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void move(IPath destination, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void move(IProjectDescription description, int updateFlags, IProgressMonitor monitor)
+            throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void move(IProjectDescription description, boolean force, boolean keepHistory,
+            IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void refreshLocal(int depth, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void revertModificationStamp(long value) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setDerived(boolean isDerived) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setLocal(boolean flag, int depth, IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public long setLocalTimeStamp(long value) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setPersistentProperty(QualifiedName key, String value) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setReadOnly(boolean readOnly) {
+        throw new NotImplementedException();
+    }
+
+    public void setResourceAttributes(ResourceAttributes attributes) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setSessionProperty(QualifiedName key, Object value) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void setTeamPrivateMember(boolean isTeamPrivate) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public void touch(IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+    }
+
+    public Object getAdapter(Class adapter) {
+        throw new NotImplementedException();
+    }
+
+    public boolean contains(ISchedulingRule rule) {
+        throw new NotImplementedException();
+    }
+
+    public boolean isConflicting(ISchedulingRule rule) {
+        throw new NotImplementedException();
+    }
+
+	public void create(IProjectDescription description, int updateFlags,
+			IProgressMonitor monitor) throws CoreException {
+        throw new NotImplementedException();
+	}
+
+	public Map getPersistentProperties() throws CoreException {
+        throw new NotImplementedException();
+	}
+
+	public Map getSessionProperties() throws CoreException {
+        throw new NotImplementedException();
+	}
+
+	public boolean isDerived(int options) {
+        throw new NotImplementedException();
+	}
+
+	public boolean isHidden() {
+        throw new NotImplementedException();
+	}
+
+	public void setHidden(boolean isHidden) throws CoreException {
+        throw new NotImplementedException();
+	}
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/jar_example.jar b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/jar_example.jar
new file mode 100644
index 0000000..f95b595
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/jar_example.jar
Binary files differ
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/jar_example.jardesc b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/jar_example.jardesc
new file mode 100644
index 0000000..14cd44f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/jar_example.jardesc
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
+<jardesc>
+    <jar path="jar_example.jar"/>
+    <options buildIfNeeded="true" compress="true" descriptionLocation="/common/tests/data/jar_example.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/>
+    <storedRefactorings deprecationInfo="true" structuralOnly="false"/>
+    <selectedProjects/>
+    <manifest generateManifest="true" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true">
+        <sealing sealJar="false">
+            <packagesToSeal/>
+            <packagesToUnSeal/>
+        </sealing>
+    </manifest>
+    <selectedElements exportClassFiles="true" exportJavaFiles="false" exportOutputFolder="false">
+        <javaElement handleIdentifier="=common/tests&lt;jar.example"/>
+    </selectedElements>
+</jardesc>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml
new file mode 100644
index 0000000..aa9a1f7
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml
@@ -0,0 +1,340 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources>
+    <!-- WARNING !!! THIS IS A MOCK FILE. DO NOT USE FOR DOCUMENTATION PURPOSES.
+         This file has been trimmed down to only extract a number of interesting cases 
+         for unit tests.
+         
+         What this contains:
+         - View
+         - ViewGroup
+         - some attributes which format are defined in Theme
+         - orientation, gravity and layout_gravity defined before they are used
+         - ViewGroup_Layout
+         - ViewGroup_MarginLayout
+         - LinearLayout
+         - LinearLayout_Layout
+         - TableLayout
+         
+         Note that TableLayout does not have a TableLayout_Layout definition here
+         where these is a class TableLayout.LayoutData.
+    -->
+
+    <!-- These are the standard attributes that make up a complete theme. -->
+    <declare-styleable name="Theme">
+
+        <!-- Defines the scrollbars size. -->
+        <attr name="scrollbarSize" format="dimension" />
+
+    </declare-styleable>
+
+        
+    <!-- Standard orientation constant. -->
+    <attr name="orientation">
+        <!-- Defines an horizontal widget. -->
+        <enum name="horizontal" value="0" />
+        <!-- Defines a vertical widget. -->
+        <enum name="vertical" value="1" />
+    </attr>
+
+    <!-- Specifies how to place an object, both
+         its x and y axis, within a larger containing object. -->
+    <attr name="gravity">
+        <!-- Push object to the top of its container, not changing its size. -->
+        <flag name="top" value="0x30" />
+        <!-- Push object to the bottom of its container, not changing its size. -->
+        <flag name="bottom" value="0x50" />
+        <!-- Push object to the left of its container, not changing its size. -->
+        <flag name="left" value="0x03" />
+        <!-- Push object to the right of its container, not changing its size. -->
+        <flag name="right" value="0x05" />
+        <!-- Place object in the vertical center of its container, not changing its size. -->
+        <flag name="center_vertical" value="0x10" />
+        <!-- Grow the vertical size of the object if needed so it completely fills its container. -->
+        <flag name="fill_vertical" value="0x70" />
+        <!-- Place object in the horizontal center of its container, not changing its size. -->
+        <flag name="center_horizontal" value="0x01" />
+        <!-- Grow the horizontal size of the object if needed so it completely fills its container. -->
+        <flag name="fill_horizontal" value="0x07" />
+        <!-- Place the object in the center of its container in both the vertical and horizontal axis, not changing its size. -->
+        <flag name="center" value="0x11" />
+        <!-- Grow the horizontal and vertical size of the object if needed so it completely fills its container. -->
+        <flag name="fill" value="0x77" />
+    </attr>
+
+    <!-- Standard gravity constant that a child can supply to its parent.
+         Defines how to place an object, both
+         its x and y axis, within a larger containing object. -->
+    <attr name="layout_gravity">
+        <!-- Push object to the top of its container, not changing its size. -->
+        <flag name="top" value="0x30" />
+        <!-- Push object to the bottom of its container, not changing its size. -->
+        <flag name="bottom" value="0x50" />
+        <!-- Push object to the left of its container, not changing its size. -->
+        <flag name="left" value="0x03" />
+        <!-- Push object to the right of its container, not changing its size. -->
+        <flag name="right" value="0x05" />
+        <!-- Place object in the vertical center of its container, not changing its size. -->
+        <flag name="center_vertical" value="0x10" />
+        <!-- Grow the vertical size of the object if needed so it completely fills its container. -->
+        <flag name="fill_vertical" value="0x70" />
+        <!-- Place object in the horizontal center of its container, not changing its size. -->
+        <flag name="center_horizontal" value="0x01" />
+        <!-- Grow the horizontal size of the object if needed so it completely fills its container. -->
+        <flag name="fill_horizontal" value="0x07" />
+        <!-- Place the object in the center of its container in both the vertical and horizontal axis, not changing its size. -->
+        <flag name="center" value="0x11" />
+        <!-- Grow the horizontal and vertical size of the object if needed so it completely fills its container. -->
+        <flag name="fill" value="0x77" />
+    </attr>
+
+    <declare-styleable name="View">
+    <!-- NOTE: View does not have a javadoc. Do not place a comment BEFORE View to make sure it
+         is NOT interpreted as Javadoc -->
+    
+        <!-- Supply an identifier name for this view, to later retrieve it
+             with {@link android.view.View#findViewById View.findViewById()} or
+             {@link android.app.Activity#findViewById Activity.findViewById()}.
+             This must be a
+             resource reference; typically you set this using the
+             <code>@+</code> syntax to create a new ID resources.
+             For example: <code>android:id="@+id/my_id"</code> which
+             allows you to later retrieve the view
+             with <code>findViewById(R.id.my_id)</code>. -->
+        <attr name="id" format="reference" />
+        
+        <!-- Supply a tag for this view containing a String, to be retrieved
+             later with {@link android.view.View#getTag View.getTag()} or
+             searched for with {@link android.view.View#findViewWithTag
+             View.findViewWithTag()}.  It is generally preferable to use
+             IDs (through the android:id attribute) instead of tags because
+             they are faster and allow for compile-time type checking. -->
+        <attr name="tag" format="string" />
+        
+        <!-- The initial horizontal scroll offset, in pixels.-->
+        <attr name="scrollX" format="dimension" />
+
+        <!-- The initial vertical scroll offset, in pixels. -->
+        <attr name="scrollY" format="dimension" />
+
+        <!-- A drawable to use as the background.  This can be either a reference
+             to a full drawable resource (such as a PNG image, 9-patch,
+             XML state list description, etc), or a solid color such as "#ff000000"
+            (black). -->
+        <attr name="background" format="reference|color" />
+
+        <!-- Boolean that controls whether a view can take focus.  By default the user can not
+             move focus to a view; by setting this attribute to true the view is
+             allowed to take focus.  This value does not impact the behavior of
+             directly calling {@link android.view.View#requestFocus}, which will
+             always request focus regardless of this view.  It only impacts where
+             focus navigation will try to move focus. -->
+        <attr name="focusable" format="boolean" />
+
+        <!-- Sets the circumstances under which this view will take focus. There are
+             two choices: "weak" or "normal". The default value is "normal" for
+             any focusable views. The focus type only applies if the view
+             has been set to be focusable. -->
+        <attr name="focusType">
+            <!-- This view is focusable, but only if none of its descendants are already focused. -->
+            <enum name="normal" value="0" />
+            <!-- This view will always claim to be focusable. -->
+            <enum name="weak" value="1" />
+        </attr>
+        
+        <!-- Controls the initial visibility of the view.  -->
+        <attr name="visibility">
+            <!-- Visible on screen; the default value. -->
+            <enum name="visible" value="0" />
+            <!-- Not displayed, but taken into account during layout (space is left for it). -->
+            <enum name="invisible" value="1" />
+            <!-- Completely hidden, as if the view had not been added. -->
+            <enum name="gone" value="2" />
+        </attr>
+
+        <!-- Defines which scrollbars should be displayed on scrolling or not. -->
+        <attr name="scrollbars">
+            <!-- No scrollbar is displayed. -->
+            <flag name="none" value="0x00000000" />
+            <!-- Displays horizontal scrollbar only. -->
+            <flag name="horizontal" value="0x00000100" />
+            <!-- Displays vertical scrollbar only. -->
+            <flag name="vertical" value="0x00000200" />
+        </attr>
+
+        <!-- Sets the width of vertical scrollbars and height of horizontal scrollbars. -->
+        <attr name="scrollbarSize" />
+        
+        <!-- Text to display. (copied from TextView for the extra localization) -->
+        <attr name="text" format="string" localization="suggested" />
+        
+    </declare-styleable>
+
+    <!-- Attributes that can be used with a {@link android.view.ViewGroup} or any
+         of its subclasses.  Also see {@link #ViewGroup_Layout} for
+         attributes that this class processes in its children. -->
+    <declare-styleable name="ViewGroup">
+        <!-- Defines whether a child is limited to draw inside of its bounds or not.
+             This is useful with animations that scale the size of the children to more
+             than 100% for instance. In such a case, this property should be set to false
+             to allow the children to draw outside of their bounds. The default value of
+             this property is true. -->
+        <attr name="clipChildren" format="boolean" />
+        <!-- Defines the layout animation to use the first time the ViewGroup is laid out.
+             Layout animations can also be started manually after the first layout. -->
+        <attr name="layoutAnimation" format="reference" />
+        <!-- Defines whether a child's animation should be kept when it is over. Keeping
+             the animations is useful with animation whose final state is different from
+             the initial state of the View. This is particularly useful with animation
+             whose fillAfter property is enabled. This property is set to false by default. -->
+        <attr name="persistentDrawingCache">
+            <!-- The drawing cache is not persisted after use. -->
+            <flag name="none" value="0x0" />
+            <!-- The drawing cache is persisted after a layout animation. -->
+            <flag name="animation" value="0x1" />
+            <!-- The drawing cache is persisted after a scroll. -->
+            <flag name="scrolling" value="0x2" />
+            <!-- The drawing cache is always persisted. -->            
+            <flag name="all" value="0x3" />
+        </attr>
+    </declare-styleable>
+
+    <!-- This is the basic set of layout attributes that are common to all
+         layout managers.  These attributes are specified with the rest of
+         a view's normal attributes (such as {@link android.R.attr#background},
+         but will be parsed by the view's parent and ignored by the child.
+        <p>The values defined here correspond to the base layout attribute
+        class {@link android.view.ViewGroup.LayoutParams}. -->
+    <declare-styleable name="ViewGroup_Layout">
+        <!-- Specifies the basic width of the view.  This is a required attribute
+             for any view inside of a containing layout manager.  Its value may
+             be a dimension (such as "12dip") for a constant width or one of
+             the special constants. -->
+        <attr name="layout_width" format="dimension">
+            <!-- The view should be as big as its parent (minus padding). -->
+            <enum name="fill_parent" value="-1" />
+            <!-- The view should be only big enough to enclose its content (plus padding). -->
+            <enum name="wrap_content" value="-2" />
+        </attr>
+
+        <!-- Specifies the basic height of the view.  This is a required attribute
+             for any view inside of a containing layout manager.  Its value may
+             be a dimension (such as "12dip") for a constant height or one of
+             the special constants. -->
+        <attr name="layout_height" format="dimension">
+            <!-- The view should be as big as its parent (minus padding). -->
+            <enum name="fill_parent" value="-1" />
+            <!-- The view should be only big enough to enclose its content (plus padding). -->
+            <enum name="wrap_content" value="-2" />
+        </attr>
+    </declare-styleable>
+
+    <!-- This is the basic set of layout attributes for layout managers that
+         wish to place margins around their child views.
+         These attributes are specified with the rest of
+         a view's normal attributes (such as {@link android.R.attr#background},
+         but will be parsed by the view's parent and ignored by the child.
+        <p>The values defined here correspond to the base layout attribute
+        class {@link android.view.ViewGroup.MarginLayoutParams}. -->
+    <declare-styleable name="ViewGroup_MarginLayout">
+        <attr name="layout_width" />
+        <attr name="layout_height" />
+        <!--  Specifies extra space on the left side of this view.
+            This space is outside this view's bounds. -->
+        <attr name="layout_marginLeft" format="dimension"  />
+        <!--  Specifies extra space on the top side of this view.
+            This space is outside this view's bounds. -->
+        <attr name="layout_marginTop" format="dimension" />
+        <!--  Specifies extra space on the right side of this view.
+            This space is outside this view's bounds. -->
+        <attr name="layout_marginRight" format="dimension"  />
+        <!--  Specifies extra space on the bottom side of this view.
+            This space is outside this view's bounds. -->
+        <attr name="layout_marginBottom" format="dimension"  />
+    </declare-styleable>
+
+    <!-- This is a linear layout. -->
+    <declare-styleable name="LinearLayout">
+        <!-- Should the layout be a column or a row?  Use "horizontal"
+             for a row, "vertical" for a column.  The default is
+             horizontal. -->
+        <attr name="orientation" />
+        <attr name="baselineAligned" format="boolean|reference" />
+        <!-- When a linear layout is part of another layout that is baseline
+          aligned, it can specify which of its children to baseline align to
+          (i.e which child TextView).-->
+        <attr name="baselineAlignedChildIndex" format="integer|color" min="0"/>
+        <!-- Defines the maximum weight sum. If unspecified, the sum is computed
+             by adding the layout_weight of all of the children. This can be
+             used for instance to give a single child 50% of the total available
+             space by giving it a layout_weight of 0.5 and setting the weightSum
+             to 1.0. -->
+        <attr name="weightSum" format="float" />
+    </declare-styleable>
+
+    <declare-styleable name="LinearLayout_Layout">
+        <attr name="layout_width" />
+        <attr name="layout_height" />
+        <attr name="layout_weight" format="float" />
+        <attr name="layout_gravity" />
+    </declare-styleable>
+
+    <declare-styleable name="TableLayout">
+        <!-- The 0 based index of the columns to stretch. The column indices
+             must be separated by a comma: 1, 2, 5. Illegal and duplicate
+             indices are ignored. You can stretch all columns by using the
+             value "*" instead. Note that a column can be marked stretchable
+             and shrinkable at the same time. -->
+        <attr name="stretchColumns" format="string" />
+       <!-- The 0 based index of the columns to shrink. The column indices
+             must be separated by a comma: 1, 2, 5. Illegal and duplicate
+             indices are ignored. You can shrink all columns by using the
+             value "*" instead. Note that a column can be marked stretchable
+             and shrinkable at the same time. -->
+        <attr name="shrinkColumns" format="string" /> 
+        <!-- The 0 based index of the columns to collapse. The column indices
+             must be separated by a comma: 1, 2, 5. Illegal and duplicate
+             indices are ignored. -->
+        <attr name="collapseColumns" format="string" />
+    </declare-styleable>
+
+	<!-- Test for deprecated attributes. -->
+	<declare-styleable name="DeprecatedTest">
+		<!-- Deprecated comments using delimiters.
+			 Ignored. {@deprecated In-line deprecated.} {@ignore Ignored}.
+		 -->
+		<attr name="deprecated-inline" /> 
+
+		<!-- Deprecated comments on their own line.
+			 @deprecated Multi-line version of deprecated
+			    that works till the next tag.
+			 @ignore This tag must be ignored
+		 -->
+		<attr name="deprecated-multiline" />
+		
+		<!-- This attribute is not deprecated. -->
+		<attr name="deprecated-not" />
+		
+        <!-- {@deprecated There is no other javadoc here. } -->
+        <attr name="deprecated-no-javadoc" format="boolean" />
+		
+	</declare-styleable>
+
+</resources>
+
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/view/View.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/view/View.java
new file mode 100644
index 0000000..a80a98d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/view/View.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mock_android.view;
+
+public class View {
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/view/ViewGroup.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/view/ViewGroup.java
new file mode 100644
index 0000000..466470f
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/view/ViewGroup.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mock_android.view;
+
+public class ViewGroup extends View {
+
+    public class MarginLayoutParams extends LayoutParams {
+
+    }
+
+    public class LayoutParams {
+
+    }
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/widget/LinearLayout.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/widget/LinearLayout.java
new file mode 100644
index 0000000..3870a63
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/widget/LinearLayout.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mock_android.widget;
+
+import mock_android.view.ViewGroup;
+
+public class LinearLayout extends ViewGroup {
+
+    public class LayoutParams extends mock_android.view.ViewGroup.LayoutParams {
+
+    }
+
+}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/widget/TableLayout.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/widget/TableLayout.java
new file mode 100644
index 0000000..e455e7d
--- /dev/null
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/mock_android/widget/TableLayout.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package mock_android.widget;
+
+import mock_android.view.ViewGroup;
+
+public class TableLayout extends ViewGroup {
+
+    public class LayoutParams extends MarginLayoutParams {
+
+    }
+
+}
diff --git a/tools/eclipse/scripts/_mk_icons.sh b/tools/eclipse/scripts/_mk_icons.sh
new file mode 100755
index 0000000..b3ea35b
--- /dev/null
+++ b/tools/eclipse/scripts/_mk_icons.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+function icon() {
+  # $1=letter, $2=letter's color (e.g. A red), $3=filename
+  ./gen_icon.py ${3}.png 16 white black $2 $1
+}
+
+icon M green  manifest
+  icon S blue   sharedUserId
+  icon S red    signature
+  icon P green  package
+
+icon I green  instrumentation
+  icon F green  functionalTest
+  icon H green  handleProfiling
+  icon I green  icon
+  icon T green  targetPackage
+
+icon U blue   uses-permission
+icon P red    permission
+  icon N green  name
+  icon L blue   label
+
+icon A blue     application
+    icon P red    permission
+    icon P blue   persistent
+    icon P green  process
+    icon T green  taskAffinity
+    icon T blue   theme
+  icon P red    provider
+    icon A green  authorities
+    icon I green  initOrder
+    icon M green  multiprocess
+    icon R green  readPermission
+    icon W green  writePermission
+    icon S green  syncable
+  icon R green  receiver
+  icon S blue   service
+  icon A green  activity
+      icon C blue   clearOnBackground
+      icon C green  configChanges
+      icon E green  excludeFromRecents
+      icon L green  launchMode
+      icon S green  stateNotNeeded
+    icon F blue  intent-filter
+        icon P green  priority
+      icon A red    action
+      icon C green  category
+      icon D green  data
+        icon M green    mimeType
+        icon S green    scheme
+        icon H green    host
+        icon P green    port
+        icon P blue     path
+
diff --git a/tools/eclipse/scripts/build_plugins.sh b/tools/eclipse/scripts/build_plugins.sh
new file mode 100755
index 0000000..5f94ca0
--- /dev/null
+++ b/tools/eclipse/scripts/build_plugins.sh
@@ -0,0 +1,225 @@
+#!/bin/bash
+
+# build script for eclipse adt build on linux platform
+#
+# Usage: development/tools/eclipse/scripts/build_plugins <build_version> 
+#
+# It expects environment variable ECLIPSE_HOME to be defined to point to _your_
+# version of Eclipse RCP (must have the WTP & GEF plugins available too.)
+#
+# If ECLIPSE_HOME is not provided, this script will _download_ a reference version
+# of Eclipse RCP and install it in a specific location.
+# 
+# Other properties, ant scripts that drive the build are defined in ./buildConfig
+# Currently, this script will create an update site at ${user.home}/www/no_crawl/android-build
+# or at the directory specified using "-d"
+
+# Known Issues:
+# - Build does not properly clean up after itself (build server always executes from
+#   a clean state.)
+# - Script will fail if current absolute path has spaces in it.
+# - Only linux is supported for now
+
+
+set -e # abort this script early if any command fails
+
+#
+# -- Utility methods --
+# 
+
+function printUsage() {
+  echo "Usage: $0 <build_qualifier> [-i] [-d <destination-directory>] [-a <archivePrefix>] "
+  echo "<build_qualifier>: build qualifier string"
+  echo "-i = build internal site. Otherwise, external site will be built"
+  echo "-d = destination directory. Default is $USER/www/no_crawl/. Cannot contain spaces."
+  echo "-a = archive prefix. Cannot contain spaces."
+}
+
+function die() {
+  echo $@
+  exit 1
+}
+
+function dieWithUsage() {
+  echo $@
+  echo
+  printUsage
+  exit 1
+}
+
+
+#
+# -- Setup our custom version of Eclipse --
+#
+
+# The dependency on the linux platform comes from a series of environment
+# variables that the eclipse ant runner expects. These are defined in the
+# build.properties file. We can easily support other platforms but would need
+# to override those values in this script.
+HOST=`uname`
+[ "$HOST" == "Linux" ] || die "ERROR: This script is currently only supported on Linux platform"
+
+# Make sure this runs from the tools/eclipse plugin.
+D=`dirname "$0"`
+cd "$D/.."
+[ `basename "$PWD"` == "eclipse" ] || dieWithUsage "Please run this script from the device/tools/eclipse directory"
+
+# check for number of parameters
+[ $# -lt 1 ] && dieWithUsage "ERROR: Not enough parameters"
+
+# check if ECLIPSE_HOME set (ECLIPSE_HOME is were the "eclipse" binary and the
+# "plugins" sub-directory are located)
+if [ -z "$ECLIPSE_HOME" ]; then
+  BASE_DIR=/buildbot/eclipse-android
+
+  echo "ECLIPSE_HOME not set, using $BASE_DIR as default"
+
+  if [ ! -d "$BASE_DIR" ]; then
+    mkdir -p "$BASE_DIR" || die "Please create a directory $BASE_DIR where Eclipse will be installed, i.e. execute 'mkdir -p $BASE_DIR && chown $USER $BASE_DIR'."
+  fi
+
+  # download the version if not available
+  VERSION="3.4.0"
+  BASE_DIR="$BASE_DIR/$VERSION"
+  scripts/setup_eclipse.sh -p "$BASE_DIR"
+
+  ECLIPSE_HOME="$BASE_DIR/eclipse"      # path to installed directory
+  PID_FILE="$BASE_DIR/eclipse.pid"
+  [ -f "$PID_FILE" ] && ECLIPSE_PID=`cat "$PID_FILE"`
+fi
+
+echo "PWD=`pwd`"
+echo "ECLIPSE_HOME=$ECLIPSE_HOME"
+
+#
+# -- Site parameters and Build version --
+#
+
+BUILD_VERSION="$1" ; shift
+
+# parse for build internal site flag. If set, pass in internalSite property to ant scripts
+if [ "-i" == "$1" ]; then
+  shift
+  echo "Setting for internal site build"
+  SITE_PARAM="-DinternalSite=1 -DupdateSiteSource=$PWD/sites/internal"
+else
+  SITE_PARAM="-DupdateSiteSource=$PWD/sites/external"
+fi
+
+if [ "-d" == $1 ]; then
+  shift
+  echo "Setting destination directory to $1"
+  SITE_PARAM="$SITE_PARAM -DupdateSiteRoot=$1"
+  shift
+fi
+
+if [ "-a" == "$1" ]; then
+  shift
+  echo "Setting archivePrefix to $1"
+  SITE_PARAM="$SITE_PARAM -DarchivePrefix=$1"
+  shift
+fi
+
+
+#
+# -- Configuration directory --
+#
+
+# The "configuration directory" will hold the workspace for this build.
+# If it contains old data the build may fail so we need to clean it first
+# and create it if it doesn't exist.
+CONFIG_DIR="../../../out/eclipse-configuration-$BUILD_VERSION"
+[ -d "$CONFIG_DIR" ] && rm -rfv "$CONFIG_DIR"
+mkdir -p "$CONFIG_DIR"
+
+# The "buildConfig" directory contains our customized ant rules
+BUILDCONFIG="$PWD/buildConfig"
+
+
+#
+# -- Find Eclipse Launcher --
+#
+
+# Get the Eclipse launcher and build script to use
+function findFirst() {
+  for i in "$@"; do
+    if [ -f "$i" ]; then
+      echo "$i"
+      return
+    fi
+  done
+}
+
+LAUNCHER=`findFirst "$ECLIPSE_HOME"/plugins/org.eclipse.equinox.launcher_*.jar`
+BUILDFILE=`findFirst "$ECLIPSE_HOME"/plugins/org.eclipse.pde.build_*/scripts/build.xml`
+
+# make sure we found valid files
+if [ ! -f "$LAUNCHER" ]; then
+  echo "Installation Error: Eclipse plugin org.eclipse.equinox.launcher...jar not detected. " \
+       "Found '$LAUNCHER'. Aborting."
+  exit 1
+fi
+if [ ! -f "$BUILDFILE" ]; then
+  echo "Installation Error: Eclipse build file org.eclipse.pde.build_.../scripts/build.xml " \
+       "not detected. Found '$BUILDFILE'. Aborting."
+  exit 1
+fi
+
+
+#
+# -- Print configuration used and actually execute the build --
+#
+
+echo "Eclipse configuration found:"
+echo "  Eclipse Home: $ECLIPSE_HOME"
+echo "  Launcher:     $LAUNCHER"
+echo "  Build File:   $BUILDFILE"
+echo "  Build Config: $BUILDCONFIG"
+echo "  Config Dir:   $CONFIG_DIR"
+
+# clean input directories to make sure there's nothing left from previous run
+
+rm -fv *.properties *.xml
+find . -name "@*" | xargs rm -rfv
+
+# Now execute the ant runner
+
+set +e  # don't stop on errors anymore, we want to catch there here
+
+java \
+  -jar $LAUNCHER \
+  -data "$CONFIG_DIR" \
+  -configuration "$CONFIG_DIR" \
+  -application org.eclipse.ant.core.antRunner \
+  -buildfile $BUILDFILE \
+  -Dbuilder=$BUILDCONFIG \
+  -DbuildDirectory=$PWD \
+  -DforceContextQualifier=$BUILD_VERSION \
+  -DECLIPSE_HOME=$ECLIPSE_HOME \
+  $SITE_PARAM
+RESULT=$?
+
+if [ "0" != "$RESULT" ]; then
+    echo "JAVA died with error code $RESULT"
+    echo "Dump of build config logs:"
+    for i in "$CONFIG_DIR"/*.log; do
+        if [ -f "$i" ]; then
+            echo "----------------------"
+            echo "--- $i"
+            echo "----------------------"
+            cat "$i"
+            echo
+        fi
+    done
+fi
+
+#
+# -- Cleanup
+#
+
+if [ -n "$ECLIPSE_PID" ] && [ -f "$PID_FILE" ]; then
+  rm -fv "$PID_FILE"
+  kill -9 "$ECLIPSE_PID"
+fi
+
+# we're done!
diff --git a/tools/eclipse/scripts/build_server.sh b/tools/eclipse/scripts/build_server.sh
new file mode 100755
index 0000000..39c8dcd
--- /dev/null
+++ b/tools/eclipse/scripts/build_server.sh
@@ -0,0 +1,118 @@
+#!/bin/bash
+# Entry point to build the Eclipse plugins for the build server.
+#
+# Input parameters:
+# $1: *Mandatory* destination directory. Must already exist. Cannot contain spaces.
+# $2: Optional build number. If present, will be appended to the date qualifier.
+#     The build number cannot contain spaces *nor* periods (dashes are ok.)
+# -z: Optional, prevents the final zip and leaves the udate-site directory intact.
+# -i: Optional, if present, the Google internal update site will be built. Otherwise, 
+#     the external site will be built
+# Workflow:
+# - make dx, ddms, ping
+# - create symlinks (for eclipse code reorg, for ddms, ping)
+# - call the actual builder script from Brett
+# - zip resulting stuff and move to $DEST
+# Note: currently wrap around existing shell script, reuse most of it,
+# eventually both might merge as needed.
+
+set -e  # Fail this script as soon as a command fails -- fail early, fail fast
+
+DEST_DIR=""
+BUILD_NUMBER=""
+CREATE_ZIP="1"
+INTERNAL_BUILD=""
+
+function get_params() {
+  # parse input parameters
+  while [ $# -gt 0 ]; do
+    if [ "$1" == "-z" ]; then
+      CREATE_ZIP=""
+    elif [ "$1" == "-i" ]; then
+      INTERNAL_BUILD="-i"
+    elif [ "$1" != "" ] && [ -z "$DEST_DIR" ]; then
+      DEST_DIR="$1"
+    elif [ "$1" != "" ] && [ -z "$BUILD_NUMBER" ]; then
+      BUILD_NUMBER="$1"
+    fi
+    shift
+  done
+}
+
+function die() {
+  echo "Error:" $*
+  echo "Aborting"
+  exit 1
+}
+
+function check_params() {
+  # This needs to run from the top android directory
+  # Automatically CD to the top android directory, whatever its name
+  D=`dirname "$0"`
+  cd "$D/../../../../" && echo "Switched to directory $PWD"
+
+  # The current Eclipse build has some Linux dependency in its config files
+  [ `uname` == "Linux" ] || die "This must run from a Linux box."
+
+  # Check dest dir exists
+  [ -n "$DEST_DIR" ] || die "Usage: $0 <destination-directory> [build-number]"
+  [ -d "$DEST_DIR" ] || die "Destination directory $DEST_DIR must exist."
+}
+
+function build_libs() {
+  MAKE_OPT="-j8"
+  echo "*** Building: make $MAKE_OPT dx ping ddms jarutils androidprefs layoutlib_api ninepatch sdklib sdkuilib"
+  make $MAKE_OPT dx ping ddms jarutils androidprefs layoutlib_api layoutlib_utils ninepatch sdklib sdkuilib
+}
+
+function build_plugin {
+  development/tools/eclipse/scripts/create_all_symlinks.sh
+
+  # Qualifier is "v" followed by date/time in YYYYMMDDHHSS format and the optional
+  # build number.
+  DATE=`date +v%Y%m%d%H%M`
+  QUALIFIER="$DATE"
+  [ -n "$BUILD_NUMBER" ] && QUALIFIER="${QUALIFIER}-${BUILD_NUMBER}"
+
+  # Compute the final directory name and remove any leftovers from previous
+  # runs if any.
+  BUILD_PREFIX="android-eclipse"  
+  if [ "$INTERNAL_BUILD" ]; then
+    # append 'eng' signifier to end of archive name to denote internal build
+    BUILD_PREFIX="${BUILD_PREFIX}-eng"
+  fi  
+
+  # exclude date from build-zip name so it can be auto-calculated by continuous
+  # test process unless there's no build number, in which case the date is
+  # still used (useful for testing)
+  ZIP_NAME="${BUILD_PREFIX}-${BUILD_NUMBER:-$DATE}.zip"
+  [ -d "$DEST_DIR/$BUILD_PREFIX" ] || rm -rfv "$DEST_DIR/$BUILD_PREFIX"
+
+  # Perform the Eclipse build and move the result in $DEST_DIR/android-build
+  development/tools/eclipse/scripts/build_plugins.sh $QUALIFIER $INTERNAL_BUILD -d "$DEST_DIR" -a "$BUILD_PREFIX"
+
+  # Cleanup
+  [ -d "$QUALIFIER" ] && rm -rfv "$QUALIFIER"
+
+  if [ "$CREATE_ZIP" ]; then
+    # The result is a full update-site under $DEST_DIR/BUILD_PREFIX
+    # Zip it and remove the directory.
+    echo "**** Package in $DEST_DIR"
+    [ -d "$DEST_DIR/$BUILD_PREFIX" ] || \
+      die "Build failed to produce $DEST_DIR/$BUILD_PREFIX"
+    cd "$DEST_DIR"
+    [ -f "$ZIP_NAME" ] && rm -rfv "$ZIP_NAME"
+    cd "$BUILD_PREFIX"
+    zip -9r "../$ZIP_NAME" *
+    cd .. # back to $DEST_DIR
+    rm -rfv "$BUILD_PREFIX"  # removes the directory, not the zip
+    echo "ZIP of Update site available at $DEST_DIR/${ZIP_NAME}"
+  else
+    echo "Update site available in $DEST_DIR/$BUILD_PREFIX"
+  fi
+}
+
+get_params "$@"
+check_params
+build_libs
+build_plugin
diff --git a/tools/eclipse/scripts/build_update_site.sh b/tools/eclipse/scripts/build_update_site.sh
new file mode 100755
index 0000000..5998756
--- /dev/null
+++ b/tools/eclipse/scripts/build_update_site.sh
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Entry point to build the Eclipse plugins for local deployment.
+#
+# Input parameters:
+# $1: Optional build number. If present, will be appended to the date qualifier.
+#     The build number cannot contain spaces *nor* periods (dashes are ok.)
+# -i: Optional, if present, the Google internal update site will be built. Otherwise, 
+#     the external site will be built
+#
+# Workflow:
+# - calls buildserver with /home/$USER/www/no_crawl and -z
+#   to build and create the update size but do not zip it in the destination directory.
+
+set -e  # Fail this script as soon as a command fails -- fail early, fail fast
+
+D=`dirname $0`
+BUILD_NUMBER=""
+INTERNAL_BUILD=""
+# parse input parameters
+while [ $# -gt 0 ]; do
+  if [ "$1" == "-i" ]; then
+    INTERNAL_BUILD="-i"
+  elif [ "$1" != "" ]; then
+    BUILD_NUMBER="$1"
+  fi
+  shift
+done
+
+DEST_DIR="$HOME"
+[ -z "$DEST_DIR" ] && [ -n "$USER" ] && DEST_DIR="/home/$USER"
+[ -z "$DEST_DIR" ] && DEST_DIR="~"
+DEST_DIR="$DEST_DIR/www/no_crawl"
+
+"$D/build_server.sh" "$DEST_DIR" "$BUILD_NUMBER" -z "$INTERNAL_BUILD"
diff --git a/tools/eclipse/scripts/collect_sources_for_sdk.sh b/tools/eclipse/scripts/collect_sources_for_sdk.sh
new file mode 100644
index 0000000..4824da7
--- /dev/null
+++ b/tools/eclipse/scripts/collect_sources_for_sdk.sh
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+function usage() {
+    cat <<EOF
+ Description:
+   This script collects all framework Java sources from the current android
+   source code and places them in a source folder suitable for the eclipse ADT
+   plugin.
+
+ Usage:
+   $0 [-n] <android-git-repo root> <sdk/platforms/xyz/sources>
+ 
+ The source and destination directories must already exist.
+ Use -n for a dry-run.
+
+EOF
+}
+
+DRY=""
+if [ "-n" == "$1" ]; then
+    DRY="echo"
+    shift
+fi
+
+DIR="frameworks"
+if [ "-s" == "$1" ]; then
+    shift
+    DIR="$1"
+    shift
+fi
+
+SRC="$1"
+DST="$2"
+
+if [ -z "$SRC" ] || [ -z "$DST" ] || [ ! -d "$SRC" ] || [ ! -d "$DST" ]; then
+    usage
+    exit 1
+fi
+
+function process() {
+    echo "Examine" $1
+}
+
+N=0
+E=0
+for i in `find -L "${SRC}/${DIR}" -name "*.java"`; do
+    if [ -f "$i" ]; then
+        # look for ^package (android.view.blah);$
+        PACKAGE=`sed -n '/^package [^ ;]\+; */{s/[^ ]* *\([^ ;]*\).*/\1/p;q}' "$i"`
+        if [ -n "$PACKAGE" ]; then
+            PACKAGE=${PACKAGE//./\/}    # e.g. android.view => android/view
+            JAVA=`basename "$i"`        # e.g. View.java
+            [ -z $DRY ] && [ ! -d "$DST/$PACKAGE" ] && mkdir -p -v "$DST/$PACKAGE"
+            $DRY cp -v "$i" "$DST/$PACKAGE/$JAVA"
+            N=$((N+1))
+        else
+            echo "Warning: $i does not have a Java package."
+            E=$((E+1))
+        fi
+    fi
+done
+
+echo "$N java files copied"
+[ $E -gt 0 ] && echo "$E warnings"
+
diff --git a/tools/eclipse/scripts/create_adt_symlinks.sh b/tools/eclipse/scripts/create_adt_symlinks.sh
new file mode 100755
index 0000000..557c4d9
--- /dev/null
+++ b/tools/eclipse/scripts/create_adt_symlinks.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+function die() {
+    echo "Error: $*"
+    exit 1
+}
+
+set -e # fail early
+
+# CD to the top android directory
+D=`dirname "$0"`
+cd "$D/../../../../"
+
+DEST="development/tools/eclipse/plugins/com.android.ide.eclipse.adt"
+# computes "../.." from DEST to here (in /android)
+BACK=`echo $DEST | sed 's@[^/]*@..@g'`
+
+LIBS="sdkstats jarutils androidprefs layoutlib_api layoutlib_utils ninepatch sdklib sdkuilib"
+
+echo "make java libs ..."
+make -j3 showcommands $LIBS || die "ADT: Fail to build one of $LIBS."
+
+echo "Copying java libs to $DEST"
+
+HOST=`uname`
+if [ "$HOST" == "Linux" ]; then
+    for LIB in $LIBS; do
+        ln -svf $BACK/out/host/linux-x86/framework/$LIB.jar "$DEST/"
+    done
+    ln -svf $BACK/out/host/linux-x86/framework/kxml2-2.3.0.jar "$DEST/"
+  
+elif [ "$HOST" == "Darwin" ]; then
+    for LIB in $LIBS; do
+        ln -svf $BACK/out/host/darwin-x86/framework/$LIB.jar "$DEST/"
+    done
+    ln -svf $BACK/out/host/darwin-x86/framework/kxml2-2.3.0.jar "$DEST/"
+
+elif [ "${HOST:0:6}" == "CYGWIN" ]; then
+    for LIB in $LIBS; do
+        cp -vf  out/host/windows-x86/framework/$LIB.jar "$DEST/"
+    done
+
+    if [ ! -f "$DEST/kxml2-2.3.0.jar" ]; then
+        cp -v "prebuilt/common/kxml2/kxml2-2.3.0.jar" "$DEST/"
+    fi
+
+    chmod -v a+rx "$DEST"/*.jar
+else
+    echo "Unsupported platform ($HOST). Nothing done."
+fi
+
diff --git a/tools/eclipse/scripts/create_all_symlinks.sh b/tools/eclipse/scripts/create_all_symlinks.sh
new file mode 100755
index 0000000..8508343
--- /dev/null
+++ b/tools/eclipse/scripts/create_all_symlinks.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+echo "### $0 executing"
+
+function die() {
+    echo "Error: $*"
+    exit 1
+}
+
+# CD to the top android directory
+D=`dirname "$0"`
+cd "$D/../../../../"
+
+DEST="development/tools/eclipse/scripts"
+
+set -e # fail early
+
+echo ; echo "### ADT ###" ; echo
+$DEST/create_adt_symlinks.sh "$*"
+echo ; echo "### DDMS ###" ; echo
+$DEST/create_ddms_symlinks.sh "$*"
+echo ; echo "### TEST ###" ; echo
+$DEST/create_test_symlinks.sh "$*"
+echo ; echo "### BRIDGE ###" ; echo
+$DEST/create_bridge_symlinks.sh "$*"
+
+echo "### $0 done"
diff --git a/tools/eclipse/scripts/create_bridge_symlinks.sh b/tools/eclipse/scripts/create_bridge_symlinks.sh
new file mode 100755
index 0000000..605ef63
--- /dev/null
+++ b/tools/eclipse/scripts/create_bridge_symlinks.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+function die() {
+    echo "Error: $*"
+    exit 1
+}
+
+set -e # fail early
+
+# CD to the top android directory
+D=`dirname "$0"`
+cd "$D/../../../../"
+
+HOST=`uname`
+if [ "$HOST" == "Linux" ]; then
+    echo # nothing to do
+
+elif [ "$HOST" == "Darwin" ]; then
+    echo # nothing to do
+
+elif [ "${HOST:0:6}" == "CYGWIN" ]; then
+    if [ "x$1" == "x" ] || [ `basename "$1"` != "layoutlib.jar" ]; then
+        echo "Usage: $0 sdk/platforms/xxx/data/layoutlib.jar"
+        echo "Argument 1 should be the path to the layoutlib.jar that should be updated."
+        exit 1
+    fi
+
+    LIBS="layoutlib ninepatch"
+    echo "Make java libs: $LIBS"
+    make -j3 showcommands $LIBS || die "Bridge: Failed to build one of $LIBS."
+
+    echo "Updating your SDK in $1"
+    cp -vf  "out/host/windows-x86/framework/layoutlib.jar" "$1"
+    chmod -v a+rx "$1"
+
+else
+    echo "Unsupported platform ($HOST). Nothing done."
+fi
+
diff --git a/tools/eclipse/scripts/create_ddms_symlinks.sh b/tools/eclipse/scripts/create_ddms_symlinks.sh
new file mode 100755
index 0000000..276cf9b
--- /dev/null
+++ b/tools/eclipse/scripts/create_ddms_symlinks.sh
@@ -0,0 +1,79 @@
+#!/bin/bash
+#----------------------------------------------------------------------------|
+# Creates the links to use ddm{ui}lib in the eclipse-ide plugin.
+# Run this from device/tools/eclipse/scripts
+#----------------------------------------------------------------------------|
+
+set -e
+
+HOST=`uname`
+if [ "${HOST:0:6}" == "CYGWIN" ]; then
+    # We can't use symlinks under Cygwin
+
+    function cpfile { # $1=dest $2=source
+        cp -fv $2 $1/
+    }
+
+    function cpdir() { # $1=dest $2=source
+        rsync -avW --delete-after $2 $1
+    }
+
+else
+    # For all other systems which support symlinks
+
+    # computes the "reverse" path, e.g. "a/b/c" => "../../.."
+    function back() {
+        echo $1 | sed 's@[^/]*@..@g'
+    }
+
+    function cpfile { # $1=dest $2=source
+        ln -svf `back $1`/$2 $1/
+    }
+
+    function cpdir() { # $1=dest $2=source
+        ln -svf `back $1`/$2 $1
+    }
+fi
+
+# CD to the top android directory
+D=`dirname "$0"`
+cd "$D/../../../../"
+
+
+BASE="development/tools/eclipse/plugins/com.android.ide.eclipse.ddms"
+
+DEST=$BASE/libs
+mkdir -p $DEST
+for i in prebuilt/common/jfreechart/*.jar; do
+  cpfile $DEST $i
+done
+
+DEST=$BASE/src/com/android
+mkdir -p $DEST
+for i in development/tools/ddms/libs/ddmlib/src/com/android/ddmlib \
+         development/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib ; do
+  cpdir $DEST $i
+done
+
+DEST=$BASE/icons
+mkdir -p $DEST
+for i in \
+    add.png \
+    backward.png \
+    clear.png \
+    d.png debug-attach.png debug-error.png debug-wait.png delete.png device.png down.png \
+    e.png edit.png empty.png emulator.png \
+    forward.png \
+    gc.png \
+    heap.png halt.png \
+    i.png importBug.png \
+    load.png \
+    pause.png play.png pull.png push.png \
+    save.png \
+    thread.png \
+    up.png \
+    v.png \
+    w.png warning.png ; do
+  cpfile $DEST development/tools/ddms/libs/ddmuilib/src/resources/images/$i
+done
+
diff --git a/tools/eclipse/scripts/create_test_symlinks.sh b/tools/eclipse/scripts/create_test_symlinks.sh
new file mode 100755
index 0000000..931dce8
--- /dev/null
+++ b/tools/eclipse/scripts/create_test_symlinks.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+set -e
+
+# CD to the top android directory
+D=`dirname "$0"`
+cd "$D/../../../../"
+
+# computes relative ".." paths from $1 to here (in /android)
+function back() {
+  echo $1 | sed 's@[^/]*@..@g'
+}
+
+HOST=`uname`
+if [ "${HOST:0:6}" == "CYGWIN" ]; then
+    # We can't use symlinks under Cygwin
+    function cpdir() { # $1=dest $2=source
+        rsync -avW --delete-after $2 $1
+    }
+
+else
+    # For all other systems which support symlinks
+    function cpdir() { # $1=dest $2=source
+        ln -svf `back $1`/$2 $1
+    }
+fi
+
+BASE="development/tools/eclipse/plugins/com.android.ide.eclipse.tests"
+DEST=$BASE
+BACK=`back $DEST`
+
+HOST=`uname`
+if [ "$HOST" == "Linux" ]; then
+    ln -svf $BACK/out/host/linux-x86/framework/kxml2-2.3.0.jar "$DEST/"
+
+elif [ "$HOST" == "Darwin" ]; then
+    ln -svf $BACK/out/host/darwin-x86/framework/kxml2-2.3.0.jar "$DEST/"
+
+elif [ "${HOST:0:6}" == "CYGWIN" ]; then
+
+    if [ ! -f "$DEST/kxml2-2.3.0.jar" ]; then
+        cp -v "prebuilt/common/kxml2/kxml2-2.3.0.jar" "$DEST/"
+        chmod -v a+rx "$DEST"/*.jar
+    fi
+
+else
+    echo "Unsupported platform ($HOST). Nothing done."
+fi
+
+# create link to ddmlib tests
+DEST=$BASE/unittests/com/android
+BACK=`back $DEST`
+cpdir $DEST development/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib
+
diff --git a/tools/eclipse/scripts/gen_icon.py b/tools/eclipse/scripts/gen_icon.py
new file mode 100755
index 0000000..f6274e1
--- /dev/null
+++ b/tools/eclipse/scripts/gen_icon.py
@@ -0,0 +1,71 @@
+#!/usr/bin/python
+
+import sys
+import StringIO
+try:
+    import Image, ImageDraw, ImageFont
+except ImportError, e:
+    print str(e)
+    print "Are you missing the Python Imaging Library? (apt-get install python-imaging)"
+    sys.exit(1)
+
+FONT_PATH = "/usr/share/fonts/truetype/msttcorefonts/arial.ttf"
+
+class Args(object):
+    def __init__(self, dest_name, size, circle_color, border_color,
+                 letter_color, letter):
+        self.dest_name = dest_name
+        self.size = size
+        self.circle_color = circle_color
+        self.border_color = border_color
+        self.letter_color = letter_color
+        self.letter = letter
+
+def main(args):
+    data = process_args(args)
+    if data:
+        createImage(data)
+
+def process_args(args):
+    if not args or len(args) != 6:
+        usage()
+    return Args(*args)
+    
+def usage():
+    print """Usage: %s <file_name> <size> <circle-color> <border-color> <letter-color> <letter>""" % sys.argv[0]
+    sys.exit(1)
+
+def createImage(data):
+    zoom = 4
+    rmin = -zoom/2
+    rmax = zoom/2
+    if zoom > 1:
+        r = range(-zoom/2, zoom/2+1)
+    else:
+        r = [ 0 ]
+    sz = int(data.size)
+    sz4 = sz * zoom
+    
+    img = Image.new("RGBA", (sz4, sz4), (255,255,255,0))
+    draw = ImageDraw.Draw(img)
+
+    draw.ellipse((0, 0, sz4-zoom, sz4-zoom),
+                     fill=data.circle_color, outline=None)
+    for i in r:
+        draw.ellipse((i, i, sz4-i-zoom, sz4-i-zoom),
+                     fill=None, outline=data.border_color)
+
+    font = ImageFont.truetype(FONT_PATH, int(sz4 * .75))
+    tsx, tsy = draw.textsize(data.letter, font=font)
+
+    ptx = (sz4 - tsx) / 2
+    pty = (sz4 - tsy) / 2
+    for i in r:
+        draw.text((ptx + i, pty), data.letter, font=font, fill=data.letter_color)
+
+    img = img.resize((sz, sz), Image.BICUBIC)
+    img.save(data.dest_name, "PNG")
+    print "Saved", data.dest_name
+
+if __name__ == "__main__":
+    main(sys.argv[1:])
diff --git a/tools/eclipse/scripts/setup_eclipse.sh b/tools/eclipse/scripts/setup_eclipse.sh
new file mode 100755
index 0000000..5143e23
--- /dev/null
+++ b/tools/eclipse/scripts/setup_eclipse.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+
+# Quick script used to setup Eclipse for the ADT plugin build.
+#
+# usage:
+#   setup_eclipse.sh <dest_dir>
+#
+# Workflow:
+# - downloads & unpack Eclipse if necessary
+# - *runs* it once
+
+
+#-----------------
+#
+# Note: right now this is invoked by //device/tools/eclipse/doBuild.sh
+# and it *MUST* be invoked with the following destination directory:
+#
+# $ setup_eclipse.sh /buildbot/eclipse-android/3.4.0/
+#
+#-----------------
+
+
+set -e # abort this script early if any command fails
+
+function die() {
+  echo $@
+  exit 1
+}
+
+if [ "-p" == "$1" ]; then
+  GET_PID="-p"
+  shift
+fi
+
+BASE_DIR="$1"
+
+[ -n "$1" ] || die "Usage: $0 <dest-dir>"
+
+# URL for 3.4.0 RCP Linux 32 Bits. Includes GEF, WTP as needed.
+DOWNLOAD_URL="http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/ganymede/R/eclipse-rcp-ganymede-linux-gtk.tar.gz&url=http://eclipse.unixheads.org/technology/epp/downloads/release/ganymede/R/eclipse-rcp-ganymede-linux-gtk.tar.gz&mirror_id=480"
+
+BIN="$BASE_DIR/eclipse/eclipse"           # path to installed binary
+TARGZ="$BASE_DIR/eclipse-rcp-ganymede-linux-gtk.tar.gz"
+
+if [ ! -f "$BIN" ]; then   
+  echo "Downloading and installing Eclipse in $BASE_DIR."
+  mkdir -p "$BASE_DIR"
+  wget --continue --no-verbose --output-document="$TARGZ" "$DOWNLOAD_URL"
+  echo "Unpacking $TARGZ"
+  (cd "$BASE_DIR" && tar xzf "$TARGZ")
+    
+  echo
+  echo "*** WARNING: To setup Eclipse correctly, it must be ran at least once manually"
+  echo "***          Eclipse will now start."
+  echo
+  if [ -n "$GET_PID" ]; then
+    # if started from the automatic eclipse build, run Eclipse in the background
+    "$BIN" &
+    ECLIPSE_PID=$!
+    echo "*** Eclipse started in background with PID $ECLIPSE_PID"
+    echo "$ECLIPSE_PID" > "$BASE_DIR"/eclipse.pid
+    sleep 5  # give some time for Eclipse to start and setup its environment
+  else
+    # if started manually, run Eclipse in the foreground
+    "$BIN"
+  fi
+fi
diff --git a/tools/eclipse/scripts/update_version.sh b/tools/eclipse/scripts/update_version.sh
new file mode 100644
index 0000000..a288965
--- /dev/null
+++ b/tools/eclipse/scripts/update_version.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+OLD="$1"
+NEW="$2"
+
+# sanity check in input args
+if [ -z "$OLD" ] || [ -z "$NEW" ]; then
+    cat <<EOF
+Usage: $0 <old> <new>
+Changes the ADT plugin revision number.
+Example:
+  cd tools/eclipse
+  scripts/update_version.sh 0.1.2 0.2.3
+EOF
+    exit 1
+fi
+
+# sanity check on current dir
+if [ `basename "$PWD"` != "eclipse" ]; then
+    echo "Please run this from tools/eclipse."
+    exit 1
+fi
+
+# quote dots for regexps
+OLD="${OLD//./\.}"
+NEW="${NEW//./\.}"
+
+# Find all the files with the old pattern, except changes.txt and
+# p4 edit them. Skip that if there's no p4 in path.
+if which g4 1>/dev/null 2>/dev/null ; then
+    grep -rl "$OLD" * | grep -E "\.xml$|\.MF$" | xargs -n 5 g4 edit
+fi
+
+# Now find the same files but this time use sed to replace in-place with
+# the new pattern. Old files get backuped with the .old extension.
+grep -rl "$OLD" * | grep -E "\.xml$|\.MF$" | xargs -n 1 sed -i.old "s/$OLD/$NEW/g"
+
diff --git a/tools/eclipse/sites/external/.project b/tools/eclipse/sites/external/.project
new file mode 100644
index 0000000..9916269
--- /dev/null
+++ b/tools/eclipse/sites/external/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>external-site</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.UpdateSiteBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.UpdateSiteNature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/eclipse/sites/external/index.html b/tools/eclipse/sites/external/index.html
new file mode 100644
index 0000000..784be4b
--- /dev/null
+++ b/tools/eclipse/sites/external/index.html
@@ -0,0 +1,60 @@
+<html>
+<head>
+<title>Android Development Toolkit update site.</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<style>@import url("web/site.css");</style>
+<script type="text/javascript">
+	var returnval = 0;
+	var stylesheet, xmlFile, cache, doc;
+	function init(){
+		// NSCP 7.1+ / Mozilla 1.4.1+ / Safari
+		// Use the standard DOM Level 2 technique, if it is supported
+		if (document.implementation && document.implementation.createDocument) {
+			xmlFile = document.implementation.createDocument("", "", null);
+			stylesheet = document.implementation.createDocument("", "", null);
+			if (xmlFile.load){
+				xmlFile.load("site.xml");
+				stylesheet.load("web/site.xsl");
+			} else {
+				alert("Document could not be loaded by browser.");
+			}
+			xmlFile.addEventListener("load", transform, false);
+			stylesheet.addEventListener("load", transform, false);
+		}
+		//IE 6.0+ solution
+		else if (window.ActiveXObject) {
+			xmlFile = new ActiveXObject("msxml2.DOMDocument.3.0");
+			xmlFile.async = false;
+			xmlFile.load("site.xml");
+			stylesheet = new ActiveXObject("msxml2.FreeThreadedDOMDocument.3.0");
+			stylesheet.async = false;
+			stylesheet.load("web/site.xsl");
+			cache = new ActiveXObject("msxml2.XSLTemplate.3.0");
+			cache.stylesheet = stylesheet;
+			transformData();
+		}
+	}
+	// separate transformation function for IE 6.0+
+	function transformData(){
+		var processor = cache.createProcessor();
+		processor.input = xmlFile;
+		processor.transform();
+		data.innerHTML = processor.output;
+	}
+	// separate transformation function for NSCP 7.1+ and Mozilla 1.4.1+
+	function transform(){
+		returnval+=1;
+		if (returnval==2){
+			var processor = new XSLTProcessor();
+			processor.importStylesheet(stylesheet);
+			doc = processor.transformToDocument(xmlFile);
+			document.getElementById("data").innerHTML = doc.documentElement.innerHTML;
+		}
+	}
+</script>
+</head>
+<body onload="init();">
+<!--[insert static HTML here]-->
+<div id="data"><!-- this is where the transformed data goes --></div>
+</body>
+</html>
diff --git a/tools/eclipse/sites/external/site.xml b/tools/eclipse/sites/external/site.xml
new file mode 100644
index 0000000..9fca8d2
--- /dev/null
+++ b/tools/eclipse/sites/external/site.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+   <description url="https://dl-ssl.google.com/android/eclipse/">
+      Update Site for Android Development Toolkit
+   </description>
+   <feature url="features/com.android.ide.eclipse.adt_0.9.0.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.0.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">
+      <category name="developer"/>
+   </feature>
+   <category-def name="developer" label="Developer Tools">
+      <description>
+         Features that add Android support to Eclipse for application developers.
+      </description>
+   </category-def>
+</site>
diff --git a/tools/eclipse/sites/external/web/site.css b/tools/eclipse/sites/external/web/site.css
new file mode 100644
index 0000000..62c6f9f
--- /dev/null
+++ b/tools/eclipse/sites/external/web/site.css
@@ -0,0 +1,12 @@
+<STYLE type="text/css">
+td.spacer {padding-bottom: 10px; padding-top: 10px;}
+.title { font-family: sans-serif; color: #99AACC;}
+.bodyText { font-family: sans-serif; font-size: 9pt; color:#000000;  }
+.sub-header { font-family: sans-serif; font-style: normal; font-weight: bold; font-size: 9pt; color: white;}
+.log-text {font-family: sans-serif; font-style: normal; font-weight: lighter; font-size: 8pt; color:black;}
+.big-header { font-family: sans-serif; font-style: normal; font-weight: bold; font-size: 9pt; color: white; border-top:10px solid white;}
+.light-row {background:#FFFFFF}
+.dark-row {background:#EEEEFF}
+.header {background:#99AADD}
+#indent {word-wrap : break-word;width :300px;text-indent:10px;}
+</STYLE>
diff --git a/tools/eclipse/sites/external/web/site.xsl b/tools/eclipse/sites/external/web/site.xsl
new file mode 100644
index 0000000..a94157d
--- /dev/null
+++ b/tools/eclipse/sites/external/web/site.xsl
@@ -0,0 +1,214 @@
+<xsl:stylesheet version = '1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl="urn:schemas-microsoft-com:xslt">
+<xsl:output method="html" encoding="UTF-8"/>
+<xsl:key name="cat" match="category" use="@name"/>
+<xsl:template match="/">
+<xsl:for-each select="site">
+	<html>
+	<head>
+	<title>update-site</title>
+	<style>@import url("web/site.css");</style>
+	</head>
+	<body>
+	<h1 class="title">update-site</h1>
+	<p class="bodyText"><xsl:value-of select="description"/></p>
+	<table width="100%" border="0" cellspacing="1" cellpadding="2">
+	<xsl:for-each select="category-def">
+		<xsl:sort select="@label" order="ascending" case-order="upper-first"/>
+		<xsl:sort select="@name" order="ascending" case-order="upper-first"/>
+	<xsl:if test="count(key('cat',@name)) != 0">
+			<tr class="header">
+				<td class="sub-header" width="30%">
+					<xsl:value-of select="@name"/>
+				</td>
+				<td class="sub-header" width="70%">
+					<xsl:value-of select="@label"/>
+				</td>
+			</tr>
+			<xsl:for-each select="key('cat',@name)">
+			<xsl:sort select="ancestor::feature//@version" order="ascending"/>
+			<xsl:sort select="ancestor::feature//@id" order="ascending" case-order="upper-first"/>
+			<tr>
+				<xsl:choose>
+				<xsl:when test="(position() mod 2 = 1)">
+					<xsl:attribute name="class">dark-row</xsl:attribute>
+				</xsl:when>
+				<xsl:otherwise>
+					<xsl:attribute name="class">light-row</xsl:attribute>
+				</xsl:otherwise>
+				</xsl:choose>
+				<td class="log-text" id="indent">
+						<xsl:choose>
+						<xsl:when test="ancestor::feature//@label">
+							<a href="{ancestor::feature//@url}"><xsl:value-of select="ancestor::feature//@label"/></a>
+							<br/>
+							<div id="indent">
+							(<xsl:value-of select="ancestor::feature//@id"/> - <xsl:value-of select="ancestor::feature//@version"/>)
+							</div>
+						</xsl:when>
+						<xsl:otherwise>
+						<a href="{ancestor::feature//@url}"><xsl:value-of select="ancestor::feature//@id"/> - <xsl:value-of select="ancestor::feature//@version"/></a>
+						</xsl:otherwise>
+						</xsl:choose>
+						<br />
+				</td>
+				<td>
+					<table>
+						<xsl:if test="ancestor::feature//@os">
+							<tr><td class="log-text" id="indent">Operating Systems:</td>
+							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@os"/></td>
+							</tr>
+						</xsl:if>
+						<xsl:if test="ancestor::feature//@ws">
+							<tr><td class="log-text" id="indent">Windows Systems:</td>
+							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@ws"/></td>
+							</tr>
+						</xsl:if>
+						<xsl:if test="ancestor::feature//@nl">
+							<tr><td class="log-text" id="indent">Languages:</td>
+							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@nl"/></td>
+							</tr>
+						</xsl:if>
+						<xsl:if test="ancestor::feature//@arch">
+							<tr><td class="log-text" id="indent">Architecture:</td>
+							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@arch"/></td>
+							</tr>
+						</xsl:if>
+					</table>
+				</td>
+			</tr>
+			</xsl:for-each>
+			<tr><td class="spacer"><br/></td><td class="spacer"><br/></td></tr>
+		</xsl:if>
+	</xsl:for-each>
+	<xsl:if test="count(feature)  &gt; count(feature/category)">
+	<tr class="header">
+		<td class="sub-header" colspan="2">
+		Uncategorized
+		</td>
+	</tr>
+	</xsl:if>
+	<xsl:choose>
+	<xsl:when test="function-available('msxsl:node-set')">
+	   <xsl:variable name="rtf-nodes">
+		<xsl:for-each select="feature[not(category)]">
+			<xsl:sort select="@id" order="ascending" case-order="upper-first"/>
+			<xsl:sort select="@version" order="ascending" />
+			<xsl:value-of select="."/>
+			<xsl:copy-of select="." />
+		</xsl:for-each>
+	   </xsl:variable>
+	   <xsl:variable name="myNodeSet" select="msxsl:node-set($rtf-nodes)/*"/>
+	<xsl:for-each select="$myNodeSet">
+	<tr>
+		<xsl:choose>
+		<xsl:when test="position() mod 2 = 1">
+		<xsl:attribute name="class">dark-row</xsl:attribute>
+		</xsl:when>
+		<xsl:otherwise>
+		<xsl:attribute name="class">light-row</xsl:attribute>
+		</xsl:otherwise>
+		</xsl:choose>
+		<td class="log-text" id="indent">
+			<xsl:choose>
+			<xsl:when test="@label">
+				<a href="{@url}"><xsl:value-of select="@label"/></a>
+				<br />
+				<div id="indent">
+				(<xsl:value-of select="@id"/> - <xsl:value-of select="@version"/>)
+				</div>
+			</xsl:when>
+			<xsl:otherwise>
+				<a href="{@url}"><xsl:value-of select="@id"/> - <xsl:value-of select="@version"/></a>
+			</xsl:otherwise>
+			</xsl:choose>
+			<br /><br />
+		</td>
+		<td>
+			<table>
+				<xsl:if test="@os">
+					<tr><td class="log-text" id="indent">Operating Systems:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@os"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@ws">
+					<tr><td class="log-text" id="indent">Windows Systems:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@ws"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@nl">
+					<tr><td class="log-text" id="indent">Languages:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@nl"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@arch">
+					<tr><td class="log-text" id="indent">Architecture:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@arch"/></td>
+					</tr>
+				</xsl:if>
+			</table>
+		</td>
+	</tr>
+	</xsl:for-each>
+	</xsl:when>
+	<xsl:otherwise>
+	<xsl:for-each select="feature[not(category)]">
+	<xsl:sort select="@id" order="ascending" case-order="upper-first"/>
+	<xsl:sort select="@version" order="ascending" />
+	<tr>
+		<xsl:choose>
+		<xsl:when test="count(preceding-sibling::feature[not(category)]) mod 2 = 1">
+		<xsl:attribute name="class">dark-row</xsl:attribute>
+		</xsl:when>
+		<xsl:otherwise>
+		<xsl:attribute name="class">light-row</xsl:attribute>
+		</xsl:otherwise>
+		</xsl:choose>
+		<td class="log-text" id="indent">
+			<xsl:choose>
+			<xsl:when test="@label">
+				<a href="{@url}"><xsl:value-of select="@label"/></a>
+				<br />
+				<div id="indent">
+				(<xsl:value-of select="@id"/> - <xsl:value-of select="@version"/>)
+				</div>
+			</xsl:when>
+			<xsl:otherwise>
+				<a href="{@url}"><xsl:value-of select="@id"/> - <xsl:value-of select="@version"/></a>
+			</xsl:otherwise>
+			</xsl:choose>
+			<br /><br />
+		</td>
+		<td>
+			<table>
+				<xsl:if test="@os">
+					<tr><td class="log-text" id="indent">Operating Systems:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@os"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@ws">
+					<tr><td class="log-text" id="indent">Windows Systems:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@ws"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@nl">
+					<tr><td class="log-text" id="indent">Languages:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@nl"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@arch">
+					<tr><td class="log-text" id="indent">Architecture:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@arch"/></td>
+					</tr>
+				</xsl:if>
+			</table>
+		</td>
+	</tr>
+	</xsl:for-each>
+	</xsl:otherwise>
+	</xsl:choose>
+	</table>
+	</body>
+	</html>
+</xsl:for-each>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/tools/eclipse/sites/internal/.project b/tools/eclipse/sites/internal/.project
new file mode 100644
index 0000000..0bd658d
--- /dev/null
+++ b/tools/eclipse/sites/internal/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>internal-site</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.UpdateSiteBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.UpdateSiteNature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/eclipse/sites/internal/index.html b/tools/eclipse/sites/internal/index.html
new file mode 100644
index 0000000..784be4b
--- /dev/null
+++ b/tools/eclipse/sites/internal/index.html
@@ -0,0 +1,60 @@
+<html>
+<head>
+<title>Android Development Toolkit update site.</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<style>@import url("web/site.css");</style>
+<script type="text/javascript">
+	var returnval = 0;
+	var stylesheet, xmlFile, cache, doc;
+	function init(){
+		// NSCP 7.1+ / Mozilla 1.4.1+ / Safari
+		// Use the standard DOM Level 2 technique, if it is supported
+		if (document.implementation && document.implementation.createDocument) {
+			xmlFile = document.implementation.createDocument("", "", null);
+			stylesheet = document.implementation.createDocument("", "", null);
+			if (xmlFile.load){
+				xmlFile.load("site.xml");
+				stylesheet.load("web/site.xsl");
+			} else {
+				alert("Document could not be loaded by browser.");
+			}
+			xmlFile.addEventListener("load", transform, false);
+			stylesheet.addEventListener("load", transform, false);
+		}
+		//IE 6.0+ solution
+		else if (window.ActiveXObject) {
+			xmlFile = new ActiveXObject("msxml2.DOMDocument.3.0");
+			xmlFile.async = false;
+			xmlFile.load("site.xml");
+			stylesheet = new ActiveXObject("msxml2.FreeThreadedDOMDocument.3.0");
+			stylesheet.async = false;
+			stylesheet.load("web/site.xsl");
+			cache = new ActiveXObject("msxml2.XSLTemplate.3.0");
+			cache.stylesheet = stylesheet;
+			transformData();
+		}
+	}
+	// separate transformation function for IE 6.0+
+	function transformData(){
+		var processor = cache.createProcessor();
+		processor.input = xmlFile;
+		processor.transform();
+		data.innerHTML = processor.output;
+	}
+	// separate transformation function for NSCP 7.1+ and Mozilla 1.4.1+
+	function transform(){
+		returnval+=1;
+		if (returnval==2){
+			var processor = new XSLTProcessor();
+			processor.importStylesheet(stylesheet);
+			doc = processor.transformToDocument(xmlFile);
+			document.getElementById("data").innerHTML = doc.documentElement.innerHTML;
+		}
+	}
+</script>
+</head>
+<body onload="init();">
+<!--[insert static HTML here]-->
+<div id="data"><!-- this is where the transformed data goes --></div>
+</body>
+</html>
diff --git a/tools/eclipse/sites/internal/site.xml b/tools/eclipse/sites/internal/site.xml
new file mode 100644
index 0000000..9f2642f
--- /dev/null
+++ b/tools/eclipse/sites/internal/site.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site>
+   <description url="https://android.corp.google.com/adt/">
+      Update Site for Android Development Toolkit
+   </description>
+   <feature url="features/com.android.ide.eclipse.adt_0.9.0.qualifier.jar" id="com.android.ide.eclipse.adt" version="0.9.0.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">
+      <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">
+      <category name="test"/>
+   </feature>
+   <category-def name="developer" label="Application Developer Tools">
+      <description>
+         Features that add Android support to Eclipse for application developers.
+      </description>
+   </category-def>
+   <category-def name="test" label="Plugin Developer Tests">
+      <description>
+         Tests for the other Android plugins
+      </description>
+   </category-def>
+</site>
diff --git a/tools/eclipse/sites/internal/web/site.css b/tools/eclipse/sites/internal/web/site.css
new file mode 100644
index 0000000..62c6f9f
--- /dev/null
+++ b/tools/eclipse/sites/internal/web/site.css
@@ -0,0 +1,12 @@
+<STYLE type="text/css">
+td.spacer {padding-bottom: 10px; padding-top: 10px;}
+.title { font-family: sans-serif; color: #99AACC;}
+.bodyText { font-family: sans-serif; font-size: 9pt; color:#000000;  }
+.sub-header { font-family: sans-serif; font-style: normal; font-weight: bold; font-size: 9pt; color: white;}
+.log-text {font-family: sans-serif; font-style: normal; font-weight: lighter; font-size: 8pt; color:black;}
+.big-header { font-family: sans-serif; font-style: normal; font-weight: bold; font-size: 9pt; color: white; border-top:10px solid white;}
+.light-row {background:#FFFFFF}
+.dark-row {background:#EEEEFF}
+.header {background:#99AADD}
+#indent {word-wrap : break-word;width :300px;text-indent:10px;}
+</STYLE>
diff --git a/tools/eclipse/sites/internal/web/site.xsl b/tools/eclipse/sites/internal/web/site.xsl
new file mode 100644
index 0000000..a94157d
--- /dev/null
+++ b/tools/eclipse/sites/internal/web/site.xsl
@@ -0,0 +1,214 @@
+<xsl:stylesheet version = '1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:msxsl="urn:schemas-microsoft-com:xslt">
+<xsl:output method="html" encoding="UTF-8"/>
+<xsl:key name="cat" match="category" use="@name"/>
+<xsl:template match="/">
+<xsl:for-each select="site">
+	<html>
+	<head>
+	<title>update-site</title>
+	<style>@import url("web/site.css");</style>
+	</head>
+	<body>
+	<h1 class="title">update-site</h1>
+	<p class="bodyText"><xsl:value-of select="description"/></p>
+	<table width="100%" border="0" cellspacing="1" cellpadding="2">
+	<xsl:for-each select="category-def">
+		<xsl:sort select="@label" order="ascending" case-order="upper-first"/>
+		<xsl:sort select="@name" order="ascending" case-order="upper-first"/>
+	<xsl:if test="count(key('cat',@name)) != 0">
+			<tr class="header">
+				<td class="sub-header" width="30%">
+					<xsl:value-of select="@name"/>
+				</td>
+				<td class="sub-header" width="70%">
+					<xsl:value-of select="@label"/>
+				</td>
+			</tr>
+			<xsl:for-each select="key('cat',@name)">
+			<xsl:sort select="ancestor::feature//@version" order="ascending"/>
+			<xsl:sort select="ancestor::feature//@id" order="ascending" case-order="upper-first"/>
+			<tr>
+				<xsl:choose>
+				<xsl:when test="(position() mod 2 = 1)">
+					<xsl:attribute name="class">dark-row</xsl:attribute>
+				</xsl:when>
+				<xsl:otherwise>
+					<xsl:attribute name="class">light-row</xsl:attribute>
+				</xsl:otherwise>
+				</xsl:choose>
+				<td class="log-text" id="indent">
+						<xsl:choose>
+						<xsl:when test="ancestor::feature//@label">
+							<a href="{ancestor::feature//@url}"><xsl:value-of select="ancestor::feature//@label"/></a>
+							<br/>
+							<div id="indent">
+							(<xsl:value-of select="ancestor::feature//@id"/> - <xsl:value-of select="ancestor::feature//@version"/>)
+							</div>
+						</xsl:when>
+						<xsl:otherwise>
+						<a href="{ancestor::feature//@url}"><xsl:value-of select="ancestor::feature//@id"/> - <xsl:value-of select="ancestor::feature//@version"/></a>
+						</xsl:otherwise>
+						</xsl:choose>
+						<br />
+				</td>
+				<td>
+					<table>
+						<xsl:if test="ancestor::feature//@os">
+							<tr><td class="log-text" id="indent">Operating Systems:</td>
+							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@os"/></td>
+							</tr>
+						</xsl:if>
+						<xsl:if test="ancestor::feature//@ws">
+							<tr><td class="log-text" id="indent">Windows Systems:</td>
+							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@ws"/></td>
+							</tr>
+						</xsl:if>
+						<xsl:if test="ancestor::feature//@nl">
+							<tr><td class="log-text" id="indent">Languages:</td>
+							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@nl"/></td>
+							</tr>
+						</xsl:if>
+						<xsl:if test="ancestor::feature//@arch">
+							<tr><td class="log-text" id="indent">Architecture:</td>
+							<td class="log-text" id="indent"><xsl:value-of select="ancestor::feature//@arch"/></td>
+							</tr>
+						</xsl:if>
+					</table>
+				</td>
+			</tr>
+			</xsl:for-each>
+			<tr><td class="spacer"><br/></td><td class="spacer"><br/></td></tr>
+		</xsl:if>
+	</xsl:for-each>
+	<xsl:if test="count(feature)  &gt; count(feature/category)">
+	<tr class="header">
+		<td class="sub-header" colspan="2">
+		Uncategorized
+		</td>
+	</tr>
+	</xsl:if>
+	<xsl:choose>
+	<xsl:when test="function-available('msxsl:node-set')">
+	   <xsl:variable name="rtf-nodes">
+		<xsl:for-each select="feature[not(category)]">
+			<xsl:sort select="@id" order="ascending" case-order="upper-first"/>
+			<xsl:sort select="@version" order="ascending" />
+			<xsl:value-of select="."/>
+			<xsl:copy-of select="." />
+		</xsl:for-each>
+	   </xsl:variable>
+	   <xsl:variable name="myNodeSet" select="msxsl:node-set($rtf-nodes)/*"/>
+	<xsl:for-each select="$myNodeSet">
+	<tr>
+		<xsl:choose>
+		<xsl:when test="position() mod 2 = 1">
+		<xsl:attribute name="class">dark-row</xsl:attribute>
+		</xsl:when>
+		<xsl:otherwise>
+		<xsl:attribute name="class">light-row</xsl:attribute>
+		</xsl:otherwise>
+		</xsl:choose>
+		<td class="log-text" id="indent">
+			<xsl:choose>
+			<xsl:when test="@label">
+				<a href="{@url}"><xsl:value-of select="@label"/></a>
+				<br />
+				<div id="indent">
+				(<xsl:value-of select="@id"/> - <xsl:value-of select="@version"/>)
+				</div>
+			</xsl:when>
+			<xsl:otherwise>
+				<a href="{@url}"><xsl:value-of select="@id"/> - <xsl:value-of select="@version"/></a>
+			</xsl:otherwise>
+			</xsl:choose>
+			<br /><br />
+		</td>
+		<td>
+			<table>
+				<xsl:if test="@os">
+					<tr><td class="log-text" id="indent">Operating Systems:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@os"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@ws">
+					<tr><td class="log-text" id="indent">Windows Systems:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@ws"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@nl">
+					<tr><td class="log-text" id="indent">Languages:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@nl"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@arch">
+					<tr><td class="log-text" id="indent">Architecture:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@arch"/></td>
+					</tr>
+				</xsl:if>
+			</table>
+		</td>
+	</tr>
+	</xsl:for-each>
+	</xsl:when>
+	<xsl:otherwise>
+	<xsl:for-each select="feature[not(category)]">
+	<xsl:sort select="@id" order="ascending" case-order="upper-first"/>
+	<xsl:sort select="@version" order="ascending" />
+	<tr>
+		<xsl:choose>
+		<xsl:when test="count(preceding-sibling::feature[not(category)]) mod 2 = 1">
+		<xsl:attribute name="class">dark-row</xsl:attribute>
+		</xsl:when>
+		<xsl:otherwise>
+		<xsl:attribute name="class">light-row</xsl:attribute>
+		</xsl:otherwise>
+		</xsl:choose>
+		<td class="log-text" id="indent">
+			<xsl:choose>
+			<xsl:when test="@label">
+				<a href="{@url}"><xsl:value-of select="@label"/></a>
+				<br />
+				<div id="indent">
+				(<xsl:value-of select="@id"/> - <xsl:value-of select="@version"/>)
+				</div>
+			</xsl:when>
+			<xsl:otherwise>
+				<a href="{@url}"><xsl:value-of select="@id"/> - <xsl:value-of select="@version"/></a>
+			</xsl:otherwise>
+			</xsl:choose>
+			<br /><br />
+		</td>
+		<td>
+			<table>
+				<xsl:if test="@os">
+					<tr><td class="log-text" id="indent">Operating Systems:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@os"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@ws">
+					<tr><td class="log-text" id="indent">Windows Systems:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@ws"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@nl">
+					<tr><td class="log-text" id="indent">Languages:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@nl"/></td>
+					</tr>
+				</xsl:if>
+				<xsl:if test="@arch">
+					<tr><td class="log-text" id="indent">Architecture:</td>
+					<td class="log-text" id="indent"><xsl:value-of select="@arch"/></td>
+					</tr>
+				</xsl:if>
+			</table>
+		</td>
+	</tr>
+	</xsl:for-each>
+	</xsl:otherwise>
+	</xsl:choose>
+	</table>
+	</body>
+	</html>
+</xsl:for-each>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/tools/eclipse/source_package_readme.txt b/tools/eclipse/source_package_readme.txt
new file mode 100644
index 0000000..456bae7
--- /dev/null
+++ b/tools/eclipse/source_package_readme.txt
@@ -0,0 +1,49 @@
+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/.classpath b/tools/eventanalyzer/.classpath
new file mode 100644
index 0000000..b0326c8
--- /dev/null
+++ b/tools/eventanalyzer/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/eventanalyzer/.project b/tools/eventanalyzer/.project
new file mode 100644
index 0000000..2862978
--- /dev/null
+++ b/tools/eventanalyzer/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>eventanalyzer</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/eventanalyzer/Android.mk b/tools/eventanalyzer/Android.mk
new file mode 100644
index 0000000..18e730e
--- /dev/null
+++ b/tools/eventanalyzer/Android.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+EVENTANALUZER_LOCAL_DIR := $(call my-dir)
+include $(EVENTANALUZER_LOCAL_DIR)/etc/Android.mk
+include $(EVENTANALUZER_LOCAL_DIR)/src/Android.mk
diff --git a/tools/eventanalyzer/etc/Android.mk b/tools/eventanalyzer/etc/Android.mk
new file mode 100644
index 0000000..e7703b4
--- /dev/null
+++ b/tools/eventanalyzer/etc/Android.mk
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_EXECUTABLES := eventanalyzer
+include $(BUILD_HOST_PREBUILT)
+
diff --git a/tools/eventanalyzer/etc/eventanalyzer b/tools/eventanalyzer/etc/eventanalyzer
new file mode 100755
index 0000000..d6c7895
--- /dev/null
+++ b/tools/eventanalyzer/etc/eventanalyzer
@@ -0,0 +1,73 @@
+#!/bin/sh
+# Copyright 2005-2007, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+    newProg=`/bin/ls -ld "${prog}"`
+    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+    if expr "x${newProg}" : 'x/' >/dev/null; then
+        prog="${newProg}"
+    else
+        progdir=`dirname "${prog}"`
+        prog="${progdir}/${newProg}"
+    fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+jarfile=eventanalyzer.jar
+frameworkdir="$progdir"
+libdir="$progdir"
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/tools/lib
+    libdir=`dirname "$progdir"`/tools/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/framework
+    libdir=`dirname "$progdir"`/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    echo `basename "$prog"`": can't find $jarfile"
+    exit 1
+fi
+
+
+# Check args.
+# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
+if [ `uname` = "Darwin" ]; then
+    os_opts="-XstartOnFirstThread"
+else
+    os_opts=
+fi
+
+if [ "$OSTYPE" = "cygwin" ] ; then
+    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
+    progdir=`cygpath -w  "$progdir"`
+else
+    jarpath="$frameworkdir/$jarfile"
+fi
+
+# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
+# might need more memory, e.g. -Xmx128M
+exec java -Xmx128M $os_opts -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -jar "$jarpath" "$@"
diff --git a/tools/eventanalyzer/etc/manifest.txt b/tools/eventanalyzer/etc/manifest.txt
new file mode 100644
index 0000000..6d99ea1
--- /dev/null
+++ b/tools/eventanalyzer/etc/manifest.txt
@@ -0,0 +1 @@
+Main-Class: com.android.eventanalyzer.EventAnalyzer
diff --git a/tools/eventanalyzer/src/Android.mk b/tools/eventanalyzer/src/Android.mk
new file mode 100644
index 0000000..e65c61f
--- /dev/null
+++ b/tools/eventanalyzer/src/Android.mk
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAR_MANIFEST := ../etc/manifest.txt
+LOCAL_JAVA_LIBRARIES := \
+	ddmlib
+LOCAL_MODULE := eventanalyzer
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java b/tools/eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java
new file mode 100644
index 0000000..c520784
--- /dev/null
+++ b/tools/eventanalyzer/src/com/android/eventanalyzer/EventAnalyzer.java
@@ -0,0 +1,484 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.eventanalyzer;
+
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.Device;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.Log.ILogOutput;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmlib.log.EventContainer;
+import com.android.ddmlib.log.EventLogParser;
+import com.android.ddmlib.log.InvalidTypeException;
+import com.android.ddmlib.log.LogReceiver;
+import com.android.ddmlib.log.LogReceiver.ILogListener;
+import com.android.ddmlib.log.LogReceiver.LogEntry;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Set;
+import java.util.TreeMap;
+
+/**
+ * Connects to a device using ddmlib and analyze its event log. 
+ */
+public class EventAnalyzer implements ILogListener {
+    
+    private final static int TAG_ACTIVITY_LAUNCH_TIME = 30009;
+    private final static char DATA_SEPARATOR = ',';
+
+    private final static String CVS_EXT = ".csv";
+    private final static String TAG_FILE_EXT = ".tag"; //$NON-NLS-1$
+    
+    private EventLogParser mParser;
+    private TreeMap<String, ArrayList<Long>> mLaunchMap = new TreeMap<String, ArrayList<Long>>(); 
+    
+    String mInputTextFile = null;
+    String mInputBinaryFile = null;
+    String mInputDevice = null;
+    String mInputFolder = null;
+    String mAlternateTagFile = null;
+    String mOutputFile = null;
+
+    public static void main(String[] args) {
+        new EventAnalyzer().run(args);
+    }
+    
+    private void run(String[] args) {
+        if (args.length == 0) {
+            printUsageAndQuit();
+        }
+        
+        int index = 0;
+        do {
+            String argument = args[index++];
+
+            if ("-s".equals(argument)) {
+                checkInputValidity("-s");
+                
+                if (index == args.length) {
+                    printUsageAndQuit();
+                }
+                
+                mInputDevice = args[index++];
+            } else if ("-fb".equals(argument)) {
+                checkInputValidity("-fb");
+                
+                if (index == args.length) {
+                    printUsageAndQuit();
+                }
+                
+                mInputBinaryFile = args[index++];
+            } else if ("-ft".equals(argument)) {
+                checkInputValidity("-ft");
+                
+                if (index == args.length) {
+                    printUsageAndQuit();
+                }
+                
+                mInputTextFile = args[index++];
+            } else if ("-F".equals(argument)) {
+                checkInputValidity("-F");
+                
+                if (index == args.length) {
+                    printUsageAndQuit();
+                }
+                
+                mInputFolder = args[index++];
+            } else if ("-t".equals(argument)) {
+                if (index == args.length) {
+                    printUsageAndQuit();
+                }
+
+                mAlternateTagFile = args[index++];
+            } else {
+                // get the filepath and break.
+                mOutputFile = argument;
+
+                // should not be any other device.
+                if (index < args.length) {
+                    printAndExit("Too many arguments!", false /* terminate */);
+                }
+            }
+        } while (index < args.length);
+
+        if ((mInputTextFile == null && mInputBinaryFile == null && mInputFolder == null &&
+                mInputDevice == null)) {
+            printUsageAndQuit();
+        }
+
+        File outputParent = new File(mOutputFile).getParentFile();
+        if (outputParent == null || outputParent.isDirectory() == false) {
+            printAndExit(String.format("%1$s is not a valid ouput file", mOutputFile),
+                    false /* terminate */);
+        }
+
+        // redirect the log output to /dev/null
+        Log.setLogOutput(new ILogOutput() {
+            public void printAndPromptLog(LogLevel logLevel, String tag, String message) {
+                // pass
+            }
+
+            public void printLog(LogLevel logLevel, String tag, String message) {
+                // pass
+            }
+        });
+
+        try {
+            if (mInputBinaryFile != null) {
+                parseBinaryLogFile();
+            } else if (mInputTextFile != null) {
+                parseTextLogFile(mInputTextFile);
+            } else if (mInputFolder != null) {
+                parseFolder(mInputFolder);
+            } else if (mInputDevice != null) {
+                parseLogFromDevice();
+            }
+            
+            // analyze the data gathered by the parser methods
+            analyzeData();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+    
+    /**
+     * Parses a binary event log file located at {@link #mInputBinaryFile}.
+     * @throws IOException 
+     */
+    private void parseBinaryLogFile() throws IOException {
+        mParser = new EventLogParser();
+
+        String tagFile = mInputBinaryFile + TAG_FILE_EXT;
+        if (mParser.init(tagFile) == false) {
+            // if we have an alternate location
+            if (mAlternateTagFile != null) {
+                if (mParser.init(mAlternateTagFile) == false) {
+                    printAndExit("Failed to get event tags from " + mAlternateTagFile,
+                            false /* terminate*/);
+                }
+            } else {
+                printAndExit("Failed to get event tags from " + tagFile, false /* terminate*/);
+            }
+        }
+        
+        LogReceiver receiver = new LogReceiver(this);
+
+        byte[] buffer = new byte[256];
+        
+        FileInputStream fis = new FileInputStream(mInputBinaryFile);
+        
+        int count;
+        while ((count = fis.read(buffer)) != -1) {
+            receiver.parseNewData(buffer, 0, count);
+        }
+    }
+
+    /**
+     * Parse a text Log file.
+     * @param filePath the location of the file.
+     * @throws IOException
+     */
+    private void parseTextLogFile(String filePath) throws IOException {
+        mParser = new EventLogParser();
+
+        String tagFile = filePath + TAG_FILE_EXT;
+        if (mParser.init(tagFile) == false) {
+            // if we have an alternate location
+            if (mAlternateTagFile != null) {
+                if (mParser.init(mAlternateTagFile) == false) {
+                    printAndExit("Failed to get event tags from " + mAlternateTagFile,
+                            false /* terminate*/);
+                }
+            } else {
+                printAndExit("Failed to get event tags from " + tagFile, false /* terminate*/);
+            }
+        }
+
+        // read the lines from the file and process them.
+        BufferedReader reader = new BufferedReader(
+                new InputStreamReader(new FileInputStream(filePath)));
+
+        String line;
+        while ((line = reader.readLine()) != null) {
+            processEvent(mParser.parse(line));
+        }
+    }
+
+    private void parseLogFromDevice() throws IOException {
+        // init the lib
+        AndroidDebugBridge.init(false /* debugger support */);
+        
+        try {
+            AndroidDebugBridge bridge = AndroidDebugBridge.createBridge();
+            
+            // we can't just ask for the device list right away, as the internal thread getting
+            // them from ADB may not be done getting the first list.
+            // Since we don't really want getDevices() to be blocking, we wait here manually.
+            int count = 0;
+            while (bridge.hasInitialDeviceList() == false) {
+                try {
+                    Thread.sleep(100);
+                    count++;
+                } catch (InterruptedException e) {
+                    // pass
+                }
+                
+                // let's not wait > 10 sec.
+                if (count > 100) {
+                    printAndExit("Timeout getting device list!", true /* terminate*/);
+                }
+            }
+
+            // now get the devices
+            Device[] devices = bridge.getDevices();
+            
+            for (Device device : devices) {
+                if (device.getSerialNumber().equals(mInputDevice)) {
+                    grabLogFrom(device);
+                    return;
+                }
+            }
+            
+            System.err.println("Could not find " + mInputDevice);
+        } finally {
+            AndroidDebugBridge.terminate();
+        }
+    }
+    
+    /**
+     * Parses the log files located in the folder, and its sub-folders.
+     * @param folderPath the path to the folder.
+     */
+    private void parseFolder(String folderPath) {
+        File f = new File(folderPath);
+        if (f.isDirectory() == false) {
+            printAndExit(String.format("%1$s is not a valid folder", folderPath),
+                    false /* terminate */);
+        }
+        
+        String[] files = f.list(new FilenameFilter() {
+            public boolean accept(File dir, String name) {
+                name = name.toLowerCase();
+                return name.endsWith(".tag") == false;
+            }
+        });
+        
+        for (String file : files) {
+            try {
+                f = new File(folderPath + File.separator + file);
+                if (f.isDirectory()) {
+                    parseFolder(f.getAbsolutePath());
+                } else {
+                    parseTextLogFile(f.getAbsolutePath());
+                }
+            } catch (IOException e) {
+                // ignore this file.
+            }
+        }
+    }
+
+    private void grabLogFrom(Device device) throws IOException {
+        mParser = new EventLogParser();
+        if (mParser.init(device) == false) {
+            printAndExit("Failed to get event-log-tags from " + device.getSerialNumber(),
+                    true /* terminate*/);
+        }
+        
+        LogReceiver receiver = new LogReceiver(this);
+
+        device.runEventLogService(receiver);
+    }
+    
+    /**
+     * Analyze the data and writes it to {@link #mOutputFile}
+     * @throws IOException
+     */
+    private void analyzeData() throws IOException {
+        BufferedWriter writer = null;
+        try {
+            // make sure the file name has the proper extension.
+            if (mOutputFile.toLowerCase().endsWith(CVS_EXT) == false) {
+                mOutputFile = mOutputFile + CVS_EXT;
+            }
+
+            writer = new BufferedWriter(new FileWriter(mOutputFile));
+            StringBuilder builder = new StringBuilder();
+            
+            // write the list of launch start. One column per activity.
+            Set<String> activities = mLaunchMap.keySet();
+            
+            // write the column headers.
+            for (String activity : activities) {
+                builder.append(activity).append(DATA_SEPARATOR);
+            }
+            writer.write(builder.append('\n').toString());
+            
+            // loop on the activities and write their values.
+            boolean moreValues = true;
+            int index = 0;
+            while (moreValues) {
+                moreValues = false;
+                builder.setLength(0);
+                
+                for (String activity : activities) {
+                    // get the activity list.
+                    ArrayList<Long> list = mLaunchMap.get(activity);
+                    if (index < list.size()) {
+                        moreValues = true;
+                        builder.append(list.get(index).longValue()).append(DATA_SEPARATOR);
+                    } else {
+                        builder.append(DATA_SEPARATOR);
+                    }
+                }
+                
+                // write the line.
+                if (moreValues) {
+                    writer.write(builder.append('\n').toString());
+                }
+                
+                index++;
+            }
+            
+            // write per-activity stats.
+            for (String activity : activities) {
+                builder.setLength(0);
+                builder.append(activity).append(DATA_SEPARATOR);
+    
+                // get the activity list.
+                ArrayList<Long> list = mLaunchMap.get(activity);
+                
+                // sort the list
+                Collections.sort(list);
+                
+                // write min/max
+                builder.append(list.get(0).longValue()).append(DATA_SEPARATOR);
+                builder.append(list.get(list.size()-1).longValue()).append(DATA_SEPARATOR);
+    
+                // write median value
+                builder.append(list.get(list.size()/2).longValue()).append(DATA_SEPARATOR);
+                
+                // compute and write average
+                long total = 0; // despite being encoded on a long, the values are low enough that
+                                // a Long should be enough to compute the total
+                for (Long value : list) {
+                    total += value.longValue();
+                }
+                builder.append(total / list.size()).append(DATA_SEPARATOR);
+                
+                // finally write the data.
+                writer.write(builder.append('\n').toString());
+            }
+        } finally {
+            writer.close();
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.log.LogReceiver.ILogListener#newData(byte[], int, int)
+     */
+    public void newData(byte[] data, int offset, int length) {
+        // we ignore raw data. New entries are processed in #newEntry(LogEntry)
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see com.android.ddmlib.log.LogReceiver.ILogListener#newEntry(com.android.ddmlib.log.LogReceiver.LogEntry)
+     */
+    public void newEntry(LogEntry entry) {
+        // parse and process the entry data.
+        processEvent(mParser.parse(entry));
+    }
+    
+    private void processEvent(EventContainer event) {
+        if (event != null && event.mTag == TAG_ACTIVITY_LAUNCH_TIME) {
+            // get the activity name
+            try {
+                String name = event.getValueAsString(0);
+
+                // get the launch time
+                Object value = event.getValue(1);
+                if (value instanceof Long) {
+                    addLaunchTime(name, (Long)value);
+                }
+
+            } catch (InvalidTypeException e) {
+                // Couldn't get the name as a string...
+                // Ignore this event.
+            }
+        }
+    }
+
+    private void addLaunchTime(String name, Long value) {
+        ArrayList<Long> list = mLaunchMap.get(name);
+        
+        if (list == null) {
+            list = new ArrayList<Long>();
+            mLaunchMap.put(name, list);
+        }
+        
+        list.add(value);
+    }
+
+    private void checkInputValidity(String option) {
+        if (mInputTextFile != null || mInputBinaryFile != null) {
+            printAndExit(String.format("ERROR: %1$s cannot be used with an input file.", option),
+                    false /* terminate */);
+        } else if (mInputFolder != null) {
+            printAndExit(String.format("ERROR: %1$s cannot be used with an input file.", option),
+                    false /* terminate */);
+        } else if (mInputDevice != null) {
+            printAndExit(String.format("ERROR: %1$s cannot be used with an input device serial number.",
+                    option), false /* terminate */);
+        }
+    }
+
+    private static void printUsageAndQuit() {
+        // 80 cols marker:  01234567890123456789012345678901234567890123456789012345678901234567890123456789
+        System.out.println("Usage:");
+        System.out.println("   eventanalyzer [-t <TAG_FILE>] <SOURCE> <OUTPUT>");
+        System.out.println("");
+        System.out.println("Possible sources:");
+        System.out.println("   -fb <file>    The path to a binary event log, gathered by dumpeventlog");
+        System.out.println("   -ft <file>    The path to a text event log, gathered by adb logcat -b events");
+        System.out.println("   -F <folder>   The path to a folder containing multiple text log files.");
+        System.out.println("   -s <serial>   The serial number of the Device to grab the event log from.");
+        System.out.println("Options:");
+        System.out.println("   -t <file>     The path to tag file to use in case the one associated with");
+        System.out.println("                 the source is missing");
+        
+        System.exit(1);
+    }
+    
+    
+    private static void printAndExit(String message, boolean terminate) {
+        System.out.println(message);
+        if (terminate) {
+            AndroidDebugBridge.terminate();
+        }
+        System.exit(1);
+    }
+}
diff --git a/tools/findunused/find_unused_resources.rb b/tools/findunused/find_unused_resources.rb
new file mode 100755
index 0000000..515b266
--- /dev/null
+++ b/tools/findunused/find_unused_resources.rb
@@ -0,0 +1,235 @@
+#!/usr/bin/ruby
+#
+# Find unused resources in all the apps found recursively under the current directory
+# Usage:
+#   find_unused_resources.rb [-html]
+#
+# If -html is specified, the output will be HTML, otherwise it will be plain text
+#
+# Author: cbeust@google.com
+
+require 'find'
+
+debug = false
+
+@@stringIdPattern = Regexp.new("name=\"([@_a-zA-Z0-9 ]*)\"")
+@@layoutIdPattern = Regexp.new("android:id=\".*id/([_a-zA-Z0-9]*)\"")
+
+@@stringXmlPatterns = [
+  Regexp.new("@string/([_a-zA-Z0-9]*)"),
+  Regexp.new("@array/([_a-zA-Z0-9]*)"),
+]
+
+@@javaIdPatterns = [
+  Regexp.new("R.id.([_a-zA-Z0-9]+)"),
+  Regexp.new("R.string.([_a-zA-Z0-9]+)"),
+  Regexp.new("R.array.([_a-zA-Z0-9]+)"),
+  Regexp.new("R.color.([_a-zA-Z0-9]+)"),
+  Regexp.new("R.configVarying.([_a-zA-Z0-9]+)"),
+  Regexp.new("R.dimen.([_a-zA-Z0-9]+)"),
+]
+
+
+@@appDir = "partner/google/apps/Gmail"
+
+def findResDirectories(root)
+  result = Array.new
+  Find.find(root) do |path|
+    if FileTest.directory?(path)
+      if File.basename(path) == "res"
+        result << path
+      else
+        next
+      end
+    end
+  end
+  result
+end
+
+class UnusedResources
+  attr_accessor :appDir, :unusedLayoutIds, :unusedStringIds
+end
+
+class FilePosition
+  attr_accessor :file, :lineNumber
+
+  def initialize(f, ln)
+    @file = f
+    @lineNumber = ln
+  end
+
+  def to_s
+    "#{file}:#{lineNumber}"
+  end
+
+  def <=>(other)
+    if @file == other.file
+      @lineNumber - other.lineNumber
+    else
+      @file <=> other.file
+    end
+  end
+end
+
+
+def findAllOccurrences(re, string)
+  result = Array.new
+
+  s = string
+  matchData = re.match(s)
+  while (matchData)
+    result << matchData[1].to_s
+    s = s[matchData.end(1) .. -1]
+    matchData = re.match(s)
+  end
+
+  result
+end
+
+@@globalJavaIdUses = Hash.new
+
+def recordJavaUses(glob)
+  Dir.glob(glob).each { |filename|
+    File.open(filename) { |file|
+      file.each { |line|
+	@@javaIdPatterns.each { |re|
+          findAllOccurrences(re, line).each { |id|
+            @@globalJavaIdUses[id] = FilePosition.new(filename, file.lineno)
+	  }
+        }
+      }
+    }
+  }
+end
+
+def findUnusedResources(dir)
+  javaIdUses = Hash.new
+  layouts = Hash.new
+  strings = Hash.new
+  xmlIdUses = Hash.new
+
+  Dir.glob("#{dir}/res/**/*.xml").each { |filename|
+    if ! (filename =~ /attrs.xml$/)
+      File.open(filename) { |file|
+        file.each { |line|
+          findAllOccurrences(@@stringIdPattern, line).each {|id|
+            strings[id] = FilePosition.new(filename, file.lineno)
+          }
+          findAllOccurrences(@@layoutIdPattern, line).each {|id|
+            layouts[id] = FilePosition.new(filename, file.lineno)
+          }
+          @@stringXmlPatterns.each { |re|
+            findAllOccurrences(re, line).each {|id|
+              xmlIdUses[id] = FilePosition.new(filename, file.lineno)
+            }
+          }
+        }
+      }
+    end
+  }
+ 
+  Dir.glob("#{dir}/AndroidManifest.xml").each { |filename|
+    File.open(filename) { |file|
+      file.each { |line|
+        @@stringXmlPatterns.each { |re|
+          findAllOccurrences(re, line).each {|id|
+            xmlIdUses[id] = FilePosition.new(filename, file.lineno)
+          }
+        }
+      }
+    }
+  }
+
+  recordJavaUses("#{dir}/src/**/*.java")
+
+  @@globalJavaIdUses.each_pair { |id, file|
+    layouts.delete(id)
+    strings.delete(id)
+  }
+
+  javaIdUses.each_pair { |id, file|
+    layouts.delete(id)
+    strings.delete(id)
+  }
+
+  xmlIdUses.each_pair { |id, file|
+    layouts.delete(id)
+    strings.delete(id)
+  }
+
+  result = UnusedResources.new
+  result.appDir = dir
+  result.unusedLayoutIds = layouts
+  result.unusedStringIds = strings
+
+  result
+end
+
+def findApps(dir)
+  result = Array.new
+  Dir.glob("#{dir}/**/res").each { |filename|
+    a = filename.split("/")
+    result << a.slice(0, a.size-1).join("/")
+  }
+  result
+end
+
+def displayText(result)
+  result.each { |unusedResources|
+    puts "=== #{unusedResources.appDir}"
+
+    puts "----- Unused layout ids"
+    unusedResources.unusedLayoutIds.sort { |id, file| id[1] <=> file[1] }.each {|f|
+      puts "    #{f[0]} #{f[1]}"
+    }
+
+ 
+    puts "----- Unused string ids"
+    unusedResources.unusedStringIds.sort { |id, file| id[1] <=> file[1] }.each {|f|
+      puts "    #{f[0]} #{f[1]}"
+    }
+ 
+  }
+end
+
+def displayHtmlUnused(unusedResourceIds, title)
+
+  puts "<h3>#{title}</h3>"
+  puts "<table border='1'>"
+  unusedResourceIds.sort { |id, file| id[1] <=> file[1] }.each {|f|
+    puts "<tr><td><b>#{f[0]}</b></td> <td>#{f[1]}</td></tr>"
+  }
+  puts "</table>"
+end
+
+def displayHtml(result)
+  title = "Unused resources as of #{Time.now.localtime}"
+  puts "<html><header><title>#{title}</title></header><body>"
+
+  puts "<h1><p align=\"center\">#{title}</p></h1>"
+  result.each { |unusedResources|
+    puts "<h2>#{unusedResources.appDir}</h2>"
+    displayHtmlUnused(unusedResources.unusedLayoutIds, "Unused layout ids")
+    displayHtmlUnused(unusedResources.unusedStringIds, "Unused other ids")
+  }
+  puts "</body>"
+end
+
+result = Array.new
+
+recordJavaUses("java/android/**/*.java")
+
+if debug
+  result << findUnusedResources("apps/Browser")
+else 
+  findApps(".").each { |appDir|
+    result << findUnusedResources(appDir)
+  }
+end
+
+if ARGV[0] == "-html"
+  displayHtml result
+else
+  displayText result
+end
+
diff --git a/tools/findunused/findunusedresources b/tools/findunused/findunusedresources
new file mode 100755
index 0000000..748139a
--- /dev/null
+++ b/tools/findunused/findunusedresources
@@ -0,0 +1,74 @@
+#!/bin/sh
+
+if [ "$1" == "-h" ]
+then
+    cat <<- EOH
+		    Usage: $0 [-p] [folder]
+		      -p option prints out unused resources, otherwise a total count is printed
+		      folder option causes only that app folder to be scanned, default is to scan all folders onder apps/
+		EOH
+    exit
+fi
+
+showall=no
+if [ "$1" == "-p" ]
+then
+    showall=yes
+    shift
+fi
+
+apps=$1
+if [ "$apps" == "" ]
+then
+    apps=$ANDROID_BUILD_TOP/packages/apps/*
+fi
+
+for app in $apps
+do
+    echo '-----------------------------------------------------------'
+    if [ -d $app/res ]
+    then
+        appname=$(basename $app)
+        resources=
+        for res in $(echo $app/res/*)
+        do
+            resources="$resources $(echo $res | grep -v '\-mcc\|[a-z]*-[a-z][a-z]$\|[a-z]*-[a-z][a-z]-.*')"
+        done
+        sources=$app/src
+        if [ -d $app/tests ]
+        then
+            sources="$sources $app/tests"
+        fi
+        if [ -d $app/samples ]
+        then
+            sources="$sources $app/samples"
+        fi
+
+        # find the R.java file that contains all the generated resource identifiers
+        rDotJava=$(find out/target/common/obj/APPS/${appname}_intermediates/ -name R.java)
+
+        # Simplistically process the content of the file to get the names of all the constants,
+        # and try to find a reference to each constant.
+        for i in $(cat $rDotJava | grep "\w*=0x\d*" | sed 's/ *public static final int //' | sed 's/=0x.*//')
+        do
+            # Since periods in the names get translated to underscores in R.java, and you can actually
+            # refer to such constants from java by using an underscore instead of a period, we also
+            # replace all underscores with a pattern that will match periods and underscores.
+            p=$(echo $i | sed 's/_/[\\._]/g')
+            echo $i $(grep -Rw R\\..*\\.$i\\\|@style/$p\\\|@drawable/$p\\\|@anim/$p\\\|@color/$p\\\|@xml/$p\\\|@layout/$p\\\|@menu/$p\\\|@+id/$p\\\|@array/$p\\\|@string/$p\\\|@dimen/$p $resources $sources $app/AndroidManifest.xml | wc -l)
+        done | grep " 0$" | {
+            # this block gets as its input a list of constants which no references were found, one per line
+            if [ "$showall" == "yes" ]
+            then
+                echo $app
+                cat
+            else
+                count=$(wc -l)
+                if [ "$count" != "0" ]
+                then
+                    echo $app: $count unused resources
+                fi
+            fi
+        }
+    fi
+done
diff --git a/tools/findunused/findunusedstrings b/tools/findunused/findunusedstrings
new file mode 100755
index 0000000..a54b060
--- /dev/null
+++ b/tools/findunused/findunusedstrings
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+if [ "$1" == "-h" ]
+then
+    cat <<- EOH
+		    Usage: $0 [-p] [folder]
+		      -p option prints out unused strings, otherwise a total count is printed
+		      folder option causes only that app folder to be scanned, default is to scan all folders onder apps/
+		EOH
+    exit
+fi
+
+showall=no
+if [ "$1" == "-p" ]
+then
+    showall=yes
+    shift
+fi
+
+apps=$1
+if [ "$apps" == "" ]
+then
+    apps=$ANDROID_BUILD_TOP/packages/apps/*
+fi
+
+for app in $apps
+do
+    if [ -d $app/res ]
+    then
+        pushd $app > /dev/null
+        for i in $(grep -R "\(string\|plurals\) name=" res | sed 's/.*<\(string\|plurals\) name="//'|sed 's/".*$//'|sort -u)
+        do
+            echo $i $(grep -Rw R.plurals.$i\\\|R.string.$i\\\|@string/$i .|wc -l)
+        done | grep ' 0$' | {
+            if [ "$showall" == "yes" ]
+            then
+                echo $app
+                cat
+            else
+                count=$(wc -l)
+                if [ "$count" != "0" ]
+                then
+                    echo $app: $count unused strings
+                fi
+            fi
+        }
+        popd $app > /dev/null
+    fi
+done
diff --git a/tools/hierarchyviewer/Android.mk b/tools/hierarchyviewer/Android.mk
new file mode 100644
index 0000000..110e2ed
--- /dev/null
+++ b/tools/hierarchyviewer/Android.mk
@@ -0,0 +1,17 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+HIERARCHYVIEWER_LOCAL_DIR := $(call my-dir)
+include $(HIERARCHYVIEWER_LOCAL_DIR)/etc/Android.mk
+include $(HIERARCHYVIEWER_LOCAL_DIR)/src/Android.mk
diff --git a/tools/hierarchyviewer/MODULE_LICENSE_APACHE2 b/tools/hierarchyviewer/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/hierarchyviewer/MODULE_LICENSE_APACHE2
diff --git a/tools/hierarchyviewer/etc/Android.mk b/tools/hierarchyviewer/etc/Android.mk
new file mode 100644
index 0000000..2794a7f
--- /dev/null
+++ b/tools/hierarchyviewer/etc/Android.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_EXECUTABLES := hierarchyviewer
+include $(BUILD_HOST_PREBUILT)
+
diff --git a/tools/hierarchyviewer/etc/hierarchyviewer b/tools/hierarchyviewer/etc/hierarchyviewer
new file mode 100755
index 0000000..4244434
--- /dev/null
+++ b/tools/hierarchyviewer/etc/hierarchyviewer
@@ -0,0 +1,63 @@
+#!/bin/sh
+# Copyright 2008, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+    newProg=`/bin/ls -ld "${prog}"`
+    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+    if expr "x${newProg}" : 'x/' >/dev/null; then
+        prog="${newProg}"
+    else
+        progdir=`dirname "${prog}"`
+        prog="${progdir}/${newProg}"
+    fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+jarfile=hierarchyviewer.jar
+frameworkdir="$progdir"
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/tools/lib
+    libdir=`dirname "$progdir"`/tools/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/framework
+    libdir=`dirname "$progdir"`/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    echo `basename "$prog"`": can't find $jarfile"
+    exit 1
+fi
+
+if [ "$OSTYPE" = "cygwin" ] ; then
+    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
+    progdir=`cygpath -w  "$progdir"`
+else
+    jarpath="$frameworkdir/$jarfile"
+fi
+
+# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
+# might need more memory, e.g. -Xmx128M
+exec java -Xmx512M -Djava.ext.dirs="$frameworkdir" -Dhierarchyviewer.adb="$progdir" -jar "$jarpath" "$@"
diff --git a/tools/hierarchyviewer/etc/hierarchyviewer.bat b/tools/hierarchyviewer/etc/hierarchyviewer.bat
new file mode 100755
index 0000000..2024a79
--- /dev/null
+++ b/tools/hierarchyviewer/etc/hierarchyviewer.bat
@@ -0,0 +1,41 @@
+@echo off
+rem Copyright (C) 2008 The Android Open Source Project
+rem
+rem Licensed under the Apache License, Version 2.0 (the "License");
+rem you may not use this file except in compliance with the License.
+rem You may obtain a copy of the License at
+rem
+rem      http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+
+rem don't modify the caller's environment
+setlocal
+
+rem Set up prog to be the path of this script, including following symlinks,
+rem and set up progdir to be the fully-qualified pathname of its directory.
+set prog=%~f0
+
+rem Change current directory and drive to where the script is, to avoid
+rem issues with directories containing whitespaces.
+cd /d %~dp0
+
+set jarfile=hierarchyviewer.jar
+set frameworkdir=
+set libdir=
+
+if exist %frameworkdir%%jarfile% goto JarFileOk
+    set frameworkdir=lib\
+
+if exist %frameworkdir%%jarfile% goto JarFileOk
+    set frameworkdir=..\framework\
+
+:JarFileOk
+
+set jarpath=%frameworkdir%%jarfile%
+
+call java -Xmx512m -Djava.ext.dirs=%frameworkdir% -Dhierarchyviewer.adb= -jar %jarpath% %*
diff --git a/tools/hierarchyviewer/etc/manifest.txt b/tools/hierarchyviewer/etc/manifest.txt
new file mode 100644
index 0000000..f7ddfa9
--- /dev/null
+++ b/tools/hierarchyviewer/etc/manifest.txt
@@ -0,0 +1,2 @@
+Main-Class: com.android.hierarchyviewer.HierarchyViewer
+Class-Path: ddmlib.jar swing-worker-1.1.jar org-openide-util.jar org-netbeans-api-visual.jar
diff --git a/tools/hierarchyviewer/src/Android.mk b/tools/hierarchyviewer/src/Android.mk
new file mode 100644
index 0000000..0bc1f1e
--- /dev/null
+++ b/tools/hierarchyviewer/src/Android.mk
@@ -0,0 +1,30 @@
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_JAVA_RESOURCE_DIRS := resources
+
+LOCAL_JAR_MANIFEST := ../etc/manifest.txt
+LOCAL_JAVA_LIBRARIES := \
+	ddmlib \
+	swing-worker-1.1 \
+	org-openide-util \
+	org-netbeans-api-visual
+LOCAL_MODULE := hierarchyviewer
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/HierarchyViewer.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/HierarchyViewer.java
new file mode 100644
index 0000000..59ce67f
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/HierarchyViewer.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer;
+
+import com.android.hierarchyviewer.ui.Workspace;
+import com.android.hierarchyviewer.device.DeviceBridge;
+
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+
+public class HierarchyViewer {
+    private static final CharSequence OS_WINDOWS = "Windows";
+    private static final CharSequence OS_MACOSX = "Mac OS X";
+
+    private static void initUserInterface() {
+        System.setProperty("apple.laf.useScreenMenuBar", "true");
+        System.setProperty("apple.awt.brushMetalLook", "true");
+        System.setProperty("com.apple.mrj.application.apple.menu.about.name", "HierarchyViewer");
+
+        final String os = System.getProperty("os.name");
+
+        try {
+            if (os.contains(OS_WINDOWS) || os.contains(OS_MACOSX)) {
+                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+            } else {
+                UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());                
+            }
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
+        } catch (InstantiationException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        } catch (UnsupportedLookAndFeelException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void main(String[] args) {
+        initUserInterface();
+        DeviceBridge.initDebugBridge();
+
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                Workspace workspace = new Workspace();
+                workspace.setDefaultCloseOperation(Workspace.EXIT_ON_CLOSE);
+                workspace.setLocationRelativeTo(null);
+                workspace.setVisible(true);
+            }
+        });
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/Configuration.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/Configuration.java
new file mode 100644
index 0000000..090730f
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/Configuration.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.device;
+
+public class Configuration {
+    public static final int DEFAULT_SERVER_PORT = 4939;
+
+    // These codes must match the auto-generated codes in IWindowManager.java
+    // See IWindowManager.aidl as well
+    public static final int SERVICE_CODE_START_SERVER = 1;
+    public static final int SERVICE_CODE_STOP_SERVER = 2;
+    public static final int SERVICE_CODE_IS_SERVER_RUNNING = 3;
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java
new file mode 100644
index 0000000..850a238
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/DeviceBridge.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.device;
+
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.Device;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.MultiLineReceiver;
+
+import java.io.IOException;
+import java.io.File;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DeviceBridge {
+    private static AndroidDebugBridge bridge;
+    
+    private static final HashMap<Device, Integer> devicePortMap = new HashMap<Device, Integer>();
+    private static int nextLocalPort = Configuration.DEFAULT_SERVER_PORT;
+
+    public static void initDebugBridge() {
+        if (bridge == null) {
+            AndroidDebugBridge.init(false /* debugger support */);
+        }
+        if (bridge == null || !bridge.isConnected()) {
+            String adbLocation = System.getProperty("hierarchyviewer.adb");
+            if (adbLocation != null && adbLocation.length() != 0) {
+                adbLocation += File.separator + "adb";
+            } else {
+                adbLocation = "adb";
+            }
+
+            bridge = AndroidDebugBridge.createBridge(adbLocation, true);
+        }
+    }
+
+    public static void startListenForDevices(AndroidDebugBridge.IDeviceChangeListener listener) {
+        AndroidDebugBridge.addDeviceChangeListener(listener);
+    }
+
+    public static void stopListenForDevices(AndroidDebugBridge.IDeviceChangeListener listener) {
+        AndroidDebugBridge.removeDeviceChangeListener(listener);
+    }
+
+    public static Device[] getDevices() {
+        return bridge.getDevices();
+    }
+
+    public static boolean isViewServerRunning(Device device) {
+        initDebugBridge();
+        final boolean[] result = new boolean[1];
+        try {
+            if (device.isOnline()) {
+                device.executeShellCommand(buildIsServerRunningShellCommand(),
+                        new BooleanResultReader(result));
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return result[0];
+    }
+
+    public static boolean startViewServer(Device device) {
+        return startViewServer(device, Configuration.DEFAULT_SERVER_PORT);
+    }
+
+    public static boolean startViewServer(Device device, int port) {
+        initDebugBridge();
+        final boolean[] result = new boolean[1];
+        try {
+            if (device.isOnline()) {
+                device.executeShellCommand(buildStartServerShellCommand(port),
+                        new BooleanResultReader(result));
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return result[0];
+    }
+
+    public static boolean stopViewServer(Device device) {
+        initDebugBridge();
+        final boolean[] result = new boolean[1];
+        try {
+            if (device.isOnline()) {
+                device.executeShellCommand(buildStopServerShellCommand(),
+                        new BooleanResultReader(result));
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return result[0];
+    }
+
+    public static void terminate() {
+        AndroidDebugBridge.terminate();
+    }
+
+    /**
+     * Sets up a just-connected device to work with the view server.
+     * <p/>This starts a port forwarding between a local port and a port on the device.
+     * @param device
+     */
+    public static void setupDeviceForward(Device device) {
+        synchronized (devicePortMap) {
+            if (device.getState() == Device.DeviceState.ONLINE) {
+                int localPort = nextLocalPort++;
+                device.createForward(localPort, Configuration.DEFAULT_SERVER_PORT);
+                devicePortMap.put(device, localPort);
+            }
+        }
+    }
+    
+    public static void removeDeviceForward(Device device) {
+        synchronized (devicePortMap) {
+            final Integer localPort = devicePortMap.get(device);
+            if (localPort != null) {
+                device.removeForward(localPort, Configuration.DEFAULT_SERVER_PORT);
+                devicePortMap.remove(device);
+            }
+        }
+    }
+    
+    public static int getDeviceLocalPort(Device device) {
+        synchronized (devicePortMap) {
+            Integer port = devicePortMap.get(device);
+            if (port != null) {
+                return port;
+            }
+            
+            Log.e("hierarchy", "Missing forwarded port for " + device.getSerialNumber());
+            return -1;
+        }
+        
+    }
+
+    private static String buildStartServerShellCommand(int port) {
+        return String.format("service call window %d i32 %d",
+                Configuration.SERVICE_CODE_START_SERVER, port);
+    }
+
+    private static String buildStopServerShellCommand() {
+        return String.format("service call window %d", Configuration.SERVICE_CODE_STOP_SERVER);
+    }
+
+    private static String buildIsServerRunningShellCommand() {
+        return String.format("service call window %d",
+                Configuration.SERVICE_CODE_IS_SERVER_RUNNING);
+    }
+
+    private static class BooleanResultReader extends MultiLineReceiver {
+        private final boolean[] mResult;
+
+        public BooleanResultReader(boolean[] result) {
+            mResult = result;
+        }
+
+        @Override
+        public void processNewLines(String[] strings) {
+            if (strings.length > 0) {
+                Pattern pattern = Pattern.compile(".*?\\([0-9]{8} ([0-9]{8}).*");
+                Matcher matcher = pattern.matcher(strings[0]);
+                if (matcher.matches()) {
+                    if (Integer.parseInt(matcher.group(1)) == 1) {
+                        mResult[0] = true;
+                    }
+                }
+            }
+        }
+
+        public boolean isCancelled() {
+            return false;
+        }
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/Window.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/Window.java
new file mode 100644
index 0000000..0417df6
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/device/Window.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.device;
+
+public class Window {
+    public static final Window FOCUSED_WINDOW = new Window("<Focused Window>", -1);
+
+    private String title;
+    private int hashCode;
+
+    public Window(String title, int hashCode) {
+        this.title = title;
+        this.hashCode = hashCode;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public int getHashCode() {
+        return hashCode;
+    }
+
+    public String encode() {
+        return Integer.toHexString(hashCode);
+    }
+
+    public String toString() {
+        return title;
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/laf/UnifiedContentBorder.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/laf/UnifiedContentBorder.java
new file mode 100644
index 0000000..401fb3e
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/laf/UnifiedContentBorder.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.laf;
+
+import javax.swing.border.AbstractBorder;
+import java.awt.*;
+
+public class UnifiedContentBorder extends AbstractBorder {
+    private static final Color BORDER_TOP_COLOR1 = new Color(0x575757);
+    private static final Color BORDER_BOTTOM_COLOR1 = new Color(0x404040);
+    private static final Color BORDER_BOTTOM_COLOR2 = new Color(0xd8d8d8);
+
+    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
+        g.setColor(BORDER_TOP_COLOR1);
+        g.drawLine(x, y, x + width, y);
+        g.setColor(BORDER_BOTTOM_COLOR1);
+        g.drawLine(x, y + height - 2, x + width, y + height - 2);
+        g.setColor(BORDER_BOTTOM_COLOR2);
+        g.drawLine(x, y + height - 1, x + width, y + height - 1);
+    }
+
+    public Insets getBorderInsets(Component component) {
+        return new Insets(1, 0, 2, 0);
+    }
+
+    public boolean isBorderOpaque() {
+        return true;
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/CaptureLoader.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/CaptureLoader.java
new file mode 100644
index 0000000..7cc44bc
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/CaptureLoader.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.scene;
+
+import com.android.ddmlib.Device;
+import com.android.hierarchyviewer.device.Configuration;
+import com.android.hierarchyviewer.device.Window;
+import com.android.hierarchyviewer.device.DeviceBridge;
+
+import java.awt.Image;
+import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import javax.imageio.ImageIO;
+
+public class CaptureLoader {
+    public static Image loadCapture(Device device, Window window, String params) {
+        Socket socket = null;
+        BufferedInputStream in = null;
+        BufferedWriter out = null;
+        
+        try {
+            socket = new Socket();
+            socket.connect(new InetSocketAddress("127.0.0.1",
+                    DeviceBridge.getDeviceLocalPort(device)));
+            
+            out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
+            in = new BufferedInputStream(socket.getInputStream());
+
+            out.write("CAPTURE " + window.encode() + " " + params);
+            out.newLine();
+            out.flush();
+
+            return ImageIO.read(in);
+        } catch (IOException e) {
+            // Empty
+        } finally {
+            try {
+                if (out != null) {
+                    out.close();
+                }
+                if (in != null) {
+                    in.close();
+                }
+                if (socket != null) {
+                    socket.close();
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+        }
+        
+        return null;
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java
new file mode 100644
index 0000000..1f3e278
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.scene;
+
+import com.android.ddmlib.Device;
+import com.android.hierarchyviewer.device.DeviceBridge;
+import com.android.hierarchyviewer.device.Window;
+
+import org.openide.util.Exceptions;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Stack;
+import java.util.regex.Pattern;
+
+public class ViewHierarchyLoader {
+    @SuppressWarnings("empty-statement")
+    public static ViewHierarchyScene loadScene(Device device, Window window) {
+        ViewHierarchyScene scene = new ViewHierarchyScene();
+
+        // Read the views tree
+        Socket socket = null;
+        BufferedReader in = null;
+        BufferedWriter out = null;
+        
+        String line;
+        
+        try {
+            System.out.println("==> Starting client");
+            
+            socket = new Socket();
+            socket.connect(new InetSocketAddress("127.0.0.1",
+                    DeviceBridge.getDeviceLocalPort(device)));
+
+            out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
+            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+            System.out.println("==> DUMP");
+            
+            out.write("DUMP " + window.encode());
+            out.newLine();
+            out.flush();
+            
+            Stack<ViewNode> stack = new Stack<ViewNode>();
+
+            boolean setRoot = true;
+            ViewNode lastNode = null;
+            int lastWhitespaceCount = Integer.MAX_VALUE;
+
+            while ((line = in.readLine()) != null) {
+                if ("DONE.".equalsIgnoreCase(line)) {
+                    break;
+                }
+                
+                int whitespaceCount = countFrontWhitespace(line);
+                if (lastWhitespaceCount < whitespaceCount) {
+                    stack.push(lastNode);
+                } else if (!stack.isEmpty()) {
+                    final int count = lastWhitespaceCount - whitespaceCount;
+                    for (int i = 0; i < count; i++) {
+                        stack.pop();
+                    }
+                }
+
+                lastWhitespaceCount = whitespaceCount;
+                line = line.trim();
+                int index = line.indexOf(' ');
+                
+                lastNode = new ViewNode();
+                lastNode.name = line.substring(0, index);
+
+                line = line.substring(index + 1);
+                loadProperties(lastNode, line);
+
+                scene.addNode(lastNode);
+                
+                if (setRoot) {
+                    scene.setRoot(lastNode);
+                    setRoot = false;
+                }
+                
+                if (!stack.isEmpty()) {
+                    final ViewNode parent = stack.peek();
+                    final String edge = parent.name + lastNode.name;
+                    scene.addEdge(edge);
+                    scene.setEdgeSource(edge, parent);
+                    scene.setEdgeTarget(edge, lastNode);
+                    lastNode.parent = parent;
+                    parent.children.add(lastNode);
+                }
+            }
+
+            updateIndices(scene.getRoot());
+
+        } catch (IOException ex) {
+            Exceptions.printStackTrace(ex);
+        } finally {
+            try {
+                if (out != null) {
+                    out.close();
+                }
+                if (in != null) {
+                    in.close();
+                }
+                socket.close();
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+        }
+        
+        System.out.println("==> DONE");
+
+        return scene;
+    }
+
+    private static void updateIndices(ViewNode root) {
+        if (root == null) return;
+
+        root.computeIndex();
+
+        for (ViewNode node : root.children) {
+            updateIndices(node);
+        }
+    }
+
+    private static int countFrontWhitespace(String line) {
+        int count = 0;
+        while (line.charAt(count) == ' ') {
+            count++;
+        }
+        return count;
+    }
+
+    private static void loadProperties(ViewNode node, String data) {
+        int start = 0;
+        boolean stop;
+
+        do {
+            int index = data.indexOf('=', start);
+            ViewNode.Property property = new ViewNode.Property();
+            property.name = data.substring(start, index);
+
+            int index2 = data.indexOf(',', index + 1);
+            int length = Integer.parseInt(data.substring(index + 1, index2));
+            start = index2 + 1 + length;
+            property.value = data.substring(index2 + 1, index2 + 1 + length);
+            
+            node.properties.add(property);
+            node.namedProperties.put(property.name, property);
+
+            stop = start >= data.length();
+            if (!stop) {
+                start += 1;
+            }
+        } while (!stop);
+
+        Collections.sort(node.properties, new Comparator<ViewNode.Property>() {
+            public int compare(ViewNode.Property source, ViewNode.Property destination) {
+                return source.name.compareTo(destination.name);
+            }
+        });
+
+        node.decode();
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java
new file mode 100644
index 0000000..08dc395
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.scene;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.GradientPaint;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.geom.Point2D;
+
+import org.netbeans.api.visual.action.ActionFactory;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.anchor.AnchorFactory;
+import org.netbeans.api.visual.border.BorderFactory;
+import org.netbeans.api.visual.graph.GraphScene;
+import org.netbeans.api.visual.layout.LayoutFactory;
+import org.netbeans.api.visual.model.ObjectState;
+import org.netbeans.api.visual.widget.ConnectionWidget;
+import org.netbeans.api.visual.widget.LabelWidget;
+import org.netbeans.api.visual.widget.LayerWidget;
+import org.netbeans.api.visual.widget.Widget;
+
+public class ViewHierarchyScene extends GraphScene<ViewNode, String> {
+    private ViewNode root;
+    private LayerWidget widgetLayer;
+    private LayerWidget connectionLayer;
+
+    private WidgetAction moveAction = ActionFactory.createMoveAction();
+
+    public ViewHierarchyScene() {
+        widgetLayer = new LayerWidget(this);
+        connectionLayer = new LayerWidget(this);
+
+        addChild(widgetLayer);
+        addChild(connectionLayer);
+    }
+    
+    public ViewNode getRoot() {
+        return root;
+    }
+    
+    void setRoot(ViewNode root) {
+        this.root = root;
+    }
+
+    @Override
+    protected Widget attachNodeWidget(ViewNode node) {
+        Widget widget = createBox(node, node.name, node.id);
+        widget.getActions().addAction(createSelectAction());
+        widget.getActions().addAction(moveAction);
+        widgetLayer.addChild(widget);
+        return widget;
+    }
+
+    private Widget createBox(ViewNode node, String nodeName, String id) {
+        final String shortName = getShortName(nodeName);
+        node.setShortName(shortName);
+
+        GradientWidget box = new GradientWidget(this, node);
+        box.setLayout(LayoutFactory.createVerticalFlowLayout());
+        box.setBorder(BorderFactory.createLineBorder(2, Color.BLACK));
+        box.setOpaque(true);
+
+        LabelWidget label = new LabelWidget(this);
+        label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 12.0f));
+        label.setLabel(shortName);
+        label.setBorder(BorderFactory.createEmptyBorder(6, 6, 0, 6));
+        label.setAlignment(LabelWidget.Alignment.CENTER);
+
+        box.addChild(label);
+        
+        label = new LabelWidget(this);
+        label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 10.0f));
+        label.setLabel(getAddress(nodeName));
+        label.setBorder(BorderFactory.createEmptyBorder(3, 6, 0, 6));
+        label.setAlignment(LabelWidget.Alignment.CENTER);
+
+        box.addressWidget = label;
+        
+        box.addChild(label);
+        
+        label = new LabelWidget(this);
+        label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 10.0f));
+        label.setLabel(id);
+        label.setBorder(BorderFactory.createEmptyBorder(3, 6, 6, 6));
+        label.setAlignment(LabelWidget.Alignment.CENTER);
+        
+        box.addChild(label);
+
+        return box;
+    }
+    
+    private static String getAddress(String name) {
+        String[] nameAndHashcode = name.split("@");
+        return "@" + nameAndHashcode[1];
+    }
+    
+    private static String getShortName(String name) {
+        String[] nameAndHashcode = name.split("@");
+        String[] packages = nameAndHashcode[0].split("\\.");
+        return packages[packages.length - 1];
+    }
+
+    @Override
+    protected Widget attachEdgeWidget(String edge) {
+        ConnectionWidget connectionWidget = new ConnectionWidget(this);
+        connectionLayer.addChild(connectionWidget);
+        return connectionWidget;
+    }
+
+    @Override
+    protected void attachEdgeSourceAnchor(String edge, ViewNode oldSourceNode, ViewNode sourceNode) {
+        final ConnectionWidget connection = (ConnectionWidget) findWidget(edge);
+        final Widget source = findWidget(sourceNode);
+        connection.bringToBack();
+        source.bringToFront();
+        connection.setSourceAnchor(AnchorFactory.createRectangularAnchor(source));
+    }
+
+    @Override
+    protected void attachEdgeTargetAnchor(String edge, ViewNode oldTargetNode, ViewNode targetNode) {
+        final ConnectionWidget connection = (ConnectionWidget) findWidget(edge);
+        final Widget target = findWidget(targetNode);
+        connection.bringToBack();
+        target.bringToFront();
+        connection.setTargetAnchor(AnchorFactory.createRectangularAnchor(target));
+    }
+    
+    private static class GradientWidget extends Widget implements ViewNode.StateListener {
+        public static final GradientPaint BLUE_EXPERIENCE = new GradientPaint(
+                new Point2D.Double(0, 0),
+                new Color(168, 204, 241),
+                new Point2D.Double(0, 1),
+                new Color(44, 61, 146));
+        public static final GradientPaint MAC_OSX_SELECTED = new GradientPaint(
+                new Point2D.Double(0, 0),
+                new Color(81, 141, 236),
+                new Point2D.Double(0, 1),
+                new Color(36, 96, 192));
+        public static final GradientPaint MAC_OSX = new GradientPaint(
+                new Point2D.Double(0, 0),
+                new Color(167, 210, 250),
+                new Point2D.Double(0, 1),
+                new Color(99, 147, 206));
+        public static final GradientPaint AERITH = new GradientPaint(
+                new Point2D.Double(0, 0),
+                Color.WHITE,
+                new Point2D.Double(0, 1),
+                new Color(64, 110, 161));
+        public static final GradientPaint GRAY = new GradientPaint(
+                new Point2D.Double(0, 0),
+                new Color(226, 226, 226),
+                new Point2D.Double(0, 1),
+                new Color(250, 248, 248));
+        public static final GradientPaint RED_XP = new GradientPaint(
+                new Point2D.Double(0, 0),
+                new Color(236, 81, 81),
+                new Point2D.Double(0, 1),
+                new Color(192, 36, 36));
+        public static final GradientPaint NIGHT_GRAY = new GradientPaint(
+                new Point2D.Double(0, 0),
+                new Color(102, 111, 127),
+                new Point2D.Double(0, 1),
+                new Color(38, 45, 61));
+        public static final GradientPaint NIGHT_GRAY_LIGHT = new GradientPaint(
+                new Point2D.Double(0, 0),
+                new Color(129, 138, 155),
+                new Point2D.Double(0, 1),
+                new Color(58, 66, 82));
+        public static final GradientPaint NIGHT_GRAY_VERY_LIGHT = new GradientPaint(
+                new Point2D.Double(0, 0),
+                new Color(129, 138, 155, 60),
+                new Point2D.Double(0, 1),
+                new Color(58, 66, 82, 60));
+
+        private static Color UNSELECTED = Color.BLACK;
+        private static Color SELECTED = Color.WHITE;
+
+        private final ViewNode node;
+
+        private LabelWidget addressWidget;
+
+        private boolean isSelected = false;
+        private final GradientPaint selectedGradient = MAC_OSX_SELECTED;
+        private final GradientPaint filteredGradient = RED_XP;
+        private final GradientPaint focusGradient = NIGHT_GRAY_VERY_LIGHT;
+
+        public GradientWidget(ViewHierarchyScene scene, ViewNode node) {
+            super(scene);
+            this.node = node;
+            node.setStateListener(this);
+        }
+
+        @Override
+        protected void notifyStateChanged(ObjectState previous, ObjectState state) {
+            super.notifyStateChanged(previous, state);
+            isSelected = state.isSelected() || state.isFocused() || state.isWidgetFocused();
+
+            pickChildrenColor();
+        }
+
+        private void pickChildrenColor() {
+            for (Widget child : getChildren()) {
+                child.setForeground(isSelected || node.filtered ? SELECTED : UNSELECTED);
+            }
+
+            repaint();
+        }
+
+        @Override
+        protected void paintBackground() {
+            super.paintBackground();
+
+            Graphics2D g2 = getGraphics();
+            Rectangle bounds = getBounds();
+
+            if (!isSelected) {
+                if (!node.filtered) {
+                    if (!node.hasFocus) {
+                        g2.setColor(Color.WHITE);
+                    } else {
+                        g2.setPaint(new GradientPaint(bounds.x, bounds.y,
+                                focusGradient.getColor1(), bounds.x, bounds.x + bounds.height,
+                                focusGradient.getColor2()));
+                    }
+                } else {
+                    g2.setPaint(new GradientPaint(bounds.x, bounds.y, filteredGradient.getColor1(),
+                        bounds.x, bounds.x + bounds.height, filteredGradient.getColor2()));
+                }
+            } else {
+                g2.setPaint(new GradientPaint(bounds.x, bounds.y, selectedGradient.getColor1(),
+                        bounds.x, bounds.x + bounds.height, selectedGradient.getColor2()));
+            }
+            g2.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
+        }
+
+        public void nodeStateChanged(ViewNode node) {
+            pickChildrenColor();
+        }
+
+        public void nodeIndexChanged(ViewNode node) {
+            if (addressWidget != null) {
+                addressWidget.setLabel("#" + node.index + addressWidget.getLabel());
+            }
+        }
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java
new file mode 100644
index 0000000..2b7efd6
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.scene;
+
+import com.android.ddmlib.Device;
+import com.android.hierarchyviewer.device.Window;
+import com.android.hierarchyviewer.device.DeviceBridge;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+
+public class ViewManager {
+    public static void invalidate(Device device, Window window, String params) {
+        sendCommand("INVALIDATE", device, window, params);
+    }
+
+    public static void requestLayout(Device device, Window window, String params) {
+        sendCommand("REQUEST_LAYOUT", device, window, params);
+    }
+
+    private static void sendCommand(String command, Device device, Window window, String params) {
+        Socket socket = null;
+        BufferedWriter out = null;
+
+        try {
+            socket = new Socket();
+            socket.connect(new InetSocketAddress("127.0.0.1",
+                    DeviceBridge.getDeviceLocalPort(device)));
+
+            out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
+
+            out.write(command + " " + window.encode() + " " + params);
+            out.newLine();
+            out.flush();
+        } catch (IOException e) {
+            // Empty
+        } finally {
+            try {
+                if (out != null) {
+                    out.close();
+                }
+                if (socket != null) {
+                    socket.close();
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+        }
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java
new file mode 100644
index 0000000..64c0703
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.scene;
+
+import java.awt.Image;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+public class ViewNode {
+    public String id;
+    public String name;
+
+    public List<Property> properties = new ArrayList<Property>();
+    public Map<String, Property> namedProperties = new HashMap<String, Property>();
+
+    public ViewNode parent;
+    public List<ViewNode> children = new ArrayList<ViewNode>();
+
+    public Image image;
+    
+    public int left;
+    public int top;
+    public int width;
+    public int height;
+    public int scrollX;
+    public int scrollY;
+    public int paddingLeft;
+    public int paddingRight;
+    public int paddingTop;
+    public int paddingBottom;
+    public int marginLeft;
+    public int marginRight;
+    public int marginTop;
+    public int marginBottom;
+    public int baseline;
+    public boolean willNotDraw;
+    public boolean hasMargins;
+    
+    boolean hasFocus;
+    int index;
+
+    public boolean decoded;
+    public boolean filtered;
+
+    private String shortName;
+    private StateListener listener;
+
+    void decode() {
+        id = namedProperties.get("mID").value;
+
+        left = getInt("mLeft", 0);
+        top = getInt("mTop", 0);
+        width = getInt("getWidth()", 0);
+        height = getInt("getHeight()", 0);
+        scrollX = getInt("mScrollX", 0);
+        scrollY = getInt("mScrollY", 0);
+        paddingLeft = getInt("mPaddingLeft", 0);
+        paddingRight = getInt("mPaddingRight", 0);
+        paddingTop = getInt("mPaddingTop", 0);
+        paddingBottom = getInt("mPaddingBottom", 0);
+        marginLeft = getInt("layout_leftMargin", Integer.MIN_VALUE);
+        marginRight = getInt("layout_rightMargin", Integer.MIN_VALUE);
+        marginTop = getInt("layout_topMargin", Integer.MIN_VALUE);
+        marginBottom = getInt("layout_bottomMargin", Integer.MIN_VALUE);
+        baseline = getInt("getBaseline()", 0);
+        willNotDraw = getBoolean("willNotDraw()", false);
+        hasFocus = getBoolean("hasFocus()", false);
+
+        hasMargins = marginLeft != Integer.MIN_VALUE &&
+                marginRight != Integer.MIN_VALUE &&
+                marginTop != Integer.MIN_VALUE &&
+                marginBottom != Integer.MIN_VALUE;
+
+        decoded = true;
+    }
+
+    private boolean getBoolean(String name, boolean defaultValue) {
+        Property p = namedProperties.get(name);
+        if (p != null) {
+            try {
+                return Boolean.parseBoolean(p.value);
+            } catch (NumberFormatException e) {
+                return defaultValue;
+            }   
+        }
+        return defaultValue;
+    }
+
+    private int getInt(String name, int defaultValue) {
+        Property p = namedProperties.get(name);
+        if (p != null) {
+            try {
+                return Integer.parseInt(p.value);
+            } catch (NumberFormatException e) {
+                return defaultValue;
+            }
+        }
+        return defaultValue;
+    }
+
+    public void filter(Pattern pattern) {
+        if (pattern == null || pattern.pattern().length() == 0) {
+            filtered = false;
+        } else {
+            filtered = pattern.matcher(shortName).find() || pattern.matcher(id).find();
+        }
+        listener.nodeStateChanged(this);
+    }
+
+    void computeIndex() {
+        index = parent == null ? 0 : parent.children.indexOf(this);
+        listener.nodeIndexChanged(this);
+    }
+
+    void setShortName(String shortName) {
+        this.shortName = shortName;
+    }
+
+    void setStateListener(StateListener listener) {
+        this.listener = listener;
+    }
+
+    @SuppressWarnings({"StringEquality"})
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final ViewNode other = (ViewNode) obj;
+        return !(this.name != other.name && (this.name == null || !this.name.equals(other.name)));
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 5;
+        hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0);
+        return hash;
+    }
+
+    public static class Property {
+        public String name;
+        public String value;
+
+        @Override
+        public String toString() {
+            return name + '=' + value;
+        }
+        
+        @SuppressWarnings({"StringEquality"})
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            final Property other = (Property) obj;
+            if (this.name != other.name && (this.name == null || !this.name.equals(other.name))) {
+                return false;
+            }
+            return !(this.value != other.value && (this.value == null || !this.value.equals(other.value)));
+        }
+
+        @Override
+        public int hashCode() {
+            int hash = 5;
+            hash = 61 * hash + (this.name != null ? this.name.hashCode() : 0);
+            hash = 61 * hash + (this.value != null ? this.value.hashCode() : 0);
+            return hash;
+        }
+    }
+
+    interface StateListener {
+        void nodeStateChanged(ViewNode node);
+        void nodeIndexChanged(ViewNode node);
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/WindowsLoader.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/WindowsLoader.java
new file mode 100644
index 0000000..6c14cb6
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/scene/WindowsLoader.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.scene;
+
+import com.android.ddmlib.Device;
+import com.android.hierarchyviewer.device.DeviceBridge;
+import com.android.hierarchyviewer.device.Window;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+
+public class WindowsLoader {
+    public static Window[] loadWindows(Device device) {
+        Socket socket = null;
+        BufferedReader in = null;
+        BufferedWriter out = null;
+
+        try {
+            ArrayList<Window> windows = new ArrayList<Window>();
+
+            socket = new Socket();
+            socket.connect(new InetSocketAddress("127.0.0.1",
+                    DeviceBridge.getDeviceLocalPort(device)));
+
+            out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
+            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+
+            out.write("LIST");
+            out.newLine();
+            out.flush();
+
+            String line;
+            while ((line = in.readLine()) != null) {
+                if ("DONE.".equalsIgnoreCase(line)) {
+                    break;
+                }
+
+                int index = line.indexOf(' ');
+                if (index != -1) {
+                    Window w = new Window(line.substring(index + 1),
+                            Integer.parseInt(line.substring(0, index), 16));
+                    windows.add(w);
+                }
+            }
+
+            return windows.toArray(new Window[windows.size()]);
+        } catch (IOException e) {
+            // Empty
+        } finally {
+            try {
+                if (out != null) {
+                    out.close();
+                }
+                if (in != null) {
+                    in.close();
+                }
+                if (socket != null) {
+                    socket.close();
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+        }
+
+        return new Window[0];
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/CaptureRenderer.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/CaptureRenderer.java
new file mode 100644
index 0000000..7ccc818
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/CaptureRenderer.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui;
+
+import com.android.hierarchyviewer.scene.ViewNode;
+
+import javax.swing.*;
+import java.awt.*;
+
+class CaptureRenderer extends JLabel {
+    private ViewNode node;
+    private boolean showExtras;
+
+    CaptureRenderer(ImageIcon icon, ViewNode node) {
+        super(icon);
+        this.node = node;
+        setBackground(Color.BLACK);
+    }
+
+    @Override
+    public Dimension getPreferredSize() {
+        Dimension d = super.getPreferredSize();
+
+        if (node.hasMargins) {
+            d.width += node.marginLeft + node.marginRight;
+            d.height += node.marginTop + node.marginBottom;
+        }
+
+        return d;
+    }
+
+    public void setShowExtras(boolean showExtras) {
+        this.showExtras = showExtras;
+        repaint();
+    }
+
+    @Override
+    protected void paintComponent(Graphics g) {
+        Icon icon = getIcon();
+        int width = icon.getIconWidth();
+        int height = icon.getIconHeight();
+
+        int x = (getWidth() - width) / 2;
+        int y = (getHeight() - height) / 2;
+
+        icon.paintIcon(this, g, x, y);
+
+        if (showExtras) {
+            g.translate(x, y);
+            g.setXORMode(Color.WHITE);
+            if ((node.paddingBottom | node.paddingLeft |
+                    node.paddingTop | node.paddingRight) != 0) {
+                g.setColor(Color.RED);
+                g.drawRect(node.paddingLeft, node.paddingTop,
+                        width - node.paddingRight - node.paddingLeft,
+                        height - node.paddingBottom - node.paddingTop);
+            }
+            if (node.baseline != -1) {
+                g.setColor(Color.BLUE);
+                g.drawLine(0, node.baseline, width, node.baseline);
+            }
+            if (node.hasMargins && (node.marginLeft | node.marginBottom |
+                    node.marginRight | node.marginRight) != 0) {
+                g.setColor(Color.BLACK);
+                g.drawRect(-node.marginLeft, -node.marginTop,
+                        node.marginLeft + width + node.marginRight,
+                        node.marginTop + height + node.marginBottom);
+            }
+            g.translate(-x, -y);
+        }
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/LayoutRenderer.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/LayoutRenderer.java
new file mode 100644
index 0000000..a50905c
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/LayoutRenderer.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui;
+
+import com.android.hierarchyviewer.scene.ViewHierarchyScene;
+import com.android.hierarchyviewer.scene.ViewNode;
+
+import javax.swing.JComponent;
+import javax.swing.BorderFactory;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.util.Set;
+
+class LayoutRenderer extends JComponent {
+    private static final int EMULATED_SCREEN_WIDTH = 320;
+    private static final int EMULATED_SCREEN_HEIGHT = 480;
+    private static final int SCREEN_MARGIN = 24;
+
+    private boolean showExtras;
+    private ViewHierarchyScene scene;
+
+    LayoutRenderer(ViewHierarchyScene scene) {
+        this.scene = scene;
+
+        setOpaque(true);
+        setBorder(BorderFactory.createEmptyBorder(0, 0, 12, 0));
+        setBackground(Color.BLACK);
+        setForeground(Color.WHITE);
+    }
+
+    @Override
+    public Dimension getPreferredSize() {
+        return new Dimension(EMULATED_SCREEN_WIDTH + SCREEN_MARGIN,
+                EMULATED_SCREEN_HEIGHT + SCREEN_MARGIN);
+    }
+
+    @Override
+    protected void paintComponent(Graphics g) {
+        g.setColor(getBackground());
+        g.fillRect(0, 0, getWidth(), getHeight());
+
+        Insets insets = getInsets();
+        g.clipRect(insets.left, insets.top,
+                getWidth() - insets.left - insets.right,
+                getHeight() - insets.top - insets.bottom);
+
+        if (scene == null) {
+            return;
+        }
+
+        ViewNode root = scene.getRoot();
+        if (root == null) {
+            return;
+        }
+
+        int x = (getWidth() - insets.left - insets.right - root.width) / 2;
+        int y = (getHeight() - insets.top - insets.bottom - root.height) / 2;
+        g.translate(insets.left + x, insets.top + y);
+
+        g.setColor(getForeground());
+        g.drawRect(root.left, root.top, root.width - 1, root.height - 1);
+        g.clipRect(root.left - 1, root.top - 1, root.width + 1, root.height + 1);
+        drawChildren(g, root, -root.scrollX, -root.scrollY);
+
+        Set<?> selection = scene.getSelectedObjects();
+        if (selection.size() > 0) {
+            ViewNode node = (ViewNode) selection.iterator().next();
+            g.setColor(Color.RED);
+            Graphics s = g.create();
+            ViewNode p = node.parent;
+            while (p != null) {
+                s.translate(p.left - p.scrollX, p.top - p.scrollY);
+                p = p.parent;
+            }
+            if (showExtras && node.image != null) {
+                s.drawImage(node.image, node.left, node.top, null);
+            }
+            s.drawRect(node.left, node.top, node.width - 1, node.height - 1);
+            s.dispose();
+        }
+
+        g.translate(-insets.left - x, -insets.top - y);
+    }
+
+    private void drawChildren(Graphics g, ViewNode root, int x, int y) {
+        g.translate(x, y);
+        for (ViewNode node : root.children) {
+            if (!node.willNotDraw) {
+                g.drawRect(node.left, node.top, node.width - 1, node.height - 1);
+            }
+
+            if (node.children.size() > 0) {
+                drawChildren(g, node,
+                        node.left - node.parent.scrollX,
+                        node.top - node.parent.scrollY);
+            }
+        }
+        g.translate(-x, -y);
+    }
+
+    public void setShowExtras(boolean showExtras) {
+        this.showExtras = showExtras;
+        repaint();
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java
new file mode 100644
index 0000000..83d926f
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/ScreenViewer.java
@@ -0,0 +1,732 @@
+package com.android.hierarchyviewer.ui;
+
+import com.android.ddmlib.Device;
+import com.android.ddmlib.RawImage;
+import com.android.hierarchyviewer.util.WorkerThread;
+import com.android.hierarchyviewer.scene.ViewNode;
+import com.android.hierarchyviewer.ui.util.PngFileFilter;
+import com.android.hierarchyviewer.ui.util.IconLoader;
+
+import javax.swing.JComponent;
+import javax.swing.Timer;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import javax.swing.BorderFactory;
+import javax.swing.JLabel;
+import javax.swing.JSlider;
+import javax.swing.Box;
+import javax.swing.JCheckBox;
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.ChangeEvent;
+import javax.imageio.ImageIO;
+
+import org.jdesktop.swingworker.SwingWorker;
+
+import java.io.IOException;
+import java.io.File;
+import java.awt.image.BufferedImage;
+import java.awt.Graphics;
+import java.awt.Dimension;
+import java.awt.BorderLayout;
+import java.awt.Graphics2D;
+import java.awt.Color;
+import java.awt.Rectangle;
+import java.awt.Point;
+import java.awt.GridBagLayout;
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+import java.awt.FlowLayout;
+import java.awt.AlphaComposite;
+import java.awt.RenderingHints;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionAdapter;
+import java.util.concurrent.ExecutionException;
+
+class ScreenViewer extends JPanel implements ActionListener {
+    private final Workspace workspace;
+    private final Device device;
+
+    private GetScreenshotTask task;
+    private BufferedImage image;
+    private int[] scanline;
+    private volatile boolean isLoading;
+
+    private BufferedImage overlay;    
+    private AlphaComposite overlayAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f);
+
+    private ScreenViewer.LoupeStatus status;
+    private ScreenViewer.LoupeViewer loupe;
+    private ScreenViewer.Crosshair crosshair;
+
+    private int zoom = 8;
+    private int y = 0;
+
+    private Timer timer;
+    private ViewNode node;
+
+    ScreenViewer(Workspace workspace, Device device, int spacing) {
+        setLayout(new BorderLayout());
+        setOpaque(false);
+
+        this.workspace = workspace;
+        this.device = device;
+
+        timer = new Timer(5000, this);
+        timer.setInitialDelay(0);
+        timer.setRepeats(true);
+
+        JPanel panel = buildViewerAndControls();
+        add(panel, BorderLayout.WEST);
+
+        JPanel loupePanel = buildLoupePanel(spacing);
+        add(loupePanel, BorderLayout.CENTER);
+
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                timer.start();                
+            }
+        });
+    }
+
+    private JPanel buildLoupePanel(int spacing) {
+        loupe = new LoupeViewer();
+        CrosshairPanel crosshairPanel = new CrosshairPanel(loupe);
+
+        JPanel loupePanel = new JPanel(new BorderLayout());
+        loupePanel.add(crosshairPanel);
+        status = new LoupeStatus();
+        loupePanel.add(status, BorderLayout.SOUTH);
+
+        loupePanel.setBorder(BorderFactory.createEmptyBorder(0, spacing, 0, 0));
+        return loupePanel;
+    }
+
+    private JPanel buildViewerAndControls() {
+        JPanel panel = new JPanel(new GridBagLayout());
+        crosshair = new Crosshair(new ScreenshotViewer());
+        panel.add(crosshair,
+                new GridBagConstraints(0, y++, 2, 1, 1.0f, 0.0f,
+                    GridBagConstraints.FIRST_LINE_START, GridBagConstraints.NONE,
+                    new Insets(0, 0, 0, 0), 0, 0));
+        buildSlider(panel, "Overlay:", "0%", "100%", 0, 100, 30, 1).addChangeListener(
+                new ChangeListener() {
+                    public void stateChanged(ChangeEvent event) {
+                        float opacity = ((JSlider) event.getSource()).getValue() / 100.0f;
+                        overlayAlpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity);
+                        repaint();
+                    }
+        });
+        buildOverlayExtraControls(panel);
+        buildSlider(panel, "Refresh Rate:", "1s", "40s", 1, 40, 5, 1).addChangeListener(
+                new ChangeListener() {
+                    public void stateChanged(ChangeEvent event) {
+                        int rate = ((JSlider) event.getSource()).getValue() * 1000;
+                        timer.setDelay(rate);
+                        timer.setInitialDelay(0);
+                        timer.restart();
+                    }
+        });
+        buildSlider(panel, "Zoom:", "2x", "24x", 2, 24, 8, 2).addChangeListener(
+                new ChangeListener() {
+                    public void stateChanged(ChangeEvent event) {
+                        zoom = ((JSlider) event.getSource()).getValue();
+                        loupe.clearGrid = true;
+                        loupe.moveToPoint(crosshair.crosshair.x, crosshair.crosshair.y);
+                        repaint();
+                    }
+        });
+        panel.add(Box.createVerticalGlue(),
+                new GridBagConstraints(0, y++, 2, 1, 1.0f, 1.0f,
+                    GridBagConstraints.FIRST_LINE_START, GridBagConstraints.NONE,
+                    new Insets(0, 0, 0, 0), 0, 0));
+        return panel;
+    }
+
+    private void buildOverlayExtraControls(JPanel panel) {
+        JPanel extras = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
+
+        JButton loadOverlay = new JButton("Load...");
+        loadOverlay.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                SwingWorker<?, ?> worker = openOverlay();
+                if (worker != null) {
+                    worker.execute();
+                }
+            }
+        });
+        extras.add(loadOverlay);
+
+        JCheckBox showInLoupe = new JCheckBox("Show in Loupe");
+        showInLoupe.setSelected(false);
+        showInLoupe.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event) {
+                loupe.showOverlay = ((JCheckBox) event.getSource()).isSelected();
+                loupe.repaint();
+            }
+        });
+        extras.add(showInLoupe);
+
+        panel.add(extras, new GridBagConstraints(1, y++, 1, 1, 1.0f, 0.0f,
+                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                        new Insets(0, 0, 0, 0), 0, 0));
+    }
+
+    public SwingWorker<?, ?> openOverlay() {
+        JFileChooser chooser = new JFileChooser();
+        chooser.setFileFilter(new PngFileFilter());
+        int choice = chooser.showOpenDialog(this);
+        if (choice == JFileChooser.APPROVE_OPTION) {
+            return new OpenOverlayTask(chooser.getSelectedFile());
+        } else {
+            return null;
+        }
+    }
+
+    private JSlider buildSlider(JPanel panel, String title, String minName, String maxName,
+            int min, int max, int value, int tick) {
+        panel.add(new JLabel(title), new GridBagConstraints(0, y, 1, 1, 1.0f, 0.0f,
+                    GridBagConstraints.LINE_END, GridBagConstraints.NONE,
+                    new Insets(0, 0, 0, 6), 0, 0));
+        JPanel sliderPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
+        sliderPanel.add(new JLabel(minName));
+        JSlider slider = new JSlider(min, max, value);
+        slider.setMinorTickSpacing(tick);
+        slider.setMajorTickSpacing(tick);
+        slider.setSnapToTicks(true);
+        sliderPanel.add(slider);
+        sliderPanel.add(new JLabel(maxName));
+        panel.add(sliderPanel, new GridBagConstraints(1, y++, 1, 1, 1.0f, 0.0f,
+                    GridBagConstraints.FIRST_LINE_START, GridBagConstraints.NONE,
+                        new Insets(0, 0, 0, 0), 0, 0));
+        return slider;
+    }
+
+    void stop() {
+        timer.stop();
+    }
+
+    void start() {
+        timer.start();
+    }
+
+    void select(ViewNode node) {
+        this.node = node;
+        repaint();
+    }
+
+    class LoupeViewer extends JComponent {
+        private final Color lineColor = new Color(1.0f, 1.0f, 1.0f, 0.3f);
+
+        private int width;
+        private int height;
+        private BufferedImage grid;
+        private int left;
+        private int top;
+        public boolean clearGrid;
+
+        private final Rectangle clip = new Rectangle();
+        private boolean showOverlay = false;
+
+        LoupeViewer() {
+            addMouseListener(new MouseAdapter() {
+                @Override
+                public void mousePressed(MouseEvent event) {
+                    moveToPoint(event);
+                }
+            });
+            addMouseMotionListener(new MouseMotionAdapter() {
+                @Override
+                public void mouseDragged(MouseEvent event) {
+                    moveToPoint(event);
+                }
+            });
+        }
+
+        @Override
+        protected void paintComponent(Graphics g) {
+            if (isLoading) {
+                return;
+            }
+
+            g.translate(-left, -top);
+
+            if (image != null) {
+                Graphics2D g2 = (Graphics2D) g.create();
+                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+                        RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
+                g2.scale(zoom, zoom);
+                g2.drawImage(image, 0, 0, null);
+                if (overlay != null && showOverlay) {
+                    g2.setComposite(overlayAlpha);
+                    g2.drawImage(overlay, 0, image.getHeight() - overlay.getHeight(), null);
+                }
+                g2.dispose();
+            }
+
+            int width = getWidth();
+            int height = getHeight();
+
+            Graphics2D g2 = null;
+            if (width != this.width || height != this.height) {
+                this.width = width;
+                this.height = height;
+
+                grid = new BufferedImage(width + zoom + 1, height + zoom + 1,
+                        BufferedImage.TYPE_INT_ARGB);
+                clearGrid = true;
+                g2 = grid.createGraphics();
+            } else if (clearGrid) {
+                g2 = grid.createGraphics();
+                g2.setComposite(AlphaComposite.Clear);
+                g2.fillRect(0, 0, grid.getWidth(), grid.getHeight());
+                g2.setComposite(AlphaComposite.SrcOver);
+            }
+
+            if (clearGrid) {
+                clearGrid = false;
+
+                g2.setColor(lineColor);
+                width += zoom;
+                height += zoom;
+
+                for (int x = zoom; x <= width; x += zoom) {
+                    g2.drawLine(x, 0, x, height);
+                }
+
+                for (int y = 0; y <= height; y += zoom) {
+                    g2.drawLine(0, y, width, y);
+                }
+
+                g2.dispose();
+            }
+
+            if (image != null) {
+                g.getClipBounds(clip);
+                g.clipRect(0, 0, image.getWidth() * zoom + 1, image.getHeight() * zoom + 1);
+                g.drawImage(grid, clip.x - clip.x % zoom, clip.y - clip.y % zoom, null);
+            }
+
+            g.translate(left, top);
+        }
+
+        void moveToPoint(MouseEvent event) {
+            int x = Math.max(0, Math.min((event.getX() + left) / zoom, image.getWidth() - 1));
+            int y = Math.max(0, Math.min((event.getY() + top) / zoom, image.getHeight() - 1));
+            moveToPoint(x, y);
+            crosshair.moveToPoint(x, y);
+        }
+
+        void moveToPoint(int x, int y) {
+            left = x * zoom - width / 2 + zoom / 2;
+            top = y * zoom - height / 2 + zoom / 2;
+            repaint();
+        }
+    }
+
+    class LoupeStatus extends JPanel {
+        private JLabel xLabel;
+        private JLabel yLabel;
+        private JLabel rLabel;
+        private JLabel gLabel;
+        private JLabel bLabel;
+        private JLabel hLabel;
+        private ScreenViewer.LoupeStatus.ColoredSquare square;
+        private Color color;
+
+        LoupeStatus() {
+            setOpaque(true);
+            setLayout(new GridBagLayout());
+            setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
+
+            square = new ColoredSquare();
+            add(square, new GridBagConstraints(0, 0, 1, 2, 0.0f, 0.0f,
+                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                    new Insets(0, 0, 0, 12), 0, 0 ));
+
+            JLabel label;
+
+            add(label = new JLabel("#ffffff"), new GridBagConstraints(0, 2, 1, 1, 0.0f, 0.0f,
+                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                    new Insets(0, 0, 0, 12), 0, 0 ));
+            label.setForeground(Color.WHITE);
+            hLabel = label;
+
+            add(label = new JLabel("R:"), new GridBagConstraints(1, 0, 1, 1, 0.0f, 0.0f,
+                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                    new Insets(0, 6, 0, 6), 0, 0 ));
+            label.setForeground(Color.WHITE);
+            add(label = new JLabel("255"), new GridBagConstraints(2, 0, 1, 1, 0.0f, 0.0f,
+                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                    new Insets(0, 0, 0, 12), 0, 0 ));
+            label.setForeground(Color.WHITE);
+            rLabel = label;
+
+            add(label = new JLabel("G:"), new GridBagConstraints(1, 1, 1, 1, 0.0f, 0.0f,
+                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                    new Insets(0, 6, 0, 6), 0, 0 ));
+            label.setForeground(Color.WHITE);
+            add(label = new JLabel("255"), new GridBagConstraints(2, 1, 1, 1, 0.0f, 0.0f,
+                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                    new Insets(0, 0, 0, 12), 0, 0 ));
+            label.setForeground(Color.WHITE);
+            gLabel = label;
+
+            add(label = new JLabel("B:"), new GridBagConstraints(1, 2, 1, 1, 0.0f, 0.0f,
+                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                    new Insets(0, 6, 0, 6), 0, 0 ));
+            label.setForeground(Color.WHITE);
+            add(label = new JLabel("255"), new GridBagConstraints(2, 2, 1, 1, 0.0f, 0.0f,
+                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                    new Insets(0, 0, 0, 12), 0, 0 ));
+            label.setForeground(Color.WHITE);
+            bLabel = label;
+
+            add(label = new JLabel("X:"), new GridBagConstraints(3, 0, 1, 1, 0.0f, 0.0f,
+                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                    new Insets(0, 6, 0, 6), 0, 0 ));
+            label.setForeground(Color.WHITE);
+            add(label = new JLabel("0 px"), new GridBagConstraints(4, 0, 1, 1, 0.0f, 0.0f,
+                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                    new Insets(0, 0, 0, 12), 0, 0 ));
+            label.setForeground(Color.WHITE);
+            xLabel = label;
+
+            add(label = new JLabel("Y:"), new GridBagConstraints(3, 1, 1, 1, 0.0f, 0.0f,
+                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                    new Insets(0, 6, 0, 6), 0, 0 ));
+            label.setForeground(Color.WHITE);
+            add(label = new JLabel("0 px"), new GridBagConstraints(4, 1, 1, 1, 0.0f, 0.0f,
+                    GridBagConstraints.LINE_START, GridBagConstraints.NONE,
+                    new Insets(0, 0, 0, 12), 0, 0 ));
+            label.setForeground(Color.WHITE);
+            yLabel = label;
+
+            add(Box.createHorizontalGlue(), new GridBagConstraints(5, 0, 1, 1, 1.0f, 0.0f,
+                    GridBagConstraints.LINE_START, GridBagConstraints.BOTH,
+                    new Insets(0, 0, 0, 0), 0, 0 ));
+        }
+
+        @Override
+        protected void paintComponent(Graphics g) {
+            g.setColor(Color.BLACK);
+            g.fillRect(0, 0, getWidth(), getHeight());
+        }
+
+        void showPixel(int x, int y) {
+            xLabel.setText(x + " px");
+            yLabel.setText(y + " px");
+
+            int pixel = image.getRGB(x, y);
+            color = new Color(pixel);
+            hLabel.setText("#" + Integer.toHexString(pixel));
+            rLabel.setText(String.valueOf((pixel >> 16) & 0xff));
+            gLabel.setText(String.valueOf((pixel >>  8) & 0xff));
+            bLabel.setText(String.valueOf((pixel      ) & 0xff));
+
+            square.repaint();
+        }
+
+        private class ColoredSquare extends JComponent {
+            @Override
+            public Dimension getPreferredSize() {
+                Dimension d = super.getPreferredSize();
+                d.width = 60;
+                d.height = 30;
+                return d;
+            }
+
+            @Override
+            protected void paintComponent(Graphics g) {
+                g.setColor(color);
+                g.fillRect(0, 0, getWidth(), getHeight());
+
+                g.setColor(Color.WHITE);
+                g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);                
+            }
+        }
+    }
+
+    class Crosshair extends JPanel {
+        // magenta = 0xff5efe
+        private final Color crosshairColor = new Color(0x00ffff);
+        Point crosshair = new Point();
+        private int width;
+        private int height;
+
+        Crosshair(ScreenshotViewer screenshotViewer) {
+            setOpaque(true);
+            setLayout(new BorderLayout());
+            add(screenshotViewer);
+            addMouseListener(new MouseAdapter() {
+                @Override
+                public void mousePressed(MouseEvent event) {
+                    moveToPoint(event);
+                }
+            });
+            addMouseMotionListener(new MouseMotionAdapter() {
+                @Override
+                public void mouseDragged(MouseEvent event) {
+                    moveToPoint(event);
+                }
+            });
+        }
+
+        void moveToPoint(int x, int y) {
+            crosshair.x = x;
+            crosshair.y = y;
+            status.showPixel(crosshair.x, crosshair.y);
+            repaint();
+        }
+
+        private void moveToPoint(MouseEvent event) {
+            crosshair.x = Math.max(0, Math.min(image.getWidth() - 1, event.getX()));
+            crosshair.y = Math.max(0, Math.min(image.getHeight() - 1, event.getY()));
+            loupe.moveToPoint(crosshair.x, crosshair.y);
+            status.showPixel(crosshair.x, crosshair.y);
+
+            repaint();
+        }
+
+        @Override
+        public void paint(Graphics g) {
+            super.paint(g);
+
+            if (crosshair == null || width != getWidth() || height != getHeight()) {
+                width = getWidth();
+                height = getHeight();
+                crosshair = new Point(width / 2, height / 2);
+            }
+
+            g.setColor(crosshairColor);
+
+            g.drawLine(crosshair.x, 0, crosshair.x, height);
+            g.drawLine(0, crosshair.y, width, crosshair.y);
+        }
+
+        @Override
+        protected void paintComponent(Graphics g) {
+            super.paintComponent(g);
+            g.setColor(Color.BLACK);
+            g.fillRect(0, 0, getWidth(), getHeight());
+        }
+    }
+
+    class ScreenshotViewer extends JComponent {
+        private final Color boundsColor = new Color(0xff5efe);
+
+        ScreenshotViewer() {
+            setOpaque(true);
+        }
+
+        @Override
+        protected void paintComponent(Graphics g) {
+            g.setColor(Color.BLACK);
+            g.fillRect(0, 0, getWidth(), getHeight());
+
+            if (isLoading) {
+                return;
+            }
+
+            if (image != null) {
+                g.drawImage(image, 0, 0, null);
+                if (overlay != null) {
+                    Graphics2D g2 = (Graphics2D) g.create();
+                    g2.setComposite(overlayAlpha);
+                    g2.drawImage(overlay, 0, image.getHeight() - overlay.getHeight(), null);
+                }
+            }
+
+            if (node != null) {
+                Graphics s = g.create();
+                s.setColor(boundsColor);
+                ViewNode p = node.parent;
+                while (p != null) {
+                    s.translate(p.left - p.scrollX, p.top - p.scrollY);
+                    p = p.parent;
+                }
+                s.drawRect(node.left, node.top, node.width - 1, node.height - 1);
+                s.translate(node.left, node.top);
+
+                s.setXORMode(Color.WHITE);
+                if ((node.paddingBottom | node.paddingLeft |
+                        node.paddingTop | node.paddingRight) != 0) {
+                    s.setColor(Color.BLACK);
+                    s.drawRect(node.paddingLeft, node.paddingTop,
+                            node.width - node.paddingRight - node.paddingLeft - 1,
+                            node.height - node.paddingBottom - node.paddingTop - 1);
+                }
+                if (node.hasMargins && (node.marginLeft | node.marginBottom |
+                        node.marginRight | node.marginRight) != 0) {
+                    s.setColor(Color.BLACK);
+                    s.drawRect(-node.marginLeft, -node.marginTop,
+                            node.marginLeft + node.width + node.marginRight - 1,
+                            node.marginTop + node.height + node.marginBottom - 1);
+                }
+
+                s.dispose();
+            }
+        }
+
+        @Override
+        public Dimension getPreferredSize() {
+            if (image == null) {
+                return new Dimension(320, 480);
+            }
+            return new Dimension(image.getWidth(), image.getHeight());
+        }
+    }
+
+    private class CrosshairPanel extends JPanel {
+        private final Color crosshairColor = new Color(0xff5efe);
+        private final Insets insets = new Insets(0, 0, 0, 0);
+
+        CrosshairPanel(LoupeViewer loupe) {
+            setLayout(new BorderLayout());
+            add(loupe);
+        }
+
+        @Override
+        public void paint(Graphics g) {
+            super.paint(g);
+
+            g.setColor(crosshairColor);
+
+            int width = getWidth();
+            int height = getHeight();
+
+            getInsets(insets);
+
+            int x = (width - insets.left - insets.right) / 2;
+            int y = (height - insets.top - insets.bottom) / 2;
+
+            g.drawLine(insets.left + x, insets.top, insets.left + x, height - insets.bottom);
+            g.drawLine(insets.left, insets.top + y, width - insets.right, insets.top + y);
+        }
+
+        @Override
+        protected void paintComponent(Graphics g) {
+            g.setColor(Color.BLACK);
+            Insets insets = getInsets();
+            g.fillRect(insets.left, insets.top, getWidth() - insets.left - insets.right,
+                    getHeight() - insets.top - insets.bottom);
+        }
+    }
+
+    public void actionPerformed(ActionEvent event) {
+        if (task != null && !task.isDone()) {
+            return;
+        }
+        task = new GetScreenshotTask();
+        task.execute();
+    }
+
+    private class GetScreenshotTask extends SwingWorker<Boolean, Void> {
+        private GetScreenshotTask() {
+            workspace.beginTask();
+        }
+
+        @Override
+        @WorkerThread
+        protected Boolean doInBackground() throws Exception {
+            RawImage rawImage;
+            try {
+                rawImage = device.getScreenshot();
+            } catch (IOException ioe) {
+                return false;
+            }
+
+            boolean resize = false;
+            isLoading = true;
+            try {
+                if (rawImage != null && rawImage.bpp == 16) {
+                    if (image == null || rawImage.width != image.getWidth() ||
+                            rawImage.height != image.getHeight()) {
+                        image = new BufferedImage(rawImage.width, rawImage.height,
+                                BufferedImage.TYPE_INT_ARGB);
+                        scanline = new int[rawImage.width];
+                        resize = true;
+                    }
+
+                    byte[] buffer = rawImage.data;
+                    int index = 0;
+                    for (int y = 0 ; y < rawImage.height ; y++) {
+                        for (int x = 0 ; x < rawImage.width ; x++) {
+                            int value = buffer[index++] & 0x00FF;
+                            value |= (buffer[index++] << 8) & 0x0FF00;
+
+                            int r = ((value >> 11) & 0x01F) << 3;
+                            int g = ((value >> 5) & 0x03F) << 2;
+                            int b = ((value     ) & 0x01F) << 3;
+
+                            scanline[x] = 0xFF << 24 | r << 16 | g << 8 | b;
+                        }
+                        image.setRGB(0, y, rawImage.width, 1, scanline,
+                                0, rawImage.width);
+                    }
+                }
+            } finally {
+                isLoading = false;
+            }
+
+            return resize;
+        }
+
+        @Override
+        protected void done() {
+            workspace.endTask();
+            try {
+                if (get()) {
+                    validate();
+                    crosshair.crosshair = new Point(image.getWidth() / 2,
+                            image.getHeight() / 2);
+                    status.showPixel(image.getWidth() / 2, image.getHeight() / 2);
+                    loupe.moveToPoint(image.getWidth() / 2, image.getHeight() / 2);
+                }
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            } catch (ExecutionException e) {
+                e.printStackTrace();
+            }
+            repaint();
+        }
+    }
+
+    private class OpenOverlayTask extends SwingWorker<BufferedImage, Void> {
+        private File file;
+
+        private OpenOverlayTask(File file) {
+            this.file = file;
+            workspace.beginTask();
+        }
+
+        @Override
+        @WorkerThread
+        protected BufferedImage doInBackground() {
+            try {
+                return IconLoader.toCompatibleImage(ImageIO.read(file));
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+            return null;
+        }
+
+        @Override
+        protected void done() {
+            try {
+                overlay = get();
+                repaint();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            } catch (ExecutionException e) {
+                e.printStackTrace();
+            } finally {
+                workspace.endTask();
+            }
+        }
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java
new file mode 100644
index 0000000..20093ae
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java
@@ -0,0 +1,1445 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui;
+
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.Device;
+import com.android.hierarchyviewer.device.DeviceBridge;
+import com.android.hierarchyviewer.device.Window;
+import com.android.hierarchyviewer.laf.UnifiedContentBorder;
+import com.android.hierarchyviewer.scene.CaptureLoader;
+import com.android.hierarchyviewer.scene.ViewHierarchyLoader;
+import com.android.hierarchyviewer.scene.ViewHierarchyScene;
+import com.android.hierarchyviewer.scene.ViewManager;
+import com.android.hierarchyviewer.scene.ViewNode;
+import com.android.hierarchyviewer.scene.WindowsLoader;
+import com.android.hierarchyviewer.util.OS;
+import com.android.hierarchyviewer.util.WorkerThread;
+import com.android.hierarchyviewer.ui.action.ShowDevicesAction;
+import com.android.hierarchyviewer.ui.action.RequestLayoutAction;
+import com.android.hierarchyviewer.ui.action.InvalidateAction;
+import com.android.hierarchyviewer.ui.action.CaptureNodeAction;
+import com.android.hierarchyviewer.ui.action.RefreshWindowsAction;
+import com.android.hierarchyviewer.ui.action.StopServerAction;
+import com.android.hierarchyviewer.ui.action.StartServerAction;
+import com.android.hierarchyviewer.ui.action.ExitAction;
+import com.android.hierarchyviewer.ui.action.LoadGraphAction;
+import com.android.hierarchyviewer.ui.action.SaveSceneAction;
+import com.android.hierarchyviewer.ui.util.PngFileFilter;
+import com.android.hierarchyviewer.ui.util.IconLoader;
+import com.android.hierarchyviewer.ui.model.PropertiesTableModel;
+import com.android.hierarchyviewer.ui.model.ViewsTreeModel;
+import org.jdesktop.swingworker.SwingWorker;
+import org.netbeans.api.visual.graph.layout.TreeGraphLayout;
+import org.netbeans.api.visual.model.ObjectSceneEvent;
+import org.netbeans.api.visual.model.ObjectSceneEventType;
+import org.netbeans.api.visual.model.ObjectSceneListener;
+import org.netbeans.api.visual.model.ObjectState;
+
+import javax.imageio.ImageIO;
+import javax.swing.ActionMap;
+import javax.swing.BorderFactory;
+import javax.swing.ButtonGroup;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.JScrollPane;
+import javax.swing.JSlider;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.JToggleButton;
+import javax.swing.JToolBar;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingUtilities;
+import javax.swing.JTree;
+import javax.swing.Box;
+import javax.swing.JTextField;
+import javax.swing.text.Document;
+import javax.swing.text.BadLocationException;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.event.DocumentEvent;
+import javax.swing.table.DefaultTableModel;
+import java.awt.image.BufferedImage;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GridBagLayout;
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+import java.awt.FlowLayout;
+import java.awt.Color;
+import java.awt.Image;
+import java.awt.Graphics2D;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+import java.util.concurrent.ExecutionException;
+
+public class Workspace extends JFrame {
+    private JLabel viewCountLabel;
+    private JSlider zoomSlider;
+    private JSplitPane sideSplitter;
+    private JSplitPane mainSplitter;
+    private JTable propertiesTable;
+    private JComponent pixelPerfectPanel;
+    private JTree pixelPerfectTree;
+    private ScreenViewer screenViewer;
+
+    private JPanel extrasPanel;
+    private LayoutRenderer layoutView;
+
+    private JScrollPane sceneScroller;
+    private JComponent sceneView;
+
+    private ViewHierarchyScene scene;
+
+    private ActionMap actionsMap;
+    private JPanel mainPanel;
+    private JProgressBar progress;
+    private JToolBar buttonsPanel;
+
+    private JComponent deviceSelector;
+    private DevicesTableModel devicesTableModel;
+    private WindowsTableModel windowsTableModel;
+
+    private Device currentDevice;
+    private Window currentWindow = Window.FOCUSED_WINDOW;
+
+    private JButton displayNodeButton;
+    private JButton invalidateButton;
+    private JButton requestLayoutButton;
+    private JButton loadButton;
+    private JButton startButton;
+    private JButton stopButton;
+    private JButton showDevicesButton;
+    private JButton refreshButton;
+    private JToggleButton graphViewButton;
+    private JToggleButton pixelPerfectViewButton;
+    private JMenuItem saveMenuItem;
+    private JMenuItem showDevicesMenuItem;
+    private JMenuItem loadMenuItem;
+    private JMenuItem startMenuItem;
+    private JMenuItem stopMenuItem;
+    private JTable devices;
+    private JTable windows;
+    private JLabel minZoomLabel;
+    private JLabel maxZoomLabel;
+    private JTextField filterText;
+    private JLabel filterLabel;
+
+    public Workspace() {
+        super("Hierarchy Viewer");
+
+        buildActions();
+        add(buildMainPanel());
+        setJMenuBar(buildMenuBar());
+
+        currentDeviceChanged();
+
+        pack();
+    }
+
+    private void buildActions() {
+        actionsMap = new ActionMap();
+        actionsMap.put(ExitAction.ACTION_NAME, new ExitAction(this));
+        actionsMap.put(ShowDevicesAction.ACTION_NAME, new ShowDevicesAction(this));
+        actionsMap.put(LoadGraphAction.ACTION_NAME, new LoadGraphAction(this));
+        actionsMap.put(SaveSceneAction.ACTION_NAME, new SaveSceneAction(this));
+        actionsMap.put(StartServerAction.ACTION_NAME, new StartServerAction(this));
+        actionsMap.put(StopServerAction.ACTION_NAME, new StopServerAction(this));
+        actionsMap.put(InvalidateAction.ACTION_NAME, new InvalidateAction(this));
+        actionsMap.put(RequestLayoutAction.ACTION_NAME, new RequestLayoutAction(this));
+        actionsMap.put(CaptureNodeAction.ACTION_NAME, new CaptureNodeAction(this));
+        actionsMap.put(RefreshWindowsAction.ACTION_NAME, new RefreshWindowsAction(this));
+    }
+
+    private JComponent buildMainPanel() {
+        mainPanel = new JPanel();
+        mainPanel.setLayout(new BorderLayout());
+        mainPanel.add(buildToolBar(), BorderLayout.PAGE_START);
+        mainPanel.add(deviceSelector = buildDeviceSelector(), BorderLayout.CENTER);
+        mainPanel.add(buildStatusPanel(), BorderLayout.SOUTH);
+
+        mainPanel.setPreferredSize(new Dimension(950, 800));
+
+        return mainPanel;
+    }
+
+    private JComponent buildGraphPanel() {
+        sceneScroller = new JScrollPane();
+        sceneScroller.setBorder(null);
+
+        mainSplitter = new JSplitPane();
+        mainSplitter.setResizeWeight(1.0);
+        mainSplitter.setContinuousLayout(true);
+        if (OS.isMacOsX() && OS.isLeopardOrLater()) {
+            mainSplitter.setBorder(new UnifiedContentBorder());
+        }
+
+        mainSplitter.setLeftComponent(sceneScroller);
+        mainSplitter.setRightComponent(buildSideSplitter());
+
+        return mainSplitter;
+    }
+
+    private JComponent buildDeviceSelector() {
+        JPanel panel = new JPanel(new GridBagLayout());
+        if (OS.isMacOsX() && OS.isLeopardOrLater()) {
+            panel.setBorder(new UnifiedContentBorder());
+        }
+
+        devicesTableModel = new DevicesTableModel();
+        for (Device device : DeviceBridge.getDevices()) {
+            DeviceBridge.setupDeviceForward(device);
+            devicesTableModel.addDevice(device);
+        }
+        DeviceBridge.startListenForDevices(devicesTableModel);
+
+        devices = new JTable(devicesTableModel);
+        devices.getSelectionModel().addListSelectionListener(new DeviceSelectedListener());
+        devices.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        devices.setBorder(null);
+        JScrollPane devicesScroller = new JScrollPane(devices);
+        devicesScroller.setBorder(null);
+        panel.add(devicesScroller, new GridBagConstraints(0, 0, 1, 1, 0.5, 1.0,
+                GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0),
+                0, 0));
+
+        windowsTableModel = new WindowsTableModel();
+        windowsTableModel.setVisible(false);
+
+        windows = new JTable(windowsTableModel);
+        windows.getSelectionModel().addListSelectionListener(new WindowSelectedListener());
+        windows.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        windows.setBorder(null);
+        JScrollPane windowsScroller = new JScrollPane(windows);
+        windowsScroller.setBorder(null);
+        panel.add(windowsScroller, new GridBagConstraints(2, 0, 1, 1, 0.5, 1.0,
+                GridBagConstraints.LINE_START, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0),
+                0, 0));
+
+        return panel;
+    }
+
+    private JComponent buildSideSplitter() {
+        propertiesTable = new JTable();
+        propertiesTable.setModel(new DefaultTableModel(new Object[][] { },
+                new String[] { "Property", "Value" }));
+        propertiesTable.setBorder(null);
+        propertiesTable.getTableHeader().setBorder(null);
+
+        JScrollPane tableScroller = new JScrollPane(propertiesTable);
+        tableScroller.setBorder(null);
+
+        sideSplitter = new JSplitPane();
+        sideSplitter.setBorder(null);
+        sideSplitter.setOrientation(JSplitPane.VERTICAL_SPLIT);
+        sideSplitter.setResizeWeight(0.5);
+        sideSplitter.setLeftComponent(tableScroller);
+        sideSplitter.setBottomComponent(null);
+        sideSplitter.setContinuousLayout(true);
+
+        return sideSplitter;
+    }
+
+    private JPanel buildStatusPanel() {
+        JPanel statusPanel = new JPanel();
+        statusPanel.setLayout(new BorderLayout());
+
+        JPanel leftSide = new JPanel();
+        leftSide.setOpaque(false);
+        leftSide.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 5));
+        leftSide.add(Box.createHorizontalStrut(6));
+
+        ButtonGroup group = new ButtonGroup();
+
+        graphViewButton = new JToggleButton(IconLoader.load(getClass(),
+                "/images/icon-graph-view.png"));
+        graphViewButton.setSelectedIcon(IconLoader.load(getClass(),
+                "/images/icon-graph-view-selected.png"));
+        graphViewButton.putClientProperty("JButton.buttonType", "segmentedTextured");
+        graphViewButton.putClientProperty("JButton.segmentPosition", "first");
+        graphViewButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                toggleGraphView();
+            }
+        });
+        group.add(graphViewButton);
+        leftSide.add(graphViewButton);
+
+        pixelPerfectViewButton = new JToggleButton(IconLoader.load(getClass(),
+                "/images/icon-pixel-perfect-view.png"));
+        pixelPerfectViewButton.setSelectedIcon(IconLoader.load(getClass(),
+                "/images/icon-pixel-perfect-view-selected.png"));
+        pixelPerfectViewButton.putClientProperty("JButton.buttonType", "segmentedTextured");
+        pixelPerfectViewButton.putClientProperty("JButton.segmentPosition", "last");
+        pixelPerfectViewButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                togglePixelPerfectView();
+            }
+        });
+        group.add(pixelPerfectViewButton);
+        leftSide.add(pixelPerfectViewButton);
+
+        graphViewButton.setSelected(true);
+
+        filterText = new JTextField(20);
+        filterText.putClientProperty("JComponent.sizeVariant", "small");
+        filterText.getDocument().addDocumentListener(new DocumentListener() {
+            public void insertUpdate(DocumentEvent e) {
+                updateFilter(e);
+            }
+
+            public void removeUpdate(DocumentEvent e) {
+                updateFilter(e);
+            }
+
+            public void changedUpdate(DocumentEvent e) {
+                updateFilter(e);
+            }
+        });
+
+        filterLabel = new JLabel("Filter by class or id:");
+        filterLabel.putClientProperty("JComponent.sizeVariant", "small");
+        filterLabel.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 6));
+
+        leftSide.add(filterLabel);
+        leftSide.add(filterText);
+
+        minZoomLabel = new JLabel();
+        minZoomLabel.setText("20%");
+        minZoomLabel.putClientProperty("JComponent.sizeVariant", "small");
+        minZoomLabel.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0));
+        leftSide.add(minZoomLabel);
+
+        zoomSlider = new JSlider();
+        zoomSlider.putClientProperty("JComponent.sizeVariant", "small");
+        zoomSlider.setMaximum(200);
+        zoomSlider.setMinimum(20);
+        zoomSlider.setValue(100);
+        zoomSlider.addChangeListener(new ChangeListener() {
+            public void stateChanged(ChangeEvent evt) {
+                zoomSliderStateChanged(evt);
+            }
+        });
+        leftSide.add(zoomSlider);
+
+        maxZoomLabel = new JLabel();
+        maxZoomLabel.putClientProperty("JComponent.sizeVariant", "small");
+        maxZoomLabel.setText("200%");
+        leftSide.add(maxZoomLabel);
+
+        viewCountLabel = new JLabel();
+        viewCountLabel.setText("0 views");
+        viewCountLabel.putClientProperty("JComponent.sizeVariant", "small");
+        viewCountLabel.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0));
+        leftSide.add(viewCountLabel);
+
+        statusPanel.add(leftSide, BorderLayout.LINE_START);
+
+        JPanel rightSide = new JPanel();
+        rightSide.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 12));
+        rightSide.setLayout(new FlowLayout(FlowLayout.RIGHT));
+
+        progress = new JProgressBar();
+        progress.setVisible(false);
+        progress.setIndeterminate(true);
+        progress.putClientProperty("JComponent.sizeVariant", "mini");
+        progress.putClientProperty("JProgressBar.style", "circular");
+        rightSide.add(progress);
+
+        statusPanel.add(rightSide, BorderLayout.LINE_END);
+
+        hideStatusBarComponents();
+
+        return statusPanel;
+    }
+
+    private void hideStatusBarComponents() {
+        viewCountLabel.setVisible(false);
+        zoomSlider.setVisible(false);
+        minZoomLabel.setVisible(false);
+        maxZoomLabel.setVisible(false);
+        filterLabel.setVisible(false);
+        filterText.setVisible(false);
+    }
+
+    private JToolBar buildToolBar() {
+        JToolBar toolBar = new JToolBar();
+        toolBar.setFloatable(false);
+        toolBar.setRollover(true);
+
+        startButton = new JButton();
+        startButton.setAction(actionsMap.get(StartServerAction.ACTION_NAME));
+        startButton.putClientProperty("JButton.buttonType", "segmentedTextured");
+        startButton.putClientProperty("JButton.segmentPosition", "first");
+        toolBar.add(startButton);
+
+        stopButton = new JButton();
+        stopButton.setAction(actionsMap.get(StopServerAction.ACTION_NAME));
+        stopButton.putClientProperty("JButton.buttonType", "segmentedTextured");
+        stopButton.putClientProperty("JButton.segmentPosition", "middle");
+        toolBar.add(stopButton);
+
+        refreshButton = new JButton();
+        refreshButton.setAction(actionsMap.get(RefreshWindowsAction.ACTION_NAME));
+        refreshButton.putClientProperty("JButton.buttonType", "segmentedTextured");
+        refreshButton.putClientProperty("JButton.segmentPosition", "last");
+        toolBar.add(refreshButton);
+
+        showDevicesButton = new JButton();
+        showDevicesButton.setAction(actionsMap.get(ShowDevicesAction.ACTION_NAME));
+        showDevicesButton.putClientProperty("JButton.buttonType", "segmentedTextured");
+        showDevicesButton.putClientProperty("JButton.segmentPosition", "first");
+        toolBar.add(showDevicesButton);
+        showDevicesButton.setEnabled(false);
+
+        loadButton = new JButton();
+        loadButton.setAction(actionsMap.get(LoadGraphAction.ACTION_NAME));
+        loadButton.putClientProperty("JButton.buttonType", "segmentedTextured");
+        loadButton.putClientProperty("JButton.segmentPosition", "last");
+        toolBar.add(loadButton);
+
+        displayNodeButton = new JButton();
+        displayNodeButton.setAction(actionsMap.get(CaptureNodeAction.ACTION_NAME));
+        displayNodeButton.putClientProperty("JButton.buttonType", "segmentedTextured");
+        displayNodeButton.putClientProperty("JButton.segmentPosition", "first");
+        toolBar.add(displayNodeButton);
+
+        invalidateButton = new JButton();
+        invalidateButton.setAction(actionsMap.get(InvalidateAction.ACTION_NAME));
+        invalidateButton.putClientProperty("JButton.buttonType", "segmentedTextured");
+        invalidateButton.putClientProperty("JButton.segmentPosition", "middle");
+        toolBar.add(invalidateButton);
+
+        requestLayoutButton = new JButton();
+        requestLayoutButton.setAction(actionsMap.get(RequestLayoutAction.ACTION_NAME));
+        requestLayoutButton.putClientProperty("JButton.buttonType", "segmentedTextured");
+        requestLayoutButton.putClientProperty("JButton.segmentPosition", "last");
+        toolBar.add(requestLayoutButton);
+
+        return toolBar;
+    }
+
+    private JMenuBar buildMenuBar() {
+        JMenuBar menuBar = new JMenuBar();
+
+        JMenu fileMenu = new JMenu();
+        JMenu viewMenu = new JMenu();
+        JMenu viewHierarchyMenu = new JMenu();
+        JMenu serverMenu = new JMenu();
+
+        saveMenuItem = new JMenuItem();
+        JMenuItem exitMenuItem = new JMenuItem();
+
+        showDevicesMenuItem = new JMenuItem();
+
+        loadMenuItem = new JMenuItem();
+
+        startMenuItem = new JMenuItem();
+        stopMenuItem = new JMenuItem();
+
+        fileMenu.setText("File");
+
+        saveMenuItem.setAction(actionsMap.get(SaveSceneAction.ACTION_NAME));
+        fileMenu.add(saveMenuItem);
+
+        exitMenuItem.setAction(actionsMap.get(ExitAction.ACTION_NAME));
+        fileMenu.add(exitMenuItem);
+
+        menuBar.add(fileMenu);
+
+        viewMenu.setText("View");
+
+        showDevicesMenuItem.setAction(actionsMap.get(ShowDevicesAction.ACTION_NAME));
+        showDevicesMenuItem.setEnabled(false);
+        viewMenu.add(showDevicesMenuItem);
+
+        menuBar.add(viewMenu);        
+
+        viewHierarchyMenu.setText("Hierarchy");
+
+        loadMenuItem.setAction(actionsMap.get(LoadGraphAction.ACTION_NAME));
+        viewHierarchyMenu.add(loadMenuItem);
+
+        menuBar.add(viewHierarchyMenu);
+
+        serverMenu.setText("Server");
+
+        startMenuItem.setAction(actionsMap.get(StartServerAction.ACTION_NAME));
+        serverMenu.add(startMenuItem);
+
+        stopMenuItem.setAction(actionsMap.get(StopServerAction.ACTION_NAME));
+        serverMenu.add(stopMenuItem);
+
+        menuBar.add(serverMenu);
+
+        return menuBar;
+    }
+
+    private JComponent buildPixelPerfectPanel() {
+        JSplitPane splitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+
+        pixelPerfectTree = new JTree(new Object[0]);
+        pixelPerfectTree.setBorder(null);
+        pixelPerfectTree.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6));
+        pixelPerfectTree.addTreeSelectionListener(new TreeSelectionListener() {
+            public void valueChanged(TreeSelectionEvent event) {
+                ViewNode node = (ViewNode) event.getPath().getLastPathComponent();
+                screenViewer.select(node);
+            }
+        });
+
+        JScrollPane scroller = new JScrollPane(pixelPerfectTree);
+        scroller.setBorder(null);
+        scroller.getViewport().setBorder(null);
+
+        splitter.setContinuousLayout(true);
+        splitter.setLeftComponent(scroller);
+        splitter.setRightComponent(buildPixelPerfectViewer(splitter));
+        splitter.setBorder(null);
+
+        if (OS.isMacOsX() && OS.isLeopardOrLater()) {
+            splitter.setBorder(new UnifiedContentBorder());
+        }
+
+        return splitter;
+    }
+
+    private JComponent buildPixelPerfectViewer(JSplitPane splitter) {
+        screenViewer = new ScreenViewer(this, currentDevice, splitter.getDividerSize());
+        return screenViewer;
+    }
+
+    private void toggleGraphView() {
+        showStatusBarComponents();
+
+        screenViewer.stop();
+        mainPanel.remove(pixelPerfectPanel);
+        mainPanel.add(mainSplitter, BorderLayout.CENTER);
+
+        validate();
+        repaint();
+    }
+
+    private void showStatusBarComponents() {
+        viewCountLabel.setVisible(true);
+        zoomSlider.setVisible(true);
+        minZoomLabel.setVisible(true);
+        maxZoomLabel.setVisible(true);
+        filterLabel.setVisible(true);
+        filterText.setVisible(true);
+    }
+
+    private void togglePixelPerfectView() {
+        if (pixelPerfectPanel == null) {
+            pixelPerfectPanel = buildPixelPerfectPanel();
+            showPixelPerfectTree();
+        } else {
+            screenViewer.start();
+        }
+
+        hideStatusBarComponents();
+
+        mainPanel.remove(mainSplitter);
+        mainPanel.add(pixelPerfectPanel, BorderLayout.CENTER);
+
+        validate();
+        repaint();
+    }
+
+    private void zoomSliderStateChanged(ChangeEvent evt) {
+        JSlider slider = (JSlider) evt.getSource();
+        if (sceneView != null) {
+            scene.setZoomFactor(slider.getValue() / 100.0d);
+            sceneView.repaint();
+        }
+    }
+
+    private void showProperties(ViewNode node) {
+        propertiesTable.setModel(new PropertiesTableModel(node));
+    }
+
+    private void showPixelPerfectTree() {
+        if (pixelPerfectTree == null) {
+            return;
+        }
+        pixelPerfectTree.setModel(new ViewsTreeModel(scene.getRoot()));
+        pixelPerfectTree.setCellRenderer(new ViewsTreeCellRenderer());
+        expandAll(pixelPerfectTree, true);
+
+    }
+
+    private static void expandAll(JTree tree, boolean expand) {
+        ViewNode root = (ViewNode) tree.getModel().getRoot();
+        expandAll(tree, new TreePath(root), expand);
+    }
+
+    private static void expandAll(JTree tree, TreePath parent, boolean expand) {
+        // Traverse children
+        ViewNode node = (ViewNode)parent.getLastPathComponent();
+        if (node.children != null) {
+            for (ViewNode n : node.children) {
+                TreePath path = parent.pathByAddingChild(n);
+                expandAll(tree, path, expand);
+            }
+        }
+
+        if (expand) {
+            tree.expandPath(parent);
+        } else {
+            tree.collapsePath(parent);
+        }
+    }
+
+    private void createGraph(ViewHierarchyScene scene) {
+        scene.addObjectSceneListener(new SceneFocusListener(),
+                ObjectSceneEventType.OBJECT_FOCUS_CHANGED);
+
+        if (mainSplitter == null) {
+            mainPanel.remove(deviceSelector);
+            mainPanel.add(buildGraphPanel(), BorderLayout.CENTER);
+            showDevicesButton.setEnabled(true);
+            showDevicesMenuItem.setEnabled(true);
+            graphViewButton.setEnabled(true);
+            pixelPerfectViewButton.setEnabled(true);
+
+            showStatusBarComponents();
+        }
+
+        sceneView = scene.createView();
+        sceneView.addMouseListener(new NodeClickListener());
+        sceneScroller.setViewportView(sceneView);
+
+        if (extrasPanel != null) {
+            sideSplitter.remove(extrasPanel);
+        }
+        sideSplitter.setBottomComponent(buildExtrasPanel());
+
+        mainSplitter.setDividerLocation(getWidth() - mainSplitter.getDividerSize() -
+                buttonsPanel.getPreferredSize().width);
+
+        saveMenuItem.setEnabled(true);
+        showPixelPerfectTree();
+
+        updateStatus();
+        layoutScene();
+    }
+
+    private void layoutScene() {
+        TreeGraphLayout<ViewNode, String> layout =
+                new TreeGraphLayout<ViewNode, String>(scene, 50, 50, 70, 30, true);
+        layout.layout(scene.getRoot());
+    }
+
+    private void updateStatus() {
+        viewCountLabel.setText("" + scene.getNodes().size() + " views");
+        zoomSlider.setEnabled(scene.getNodes().size() > 0);
+    }
+
+    private JPanel buildExtrasPanel() {
+        extrasPanel = new JPanel(new BorderLayout());
+        extrasPanel.add(new JScrollPane(layoutView = new LayoutRenderer(scene)));
+        extrasPanel.add(scene.createSatelliteView(), BorderLayout.SOUTH);
+        extrasPanel.add(buildLayoutViewControlButtons(), BorderLayout.NORTH);
+        return extrasPanel;
+    }
+
+    private JComponent buildLayoutViewControlButtons() {
+        buttonsPanel = new JToolBar();
+        buttonsPanel.setFloatable(false);
+
+        ButtonGroup group = new ButtonGroup();
+
+        JToggleButton white = new JToggleButton("On White");
+        toggleColorOnSelect(white);
+        white.putClientProperty("JButton.buttonType", "segmentedTextured");
+        white.putClientProperty("JButton.segmentPosition", "first");
+        white.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                layoutView.setBackground(Color.WHITE);
+                layoutView.setForeground(Color.BLACK);
+            }
+        });
+        group.add(white);
+        buttonsPanel.add(white);
+
+        JToggleButton black = new JToggleButton("On Black");
+        toggleColorOnSelect(black);
+        black.putClientProperty("JButton.buttonType", "segmentedTextured");
+        black.putClientProperty("JButton.segmentPosition", "last");
+        black.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                layoutView.setBackground(Color.BLACK);
+                layoutView.setForeground(Color.WHITE);
+            }
+        });
+        group.add(black);
+        buttonsPanel.add(black);
+
+        black.setSelected(true);
+
+        JCheckBox showExtras = new JCheckBox("Show Extras");
+        showExtras.putClientProperty("JComponent.sizeVariant", "small");
+        showExtras.addChangeListener(new ChangeListener() {
+            public void stateChanged(ChangeEvent e) {
+                layoutView.setShowExtras(((JCheckBox) e.getSource()).isSelected());
+            }
+        });
+        buttonsPanel.add(showExtras);
+
+        return buttonsPanel;
+    }
+
+    private void showCaptureWindow(ViewNode node, String captureParams, Image image) {
+        if (image != null) {
+            layoutView.repaint();
+
+            JFrame frame = new JFrame(captureParams);
+            JPanel panel = new JPanel(new BorderLayout());
+
+            final CaptureRenderer label = new CaptureRenderer(new ImageIcon(image), node);
+            label.setBorder(BorderFactory.createEmptyBorder(24, 24, 24, 24));
+
+            final JPanel solidColor = new JPanel(new BorderLayout());
+            solidColor.setBackground(Color.BLACK);
+            solidColor.add(label);
+
+            JToolBar toolBar = new JToolBar();
+            toolBar.setFloatable(false);
+
+            ButtonGroup group = new ButtonGroup();
+
+            JToggleButton white = new JToggleButton("On White");
+            toggleColorOnSelect(white);
+            white.putClientProperty("JButton.buttonType", "segmentedTextured");
+            white.putClientProperty("JButton.segmentPosition", "first");
+            white.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent e) {
+                    solidColor.setBackground(Color.WHITE);
+                }
+            });
+            group.add(white);
+            toolBar.add(white);
+
+            JToggleButton black = new JToggleButton("On Black");
+            toggleColorOnSelect(black);
+            black.putClientProperty("JButton.buttonType", "segmentedTextured");
+            black.putClientProperty("JButton.segmentPosition", "last");
+            black.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent e) {
+                    solidColor.setBackground(Color.BLACK);
+                }
+            });
+            group.add(black);
+            toolBar.add(black);
+
+            black.setSelected(true);
+
+            JCheckBox showExtras = new JCheckBox("Show Extras");
+            showExtras.addChangeListener(new ChangeListener() {
+                public void stateChanged(ChangeEvent e) {
+                    label.setShowExtras(((JCheckBox) e.getSource()).isSelected());
+                }
+            });
+            toolBar.add(showExtras);
+
+            panel.add(toolBar, BorderLayout.NORTH);
+            panel.add(solidColor);
+            frame.add(panel);
+
+            frame.pack();
+            frame.setResizable(false);
+            frame.setLocationRelativeTo(Workspace.this);
+            frame.setVisible(true);
+        }
+    }
+
+    private void reset() {
+        currentDevice = null;
+        currentWindow = null;
+        currentDeviceChanged();
+        windowsTableModel.setVisible(false);
+        windowsTableModel.clear();
+
+        showDevicesSelector();
+    }
+
+    public void showDevicesSelector() {
+        if (mainSplitter != null) {
+            if (pixelPerfectPanel != null) {
+                screenViewer.start();                
+            }
+            mainPanel.remove(graphViewButton.isSelected() ? mainSplitter : pixelPerfectPanel);
+            mainPanel.add(deviceSelector, BorderLayout.CENTER);
+            pixelPerfectPanel = mainSplitter = null;
+            graphViewButton.setSelected(true);
+
+            hideStatusBarComponents();
+
+            saveMenuItem.setEnabled(false);            
+            showDevicesMenuItem.setEnabled(false);
+            showDevicesButton.setEnabled(false);
+            displayNodeButton.setEnabled(false);
+            invalidateButton.setEnabled(false);
+            requestLayoutButton.setEnabled(false);
+            graphViewButton.setEnabled(false);
+            pixelPerfectViewButton.setEnabled(false);
+
+            if (currentDevice != null) {
+                if (!DeviceBridge.isViewServerRunning(currentDevice)) {
+                    DeviceBridge.startViewServer(currentDevice);
+                }
+                loadWindows().execute();
+                windowsTableModel.setVisible(true);
+            }
+
+            validate();
+            repaint();
+        }
+    }
+
+    private void currentDeviceChanged() {
+        if (currentDevice == null) {
+            startButton.setEnabled(false);
+            startMenuItem.setEnabled(false);
+            stopButton.setEnabled(false);
+            stopMenuItem.setEnabled(false);
+            refreshButton.setEnabled(false);
+            saveMenuItem.setEnabled(false);
+            loadButton.setEnabled(false);
+            displayNodeButton.setEnabled(false);
+            invalidateButton.setEnabled(false);
+            graphViewButton.setEnabled(false);
+            pixelPerfectViewButton.setEnabled(false);
+            requestLayoutButton.setEnabled(false);
+            loadMenuItem.setEnabled(false);
+        } else {
+            loadMenuItem.setEnabled(true);
+            checkForServerOnCurrentDevice();
+        }
+    }
+
+    private void checkForServerOnCurrentDevice() {
+        if (DeviceBridge.isViewServerRunning(currentDevice)) {
+            startButton.setEnabled(false);
+            startMenuItem.setEnabled(false);
+            stopButton.setEnabled(true);
+            stopMenuItem.setEnabled(true);
+            loadButton.setEnabled(true);
+            refreshButton.setEnabled(true);
+        } else {
+            startButton.setEnabled(true);
+            startMenuItem.setEnabled(true);
+            stopButton.setEnabled(false);
+            stopMenuItem.setEnabled(false);
+            loadButton.setEnabled(false);
+            refreshButton.setEnabled(false);
+        }
+    }
+
+    public void cleanupDevices() {
+        for (Device device : devicesTableModel.getDevices()) {
+            DeviceBridge.removeDeviceForward(device);
+        }
+    }
+
+    private static void toggleColorOnSelect(JToggleButton button) {
+        if (!OS.isMacOsX() || !OS.isLeopardOrLater()) {
+            return;
+        }
+
+        button.addChangeListener(new ChangeListener() {
+            public void stateChanged(ChangeEvent event) {
+                JToggleButton button = (JToggleButton) event.getSource();
+                if (button.isSelected()) {
+                    button.setForeground(Color.WHITE);
+                } else {
+                    button.setForeground(Color.BLACK);
+                }
+            }
+        });
+    }
+
+    private void updateFilter(DocumentEvent e) {
+        final Document document = e.getDocument();
+        try {
+            updateFilteredNodes(document.getText(0, document.getLength()));
+        } catch (BadLocationException e1) {
+            e1.printStackTrace();
+        }
+    }
+
+    private void updateFilteredNodes(String filterText) {
+        final ViewNode root = scene.getRoot();
+        try {
+            final Pattern pattern = Pattern.compile(filterText, Pattern.CASE_INSENSITIVE);
+            filterNodes(pattern, root);
+        } catch (PatternSyntaxException e) {
+            filterNodes(null, root);
+        }
+        repaint();
+    }
+
+    private void filterNodes(Pattern pattern, ViewNode root) {
+        root.filter(pattern);
+
+        for (ViewNode node : root.children) {
+            filterNodes(pattern, node);
+        }
+    }
+
+    public void beginTask() {
+        progress.setVisible(true);
+    }
+
+    public void endTask() {
+        progress.setVisible(false);
+    }
+
+    public SwingWorker<?, ?> showNodeCapture() {
+        if (scene.getFocusedObject() == null) {
+            return null;
+        }
+        return new CaptureNodeTask();
+    }    
+
+    public SwingWorker<?, ?> startServer() {
+        return new StartServerTask();
+    }
+
+    public SwingWorker<?, ?> stopServer() {
+        return new StopServerTask();
+    }
+
+    public SwingWorker<?, ?> loadWindows() {
+        return new LoadWindowsTask();
+    }
+
+    public SwingWorker<?, ?> loadGraph() {
+        return new LoadGraphTask();
+    }
+
+    public SwingWorker<?, ?> invalidateView() {
+        if (scene.getFocusedObject() == null) {
+            return null;
+        }
+        return new InvalidateTask();
+    }
+
+    public SwingWorker<?, ?> requestLayout() {
+        if (scene.getFocusedObject() == null) {
+            return null;
+        }
+        return new RequestLayoutTask();
+    }
+
+    public SwingWorker<?, ?> saveSceneAsImage() {
+        JFileChooser chooser = new JFileChooser();
+        chooser.setFileFilter(new PngFileFilter());
+        int choice = chooser.showSaveDialog(sceneView);
+        if (choice == JFileChooser.APPROVE_OPTION) {
+            return new SaveSceneTask(chooser.getSelectedFile());
+        } else {
+            return null;
+        }
+    }
+
+    private class InvalidateTask extends SwingWorker<Object, Void> {
+        private String captureParams;
+
+        private InvalidateTask() {
+            captureParams = scene.getFocusedObject().toString();
+            beginTask();
+        }
+
+        @Override
+        @WorkerThread
+        protected Object doInBackground() throws Exception {
+            ViewManager.invalidate(currentDevice, currentWindow, captureParams);
+            return null;
+        }
+
+        @Override
+        protected void done() {
+            endTask();
+        }
+    }
+
+    private class RequestLayoutTask extends SwingWorker<Object, Void> {
+        private String captureParams;
+
+        private RequestLayoutTask() {
+            captureParams = scene.getFocusedObject().toString();
+            beginTask();
+        }
+
+        @Override
+        @WorkerThread
+        protected Object doInBackground() throws Exception {
+            ViewManager.requestLayout(currentDevice, currentWindow, captureParams);
+            return null;
+        }
+
+        @Override
+        protected void done() {
+            endTask();
+        }
+    }
+
+    private class CaptureNodeTask extends SwingWorker<Image, Void> {
+        private String captureParams;
+        private ViewNode node;
+
+        private CaptureNodeTask() {
+            node = (ViewNode) scene.getFocusedObject();
+            captureParams = node.toString();
+            beginTask();
+        }
+
+        @Override
+        @WorkerThread
+        protected Image doInBackground() throws Exception {
+            node.image = CaptureLoader.loadCapture(currentDevice, currentWindow, captureParams);
+            return node.image;
+        }
+
+        @Override
+        protected void done() {
+            try {
+                Image image = get();
+                showCaptureWindow(node, captureParams, image);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            } catch (ExecutionException e) {
+                e.printStackTrace();
+            } finally {
+                endTask();
+            }
+        }
+    }
+
+    private class LoadWindowsTask extends SwingWorker<Window[], Void> {
+        private LoadWindowsTask() {
+            beginTask();
+        }
+
+        @Override
+        @WorkerThread
+        protected Window[] doInBackground() throws Exception {
+            return WindowsLoader.loadWindows(currentDevice);
+        }
+
+        @Override
+        protected void done() {
+            try {
+                windowsTableModel.clear();
+                windowsTableModel.addWindows(get());
+            } catch (ExecutionException e) {
+                e.printStackTrace();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            } finally {
+                endTask();
+            }
+        }
+    }
+
+    private class StartServerTask extends SwingWorker<Object, Void> {
+        public StartServerTask() {
+            beginTask();
+        }
+
+        @Override
+        @WorkerThread
+        protected Object doInBackground() {
+            DeviceBridge.startViewServer(currentDevice);
+            return null;
+        }
+
+        @Override
+        protected void done() {
+            new LoadWindowsTask().execute();
+            windowsTableModel.setVisible(true);
+            checkForServerOnCurrentDevice();
+            endTask();
+        }
+    }
+
+    private class StopServerTask extends SwingWorker<Object, Void> {
+        public StopServerTask() {
+            beginTask();
+        }
+
+        @Override
+        @WorkerThread
+        protected Object doInBackground() {
+            DeviceBridge.stopViewServer(currentDevice);
+            return null;
+        }
+
+        @Override
+        protected void done() {
+            windowsTableModel.setVisible(false);
+            windowsTableModel.clear();
+            checkForServerOnCurrentDevice();
+            endTask();
+        }
+    }
+
+    private class LoadGraphTask extends SwingWorker<ViewHierarchyScene, Void> {
+        public LoadGraphTask() {
+            beginTask();
+        }
+
+        @Override
+        @WorkerThread
+        protected ViewHierarchyScene doInBackground() {
+            scene = ViewHierarchyLoader.loadScene(currentDevice, currentWindow);
+            return scene;
+        }
+
+        @Override
+        protected void done() {
+            try {
+                createGraph(get());
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            } catch (ExecutionException e) {
+                e.printStackTrace();
+            } finally {
+                endTask();
+            }
+        }
+    }
+
+    private class SaveSceneTask extends SwingWorker<Object, Void> {
+        private File file;
+
+        private SaveSceneTask(File file) {
+            this.file = file;
+            beginTask();
+        }
+
+        @Override
+        @WorkerThread
+        protected Object doInBackground() {
+            if (sceneView == null) {
+                return null;
+            }
+
+            try {
+                BufferedImage image = new BufferedImage(sceneView.getWidth(),
+                        sceneView.getHeight(), BufferedImage.TYPE_INT_RGB);
+                Graphics2D g2 = image.createGraphics();
+                sceneView.paint(g2);
+                g2.dispose();
+                ImageIO.write(image, "PNG", file);
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+            return null;
+        }
+
+        @Override
+        protected void done() {
+            endTask();            
+        }
+    }
+
+    private class SceneFocusListener implements ObjectSceneListener {
+
+        public void objectAdded(ObjectSceneEvent arg0, Object arg1) {
+        }
+
+        public void objectRemoved(ObjectSceneEvent arg0, Object arg1) {
+        }
+
+        public void objectStateChanged(ObjectSceneEvent arg0, Object arg1,
+                ObjectState arg2, ObjectState arg3) {
+        }
+
+        public void selectionChanged(ObjectSceneEvent e, Set<Object> previousSelection,
+                Set<Object> newSelection) {
+        }
+
+        public void highlightingChanged(ObjectSceneEvent arg0, Set<Object> arg1, Set<Object> arg2) {
+        }
+
+        public void hoverChanged(ObjectSceneEvent arg0, Object arg1, Object arg2) {
+        }
+
+        public void focusChanged(ObjectSceneEvent e, Object oldFocus, Object newFocus) {
+            displayNodeButton.setEnabled(true);
+            invalidateButton.setEnabled(true);
+            requestLayoutButton.setEnabled(true);
+
+            Set<Object> selection = new HashSet<Object>();
+            selection.add(newFocus);
+            scene.setSelectedObjects(selection);
+
+            showProperties((ViewNode) newFocus);
+            layoutView.repaint();
+        }
+    }
+
+    private class NodeClickListener extends MouseAdapter {
+        @Override
+        public void mouseClicked(MouseEvent e) {
+            if (e.getClickCount() == 2) {
+                showNodeCapture().execute();
+            }
+        }
+    }
+
+    private class DevicesTableModel extends DefaultTableModel implements
+            AndroidDebugBridge.IDeviceChangeListener {
+
+        private ArrayList<Device> devices;
+
+        private DevicesTableModel() {
+            devices = new ArrayList<Device>();
+        }
+
+        @Override
+        public int getColumnCount() {
+            return 1;
+        }
+
+        @Override
+        public boolean isCellEditable(int row, int column) {
+            return false;
+        }
+
+        @Override
+        public Object getValueAt(int row, int column) {
+            return devices.get(row);
+        }
+
+        @Override
+        public String getColumnName(int column) {
+            return "Devices";
+        }
+
+        @WorkerThread
+        public void deviceConnected(final Device device) {
+            DeviceBridge.setupDeviceForward(device);
+
+            SwingUtilities.invokeLater(new Runnable() {
+                public void run() {
+                    addDevice(device);
+                }
+            });
+        }
+
+        @WorkerThread
+        public void deviceDisconnected(final Device device) {
+            DeviceBridge.removeDeviceForward(device);
+
+            SwingUtilities.invokeLater(new Runnable() {
+                public void run() {
+                    removeDevice(device);
+                }
+            });
+        }
+
+        public void addDevice(Device device) {
+            if (!devices.contains(device)) {
+                devices.add(device);
+                fireTableDataChanged();
+            }
+        }
+
+        public void removeDevice(Device device) {
+            if (device.equals(currentDevice)) {
+                reset();
+            }
+
+            if (devices.contains(device)) {
+                devices.remove(device);
+                fireTableDataChanged();
+            }
+        }
+
+        @WorkerThread
+        public void deviceChanged(Device device, int changeMask) {
+            if ((changeMask & Device.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) {
+                // if the changed device is the current one and the client list changed, we update
+                // the UI.
+                loadWindows().execute();
+                windowsTableModel.setVisible(true);
+            }
+        }
+
+        @Override
+        public int getRowCount() {
+            return devices == null ? 0 : devices.size();
+        }
+
+        public Device getDevice(int index) {
+            return index < devices.size() ? devices.get(index) : null;
+        }
+
+        public Device[] getDevices() {
+            return devices.toArray(new Device[devices.size()]);
+        }
+    }
+
+    private static class WindowsTableModel extends DefaultTableModel {
+        private ArrayList<Window> windows;
+        private boolean visible;
+
+        private WindowsTableModel() {
+            windows = new ArrayList<Window>();
+            windows.add(Window.FOCUSED_WINDOW);
+        }
+
+        @Override
+        public int getColumnCount() {
+            return 1;
+        }
+
+        @Override
+        public boolean isCellEditable(int row, int column) {
+            return false;
+        }
+
+        @Override
+        public String getColumnName(int column) {
+            return "Windows";
+        }
+
+        @Override
+        public Object getValueAt(int row, int column) {
+            return windows.get(row);
+        }
+
+        @Override
+        public int getRowCount() {
+            return !visible || windows == null ? 0 : windows.size();
+        }
+
+        public void setVisible(boolean visible) {
+            this.visible = visible;
+            fireTableDataChanged();
+        }
+
+        public void addWindow(Window window) {
+            windows.add(window);
+            fireTableDataChanged();
+        }
+
+        public void addWindows(Window[] windowsList) {
+            //noinspection ManualArrayToCollectionCopy
+            for (Window window : windowsList) {
+                windows.add(window);
+            }
+            fireTableDataChanged();
+        }
+
+        public void clear() {
+            windows.clear();
+            windows.add(Window.FOCUSED_WINDOW);            
+        }
+
+        public Window getWindow(int index) {
+            return windows.get(index);
+        }
+    }
+
+    private class DeviceSelectedListener implements ListSelectionListener {
+        public void valueChanged(ListSelectionEvent event) {
+            if (event.getValueIsAdjusting()) {
+                return;
+            }
+
+            int row = devices.getSelectedRow();
+            if (row >= 0) {
+                currentDevice = devicesTableModel.getDevice(row);
+                currentDeviceChanged();
+                if (currentDevice != null) {
+                    if (!DeviceBridge.isViewServerRunning(currentDevice)) {
+                        DeviceBridge.startViewServer(currentDevice);
+                        checkForServerOnCurrentDevice();                        
+                    }
+                    loadWindows().execute();
+                    windowsTableModel.setVisible(true);
+                }
+            } else {
+                currentDevice = null;
+                currentDeviceChanged();
+                windowsTableModel.setVisible(false);
+                windowsTableModel.clear();
+            }
+        }
+    }
+
+    private class WindowSelectedListener implements ListSelectionListener {
+        public void valueChanged(ListSelectionEvent event) {
+            if (event.getValueIsAdjusting()) {
+                return;
+            }
+
+            int row = windows.getSelectedRow();
+            if (row >= 0) {
+                currentWindow = windowsTableModel.getWindow(row);
+            } else {
+                currentWindow = Window.FOCUSED_WINDOW;
+            }
+        }
+    }
+
+    private static class ViewsTreeCellRenderer extends DefaultTreeCellRenderer {
+        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected,
+                boolean expanded, boolean leaf, int row, boolean hasFocus) {
+
+            final String name = ((ViewNode) value).name;
+            value = name.substring(name.lastIndexOf('.') + 1, name.lastIndexOf('@'));
+            return super.getTreeCellRendererComponent(tree, value, selected, expanded,
+                    leaf, row, hasFocus);
+        }
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/BackgroundAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/BackgroundAction.java
new file mode 100644
index 0000000..051e3f3
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/BackgroundAction.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui.action;
+
+import org.jdesktop.swingworker.SwingWorker;
+
+import javax.swing.AbstractAction;
+
+public abstract class BackgroundAction extends AbstractAction {
+    protected void executeBackgroundTask(SwingWorker<?, ?> worker) {
+        if (worker != null) {
+            worker.execute();
+        }
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/CaptureNodeAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/CaptureNodeAction.java
new file mode 100644
index 0000000..a8aee3c
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/CaptureNodeAction.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui.action;
+
+import com.android.hierarchyviewer.ui.Workspace;
+
+import javax.swing.KeyStroke;
+import java.awt.event.KeyEvent;
+import java.awt.event.ActionEvent;
+import java.awt.Toolkit;
+
+public class CaptureNodeAction extends BackgroundAction {
+    public static final String ACTION_NAME = "captureNode";
+    private Workspace mWorkspace;
+
+    public CaptureNodeAction(Workspace workspace) {
+        putValue(NAME, "Display View");
+        putValue(SHORT_DESCRIPTION, "Display View");
+        putValue(LONG_DESCRIPTION, "Display View");
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_D,
+                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
+        this.mWorkspace = workspace;
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        executeBackgroundTask(mWorkspace.showNodeCapture());
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/ExitAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/ExitAction.java
new file mode 100644
index 0000000..e5aaed5
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/ExitAction.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui.action;
+
+import com.android.hierarchyviewer.ui.Workspace;
+import com.android.hierarchyviewer.device.DeviceBridge;
+
+import javax.swing.AbstractAction;
+import javax.swing.KeyStroke;
+import java.awt.event.KeyEvent;
+import java.awt.event.ActionEvent;
+import java.awt.Toolkit;
+
+public class ExitAction extends AbstractAction {
+    public static final String ACTION_NAME = "exit";
+    private Workspace mWorkspace;
+
+    public ExitAction(Workspace workspace) {
+        putValue(NAME, "Quit");
+        putValue(SHORT_DESCRIPTION, "Quit");
+        putValue(LONG_DESCRIPTION, "Quit");
+        putValue(MNEMONIC_KEY, KeyEvent.VK_Q);
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_Q,
+                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
+        this.mWorkspace = workspace;
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        mWorkspace.cleanupDevices();
+        mWorkspace.dispose();
+        DeviceBridge.terminate();
+        System.exit(0);
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/InvalidateAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/InvalidateAction.java
new file mode 100644
index 0000000..7767cda
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/InvalidateAction.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui.action;
+
+import com.android.hierarchyviewer.ui.Workspace;
+
+import javax.swing.KeyStroke;
+import java.awt.event.KeyEvent;
+import java.awt.event.ActionEvent;
+import java.awt.Toolkit;
+
+public class InvalidateAction extends BackgroundAction {
+    public static final String ACTION_NAME = "invalidate";
+    private Workspace mWorkspace;
+
+    public InvalidateAction(Workspace workspace) {
+        putValue(NAME, "Invalidate");
+        putValue(SHORT_DESCRIPTION, "Invalidate");
+        putValue(LONG_DESCRIPTION, "Invalidate");
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_I,
+                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
+        this.mWorkspace = workspace;
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        executeBackgroundTask(mWorkspace.invalidateView());
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/LoadGraphAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/LoadGraphAction.java
new file mode 100644
index 0000000..42c8b8e
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/LoadGraphAction.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui.action;
+
+import com.android.hierarchyviewer.ui.Workspace;
+
+import javax.swing.KeyStroke;
+import java.awt.event.KeyEvent;
+import java.awt.event.ActionEvent;
+import java.awt.Toolkit;
+
+public class LoadGraphAction extends BackgroundAction {
+    public static final String ACTION_NAME = "loadGraph";
+    private Workspace mWorkspace;
+
+    public LoadGraphAction(Workspace workspace) {
+        putValue(NAME, "Load View Hierarchy");
+        putValue(SHORT_DESCRIPTION, "Load");
+        putValue(LONG_DESCRIPTION, "Load View Hierarchy");
+        putValue(MNEMONIC_KEY, KeyEvent.VK_L);
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_L,
+                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
+        this.mWorkspace = workspace;
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        executeBackgroundTask(mWorkspace.loadGraph());
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/RefreshWindowsAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/RefreshWindowsAction.java
new file mode 100644
index 0000000..bcb7ea7
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/RefreshWindowsAction.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui.action;
+
+import com.android.hierarchyviewer.ui.Workspace;
+
+import javax.swing.KeyStroke;
+import java.awt.event.KeyEvent;
+import java.awt.event.ActionEvent;
+
+public class RefreshWindowsAction extends BackgroundAction {
+    public static final String ACTION_NAME = "refreshWindows";
+    private Workspace mWorkspace;
+
+    public RefreshWindowsAction(Workspace workspace) {
+        putValue(NAME, "Refresh Windows");
+        putValue(SHORT_DESCRIPTION, "Refresh");
+        putValue(LONG_DESCRIPTION, "Refresh Windows");
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F7, 0));
+        this.mWorkspace = workspace;
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        executeBackgroundTask(mWorkspace.loadWindows());
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/RequestLayoutAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/RequestLayoutAction.java
new file mode 100644
index 0000000..6fc2832
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/RequestLayoutAction.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui.action;
+
+import com.android.hierarchyviewer.ui.Workspace;
+
+import javax.swing.KeyStroke;
+import java.awt.event.KeyEvent;
+import java.awt.event.ActionEvent;
+import java.awt.Toolkit;
+
+public class RequestLayoutAction extends BackgroundAction {
+    public static final String ACTION_NAME = "requestLayout";
+    private Workspace mWorkspace;
+
+    public RequestLayoutAction(Workspace workspace) {
+        putValue(NAME, "Request Layout");
+        putValue(SHORT_DESCRIPTION, "Request Layout");
+        putValue(LONG_DESCRIPTION, "Request Layout");
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_R,
+                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
+        this.mWorkspace = workspace;
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        executeBackgroundTask(mWorkspace.requestLayout());
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/SaveSceneAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/SaveSceneAction.java
new file mode 100644
index 0000000..7c7a8a9
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/SaveSceneAction.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui.action;
+
+import com.android.hierarchyviewer.ui.Workspace;
+
+import javax.swing.KeyStroke;
+import java.awt.event.KeyEvent;
+import java.awt.event.ActionEvent;
+import java.awt.Toolkit;
+
+public class SaveSceneAction extends BackgroundAction {
+    public static final String ACTION_NAME = "saveScene";
+    private Workspace mWorkspace;
+
+    public SaveSceneAction(Workspace workspace) {
+        mWorkspace = workspace;
+        putValue(NAME, "Save as PNG...");
+        putValue(SHORT_DESCRIPTION, "Save");
+        putValue(LONG_DESCRIPTION, "Save as PNG...");
+        putValue(MNEMONIC_KEY, KeyEvent.VK_S);
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S,
+                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        executeBackgroundTask(mWorkspace.saveSceneAsImage());
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/ShowDevicesAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/ShowDevicesAction.java
new file mode 100644
index 0000000..a91ab7a
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/ShowDevicesAction.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui.action;
+
+import com.android.hierarchyviewer.ui.Workspace;
+
+import javax.swing.AbstractAction;
+import javax.swing.KeyStroke;
+import java.awt.event.KeyEvent;
+import java.awt.event.ActionEvent;
+import java.awt.Toolkit;
+
+public class ShowDevicesAction extends AbstractAction {
+    public static final String ACTION_NAME = "showDevices";
+    private Workspace mWorkspace;
+
+    public ShowDevicesAction(Workspace workspace) {
+        putValue(NAME, "Devices");
+        putValue(SHORT_DESCRIPTION, "Devices");
+        putValue(LONG_DESCRIPTION, "Show Devices");
+        putValue(MNEMONIC_KEY, KeyEvent.VK_D);
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_D,
+                Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
+        this.mWorkspace = workspace;
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        mWorkspace.showDevicesSelector();
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/StartServerAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/StartServerAction.java
new file mode 100644
index 0000000..ccb6ae0
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/StartServerAction.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui.action;
+
+import com.android.hierarchyviewer.ui.Workspace;
+
+import javax.swing.KeyStroke;
+import java.awt.event.KeyEvent;
+import java.awt.event.ActionEvent;
+
+public class StartServerAction extends BackgroundAction {
+    public static final String ACTION_NAME = "startServer";
+    private Workspace mWorkspace;
+
+    public StartServerAction(Workspace workspace) {
+        putValue(NAME, "Start Server");
+        putValue(SHORT_DESCRIPTION, "Start");
+        putValue(LONG_DESCRIPTION, "Start Server");
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
+        this.mWorkspace = workspace;
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        executeBackgroundTask(mWorkspace.startServer());
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/StopServerAction.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/StopServerAction.java
new file mode 100644
index 0000000..ac76e14
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/action/StopServerAction.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui.action;
+
+import com.android.hierarchyviewer.ui.Workspace;
+
+import javax.swing.KeyStroke;
+import java.awt.event.KeyEvent;
+import java.awt.event.ActionEvent;
+
+public class StopServerAction extends BackgroundAction {
+    public static final String ACTION_NAME = "stopServer";
+    private Workspace mWorkspace;
+
+    public StopServerAction(Workspace workspace) {
+        putValue(NAME, "Stop Server");
+        putValue(SHORT_DESCRIPTION, "Stop");
+        putValue(LONG_DESCRIPTION, "Stop Server");
+        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F6, 0));
+        this.mWorkspace = workspace;
+    }
+
+    public void actionPerformed(ActionEvent e) {
+        executeBackgroundTask(mWorkspace.stopServer());
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/PropertiesTableModel.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/PropertiesTableModel.java
new file mode 100644
index 0000000..cc4f7e3
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/PropertiesTableModel.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui.model;
+
+import com.android.hierarchyviewer.scene.ViewNode;
+
+import javax.swing.table.DefaultTableModel;
+import java.util.List;
+import java.util.ArrayList;
+
+public class PropertiesTableModel extends DefaultTableModel {
+    private List<ViewNode.Property> properties;
+    private List<ViewNode.Property> privateProperties = new ArrayList<ViewNode.Property>();
+
+    public PropertiesTableModel(ViewNode node) {
+        properties = node.properties;
+        loadPrivateProperties(node);
+    }
+
+    private void loadPrivateProperties(ViewNode node) {
+        int x = node.left;
+        int y = node.top;
+        ViewNode p = node.parent;
+        while (p != null) {
+            x += p.left - p.scrollX;
+            y += p.top - p.scrollY;
+            p = p.parent;
+        }
+
+        ViewNode.Property property = new ViewNode.Property();
+        property.name = "absolute_x";
+        property.value = String.valueOf(x);
+        privateProperties.add(property);
+
+        property = new ViewNode.Property();
+        property.name = "absolute_y";
+        property.value = String.valueOf(y);
+        privateProperties.add(property);
+    }
+
+    @Override
+    public int getRowCount() {
+        return (privateProperties == null ? 0 : privateProperties.size()) +
+                (properties == null ? 0 : properties.size());
+    }
+
+    @Override
+    public Object getValueAt(int row, int column) {
+        ViewNode.Property property;
+
+        if (row < privateProperties.size()) {
+            property = privateProperties.get(row);
+        } else {
+            property = properties.get(row - privateProperties.size());
+        }
+
+        return column == 0 ? property.name : property.value;
+    }
+
+    @Override
+    public int getColumnCount() {
+        return 2;
+    }
+
+    @Override
+    public String getColumnName(int column) {
+        return column == 0 ? "Property" : "Value";
+    }
+
+    @Override
+    public boolean isCellEditable(int arg0, int arg1) {
+        return false;
+    }
+
+    @Override
+    public void setValueAt(Object arg0, int arg1, int arg2) {
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/ViewsTreeModel.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/ViewsTreeModel.java
new file mode 100644
index 0000000..f3a07f8
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/model/ViewsTreeModel.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.ui.model;
+
+import com.android.hierarchyviewer.scene.ViewNode;
+
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreePath;
+import javax.swing.event.TreeModelListener;
+
+public class ViewsTreeModel implements TreeModel {
+    private final ViewNode root;
+
+    public ViewsTreeModel(ViewNode root) {
+        this.root = root;
+    }
+
+    public Object getRoot() {
+        return root;
+    }
+
+    public Object getChild(Object o, int i) {
+        return ((ViewNode) o).children.get(i);
+    }
+
+    public int getChildCount(Object o) {
+        return ((ViewNode) o).children.size();
+    }
+
+    public boolean isLeaf(Object child) {
+        ViewNode node = (ViewNode) child;
+        return node.children == null || node.children.size() == 0;
+    }
+
+    public void valueForPathChanged(TreePath treePath, Object child) {
+    }
+
+    public int getIndexOfChild(Object parent, Object child) {
+        //noinspection SuspiciousMethodCalls
+        return ((ViewNode) parent).children.indexOf(child);
+    }
+
+    public void addTreeModelListener(TreeModelListener treeModelListener) {
+    }
+
+    public void removeTreeModelListener(TreeModelListener treeModelListener) {
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/util/IconLoader.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/util/IconLoader.java
new file mode 100644
index 0000000..ef73956
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/util/IconLoader.java
@@ -0,0 +1,49 @@
+package com.android.hierarchyviewer.ui.util;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.imageio.ImageIO;
+import java.io.IOException;
+import java.awt.image.BufferedImage;
+import java.awt.Graphics;
+import java.awt.GraphicsEnvironment;
+import java.awt.GraphicsConfiguration;
+
+public class IconLoader {
+    public static Icon load(Class<?> klass, String path) {
+        try {
+            return new ImageIcon(ImageIO.read(klass.getResourceAsStream(path)));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private static GraphicsConfiguration getGraphicsConfiguration() {
+        GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
+        return environment.getDefaultScreenDevice().getDefaultConfiguration();
+    }
+
+    private static boolean isHeadless() {
+        return GraphicsEnvironment.isHeadless();
+    }
+
+    public static BufferedImage toCompatibleImage(BufferedImage image) {
+        if (isHeadless()) {
+            return image;
+        }
+
+        if (image.getColorModel().equals(
+                getGraphicsConfiguration().getColorModel())) {
+            return image;
+        }
+
+        BufferedImage compatibleImage = getGraphicsConfiguration().createCompatibleImage(
+                    image.getWidth(), image.getHeight(), image.getTransparency());
+        Graphics g = compatibleImage.getGraphics();
+        g.drawImage(image, 0, 0, null);
+        g.dispose();
+
+        return compatibleImage;
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/util/PngFileFilter.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/util/PngFileFilter.java
new file mode 100644
index 0000000..5d6472d
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/ui/util/PngFileFilter.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.hierarchyviewer.ui.util;
+
+import javax.swing.filechooser.FileFilter;
+import java.io.File;
+
+public class PngFileFilter extends FileFilter {
+    @Override
+    public boolean accept(File f) {
+        return f.isDirectory() || f.getName().toLowerCase().endsWith(".png");
+    }
+
+    @Override
+    public String getDescription() {
+        return "PNG Image (*.png)";
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/util/OS.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/util/OS.java
new file mode 100644
index 0000000..fd619d6
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/util/OS.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hierarchyviewer.util;
+
+public class OS {
+    private static boolean macOs;
+    private static boolean leopard;
+    private static boolean linux;
+    private static boolean windows;
+
+    static {
+        String osName = System.getProperty("os.name");
+        macOs = "Mac OS X".startsWith(osName);
+        linux = "Linux".startsWith(osName);
+        windows = "Windows".startsWith(osName);
+
+        String version = System.getProperty("os.version");
+        final String[] parts = version.split("\\.");
+        leopard = Integer.parseInt(parts[0]) >= 10 && Integer.parseInt(parts[1]) >= 5;
+    }
+
+    public static boolean isMacOsX() {
+        return macOs;
+    }
+
+    public static boolean isLeopardOrLater() {
+        return leopard;
+    }
+
+    public static boolean isLinux() {
+        return linux;
+    }
+
+    public static boolean isWindows() {
+        return windows;
+    }
+}
diff --git a/tools/hierarchyviewer/src/com/android/hierarchyviewer/util/WorkerThread.java b/tools/hierarchyviewer/src/com/android/hierarchyviewer/util/WorkerThread.java
new file mode 100644
index 0000000..c714c1c
--- /dev/null
+++ b/tools/hierarchyviewer/src/com/android/hierarchyviewer/util/WorkerThread.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.hierarchyviewer.util;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Simple utility class used only to mark methods that are not executed on the UI thread
+ * (or Event Dispatch Thread in Swing/AWT.) This annotation's sole purpose is to help
+ * reading the source code. It has no additional effect.
+ */
+@Target({ ElementType.METHOD })
+@Retention(RetentionPolicy.SOURCE)
+public @interface WorkerThread {
+}
diff --git a/tools/hierarchyviewer/src/resources/images/icon-graph-view-selected.png b/tools/hierarchyviewer/src/resources/images/icon-graph-view-selected.png
new file mode 100644
index 0000000..91f7119
--- /dev/null
+++ b/tools/hierarchyviewer/src/resources/images/icon-graph-view-selected.png
Binary files differ
diff --git a/tools/hierarchyviewer/src/resources/images/icon-graph-view.png b/tools/hierarchyviewer/src/resources/images/icon-graph-view.png
new file mode 100644
index 0000000..9a7f68b
--- /dev/null
+++ b/tools/hierarchyviewer/src/resources/images/icon-graph-view.png
Binary files differ
diff --git a/tools/hierarchyviewer/src/resources/images/icon-pixel-perfect-view-selected.png b/tools/hierarchyviewer/src/resources/images/icon-pixel-perfect-view-selected.png
new file mode 100644
index 0000000..1e44000
--- /dev/null
+++ b/tools/hierarchyviewer/src/resources/images/icon-pixel-perfect-view-selected.png
Binary files differ
diff --git a/tools/hierarchyviewer/src/resources/images/icon-pixel-perfect-view.png b/tools/hierarchyviewer/src/resources/images/icon-pixel-perfect-view.png
new file mode 100644
index 0000000..ec51cec
--- /dev/null
+++ b/tools/hierarchyviewer/src/resources/images/icon-pixel-perfect-view.png
Binary files differ
diff --git a/tools/idegen/Android.mk b/tools/idegen/Android.mk
new file mode 100644
index 0000000..e76e5b4
--- /dev/null
+++ b/tools/idegen/Android.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_MODULE:= idegen
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/idegen/README b/tools/idegen/README
new file mode 100644
index 0000000..1f773d8
--- /dev/null
+++ b/tools/idegen/README
@@ -0,0 +1,80 @@
+IDEGen automatically generates Android IDE configurations for IntelliJ IDEA
+and Eclipse. Your IDE should be able to compile everything in a reasonable
+amount of time with no errors.
+
+If you're using IntelliJ...
+
+    If this is your first time using IDEGen...
+
+        IDEA needs a lot of memory. Add "-Xms748m -Xmx748m" to your VM options
+        in "IDEA_HOME/bin/idea.vmoptions" on Linux or 
+        "IntelliJ IDEA.app/Contents/Info.plist" on OS X.
+
+        Create a JDK configuration named "1.5 (No Libraries)" by adding a new
+        JDK like you normally would and then removing all of the jar entries
+        under the "Classpath" tab. This will ensure that you only get access to
+        Android's core libraries and not those from your desktop VM.
+
+    From the project's root directory...
+
+        Repeat these steps after each sync...
+        
+        1) make (to produce generated .java source)
+        2) development/tools/idegen/idegen.sh
+        3) Open android.ipr in IntelliJ. If you already have the project open,
+           hit the sync button in IntelliJ, and it will automatically detect the
+           updated configuration.
+        
+        If you get unexpected compilation errors from IntelliJ, try running
+        "Build -> Rebuild Project". Sometimes IntelliJ gets confused after the
+        project changes significantly.
+
+If you're using Eclipse...
+
+    If this is your first time using IDEGen...
+
+        Edit eclipse.ini ("Eclipse.app/Contents/MacOS/eclipse.ini" on OS X) and
+        add "-Xms748m -Xmx748m" to your VM options.
+
+        Configure a JRE named "1.5 (No Libraries)" under "Preferences -> Java ->
+        Installed JREs". Remove all of the jar entries underneath "JRE system
+        libraries". Eclipse will not let you save your configuration unless at
+        least one jar is present, so include a random jar that won't get in the
+        way.
+
+    From the project's root directory...
+
+        Repeat these steps after each sync...
+
+        1) make (to produce generated .java source)
+        2) development/tools/idegen/idegen.sh
+        3) Import the project root directory into your Eclipse workspace. If you
+           already have the project open, simply refresh it (F5).
+
+Excluding source roots and jars
+
+    IDEGen keeps an exclusion list in the "excluded-paths" file. This file 
+    has one regular expression per line that matches paths (relative to the
+    project root) that should be excluded from the IDE configuration. We
+    use Java's regular expression parser (see java.util.regex.Parser).
+
+    You can create your own additional exclusion list by creating an
+    "excluded-paths" file in the project's root directory. For example, you
+    might exclude all apps except the Browser in your IDE configuration with
+    this regular expression: "^packages/apps/(?!Browser)".
+    
+Controlling source root ordering (Eclipse)
+
+    You may want some source roots to come before others in Eclipse. Simply
+    create a file named "path-precedence" in your project's root directory.
+    Each line in the file is a regular expression that matches a source root
+    path (relative to the project's root directory). If a given source root's
+    path matches a regular expression that comes earlier in the file, that
+    source root will come earlier in the generated configuration. If a source
+    root doesn't match any of the expressions in the file, it will come last,
+    so you effectively have an implicit ".*" rule at the end of the file.
+
+    For example, if you want your applications's source root to come first,
+    you might add an expression like "^packages/apps/MyApp/src$" to the top
+    of the "path-precedence" file.  To make source roots under ./out come last,
+    add "^(?!out/)" (which matches all paths that don't start with "out/").
\ No newline at end of file
diff --git a/tools/idegen/excluded-paths b/tools/idegen/excluded-paths
new file mode 100644
index 0000000..35280ad
--- /dev/null
+++ b/tools/idegen/excluded-paths
@@ -0,0 +1,64 @@
+# Default Idegen excluded paths file. Contains regular expressions, one per
+# line, which match paths of directories and .jar files that should be excluded
+# from the IDE configuration.
+#
+# We want to exclude as litte as possible by default, so it's important to
+# document the reason for each exclusion.
+#
+# Developers can also create an 'excluded-paths' file in the project's root
+# directory and add their own excludes to slim down their build.
+#
+# Currently, we lump all the .java files together into one big module, so you
+# can't have two classes with the same name at once. In the future, we'll
+# generate individual modules, each with their own dependencies, much like the
+# build, so we won't have to worry about duplicate names any more than the
+# build does.
+#
+# Note: Google-specific excludes go in vendor/google/excluded-paths.
+
+# Generated API stubs. We only want the originals in our IDE.
+android_stubs
+
+# Extra copies of JUnit.
+^dalvik/dx/src/junit$
+^dalvik/libcore/luni/src/test/java/junit$
+
+# Duplicate R.java files. We'll keep the versions from the "intermediates"
+# directories.
+^out/target/common/R$
+
+# Not actually built. Also disabled in make file.
+^development/samples/MySampleRss$
+^development/apps/OBJViewer$
+^packages/apps/IM/samples/PluginDemo$
+
+# We don't currently support development tool source code. Development tools
+# typically have their own IDE configurations anyway.
+#
+# The main problem is that the development tools are meant to run against a
+# fully featured desktop VM while almost everything in our IDE configuration
+# is meant to run against Android's more limited APIs. Mixing the two
+# environments in one IDE configuration doesn't work well.
+^development/tools$
+^external/jdiff$
+^external/emma$
+^external/clearsilver$
+layoutlib
+^prebuilt/.*\.jar$
+^dalvik/.*\.jar$
+^build/tools/droiddoc$
+
+# Each test has a Main.java in the default package, so they conflict with
+# each other.
+^dalvik/tests$
+
+# We can only support one policy impl at a time.
+^frameworks/policies/base/mid$
+#^frameworks/policies/base/phone$
+
+# We don't want compiled jars.
+^out/.*\.jar$
+
+# This directory contains only an R.java file which is the same as the one in
+# Camera_intermediates.
+^out/target/common/obj/APPS/CameraTests_intermediates$
diff --git a/tools/idegen/idegen.iml b/tools/idegen/idegen.iml
new file mode 100644
index 0000000..04646ae
--- /dev/null
+++ b/tools/idegen/idegen.iml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/classes" />
+    <output-test url="file://$MODULE_DIR$/classes" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
+
diff --git a/tools/idegen/idegen.ipr b/tools/idegen/idegen.ipr
new file mode 100644
index 0000000..00cf4fd
--- /dev/null
+++ b/tools/idegen/idegen.ipr
@@ -0,0 +1,330 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project relativePaths="false" version="4">
+  <component name="AntConfiguration">
+    <defaultAnt bundledAnt="true" />
+  </component>
+  <component name="BuildJarProjectSettings">
+    <option name="BUILD_JARS_ON_MAKE" value="false" />
+  </component>
+  <component name="CodeStyleProjectProfileManger">
+    <option name="PROJECT_PROFILE" />
+    <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
+  </component>
+  <component name="CodeStyleSettingsManager">
+    <option name="PER_PROJECT_SETTINGS">
+      <value>
+        <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
+        <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1000" />
+        <option name="RIGHT_MARGIN" value="80" />
+        <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
+        <option name="PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE" value="true" />
+        <ADDITIONAL_INDENT_OPTIONS fileType="java">
+          <option name="INDENT_SIZE" value="4" />
+          <option name="CONTINUATION_INDENT_SIZE" value="8" />
+          <option name="TAB_SIZE" value="4" />
+          <option name="USE_TAB_CHARACTER" value="false" />
+          <option name="SMART_TABS" value="false" />
+          <option name="LABEL_INDENT_SIZE" value="0" />
+          <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+        </ADDITIONAL_INDENT_OPTIONS>
+        <ADDITIONAL_INDENT_OPTIONS fileType="xml">
+          <option name="INDENT_SIZE" value="4" />
+          <option name="CONTINUATION_INDENT_SIZE" value="8" />
+          <option name="TAB_SIZE" value="4" />
+          <option name="USE_TAB_CHARACTER" value="false" />
+          <option name="SMART_TABS" value="false" />
+          <option name="LABEL_INDENT_SIZE" value="0" />
+          <option name="LABEL_INDENT_ABSOLUTE" value="false" />
+        </ADDITIONAL_INDENT_OPTIONS>
+      </value>
+    </option>
+    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
+  </component>
+  <component name="CompilerConfiguration">
+    <option name="DEFAULT_COMPILER" value="Javac" />
+    <option name="DEPLOY_AFTER_MAKE" value="0" />
+    <resourceExtensions>
+      <entry name=".+\.(properties|xml|html|dtd|tld)" />
+      <entry name=".+\.(gif|png|jpeg|jpg)" />
+    </resourceExtensions>
+    <wildcardResourcePatterns>
+      <entry name="?*.properties" />
+      <entry name="?*.xml" />
+      <entry name="?*.gif" />
+      <entry name="?*.png" />
+      <entry name="?*.jpeg" />
+      <entry name="?*.jpg" />
+      <entry name="?*.html" />
+      <entry name="?*.dtd" />
+      <entry name="?*.tld" />
+    </wildcardResourcePatterns>
+  </component>
+  <component name="DependenciesAnalyzeManager">
+    <option name="myForwardDirection" value="false" />
+  </component>
+  <component name="DependencyValidationManager">
+    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
+  </component>
+  <component name="EclipseCompilerSettings">
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="true" />
+    <option name="DEPRECATION" value="false" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+    <option name="MAXIMUM_HEAP_SIZE" value="128" />
+  </component>
+  <component name="EclipseEmbeddedCompilerSettings">
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="true" />
+    <option name="DEPRECATION" value="false" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+    <option name="MAXIMUM_HEAP_SIZE" value="128" />
+  </component>
+  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
+  <component name="EntryPointsManager">
+    <entry_points />
+  </component>
+  <component name="ExportToHTMLSettings">
+    <option name="PRINT_LINE_NUMBERS" value="false" />
+    <option name="OPEN_IN_BROWSER" value="false" />
+    <option name="OUTPUT_DIRECTORY" />
+  </component>
+  <component name="IdProvider" IDEtalkID="D171F99B9178C1675593DC9A76A5CC7E" />
+  <component name="InspectionProjectProfileManager">
+    <option name="PROJECT_PROFILE" value="Project Default" />
+    <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
+    <scopes />
+    <profiles>
+      <profile version="1.0" is_locked="false">
+        <option name="myName" value="Project Default" />
+        <option name="myLocal" value="false" />
+        <inspection_tool class="JavaDoc" level="WARNING" enabled="false">
+          <option name="TOP_LEVEL_CLASS_OPTIONS">
+            <value>
+              <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+              <option name="REQUIRED_TAGS" value="" />
+            </value>
+          </option>
+          <option name="INNER_CLASS_OPTIONS">
+            <value>
+              <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+              <option name="REQUIRED_TAGS" value="" />
+            </value>
+          </option>
+          <option name="METHOD_OPTIONS">
+            <value>
+              <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+              <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
+            </value>
+          </option>
+          <option name="FIELD_OPTIONS">
+            <value>
+              <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+              <option name="REQUIRED_TAGS" value="" />
+            </value>
+          </option>
+          <option name="IGNORE_DEPRECATED" value="false" />
+          <option name="IGNORE_JAVADOC_PERIOD" value="true" />
+          <option name="myAdditionalJavadocTags" value="" />
+        </inspection_tool>
+      </profile>
+    </profiles>
+    <list size="0" />
+  </component>
+  <component name="JavacSettings">
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="false" />
+    <option name="DEPRECATION" value="true" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+    <option name="MAXIMUM_HEAP_SIZE" value="128" />
+  </component>
+  <component name="JavadocGenerationManager">
+    <option name="OUTPUT_DIRECTORY" />
+    <option name="OPTION_SCOPE" value="protected" />
+    <option name="OPTION_HIERARCHY" value="true" />
+    <option name="OPTION_NAVIGATOR" value="true" />
+    <option name="OPTION_INDEX" value="true" />
+    <option name="OPTION_SEPARATE_INDEX" value="true" />
+    <option name="OPTION_DOCUMENT_TAG_USE" value="false" />
+    <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
+    <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
+    <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
+    <option name="OPTION_DEPRECATED_LIST" value="true" />
+    <option name="OTHER_OPTIONS" value="" />
+    <option name="HEAP_SIZE" />
+    <option name="LOCALE" />
+    <option name="OPEN_IN_BROWSER" value="true" />
+  </component>
+  <component name="JikesSettings">
+    <option name="JIKES_PATH" value="" />
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="DEPRECATION" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="false" />
+    <option name="IS_EMACS_ERRORS_MODE" value="true" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+  </component>
+  <component name="LogConsolePreferences">
+    <option name="FILTER_ERRORS" value="false" />
+    <option name="FILTER_WARNINGS" value="false" />
+    <option name="FILTER_INFO" value="true" />
+    <option name="CUSTOM_FILTER" />
+  </component>
+  <component name="Palette2">
+    <group name="Swing">
+      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
+      </item>
+      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
+        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
+        <initial-values>
+          <property name="text" value="Button" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="RadioButton" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="CheckBox" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="Label" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
+          <preferred-size width="-1" height="20" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
+      </item>
+    </group>
+  </component>
+  <component name="ProjectDetails">
+    <option name="projectName" value="idegen" />
+  </component>
+  <component name="ProjectFileVersion" converted="true" />
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/idegen.iml" filepath="$PROJECT_DIR$/idegen.iml" />
+    </modules>
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_5" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/classes" />
+  </component>
+  <component name="RmicSettings">
+    <option name="IS_EANABLED" value="false" />
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="false" />
+    <option name="GENERATE_IIOP_STUBS" value="false" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+  </component>
+  <component name="SvnBranchConfigurationManager">
+    <option name="myVersion" value="124" />
+  </component>
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="Perforce" />
+  </component>
+  <component name="com.intellij.jsf.UserDefinedFacesConfigs">
+    <option name="USER_DEFINED_CONFIGS">
+      <value>
+        <list size="0" />
+      </value>
+    </option>
+  </component>
+  <component name="uidesigner-configuration">
+    <option name="INSTRUMENT_CLASSES" value="true" />
+    <option name="COPY_FORMS_RUNTIME_TO_OUTPUT" value="true" />
+    <option name="DEFAULT_LAYOUT_MANAGER" value="GridLayoutManager" />
+  </component>
+</project>
+
diff --git a/tools/idegen/idegen.sh b/tools/idegen/idegen.sh
new file mode 100755
index 0000000..d7e6986
--- /dev/null
+++ b/tools/idegen/idegen.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+if [ ! -d development ]; then
+    echo "Error: Run from the root of the tree."
+    exit 1
+fi
+
+idegenjar=`find out -name idegen.jar -follow | grep -v intermediates`
+if [ "" = "$idegenjar" ]; then
+    echo "Couldn't find idegen.jar. Please run make first."
+else 
+    java -cp $idegenjar Main
+fi
diff --git a/tools/idegen/src/Configuration.java b/tools/idegen/src/Configuration.java
new file mode 100644
index 0000000..392cb5d
--- /dev/null
+++ b/tools/idegen/src/Configuration.java
@@ -0,0 +1,263 @@
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.SortedSet;
+import java.util.regex.Pattern;
+
+/**
+ * Immutable representation of an IDE configuration. Assumes that the current
+ * directory is the project's root directory.
+ */
+public class Configuration {
+
+    /** Java source tree roots. */
+    public final SortedSet<File> sourceRoots;
+
+    /** Found .jar files (that weren't excluded). */
+    public final List<File> jarFiles;
+
+    /** Excluded directories which may or may not be under a source root. */
+    public final SortedSet<File> excludedDirs;
+
+    /** The root directory for this tool. */
+    public final File toolDirectory;
+
+    /** File name used for excluded path files. */
+    private static final String EXCLUDED_PATHS = "excluded-paths";
+
+    /**
+     * Constructs a Configuration by traversing the directory tree, looking
+     * for .java and .jar files and identifying source roots.
+     */
+    public Configuration() throws IOException {
+        this.toolDirectory = new File("development/tools/idegen");
+        if (!toolDirectory.isDirectory()) {
+            // The wrapper script should have already verified this.
+            throw new AssertionError("Not in root directory.");
+        }
+
+        Stopwatch stopwatch = new Stopwatch();
+
+        Excludes excludes = readExcludes();
+
+        stopwatch.reset("Read excludes");
+
+        List<File> jarFiles = new ArrayList<File>(500);
+        SortedSet<File> excludedDirs = new TreeSet<File>();
+        SortedSet<File> sourceRoots = new TreeSet<File>();
+
+        traverse(new File("."), sourceRoots, jarFiles, excludedDirs, excludes);
+
+        stopwatch.reset("Traversed tree");
+
+        Log.debug(sourceRoots.size() + " source roots");
+        Log.debug(jarFiles.size() + " jar files");
+        Log.debug(excludedDirs.size() + " excluded dirs");
+
+        this.sourceRoots = Collections.unmodifiableSortedSet(sourceRoots);
+        this.jarFiles = Collections.unmodifiableList(jarFiles);
+        this.excludedDirs = Collections.unmodifiableSortedSet(excludedDirs);
+    }
+
+    /**
+     * Reads excluded path files.
+     */
+    private Excludes readExcludes() throws IOException {
+        List<Pattern> patterns = new ArrayList<Pattern>();
+
+        File globalExcludes = new File(toolDirectory, EXCLUDED_PATHS);
+        parseFile(globalExcludes, patterns);
+
+        // Look for Google-specific excludes.
+        // TODO: Traverse all vendor-specific directories.
+        File googleExcludes = new File("./vendor/google/" + EXCLUDED_PATHS);
+        if (googleExcludes.exists()) {
+            parseFile(googleExcludes, patterns);
+        }
+
+        // Look for user-specific excluded-paths file in current directory.
+        File localExcludes = new File(EXCLUDED_PATHS);
+        if (localExcludes.exists()) {
+            parseFile(localExcludes, patterns);
+        }
+
+        return new Excludes(patterns);
+    }
+
+    /**
+     * Recursively finds .java source roots, .jar files, and excluded
+     * directories.
+     */
+    private static void traverse(File directory, Set<File> sourceRoots,
+            Collection<File> jarFiles, Collection<File> excludedDirs,
+            Excludes excludes) throws IOException {
+        /*
+         * Note it would be faster to stop traversing a source root as soon as
+         * we encounter the first .java file, but it appears we have nested
+         * source roots in our generated source directory (specifically,
+         * R.java files and aidl .java files don't share the same source
+         * root).
+         */
+
+        boolean firstJavaFile = true;
+        for (File file : directory.listFiles()) {
+            // Trim preceding "./" from path.
+            String path = file.getPath().substring(2);
+
+            // Keep track of source roots for .java files.
+            if (path.endsWith(".java")) {
+                if (firstJavaFile) {
+                    // Only parse one .java file per directory.
+                    firstJavaFile = false;
+
+                    File sourceRoot = rootOf(file);
+                    if (sourceRoot != null) {
+                        sourceRoots.add(sourceRoot);
+                    }
+                }
+                                
+                continue;
+            }
+
+            // Keep track of .jar files.
+            if (path.endsWith(".jar")) {
+                if (!excludes.exclude(path)) {
+                    jarFiles.add(file);
+                } else {
+                    Log.debug("Skipped: " + file);
+                }
+
+                continue;
+            }
+
+            // Traverse nested directories.
+            if (file.isDirectory()) {
+                if (excludes.exclude(path)) {
+                    // Don't recurse into excluded dirs.
+                    Log.debug("Excluding: " + path);
+                    excludedDirs.add(file);
+                } else {
+                    traverse(file, sourceRoots, jarFiles, excludedDirs,
+                            excludes);
+                }
+            }
+        }
+    }
+
+    /**
+     * Determines the source root for a given .java file. Returns null
+     * if the file doesn't have a package or if the file isn't in the
+     * correct directory structure.
+     */
+    private static File rootOf(File javaFile) throws IOException {
+        String packageName = parsePackageName(javaFile);
+        if (packageName == null) {
+            // No package.
+            // TODO: Treat this as a source root?
+            return null;
+        }
+
+        String packagePath = packageName.replace('.', File.separatorChar);
+        File parent = javaFile.getParentFile();
+        String parentPath = parent.getPath();
+        if (!parentPath.endsWith(packagePath)) {
+            // Bad dir structure.
+            return null;
+        }
+
+        return new File(parentPath.substring(
+                0, parentPath.length() - packagePath.length()));
+    }
+
+    /**
+     * Reads a Java file and parses out the package name. Returns null if none
+     * found.
+     */
+    private static String parsePackageName(File file) throws IOException {
+        BufferedReader in = new BufferedReader(new FileReader(file));
+        try {
+            String line;
+            while ((line = in.readLine()) != null) {
+                String trimmed = line.trim();
+                if (trimmed.startsWith("package")) {
+                    // TODO: Make this more robust.
+                    // Assumes there's only once space after "package" and the
+                    // line ends in a ";".
+                    return trimmed.substring(8, trimmed.length() - 1);
+                }
+            }
+
+            return null;
+        } finally {
+            in.close();
+        }
+    }
+
+    /**
+     * Picks out excluded directories that are under source roots.
+     */
+    public SortedSet<File> excludesUnderSourceRoots() {
+        // TODO: Refactor this to share the similar logic in
+        // Eclipse.constructExcluding().
+        SortedSet<File> picked = new TreeSet<File>();
+        for (File sourceRoot : sourceRoots) {
+            String sourcePath = sourceRoot.getPath() + "/";
+            SortedSet<File> tailSet = excludedDirs.tailSet(sourceRoot);
+            for (File file : tailSet) {
+                if (file.getPath().startsWith(sourcePath)) {
+                    picked.add(file);
+                } else {
+                    break;
+                }
+            }
+        }
+        return picked;
+    }
+
+    /**
+     * Reads a list of regular expressions from a file, one per line, and adds
+     * the compiled patterns to the given collection. Ignores lines starting
+     * with '#'.
+     *
+     * @param file containing regular expressions, one per line
+     * @param patterns collection to add compiled patterns from file to
+     */
+    public static void parseFile(File file, Collection<Pattern> patterns)
+            throws IOException {
+        BufferedReader in = new BufferedReader(new FileReader(file));
+        try {
+            String line;
+            while ((line = in.readLine()) != null) {
+                String trimmed = line.trim();
+                if (trimmed.length() > 0 && !trimmed.startsWith("#")) {
+                    patterns.add(Pattern.compile(trimmed));
+                }
+            }
+        } finally {
+            in.close();
+        }
+    }
+}
diff --git a/tools/idegen/src/Eclipse.java b/tools/idegen/src/Eclipse.java
new file mode 100644
index 0000000..403c7d8
--- /dev/null
+++ b/tools/idegen/src/Eclipse.java
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.Collection;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * Generates an Eclipse project.
+ */
+public class Eclipse {
+
+    /**
+     * Generates an Eclipse .classpath file from the given configuration.
+     */
+    public static void generateFrom(Configuration c) throws IOException {
+        StringBuilder classpath = new StringBuilder();
+
+        classpath.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+                + "<classpath>\n");
+
+        /*
+         * If the user has a file named "path-precedence" in their project's
+         * root directory, we'll order source roots based on how they match
+         * regular expressions in that file. Source roots that match earlier
+         * patterns will come sooner in configuration file.
+         */
+        List<Pattern> patterns = new ArrayList<Pattern>();
+
+        File precedence = new File("path-precedence");
+        if (precedence.exists()) {
+            Configuration.parseFile(precedence, patterns);
+        } else {
+            // Put ./out at the bottom by default.
+            patterns.add(Pattern.compile("^(?!out/)"));
+        }
+
+        // Everything not matched by the user's precedence spec.
+        patterns.add(Pattern.compile(".*"));
+
+
+        List<Bucket> buckets = new ArrayList<Bucket>(patterns.size());
+        for (Pattern pattern : patterns) {
+            buckets.add(new Bucket(pattern));
+        }
+
+        // Put source roots in respective buckets.
+        OUTER: for (File sourceRoot : c.sourceRoots) {
+            // Trim preceding "./" from path.
+            String path = sourceRoot.getPath().substring(2);
+
+            for (Bucket bucket : buckets) {
+                if (bucket.matches(path)) {
+                    bucket.sourceRoots.add(sourceRoot);
+                    continue OUTER;
+                }
+            }
+        }
+
+        // Output source roots to configuration file.
+        for (Bucket bucket : buckets) {
+            for (File sourceRoot : bucket.sourceRoots) {
+                classpath.append("  <classpathentry kind=\"src\"");
+                CharSequence excluding = constructExcluding(sourceRoot, c);
+                if (excluding.length() > 0) {
+                    classpath.append(" excluding=\"")
+                            .append(excluding).append("\"");
+                }
+                classpath.append(" path=\"")
+                        .append(trimmed(sourceRoot)).append("\"/>\n");
+            }
+
+        }
+
+        // Output .jar entries.
+        for (File jar : c.jarFiles) {
+            classpath.append("  <classpathentry kind=\"lib\" path=\"")
+                    .append(trimmed(jar)).append("\"/>\n");
+        }
+
+        /*
+         * Output directory. Unfortunately, Eclipse forces us to put it
+         * somewhere under the project directory.
+         */
+        classpath.append("  <classpathentry kind=\"output\" path=\""
+                + "out/eclipse\"/>\n");
+
+        classpath.append("</classpath>\n");
+
+        Files.toFile(classpath.toString(), new File(".classpath"));
+    }
+
+
+    /**
+     * Constructs the "excluding" argument for a given source root.
+     */
+    private static CharSequence constructExcluding(File sourceRoot,
+            Configuration c) {
+        StringBuilder classpath = new StringBuilder();
+        String path = sourceRoot.getPath();
+
+        // Exclude nested source roots.
+        SortedSet<File> nextRoots = c.sourceRoots.tailSet(sourceRoot);
+        int count = 0;
+        for (File nextRoot : nextRoots) {
+            // The first root is this root.
+            if (count == 0) {
+                count++;
+                continue;
+            }
+
+            String nextPath = nextRoot.getPath();
+            if (!nextPath.startsWith(path)) {
+                break;
+            }
+
+            if (count > 1) {
+                classpath.append('|');
+            }
+            classpath.append(nextPath.substring(path.length() + 1))
+                    .append('/');
+
+            count++;
+        }
+
+        // Exclude excluded directories under this source root.
+        SortedSet<File> excludedDirs = c.excludedDirs.tailSet(sourceRoot);
+        for (File excludedDir : excludedDirs) {
+            String excludedPath = excludedDir.getPath();
+            if (!excludedPath.startsWith(path)) {
+                break;
+            }
+
+            if (count > 1) {
+                classpath.append('|');
+            }
+            classpath.append(excludedPath.substring(path.length() + 1))
+                    .append('/');
+
+            count++;
+        }
+
+        return classpath;
+    }
+
+    /**
+     * Returns the trimmed path.
+     */
+    private static String trimmed(File file) {
+        return file.getPath().substring(2);
+    }
+
+    /**
+     * A precedence bucket for source roots.
+     */
+    private static class Bucket {
+
+        private final Pattern pattern;
+        private final List<File> sourceRoots = new ArrayList<File>();
+
+        private Bucket(Pattern pattern) {
+            this.pattern = pattern;
+        }
+
+        private boolean matches(String path) {
+            return pattern.matcher(path).find();
+        }
+    }
+}
diff --git a/tools/idegen/src/Excludes.java b/tools/idegen/src/Excludes.java
new file mode 100644
index 0000000..8531d47
--- /dev/null
+++ b/tools/idegen/src/Excludes.java
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+import java.util.regex.Pattern;
+import java.util.List;
+
+/**
+ * Decides whether or not to exclude certain paths.
+ */
+public class Excludes {
+
+    private final List<Pattern> patterns;
+
+    /**
+     * Constructs a set of excludes matching the given patterns.
+     */
+    public Excludes(List<Pattern> patterns) {
+        this.patterns = patterns;
+    }
+
+    /**
+     * Returns true if the given path should be excluded.
+     */
+    public boolean exclude(String path) {
+        for (Pattern pattern : patterns) {
+            if (pattern.matcher(path).find()) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/tools/idegen/src/Files.java b/tools/idegen/src/Files.java
new file mode 100644
index 0000000..81176ee
--- /dev/null
+++ b/tools/idegen/src/Files.java
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+
+import java.io.*;
+
+/**
+ * File utility methods.
+ */
+class Files {
+
+    /**
+     * Reads file into a string using default encoding.
+     */
+    static String toString(File file) throws IOException {
+        char[] buffer = new char[0x1000]; // 4k
+        int read;
+        Reader in = new FileReader(file);
+        StringBuilder builder = new StringBuilder();
+        while ((read = in.read(buffer)) > -1) {
+            builder.append(buffer, 0, read);
+        }
+        in.close();
+        return builder.toString();
+    }
+
+    /**
+     * Writes a string to a file using default encoding.
+     */
+    static void toFile(String contents, File file) throws IOException {
+        FileWriter out = new FileWriter(file);
+        out.write(contents);
+        out.close();
+    }
+}
\ No newline at end of file
diff --git a/tools/idegen/src/IntelliJ.java b/tools/idegen/src/IntelliJ.java
new file mode 100644
index 0000000..00d731d
--- /dev/null
+++ b/tools/idegen/src/IntelliJ.java
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.SortedSet;
+
+/**
+ * Generates an IntelliJ project.
+ */
+public class IntelliJ {
+
+    private static final String IDEA_IML = "android.iml";
+    private static final String IDEA_IPR = "android.ipr";
+
+    /**
+     * Generates IntelliJ configuration files from the given configuration.
+     */
+    public static void generateFrom(Configuration c) throws IOException {
+        File templatesDirectory = new File(c.toolDirectory, "templates");
+        String ipr = Files.toString(new File(templatesDirectory, IDEA_IPR));
+        Files.toFile(ipr, new File(IDEA_IPR));
+
+        String iml = Files.toString(new File(templatesDirectory, IDEA_IML));
+
+        StringBuilder sourceRootsXml = new StringBuilder();
+        for (File sourceRoot : c.sourceRoots) {
+            sourceRootsXml.append("<sourceFolder url=\"file://$MODULE_DIR$/")
+                .append(sourceRoot.getPath())
+                .append("\" isTestSource=\"").append(isTests(sourceRoot))
+                .append("\"/>\n");
+        }
+
+        /*
+         * IntelliJ excludes are module-wide. We explicitly exclude directories
+         * under source roots but leave the rest in so you can still pull
+         * up random non-Java files.
+         */
+        StringBuilder excludeXml = new StringBuilder();
+        for (File excludedDir : c.excludesUnderSourceRoots()) {
+            sourceRootsXml.append("<excludeFolder url=\"file://$MODULE_DIR$/")
+                .append(excludedDir.getPath())
+                .append("\"/>\n");
+        }
+
+        // Exclude Eclipse's output directory.
+        sourceRootsXml.append("<excludeFolder "
+                + "url=\"file://$MODULE_DIR$/out/eclipse\"/>\n");
+
+        StringBuilder jarsXml = new StringBuilder();
+        for (File jar : c.jarFiles) {
+            jarsXml.append("<orderEntry type=\"module-library\">"
+                    + "<library><CLASSES><root url=\"jar://$MODULE_DIR$/")
+                .append(jar.getPath())
+            .append("!/\"/></CLASSES><JAVADOC/><SOURCES/></library>"
+                    + "</orderEntry>\n");
+        }
+
+        iml = iml.replace("SOURCE_FOLDERS",
+                sourceRootsXml.toString() + excludeXml.toString());
+        iml = iml.replace("JAR_ENTRIES", jarsXml.toString());
+
+        Files.toFile(iml, new File(IDEA_IML));
+    }
+
+    private static boolean isTests(File file) {
+        String path = file.getPath();
+
+        // test-runner is testing infrastructure, not test code.
+        if (path.contains("test-runner")) {
+            return false;
+        }
+
+        return path.toUpperCase().contains("TEST");
+    }
+}
\ No newline at end of file
diff --git a/tools/idegen/src/Log.java b/tools/idegen/src/Log.java
new file mode 100644
index 0000000..e35d060
--- /dev/null
+++ b/tools/idegen/src/Log.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Logs messages.
+ */
+class Log {
+
+    static final boolean DEBUG = false;
+
+    static void debug(String message) {
+        if (DEBUG) {
+            info(message);
+        }
+    }
+
+    static void info(String message) {
+        System.out.println(message);
+    }
+}
diff --git a/tools/idegen/src/Main.java b/tools/idegen/src/Main.java
new file mode 100644
index 0000000..294dbee
--- /dev/null
+++ b/tools/idegen/src/Main.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.
+ */
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * Generates IntelliJ and Eclipse project configurations.
+ */
+public class Main {
+
+    public static void main(String[] args) throws Exception {
+        Configuration configuration = new Configuration();
+        IntelliJ.generateFrom(configuration);
+        Eclipse.generateFrom(configuration);
+    }
+}
diff --git a/tools/idegen/src/Stopwatch.java b/tools/idegen/src/Stopwatch.java
new file mode 100644
index 0000000..4bd2ae8
--- /dev/null
+++ b/tools/idegen/src/Stopwatch.java
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+/**
+ * Measures passed time.
+ */
+class Stopwatch {
+
+    long last = System.currentTimeMillis();
+
+    void reset(String label) {
+        long now = System.currentTimeMillis();
+        Log.info(label + ": " + (now - last) + "ms");
+        last = now;
+    }
+}
\ No newline at end of file
diff --git a/tools/idegen/templates/android.iml b/tools/idegen/templates/android.iml
new file mode 100644
index 0000000..12e934c
--- /dev/null
+++ b/tools/idegen/templates/android.iml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module version="4" relativePaths="true" type="JAVA_MODULE">
+  <component name="ModuleRootManager" />
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      SOURCE_FOLDERS
+    </content>
+    JAR_ENTRIES
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntryProperties />
+  </component>
+</module>
+
diff --git a/tools/idegen/templates/android.ipr b/tools/idegen/templates/android.ipr
new file mode 100644
index 0000000..d6aba4b
--- /dev/null
+++ b/tools/idegen/templates/android.ipr
@@ -0,0 +1,311 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project relativePaths="true" version="4">
+  <component name="AntConfiguration">
+    <defaultAnt bundledAnt="true" />
+    <buildFile url="file://$PROJECT_DIR$/ide/intellij/build.xml">
+      <additionalClassPath />
+      <antReference projectDefault="true" />
+      <customJdkName value="" />
+      <maximumHeapSize value="128" />
+      <properties />
+    </buildFile>
+  </component>
+  <component name="BuildJarProjectSettings">
+    <option name="BUILD_JARS_ON_MAKE" value="false" />
+  </component>
+  <component name="CodeStyleProjectProfileManger">
+    <option name="PROJECT_PROFILE" />
+    <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
+  </component>
+  <component name="CodeStyleSettingsManager">
+    <option name="PER_PROJECT_SETTINGS">
+      <value>
+        <option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
+        <option name="RIGHT_MARGIN" value="80" />
+        <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" />
+        <option name="PLACE_ASSIGNMENT_SIGN_ON_NEXT_LINE" value="true" />
+      </value>
+    </option>
+    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
+  </component>
+  <component name="CompilerConfiguration">
+    <option name="DEFAULT_COMPILER" value="Javac" />
+    <option name="DEPLOY_AFTER_MAKE" value="0" />
+    <resourceExtensions>
+      <entry name=".+\.(properties|xml|html|dtd|tld)" />
+      <entry name=".+\.(gif|png|jpeg|jpg)" />
+    </resourceExtensions>
+    <wildcardResourcePatterns>
+      <entry name="?*.properties" />
+      <entry name="?*.xml" />
+      <entry name="?*.gif" />
+      <entry name="?*.png" />
+      <entry name="?*.jpeg" />
+      <entry name="?*.jpg" />
+      <entry name="?*.html" />
+      <entry name="?*.dtd" />
+      <entry name="?*.tld" />
+    </wildcardResourcePatterns>
+  </component>
+  <component name="DependenciesAnalyzeManager">
+    <option name="myForwardDirection" value="false" />
+  </component>
+  <component name="DependencyValidationManager">
+    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
+  </component>
+  <component name="EclipseCompilerSettings">
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="true" />
+    <option name="DEPRECATION" value="false" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+    <option name="MAXIMUM_HEAP_SIZE" value="128" />
+  </component>
+  <component name="EclipseEmbeddedCompilerSettings">
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="true" />
+    <option name="DEPRECATION" value="false" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+    <option name="MAXIMUM_HEAP_SIZE" value="128" />
+  </component>
+  <component name="EntryPointsManager">
+    <entry_points version="2.0" />
+  </component>
+  <component name="ExportToHTMLSettings">
+    <option name="PRINT_LINE_NUMBERS" value="false" />
+    <option name="OPEN_IN_BROWSER" value="false" />
+    <option name="OUTPUT_DIRECTORY" />
+  </component>
+  <component name="IdProvider" IDEtalkID="C8FEF8FDDA8778BFC0BDE2CF5A21CB2C" />
+  <component name="InspectionProjectProfileManager">
+    <option name="PROJECT_PROFILE" value="Project Default" />
+    <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
+    <scopes />
+    <profiles>
+      <profile version="1.0" is_locked="false">
+        <option name="myName" value="Project Default" />
+        <option name="myLocal" value="false" />
+        <inspection_tool class="JavaDoc" level="WARNING" enabled="false">
+          <option name="TOP_LEVEL_CLASS_OPTIONS">
+            <value>
+              <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+              <option name="REQUIRED_TAGS" value="" />
+            </value>
+          </option>
+          <option name="INNER_CLASS_OPTIONS">
+            <value>
+              <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+              <option name="REQUIRED_TAGS" value="" />
+            </value>
+          </option>
+          <option name="METHOD_OPTIONS">
+            <value>
+              <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+              <option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
+            </value>
+          </option>
+          <option name="FIELD_OPTIONS">
+            <value>
+              <option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
+              <option name="REQUIRED_TAGS" value="" />
+            </value>
+          </option>
+          <option name="IGNORE_DEPRECATED" value="false" />
+          <option name="IGNORE_JAVADOC_PERIOD" value="true" />
+          <option name="myAdditionalJavadocTags" value="" />
+        </inspection_tool>
+      </profile>
+    </profiles>
+    <list size="0" />
+  </component>
+  <component name="JavacSettings">
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="false" />
+    <option name="DEPRECATION" value="false" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="-Xlint:all,-deprecation,-serial" />
+    <option name="MAXIMUM_HEAP_SIZE" value="512" />
+  </component>
+  <component name="JavadocGenerationManager">
+    <option name="OUTPUT_DIRECTORY" />
+    <option name="OPTION_SCOPE" value="protected" />
+    <option name="OPTION_HIERARCHY" value="true" />
+    <option name="OPTION_NAVIGATOR" value="true" />
+    <option name="OPTION_INDEX" value="true" />
+    <option name="OPTION_SEPARATE_INDEX" value="true" />
+    <option name="OPTION_DOCUMENT_TAG_USE" value="false" />
+    <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
+    <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
+    <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
+    <option name="OPTION_DEPRECATED_LIST" value="true" />
+    <option name="OTHER_OPTIONS" value="" />
+    <option name="HEAP_SIZE" />
+    <option name="LOCALE" />
+    <option name="OPEN_IN_BROWSER" value="true" />
+  </component>
+  <component name="JikesSettings">
+    <option name="JIKES_PATH" value="" />
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="DEPRECATION" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="false" />
+    <option name="IS_EMACS_ERRORS_MODE" value="true" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+  </component>
+  <component name="LogConsolePreferences">
+    <option name="FILTER_ERRORS" value="false" />
+    <option name="FILTER_WARNINGS" value="false" />
+    <option name="FILTER_INFO" value="true" />
+    <option name="CUSTOM_FILTER" />
+  </component>
+  <component name="Palette2">
+    <group name="Swing">
+      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
+      </item>
+      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
+        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
+        <initial-values>
+          <property name="text" value="Button" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="RadioButton" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="CheckBox" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="Label" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
+          <preferred-size width="-1" height="20" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
+      </item>
+    </group>
+  </component>
+  <component name="ProjectFileVersion" converted="true" />
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/android.iml" filepath="$PROJECT_DIR$/android.iml" />
+    </modules>
+  </component>
+  <component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="1.5 (No Libraries)" project-jdk-type="JavaSDK">
+    <output url="file:///tmp/intellij$PROJECT_DIR$/classes" />
+  </component>
+  <component name="RmicSettings">
+    <option name="IS_EANABLED" value="false" />
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="false" />
+    <option name="GENERATE_IIOP_STUBS" value="false" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+  </component>
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="Perforce" />
+  </component>
+  <component name="com.intellij.jsf.UserDefinedFacesConfigs">
+    <option name="USER_DEFINED_CONFIGS">
+      <value>
+        <list size="0" />
+      </value>
+    </option>
+  </component>
+  <component name="uidesigner-configuration">
+    <option name="INSTRUMENT_CLASSES" value="true" />
+    <option name="COPY_FORMS_RUNTIME_TO_OUTPUT" value="true" />
+    <option name="DEFAULT_LAYOUT_MANAGER" value="GridLayoutManager" />
+  </component>
+</project>
+
diff --git a/tools/jarutils/.classpath b/tools/jarutils/.classpath
new file mode 100644
index 0000000..fc17a43
--- /dev/null
+++ b/tools/jarutils/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/jarutils/.project b/tools/jarutils/.project
new file mode 100644
index 0000000..3649e40
--- /dev/null
+++ b/tools/jarutils/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>JarUtils</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/jarutils/Android.mk b/tools/jarutils/Android.mk
new file mode 100644
index 0000000..707614a
--- /dev/null
+++ b/tools/jarutils/Android.mk
@@ -0,0 +1,4 @@
+# Copyright 2008 The Android Open Source Project
+#
+JARUTILS_LOCAL_DIR := $(call my-dir)
+include $(JARUTILS_LOCAL_DIR)/src/Android.mk
diff --git a/tools/jarutils/src/Android.mk b/tools/jarutils/src/Android.mk
new file mode 100644
index 0000000..2248b7f
--- /dev/null
+++ b/tools/jarutils/src/Android.mk
@@ -0,0 +1,14 @@
+# Copyright 2008 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES := \
+	androidprefs
+
+LOCAL_MODULE := jarutils
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/jarutils/src/com/android/jarutils/DebugKeyProvider.java b/tools/jarutils/src/com/android/jarutils/DebugKeyProvider.java
new file mode 100644
index 0000000..6dc32ba
--- /dev/null
+++ b/tools/jarutils/src/com/android/jarutils/DebugKeyProvider.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jarutils;
+
+import com.android.prefs.AndroidLocation;
+import com.android.prefs.AndroidLocation.AndroidLocationException;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.UnrecoverableEntryException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+
+/**
+ * A provider of a dummy key to sign Android application for debugging purpose.
+ * <p/>This provider uses a custom keystore to create and store a key with a known password.
+ */
+public class DebugKeyProvider {
+    
+    public interface IKeyGenOutput {
+        public void out(String message);
+        public void err(String message);
+    }
+    
+    private static final String PASSWORD_STRING = "android";
+    private static final char[] PASSWORD_CHAR = PASSWORD_STRING.toCharArray();
+    private static final String DEBUG_ALIAS = "AndroidDebugKey";
+    
+    // Certificate CN value. This is a hard-coded value for the debug key.
+    // Android Market checks against this value in order to refuse applications signed with
+    // debug keys.
+    private static final String CERTIFICATE_DESC = "CN=Android Debug,O=Android,C=US";
+    
+    private KeyStore.PrivateKeyEntry mEntry;
+    
+    public static class KeytoolException extends Exception {
+        /** default serial uid */
+        private static final long serialVersionUID = 1L;
+        private String mJavaHome = null;
+        private String mCommandLine = null;
+        
+        KeytoolException(String message) {
+            super(message);
+        }
+
+        KeytoolException(String message, String javaHome, String commandLine) {
+            super(message);
+            
+            mJavaHome = javaHome;
+            mCommandLine = commandLine;
+        }
+        
+        public String getJavaHome() {
+            return mJavaHome;
+        }
+        
+        public String getCommandLine() {
+            return mCommandLine;
+        }
+    }
+    
+    /**
+     * Creates a provider using a keystore at the given location.
+     * <p/>The keystore, and a new random android debug key are created if they do not yet exist.
+     * <p/>Password for the store/key is <code>android</code>, and the key alias is
+     * <code>AndroidDebugKey</code>.
+     * @param osKeyStorePath the OS path to the keystore, or <code>null</code> if the default one
+     * is to be used.
+     * @param storeType an optional keystore type, or <code>null</code> if the default is to
+     * be used.
+     * @param output an optional {@link IKeyGenOutput} object to get the stdout and stderr
+     * of the keytool process call.
+     * @throws KeytoolException If the creation of the debug key failed.
+     * @throws AndroidLocationException 
+     */
+    public DebugKeyProvider(String osKeyStorePath, String storeType, IKeyGenOutput output)
+            throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
+            UnrecoverableEntryException, IOException, KeytoolException, AndroidLocationException {
+        
+        if (osKeyStorePath == null) {
+            osKeyStorePath = getDefaultKeyStoreOsPath();
+        }
+        
+        if (loadKeyEntry(osKeyStorePath, storeType) == false) {
+            // create the store with the key
+            createNewStore(osKeyStorePath, storeType, output);
+        }
+    }
+
+    /**
+     * Returns the OS path to the default debug keystore.
+     * 
+     * @return The OS path to the default debug keystore.
+     * @throws KeytoolException
+     * @throws AndroidLocationException
+     */
+    public static String getDefaultKeyStoreOsPath()
+            throws KeytoolException, AndroidLocationException {
+        String folder = AndroidLocation.getFolder();
+        if (folder == null) {
+            throw new KeytoolException("Failed to get HOME directory!\n");
+        }
+        String osKeyStorePath = folder + "debug.keystore";
+
+        return osKeyStorePath;
+    }
+
+    /**
+     * Returns the debug {@link PrivateKey} to use to sign applications for debug purpose.
+     * @return the private key or <code>null</code> if its creation failed.
+     */
+    public PrivateKey getDebugKey() throws KeyStoreException, NoSuchAlgorithmException,
+            UnrecoverableKeyException, UnrecoverableEntryException {
+        if (mEntry != null) {
+            return mEntry.getPrivateKey();
+        }
+        
+        return null;
+    }
+
+    /**
+     * Returns the debug {@link Certificate} to use to sign applications for debug purpose.
+     * @return the certificate or <code>null</code> if its creation failed.
+     */
+    public Certificate getCertificate() throws KeyStoreException, NoSuchAlgorithmException,
+            UnrecoverableKeyException, UnrecoverableEntryException {
+        if (mEntry != null) {
+            return mEntry.getCertificate();
+        }
+
+        return null;
+    }
+    
+    /**
+     * Loads the debug key from the keystore.
+     * @param osKeyStorePath the OS path to the keystore.
+     * @param storeType an optional keystore type, or <code>null</code> if the default is to
+     * be used.
+     * @return <code>true</code> if success, <code>false</code> if the keystore does not exist.
+     */
+    private boolean loadKeyEntry(String osKeyStorePath, String storeType) throws KeyStoreException,
+            NoSuchAlgorithmException, CertificateException, IOException,
+            UnrecoverableEntryException {
+        try {
+            KeyStore keyStore = KeyStore.getInstance(
+                    storeType != null ? storeType : KeyStore.getDefaultType());
+            FileInputStream fis = new FileInputStream(osKeyStorePath);
+            keyStore.load(fis, PASSWORD_CHAR);
+            fis.close();
+            mEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(
+                    DEBUG_ALIAS, new KeyStore.PasswordProtection(PASSWORD_CHAR));
+        } catch (FileNotFoundException e) {
+            return false;
+        }
+        
+        return true;
+    }
+
+    /**
+     * Creates a new store
+     * @param osKeyStorePath the location of the store
+     * @param storeType an optional keystore type, or <code>null</code> if the default is to
+     * be used.
+     * @param output an optional {@link IKeyGenOutput} object to get the stdout and stderr
+     * of the keytool process call.
+     * @throws KeyStoreException
+     * @throws NoSuchAlgorithmException
+     * @throws CertificateException
+     * @throws UnrecoverableEntryException
+     * @throws IOException
+     * @throws KeytoolException
+     */
+    private void createNewStore(String osKeyStorePath, String storeType, IKeyGenOutput output)
+            throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
+            UnrecoverableEntryException, IOException, KeytoolException {
+        
+        if (KeystoreHelper.createNewStore(osKeyStorePath, storeType, PASSWORD_STRING, DEBUG_ALIAS,
+                PASSWORD_STRING, CERTIFICATE_DESC, 1 /* validity*/, output)) {
+            loadKeyEntry(osKeyStorePath, storeType);
+        }
+    }
+}
diff --git a/tools/jarutils/src/com/android/jarutils/JavaResourceFilter.java b/tools/jarutils/src/com/android/jarutils/JavaResourceFilter.java
new file mode 100644
index 0000000..d9f8da6
--- /dev/null
+++ b/tools/jarutils/src/com/android/jarutils/JavaResourceFilter.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jarutils;
+
+import com.android.jarutils.SignedJarBuilder.IZipEntryFilter;
+
+/**
+ * A basic implementation of {@link IZipEntryFilter} to filter out anything that is not a
+ * java resource.
+ */
+public class JavaResourceFilter implements IZipEntryFilter {
+
+    public boolean checkEntry(String name) {
+        // split the path into segments.
+        String[] segments = name.split("/");
+
+        // empty path? skip to next entry.
+        if (segments.length == 0) {
+            return false;
+        }
+
+        // Check each folders to make sure they should be included.
+        // Folders like CVS, .svn, etc.. should already have been excluded from the
+        // jar file, but we need to exclude some other folder (like /META-INF) so
+        // we check anyway.
+        for (int i = 0 ; i < segments.length - 1; i++) {
+            if (checkFolderForPackaging(segments[i]) == false) {
+                return false;
+            }
+        }
+
+        // get the file name from the path
+        String fileName = segments[segments.length-1];
+        
+        return checkFileForPackaging(fileName);
+    }
+    
+    /**
+     * Checks whether a folder and its content is valid for packaging into the .apk as
+     * standard Java resource.
+     * @param folderName the name of the folder.
+     */
+    public static boolean checkFolderForPackaging(String folderName) {
+        return folderName.equals("CVS") == false &&
+            folderName.equals(".svn") == false &&
+            folderName.equals("SCCS") == false &&
+            folderName.equals("META-INF") == false &&
+            folderName.startsWith("_") == false;
+    }
+
+    /**
+     * Checks a file to make sure it should be packaged as standard resources.
+     * @param fileName the name of the file (including extension)
+     * @return true if the file should be packaged as standard java resources.
+     */
+    public static boolean checkFileForPackaging(String fileName) {
+        String[] fileSegments = fileName.split("\\.");
+        String fileExt = "";
+        if (fileSegments.length > 1) {
+            fileExt = fileSegments[fileSegments.length-1];
+        }
+
+        return checkFileForPackaging(fileName, fileExt);
+    }
+
+    /**
+     * Checks a file to make sure it should be packaged as standard resources.
+     * @param fileName the name of the file (including extension)
+     * @param extension the extension of the file (excluding '.')
+     * @return true if the file should be packaged as standard java resources.
+     */
+    public static boolean checkFileForPackaging(String fileName, String extension) {
+        return "aidl".equalsIgnoreCase(extension) == false &&
+            "java".equalsIgnoreCase(extension) == false &&
+            "class".equalsIgnoreCase(extension) == false &&
+            "package.html".equalsIgnoreCase(fileName) == false &&
+            "overview.html".equalsIgnoreCase(fileName) == false &&
+            ".cvsignore".equalsIgnoreCase(fileName) == false &&
+            ".DS_Store".equals(fileName) == false && 
+            fileName.charAt(fileName.length()-1) != '~';
+    }
+}
diff --git a/tools/jarutils/src/com/android/jarutils/KeystoreHelper.java b/tools/jarutils/src/com/android/jarutils/KeystoreHelper.java
new file mode 100644
index 0000000..c694684
--- /dev/null
+++ b/tools/jarutils/src/com/android/jarutils/KeystoreHelper.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jarutils;
+
+import com.android.jarutils.DebugKeyProvider.IKeyGenOutput;
+import com.android.jarutils.DebugKeyProvider.KeytoolException;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableEntryException;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+
+/**
+ * A Helper to create new keystore/key.
+ */
+public final class KeystoreHelper {
+
+    /**
+     * Creates a new store
+     * @param osKeyStorePath the location of the store
+     * @param storeType an optional keystore type, or <code>null</code> if the default is to
+     * be used.
+     * @param output an optional {@link IKeyGenOutput} object to get the stdout and stderr
+     * of the keytool process call.
+     * @throws KeyStoreException
+     * @throws NoSuchAlgorithmException
+     * @throws CertificateException
+     * @throws UnrecoverableEntryException
+     * @throws IOException
+     * @throws KeytoolException
+     */
+    public static boolean createNewStore(
+            String osKeyStorePath,
+            String storeType,
+            String storePassword,
+            String alias,
+            String keyPassword,
+            String description,
+            int validityYears,
+            IKeyGenOutput output)
+            throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
+            UnrecoverableEntryException, IOException, KeytoolException {
+        
+        // get the executable name of keytool depending on the platform.
+        String os = System.getProperty("os.name");
+
+        String keytoolCommand;
+        if (os.startsWith("Windows")) {
+            keytoolCommand = "keytool.exe";
+        } else {
+            keytoolCommand = "keytool";
+        }
+
+        String javaHome = System.getProperty("java.home");
+
+        if (javaHome != null && javaHome.length() > 0) {
+            keytoolCommand = javaHome + File.separator + "bin" + File.separator + keytoolCommand; 
+        }
+        
+        // create the command line to call key tool to build the key with no user input.
+        ArrayList<String> commandList = new ArrayList<String>();
+        commandList.add(keytoolCommand);
+        commandList.add("-genkey");
+        commandList.add("-alias");
+        commandList.add(alias);
+        commandList.add("-keyalg");
+        commandList.add("RSA");
+        commandList.add("-dname");
+        commandList.add(description);
+        commandList.add("-validity");
+        commandList.add(Integer.toString(validityYears * 365));
+        commandList.add("-keypass");
+        commandList.add(keyPassword);
+        commandList.add("-keystore");
+        commandList.add(osKeyStorePath);
+        commandList.add("-storepass");
+        commandList.add(storePassword);
+        if (storeType != null) {
+            commandList.add("-storetype");
+            commandList.add(storeType);
+        }
+
+        String[] commandArray = commandList.toArray(new String[commandList.size()]);
+
+        // launch the command line process
+        int result = 0;
+        try {
+            result = grabProcessOutput(Runtime.getRuntime().exec(commandArray), output);
+        } catch (Exception e) {
+            // create the command line as one string
+            StringBuilder builder = new StringBuilder();
+            boolean firstArg = true;
+            for (String arg : commandArray) {
+                boolean hasSpace = arg.indexOf(' ') != -1;
+                
+                if (firstArg == true) {
+                    firstArg = false;
+                } else {
+                    builder.append(' ');
+                }
+                
+                if (hasSpace) {
+                    builder.append('"');
+                }
+                
+                builder.append(arg);
+
+                if (hasSpace) {
+                    builder.append('"');
+                }
+            }
+            
+            throw new KeytoolException("Failed to create key: " + e.getMessage(),
+                    javaHome, builder.toString());
+        }
+        
+        if (result != 0) {
+            return false;
+        }
+        
+        return true;
+    }
+    
+    /**
+     * Get the stderr/stdout outputs of a process and return when the process is done.
+     * Both <b>must</b> be read or the process will block on windows.
+     * @param process The process to get the ouput from
+     * @return the process return code.
+     * @throws InterruptedException
+     */
+    private static int grabProcessOutput(final Process process, final IKeyGenOutput output) {
+        // read the lines as they come. if null is returned, it's
+        // because the process finished
+        Thread t1 = new Thread("") {
+            @Override
+            public void run() {
+                // create a buffer to read the stderr output
+                InputStreamReader is = new InputStreamReader(process.getErrorStream());
+                BufferedReader errReader = new BufferedReader(is);
+
+                try {
+                    while (true) {
+                        String line = errReader.readLine();
+                        if (line != null) {
+                            if (output != null) {
+                                output.err(line);
+                            } else {
+                                System.err.println(line);
+                            }
+                        } else {
+                            break;
+                        }
+                    }
+                } catch (IOException e) {
+                    // do nothing.
+                }
+            }
+        };
+
+        Thread t2 = new Thread("") {
+            @Override
+            public void run() {
+                InputStreamReader is = new InputStreamReader(process.getInputStream());
+                BufferedReader outReader = new BufferedReader(is);
+
+                try {
+                    while (true) {
+                        String line = outReader.readLine();
+                        if (line != null) {
+                            if (output != null) {
+                                output.out(line);
+                            } else {
+                                System.out.println(line);
+                            }
+                        } else {
+                            break;
+                        }
+                    }
+                } catch (IOException e) {
+                    // do nothing.
+                }
+            }
+        };
+
+        t1.start();
+        t2.start();
+
+        // it looks like on windows process#waitFor() can return
+        // before the thread have filled the arrays, so we wait for both threads and the
+        // process itself.
+        try {
+            t1.join();
+        } catch (InterruptedException e) {
+        }
+        try {
+            t2.join();
+        } catch (InterruptedException e) {
+        }
+
+        // get the return code from the process
+        try {
+            return process.waitFor();
+        } catch (InterruptedException e) {
+            // since we're waiting for the output thread above, we should never actually wait
+            // on the process to end, since it'll be done by the time we call waitFor()
+            return 0;
+        }
+    }
+}
diff --git a/tools/jarutils/src/com/android/jarutils/SignedJarBuilder.java b/tools/jarutils/src/com/android/jarutils/SignedJarBuilder.java
new file mode 100644
index 0000000..335ab7d
--- /dev/null
+++ b/tools/jarutils/src/com/android/jarutils/SignedJarBuilder.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jarutils;
+
+import sun.misc.BASE64Encoder;
+import sun.security.pkcs.ContentInfo;
+import sun.security.pkcs.PKCS7;
+import sun.security.pkcs.SignerInfo;
+import sun.security.x509.AlgorithmId;
+import sun.security.x509.X500Name;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.security.DigestOutputStream;
+import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.X509Certificate;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+/**
+ * A Jar file builder with signature support.
+ */
+public class SignedJarBuilder {
+    private static final String DIGEST_ALGORITHM = "SHA1";
+    private static final String DIGEST_ATTR = "SHA1-Digest";
+    private static final String DIGEST_MANIFEST_ATTR = "SHA1-Digest-Manifest";
+
+    /** Write to another stream and also feed it to the Signature object. */
+    private static class SignatureOutputStream extends FilterOutputStream {
+        private Signature mSignature;
+
+        public SignatureOutputStream(OutputStream out, Signature sig) {
+            super(out);
+            mSignature = sig;
+        }
+
+        @Override
+        public void write(int b) throws IOException {
+            try {
+                mSignature.update((byte) b);
+            } catch (SignatureException e) {
+                throw new IOException("SignatureException: " + e);
+            }
+            super.write(b);
+        }
+
+        @Override
+        public void write(byte[] b, int off, int len) throws IOException {
+            try {
+                mSignature.update(b, off, len);
+            } catch (SignatureException e) {
+                throw new IOException("SignatureException: " + e);
+            }
+            super.write(b, off, len);
+        }
+    }
+
+    private JarOutputStream mOutputJar;
+    private PrivateKey mKey;
+    private X509Certificate mCertificate;
+    private Manifest mManifest;
+    private BASE64Encoder mBase64Encoder;
+    private MessageDigest mMessageDigest;
+
+    private byte[] mBuffer = new byte[4096];
+
+    /**
+     * Classes which implement this interface provides a method to check whether a file should
+     * be added to a Jar file.
+     */
+    public interface IZipEntryFilter {
+        /**
+         * Checks a file for inclusion in a Jar archive.
+         * @param name the archive file path of the entry
+         * @return <code>true</code> if the file should be included.
+         */
+        public boolean checkEntry(String name);
+    }
+    
+    /**
+     * Creates a {@link SignedJarBuilder} with a given output stream, and signing information.
+     * <p/>If either <code>key</code> or <code>certificate</code> is <code>null</code> then
+     * the archive will not be signed.
+     * @param out the {@link OutputStream} where to write the Jar archive.
+     * @param key the {@link PrivateKey} used to sign the archive, or <code>null</code>.
+     * @param certificate the {@link X509Certificate} used to sign the archive, or
+     * <code>null</code>.
+     * @throws IOException
+     * @throws NoSuchAlgorithmException
+     */
+    public SignedJarBuilder(OutputStream out, PrivateKey key, X509Certificate certificate)
+            throws IOException, NoSuchAlgorithmException {
+        mOutputJar = new JarOutputStream(out);
+        mOutputJar.setLevel(9);
+        mKey = key;
+        mCertificate = certificate;
+        
+        if (mKey != null && mCertificate != null) {
+            mManifest = new Manifest();
+            Attributes main = mManifest.getMainAttributes();
+            main.putValue("Manifest-Version", "1.0");
+            main.putValue("Created-By", "1.0 (Android)");
+    
+            mBase64Encoder = new BASE64Encoder();
+            mMessageDigest = MessageDigest.getInstance(DIGEST_ALGORITHM);
+        }
+    }
+    
+    /**
+     * Writes a new {@link File} into the archive.
+     * @param inputFile the {@link File} to write.
+     * @param jarPath the filepath inside the archive.
+     * @throws IOException
+     */
+    public void writeFile(File inputFile, String jarPath) throws IOException {
+        // Get an input stream on the file.
+        FileInputStream fis = new FileInputStream(inputFile);
+        try {
+            
+            // create the zip entry
+            JarEntry entry = new JarEntry(jarPath);
+            entry.setTime(inputFile.lastModified());
+
+            writeEntry(fis, entry);
+        } finally {
+            // close the file stream used to read the file
+            fis.close();
+        }
+    }
+
+    /**
+     * Copies the content of a Jar/Zip archive into the receiver archive.
+     * <p/>An optional {@link IZipEntryFilter} allows to selectively choose which files
+     * to copy over.
+     * @param input the {@link InputStream} for the Jar/Zip to copy.
+     * @param filter the filter or <code>null</code>
+     * @throws IOException
+     */
+    public void writeZip(InputStream input, IZipEntryFilter filter) throws IOException {
+        ZipInputStream zis = new ZipInputStream(input);
+
+        try {
+            // loop on the entries of the intermediary package and put them in the final package.
+            ZipEntry entry;
+            while ((entry = zis.getNextEntry()) != null) {
+                String name = entry.getName();
+                
+                // do not take directories or anything inside a potential META-INF folder.
+                if (entry.isDirectory() || name.startsWith("META-INF/")) {
+                    continue;
+                }
+    
+                // if we have a filter, we check the entry against it
+                if (filter != null && filter.checkEntry(name) == false) {
+                    continue;
+                }
+    
+                JarEntry newEntry;
+    
+                // Preserve the STORED method of the input entry.
+                if (entry.getMethod() == JarEntry.STORED) {
+                    newEntry = new JarEntry(entry);
+                } else {
+                    // Create a new entry so that the compressed len is recomputed.
+                    newEntry = new JarEntry(name);
+                }
+                
+                writeEntry(zis, newEntry);
+    
+                zis.closeEntry();
+            }
+        } finally {
+            zis.close();
+        }
+    }
+
+    /**
+     * Closes the Jar archive by creating the manifest, and signing the archive. 
+     * @throws IOException
+     * @throws GeneralSecurityException
+     */
+    public void close() throws IOException, GeneralSecurityException {
+        if (mManifest != null) {
+            // write the manifest to the jar file
+            mOutputJar.putNextEntry(new JarEntry(JarFile.MANIFEST_NAME));
+            mManifest.write(mOutputJar);
+            
+            // CERT.SF
+            Signature signature = Signature.getInstance("SHA1with" + mKey.getAlgorithm());
+            signature.initSign(mKey);
+            mOutputJar.putNextEntry(new JarEntry("META-INF/CERT.SF"));
+            writeSignatureFile(new SignatureOutputStream(mOutputJar, signature));
+    
+            // CERT.*
+            mOutputJar.putNextEntry(new JarEntry("META-INF/CERT." + mKey.getAlgorithm()));
+            writeSignatureBlock(signature, mCertificate, mKey);
+        }
+        
+        mOutputJar.close();
+    }
+    
+    /**
+     * Adds an entry to the output jar, and write its content from the {@link InputStream}
+     * @param input The input stream from where to write the entry content.
+     * @param entry the entry to write in the jar.
+     * @throws IOException
+     */
+    private void writeEntry(InputStream input, JarEntry entry) throws IOException {
+        // add the entry to the jar archive
+        mOutputJar.putNextEntry(entry);
+
+        // read the content of the entry from the input stream, and write it into the archive.
+        int count; 
+        while ((count = input.read(mBuffer)) != -1) {
+            mOutputJar.write(mBuffer, 0, count);
+            
+            // update the digest
+            if (mMessageDigest != null) {
+                mMessageDigest.update(mBuffer, 0, count);
+            }
+        }
+
+        // close the entry for this file
+        mOutputJar.closeEntry();
+        
+        if (mManifest != null) {
+            // update the manifest for this entry.
+            Attributes attr = mManifest.getAttributes(entry.getName());
+            if (attr == null) {
+                attr = new Attributes();
+                mManifest.getEntries().put(entry.getName(), attr);
+            }
+            attr.putValue(DIGEST_ATTR, mBase64Encoder.encode(mMessageDigest.digest()));
+        }
+    }
+    
+    /** Writes a .SF file with a digest to the manifest. */
+    private void writeSignatureFile(OutputStream out)
+            throws IOException, GeneralSecurityException {
+        Manifest sf = new Manifest();
+        Attributes main = sf.getMainAttributes();
+        main.putValue("Signature-Version", "1.0");
+        main.putValue("Created-By", "1.0 (Android)");
+
+        BASE64Encoder base64 = new BASE64Encoder();
+        MessageDigest md = MessageDigest.getInstance(DIGEST_ALGORITHM);
+        PrintStream print = new PrintStream(
+                new DigestOutputStream(new ByteArrayOutputStream(), md),
+                true, "UTF-8");
+
+        // Digest of the entire manifest
+        mManifest.write(print);
+        print.flush();
+        main.putValue(DIGEST_MANIFEST_ATTR, base64.encode(md.digest()));
+
+        Map<String, Attributes> entries = mManifest.getEntries();
+        for (Map.Entry<String, Attributes> entry : entries.entrySet()) {
+            // Digest of the manifest stanza for this entry.
+            print.print("Name: " + entry.getKey() + "\r\n");
+            for (Map.Entry<Object, Object> att : entry.getValue().entrySet()) {
+                print.print(att.getKey() + ": " + att.getValue() + "\r\n");
+            }
+            print.print("\r\n");
+            print.flush();
+
+            Attributes sfAttr = new Attributes();
+            sfAttr.putValue(DIGEST_ATTR, base64.encode(md.digest()));
+            sf.getEntries().put(entry.getKey(), sfAttr);
+        }
+
+        sf.write(out);
+    }
+
+    /** Write the certificate file with a digital signature. */
+    private void writeSignatureBlock(Signature signature, X509Certificate publicKey,
+            PrivateKey privateKey)
+            throws IOException, GeneralSecurityException {
+        SignerInfo signerInfo = new SignerInfo(
+                new X500Name(publicKey.getIssuerX500Principal().getName()),
+                publicKey.getSerialNumber(),
+                AlgorithmId.get(DIGEST_ALGORITHM),
+                AlgorithmId.get(privateKey.getAlgorithm()),
+                signature.sign());
+
+        PKCS7 pkcs7 = new PKCS7(
+                new AlgorithmId[] { AlgorithmId.get(DIGEST_ALGORITHM) },
+                new ContentInfo(ContentInfo.DATA_OID, null),
+                new X509Certificate[] { publicKey },
+                new SignerInfo[] { signerInfo });
+
+        pkcs7.encodeSignedData(mOutputJar);
+    }
+}
diff --git a/tools/jdwpspy/Android.mk b/tools/jdwpspy/Android.mk
new file mode 100644
index 0000000..eca3e22
--- /dev/null
+++ b/tools/jdwpspy/Android.mk
@@ -0,0 +1,17 @@
+# Copyright 2006 The Android Open Source Project
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	Main.c \
+	Net.c \
+	find_JdwpConstants.c
+
+LOCAL_C_INCLUDES += \
+	dalvik/vm
+
+LOCAL_MODULE := jdwpspy
+
+include $(BUILD_HOST_EXECUTABLE)
+
diff --git a/tools/jdwpspy/Common.h b/tools/jdwpspy/Common.h
new file mode 100644
index 0000000..c42d183
--- /dev/null
+++ b/tools/jdwpspy/Common.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * jdwpspy common stuff.
+ */
+#ifndef _JDWPSPY_COMMON
+#define _JDWPSPY_COMMON
+
+#include <stdio.h>
+#include <sys/types.h>
+
+typedef unsigned char u1;
+typedef unsigned short u2;
+typedef unsigned int u4;
+typedef unsigned long long u8;
+
+#ifndef __bool_true_false_are_defined
+typedef enum { false=0, true=!false } bool;
+#define __bool_true_false_are_defined 1
+#endif
+
+#define NELEM(x) (sizeof(x) / sizeof((x)[0]))
+
+#ifndef _JDWP_MISC_INLINE
+# define INLINE extern inline
+#else
+# define INLINE
+#endif
+
+/*
+ * Get 1 byte.  (Included to make the code more legible.)
+ */
+INLINE u1 get1(unsigned const char* pSrc)
+{
+    return *pSrc;
+}
+
+/*
+ * Get 2 big-endian bytes.
+ */
+INLINE u2 get2BE(unsigned char const* pSrc)
+{
+    u2 result;
+
+    result = *pSrc++ << 8;
+    result |= *pSrc++;
+
+    return result;
+}
+
+/*
+ * Get 4 big-endian bytes.
+ */
+INLINE u4 get4BE(unsigned char const* pSrc)
+{
+    u4 result;
+
+    result = *pSrc++ << 24;
+    result |= *pSrc++ << 16;
+    result |= *pSrc++ << 8;
+    result |= *pSrc++;
+
+    return result;
+}
+
+/*
+ * Get 8 big-endian bytes.
+ */
+INLINE u8 get8BE(unsigned char const* pSrc)
+{
+    u8 result;
+
+    result = (u8) *pSrc++ << 56;
+    result |= (u8) *pSrc++ << 48;
+    result |= (u8) *pSrc++ << 40;
+    result |= (u8) *pSrc++ << 32;
+    result |= (u8) *pSrc++ << 24;
+    result |= (u8) *pSrc++ << 16;
+    result |= (u8) *pSrc++ << 8;
+    result |= (u8) *pSrc++;
+
+    return result;
+}
+
+
+/*
+ * Start here.
+ */
+int run(const char* connectHost, int connectPort, int listenPort);
+
+/*
+ * Print a hex dump to the specified file pointer.
+ *
+ * "local" mode prints a hex dump starting from offset 0 (roughly equivalent
+ * to "xxd -g1").
+ *
+ * "mem" mode shows the actual memory address, and will offset the start
+ * so that the low nibble of the address is always zero.
+ */
+typedef enum { kHexDumpLocal, kHexDumpMem } HexDumpMode;
+void printHexDump(const void* vaddr, size_t length);
+void printHexDump2(const void* vaddr, size_t length, const char* prefix);
+void printHexDumpEx(FILE* fp, const void* vaddr, size_t length,
+    HexDumpMode mode, const char* prefix);
+
+#endif /*_JDWPSPY_COMMON*/
diff --git a/tools/jdwpspy/Main.c b/tools/jdwpspy/Main.c
new file mode 100644
index 0000000..62a0007
--- /dev/null
+++ b/tools/jdwpspy/Main.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * JDWP spy.
+ */
+#define _JDWP_MISC_INLINE
+#include "Common.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+
+static const char gHexDigit[] = "0123456789abcdef";
+
+/*
+ * Print a hex dump.  Just hands control off to the fancy version.
+ */
+void printHexDump(const void* vaddr, size_t length)
+{
+    printHexDumpEx(stdout, vaddr, length, kHexDumpLocal, "");
+}
+void printHexDump2(const void* vaddr, size_t length, const char* prefix)
+{
+    printHexDumpEx(stdout, vaddr, length, kHexDumpLocal, prefix);
+}
+
+/*
+ * Print a hex dump in this format:
+ *
+01234567: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff  0123456789abcdef\n
+ */
+void printHexDumpEx(FILE* fp, const void* vaddr, size_t length,
+    HexDumpMode mode, const char* prefix)
+{
+    const unsigned char* addr = vaddr;
+    char out[77];       /* exact fit */
+    unsigned int offset;    /* offset to show while printing */
+    char* hex;
+    char* asc;
+    int gap;
+
+    if (mode == kHexDumpLocal)
+        offset = 0;
+    else
+        offset = (int) addr;
+
+    memset(out, ' ', sizeof(out)-1);
+    out[8] = ':';
+    out[sizeof(out)-2] = '\n';
+    out[sizeof(out)-1] = '\0';
+
+    gap = (int) offset & 0x0f;
+    while (length) {
+        unsigned int lineOffset = offset & ~0x0f;
+        int i, count;
+        
+        hex = out;
+        asc = out + 59;
+
+        for (i = 0; i < 8; i++) {
+            *hex++ = gHexDigit[lineOffset >> 28];
+            lineOffset <<= 4;
+        }
+        hex++;
+        hex++;
+
+        count = ((int)length > 16-gap) ? 16-gap : (int) length; /* cap length */
+        assert(count != 0);
+        assert(count+gap <= 16);
+
+        if (gap) {
+            /* only on first line */
+            hex += gap * 3;
+            asc += gap;
+        }
+
+        for (i = gap ; i < count+gap; i++) {
+            *hex++ = gHexDigit[*addr >> 4];
+            *hex++ = gHexDigit[*addr & 0x0f];
+            hex++;
+            if (isprint(*addr))
+                *asc++ = *addr;
+            else
+                *asc++ = '.';
+            addr++;
+        }
+        for ( ; i < 16; i++) {
+            /* erase extra stuff; only happens on last line */
+            *hex++ = ' ';
+            *hex++ = ' ';
+            hex++;
+            *asc++ = ' ';
+        }
+
+        fprintf(fp, "%s%s", prefix, out);
+
+        gap = 0;
+        length -= count;
+        offset += count;
+    }
+}
+
+
+/*
+ * Explain it.
+ */
+static void usage(const char* progName)
+{
+    fprintf(stderr, "Usage: %s VM-port [debugger-listen-port]\n\n", progName);
+    fprintf(stderr,
+"When a debugger connects to the debugger-listen-port, jdwpspy will connect\n");
+    fprintf(stderr, "to the VM on the VM-port.\n");
+}
+
+/*
+ * Parse args.
+ */
+int main(int argc, char* argv[])
+{
+    int connectPort, listenPort;
+    int cc;
+
+    if (argc < 2 || argc > 3) {
+        usage("jdwpspy");
+        return 2;
+    }
+
+    setvbuf(stdout, NULL, _IONBF, 0);
+
+    /* may want this to be host:port */
+    connectPort = atoi(argv[1]);
+
+    if (argc > 2)
+        listenPort = atoi(argv[2]);
+    else
+        listenPort = connectPort + 1;
+
+    cc = run("localhost", connectPort, listenPort);
+
+    return (cc != 0);
+}
+
diff --git a/tools/jdwpspy/Net.c b/tools/jdwpspy/Net.c
new file mode 100644
index 0000000..555fe49
--- /dev/null
+++ b/tools/jdwpspy/Net.c
@@ -0,0 +1,751 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * JDWP spy.  This is a rearranged version of the JDWP code from the VM.
+ */
+#include "Common.h"
+#include "jdwp/JdwpConstants.h"
+
+#include <stdlib.h>
+#include <unistd.h>     
+#include <stdio.h>
+#include <string.h>     
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <time.h>
+#include <errno.h>
+#include <assert.h>
+
+#define kInputBufferSize    (256*1024)
+
+#define kMagicHandshakeLen  14      /* "JDWP-Handshake" */
+#define kJDWPHeaderLen      11
+#define kJDWPFlagReply      0x80
+
+
+/*
+ * Information about the remote end.
+ */
+typedef struct Peer {
+    char    label[2];           /* 'D' or 'V' */
+
+    int     sock;
+    unsigned char   inputBuffer[kInputBufferSize];
+    int     inputCount;
+
+    bool    awaitingHandshake;  /* waiting for "JDWP-Handshake" */
+} Peer;
+
+
+/*
+ * Network state.
+ */
+typedef struct NetState {
+    /* listen here for connection from debugger */
+    int     listenSock;
+
+    /* connect here to contact VM */
+    struct in_addr vmAddr;
+    short   vmPort;
+
+    Peer    dbg;
+    Peer    vm;
+} NetState;
+
+/*
+ * Function names.
+ */
+typedef struct {
+    u1  cmdSet;
+    u1  cmd;
+    const char* descr;
+} JdwpHandlerMap;
+
+/*
+ * Map commands to names.
+ *
+ * Command sets 0-63 are incoming requests, 64-127 are outbound requests,
+ * and 128-256 are vendor-defined.
+ */
+static const JdwpHandlerMap gHandlerMap[] = {
+    /* VirtualMachine command set (1) */
+    { 1,    1,  "VirtualMachine.Version" },
+    { 1,    2,  "VirtualMachine.ClassesBySignature" },
+    { 1,    3,  "VirtualMachine.AllClasses" },
+    { 1,    4,  "VirtualMachine.AllThreads" },
+    { 1,    5,  "VirtualMachine.TopLevelThreadGroups" },
+    { 1,    6,  "VirtualMachine.Dispose" },
+    { 1,    7,  "VirtualMachine.IDSizes" },
+    { 1,    8,  "VirtualMachine.Suspend" },
+    { 1,    9,  "VirtualMachine.Resume" },
+    { 1,    10, "VirtualMachine.Exit" },
+    { 1,    11, "VirtualMachine.CreateString" },
+    { 1,    12, "VirtualMachine.Capabilities" },
+    { 1,    13, "VirtualMachine.ClassPaths" },
+    { 1,    14, "VirtualMachine.DisposeObjects" },
+    { 1,    15, "VirtualMachine.HoldEvents" },
+    { 1,    16, "VirtualMachine.ReleaseEvents" },
+    { 1,    17, "VirtualMachine.CapabilitiesNew" },
+    { 1,    18, "VirtualMachine.RedefineClasses" },
+    { 1,    19, "VirtualMachine.SetDefaultStratum" },
+    { 1,    20, "VirtualMachine.AllClassesWithGeneric"},
+    { 1,    21, "VirtualMachine.InstanceCounts"},
+
+    /* ReferenceType command set (2) */
+    { 2,    1,  "ReferenceType.Signature" },
+    { 2,    2,  "ReferenceType.ClassLoader" },
+    { 2,    3,  "ReferenceType.Modifiers" },
+    { 2,    4,  "ReferenceType.Fields" },
+    { 2,    5,  "ReferenceType.Methods" },
+    { 2,    6,  "ReferenceType.GetValues" },
+    { 2,    7,  "ReferenceType.SourceFile" },
+    { 2,    8,  "ReferenceType.NestedTypes" },
+    { 2,    9,  "ReferenceType.Status" },
+    { 2,    10, "ReferenceType.Interfaces" },
+    { 2,    11, "ReferenceType.ClassObject" },
+    { 2,    12, "ReferenceType.SourceDebugExtension" },
+    { 2,    13, "ReferenceType.SignatureWithGeneric" },
+    { 2,    14, "ReferenceType.FieldsWithGeneric" },
+    { 2,    15, "ReferenceType.MethodsWithGeneric" },
+    { 2,    16, "ReferenceType.Instances" },
+    { 2,    17, "ReferenceType.ClassFileVersion" },
+    { 2,    18, "ReferenceType.ConstantPool" },
+
+    /* ClassType command set (3) */
+    { 3,    1,  "ClassType.Superclass" },
+    { 3,    2,  "ClassType.SetValues" },
+    { 3,    3,  "ClassType.InvokeMethod" },
+    { 3,    4,  "ClassType.NewInstance" },
+
+    /* ArrayType command set (4) */
+    { 4,    1,  "ArrayType.NewInstance" },
+
+    /* InterfaceType command set (5) */
+
+    /* Method command set (6) */
+    { 6,    1,  "Method.LineTable" },
+    { 6,    2,  "Method.VariableTable" },
+    { 6,    3,  "Method.Bytecodes" },
+    { 6,    4,  "Method.IsObsolete" },
+    { 6,    5,  "Method.VariableTableWithGeneric" },
+
+    /* Field command set (8) */
+
+    /* ObjectReference command set (9) */
+    { 9,    1,  "ObjectReference.ReferenceType" },
+    { 9,    2,  "ObjectReference.GetValues" },
+    { 9,    3,  "ObjectReference.SetValues" },
+    { 9,    4,  "ObjectReference.UNUSED" },
+    { 9,    5,  "ObjectReference.MonitorInfo" },
+    { 9,    6,  "ObjectReference.InvokeMethod" },
+    { 9,    7,  "ObjectReference.DisableCollection" },
+    { 9,    8,  "ObjectReference.EnableCollection" },
+    { 9,    9,  "ObjectReference.IsCollected" },
+    { 9,    10, "ObjectReference.ReferringObjects" },
+
+    /* StringReference command set (10) */
+    { 10,   1,  "StringReference.Value" },
+
+    /* ThreadReference command set (11) */
+    { 11,   1,  "ThreadReference.Name" },
+    { 11,   2,  "ThreadReference.Suspend" },
+    { 11,   3,  "ThreadReference.Resume" },
+    { 11,   4,  "ThreadReference.Status" },
+    { 11,   5,  "ThreadReference.ThreadGroup" },
+    { 11,   6,  "ThreadReference.Frames" },
+    { 11,   7,  "ThreadReference.FrameCount" },
+    { 11,   8,  "ThreadReference.OwnedMonitors" },
+    { 11,   9,  "ThreadReference.CurrentContendedMonitor" },
+    { 11,   10, "ThreadReference.Stop" },
+    { 11,   11, "ThreadReference.Interrupt" },
+    { 11,   12, "ThreadReference.SuspendCount" },
+    { 11,   13, "ThreadReference.OwnedMonitorsStackDepthInfo" },
+    { 11,   14, "ThreadReference.ForceEarlyReturn" },
+
+    /* ThreadGroupReference command set (12) */
+    { 12,   1,  "ThreadGroupReference.Name" },
+    { 12,   2,  "ThreadGroupReference.Parent" },
+    { 12,   3,  "ThreadGroupReference.Children" },
+
+    /* ArrayReference command set (13) */
+    { 13,   1,  "ArrayReference.Length" },
+    { 13,   2,  "ArrayReference.GetValues" },
+    { 13,   3,  "ArrayReference.SetValues" },
+
+    /* ClassLoaderReference command set (14) */
+    { 14,   1,  "ArrayReference.VisibleClasses" },
+
+    /* EventRequest command set (15) */
+    { 15,   1,  "EventRequest.Set" },
+    { 15,   2,  "EventRequest.Clear" },
+    { 15,   3,  "EventRequest.ClearAllBreakpoints" },
+
+    /* StackFrame command set (16) */
+    { 16,   1,  "StackFrame.GetValues" },
+    { 16,   2,  "StackFrame.SetValues" },
+    { 16,   3,  "StackFrame.ThisObject" },
+    { 16,   4,  "StackFrame.PopFrames" },
+
+    /* ClassObjectReference command set (17) */
+    { 17,   1,  "ClassObjectReference.ReflectedType" },
+
+    /* Event command set (64) */
+    { 64,  100, "Event.Composite" },
+
+    /* DDMS */
+    { 199,  1,  "DDMS.Chunk" },
+};
+
+/*
+ * Look up a command's name.
+ */
+static const char* getCommandName(int cmdSet, int cmd)
+{
+    int i;
+
+    for (i = 0; i < (int) NELEM(gHandlerMap); i++) {
+        if (gHandlerMap[i].cmdSet == cmdSet &&
+            gHandlerMap[i].cmd == cmd)
+        {
+            return gHandlerMap[i].descr;
+        }
+    }
+
+    return "?UNKNOWN?";
+}
+
+
+void jdwpNetFree(NetState* netState);       /* fwd */
+
+/*
+ * Allocate state structure and bind to the listen port.
+ *
+ * Returns 0 on success.
+ */
+NetState* jdwpNetStartup(unsigned short listenPort, const char* connectHost,
+    unsigned short connectPort)
+{
+    NetState* netState;
+    int one = 1;
+
+    netState = (NetState*) malloc(sizeof(*netState));
+    memset(netState, 0, sizeof(*netState));
+    netState->listenSock = -1;
+    netState->dbg.sock = netState->vm.sock = -1;
+
+    strcpy(netState->dbg.label, "D");
+    strcpy(netState->vm.label, "V");
+
+    /*
+     * Set up a socket to listen for connections from the debugger.
+     */
+
+    netState->listenSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (netState->listenSock < 0) {
+        fprintf(stderr, "Socket create failed: %s\n", strerror(errno));
+        goto fail;
+    }
+
+    /* allow immediate re-use if we die */
+    if (setsockopt(netState->listenSock, SOL_SOCKET, SO_REUSEADDR, &one,
+            sizeof(one)) < 0)
+    {
+        fprintf(stderr, "setsockopt(SO_REUSEADDR) failed: %s\n",
+            strerror(errno));
+        goto fail;
+    }
+
+    struct sockaddr_in addr;
+    addr.sin_family = AF_INET;
+    addr.sin_port = htons(listenPort);
+    addr.sin_addr.s_addr = INADDR_ANY;
+
+    if (bind(netState->listenSock, (struct sockaddr*) &addr, sizeof(addr)) != 0)
+    {
+        fprintf(stderr, "attempt to bind to port %u failed: %s\n",
+            listenPort, strerror(errno));
+        goto fail;
+    }
+
+    fprintf(stderr, "+++ bound to port %u\n", listenPort);
+
+    if (listen(netState->listenSock, 5) != 0) {
+        fprintf(stderr, "Listen failed: %s\n", strerror(errno));
+        goto fail;
+    }
+
+    /*
+     * Do the hostname lookup for the VM.
+     */
+    struct hostent* pHost;
+
+    pHost = gethostbyname(connectHost);
+    if (pHost == NULL) {
+        fprintf(stderr, "Name lookup of '%s' failed: %s\n",
+            connectHost, strerror(h_errno));
+        goto fail;
+    }
+
+    netState->vmAddr = *((struct in_addr*) pHost->h_addr_list[0]);
+    netState->vmPort = connectPort;
+
+    fprintf(stderr, "+++ connect host resolved to %s\n",
+        inet_ntoa(netState->vmAddr));
+
+    return netState;
+
+fail:
+    jdwpNetFree(netState);
+    return NULL;
+}
+
+/*
+ * Shut down JDWP listener.  Don't free state.
+ *
+ * Note that "netState" may be partially initialized if "startup" failed.
+ */
+void jdwpNetShutdown(NetState* netState)
+{
+    int listenSock = netState->listenSock;
+    int dbgSock = netState->dbg.sock;
+    int vmSock = netState->vm.sock;
+
+    /* clear these out so it doesn't wake up and try to reuse them */
+    /* (important when multi-threaded) */
+    netState->listenSock = netState->dbg.sock = netState->vm.sock = -1;
+
+    if (listenSock >= 0) {
+        shutdown(listenSock, SHUT_RDWR);
+        close(listenSock);
+    }
+    if (dbgSock >= 0) {
+        shutdown(dbgSock, SHUT_RDWR);
+        close(dbgSock);
+    }
+    if (vmSock >= 0) {
+        shutdown(vmSock, SHUT_RDWR);
+        close(vmSock);
+    }
+}
+
+/*
+ * Shut down JDWP listener and free its state.
+ */
+void jdwpNetFree(NetState* netState)
+{
+    if (netState == NULL)
+        return;
+
+    jdwpNetShutdown(netState);
+    free(netState);
+}
+
+/*
+ * Disable the TCP Nagle algorithm, which delays transmission of outbound
+ * packets until the previous transmissions have been acked.  JDWP does a
+ * lot of back-and-forth with small packets, so this may help.
+ */
+static int setNoDelay(int fd)
+{
+    int cc, on = 1;
+
+    cc = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
+    assert(cc == 0);
+    return cc;
+}
+
+/*
+ * Accept a connection.  This will block waiting for somebody to show up.
+ */
+bool jdwpAcceptConnection(NetState* netState)
+{
+    struct sockaddr_in addr;
+    socklen_t addrlen;
+    int sock;
+
+    if (netState->listenSock < 0)
+        return false;       /* you're not listening! */
+
+    assert(netState->dbg.sock < 0);     /* must not already be talking */
+
+    addrlen = sizeof(addr);
+    do {
+        sock = accept(netState->listenSock, (struct sockaddr*) &addr, &addrlen);
+        if (sock < 0 && errno != EINTR) {
+            fprintf(stderr, "accept failed: %s\n", strerror(errno));
+            return false;
+        }
+    } while (sock < 0);
+
+    fprintf(stderr, "+++ accepted connection from %s:%u\n",
+        inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+
+    netState->dbg.sock = sock;
+    netState->dbg.awaitingHandshake = true;
+    netState->dbg.inputCount = 0;
+
+    setNoDelay(sock);
+
+    return true;
+}
+
+/*
+ * Close the connections to the debugger and VM.
+ *
+ * Reset the state so we're ready to receive a new connection.
+ */
+void jdwpCloseConnection(NetState* netState)
+{
+    if (netState->dbg.sock >= 0) {
+        fprintf(stderr, "+++ closing connection to debugger\n");
+        close(netState->dbg.sock);
+        netState->dbg.sock = -1;
+    }
+    if (netState->vm.sock >= 0) {
+        fprintf(stderr, "+++ closing connection to vm\n");
+        close(netState->vm.sock);
+        netState->vm.sock = -1;
+    }
+}
+
+/*
+ * Figure out if we have a full packet in the buffer.
+ */
+static bool haveFullPacket(Peer* pPeer)
+{
+    long length;
+
+    if (pPeer->awaitingHandshake)
+        return (pPeer->inputCount >= kMagicHandshakeLen);
+
+    if (pPeer->inputCount < 4)
+        return false;
+
+    length = get4BE(pPeer->inputBuffer);
+    return (pPeer->inputCount >= length);
+}
+
+/*
+ * Consume bytes from the buffer.
+ *
+ * This would be more efficient with a circular buffer.  However, we're
+ * usually only going to find one packet, which is trivial to handle.
+ */
+static void consumeBytes(Peer* pPeer, int count)
+{
+    assert(count > 0);
+    assert(count <= pPeer->inputCount);
+
+    if (count == pPeer->inputCount) {
+        pPeer->inputCount = 0;
+        return;
+    }
+
+    memmove(pPeer->inputBuffer, pPeer->inputBuffer + count,
+        pPeer->inputCount - count);
+    pPeer->inputCount -= count;
+}
+
+/*
+ * Get the current time.
+ */
+static void getCurrentTime(int* pMin, int* pSec)
+{
+    time_t now;
+    struct tm* ptm;
+
+    now = time(NULL);
+    ptm = localtime(&now);
+    *pMin = ptm->tm_min;
+    *pSec = ptm->tm_sec;
+}
+
+/*
+ * Dump the contents of a packet to stdout.
+ */
+static void dumpPacket(const unsigned char* packetBuf, const char* srcName,
+    const char* dstName)
+{
+    const unsigned char* buf = packetBuf;
+    char prefix[3];
+    u4 length, id;
+    u1 flags, cmdSet=0, cmd=0;
+    u2 error=0;
+    bool reply;
+    int dataLen;
+
+    length = get4BE(buf+0);
+    id = get4BE(buf+4);
+    flags = get1(buf+8);
+    if ((flags & kJDWPFlagReply) != 0) {
+        reply = true;
+        error = get2BE(buf+9);
+    } else {
+        reply = false;
+        cmdSet = get1(buf+9);
+        cmd = get1(buf+10);
+    }
+
+    buf += kJDWPHeaderLen;
+    dataLen = length - (buf - packetBuf);
+
+    if (!reply) {
+        prefix[0] = srcName[0];
+        prefix[1] = '>';
+    } else {
+        prefix[0] = dstName[0];
+        prefix[1] = '<';
+    }
+    prefix[2] = '\0';
+
+    int min, sec;
+    getCurrentTime(&min, &sec);
+
+    if (!reply) {
+        printf("%s REQUEST dataLen=%-5u id=0x%08x flags=0x%02x cmd=%d/%d [%02d:%02d]\n",
+            prefix, dataLen, id, flags, cmdSet, cmd, min, sec);
+        printf("%s   --> %s\n", prefix, getCommandName(cmdSet, cmd));
+    } else {
+        printf("%s REPLY   dataLen=%-5u id=0x%08x flags=0x%02x err=%d (%s) [%02d:%02d]\n",
+            prefix, dataLen, id, flags, error, dvmJdwpErrorStr(error), min,sec);
+    }
+    if (dataLen > 0)
+        printHexDump2(buf, dataLen, prefix);
+    printf("%s ----------\n", prefix);
+}
+
+/*
+ * Handle a packet.  Returns "false" if we encounter a connection-fatal error.
+ */
+static bool handlePacket(Peer* pDst, Peer* pSrc)
+{
+    const unsigned char* buf = pSrc->inputBuffer;
+    u4 length;
+    u1 flags;
+    int cc;
+
+    length = get4BE(buf+0);
+    flags = get1(buf+9);
+
+    assert((int) length <= pSrc->inputCount);
+
+    dumpPacket(buf, pSrc->label, pDst->label);
+
+    cc = write(pDst->sock, buf, length);
+    if (cc != (int) length) {
+        fprintf(stderr, "Failed sending packet: %s\n", strerror(errno));
+        return false;
+    }
+    /*printf("*** wrote %d bytes from %c to %c\n",
+        cc, pSrc->label[0], pDst->label[0]);*/
+
+    consumeBytes(pSrc, length);
+    return true;
+}
+
+/*
+ * Handle incoming data.  If we have a full packet in the buffer, process it.
+ */
+static bool handleIncoming(Peer* pWritePeer, Peer* pReadPeer)
+{
+    if (haveFullPacket(pReadPeer)) {
+        if (pReadPeer->awaitingHandshake) {
+            printf("Handshake [%c]: %.14s\n",
+                pReadPeer->label[0], pReadPeer->inputBuffer);
+            if (write(pWritePeer->sock, pReadPeer->inputBuffer,
+                    kMagicHandshakeLen) != kMagicHandshakeLen)
+            {
+                fprintf(stderr,
+                    "+++ [%c] handshake write failed\n", pReadPeer->label[0]);
+                goto fail;
+            }
+            consumeBytes(pReadPeer, kMagicHandshakeLen);
+            pReadPeer->awaitingHandshake = false;
+        } else {
+            if (!handlePacket(pWritePeer, pReadPeer))
+                goto fail;
+        }
+    } else {
+        /*printf("*** %c not full yet\n", pReadPeer->label[0]);*/
+    }
+
+    return true;
+
+fail:
+    return false;
+}
+
+/*
+ * Process incoming data.  If no data is available, this will block until
+ * some arrives.
+ *
+ * Returns "false" on error (indicating that the connection has been severed).
+ */
+bool jdwpProcessIncoming(NetState* netState)
+{
+    int cc;
+
+    assert(netState->dbg.sock >= 0);
+    assert(netState->vm.sock >= 0);
+
+    while (!haveFullPacket(&netState->dbg) && !haveFullPacket(&netState->vm)) {
+        /* read some more */
+        int highFd;
+        fd_set readfds;
+
+        highFd = (netState->dbg.sock > netState->vm.sock) ?
+            netState->dbg.sock+1 : netState->vm.sock+1;
+        FD_ZERO(&readfds);
+        FD_SET(netState->dbg.sock, &readfds);
+        FD_SET(netState->vm.sock, &readfds);
+
+        errno = 0;
+        cc = select(highFd, &readfds, NULL, NULL, NULL);
+        if (cc < 0) {
+            if (errno == EINTR) {
+                fprintf(stderr, "+++ EINTR on select\n");
+                continue;
+            }
+            fprintf(stderr, "+++ select failed: %s\n", strerror(errno));
+            goto fail;
+        }
+
+        if (FD_ISSET(netState->dbg.sock, &readfds)) {
+            cc = read(netState->dbg.sock,
+                netState->dbg.inputBuffer + netState->dbg.inputCount,
+                sizeof(netState->dbg.inputBuffer) - netState->dbg.inputCount);
+            if (cc < 0) {
+                if (errno == EINTR) {
+                    fprintf(stderr, "+++ EINTR on read\n");
+                    continue;
+                }
+                fprintf(stderr, "+++ dbg read failed: %s\n", strerror(errno));
+                goto fail;
+            }
+            if (cc == 0) {
+                if (sizeof(netState->dbg.inputBuffer) ==
+                        netState->dbg.inputCount)
+                    fprintf(stderr, "+++ debugger sent huge message\n");
+                else
+                    fprintf(stderr, "+++ debugger disconnected\n");
+                goto fail;
+            }
+
+            /*printf("*** %d bytes from dbg\n", cc);*/
+            netState->dbg.inputCount += cc;
+        }
+
+        if (FD_ISSET(netState->vm.sock, &readfds)) {
+            cc = read(netState->vm.sock,
+                netState->vm.inputBuffer + netState->vm.inputCount,
+                sizeof(netState->vm.inputBuffer) - netState->vm.inputCount);
+            if (cc < 0) {
+                if (errno == EINTR) {
+                    fprintf(stderr, "+++ EINTR on read\n");
+                    continue;
+                }
+                fprintf(stderr, "+++ vm read failed: %s\n", strerror(errno));
+                goto fail;
+            }
+            if (cc == 0) {
+                if (sizeof(netState->vm.inputBuffer) ==
+                        netState->vm.inputCount)
+                    fprintf(stderr, "+++ vm sent huge message\n");
+                else
+                    fprintf(stderr, "+++ vm disconnected\n");
+                goto fail;
+            }
+
+            /*printf("*** %d bytes from vm\n", cc);*/
+            netState->vm.inputCount += cc;
+        }
+    }
+
+    if (!handleIncoming(&netState->dbg, &netState->vm))
+        goto fail;
+    if (!handleIncoming(&netState->vm, &netState->dbg))
+        goto fail;
+
+    return true;
+
+fail:
+    jdwpCloseConnection(netState);
+    return false;
+}
+
+/*
+ * Connect to the VM.
+ */
+bool jdwpConnectToVm(NetState* netState)
+{
+    struct sockaddr_in addr;
+    int sock = -1;
+
+    sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (sock < 0) {
+        fprintf(stderr, "Socket create failed: %s\n", strerror(errno));
+        goto fail;
+    }
+
+    addr.sin_family = AF_INET;
+    addr.sin_addr = netState->vmAddr;
+    addr.sin_port = htons(netState->vmPort);
+    if (connect(sock, (struct sockaddr*) &addr, sizeof(addr)) != 0) {
+        fprintf(stderr, "Connection to %s:%u failed: %s\n",
+            inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), strerror(errno));
+        goto fail;
+    }
+    fprintf(stderr, "+++ connected to VM %s:%u\n",
+        inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+
+    netState->vm.sock = sock;
+    netState->vm.awaitingHandshake = true;
+    netState->vm.inputCount = 0;
+
+    setNoDelay(netState->vm.sock);
+    return true;
+
+fail:
+    if (sock >= 0)
+        close(sock);
+    return false;
+}
+
+/*
+ * Establish network connections and start things running.
+ *
+ * We wait for a new connection from the debugger.  When one arrives we
+ * open a connection to the VM.  If one side or the other goes away, we
+ * drop both ends and go back to listening.
+ */
+int run(const char* connectHost, int connectPort, int listenPort)
+{
+    NetState* state;
+
+    state = jdwpNetStartup(listenPort, connectHost, connectPort);
+    if (state == NULL)
+        return -1;
+
+    while (true) {
+        if (!jdwpAcceptConnection(state))
+            break;
+
+        if (jdwpConnectToVm(state)) {
+            while (true) {
+                if (!jdwpProcessIncoming(state))
+                    break;
+            }
+        }
+
+        jdwpCloseConnection(state);
+    }
+
+    jdwpNetFree(state);
+
+    return 0;
+}
+
diff --git a/tools/jdwpspy/find_JdwpConstants.c b/tools/jdwpspy/find_JdwpConstants.c
new file mode 100644
index 0000000..8ff8186
--- /dev/null
+++ b/tools/jdwpspy/find_JdwpConstants.c
@@ -0,0 +1 @@
+#include "jdwp/JdwpConstants.c"
diff --git a/tools/layoutlib_utils/.classpath b/tools/layoutlib_utils/.classpath
new file mode 100644
index 0000000..0321c43
--- /dev/null
+++ b/tools/layoutlib_utils/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/layoutlib_api"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/layoutlib_utils/.project b/tools/layoutlib_utils/.project
new file mode 100644
index 0000000..b427809
--- /dev/null
+++ b/tools/layoutlib_utils/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>layoutlib_utils</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/layoutlib_utils/Android.mk b/tools/layoutlib_utils/Android.mk
new file mode 100644
index 0000000..50eb0ff
--- /dev/null
+++ b/tools/layoutlib_utils/Android.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under,src)
+
+LOCAL_JAVA_LIBRARIES := \
+	layoutlib_api
+
+LOCAL_MODULE := layoutlib_utils
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/layoutlib_utils/src/com/android/layoutlib/utils/ResourceValue.java b/tools/layoutlib_utils/src/com/android/layoutlib/utils/ResourceValue.java
new file mode 100644
index 0000000..98b4de6
--- /dev/null
+++ b/tools/layoutlib_utils/src/com/android/layoutlib/utils/ResourceValue.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.utils;
+
+import com.android.layoutlib.api.IResourceValue;
+
+public class ResourceValue implements IResourceValue {
+    private final String mType;
+    private final String mName;
+    private String mValue = null;
+    private final boolean mIsFramwork;
+    
+    public ResourceValue(String type, String name, boolean isFramwork) {
+        mType = type;
+        mName = name;
+        mIsFramwork = isFramwork;
+    }
+
+    public ResourceValue(String type, String name, String value, boolean isFramework) {
+        mType = type;
+        mName = name;
+        mValue = value;
+        mIsFramwork = isFramework;
+    }
+
+    public String getType() {
+        return mType;
+    }
+
+    public final String getName() {
+        return mName;
+    }
+    
+    public final String getValue() {
+        return mValue;
+    }
+    
+    public final void setValue(String value) {
+        mValue = value;
+    }
+    
+    public void replaceWith(ResourceValue value) {
+        mValue = value.mValue;
+    }
+
+    public boolean isFramework() {
+        return mIsFramwork;
+    }
+}
diff --git a/tools/layoutlib_utils/src/com/android/layoutlib/utils/StyleResourceValue.java b/tools/layoutlib_utils/src/com/android/layoutlib/utils/StyleResourceValue.java
new file mode 100644
index 0000000..a32ac1b
--- /dev/null
+++ b/tools/layoutlib_utils/src/com/android/layoutlib/utils/StyleResourceValue.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.utils;
+
+import com.android.layoutlib.api.IResourceValue;
+import com.android.layoutlib.api.IStyleResourceValue;
+
+import java.util.HashMap;
+
+public final class StyleResourceValue extends ResourceValue implements IStyleResourceValue {
+
+    private String mParentStyle = null;
+    private HashMap<String, IResourceValue> mItems = new HashMap<String, IResourceValue>();
+
+    public StyleResourceValue(String type, String name, boolean isFramework) {
+        super(type, name, isFramework);
+    }
+
+    public StyleResourceValue(String type, String name, String parentStyle, boolean isFramework) {
+        super(type, name, isFramework);
+        mParentStyle = parentStyle;
+    }
+
+    public String getParentStyle() {
+        return mParentStyle;
+    }
+    
+    public IResourceValue findItem(String name) {
+        return mItems.get(name);
+    }
+    
+    public void addItem(IResourceValue value) {
+        mItems.put(value.getName(), value);
+    }
+    
+    @Override
+    public void replaceWith(ResourceValue value) {
+        super.replaceWith(value);
+        
+        if (value instanceof StyleResourceValue) {
+            mItems.clear();
+            mItems.putAll(((StyleResourceValue)value).mItems);
+        }
+    }
+
+}
diff --git a/tools/layoutlib_utils/src/com/android/layoutlib/utils/ValueResourceParser.java b/tools/layoutlib_utils/src/com/android/layoutlib/utils/ValueResourceParser.java
new file mode 100644
index 0000000..8b768ef
--- /dev/null
+++ b/tools/layoutlib_utils/src/com/android/layoutlib/utils/ValueResourceParser.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.layoutlib.utils;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * SAX handler to parser value resource files.
+ */
+public final class ValueResourceParser extends DefaultHandler {
+
+    // TODO: reuse definitions from somewhere else.
+    private final static String NODE_RESOURCES = "resources";
+    private final static String NODE_ITEM = "item";
+    private final static String ATTR_NAME = "name";
+    private final static String ATTR_TYPE = "type";
+    private final static String ATTR_PARENT = "parent";
+    
+    // Resource type definition
+    private final static String RES_STYLE = "style";
+    private final static String RES_ATTR = "attr";
+    
+    private final static String DEFAULT_NS_PREFIX = "android:";
+    private final static int DEFAULT_NS_PREFIX_LEN = DEFAULT_NS_PREFIX.length();
+    
+    public interface IValueResourceRepository {
+        void addResourceValue(String resType, ResourceValue value);
+    }
+    
+    private boolean inResources = false;
+    private int mDepth = 0;
+    private StyleResourceValue mCurrentStyle = null;
+    private ResourceValue mCurrentValue = null;
+    private IValueResourceRepository mRepository;
+    private final boolean mIsFramework;
+    
+    public ValueResourceParser(IValueResourceRepository repository, boolean isFramework) {
+        mRepository = repository;
+        mIsFramework = isFramework;
+    }
+
+    @Override
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+        if (mCurrentValue != null) {
+            mCurrentValue.setValue(trimXmlWhitespaces(mCurrentValue.getValue()));
+        }
+        
+        if (inResources && qName.equals(NODE_RESOURCES)) {
+            inResources = false;
+        } else if (mDepth == 2) {
+            mCurrentValue = null;
+            mCurrentStyle = null;
+        } else if (mDepth == 3) {
+            mCurrentValue = null;
+        }
+        
+        mDepth--;
+        super.endElement(uri, localName, qName);
+    }
+
+    @Override
+    public void startElement(String uri, String localName, String qName, Attributes attributes)
+            throws SAXException {
+        try {
+            mDepth++;
+            if (inResources == false && mDepth == 1) {
+                if (qName.equals(NODE_RESOURCES)) {
+                    inResources = true;
+                }
+            } else if (mDepth == 2 && inResources == true) {
+                String type;
+                
+                // if the node is <item>, we get the type from the attribute "type"
+                if (NODE_ITEM.equals(qName)) {
+                    type = attributes.getValue(ATTR_TYPE);
+                } else {
+                    // the type is the name of the node.
+                    type = qName;
+                }
+
+                if (type != null) {
+                    if (RES_ATTR.equals(type) == false) {
+                        // get the resource name
+                        String name = attributes.getValue(ATTR_NAME);
+                        if (name != null) {
+                            if (RES_STYLE.equals(type)) {
+                                String parent = attributes.getValue(ATTR_PARENT);
+                                mCurrentStyle = new StyleResourceValue(type, name, parent, mIsFramework);
+                                mRepository.addResourceValue(type, mCurrentStyle);
+                            } else {
+                                mCurrentValue = new ResourceValue(type, name, mIsFramework);
+                                mRepository.addResourceValue(type, mCurrentValue);
+                            }
+                        }
+                    }
+                }
+            } else if (mDepth == 3 && mCurrentStyle != null) {
+                // get the resource name
+                String name = attributes.getValue(ATTR_NAME);
+                if (name != null) {
+                    // the name can, in some cases, contain a prefix! we remove it.
+                    if (name.startsWith(DEFAULT_NS_PREFIX)) {
+                        name = name.substring(DEFAULT_NS_PREFIX_LEN);
+                    }
+    
+                    mCurrentValue = new ResourceValue(null, name, mIsFramework);
+                    mCurrentStyle.addItem(mCurrentValue);
+                }
+            }
+        } finally {
+            super.startElement(uri, localName, qName, attributes);
+        }
+    }
+    
+    @Override
+    public void characters(char[] ch, int start, int length) throws SAXException {
+        if (mCurrentValue != null) {
+            String value = mCurrentValue.getValue();
+            if (value == null) {
+                mCurrentValue.setValue(new String(ch, start, length));
+            } else {
+                mCurrentValue.setValue(value + new String(ch, start, length));
+            }
+        }
+    }
+    
+    public static String trimXmlWhitespaces(String value) {
+        if (value == null) {
+            return null;
+        }
+
+        // look for carriage return and replace all whitespace around it by just 1 space.
+        int index;
+        
+        while ((index = value.indexOf('\n')) != -1) {
+            // look for whitespace on each side
+            int left = index - 1;
+            while (left >= 0) {
+                if (Character.isWhitespace(value.charAt(left))) {
+                    left--;
+                } else {
+                    break;
+                }
+            }
+            
+            int right = index + 1;
+            int count = value.length();
+            while (right < count) {
+                if (Character.isWhitespace(value.charAt(right))) {
+                    right++;
+                } else {
+                    break;
+                }
+            }
+            
+            // remove all between left and right (non inclusive) and replace by a single space.
+            String leftString = null;
+            if (left >= 0) {
+                leftString = value.substring(0, left + 1);
+            }
+            String rightString = null;
+            if (right < count) {
+                rightString = value.substring(right);
+            }
+            
+            if (leftString != null) {
+                value = leftString;
+                if (rightString != null) {
+                    value += " " + rightString;
+                }
+            } else {
+                value = rightString != null ? rightString : "";
+            }
+        }
+        
+        // now we un-escape the string
+        int length = value.length();
+        char[] buffer = value.toCharArray();
+        
+        for (int i = 0 ; i < length ; i++) {
+            if (buffer[i] == '\\') {
+                if (buffer[i+1] == 'u') {
+                    // this is unicode char.
+                    int unicodeChar = Integer.parseInt(new String(buffer, i+2, 4), 16);
+                    
+                    // put the unicode char at the location of the \
+                    buffer[i] = (char)unicodeChar;
+
+                    // offset the rest of the buffer since we go from 6 to 1 char
+                    if (i + 6 < buffer.length) {
+                        System.arraycopy(buffer, i+6, buffer, i+1, length - i - 6);
+                    }
+                    length -= 5;
+                } else {
+                    if (buffer[i+1] == 'n') {
+                        // replace the 'n' char with \n
+                        buffer[i+1] = '\n';
+                    }
+                    
+                    // offset the buffer to erase the \
+                    System.arraycopy(buffer, i+1, buffer, i, length - i - 1);
+                    length--;
+                }
+            }
+        }
+        
+        return new String(buffer, 0, length);
+    }
+}
diff --git a/tools/line_endings/Android.mk b/tools/line_endings/Android.mk
new file mode 100644
index 0000000..e3902ae
--- /dev/null
+++ b/tools/line_endings/Android.mk
@@ -0,0 +1,14 @@
+# Copyright 2007 The Android Open Source Project
+#
+# Copies files into the directory structure described by a manifest
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+	line_endings.c
+
+LOCAL_MODULE := line_endings
+
+include $(BUILD_HOST_EXECUTABLE)
+
diff --git a/tools/line_endings/line_endings.c b/tools/line_endings/line_endings.c
new file mode 100644
index 0000000..97e1a29
--- /dev/null
+++ b/tools/line_endings/line_endings.c
@@ -0,0 +1,158 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#define BUFSIZE (1024*8)
+static void to_unix(char* buf);
+static void unix_to_dos(char* buf2, const char* buf);
+
+int usage()
+{
+    fprintf(stderr, "usage: line_endings unix|dos FILES\n"
+            "\n"
+            "Convert FILES to either unix or dos line endings.\n");
+    return 1;
+}
+
+typedef struct Node {
+    struct Node *next;
+    char buf[BUFSIZE*2+3];
+} Node;
+
+int
+main(int argc, char** argv)
+{
+    enum { UNIX, DOS } ending;
+    int i;
+
+    if (argc < 2) {
+        return usage();
+    }
+
+    if (0 == strcmp("unix", argv[1])) {
+        ending = UNIX;
+    }
+    else if (0 == strcmp("dos", argv[1])) {
+        ending = DOS;
+    }
+    else {
+        return usage();
+    }
+
+    for (i=2; i<argc; i++) {
+        int fd;
+        int len;
+
+        // force implied
+        chmod(argv[i], S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
+
+        fd = open(argv[i], O_RDWR);
+        if (fd < 0) {
+            fprintf(stderr, "unable to open file for read/write: %s\n", argv[i]);
+            return 1;
+        }
+
+        len = lseek(fd, 0, SEEK_END);
+        lseek(fd, 0, SEEK_SET);
+
+        if (len > 0) {
+            Node* root = malloc(sizeof(Node));
+            Node* node = root;
+            node->buf[0] = 0;
+
+            while (len > 0) {
+                node->next = malloc(sizeof(Node));
+                node = node->next;
+                node->next = NULL;
+
+                char buf[BUFSIZE+2];
+                ssize_t amt;
+                ssize_t amt2 = len < BUFSIZE ? len : BUFSIZE;
+                amt = read(fd, buf, amt2);
+                if (amt != amt2) {
+                    fprintf(stderr, "unable to read file: %s\n", argv[i]);
+                    return 1;
+                }
+                buf[amt2] = '\0';
+                to_unix(buf);
+                if (ending == UNIX) {
+                    strcpy(node->buf, buf);
+                } else {
+                    char buf2[(BUFSIZE*2)+3];
+                    unix_to_dos(buf2, buf);
+                    strcpy(node->buf, buf2);
+                }
+                len -= amt2;
+            }
+
+            ftruncate(fd, 0);
+            lseek(fd, 0, SEEK_SET);
+            while (root) {
+                ssize_t amt2 = strlen(root->buf);
+                if (amt2 > 0) {
+                    ssize_t amt = write(fd, root->buf, amt2);
+                    if (amt != amt2) {
+                        fprintf(stderr, "unable to write file: %s\n", argv[i]);
+                        return 1;
+                    }
+                }
+                node = root;
+                root = root->next;
+                free(node);
+            }
+        }
+        close(fd);
+    }
+    return 0;
+}
+
+void
+to_unix(char* buf)
+{
+    char* p = buf;
+    char* q = buf;
+    while (*p) {
+        if (p[0] == '\r' && p[1] == '\n') {
+            // dos
+            *q = '\n';
+            p += 2;
+            q += 1;
+        }
+        else if (p[0] == '\r') {
+            // old mac
+            *q = '\n';
+            p += 1;
+            q += 1;
+        }
+        else {
+            *q = *p;
+            p += 1;
+            q += 1;
+        }
+    }
+    *q = '\0';
+}
+
+void
+unix_to_dos(char* buf2, const char* buf)
+{
+    const char* p = buf;
+    char* q = buf2;
+    while (*p) {
+        if (*p == '\n') {
+            q[0] = '\r';
+            q[1] = '\n';
+            q += 2;
+            p += 1;
+        } else {
+            *q = *p;
+            p += 1;
+            q += 1;
+        }
+    }
+    *q = '\0';
+}
+
diff --git a/tools/ninepatch/Android.mk b/tools/ninepatch/Android.mk
new file mode 100644
index 0000000..42e0205
--- /dev/null
+++ b/tools/ninepatch/Android.mk
@@ -0,0 +1,23 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under,src)
+
+LOCAL_MODULE := ninepatch
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/ninepatch/src/com/android/ninepatch/GraphicsUtilities.java b/tools/ninepatch/src/com/android/ninepatch/GraphicsUtilities.java
new file mode 100644
index 0000000..7a823ec
--- /dev/null
+++ b/tools/ninepatch/src/com/android/ninepatch/GraphicsUtilities.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ninepatch;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Graphics;
+import java.awt.Transparency;
+import java.net.URL;
+import java.io.IOException;
+
+public class GraphicsUtilities {
+    public static BufferedImage loadCompatibleImage(URL resource) throws IOException {
+        BufferedImage image = ImageIO.read(resource);
+        return toCompatibleImage(image);
+    }
+
+    public static BufferedImage createCompatibleImage(int width, int height) {
+        return getGraphicsConfiguration().createCompatibleImage(width, height);
+    }
+
+    public static BufferedImage toCompatibleImage(BufferedImage image) {
+        if (isHeadless()) {
+            return image;
+        }
+
+        if (image.getColorModel().equals(getGraphicsConfiguration().getColorModel())) {
+            return image;
+        }
+
+        BufferedImage compatibleImage = getGraphicsConfiguration().createCompatibleImage(
+                    image.getWidth(), image.getHeight(), image.getTransparency());
+        Graphics g = compatibleImage.getGraphics();
+        g.drawImage(image, 0, 0, null);
+        g.dispose();
+
+        return compatibleImage;
+    }
+
+    public static BufferedImage createCompatibleImage(BufferedImage image, int width, int height) {
+        return getGraphicsConfiguration().createCompatibleImage(width, height,
+                                                   image.getTransparency());
+    }
+
+    private static GraphicsConfiguration getGraphicsConfiguration() {
+        GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
+        return environment.getDefaultScreenDevice().getDefaultConfiguration();
+    }
+
+    private static boolean isHeadless() {
+        return GraphicsEnvironment.isHeadless();
+    }
+
+    public static BufferedImage createTranslucentCompatibleImage(int width, int height) {
+        return getGraphicsConfiguration().createCompatibleImage(width, height,
+                Transparency.TRANSLUCENT);
+    }
+
+    public static int[] getPixels(BufferedImage img, int x, int y, int w, int h, int[] pixels) {
+        if (w == 0 || h == 0) {
+            return new int[0];
+        }
+
+        if (pixels == null) {
+            pixels = new int[w * h];
+        } else if (pixels.length < w * h) {
+            throw new IllegalArgumentException("Pixels array must have a length >= w * h");
+        }
+
+        int imageType = img.getType();
+        if (imageType == BufferedImage.TYPE_INT_ARGB || imageType == BufferedImage.TYPE_INT_RGB) {
+            Raster raster = img.getRaster();
+            return (int[]) raster.getDataElements(x, y, w, h, pixels);
+        }
+
+        // Unmanages the image
+        return img.getRGB(x, y, w, h, pixels, 0, w);
+    }
+}
diff --git a/tools/ninepatch/src/com/android/ninepatch/NinePatch.java b/tools/ninepatch/src/com/android/ninepatch/NinePatch.java
new file mode 100644
index 0000000..39e05c6
--- /dev/null
+++ b/tools/ninepatch/src/com/android/ninepatch/NinePatch.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ninepatch;
+
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents a 9-Patch bitmap.
+ */
+public class NinePatch {
+    public static final String EXTENSION_9PATCH = ".9.png";
+
+    private BufferedImage mImage;
+    
+    private int mMinWidth;
+    private int mMinHeight;
+
+    private int[] row;
+    private int[] column;
+
+    private boolean mVerticalStartWithPatch;
+    private boolean mHorizontalStartWithPatch;
+
+    private List<Rectangle> mFixed;
+    private List<Rectangle> mPatches;
+    private List<Rectangle> mHorizontalPatches;
+    private List<Rectangle> mVerticalPatches;
+
+    private Pair<Integer> mHorizontalPadding;
+    private Pair<Integer> mVerticalPadding;
+    
+    private float mHorizontalPatchesSum;
+    private float mVerticalPatchesSum;
+
+    private int mRemainderHorizontal;
+
+    private int mRemainderVertical;
+
+    private final URL mFileUrl;
+
+    /**
+     * Loads a 9 patch or regular bitmap.
+     * @param fileUrl the URL of the file to load.
+     * @param convert if <code>true</code>, non 9-patch bitmpa will be converted into a 9 patch.
+     * If <code>false</code> and the bitmap is not a 9 patch, the method will return
+     * <code>null</code>.
+     * @return a {@link NinePatch} or <code>null</code>.
+     * @throws IOException
+     */
+    public static NinePatch load(URL fileUrl, boolean convert) throws IOException {
+        BufferedImage image = null;
+        try {
+            image  = GraphicsUtilities.loadCompatibleImage(fileUrl);
+        } catch (MalformedURLException e) {
+            // really this shouldn't be happening since we're not creating the URL manually.
+            return null;
+        }
+        
+        boolean is9Patch = fileUrl.getPath().toLowerCase().endsWith(EXTENSION_9PATCH);
+        
+        if (is9Patch == false) {
+            if (convert) {
+                image = convertTo9Patch(image);
+            } else {
+                return null;
+            }
+        } else {
+            ensure9Patch(image);
+        }
+
+        
+        return new NinePatch(fileUrl, image);
+    }
+    
+    public int getWidth() {
+        return mImage.getWidth() - 2;
+    }
+
+    public int getHeight() {
+        return mImage.getHeight() - 2;
+    }
+    
+    /**
+     * 
+     * @param padding array of left, top, right, bottom padding
+     * @return
+     */
+    public boolean getPadding(int[] padding) {
+        padding[0] = mHorizontalPadding.mFirst; // left
+        padding[2] = mHorizontalPadding.mSecond; // right
+        padding[1] = mVerticalPadding.mFirst; // top
+        padding[3] = mVerticalPadding.mSecond; // bottom
+        return true;
+    }
+
+
+    public void draw(Graphics2D graphics2D, int x, int y, int scaledWidth, int scaledHeight) {
+        if (scaledWidth <= 1 || scaledHeight <= 1) {
+            return;
+        }
+
+        Graphics2D g = (Graphics2D)graphics2D.create();
+        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+        
+
+        try {
+            if (mPatches.size() == 0 || mHorizontalPatches.size() == 0 ||
+                    mVerticalPatches.size() == 0) {
+                g.drawImage(mImage, x, y, scaledWidth, scaledHeight, null);
+                return;
+            }
+
+            g.translate(x, y);
+            x = y = 0;
+            
+            computePatches(scaledWidth, scaledHeight);
+    
+            int fixedIndex = 0;
+            int horizontalIndex = 0;
+            int verticalIndex = 0;
+            int patchIndex = 0;
+    
+            boolean hStretch;
+            boolean vStretch;
+    
+            float vWeightSum = 1.0f;
+            float vRemainder = mRemainderVertical;
+    
+            vStretch = mVerticalStartWithPatch;
+            while (y < scaledHeight - 1) {
+                hStretch = mHorizontalStartWithPatch;
+    
+                int height = 0;
+                float vExtra = 0.0f;
+    
+                float hWeightSum = 1.0f;
+                float hRemainder = mRemainderHorizontal;
+    
+                while (x < scaledWidth - 1) {
+                    Rectangle r;
+                    if (!vStretch) {
+                        if (hStretch) {
+                            r = mHorizontalPatches.get(horizontalIndex++);
+                            float extra = r.width / mHorizontalPatchesSum;
+                            int width = (int) (extra * hRemainder / hWeightSum);
+                            hWeightSum -= extra;
+                            hRemainder -= width;
+                            g.drawImage(mImage, x, y, x + width, y + r.height, r.x, r.y,
+                                    r.x + r.width, r.y + r.height, null);
+                            x += width;
+                        } else {
+                            r = mFixed.get(fixedIndex++);
+                            g.drawImage(mImage, x, y, x + r.width, y + r.height, r.x, r.y,
+                                    r.x + r.width, r.y + r.height, null);
+                            x += r.width;
+                        }
+                        height = r.height;
+                    } else {
+                        if (hStretch) {
+                            r = mPatches.get(patchIndex++);
+                            vExtra = r.height / mVerticalPatchesSum;
+                            height = (int) (vExtra * vRemainder / vWeightSum);
+                            float extra = r.width / mHorizontalPatchesSum;
+                            int width = (int) (extra * hRemainder / hWeightSum);
+                            hWeightSum -= extra;
+                            hRemainder -= width;
+                            g.drawImage(mImage, x, y, x + width, y + height, r.x, r.y,
+                                    r.x + r.width, r.y + r.height, null);
+                            x += width;
+                        } else {
+                            r = mVerticalPatches.get(verticalIndex++);
+                            vExtra = r.height / mVerticalPatchesSum;
+                            height = (int) (vExtra * vRemainder / vWeightSum);
+                            g.drawImage(mImage, x, y, x + r.width, y + height, r.x, r.y,
+                                    r.x + r.width, r.y + r.height, null);
+                            x += r.width;
+                        }
+                        
+                    }
+                    hStretch = !hStretch;
+                }
+                x = 0;
+                y += height;
+                if (vStretch) {
+                    vWeightSum -= vExtra;
+                    vRemainder -= height;
+                }
+                vStretch = !vStretch;
+            }
+    
+        } finally {
+            g.dispose();
+        }
+    }
+    
+    void computePatches(int scaledWidth, int scaledHeight) {
+        boolean measuredWidth = false;
+        boolean endRow = true;
+
+        int remainderHorizontal = 0;
+        int remainderVertical = 0;
+
+        if (mFixed.size() > 0) {
+            int start = mFixed.get(0).y;
+            for (Rectangle rect : mFixed) {
+                if (rect.y > start) {
+                    endRow = true;
+                    measuredWidth = true;
+                }
+                if (!measuredWidth) {
+                    remainderHorizontal += rect.width;
+                }
+                if (endRow) {
+                    remainderVertical += rect.height;
+                    endRow = false;
+                    start = rect.y;
+                }
+            }
+        }
+
+        mRemainderHorizontal = scaledWidth - remainderHorizontal;
+
+        mRemainderVertical = scaledHeight - remainderVertical;
+
+        mHorizontalPatchesSum = 0;
+        if (mHorizontalPatches.size() > 0) {
+            int start = -1;
+            for (Rectangle rect : mHorizontalPatches) {
+                if (rect.x > start) {
+                    mHorizontalPatchesSum += rect.width;
+                    start = rect.x;
+                }
+            }
+        }
+
+        mVerticalPatchesSum = 0;
+        if (mVerticalPatches.size() > 0) {
+            int start = -1;
+            for (Rectangle rect : mVerticalPatches) {
+                if (rect.y > start) {
+                    mVerticalPatchesSum += rect.height;
+                    start = rect.y;
+                }
+            }
+        }
+    }
+
+    
+    private NinePatch(URL fileUrl, BufferedImage image) {
+        mFileUrl = fileUrl;
+        mImage = image;
+        
+        findPatches();
+    }
+    
+    private void findPatches() {
+        int width = mImage.getWidth();
+        int height = mImage.getHeight();
+
+        row = GraphicsUtilities.getPixels(mImage, 0, 0, width, 1, row);
+        column = GraphicsUtilities.getPixels(mImage, 0, 0, 1, height, column);
+
+        boolean[] result = new boolean[1];
+        Pair<List<Pair<Integer>>> left = getPatches(column, result);
+        mVerticalStartWithPatch = result[0];
+        
+        // compute the min size, based on the list of fixed sections, which is stored in 
+        // Pair.mFirst
+        mMinHeight = 0;
+        List<Pair<Integer>> fixedSections = left.mFirst;
+        for (Pair<Integer> section : fixedSections) {
+            mMinHeight += section.mSecond - section.mFirst;
+        }
+
+        result = new boolean[1];
+        Pair<List<Pair<Integer>>> top = getPatches(row, result);
+        mHorizontalStartWithPatch = result[0];
+
+        // compute the min size, based on the list of fixed sections, which is stored in 
+        // Pair.mFirst
+
+        mMinWidth = 0;
+        fixedSections = top.mFirst;
+        for (Pair<Integer> section : fixedSections) {
+            mMinWidth += section.mSecond - section.mFirst;
+        }
+
+        mFixed = getRectangles(left.mFirst, top.mFirst);
+        mPatches = getRectangles(left.mSecond, top.mSecond);
+
+        if (mFixed.size() > 0) {
+            mHorizontalPatches = getRectangles(left.mFirst, top.mSecond);
+            mVerticalPatches = getRectangles(left.mSecond, top.mFirst);
+        } else {
+            mHorizontalPatches = mVerticalPatches = new ArrayList<Rectangle>(0);
+        }
+
+        row = GraphicsUtilities.getPixels(mImage, 0, height - 1, width, 1, row);
+        column = GraphicsUtilities.getPixels(mImage, width - 1, 0, 1, height, column);
+
+        top = getPatches(row, result);
+        mHorizontalPadding = getPadding(top.mFirst);
+
+        left = getPatches(column, result);
+        mVerticalPadding = getPadding(left.mFirst);
+        
+        mHorizontalPatchesSum = 0;
+        if (mHorizontalPatches.size() > 0) {
+            int start = -1;
+            for (Rectangle rect : mHorizontalPatches) {
+                if (rect.x > start) {
+                    mHorizontalPatchesSum += rect.width;
+                    start = rect.x;
+                }
+            }
+        }
+
+        mVerticalPatchesSum = 0;
+        if (mVerticalPatches.size() > 0) {
+            int start = -1;
+            for (Rectangle rect : mVerticalPatches) {
+                if (rect.y > start) {
+                    mVerticalPatchesSum += rect.height;
+                    start = rect.y;
+                }
+            }
+        }
+
+    }
+    
+    private Pair<Integer> getPadding(List<Pair<Integer>> pairs) {
+        if (pairs.size() == 0) {
+            return new Pair<Integer>(0, 0);
+        } else if (pairs.size() == 1) {
+            if (pairs.get(0).mFirst == 1) {
+                return new Pair<Integer>(pairs.get(0).mSecond - pairs.get(0).mFirst, 0);
+            } else {
+                return new Pair<Integer>(0, pairs.get(0).mSecond - pairs.get(0).mFirst);
+            }
+        } else {
+            int index = pairs.size() - 1;
+            return new Pair<Integer>(pairs.get(0).mSecond - pairs.get(0).mFirst,
+                    pairs.get(index).mSecond - pairs.get(index).mFirst);
+        }
+    }
+    
+    private List<Rectangle> getRectangles(List<Pair<Integer>> leftPairs,
+            List<Pair<Integer>> topPairs) {
+        List<Rectangle> rectangles = new ArrayList<Rectangle>();
+        for (Pair<Integer> left : leftPairs) {
+            int y = left.mFirst;
+            int height = left.mSecond - left.mFirst;
+            for (Pair<Integer> top: topPairs) {
+                int x = top.mFirst;
+                int width = top.mSecond - top.mFirst;
+
+                rectangles.add(new Rectangle(x, y, width, height));
+            }
+        }
+        return rectangles;
+    }
+    
+    private Pair<List<Pair<Integer>>> getPatches(int[] pixels, boolean[] startWithPatch) {
+        int lastIndex = 1;
+        int lastPixel = pixels[1];
+        boolean first = true;
+
+        List<Pair<Integer>> fixed = new ArrayList<Pair<Integer>>();
+        List<Pair<Integer>> patches = new ArrayList<Pair<Integer>>();
+        
+        for (int i = 1; i < pixels.length - 1; i++) {
+            int pixel = pixels[i];
+            if (pixel != lastPixel) {
+                if (lastPixel == 0xFF000000) {
+                    if (first) startWithPatch[0] = true;
+                    patches.add(new Pair<Integer>(lastIndex, i));
+                } else {
+                    fixed.add(new Pair<Integer>(lastIndex, i));
+                }
+                first = false;
+
+                lastIndex = i;
+                lastPixel = pixel;
+            }
+        }
+        if (lastPixel == 0xFF000000) {
+            if (first) startWithPatch[0] = true;
+            patches.add(new Pair<Integer>(lastIndex, pixels.length - 1));
+        } else {
+            fixed.add(new Pair<Integer>(lastIndex, pixels.length - 1));
+        }
+
+        if (patches.size() == 0) {
+            patches.add(new Pair<Integer>(1, pixels.length - 1));
+            startWithPatch[0] = true;
+            fixed.clear();
+        }
+        return new Pair<List<Pair<Integer>>>(fixed, patches);
+    }
+
+    private static void ensure9Patch(BufferedImage image) {
+        int width = image.getWidth();
+        int height = image.getHeight();
+        for (int i = 0; i < width; i++) {
+            int pixel = image.getRGB(i, 0);
+            if (pixel != 0 && pixel != 0xFF000000) {
+                image.setRGB(i, 0, 0);
+            }
+            pixel = image.getRGB(i, height - 1);
+            if (pixel != 0 && pixel != 0xFF000000) {
+                image.setRGB(i, height - 1, 0);
+            }
+        }
+        for (int i = 0; i < height; i++) {
+            int pixel = image.getRGB(0, i);
+            if (pixel != 0 && pixel != 0xFF000000) {
+                image.setRGB(0, i, 0);
+            }
+            pixel = image.getRGB(width - 1, i);
+            if (pixel != 0 && pixel != 0xFF000000) {
+                image.setRGB(width - 1, i, 0);
+            }
+        }
+    }
+
+    private static BufferedImage convertTo9Patch(BufferedImage image) {
+        BufferedImage buffer = GraphicsUtilities.createTranslucentCompatibleImage(
+                image.getWidth() + 2, image.getHeight() + 2);
+
+        Graphics2D g2 = buffer.createGraphics();
+        g2.drawImage(image, 1, 1, null);
+        g2.dispose();
+
+        return buffer;
+    }
+    
+    static class Pair<E> {
+        E mFirst;
+        E mSecond;
+
+        Pair(E first, E second) {
+            mFirst = first;
+            mSecond = second;
+        }
+
+        @Override
+        public String toString() {
+            return "Pair[" + mFirst + ", " + mSecond + "]";
+        }
+    }
+}
diff --git a/tools/runtest b/tools/runtest
new file mode 100755
index 0000000..349b5a7
--- /dev/null
+++ b/tools/runtest
@@ -0,0 +1,360 @@
+#!/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  # AndroidTests com.android.unit_tests #"
+  "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/.classpath b/tools/screenshot/.classpath
new file mode 100644
index 0000000..b0326c8
--- /dev/null
+++ b/tools/screenshot/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/screenshot/.project b/tools/screenshot/.project
new file mode 100644
index 0000000..f5d3f51
--- /dev/null
+++ b/tools/screenshot/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>screenshot</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/screenshot/Android.mk b/tools/screenshot/Android.mk
new file mode 100644
index 0000000..7cf9090
--- /dev/null
+++ b/tools/screenshot/Android.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+SCREENSHOT2_LOCAL_DIR := $(call my-dir)
+include $(SCREENSHOT2_LOCAL_DIR)/etc/Android.mk
+include $(SCREENSHOT2_LOCAL_DIR)/src/Android.mk
diff --git a/tools/screenshot/etc/Android.mk b/tools/screenshot/etc/Android.mk
new file mode 100644
index 0000000..5107535
--- /dev/null
+++ b/tools/screenshot/etc/Android.mk
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_EXECUTABLES := screenshot2
+include $(BUILD_HOST_PREBUILT)
+
diff --git a/tools/screenshot/etc/manifest.txt b/tools/screenshot/etc/manifest.txt
new file mode 100644
index 0000000..f52874a
--- /dev/null
+++ b/tools/screenshot/etc/manifest.txt
@@ -0,0 +1 @@
+Main-Class: com.android.screenshot.Screenshot
diff --git a/tools/screenshot/etc/screenshot2 b/tools/screenshot/etc/screenshot2
new file mode 100755
index 0000000..10b921a
--- /dev/null
+++ b/tools/screenshot/etc/screenshot2
@@ -0,0 +1,74 @@
+#!/bin/sh
+# Copyright 2005-2007, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+    newProg=`/bin/ls -ld "${prog}"`
+    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+    if expr "x${newProg}" : 'x/' >/dev/null; then
+        prog="${newProg}"
+    else
+        progdir=`dirname "${prog}"`
+        prog="${progdir}/${newProg}"
+    fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+jarfile=screenshot2.jar
+frameworkdir="$progdir"
+libdir="$progdir"
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/tools/lib
+    libdir=`dirname "$progdir"`/tools/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/framework
+    libdir=`dirname "$progdir"`/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    echo `basename "$prog"`": can't find $jarfile"
+    exit 1
+fi
+
+
+# Check args.
+if [ debug = "$1" ]; then
+    # add this in for debugging
+    java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
+    shift 1
+else
+    java_debug=
+fi
+
+if [ "$OSTYPE" = "cygwin" ] ; then
+    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
+    progdir=`cygpath -w  "$progdir"`
+else
+    jarpath="$frameworkdir/$jarfile"
+fi
+
+# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
+# might need more memory, e.g. -Xmx128M
+exec java -Xmx128M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -Dcom.android.screenshot.bindir="$progdir" -jar "$jarpath" "$@"
diff --git a/tools/screenshot/src/Android.mk b/tools/screenshot/src/Android.mk
new file mode 100644
index 0000000..8b5ea3a
--- /dev/null
+++ b/tools/screenshot/src/Android.mk
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAR_MANIFEST := ../etc/manifest.txt
+LOCAL_JAVA_LIBRARIES := \
+	ddmlib
+LOCAL_MODULE := screenshot2
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/screenshot/src/com/android/screenshot/Screenshot.java b/tools/screenshot/src/com/android/screenshot/Screenshot.java
new file mode 100644
index 0000000..40ceffa
--- /dev/null
+++ b/tools/screenshot/src/com/android/screenshot/Screenshot.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.screenshot;
+
+import com.android.ddmlib.AndroidDebugBridge;
+import com.android.ddmlib.Device;
+import com.android.ddmlib.Log;
+import com.android.ddmlib.RawImage;
+import com.android.ddmlib.Log.ILogOutput;
+import com.android.ddmlib.Log.LogLevel;
+
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+/**
+ * Connects to a device using ddmlib and dumps its event log as long as the device is connected. 
+ */
+public class Screenshot {
+
+    public static void main(String[] args) {
+        boolean device = false;
+        boolean emulator = false;
+        String serial = null;
+        String filepath = null;
+        boolean landscape = false;
+        
+        if (args.length == 0) {
+            printUsageAndQuit();
+        }
+
+        // parse command line parameters.
+        int index = 0;
+        do {
+            String argument = args[index++];
+
+            if ("-d".equals(argument)) {
+                if (emulator || serial != null) {
+                    printAndExit("-d conflicts with -e and -s", false /* terminate */);
+                }
+                device = true;
+            } else if ("-e".equals(argument)) {
+                if (device || serial != null) {
+                    printAndExit("-e conflicts with -d and -s", false /* terminate */);
+                }
+                emulator = true;
+            } else if ("-s".equals(argument)) {
+                // quick check on the next argument.
+                if (index == args.length) {
+                    printAndExit("Missing serial number after -s", false /* terminate */);
+                }
+
+                if (device || emulator) {
+                    printAndExit("-s conflicts with -d and -e", false /* terminate */);
+                }
+                
+                serial = args[index++];
+            } else if ("-l".equals(argument)) {
+                landscape = true;
+            } else {
+                // get the filepath and break.
+                filepath = argument;
+
+                // should not be any other device.
+                if (index < args.length) {
+                    printAndExit("Too many arguments!", false /* terminate */);
+                }
+            }
+        } while (index < args.length);
+        
+        if (filepath == null) {
+            printUsageAndQuit();
+        }
+        
+        Log.setLogOutput(new ILogOutput() {
+            public void printAndPromptLog(LogLevel logLevel, String tag, String message) {
+                System.err.println(logLevel.getStringValue() + ":" + tag + ":" + message);
+            }
+
+            public void printLog(LogLevel logLevel, String tag, String message) {
+                System.err.println(logLevel.getStringValue() + ":" + tag + ":" + message);
+            }
+        });
+        
+        // init the lib
+        // [try to] ensure ADB is running
+        String adbLocation = System.getProperty("com.android.screenshot.bindir"); //$NON-NLS-1$
+        if (adbLocation != null && adbLocation.length() != 0) {
+            adbLocation += File.separator + "adb"; //$NON-NLS-1$
+        } else {
+            adbLocation = "adb"; //$NON-NLS-1$
+        }
+
+        AndroidDebugBridge.init(false /* debugger support */);
+        
+        try {
+            AndroidDebugBridge bridge = AndroidDebugBridge.createBridge(
+                    adbLocation, true /* forceNewBridge */);
+            
+            // we can't just ask for the device list right away, as the internal thread getting
+            // them from ADB may not be done getting the first list.
+            // Since we don't really want getDevices() to be blocking, we wait here manually.
+            int count = 0;
+            while (bridge.hasInitialDeviceList() == false) {
+                try {
+                    Thread.sleep(100);
+                    count++;
+                } catch (InterruptedException e) {
+                    // pass
+                }
+                
+                // let's not wait > 10 sec.
+                if (count > 100) {
+                    System.err.println("Timeout getting device list!");
+                    return;
+                }
+            }
+
+            // now get the devices
+            Device[] devices = bridge.getDevices();
+            
+            if (devices.length == 0) {
+                printAndExit("No devices found!", true /* terminate */);
+            }
+            
+            Device target = null;
+            
+            if (emulator || device) {
+                for (Device d : devices) {
+                    // this test works because emulator and device can't both be true at the same
+                    // time.
+                    if (d.isEmulator() == emulator) {
+                        // if we already found a valid target, we print an error and return.
+                        if (target != null) {
+                            if (emulator) {
+                                printAndExit("Error: more than one emulator launched!",
+                                        true /* terminate */);
+                            } else {
+                                printAndExit("Error: more than one device connected!",true /* terminate */);
+                            }
+                        }
+                        target = d;
+                    }
+                }
+            } else if (serial != null) {
+                for (Device d : devices) {
+                    if (serial.equals(d.getSerialNumber())) {
+                        target = d;
+                        break;
+                    }
+                }
+            } else {
+                if (devices.length > 1) {
+                    printAndExit("Error: more than one emulator or device available!",
+                            true /* terminate */);
+                }
+                target = devices[0];
+            }
+            
+            if (target != null) {
+                try {
+                    System.out.println("Taking screenshot from: " + target.getSerialNumber());
+                    getDeviceImage(target, filepath, landscape);
+                    System.out.println("Success.");
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            } else {
+                printAndExit("Could not find matching device/emulator.", true /* terminate */);
+            }
+        } finally {
+            AndroidDebugBridge.terminate();
+        }
+    }
+    
+    /*
+     * Grab an image from an ADB-connected device.
+     */
+    private static void getDeviceImage(Device device, String filepath, boolean landscape)
+            throws IOException {
+        RawImage rawImage;
+
+        try {
+            rawImage = device.getScreenshot();
+        }
+        catch (IOException ioe) {
+            printAndExit("Unable to get frame buffer: " + ioe.getMessage(), true /* terminate */);
+            return;
+        }
+
+        // device/adb not available?
+        if (rawImage == null)
+            return;
+
+        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);
+                }
+            }
+        } else {
+            // 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");
+        System.out.println("");
+        System.out.println("    -d      Uses the first device found.");
+        System.out.println("    -e      Uses the first emulator found.");
+        System.out.println("    -s      Targets the device by serial number.");
+        System.out.println("");
+        System.out.println("    -l      Rotate images for landscape mode.");
+        System.out.println("");
+        
+        System.exit(1);
+    }
+    
+    private static void printAndExit(String message, boolean terminate) {
+        System.out.println(message);
+        if (terminate) {
+            AndroidDebugBridge.terminate();
+        }
+        System.exit(1);
+    }
+}
diff --git a/tools/scripts/AndroidManifest.alias.template b/tools/scripts/AndroidManifest.alias.template
new file mode 100644
index 0000000..b1be4c8
--- /dev/null
+++ b/tools/scripts/AndroidManifest.alias.template
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="PACKAGE"
+      android:versionCode="1"
+      android:versionName="1.0">
+    <application android:hasCode="false">
+        <activity android:name="android.app.AliasActivity" android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <meta-data android:name="android.app.alias" android:resource="@xml/alias" />
+        </activity>
+    </application>
+</manifest> 
diff --git a/tools/scripts/AndroidManifest.template b/tools/scripts/AndroidManifest.template
new file mode 100644
index 0000000..2b06e76
--- /dev/null
+++ b/tools/scripts/AndroidManifest.template
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="PACKAGE"
+      android:versionCode="1"
+      android:versionName="1.0">
+    <application android:label="@string/app_name">
+        <activity android:name=".ACTIVITY_NAME"
+                  android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest> 
diff --git a/tools/scripts/AndroidManifest.tests.template b/tools/scripts/AndroidManifest.tests.template
new file mode 100644
index 0000000..1f7d827
--- /dev/null
+++ b/tools/scripts/AndroidManifest.tests.template
@@ -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="PACKAGE.tests"
+          android:versionCode="1"
+          android:versionName="1.0">
+    <!-- We add an application tag here just so that we can indicate that
+         this package needs to link against the android.test library,
+         which is needed when building test cases. -->
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+    <!--
+    This declares that this application uses the instrumentation test runner targeting
+    the package of PACKAGE.  To run the tests use the command:
+    "adb shell am instrument -w PACKAGE.tests/android.test.InstrumentationTestRunner"
+    -->
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="PACKAGE"
+                     android:label="Tests for ACTIVITY_NAME"/>
+</manifest>
diff --git a/tools/scripts/README_add-ons.txt b/tools/scripts/README_add-ons.txt
new file mode 100644
index 0000000..b8eb1d6
--- /dev/null
+++ b/tools/scripts/README_add-ons.txt
@@ -0,0 +1,2 @@
+Add-on folder.
+Drop vendor supplied SDK add-on in this folder.
\ No newline at end of file
diff --git a/tools/scripts/add-accounts b/tools/scripts/add-accounts
new file mode 100755
index 0000000..d2cddc0
--- /dev/null
+++ b/tools/scripts/add-accounts
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+A faux Setup Wizard.  Stuffs one or two usernames + passwords into the
+database on the device.
+"""
+
+import sys
+if sys.hexversion < 0x02040000:
+  print "This script requires python 2.4 or higher."
+  sys.exit(1)
+
+import getpass
+import subprocess
+import time
+import sha
+
+DB = "/data/data/com.google.android.googleapps/databases/accounts.db"
+
+def RunCmd(args):
+  proc = subprocess.Popen(args, stdout=subprocess.PIPE)
+  out = proc.stdout.read()
+  if proc.wait():
+    print
+    print "failed: %s" % " ".join(args)
+    return None
+  return out
+
+def GetProp(adb_flags, name):
+  args = ("adb",) + adb_flags + ("shell", "su", "root",
+                                 "/system/bin/getprop", name)
+  return RunCmd(args)
+
+def SetProp(adb_flags, name, value):
+  args = ("adb",) + adb_flags + ("shell", "su", "root",
+                                 "/system/bin/setprop", name, value)
+  return RunCmd(args)
+
+def DbExists(adb_flags):
+  args = ("adb",) + adb_flags + ("shell", "su", "root",
+                                 "/system/bin/ls", DB)
+  result = RunCmd(args)
+  if result is None: return None
+  return "No such file" not in result
+
+def main(argv):
+  if len(argv) == 1:
+    print ("usage: %s [adb flags] "
+           "[<dasher address[:password]>] "
+           "[<gmail address[:password]>]") % (argv[0],)
+    sys.exit(2)
+
+  argv = argv[1:]
+
+  gmail = None
+  dasher = None
+  while argv and "@" in argv[-1]:
+    addr = argv.pop()
+    if "@gmail.com" in addr or "@googlemail.com" in addr:
+      gmail = addr
+    else:
+      dasher = addr
+
+  adb_flags = tuple(argv)
+
+  while True:
+    db = DbExists(adb_flags)
+    if db is None:
+      print "failed to contact device; will retry in 3 seconds"
+      time.sleep(3)
+      continue
+
+    if db:
+      print
+      print "GoogleLoginService has already started on this device;"
+      print "it's too late to use this script to add accounts."
+      print
+      print "This script only works on a freshly-wiped device (or "
+      print "emulator) while booting for the first time."
+      print
+      break
+
+    hosted_account = GetProp(adb_flags, "ro.config.hosted_account").strip()
+    google_account = GetProp(adb_flags, "ro.config.google_account").strip()
+
+    if dasher and hosted_account:
+      print
+      print "A dasher account is already configured on this device;"
+      print "can't add", hosted_account
+      print
+      dasher = None
+
+    if gmail and google_account:
+      print
+      print "A google account is already configured on this device;"
+      print "can't add", google_account
+      print
+      gmail = None
+
+    if not gmail and not dasher: break
+
+    if dasher:
+      SetProp(adb_flags, "ro.config.hosted_account", dasher)
+      print "set hosted_account to", dasher
+    if gmail:
+      SetProp(adb_flags, "ro.config.google_account", gmail)
+      print "set google_account to", gmail
+
+    break
+
+
+
+
+
+
+if __name__ == "__main__":
+  main(sys.argv)
diff --git a/tools/scripts/add-accounts-sdk b/tools/scripts/add-accounts-sdk
new file mode 100755
index 0000000..bb3447f
--- /dev/null
+++ b/tools/scripts/add-accounts-sdk
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+A faux Setup Wizard.  Stuffs one or two usernames + passwords into the
+database on the device.
+"""
+
+import sys
+if sys.hexversion < 0x02040000:
+  print "This script requires python 2.4 or higher."
+  sys.exit(1)
+
+import getpass
+import subprocess
+import time
+import sha
+
+DB = "/data/data/com.google.android.googleapps/databases/accounts.db"
+
+def RunCmd(args):
+  proc = subprocess.Popen(args, stdout=subprocess.PIPE)
+  out = proc.stdout.read()
+  if proc.wait():
+    print
+    print "failed: %s" % " ".join(args)
+    return None
+  return out
+
+def GetProp(adb_flags, name):
+  args = ("adb",) + adb_flags + ("shell", "/system/bin/getprop", name)
+  return RunCmd(args)
+
+def SetProp(adb_flags, name, value):
+  args = ("adb",) + adb_flags + ("shell", "/system/bin/setprop", name, value)
+  return RunCmd(args)
+
+def DbExists(adb_flags):
+  args = ("adb",) + adb_flags + ("shell", "/system/bin/ls", DB)
+  result = RunCmd(args)
+  if result is None: return None
+  return "No such file" not in result
+
+def main(argv):
+  if len(argv) == 1:
+    print ("usage: %s [adb flags] "
+           "[<hosted address[:password]>] "
+           "[<gmail address[:password]>]") % (argv[0],)
+    sys.exit(2)
+
+  argv = argv[1:]
+
+  gmail = None
+  hosted = None
+  while argv and "@" in argv[-1]:
+    addr = argv.pop()
+    if "@gmail.com" in addr or "@googlemail.com" in addr:
+      gmail = addr
+    else:
+      hosted = addr
+
+  adb_flags = tuple(argv)
+
+  while True:
+    db = DbExists(adb_flags)
+    if db is None:
+      print "failed to contact device; will retry in 3 seconds"
+      time.sleep(3)
+      continue
+
+    if db:
+      print
+      print "GoogleLoginService has already started on this device;"
+      print "it's too late to use this script to add accounts."
+      print
+      print "This script only works on a freshly-wiped device (or "
+      print "emulator) while booting for the first time."
+      print
+      break
+
+    hosted_account = GetProp(adb_flags, "ro.config.hosted_account").strip()
+    google_account = GetProp(adb_flags, "ro.config.google_account").strip()
+
+    if hosted and hosted_account:
+      print
+      print "A hosted account is already configured on this device;"
+      print "can't add", hosted_account
+      print
+      hosted = None
+
+    if gmail and google_account:
+      print
+      print "A google account is already configured on this device;"
+      print "can't add", google_account
+      print
+      gmail = None
+
+    if not gmail and not hosted: break
+
+    if hosted:
+      SetProp(adb_flags, "ro.config.hosted_account", hosted)
+      print "set hosted_account to", hosted
+    if gmail:
+      SetProp(adb_flags, "ro.config.google_account", gmail)
+      print "set google_account to", gmail
+
+    break
+
+
+
+
+
+
+if __name__ == "__main__":
+  main(sys.argv)
diff --git a/tools/scripts/alias.template b/tools/scripts/alias.template
new file mode 100644
index 0000000..8be355b
--- /dev/null
+++ b/tools/scripts/alias.template
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<alias xmlns:android="http://schemas.android.com/apk/res/android">
+    <intent android:action="android.intent.action.VIEW"
+        android:data="ALIASDATA"/>
+</alias>
\ No newline at end of file
diff --git a/tools/scripts/alias_rules.xml b/tools/scripts/alias_rules.xml
new file mode 100644
index 0000000..bc7de7c
--- /dev/null
+++ b/tools/scripts/alias_rules.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="alias_rules" default="package">
+
+    <!-- No user servicable parts below. -->
+
+    <!-- Input directories -->
+    <property name="resource-dir" value="res" />
+
+    <!-- The final package file to generate -->
+    <property name="out-package" value="${ant.project.name}.apk" />
+
+    <!-- Tools -->
+    <condition property="aapt" value="${android-tools}/aapt.exe" else="${android-tools}/aapt" >
+        <os family="windows"/>
+    </condition>
+    <condition property="adb" value="${android-tools}/adb.exe" else="${android-tools}/adb" >
+        <os family="windows"/>
+    </condition>
+    <property name="android-jar" value="${sdk-folder}/android.jar" />
+
+    <!-- Rules -->
+
+    <!-- Packages the manifest and the resource files -->
+    <target name="package-res">
+        <echo>Packaging resources...</echo>
+        <exec executable="${aapt}" failonerror="true">
+            <arg value="package" />
+            <arg value="-f" />
+            <arg value="-M" />
+            <arg value="AndroidManifest.xml" />
+            <arg value="-S" />
+            <arg value="${resource-dir}" />
+            <arg value="-I" />
+            <arg value="${android-jar}" />
+            <arg value="-F" />
+            <arg value="${out-package}" />
+        </exec>
+    </target>
+
+    <!-- Create the package file for this project from the sources. -->
+    <target name="package" depends="package-res" />
+
+    <!-- Create the package and install package on the default emulator -->
+    <target name="install" depends="package">
+        <echo>Sending package to default emulator...</echo>
+        <exec executable="${adb}" failonerror="true">
+            <arg value="install" />
+            <arg value="${out-package}" />
+        </exec>
+    </target>
+
+</project>
diff --git a/tools/scripts/android.el b/tools/scripts/android.el
new file mode 100644
index 0000000..49f2f1e
--- /dev/null
+++ b/tools/scripts/android.el
@@ -0,0 +1,131 @@
+;;;; Copyright 2007 The Android Open Source Project
+
+;;; Set up GUD+JDB to attach to a Java process running on the phone or
+;;; under the emulator.
+
+(defvar android-jdb-port-history '("8700")
+ "history of ports supplied to `android-jdb'")
+
+(defvar android-jdb-project-root-history '()
+ "history of project roots supplied to `android-jdb'")
+(defvar android-jdb-history nil
+ "history of commands supplied to `android-jdb'")
+
+(defvar android-jdb-activity-class-history ()
+ "history of activity classes supplied to `start-android-activity'")
+
+(defcustom  android-jdb-command-name "jdb"
+  "Name of Java debugger."
+  :type 'string
+  :group 'android)
+
+(defgroup android nil
+  "Android Applications."
+  :group 'applications)
+
+(defcustom android-project-root nil
+ "This is where your Android project root is stored."
+  :type 'directory
+ :group 'android )
+
+(defcustom android-apk nil
+ "This is where your Android Application Package is stored."
+ :type 'string
+ :group 'android)
+
+(defcustom android-activity-class nil
+ "This is where your Android Activity class is stored."
+ :type 'string
+ :group 'android)
+
+(defun android-read-project-root ()
+ (if (or (string-match "XEmacs" emacs-version)
+         (>= emacs-major-version 22))
+     (read-file-name "Android project root: "
+                     android-project-root
+                     nil
+                     t
+                     nil
+                     'file-directory-p)
+   (labels ((read-directory ()
+                            (read-file-name "Android project root: "
+                                            android-project-root
+                                            nil
+                                            t
+                                            nil)))
+     (do ((entered-root (read-directory) (read-directory)))
+         ((and entered-root
+               (file-directory-p entered-root))
+          (expand-file-name entered-root))))))
+
+(defun android-jdb (port root)
+ "Set GUD+JDB up to run against Android on PORT in directory ROOT."
+ (interactive
+  (list
+   (read-from-minibuffer "Activity's JDWP DDMS port: "
+                     (car android-jdb-port-history)
+                     nil
+                     t
+                     'android-jdb-port-history)
+                    (android-read-project-root)))
+ (setq android-project-root root)
+ (let ((jdb-command
+        (format "%s -attach localhost:%s -sourcepath%s"
+                android-jdb-command-name
+                port
+                (format "%s/src" root))))
+   (if (not (string= jdb-command (car android-jdb-history)))
+       (push jdb-command android-jdb-history))
+   (jdb jdb-command)))
+
+(defun android-emulate ()
+ "Run the Android emulator. This expects the SDK tools directory to be in the current path."
+ (interactive)
+ (compile "emulator"))
+
+(defun android-install-app (apk)
+  "Install an Android application package APK in the Android emulator. This expects the SDK tools directory to be in the current path."
+  (interactive (list (expand-file-name
+                      (read-file-name "Android Application Package (.apk): "
+                                      nil
+                                      android-apk
+                                      t
+                                      nil
+                                      nil))))
+  (setq android-apk apk)
+  (compile (format "adb install -r %s" apk)))
+
+(defun android-uninstall-app (package-name)
+  "Uninstall an Android application package APK in the Android emulator. This expects the SDK tools directory to be in the current path.
+Specify the package name --- and not the name of the application e.g., com.android.foo."
+  (interactive
+   (list
+    (read-from-minibuffer "Package: ")))
+  (compile (format "adb install -r %s" package)))
+
+(defun android-start-activity (package class)
+ "Start the activity PACKAGE/CLASS in the Android emulator. This expects the SDK tools directory to be in the current path."
+ (interactive
+  (list
+   (read-from-minibuffer "Package: ")
+   (read-from-minibuffer "Activity Java class: "
+         (car android-jdb-activity-class-history)
+         nil
+         t
+         'android-jdb-activity-class-history)))
+ (compile (format "adb shell am start -n %s/%s" package class)))
+
+(defun android-debug-activity (package class)
+ "Start the activity PACKAGE/CLASS within the debugger in the Android emulator. This expects the SDK tools directory to be in the current path."
+ (interactive
+  (list
+   (read-from-minibuffer "Package: ")
+   (read-from-minibuffer "Activity Java class: "
+         (car android-jdb-activity-class-history)
+         nil
+         t
+         'android-jdb-activity-class-history)))
+ (compile (format "adb shell am start -D -n %s/%s" package class)))
+
+(provide 'android)
+
diff --git a/tools/scripts/android_rules.xml b/tools/scripts/android_rules.xml
new file mode 100644
index 0000000..799aa0b
--- /dev/null
+++ b/tools/scripts/android_rules.xml
@@ -0,0 +1,225 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="android_rules" default="debug">
+
+    <!--
+        This rules file is meant to be imported by the custom Ant task:
+            com.android.ant.AndroidInitTask
+
+        The following properties are put in place by the importing task:
+            android-jar, android-aidl, aapt, aidl, and dx
+
+        Additionnaly, the task sets up the following classpath reference:
+            android.target.classpath
+        This is used by the compiler task as the boot classpath.
+    -->
+
+    <!-- Custom tasks -->
+    <taskdef name="aaptexec"
+        classname="com.android.ant.AaptExecLoopTask"
+        classpathref="android.antlibs"/>
+
+    <taskdef name="apkbuilder"
+        classname="com.android.ant.ApkBuilderTask"
+        classpathref="android.antlibs"/>
+
+    <!-- Properties -->
+
+    <property name="android-tools" value="${sdk-location}/tools" />
+
+    <!-- Input directories -->
+    <property name="source-folder" value="src" />
+    <property name="resource-folder" value="res" />
+    <property name="asset-folder" value="assets" />
+    <property name="source-location" value="${basedir}/${source-folder}" />
+
+    <!-- folder for the 3rd party java libraries -->
+    <property name="external-libs-folder" value="libs" />
+
+    <!-- folder for the native libraries -->
+    <property name="native-libs-folder" value="libs" />
+
+    <!-- Output directories -->
+    <property name="out-folder" value="bin" />
+    <property name="out-classes" value="${out-folder}/classes" />
+    <property name="out-classes-location" value="${basedir}/${out-classes}"/>
+    <!-- out folders for a parent project if this project is an instrumentation project -->
+    <property name="main-out-folder" value="../${out-folder}" />
+    <property name="main-out-classes" value="${main-out-folder}/classes"/>
+
+    <!-- Create R.java in the source directory -->
+    <property name="r-folder" value="${source-folder}" />
+
+    <!-- Intermediate files -->
+    <property name="dex-file" value="classes.dex" />
+    <property name="intermediate-dex" value="${out-folder}/${dex-file}" />
+    <!-- dx does not properly support incorrect / or \ based on the platform
+         and Ant cannot convert them because the parameter is not a valid path.
+         Because of this we have to compute different paths depending on the platform. -->
+    <condition property="intermediate-dex-location"
+            value="${basedir}\${intermediate-dex}"
+            else="${basedir}/${intermediate-dex}" >
+        <os family="windows"/>
+    </condition>
+
+    <!-- The final package file to generate -->
+    <property name="out-debug-package" value="${out-folder}/${ant.project.name}-debug.apk"/>
+
+    <!-- Tools -->
+    <condition property="exe" value="exe" else=""><os family="windows"/></condition>
+    <property name="adb" value="${android-tools}/adb${exe}"/>
+
+    <!-- rules -->
+
+    <!-- Create the output directories if they don't exist yet. -->
+    <target name="dirs">
+        <echo>Creating output directories if needed...</echo>
+        <mkdir dir="${out-folder}" />
+        <mkdir dir="${out-classes}" />
+    </target>
+
+    <!-- Generate the R.java file for this project's resources. -->
+    <target name="resource-src" depends="dirs">
+        <echo>Generating R.java / Manifest.java from the resources...</echo>
+        <exec executable="${aapt}" failonerror="true">
+            <arg value="package" />
+            <arg value="-m" />
+            <arg value="-J" />
+            <arg path="${r-folder}" />
+            <arg value="-M" />
+            <arg path="AndroidManifest.xml" />
+            <arg value="-S" />
+            <arg path="${resource-folder}" />
+            <arg value="-I" />
+            <arg path="${android-jar}" />
+        </exec>
+    </target>
+
+    <!-- Generate java classes from .aidl files. -->
+    <target name="aidl" depends="dirs">
+        <echo>Compiling aidl files into Java classes...</echo>
+        <apply executable="${aidl}" failonerror="true">
+            <arg value="-p${android-aidl}" />
+            <arg value="-I${source-folder}" />
+            <fileset dir="${source-folder}">
+                <include name="**/*.aidl"/>
+            </fileset>
+        </apply>
+    </target>
+
+    <!-- Compile this project's .java files into .class files. -->
+    <target name="compile" depends="dirs, resource-src, aidl">
+        <javac encoding="ascii" target="1.5" debug="true" extdirs=""
+                srcdir="${source-folder}"
+                destdir="${out-classes}"
+                bootclasspathref="android.target.classpath">
+            <classpath>
+                <fileset dir="${external-libs-folder}" includes="*.jar"/>
+                <pathelement path="${main-out-classes}"/>
+            </classpath>
+         </javac>
+    </target>
+
+    <!-- Convert this project's .class files into .dex files. -->
+    <target name="dex" depends="compile">
+        <echo>Converting compiled files and external libraries into ${out-folder}/${dex-file}...</echo>
+        <apply executable="${dx}" failonerror="true" parallel="true">
+            <arg value="--dex" />
+            <arg value="--output=${intermediate-dex-location}" />
+            <arg path="${out-classes-location}" />
+            <fileset dir="${external-libs-folder}" includes="*.jar"/>
+        </apply>
+    </target>
+
+    <!-- Put the project's resources into the output package file
+         This actually can create multiple resource package in case
+         Some custom apk with specific configuration have been
+         declared in default.properties.
+         -->
+    <target name="package-resources">
+        <echo>Packaging resources</echo>
+        <aaptexec executable="${aapt}"
+                command="package"
+                manifest="AndroidManifest.xml"
+                resources="${resource-folder}"
+                assets="${asset-folder}"
+                androidjar="${android-jar}"
+                outfolder="${out-folder}"
+                basename="${ant.project.name}" />
+    </target>
+
+    <!-- Package the application and sign it with a debug key.
+         This is the default target when building. It is used for debug. -->
+    <target name="debug" depends="dex, package-resources">
+        <apkbuilder
+                outfolder="${out-folder}"
+                basename="${ant.project.name}"
+                signed="true"
+                verbose="false">
+            <file path="${intermediate-dex}" />
+            <sourcefolder path="${source-folder}" />
+            <jarfolder path="${external-libs-folder}" />
+            <nativefolder path="${native-libs-folder}" />
+        </apkbuilder>
+    </target>
+
+    <!-- Package the application without signing it.
+         This allows for the application to be signed later with an official publishing key. -->
+    <target name="release" depends="dex, package-resources">
+        <apkbuilder
+                outfolder="${out-folder}"
+                basename="${ant.project.name}"
+                signed="false"
+                verbose="false">
+            <file path="${intermediate-dex}" />
+            <sourcefolder path="${source-folder}" />
+            <jarfolder path="${external-libs-folder}" />
+            <nativefolder path="${native-libs-folder}" />
+        </apkbuilder>
+        <echo>All generated packages need to be signed with jarsigner before they are published.</echo>
+    </target>
+
+    <!-- Install the package on the default emulator -->
+    <target name="install" depends="debug">
+        <echo>Installing ${out-debug-package} onto default emulator...</echo>
+        <exec executable="${adb}" failonerror="true">
+            <arg value="install" />
+            <arg path="${out-debug-package}" />
+        </exec>
+    </target>
+
+    <target name="reinstall" depends="debug">
+        <echo>Installing ${out-debug-package} onto default emulator...</echo>
+        <exec executable="${adb}" failonerror="true">
+            <arg value="install" />
+            <arg value="-r" />
+            <arg path="${out-debug-package}" />
+        </exec>
+    </target>
+
+    <!-- Uinstall the package from the default emulator -->
+    <target name="uninstall">
+        <echo>Uninstalling ${application-package} from the default emulator...</echo>
+        <exec executable="${adb}" failonerror="true">
+            <arg value="uninstall" />
+            <arg path="${application-package}" />
+        </exec>
+    </target>
+    
+    <target name="help">
+        <!-- displays starts at col 13
+              |13                                                              80| -->
+        <echo>Android Ant Build. Available targets:</echo>
+        <echo>   help:      Displays this help.</echo>
+        <echo>   debug:     Builds the application and sign it with a debug key.</echo>
+        <echo>   release:   Builds the application. The generated apk file must be</echo>
+        <echo>              signed before it is published.</echo>
+        <echo>   install:   Installs the debug package onto a running emulator or</echo>
+        <echo>              device. This can only be used if the application has </echo>
+        <echo>              not yet been installed.</echo>
+        <echo>   reinstall: Installs the debug package on a running emulator or</echo>
+        <echo>              device that already has the application.</echo>
+        <echo>              The signatures must match.</echo>
+        <echo>   uninstall: uninstall the application from a running emulator or</echo>
+        <echo>              device.</echo>
+    </target>
+</project>
diff --git a/tools/scripts/app_engine_server/LICENSE b/tools/scripts/app_engine_server/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/tools/scripts/app_engine_server/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/tools/scripts/app_engine_server/app.yaml b/tools/scripts/app_engine_server/app.yaml
new file mode 100755
index 0000000..1fb50c7
--- /dev/null
+++ b/tools/scripts/app_engine_server/app.yaml
@@ -0,0 +1,16 @@
+application: androidappdocs-staging
+version: 1
+runtime: python
+api_version: 1
+
+handlers:
+- url: /gae_shell/static
+  static_dir: gae_shell/static
+  expiration: 1d
+
+- url: /gae_shell/.*
+  script: /gae_shell/shell.py
+  login: admin
+
+- url: .*
+  script: main.py
diff --git a/tools/scripts/app_engine_server/gae_shell/README b/tools/scripts/app_engine_server/gae_shell/README
new file mode 100644
index 0000000..5b0089f
--- /dev/null
+++ b/tools/scripts/app_engine_server/gae_shell/README
@@ -0,0 +1,17 @@
+An interactive, stateful AJAX shell that runs Python code on the server.
+
+Part of http://code.google.com/p/google-app-engine-samples/.
+
+May be run as a standalone app or in an existing app as an admin-only handler.
+Can be used for system administration tasks, as an interactive way to try out
+APIs, or as a debugging aid during development.
+
+The logging, os, sys, db, and users modules are imported automatically.
+
+Interpreter state is stored in the datastore so that variables, function
+definitions, and other values in the global and local namespaces can be used
+across commands.
+
+To use the shell in your app, copy shell.py, static/*, and templates/* into
+your app's source directory. Then, copy the URL handlers from app.yaml into
+your app.yaml.
diff --git a/tools/scripts/app_engine_server/gae_shell/__init__.py b/tools/scripts/app_engine_server/gae_shell/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/scripts/app_engine_server/gae_shell/__init__.py
diff --git a/tools/scripts/app_engine_server/gae_shell/__init__.pyc b/tools/scripts/app_engine_server/gae_shell/__init__.pyc
new file mode 100644
index 0000000..84951e9
--- /dev/null
+++ b/tools/scripts/app_engine_server/gae_shell/__init__.pyc
Binary files differ
diff --git a/tools/scripts/app_engine_server/gae_shell/shell.py b/tools/scripts/app_engine_server/gae_shell/shell.py
new file mode 100755
index 0000000..df2fb17
--- /dev/null
+++ b/tools/scripts/app_engine_server/gae_shell/shell.py
@@ -0,0 +1,308 @@
+#!/usr/bin/python
+#
+# Copyright 2007 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+An interactive, stateful AJAX shell that runs Python code on the server.
+
+Part of http://code.google.com/p/google-app-engine-samples/.
+
+May be run as a standalone app or in an existing app as an admin-only handler.
+Can be used for system administration tasks, as an interactive way to try out
+APIs, or as a debugging aid during development.
+
+The logging, os, sys, db, and users modules are imported automatically.
+
+Interpreter state is stored in the datastore so that variables, function
+definitions, and other values in the global and local namespaces can be used
+across commands.
+
+To use the shell in your app, copy shell.py, static/*, and templates/* into
+your app's source directory. Then, copy the URL handlers from app.yaml into
+your app.yaml.
+
+TODO: unit tests!
+"""
+
+import logging
+import new
+import os
+import pickle
+import sys
+import traceback
+import types
+import wsgiref.handlers
+
+from google.appengine.api import users
+from google.appengine.ext import db
+from google.appengine.ext import webapp
+from google.appengine.ext.webapp import template
+
+
+# Set to True if stack traces should be shown in the browser, etc.
+_DEBUG = True
+
+# The entity kind for shell sessions. Feel free to rename to suit your app.
+_SESSION_KIND = '_Shell_Session'
+
+# Types that can't be pickled.
+UNPICKLABLE_TYPES = (
+  types.ModuleType,
+  types.TypeType,
+  types.ClassType,
+  types.FunctionType,
+  )
+
+# Unpicklable statements to seed new sessions with.
+INITIAL_UNPICKLABLES = [
+  'import logging',
+  'import os',
+  'import sys',
+  'from google.appengine.ext import db',
+  'from google.appengine.api import users',
+  ]
+
+
+class Session(db.Model):
+  """A shell session. Stores the session's globals.
+
+  Each session globals is stored in one of two places:
+
+  If the global is picklable, it's stored in the parallel globals and
+  global_names list properties. (They're parallel lists to work around the
+  unfortunate fact that the datastore can't store dictionaries natively.)
+
+  If the global is not picklable (e.g. modules, classes, and functions), or if
+  it was created by the same statement that created an unpicklable global,
+  it's not stored directly. Instead, the statement is stored in the
+  unpicklables list property. On each request, before executing the current
+  statement, the unpicklable statements are evaluated to recreate the
+  unpicklable globals.
+
+  The unpicklable_names property stores all of the names of globals that were
+  added by unpicklable statements. When we pickle and store the globals after
+  executing a statement, we skip the ones in unpicklable_names.
+
+  Using Text instead of string is an optimization. We don't query on any of
+  these properties, so they don't need to be indexed.
+  """
+  global_names = db.ListProperty(db.Text)
+  globals = db.ListProperty(db.Blob)
+  unpicklable_names = db.ListProperty(db.Text)
+  unpicklables = db.ListProperty(db.Text)
+
+  def set_global(self, name, value):
+    """Adds a global, or updates it if it already exists.
+
+    Also removes the global from the list of unpicklable names.
+
+    Args:
+      name: the name of the global to remove
+      value: any picklable value
+    """
+    blob = db.Blob(pickle.dumps(value))
+
+    if name in self.global_names:
+      index = self.global_names.index(name)
+      self.globals[index] = blob
+    else:
+      self.global_names.append(db.Text(name))
+      self.globals.append(blob)
+
+    self.remove_unpicklable_name(name)
+
+  def remove_global(self, name):
+    """Removes a global, if it exists.
+
+    Args:
+      name: string, the name of the global to remove
+    """
+    if name in self.global_names:
+      index = self.global_names.index(name)
+      del self.global_names[index]
+      del self.globals[index]
+
+  def globals_dict(self):
+    """Returns a dictionary view of the globals.
+    """
+    return dict((name, pickle.loads(val))
+                for name, val in zip(self.global_names, self.globals))
+
+  def add_unpicklable(self, statement, names):
+    """Adds a statement and list of names to the unpicklables.
+
+    Also removes the names from the globals.
+
+    Args:
+      statement: string, the statement that created new unpicklable global(s).
+      names: list of strings; the names of the globals created by the statement.
+    """
+    self.unpicklables.append(db.Text(statement))
+
+    for name in names:
+      self.remove_global(name)
+      if name not in self.unpicklable_names:
+        self.unpicklable_names.append(db.Text(name))
+
+  def remove_unpicklable_name(self, name):
+    """Removes a name from the list of unpicklable names, if it exists.
+
+    Args:
+      name: string, the name of the unpicklable global to remove
+    """
+    if name in self.unpicklable_names:
+      self.unpicklable_names.remove(name)
+
+
+class FrontPageHandler(webapp.RequestHandler):
+  """Creates a new session and renders the shell.html template.
+  """
+
+  def get(self):
+    # set up the session. TODO: garbage collect old shell sessions
+    session_key = self.request.get('session')
+    if session_key:
+      session = Session.get(session_key)
+    else:
+      # create a new session
+      session = Session()
+      session.unpicklables = [db.Text(line) for line in INITIAL_UNPICKLABLES]
+      session_key = session.put()
+
+    template_file = os.path.join(os.path.dirname(__file__), 'templates',
+                                 'shell.html')
+    session_url = '/?session=%s' % session_key
+    vars = { 'server_software': os.environ['SERVER_SOFTWARE'],
+             'python_version': sys.version,
+             'session': str(session_key),
+             'user': users.get_current_user(),
+             'login_url': users.create_login_url(session_url),
+             'logout_url': users.create_logout_url(session_url),
+             }
+    rendered = webapp.template.render(template_file, vars, debug=_DEBUG)
+    self.response.out.write(rendered)
+
+
+class StatementHandler(webapp.RequestHandler):
+  """Evaluates a python statement in a given session and returns the result.
+  """
+
+  def get(self):
+    self.response.headers['Content-Type'] = 'text/plain'
+
+    # extract the statement to be run
+    statement = self.request.get('statement')
+    if not statement:
+      return
+
+    # the python compiler doesn't like network line endings
+    statement = statement.replace('\r\n', '\n')
+
+    # add a couple newlines at the end of the statement. this makes
+    # single-line expressions such as 'class Foo: pass' evaluate happily.
+    statement += '\n\n'
+
+    # log and compile the statement up front
+    try:
+      logging.info('Compiling and evaluating:\n%s' % statement)
+      compiled = compile(statement, '<string>', 'single')
+    except:
+      self.response.out.write(traceback.format_exc())
+      return
+
+    # create a dedicated module to be used as this statement's __main__
+    statement_module = new.module('__main__')
+
+    # use this request's __builtin__, since it changes on each request.
+    # this is needed for import statements, among other things.
+    import __builtin__
+    statement_module.__builtins__ = __builtin__
+
+    # load the session from the datastore
+    session = Session.get(self.request.get('session'))
+
+    # swap in our custom module for __main__. then unpickle the session
+    # globals, run the statement, and re-pickle the session globals, all
+    # inside it.
+    old_main = sys.modules.get('__main__')
+    try:
+      sys.modules['__main__'] = statement_module
+      statement_module.__name__ = '__main__'
+
+      # re-evaluate the unpicklables
+      for code in session.unpicklables:
+        exec code in statement_module.__dict__
+
+      # re-initialize the globals
+      for name, val in session.globals_dict().items():
+        try:
+          statement_module.__dict__[name] = val
+        except:
+          msg = 'Dropping %s since it could not be unpickled.\n' % name
+          self.response.out.write(msg)
+          logging.warning(msg + traceback.format_exc())
+          session.remove_global(name)
+
+      # run!
+      old_globals = dict(statement_module.__dict__)
+      try:
+        old_stdout = sys.stdout
+        old_stderr = sys.stderr
+        try:
+          sys.stdout = self.response.out
+          sys.stderr = self.response.out
+          exec compiled in statement_module.__dict__
+        finally:
+          sys.stdout = old_stdout
+          sys.stderr = old_stderr
+      except:
+        self.response.out.write(traceback.format_exc())
+        return
+
+      # extract the new globals that this statement added
+      new_globals = {}
+      for name, val in statement_module.__dict__.items():
+        if name not in old_globals or val != old_globals[name]:
+          new_globals[name] = val
+
+      if True in [isinstance(val, UNPICKLABLE_TYPES)
+                  for val in new_globals.values()]:
+        # this statement added an unpicklable global. store the statement and
+        # the names of all of the globals it added in the unpicklables.
+        session.add_unpicklable(statement, new_globals.keys())
+        logging.debug('Storing this statement as an unpicklable.')
+
+      else:
+        # this statement didn't add any unpicklables. pickle and store the
+        # new globals back into the datastore.
+        for name, val in new_globals.items():
+          if not name.startswith('__'):
+            session.set_global(name, val)
+
+    finally:
+      sys.modules['__main__'] = old_main
+
+    session.put()
+
+
+def main():
+  application = webapp.WSGIApplication(
+    [('/gae_shell/', FrontPageHandler),
+     ('/gae_shell/shell.do', StatementHandler)], debug=_DEBUG)
+  wsgiref.handlers.CGIHandler().run(application)
+
+
+if __name__ == '__main__':
+  main()
diff --git a/tools/scripts/app_engine_server/gae_shell/shell.py~ b/tools/scripts/app_engine_server/gae_shell/shell.py~
new file mode 100755
index 0000000..dee9fdb
--- /dev/null
+++ b/tools/scripts/app_engine_server/gae_shell/shell.py~
@@ -0,0 +1,308 @@
+#!/usr/bin/python
+#
+# Copyright 2007 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+An interactive, stateful AJAX shell that runs Python code on the server.
+
+Part of http://code.google.com/p/google-app-engine-samples/.
+
+May be run as a standalone app or in an existing app as an admin-only handler.
+Can be used for system administration tasks, as an interactive way to try out
+APIs, or as a debugging aid during development.
+
+The logging, os, sys, db, and users modules are imported automatically.
+
+Interpreter state is stored in the datastore so that variables, function
+definitions, and other values in the global and local namespaces can be used
+across commands.
+
+To use the shell in your app, copy shell.py, static/*, and templates/* into
+your app's source directory. Then, copy the URL handlers from app.yaml into
+your app.yaml.
+
+TODO: unit tests!
+"""
+
+import logging
+import new
+import os
+import pickle
+import sys
+import traceback
+import types
+import wsgiref.handlers
+
+from google.appengine.api import users
+from google.appengine.ext import db
+from google.appengine.ext import webapp
+from google.appengine.ext.webapp import template
+
+
+# Set to True if stack traces should be shown in the browser, etc.
+_DEBUG = True
+
+# The entity kind for shell sessions. Feel free to rename to suit your app.
+_SESSION_KIND = '_Shell_Session'
+
+# Types that can't be pickled.
+UNPICKLABLE_TYPES = (
+  types.ModuleType,
+  types.TypeType,
+  types.ClassType,
+  types.FunctionType,
+  )
+
+# Unpicklable statements to seed new sessions with.
+INITIAL_UNPICKLABLES = [
+  'import logging',
+  'import os',
+  'import sys',
+  'from google.appengine.ext import db',
+  'from google.appengine.api import users',
+  ]
+
+
+class Session(db.Model):
+  """A shell session. Stores the session's globals.
+
+  Each session globals is stored in one of two places:
+
+  If the global is picklable, it's stored in the parallel globals and
+  global_names list properties. (They're parallel lists to work around the
+  unfortunate fact that the datastore can't store dictionaries natively.)
+
+  If the global is not picklable (e.g. modules, classes, and functions), or if
+  it was created by the same statement that created an unpicklable global,
+  it's not stored directly. Instead, the statement is stored in the
+  unpicklables list property. On each request, before executing the current
+  statement, the unpicklable statements are evaluated to recreate the
+  unpicklable globals.
+
+  The unpicklable_names property stores all of the names of globals that were
+  added by unpicklable statements. When we pickle and store the globals after
+  executing a statement, we skip the ones in unpicklable_names.
+
+  Using Text instead of string is an optimization. We don't query on any of
+  these properties, so they don't need to be indexed.
+  """
+  global_names = db.ListProperty(db.Text)
+  globals = db.ListProperty(db.Blob)
+  unpicklable_names = db.ListProperty(db.Text)
+  unpicklables = db.ListProperty(db.Text)
+
+  def set_global(self, name, value):
+    """Adds a global, or updates it if it already exists.
+
+    Also removes the global from the list of unpicklable names.
+
+    Args:
+      name: the name of the global to remove
+      value: any picklable value
+    """
+    blob = db.Blob(pickle.dumps(value))
+
+    if name in self.global_names:
+      index = self.global_names.index(name)
+      self.globals[index] = blob
+    else:
+      self.global_names.append(db.Text(name))
+      self.globals.append(blob)
+
+    self.remove_unpicklable_name(name)
+
+  def remove_global(self, name):
+    """Removes a global, if it exists.
+
+    Args:
+      name: string, the name of the global to remove
+    """
+    if name in self.global_names:
+      index = self.global_names.index(name)
+      del self.global_names[index]
+      del self.globals[index]
+
+  def globals_dict(self):
+    """Returns a dictionary view of the globals.
+    """
+    return dict((name, pickle.loads(val))
+                for name, val in zip(self.global_names, self.globals))
+
+  def add_unpicklable(self, statement, names):
+    """Adds a statement and list of names to the unpicklables.
+
+    Also removes the names from the globals.
+
+    Args:
+      statement: string, the statement that created new unpicklable global(s).
+      names: list of strings; the names of the globals created by the statement.
+    """
+    self.unpicklables.append(db.Text(statement))
+
+    for name in names:
+      self.remove_global(name)
+      if name not in self.unpicklable_names:
+        self.unpicklable_names.append(db.Text(name))
+
+  def remove_unpicklable_name(self, name):
+    """Removes a name from the list of unpicklable names, if it exists.
+
+    Args:
+      name: string, the name of the unpicklable global to remove
+    """
+    if name in self.unpicklable_names:
+      self.unpicklable_names.remove(name)
+
+
+class FrontPageHandler(webapp.RequestHandler):
+  """Creates a new session and renders the shell.html template.
+  """
+
+  def get(self):
+    # set up the session. TODO: garbage collect old shell sessions
+    session_key = self.request.get('session')
+    if session_key:
+      session = Session.get(session_key)
+    else:
+      # create a new session
+      session = Session()
+      session.unpicklables = [db.Text(line) for line in INITIAL_UNPICKLABLES]
+      session_key = session.put()
+
+    template_file = os.path.join(os.path.dirname(__file__), 'templates',
+                                 'shell.html')
+    session_url = '/?session=%s' % session_key
+    vars = { 'server_software': os.environ['SERVER_SOFTWARE'],
+             'python_version': sys.version,
+             'session': str(session_key),
+             'user': users.get_current_user(),
+             'login_url': users.create_login_url(session_url),
+             'logout_url': users.create_logout_url(session_url),
+             }
+    rendered = webapp.template.render(template_file, vars, debug=_DEBUG)
+    self.response.out.write(rendered)
+
+
+class StatementHandler(webapp.RequestHandler):
+  """Evaluates a python statement in a given session and returns the result.
+  """
+
+  def get(self):
+    self.response.headers['Content-Type'] = 'text/plain'
+
+    # extract the statement to be run
+    statement = self.request.get('statement')
+    if not statement:
+      return
+
+    # the python compiler doesn't like network line endings
+    statement = statement.replace('\r\n', '\n')
+
+    # add a couple newlines at the end of the statement. this makes
+    # single-line expressions such as 'class Foo: pass' evaluate happily.
+    statement += '\n\n'
+
+    # log and compile the statement up front
+    try:
+      logging.info('Compiling and evaluating:\n%s' % statement)
+      compiled = compile(statement, '<string>', 'single')
+    except:
+      self.response.out.write(traceback.format_exc())
+      return
+
+    # create a dedicated module to be used as this statement's __main__
+    statement_module = new.module('__main__')
+
+    # use this request's __builtin__, since it changes on each request.
+    # this is needed for import statements, among other things.
+    import __builtin__
+    statement_module.__builtins__ = __builtin__
+
+    # load the session from the datastore
+    session = Session.get(self.request.get('session'))
+
+    # swap in our custom module for __main__. then unpickle the session
+    # globals, run the statement, and re-pickle the session globals, all
+    # inside it.
+    old_main = sys.modules.get('__main__')
+    try:
+      sys.modules['__main__'] = statement_module
+      statement_module.__name__ = '__main__'
+
+      # re-evaluate the unpicklables
+      for code in session.unpicklables:
+        exec code in statement_module.__dict__
+
+      # re-initialize the globals
+      for name, val in session.globals_dict().items():
+        try:
+          statement_module.__dict__[name] = val
+        except:
+          msg = 'Dropping %s since it could not be unpickled.\n' % name
+          self.response.out.write(msg)
+          logging.warning(msg + traceback.format_exc())
+          session.remove_global(name)
+
+      # run!
+      old_globals = dict(statement_module.__dict__)
+      try:
+        old_stdout = sys.stdout
+        old_stderr = sys.stderr
+        try:
+          sys.stdout = self.response.out
+          sys.stderr = self.response.out
+          exec compiled in statement_module.__dict__
+        finally:
+          sys.stdout = old_stdout
+          sys.stderr = old_stderr
+      except:
+        self.response.out.write(traceback.format_exc())
+        return
+
+      # extract the new globals that this statement added
+      new_globals = {}
+      for name, val in statement_module.__dict__.items():
+        if name not in old_globals or val != old_globals[name]:
+          new_globals[name] = val
+
+      if True in [isinstance(val, UNPICKLABLE_TYPES)
+                  for val in new_globals.values()]:
+        # this statement added an unpicklable global. store the statement and
+        # the names of all of the globals it added in the unpicklables.
+        session.add_unpicklable(statement, new_globals.keys())
+        logging.debug('Storing this statement as an unpicklable.')
+
+      else:
+        # this statement didn't add any unpicklables. pickle and store the
+        # new globals back into the datastore.
+        for name, val in new_globals.items():
+          if not name.startswith('__'):
+            session.set_global(name, val)
+
+    finally:
+      sys.modules['__main__'] = old_main
+
+    session.put()
+
+
+def main():
+  application = webapp.WSGIApplication(
+    [('/', FrontPageHandler),
+     ('/shell.do', StatementHandler)], debug=_DEBUG)
+  wsgiref.handlers.CGIHandler().run(application)
+
+
+if __name__ == '__main__':
+  main()
diff --git a/tools/scripts/app_engine_server/gae_shell/static/shell.js b/tools/scripts/app_engine_server/gae_shell/static/shell.js
new file mode 100644
index 0000000..4aa1583
--- /dev/null
+++ b/tools/scripts/app_engine_server/gae_shell/static/shell.js
@@ -0,0 +1,195 @@
+// Copyright 2007 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview
+ * Javascript code for the interactive AJAX shell.
+ *
+ * Part of http://code.google.com/p/google-app-engine-samples/.
+ *
+ * Includes a function (shell.runStatement) that sends the current python
+ * statement in the shell prompt text box to the server, and a callback
+ * (shell.done) that displays the results when the XmlHttpRequest returns.
+ *
+ * Also includes cross-browser code (shell.getXmlHttpRequest) to get an
+ * XmlHttpRequest.
+ */
+
+/**
+ * Shell namespace.
+ * @type {Object}
+ */
+var shell = {}
+
+/**
+ * The shell history. history is an array of strings, ordered oldest to
+ * newest. historyCursor is the current history element that the user is on.
+ *
+ * The last history element is the statement that the user is currently
+ * typing. When a statement is run, it's frozen in the history, a new history
+ * element is added to the end of the array for the new statement, and
+ * historyCursor is updated to point to the new element.
+ *
+ * @type {Array}
+ */
+shell.history = [''];
+
+/**
+ * See {shell.history}
+ * @type {number}
+ */
+shell.historyCursor = 0;
+
+/**
+ * A constant for the XmlHttpRequest 'done' state.
+ * @type Number
+ */
+shell.DONE_STATE = 4;
+
+/**
+ * A cross-browser function to get an XmlHttpRequest object.
+ *
+ * @return {XmlHttpRequest?} a new XmlHttpRequest
+ */
+shell.getXmlHttpRequest = function() {
+  if (window.XMLHttpRequest) {
+    return new XMLHttpRequest();
+  } else if (window.ActiveXObject) {
+    try {
+      return new ActiveXObject('Msxml2.XMLHTTP');
+    } catch(e) {
+      return new ActiveXObject('Microsoft.XMLHTTP');
+    }
+  }
+
+  return null;
+};
+
+/**
+ * This is the prompt textarea's onkeypress handler. Depending on the key that
+ * was pressed, it will run the statement, navigate the history, or update the
+ * current statement in the history.
+ *
+ * @param {Event} event the keypress event
+ * @return {Boolean} false to tell the browser not to submit the form.
+ */
+shell.onPromptKeyPress = function(event) {
+  var statement = document.getElementById('statement');
+
+  if (this.historyCursor == this.history.length - 1) {
+    // we're on the current statement. update it in the history before doing
+    // anything.
+    this.history[this.historyCursor] = statement.value;
+  }
+
+  // should we pull something from the history?
+  if (event.ctrlKey && event.keyCode == 38 /* up arrow */) {
+    if (this.historyCursor > 0) {
+      statement.value = this.history[--this.historyCursor];
+    }
+    return false;
+  } else if (event.ctrlKey && event.keyCode == 40 /* down arrow */) {
+    if (this.historyCursor < this.history.length - 1) {
+      statement.value = this.history[++this.historyCursor];
+    }
+    return false;
+  } else if (!event.altKey) {
+    // probably changing the statement. update it in the history.
+    this.historyCursor = this.history.length - 1;
+    this.history[this.historyCursor] = statement.value;
+  }
+
+  // should we submit?
+  var ctrlEnter = (document.getElementById('submit_key').value == 'ctrl-enter');
+  if (event.keyCode == 13 /* enter */ && !event.altKey && !event.shiftKey &&
+      event.ctrlKey == ctrlEnter) {
+    return this.runStatement();
+  }
+};
+
+/**
+ * The XmlHttpRequest callback. If the request succeeds, it adds the command
+ * and its resulting output to the shell history div.
+ *
+ * @param {XmlHttpRequest} req the XmlHttpRequest we used to send the current
+ *     statement to the server
+ */
+shell.done = function(req) {
+  if (req.readyState == this.DONE_STATE) {
+    var statement = document.getElementById('statement')
+    statement.className = 'prompt';
+
+    // add the command to the shell output
+    var output = document.getElementById('output');
+
+    output.value += '\n>>> ' + statement.value;
+    statement.value = '';
+
+    // add a new history element
+    this.history.push('');
+    this.historyCursor = this.history.length - 1;
+
+    // add the command's result
+    var result = req.responseText.replace(/^\s*|\s*$/g, '');  // trim whitespace
+    if (result != '')
+      output.value += '\n' + result;
+
+    // scroll to the bottom
+    output.scrollTop = output.scrollHeight;
+    if (output.createTextRange) {
+      var range = output.createTextRange();
+      range.collapse(false);
+      range.select();
+    }
+  }
+};
+
+/**
+ * This is the form's onsubmit handler. It sends the python statement to the
+ * server, and registers shell.done() as the callback to run when it returns.
+ *
+ * @return {Boolean} false to tell the browser not to submit the form.
+ */
+shell.runStatement = function() {
+  var form = document.getElementById('form');
+
+  // build a XmlHttpRequest
+  var req = this.getXmlHttpRequest();
+  if (!req) {
+    document.getElementById('ajax-status').innerHTML =
+        "<span class='error'>Your browser doesn't support AJAX. :(</span>";
+    return false;
+  }
+
+  req.onreadystatechange = function() { shell.done(req); };
+
+  // build the query parameter string
+  var params = '';
+  for (i = 0; i < form.elements.length; i++) {
+    var elem = form.elements[i];
+    if (elem.type != 'submit' && elem.type != 'button' && elem.id != 'caret') {
+      var value = escape(elem.value).replace(/\+/g, '%2B'); // escape ignores +
+      params += '&' + elem.name + '=' + value;
+    }
+  }
+
+  // send the request and tell the user.
+  document.getElementById('statement').className = 'prompt processing';
+  req.open(form.method, form.action + '?' + params, true);
+  req.setRequestHeader('Content-type',
+                       'application/x-www-form-urlencoded;charset=UTF-8');
+  req.send(null);
+
+  return false;
+};
diff --git a/tools/scripts/app_engine_server/gae_shell/static/spinner.gif b/tools/scripts/app_engine_server/gae_shell/static/spinner.gif
new file mode 100644
index 0000000..3e58d6e
--- /dev/null
+++ b/tools/scripts/app_engine_server/gae_shell/static/spinner.gif
Binary files differ
diff --git a/tools/scripts/app_engine_server/gae_shell/templates/shell.html b/tools/scripts/app_engine_server/gae_shell/templates/shell.html
new file mode 100644
index 0000000..123b200
--- /dev/null
+++ b/tools/scripts/app_engine_server/gae_shell/templates/shell.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title> Interactive Shell </title>
+<script type="text/javascript" src="/gae_shell/static/shell.js"></script>
+<style type="text/css">
+body {
+  font-family: monospace;
+  font-size: 10pt;
+}
+
+p {
+  margin: 0.5em;
+}
+
+.prompt, #output {
+  width: 45em;
+  border: 1px solid silver;
+  background-color: #f5f5f5;
+  font-size: 10pt;
+  margin: 0.5em;
+  padding: 0.5em;
+  padding-right: 0em;
+  overflow-x: hidden;
+}
+
+#toolbar {
+  margin-left: 0.5em;
+  padding-left: 0.5em;
+}
+
+#caret {
+  width: 2.5em;
+  margin-right: 0px;
+  padding-right: 0px;
+  border-right: 0px;
+}
+
+#statement {
+  width: 43em;
+  margin-left: -1em;
+  padding-left: 0px;
+  border-left: 0px;
+  background-position: top right;
+  background-repeat: no-repeat;
+}
+
+.processing {
+  background-image: url("/gae_shell/static/spinner.gif");
+}
+
+#ajax-status {
+  font-weight: bold;
+}
+
+.message {
+  color: #8AD;
+  font-weight: bold;
+  font-style: italic;
+}
+
+.error {
+  color: #F44;
+}
+
+.username {
+  font-weight: bold;
+}
+
+</style>
+</head>
+
+<body>
+
+<p> Interactive server-side Python shell for
+<a href="http://code.google.com/appengine/">Google App Engine</a>.
+(<a href="http://code.google.com/p/google-app-engine-samples/">source</a>)
+</p>
+
+<textarea id="output" rows="22" readonly="readonly">
+{{ server_software }}
+Python {{ python_version }}
+</textarea>
+
+<form id="form" action="shell.do" method="get">
+  <nobr>
+  <textarea class="prompt" id="caret" readonly="readonly" rows="4"
+            onfocus="document.getElementById('statement').focus()"
+            >&gt;&gt;&gt;</textarea>
+  <textarea class="prompt" name="statement" id="statement" rows="4"
+            onkeypress="return shell.onPromptKeyPress(event);"></textarea>
+  </nobr>
+  <input type="hidden" name="session" value="{{ session }}" />
+  <input type="submit" style="display: none" />
+</form>
+
+<p id="ajax-status"></p>
+
+<p id="toolbar">
+{% if user %}
+  <span class="username">{{ user.nickname }}</span>
+  (<a href="{{ logout_url }}">log out</a>)
+{% else %}
+  <a href="{{ login_url }}">log in</a>
+{% endif %}
+ | Ctrl-Up/Down for history |
+<select id="submit_key">
+  <option value="enter">Enter</option>
+  <option value="ctrl-enter" selected="selected">Ctrl-Enter</option>
+</select>
+<label for="submit_key">submits</label>
+</p>
+
+<script type="text/javascript">
+document.getElementById('statement').focus();
+</script>
+
+</body>
+</html>
+
diff --git a/tools/scripts/app_engine_server/index.yaml b/tools/scripts/app_engine_server/index.yaml
new file mode 100644
index 0000000..8e6046d
--- /dev/null
+++ b/tools/scripts/app_engine_server/index.yaml
@@ -0,0 +1,12 @@
+indexes:
+
+# AUTOGENERATED
+
+# This index.yaml is automatically updated whenever the dev_appserver
+# detects that a new type of query is run.  If you want to manage the
+# index.yaml file manually, remove the above marker line (the line
+# saying "# AUTOGENERATED").  If you want to manage some indexes
+# manually, move them above the marker line.  The index.yaml file is
+# automatically uploaded to the admin console when you next deploy
+# your application using appcfg.py.
+
diff --git a/tools/scripts/app_engine_server/memcache_zipserve.py b/tools/scripts/app_engine_server/memcache_zipserve.py
new file mode 100644
index 0000000..e11cfc5
--- /dev/null
+++ b/tools/scripts/app_engine_server/memcache_zipserve.py
@@ -0,0 +1,412 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""A class to serve pages from zip files and use memcache for performance.
+
+This contains a class and a function to create an anonymous instance of the
+class to serve HTTP GET requests. Memcache is used to increase response speed
+and lower processing cycles used in serving. Credit to Guido van Rossum and
+his implementation of zipserve which served as a reference as I wrote this.
+
+  MemcachedZipHandler: Class that serves request
+  create_handler: method to create instance of MemcachedZipHandler
+"""
+
+__author__ = 'jmatt@google.com (Justin Mattson)'
+
+import email.Utils
+import logging
+import mimetypes
+import time
+import zipfile
+
+from google.appengine.api import memcache
+from google.appengine.ext import webapp
+from google.appengine.ext.webapp import util
+
+
+def create_handler(zip_files, max_age=None, public=None):
+  """Factory method to create a MemcachedZipHandler instance.
+
+  Args:
+    zip_files: A list of file names, or a list of lists of file name, first
+        member of file mappings. See MemcachedZipHandler documentation for
+        more information about using the list of lists format
+    max_age: The maximum client-side cache lifetime
+    public: Whether this should be declared public in the client-side cache
+  Returns:
+    A MemcachedZipHandler wrapped in a pretty, anonymous bow for use with App
+    Engine
+
+  Raises:
+    ValueError: if the zip_files argument is not a list
+  """
+  # verify argument integrity. If the argument is passed in list format,
+  # convert it to list of lists format
+  
+  if zip_files and type(zip_files).__name__ == 'list':
+    num_items = len(zip_files)
+    while num_items > 0:
+      if type(zip_files[num_items - 1]).__name__ != 'list':
+        zip_files[num_items - 1] = [zip_files[num_items-1]]
+      num_items -= 1
+  else:
+    raise ValueError('File name arguments must be a list')
+
+  class HandlerWrapper(MemcachedZipHandler):
+    """Simple wrapper for an instance of MemcachedZipHandler.
+
+    I'm still not sure why this is needed
+    """
+    
+    def get(self, name):
+      self.zipfilenames = zip_files
+      self.TrueGet(name)
+      if max_age is not None:
+        MAX_AGE = max_age
+      if public is not None:
+        PUBLIC = public
+
+  return HandlerWrapper
+
+
+class MemcachedZipHandler(webapp.RequestHandler):
+  """Handles get requests for a given URL.
+
+  Serves a GET request from a series of zip files. As files are served they are
+  put into memcache, which is much faster than retreiving them from the zip
+  source file again. It also uses considerably fewer CPU cycles.
+  """
+  zipfile_cache = {}                # class cache of source zip files
+  MAX_AGE = 600                     # max client-side cache lifetime
+  PUBLIC = True                     # public cache setting
+  CACHE_PREFIX = 'cache://'         # memcache key prefix for actual URLs
+  NEG_CACHE_PREFIX = 'noncache://'  # memcache key prefix for non-existant URL
+
+  def TrueGet(self, name):
+    """The top-level entry point to serving requests.
+
+    Called 'True' get because it does the work when called from the wrapper
+    class' get method
+
+    Args:
+      name: URL requested
+
+    Returns:
+      None
+    """
+    name = self.PreprocessUrl(name)
+
+    # see if we have the page in the memcache
+    resp_data = self.GetFromCache(name)
+    if resp_data is None:
+      logging.info('Cache miss for %s', name)
+      resp_data = self.GetFromNegativeCache(name)
+      if resp_data is None:
+        resp_data = self.GetFromStore(name)
+
+        # IF we have the file, put it in the memcache
+        # ELSE put it in the negative cache
+        if resp_data is not None:
+          self.StoreOrUpdateInCache(name, resp_data)
+        else:
+          logging.info('Adding %s to negative cache, serving 404', name)
+          self.StoreInNegativeCache(name)
+          self.Write404Error()
+          return
+      else:
+        self.Write404Error()
+        return
+
+    content_type, encoding = mimetypes.guess_type(name)
+    if content_type:
+      self.response.headers['Content-Type'] = content_type
+    self.SetCachingHeaders()
+    self.response.out.write(resp_data)
+
+  def PreprocessUrl(self, name):
+    """Any preprocessing work on the URL when it comes it.
+
+    Put any work related to interpretting the incoming URL here. For example,
+    this is used to redirect requests for a directory to the index.html file
+    in that directory. Subclasses should override this method to do different
+    preprocessing.
+
+    Args:
+      name: The incoming URL
+
+    Returns:
+      The processed URL
+    """
+    # handle special case of requesting the domain itself
+    if not name:
+      name = 'index.html'
+
+    # determine if this is a request for a directory
+    final_path_segment = name
+    final_slash_offset = name.rfind('/')
+    if final_slash_offset != len(name) - 1:
+      final_path_segment = name[final_slash_offset + 1:]
+      if final_path_segment.find('.') == -1:
+        name = ''.join([name, '/'])
+
+    # if this is a directory, redirect to index.html
+    if name[len(name) - 1:] == '/':
+      return '%s%s' % (name, 'index.html')
+    else:
+      return name
+
+  def GetFromStore(self, file_path):
+    """Retrieve file from zip files.
+
+    Get the file from the source, it must not have been in the memcache. If
+    possible, we'll use the zip file index to quickly locate where the file
+    should be found. (See MapToFileArchive documentation for assumptions about
+    file ordering.) If we don't have an index or don't find the file where the
+    index says we should, look through all the zip files to find it.
+
+    Args:
+      file_path: the file that we're looking for
+
+    Returns:
+      The contents of the requested file
+    """
+    resp_data = None
+    file_itr = iter(self.zipfilenames)
+
+    # check the index, if we have one, to see what archive the file is in
+    archive_name = self.MapFileToArchive(file_path)
+    if not archive_name:
+      archive_name = file_itr.next()[0]
+    
+    while resp_data is None and archive_name:
+      zip_archive = self.LoadZipFile(archive_name)
+      if zip_archive:
+
+        # we expect some lookups will fail, and that's okay, 404s will deal
+        # with that
+        try:
+          resp_data = zip_archive.read(file_path)
+        except (KeyError, RuntimeError), err:
+          # no op
+          x = False
+        if resp_data is not None:
+          logging.info('%s read from %s', file_path, archive_name)
+          
+      try:
+        archive_name = file_itr.next()[0]
+      except (StopIteration), err:
+        archive_name = False
+
+    return resp_data
+
+  def LoadZipFile(self, zipfilename):
+    """Convenience method to load zip file.
+
+    Just a convenience method to load the zip file from the data store. This is
+    useful if we ever want to change data stores and also as a means of
+    dependency injection for testing. This method will look at our file cache
+    first, and then load and cache the file if there's a cache miss
+
+    Args:
+      zipfilename: the name of the zip file to load
+
+    Returns:
+      The zip file requested, or None if there is an I/O error
+    """
+    zip_archive = None
+    zip_archive = self.zipfile_cache.get(zipfilename)
+    if zip_archive is None:
+      try:
+        zip_archive = zipfile.ZipFile(zipfilename)
+        self.zipfile_cache[zipfilename] = zip_archive
+      except (IOError, RuntimeError), err:
+        logging.error('Can\'t open zipfile %s, cause: %s' % (zipfilename,
+                                                             err))
+    return zip_archive
+
+  def MapFileToArchive(self, file_path):
+    """Given a file name, determine what archive it should be in.
+
+    This method makes two critical assumptions.
+    (1) The zip files passed as an argument to the handler, if concatenated
+        in that same order, would result in a total ordering
+        of all the files. See (2) for ordering type.
+    (2) Upper case letters before lower case letters. The traversal of a
+        directory tree is depth first. A parent directory's files are added
+        before the files of any child directories
+
+    Args:
+      file_path: the file to be mapped to an archive
+
+    Returns:
+      The name of the archive where we expect the file to be
+    """
+    num_archives = len(self.zipfilenames)
+    while num_archives > 0:
+      target = self.zipfilenames[num_archives - 1]
+      if len(target) > 1:
+        if self.CompareFilenames(target[1], file_path) >= 0:
+          return target[0]
+      num_archives -= 1
+
+    return None
+
+  def CompareFilenames(self, file1, file2):
+    """Determines whether file1 is lexigraphically 'before' file2.
+
+    WARNING: This method assumes that paths are output in a depth-first,
+    with parent directories' files stored before childs'
+
+    We say that file1 is lexigraphically before file2 if the last non-matching
+    path segment of file1 is alphabetically before file2.
+    
+    Args:
+      file1: the first file path
+      file2: the second file path
+
+    Returns:
+      A positive number if file1 is before file2
+      A negative number if file2 is before file1
+      0 if filenames are the same
+    """
+    f1_segments = file1.split('/')
+    f2_segments = file2.split('/')
+
+    segment_ptr = 0
+    while (segment_ptr < len(f1_segments) and
+           segment_ptr < len(f2_segments) and
+           f1_segments[segment_ptr] == f2_segments[segment_ptr]):
+      segment_ptr += 1
+
+    if len(f1_segments) == len(f2_segments):
+
+      # we fell off the end, the paths much be the same
+      if segment_ptr == len(f1_segments):
+        return 0
+
+      # we didn't fall of the end, compare the segments where they differ
+      if f1_segments[segment_ptr] < f2_segments[segment_ptr]:
+        return 1
+      elif f1_segments[segment_ptr] > f2_segments[segment_ptr]:
+        return -1
+      else:
+        return 0
+
+      # the number of segments differs, we either mismatched comparing
+      # directories, or comparing a file to a directory
+    else:
+
+      # IF we were looking at the last segment of one of the paths,
+      # the one with fewer segments is first because files come before
+      # directories
+      # ELSE we just need to compare directory names
+      if (segment_ptr + 1 == len(f1_segments) or
+          segment_ptr + 1 == len(f2_segments)):
+        return len(f2_segments) - len(f1_segments)
+      else:
+        if f1_segments[segment_ptr] < f2_segments[segment_ptr]:
+          return 1
+        elif f1_segments[segment_ptr] > f2_segments[segment_ptr]:
+          return -1
+        else:
+          return 0
+
+  def SetCachingHeaders(self):
+    """Set caching headers for the request."""
+    max_age = self.MAX_AGE
+    self.response.headers['Expires'] = email.Utils.formatdate(
+        time.time() + max_age, usegmt=True)
+    cache_control = []
+    if self.PUBLIC:
+      cache_control.append('public')
+    cache_control.append('max-age=%d' % max_age)
+    self.response.headers['Cache-Control'] = ', '.join(cache_control)
+
+  def GetFromCache(self, filename):
+    """Get file from memcache, if available.
+
+    Args:
+      filename: The URL of the file to return
+
+    Returns:
+      The content of the file
+    """
+    return memcache.get('%s%s' % (self.CACHE_PREFIX, filename))
+
+  def StoreOrUpdateInCache(self, filename, data):
+    """Store data in the cache.
+
+    Store a piece of data in the memcache. Memcache has a maximum item size of
+    1*10^6 bytes. If the data is too large, fail, but log the failure. Future
+    work will consider compressing the data before storing or chunking it
+
+    Args:
+      filename: the name of the file to store
+      data: the data of the file
+
+    Returns:
+      None
+    """
+    try:
+      if not memcache.add('%s%s' % (self.CACHE_PREFIX, filename), data):
+        memcache.replace('%s%s' % (self.CACHE_PREFIX, filename), data)
+    except (ValueError), err:
+      logging.warning('Data size too large to cache\n%s' % err)
+
+  def Write404Error(self):
+    """Ouptut a simple 404 response."""
+    self.error(404)
+    self.response.out.write(
+        ''.join(['<html><head><title>404: Not Found</title></head>',
+                 '<body><b><h2>Error 404</h2><br/>',
+                 'File not found</b></body></html>']))
+
+  def StoreInNegativeCache(self, filename):
+    """If a non-existant URL is accessed, cache this result as well.
+
+    Future work should consider setting a maximum negative cache size to
+    prevent it from from negatively impacting the real cache.
+
+    Args:
+      filename: URL to add ot negative cache
+
+    Returns:
+      None
+    """
+    memcache.add('%s%s' % (self.NEG_CACHE_PREFIX, filename), -1)
+
+  def GetFromNegativeCache(self, filename):
+    """Retrieve from negative cache.
+
+    Args:
+      filename: URL to retreive
+
+    Returns:
+      The file contents if present in the negative cache.
+    """
+    return memcache.get('%s%s' % (self.NEG_CACHE_PREFIX, filename))
+
+
+def main():
+  application = webapp.WSGIApplication([('/([^/]+)/(.*)',
+                                         MemcachedZipHandler)])
+  util.run_wsgi_app(application)
+
+
+if __name__ == '__main__':
+  main()
diff --git a/tools/scripts/build.alias.template b/tools/scripts/build.alias.template
new file mode 100644
index 0000000..b605295
--- /dev/null
+++ b/tools/scripts/build.alias.template
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="PROJECT_NAME" default="package">
+
+    <!-- The build.properties file can be created by you and is never touched
+         by activitycreator. If you want to manually set properties, this is
+         the best place to set them. -->
+    <property file="build.properties"/>
+
+    <!-- The default.properties file is created and updated by activitycreator.
+         It will set any properties not already defined by build.properties. -->
+    <property file="default.properties"/>
+
+    <!-- ************************************************************************************* -->
+    <!-- Import the default Android build rules. 
+         This requires ant 1.6.0 or above. -->
+
+    <import file="${sdk-folder}/tools/lib/alias_rules.xml" />
+
+</project>
diff --git a/tools/scripts/build.template b/tools/scripts/build.template
new file mode 100644
index 0000000..7939e6c
--- /dev/null
+++ b/tools/scripts/build.template
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="PROJECT_NAME" default="help">
+
+    <!-- The local.properties file is created and updated by the 'android' tool.
+         It contain the path to the SDK. It should *NOT* be checked in in Version
+         Control Systems. -->
+    <property file="local.properties"/>
+
+    <!-- The build.properties file can be created by you and is never touched
+         by the 'android' tool. This is the place to change some of the default property values
+         used by the Ant rules.
+         Here are some properties you may want to change/update:
+
+         application-package
+             the name of your application package as defined in the manifest. Used by the
+             'uninstall' rule.
+         source-folder
+             the name of the source folder. Default is 'src'.
+         out-folder
+             the name of the output folder. Default is 'bin'.
+
+         Properties related to the SDK location or the project target should be updated
+          using the 'android' tool with the 'update' action.
+
+         This file is an integral part of the build system for your application and
+         should be checked in in Version Control Systems.
+
+         -->
+    <property file="build.properties"/>
+
+    <!-- The default.properties file is created and updated by the 'android' tool, as well
+         as ADT. 
+         This file is an integral part of the build system for your application and
+         should be checked in in Version Control Systems. -->
+    <property file="default.properties"/>
+
+    <!-- Custom Android task to deal with the project target, and import the proper rules.
+         This requires ant 1.6.0 or above. -->
+    <path id="android.antlibs">
+        <pathelement path="${sdk-location}/tools/lib/anttasks.jar" />
+        <pathelement path="${sdk-location}/tools/lib/sdklib.jar" />
+        <pathelement path="${sdk-location}/tools/lib/androidprefs.jar" />
+        <pathelement path="${sdk-location}/tools/lib/apkbuilder.jar" />
+        <pathelement path="${sdk-location}/tools/lib/jarutils.jar" />
+    </path>
+
+    <taskdef name="setup"
+        classname="com.android.ant.SetupTask"
+        classpathref="android.antlibs"/>
+
+    <!-- Execute the Android Setup task that will setup some properties specific to the target,
+         and import the rules files.
+         To customize the rules, copy/paste them below the task, and disable import by setting
+         the import attribute to false:
+            <setup import="false" />
+         
+         This will ensure that the properties are setup correctly but that your customized
+         targets are used.
+    -->
+    <setup />
+</project>
diff --git a/tools/scripts/combine_sdks.sh b/tools/scripts/combine_sdks.sh
new file mode 100755
index 0000000..ebaa1c6
--- /dev/null
+++ b/tools/scripts/combine_sdks.sh
@@ -0,0 +1,105 @@
+#!/bin/bash
+
+function replace()
+{
+        echo replacing $1
+        rm $V -rf "$UNZIPPED_BASE_DIR"/$1
+        cp $V -rf "$UNZIPPED_IMAGE_DIR"/$1 "$UNZIPPED_BASE_DIR"/$1
+}
+
+V=""
+Q="-q"
+if [ "$1" == "-v" ]; then
+    V="-v"
+    Q=""
+    shift
+fi
+
+NOZIP=""
+if [ "$1" == "-nozip" ]; then
+    NOZIP="1"
+    shift
+fi
+
+BASE="$1"
+IMAGES="$2"
+OUTPUT="$3"
+
+if [[ -z "$BASE" || -z "$IMAGES" || -z "$OUTPUT" ]] ; then
+    echo "usage: combine_sdks.sh [-v] [-nozip] BASE IMAGES OUTPUT"
+    echo
+    echo "  BASE and IMAGES should be sdk zip files.  The system image files,"
+    echo "  emulator and other runtime files will be copied from IMAGES and"
+    echo "  everything else will be copied from BASE.  All of this will be"
+    echo "  bundled into OUTPUT and zipped up again (unless -nozip is specified)."
+    echo
+    exit 1
+fi
+
+TMP=$(mktemp -d)
+
+TMP_ZIP=tmp.zip
+
+# determine executable extension
+case `uname -s` in
+    *_NT-*)  # for Windows
+        EXE=.exe
+        ;;
+    *)
+        EXE=
+        ;;
+esac
+
+BASE_DIR="$TMP"/base
+IMAGES_DIR="$TMP"/images
+OUTPUT_TMP_ZIP="$BASE_DIR/$TMP_ZIP"
+
+unzip $Q "$BASE"   -d "$BASE_DIR"
+unzip $Q "$IMAGES" -d "$IMAGES_DIR"
+
+UNZIPPED_BASE_DIR=$(echo "$BASE_DIR"/*)
+UNZIPPED_IMAGE_DIR=$(echo "$IMAGES_DIR"/*)
+
+#
+# The commands to copy over the files that we want
+#
+
+# replace tools/emulator # at this time we do not want the exe from SDK1.x
+replace tools/lib/images
+replace tools/lib/res
+replace tools/lib/fonts
+replace tools/lib/layoutlib.jar
+replace docs
+replace android.jar
+
+for i in widgets categories broadcast_actions service_actions; do
+    replace tools/lib/$i.txt
+done
+
+if [ -d "$UNZIPPED_BASE_DIR"/usb_driver ]; then
+    replace usb_driver
+fi
+
+#
+# end
+#
+
+if [ -z "$NOZIP" ]; then
+    pushd "$BASE_DIR" &> /dev/null
+        # rename the directory to the leaf minus the .zip of OUTPUT
+        LEAF=$(echo "$OUTPUT" | sed -e "s:.*\.zip/::" | sed -e "s:.zip$::")
+        mv * "$LEAF"
+        # zip it
+        zip $V -qr "$TMP_ZIP" "$LEAF"
+    popd &> /dev/null
+
+    cp $V "$OUTPUT_TMP_ZIP" "$OUTPUT"
+    echo "Combined SDK available at $OUTPUT"
+else
+    OUT_DIR="${OUTPUT//.zip/}"
+    mv $V "$BASE_DIR"/* "$OUT_DIR"
+    echo "Unzipped combined SDK available at $OUT_DIR"
+fi
+
+rm $V -rf "$TMP"
+
diff --git a/tools/scripts/divide_and_compress.py b/tools/scripts/divide_and_compress.py
new file mode 100755
index 0000000..d369be4
--- /dev/null
+++ b/tools/scripts/divide_and_compress.py
@@ -0,0 +1,352 @@
+#!/usr/bin/python2.4
+#
+# Copyright (C) 2008 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""Module to compress directories in to series of zip files.
+
+This module will take a directory and compress all its contents, including
+child directories into a series of zip files named N.zip where 'N' ranges from
+0 to infinity. The zip files will all be below a certain specified maximum
+threshold.
+
+The directory is compressed with a depth first traversal, each directory's
+file contents being compressed as it is visisted, before the compression of any
+child directory's contents. In this way the files within an archive are ordered
+and the archives themselves are ordered.
+
+The class also constructs a 'main.py' file intended for use with Google App
+Engine with a custom App Engine program not currently distributed with this
+code base. The custom App Engine runtime can leverage the index files written
+out by this class to more quickly locate which zip file to serve a given URL
+from.
+"""
+
+__author__ = 'jmatt@google.com (Justin Mattson)'
+
+from optparse import OptionParser
+import os
+import stat
+import sys
+import zipfile
+from zipfile import ZipFile
+import divide_and_compress_constants
+
+
+def Main(argv):
+  parser = CreateOptionsParser()
+  (options, args) = parser.parse_args()
+  VerifyArguments(options, parser)
+  zipper = DirectoryZipper(options.destination, 
+                           options.sourcefiles, 
+                           ParseSize(options.filesize),
+                           options.compress)
+  zipper.StartCompress()
+  
+
+def CreateOptionsParser():
+  rtn = OptionParser()
+  rtn.add_option('-s', '--sourcefiles', dest='sourcefiles', default=None,
+                 help='The directory containing the files to compress')
+  rtn.add_option('-d', '--destination', dest='destination', default=None,
+                 help=('Where to put the archive files, this should not be'
+                       ' a child of where the source files exist.'))
+  rtn.add_option('-f', '--filesize', dest='filesize', default='1M',
+                 help=('Maximum size of archive files. A number followed by' 
+                       'a magnitude indicator, eg. 1000000B == one million '
+                       'BYTES, 500K == five hundred KILOBYTES, 1.2M == one '
+                       'point two MEGABYTES. 1M == 1048576 BYTES'))
+  rtn.add_option('-n', '--nocompress', action='store_false', dest='compress',
+                 default=True, 
+                 help=('Whether the archive files should be compressed, or '
+                       'just a concatenation of the source files'))
+  return rtn
+
+
+def VerifyArguments(options, parser):
+  try:
+    if options.sourcefiles is None or options.destination is None:
+      parser.print_help()
+      sys.exit(-1)
+  except (AttributeError), err:
+    parser.print_help()
+    sys.exit(-1)
+
+
+def ParseSize(size_str):
+  if len(size_str) < 2:
+    raise ValueError(('filesize argument not understood, please include'
+                      ' a numeric value and magnitude indicator'))
+  magnitude = size_str[len(size_str)-1:]
+  if not magnitude in ('K', 'B', 'M'):
+    raise ValueError(('filesize magnitude indicator not valid, must be \'K\','
+                      '\'B\', or \'M\''))
+  numeral = float(size_str[0:len(size_str)-1])
+  if magnitude == 'K':
+    numeral *= 1024
+  elif magnitude == 'M':
+    numeral *= 1048576
+  return int(numeral)
+
+
+class DirectoryZipper(object):
+  """Class to compress a directory and all its sub-directories."""  
+  current_archive = None
+  output_dir = None
+  base_path = None
+  max_size = None
+  compress = None
+  index_fp = None
+
+  def __init__(self, output_path, base_dir, archive_size, enable_compression):
+    """DirectoryZipper constructor.
+
+    Args:
+      output_path: the path to write the archives and index file to
+      base_dir: the directory to compress
+      archive_size: the maximum size, in bytes, of a single archive file
+      enable_compression: whether or not compression should be enabled, if
+        disabled, the files will be written into an uncompresed zip
+    """
+    self.output_dir = output_path
+    self.current_archive = '0.zip'
+    self.base_path = base_dir
+    self.max_size = archive_size
+    self.compress = enable_compression
+
+  def StartCompress(self):
+    """Start compress of the directory.
+
+    This will start the compression process and write the archives to the
+    specified output directory. It will also produce an 'index.txt' file in the
+    output directory that maps from file to archive.
+    """
+    self.index_fp = open(''.join([self.output_dir, 'main.py']), 'w')
+    self.index_fp.write(divide_and_compress_constants.file_preamble)
+    os.path.walk(self.base_path, self.CompressDirectory, 1)
+    self.index_fp.write(divide_and_compress_constants.file_endpiece)
+    self.index_fp.close()
+
+  def RemoveLastFile(self, archive_path=None):
+    """Removes the last item in the archive.
+
+    This removes the last item in the archive by reading the items out of the
+    archive, adding them to a new archive, deleting the old archive, and
+    moving the new archive to the location of the old archive.
+
+    Args:
+      archive_path: Path to the archive to modify. This archive should not be
+        open elsewhere, since it will need to be deleted.
+    Return:
+      A new ZipFile object that points to the modified archive file
+    """
+    if archive_path is None:
+      archive_path = ''.join([self.output_dir, self.current_archive])
+
+    # Move the old file and create a new one at its old location
+    ext_offset = archive_path.rfind('.')
+    old_archive = ''.join([archive_path[0:ext_offset], '-old',
+                           archive_path[ext_offset:]])
+    os.rename(archive_path, old_archive)
+    old_fp = self.OpenZipFileAtPath(old_archive, mode='r')
+
+    if self.compress:
+      new_fp = self.OpenZipFileAtPath(archive_path,
+                                      mode='w',
+                                      compress=zipfile.ZIP_DEFLATED)
+    else:
+      new_fp = self.OpenZipFileAtPath(archive_path,
+                                      mode='w',
+                                      compress=zipfile.ZIP_STORED)
+    
+    # Read the old archive in a new archive, except the last one
+    zip_members = enumerate(old_fp.infolist())
+    num_members = len(old_fp.infolist())
+    while num_members > 1:
+      this_member = zip_members.next()[1]
+      new_fp.writestr(this_member.filename, old_fp.read(this_member.filename))
+      num_members -= 1
+
+    # Close files and delete the old one
+    old_fp.close()
+    new_fp.close()
+    os.unlink(old_archive)
+
+  def OpenZipFileAtPath(self, path, mode=None, compress=zipfile.ZIP_DEFLATED):
+    """This method is mainly for testing purposes, eg dependency injection."""
+    if mode is None:
+      if os.path.exists(path):
+        mode = 'a'
+      else:
+        mode = 'w'
+
+    if mode == 'r':
+      return ZipFile(path, mode)
+    else:
+      return ZipFile(path, mode, compress)
+
+  def CompressDirectory(self, irrelevant, dir_path, dir_contents):
+    """Method to compress the given directory.
+
+    This method compresses the directory 'dir_path'. It will add to an existing
+    zip file that still has space and create new ones as necessary to keep zip
+    file sizes under the maximum specified size. This also writes out the
+    mapping of files to archives to the self.index_fp file descriptor
+
+    Args:
+      irrelevant: a numeric identifier passed by the os.path.walk method, this
+        is not used by this method
+      dir_path: the path to the directory to compress
+      dir_contents: a list of directory contents to be compressed
+    """
+    
+    # construct the queue of files to be added that this method will use
+    # it seems that dir_contents is given in reverse alphabetical order,
+    # so put them in alphabetical order by inserting to front of the list
+    dir_contents.sort()
+    zip_queue = []
+    if dir_path[len(dir_path) - 1:] == os.sep:
+      for filename in dir_contents:
+        zip_queue.append(''.join([dir_path, filename]))
+    else:
+      for filename in dir_contents:
+        zip_queue.append(''.join([dir_path, os.sep, filename]))
+    compress_bit = zipfile.ZIP_DEFLATED
+    if not self.compress:
+      compress_bit = zipfile.ZIP_STORED
+
+    # zip all files in this directory, adding to existing archives and creating
+    # as necessary
+    while len(zip_queue) > 0:
+      target_file = zip_queue[0]
+      if os.path.isfile(target_file):
+        self.AddFileToArchive(target_file, compress_bit)
+        
+        # see if adding the new file made our archive too large
+        if not self.ArchiveIsValid():
+          
+          # IF fixing fails, the last added file was to large, skip it
+          # ELSE the current archive filled normally, make a new one and try
+          #  adding the file again
+          if not self.FixArchive('SIZE'):
+            zip_queue.pop(0)
+          else:
+            self.current_archive = '%i.zip' % (
+                int(self.current_archive[
+                    0:self.current_archive.rfind('.zip')]) + 1)
+        else:
+
+          # if this the first file in the archive, write an index record
+          self.WriteIndexRecord()
+          zip_queue.pop(0)
+      else:
+        zip_queue.pop(0)
+
+  def WriteIndexRecord(self):
+    """Write an index record to the index file.
+
+    Only write an index record if this is the first file to go into archive
+
+    Returns:
+      True if an archive record is written, False if it isn't
+    """
+    archive = self.OpenZipFileAtPath(
+        ''.join([self.output_dir, self.current_archive]), 'r')
+    archive_index = archive.infolist()
+    if len(archive_index) == 1:
+      self.index_fp.write(
+          '[\'%s\', \'%s\'],\n' % (self.current_archive,
+                                   archive_index[0].filename))
+      archive.close()
+      return True
+    else:
+      archive.close()
+      return False
+
+  def FixArchive(self, problem):
+    """Make the archive compliant.
+
+    Args:
+      problem: the reason the archive is invalid
+
+    Returns:
+      Whether the file(s) removed to fix the archive could conceivably be
+      in an archive, but for some reason can't be added to this one.
+    """
+    archive_path = ''.join([self.output_dir, self.current_archive])
+    rtn_value = None
+    
+    if problem == 'SIZE':
+      archive_obj = self.OpenZipFileAtPath(archive_path, mode='r')
+      num_archive_files = len(archive_obj.infolist())
+      
+      # IF there is a single file, that means its too large to compress,
+      # delete the created archive
+      # ELSE do normal finalization
+      if num_archive_files == 1:
+        print ('WARNING: %s%s is too large to store.' % (
+            self.base_path, archive_obj.infolist()[0].filename))
+        archive_obj.close()
+        os.unlink(archive_path)
+        rtn_value = False
+      else:
+        self.RemoveLastFile(''.join([self.output_dir, self.current_archive]))
+        archive_obj.close()
+        print 'Final archive size for %s is %i' % (
+            self.current_archive, os.stat(archive_path)[stat.ST_SIZE])
+        rtn_value = True
+    return rtn_value
+
+  def AddFileToArchive(self, filepath, compress_bit):
+    """Add the file at filepath to the current archive.
+
+    Args:
+      filepath: the path of the file to add
+      compress_bit: whether or not this fiel should be compressed when added
+
+    Returns:
+      True if the file could be added (typically because this is a file) or
+      False if it couldn't be added (typically because its a directory)
+    """
+    curr_archive_path = ''.join([self.output_dir, self.current_archive])
+    if os.path.isfile(filepath):
+      if os.stat(filepath)[stat.ST_SIZE] > 1048576:
+        print 'Warning: %s is potentially too large to serve on GAE' % filepath
+      archive = self.OpenZipFileAtPath(curr_archive_path,
+                                       compress=compress_bit)
+      # add the file to the archive
+      archive.write(filepath, filepath[len(self.base_path):])
+      archive.close()
+      return True
+    else:
+      return False
+
+  def ArchiveIsValid(self):
+    """Check whether the archive is valid.
+
+    Currently this only checks whether the archive is under the required size.
+    The thought is that eventually this will do additional validation
+
+    Returns:
+      True if the archive is valid, False if its not
+    """
+    archive_path = ''.join([self.output_dir, self.current_archive])
+    if os.stat(archive_path)[stat.ST_SIZE] > self.max_size:
+      return False
+    else:
+      return True
+
+if __name__ == '__main__':
+  Main(sys.argv)
diff --git a/tools/scripts/divide_and_compress_constants.py b/tools/scripts/divide_and_compress_constants.py
new file mode 100644
index 0000000..4e11b6f
--- /dev/null
+++ b/tools/scripts/divide_and_compress_constants.py
@@ -0,0 +1,60 @@
+#!/usr/bin/python2.4
+#
+# Copyright (C) 2008 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""Constants for the divide_and_compress script and DirectoryZipper class."""
+
+__author__ = 'jmatt@google.com (Justin Mattson)'
+
+file_preamble = ('#!/usr/bin/env python\n'
+                 '#\n'
+                 '# Copyright 2008 Google Inc.\n'
+                 '#\n'                                                       
+                 '# Licensed under the Apache License, Version 2.0 (the' 
+                 '\"License");\n'                               
+                 '# you may not use this file except in compliance with the '
+                 'License.\n'                                                 
+                 '# You may obtain a copy of the License at\n'           
+                 '#\n'
+                 '#     http://www.apache.org/licenses/LICENSE-2.0\n'
+                 '#\n'
+                 '# Unless required by applicable law or agreed to in writing,'
+                 ' software\n'                                              
+                 '# distributed under the License is distributed on an \"AS' 
+                 'IS\" BASIS,\n'
+                 '# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either '
+                 'express or implied.\n'
+                 '# See the License for the specific language governing' 
+                 ' permissions and\n'
+                 '# limitations under the License.\n'
+                 '#\n\n'
+                 'import wsgiref.handlers\n'
+                 'from google.appengine.ext import zipserve\n'
+                 'from google.appengine.ext import webapp\n'
+                 'import memcache_zipserve\n\n\n'
+                 'class MainHandler(webapp.RequestHandler):\n\n'
+                 '  def get(self):\n'
+                 '    self.response.out.write(\'Hello world!\')\n\n'
+                 'def main():\n'
+                 '  application = webapp.WSGIApplication([(\'/(.*)\','
+                 ' memcache_zipserve.create_handler([')
+
+file_endpiece = ('])),\n'
+                 '],\n'
+                 'debug=False)\n'
+                 '  wsgiref.handlers.CGIHandler().run(application)\n\n'
+                 'if __name__ == \'__main__\':\n'
+                 '  main()')
diff --git a/tools/scripts/iml.template b/tools/scripts/iml.template
new file mode 100644
index 0000000..c4fe3a3
--- /dev/null
+++ b/tools/scripts/iml.template
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module version="4" relativePaths="true" type="JAVA_MODULE">
+  <component name="ModuleRootManager" />
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="android" level="project" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntryProperties />
+  </component>
+</module>
diff --git a/tools/scripts/ipr.template b/tools/scripts/ipr.template
new file mode 100644
index 0000000..cb3d65e
--- /dev/null
+++ b/tools/scripts/ipr.template
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4" relativePaths="false">
+  <component name="AntConfiguration">
+    <defaultAnt bundledAnt="true" />
+    <buildFile url="file://$PROJECT_DIR$/build.xml">
+      <additionalClassPath />
+      <antReference projectDefault="true" />
+      <customJdkName value="" />
+      <maximumHeapSize value="128" />
+      <properties />
+    </buildFile>
+  </component>
+  <component name="BuildJarProjectSettings">
+    <option name="BUILD_JARS_ON_MAKE" value="false" />
+  </component>
+  <component name="CodeStyleProjectProfileManger">
+    <option name="PROJECT_PROFILE" />
+    <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
+  </component>
+  <component name="CodeStyleSettingsManager">
+    <option name="PER_PROJECT_SETTINGS" />
+    <option name="USE_PER_PROJECT_SETTINGS" value="false" />
+  </component>
+  <component name="CompilerConfiguration">
+    <option name="DEFAULT_COMPILER" value="Javac" />
+    <option name="DEPLOY_AFTER_MAKE" value="0" />
+    <resourceExtensions>
+      <entry name=".+\.(properties|xml|html|dtd|tld)" />
+      <entry name=".+\.(gif|png|jpeg|jpg)" />
+    </resourceExtensions>
+    <wildcardResourcePatterns>
+      <entry name="?*.properties" />
+      <entry name="?*.xml" />
+      <entry name="?*.gif" />
+      <entry name="?*.png" />
+      <entry name="?*.jpeg" />
+      <entry name="?*.jpg" />
+      <entry name="?*.html" />
+      <entry name="?*.dtd" />
+      <entry name="?*.tld" />
+    </wildcardResourcePatterns>
+  </component>
+  <component name="DataSourceManagerImpl" />
+  <component name="DependenciesAnalyzeManager">
+    <option name="myForwardDirection" value="false" />
+  </component>
+  <component name="DependencyValidationManager" />
+  <component name="EclipseCompilerSettings">
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="true" />
+    <option name="DEPRECATION" value="false" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+    <option name="MAXIMUM_HEAP_SIZE" value="128" />
+  </component>
+  <component name="EclipseEmbeddedCompilerSettings">
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="true" />
+    <option name="DEPRECATION" value="false" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+    <option name="MAXIMUM_HEAP_SIZE" value="128" />
+  </component>
+  <component name="EntryPointsManager">
+    <entry_points />
+  </component>
+  <component name="ExportToHTMLSettings">
+    <option name="PRINT_LINE_NUMBERS" value="false" />
+    <option name="OPEN_IN_BROWSER" value="false" />
+    <option name="OUTPUT_DIRECTORY" />
+  </component>
+  <component name="GUI Designer component loader factory" />
+  <component name="IdProvider" IDEtalkID="F6EC4D80E2C03FEF19EDD201903A6DFE" />
+  <component name="InspectionProjectProfileManager">
+    <option name="PROJECT_PROFILE" value="Project Default" />
+    <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
+    <scopes />
+    <profiles>
+      <profile version="1.0" is_locked="false">
+        <option name="myName" value="Project Default" />
+        <option name="myLocal" value="false" />
+        <used_levels>
+          <error>
+            <option name="myName" value="ERROR" />
+            <option name="myVal" value="400" />
+          </error>
+          <warning>
+            <option name="myName" value="WARNING" />
+            <option name="myVal" value="300" />
+          </warning>
+          <information>
+            <option name="myName" value="INFO" />
+            <option name="myVal" value="200" />
+          </information>
+          <server>
+            <option name="myName" value="SERVER PROBLEM" />
+            <option name="myVal" value="100" />
+          </server>
+        </used_levels>
+        <inspection_tool class="ClassReferencesSubclass" level="WARNING" enabled="true" />
+        <inspection_tool class="MissingOverrideAnnotation" level="WARNING" enabled="true" />
+        <inspection_tool class="Finalize" level="WARNING" enabled="true" />
+        <inspection_tool class="UnusedImport" level="WARNING" enabled="true" />
+        <inspection_tool class="StaticInheritance" level="WARNING" enabled="true" />
+        <inspection_tool class="RedundantMethodOverride" level="WARNING" enabled="true" />
+        <inspection_tool class="AbstractMethodCallInConstructor" level="WARNING" enabled="true" />
+        <inspection_tool class="RawUseOfParameterizedType" level="WARNING" enabled="true">
+          <option name="ignoreObjectConstruction" value="true" />
+          <option name="ignoreTypeCasts" value="false" />
+        </inspection_tool>
+        <inspection_tool class="SystemGC" level="WARNING" enabled="true" />
+        <inspection_tool class="ConstantNamingConvention" level="WARNING" enabled="true">
+          <option name="m_regex" value="[A-Z_\d]*" />
+          <option name="m_minLength" value="5" />
+          <option name="m_maxLength" value="32" />
+        </inspection_tool>
+        <inspection_tool class="EnumeratedConstantNamingConvention" level="WARNING" enabled="true">
+          <option name="m_regex" value="[A-Z][A-Za-z\d]*" />
+          <option name="m_minLength" value="5" />
+          <option name="m_maxLength" value="32" />
+        </inspection_tool>
+        <inspection_tool class="DivideByZero" level="WARNING" enabled="true" />
+        <inspection_tool class="CloneCallsConstructors" level="WARNING" enabled="true" />
+        <inspection_tool class="CloneDeclaresCloneNotSupported" level="WARNING" enabled="false" />
+        <inspection_tool class="CloneInNonCloneableClass" level="WARNING" enabled="true" />
+        <inspection_tool class="UtilityClassWithoutPrivateConstructor" level="WARNING" enabled="true">
+          <option name="ignoreClassesWithOnlyMain" value="false" />
+        </inspection_tool>
+        <inspection_tool class="UtilityClassWithPublicConstructor" level="WARNING" enabled="true" />
+        <inspection_tool class="ConditionalExpressionWithIdenticalBranches" level="WARNING" enabled="true" />
+        <inspection_tool class="CanBeFinal" level="WARNING" enabled="false">
+          <option name="REPORT_CLASSES" value="false" />
+          <option name="REPORT_METHODS" value="false" />
+          <option name="REPORT_FIELDS" value="true" />
+        </inspection_tool>
+        <inspection_tool class="ThisEscapedInConstructor" level="WARNING" enabled="true" />
+        <inspection_tool class="NonThreadSafeLazyInitialization" level="WARNING" enabled="true" />
+        <inspection_tool class="FieldMayBeStatic" level="WARNING" enabled="true" />
+        <inspection_tool class="InnerClassMayBeStatic" level="WARNING" enabled="true" />
+        <inspection_tool class="MethodMayBeStatic" level="WARNING" enabled="true">
+          <option name="m_onlyPrivateOrFinal" value="false" />
+          <option name="m_ignoreEmptyMethods" value="true" />
+        </inspection_tool>
+        <inspection_tool class="ComponentRegistrationProblems" level="ERROR" enabled="false">
+          <option name="CHECK_PLUGIN_XML" value="true" />
+          <option name="CHECK_JAVA_CODE" value="true" />
+          <option name="CHECK_ACTIONS" value="true" />
+        </inspection_tool>
+        <inspection_tool class="ComponentNotRegistered" level="WARNING" enabled="false">
+          <option name="CHECK_ACTIONS" value="true" />
+          <option name="IGNORE_NON_PUBLIC" value="true" />
+        </inspection_tool>
+        <inspection_tool class="BusyWait" level="WARNING" enabled="true" />
+        <inspection_tool class="UnconditionalWait" level="WARNING" enabled="true" />
+        <inspection_tool class="WaitNotInLoop" level="WARNING" enabled="true" />
+      </profile>
+    </profiles>
+  </component>
+  <component name="JavacSettings">
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="false" />
+    <option name="DEPRECATION" value="true" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+    <option name="MAXIMUM_HEAP_SIZE" value="128" />
+  </component>
+  <component name="JavadocGenerationManager">
+    <option name="OUTPUT_DIRECTORY" />
+    <option name="OPTION_SCOPE" value="protected" />
+    <option name="OPTION_HIERARCHY" value="true" />
+    <option name="OPTION_NAVIGATOR" value="true" />
+    <option name="OPTION_INDEX" value="true" />
+    <option name="OPTION_SEPARATE_INDEX" value="true" />
+    <option name="OPTION_DOCUMENT_TAG_USE" value="false" />
+    <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
+    <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
+    <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
+    <option name="OPTION_DEPRECATED_LIST" value="true" />
+    <option name="OTHER_OPTIONS" value="" />
+    <option name="HEAP_SIZE" />
+    <option name="LOCALE" />
+    <option name="OPEN_IN_BROWSER" value="true" />
+  </component>
+  <component name="JikesSettings">
+    <option name="JIKES_PATH" value="" />
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="DEPRECATION" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="false" />
+    <option name="IS_EMACS_ERRORS_MODE" value="true" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+  </component>
+  <component name="LogConsolePreferences">
+    <option name="FILTER_ERRORS" value="false" />
+    <option name="FILTER_WARNINGS" value="false" />
+    <option name="FILTER_INFO" value="true" />
+    <option name="CUSTOM_FILTER" />
+  </component>
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/ACTIVITY_NAME.iml" filepath="$PROJECT_DIR$/ACTIVITY_NAME.iml" />
+    </modules>
+  </component>
+  <component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/bin" />
+  </component>
+  <component name="ProjectRunConfigurationManager" />
+  <component name="RmicSettings">
+    <option name="IS_EANABLED" value="false" />
+    <option name="DEBUGGING_INFO" value="true" />
+    <option name="GENERATE_NO_WARNINGS" value="false" />
+    <option name="GENERATE_IIOP_STUBS" value="false" />
+    <option name="ADDITIONAL_OPTIONS_STRING" value="" />
+  </component>
+  <component name="StarteamVcsAdapter" />
+  <component name="XSLT-Support.FileAssociationsManager" />
+  <component name="com.intellij.jsf.UserDefinedFacesConfigs">
+    <option name="USER_DEFINED_CONFIGS">
+      <value>
+        <list size="0" />
+      </value>
+    </option>
+  </component>
+  <component name="libraryTable">
+    <library name="android">
+      <CLASSES>
+        <root url="jar://ANDROID_SDK_FOLDER/android.jar!/" />
+      </CLASSES>
+      <JAVADOC>
+        <root url="file://ANDROID_SDK_FOLDER/docs/reference" />
+      </JAVADOC>
+      <SOURCES />
+    </library>
+  </component>
+  <UsedPathMacros />
+</project>
diff --git a/tools/scripts/iws.template b/tools/scripts/iws.template
new file mode 100644
index 0000000..67d2053
--- /dev/null
+++ b/tools/scripts/iws.template
@@ -0,0 +1,470 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4" relativePaths="false">
+  <component name="AntConfiguration">
+    <defaultAnt bundledAnt="true" />
+    <buildFile url="file://$PROJECT_DIR$/build.xml">
+      <additionalClassPath />
+      <antReference projectDefault="true" />
+      <customJdkName value="" />
+      <maximumHeapSize value="128" />
+      <properties />
+    </buildFile>
+  </component>
+  <component name="BookmarkManager" />
+  <component name="ChangeBrowserSettings">
+    <option name="MAIN_SPLITTER_PROPORTION" value="0.3" />
+    <option name="MESSAGES_SPLITTER_PROPORTION" value="0.8" />
+    <option name="USE_DATE_BEFORE_FILTER" value="false" />
+    <option name="USE_DATE_AFTER_FILTER" value="false" />
+    <option name="USE_CHANGE_BEFORE_FILTER" value="false" />
+    <option name="USE_CHANGE_AFTER_FILTER" value="false" />
+    <option name="DATE_BEFORE" value="" />
+    <option name="DATE_AFTER" value="" />
+    <option name="CHANGE_BEFORE" value="" />
+    <option name="CHANGE_AFTER" value="" />
+    <option name="USE_USER_FILTER" value="false" />
+    <option name="USER" value="" />
+  </component>
+  <component name="ChangeListManager">
+    <list default="true" name="Default" comment="" />
+  </component>
+  <component name="ChangeListSynchronizer" />
+  <component name="ChangesViewManager" flattened_view="true" />
+  <component name="CheckinPanelState" />
+  <component name="Commander">
+    <leftPanel />
+    <rightPanel />
+    <splitter proportion="0.5" />
+  </component>
+  <component name="CompilerWorkspaceConfiguration">
+    <option name="COMPILE_IN_BACKGROUND" value="false" />
+    <option name="AUTO_SHOW_ERRORS_IN_EDITOR" value="true" />
+    <option name="CLOSE_MESSAGE_VIEW_IF_SUCCESS" value="true" />
+    <option name="COMPILE_DEPENDENT_FILES" value="false" />
+    <option name="CLEAR_OUTPUT_DIRECTORY" value="false" />
+    <option name="ASSERT_NOT_NULL" value="true" />
+  </component>
+  <component name="CoverageDataManager" />
+  <component name="Cvs2Configuration">
+    <option name="PRUNE_EMPTY_DIRECTORIES" value="true" />
+    <option name="MERGING_MODE" value="0" />
+    <option name="MERGE_WITH_BRANCH1_NAME" value="HEAD" />
+    <option name="MERGE_WITH_BRANCH2_NAME" value="HEAD" />
+    <option name="RESET_STICKY" value="false" />
+    <option name="CREATE_NEW_DIRECTORIES" value="true" />
+    <option name="DEFAULT_TEXT_FILE_SUBSTITUTION" value="kv" />
+    <option name="PROCESS_UNKNOWN_FILES" value="false" />
+    <option name="PROCESS_DELETED_FILES" value="false" />
+    <option name="PROCESS_IGNORED_FILES" value="false" />
+    <option name="RESERVED_EDIT" value="false" />
+    <option name="CHECKOUT_DATE_OR_REVISION_SETTINGS">
+      <value>
+        <option name="BRANCH" value="" />
+        <option name="DATE" value="" />
+        <option name="USE_BRANCH" value="false" />
+        <option name="USE_DATE" value="false" />
+      </value>
+    </option>
+    <option name="UPDATE_DATE_OR_REVISION_SETTINGS">
+      <value>
+        <option name="BRANCH" value="" />
+        <option name="DATE" value="" />
+        <option name="USE_BRANCH" value="false" />
+        <option name="USE_DATE" value="false" />
+      </value>
+    </option>
+    <option name="SHOW_CHANGES_REVISION_SETTINGS">
+      <value>
+        <option name="BRANCH" value="" />
+        <option name="DATE" value="" />
+        <option name="USE_BRANCH" value="false" />
+        <option name="USE_DATE" value="false" />
+      </value>
+    </option>
+    <option name="SHOW_OUTPUT" value="false" />
+    <option name="ADD_WATCH_INDEX" value="0" />
+    <option name="REMOVE_WATCH_INDEX" value="0" />
+    <option name="UPDATE_KEYWORD_SUBSTITUTION" />
+    <option name="MAKE_NEW_FILES_READONLY" value="false" />
+    <option name="SHOW_CORRUPTED_PROJECT_FILES" value="0" />
+    <option name="TAG_AFTER_PROJECT_COMMIT" value="false" />
+    <option name="OVERRIDE_EXISTING_TAG_FOR_PROJECT" value="true" />
+    <option name="TAG_AFTER_PROJECT_COMMIT_NAME" value="" />
+    <option name="CLEAN_COPY" value="false" />
+  </component>
+  <component name="DaemonCodeAnalyzer">
+    <disable_hints />
+  </component>
+  <component name="DebuggerManager">
+    <breakpoint_any>
+      <breakpoint>
+        <option name="NOTIFY_CAUGHT" value="true" />
+        <option name="NOTIFY_UNCAUGHT" value="true" />
+        <option name="ENABLED" value="false" />
+        <option name="SUSPEND_POLICY" value="SuspendAll" />
+        <option name="LOG_ENABLED" value="false" />
+        <option name="LOG_EXPRESSION_ENABLED" value="false" />
+        <option name="COUNT_FILTER_ENABLED" value="false" />
+        <option name="COUNT_FILTER" value="0" />
+        <option name="CONDITION_ENABLED" value="false" />
+        <option name="CLASS_FILTERS_ENABLED" value="false" />
+        <option name="INSTANCE_FILTERS_ENABLED" value="false" />
+        <option name="CONDITION" value="" />
+        <option name="LOG_MESSAGE" value="" />
+      </breakpoint>
+      <breakpoint>
+        <option name="NOTIFY_CAUGHT" value="true" />
+        <option name="NOTIFY_UNCAUGHT" value="true" />
+        <option name="ENABLED" value="false" />
+        <option name="SUSPEND_POLICY" value="SuspendAll" />
+        <option name="LOG_ENABLED" value="false" />
+        <option name="LOG_EXPRESSION_ENABLED" value="false" />
+        <option name="COUNT_FILTER_ENABLED" value="false" />
+        <option name="COUNT_FILTER" value="0" />
+        <option name="CONDITION_ENABLED" value="false" />
+        <option name="CLASS_FILTERS_ENABLED" value="false" />
+        <option name="INSTANCE_FILTERS_ENABLED" value="false" />
+        <option name="CONDITION" value="" />
+        <option name="LOG_MESSAGE" value="" />
+      </breakpoint>
+    </breakpoint_any>
+    <breakpoint_rules />
+    <ui_properties />
+  </component>
+  <component name="ErrorTreeViewConfiguration">
+    <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
+    <option name="HIDE_WARNINGS" value="false" />
+  </component>
+  <component name="FavoritesManager">
+    <favorites_list name="LunarLander" />
+  </component>
+  <component name="FavoritesProjectViewPane" />
+	<component name="FileEditorManager">
+    <leaf>
+      <file leaf-file-name="ACTIVITY_NAME.java" pinned="false" current="true" current-in-tab="true">
+        <entry file="file://$PROJECT_DIR$/src/PACKAGE_PATH/ACTIVITY_NAME.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.08211144">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+    </leaf>
+  </component>
+  <component name="FindManager">
+    <FindUsagesManager>
+      <setting name="OPEN_NEW_TAB" value="false" />
+    </FindUsagesManager>
+  </component>
+  <component name="HierarchyBrowserManager">
+    <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
+    <option name="SORT_ALPHABETICALLY" value="false" />
+    <option name="HIDE_CLASSES_WHERE_METHOD_NOT_IMPLEMENTED" value="false" />
+  </component>
+  <component name="InspectionManager">
+    <option name="AUTOSCROLL_TO_SOURCE" value="false" />
+    <option name="SPLITTER_PROPORTION" value="0.5" />
+    <option name="GROUP_BY_SEVERITY" value="false" />
+    <option name="FILTER_RESOLVED_ITEMS" value="true" />
+    <option name="ANALYZE_TEST_SOURCES" value="true" />
+    <option name="SHOW_DIFF_WITH_PREVIOUS_RUN" value="false" />
+    <option name="SCOPE_TYPE" value="1" />
+    <option name="CUSTOM_SCOPE_NAME" value="" />
+    <option name="SHOW_ONLY_DIFF" value="false" />
+    <option name="myCurrentProfileName" value="Default" />
+  </component>
+  <component name="J2EEProjectPane" />
+  <component name="JspContextManager" />
+  <component name="ModuleEditorState">
+    <option name="LAST_EDITED_MODULE_NAME" />
+    <option name="LAST_EDITED_TAB_NAME" />
+  </component>
+  <component name="NamedScopeManager" />
+  <component name="PackagesPane">
+    <subPane>
+      <PATH>
+        <PATH_ELEMENT>
+          <option name="myItemId" value="ACTIVITY_NAME.ipr" />
+          <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" />
+        </PATH_ELEMENT>
+        <PATH_ELEMENT>
+          <option name="myItemId" value="ACTIVITY_NAME" />
+          <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewModuleNode" />
+        </PATH_ELEMENT>
+      </PATH>
+    </subPane>
+  </component>
+  <component name="PerforceChangeBrowserSettings">
+    <option name="USE_CLIENT_FILTER" value="true" />
+    <option name="CLIENT" value="" />
+  </component>
+  <component name="PerforceDirect.Settings">
+    <option name="useP4CONFIG" value="true" />
+    <option name="port" value="&lt;perforce_server&gt;:1666" />
+    <option name="client" value="" />
+    <option name="user" value="" />
+    <option name="passwd" value="" />
+    <option name="showCmds" value="false" />
+    <option name="useNativeApi" value="false" />
+    <option name="pathToExec" value="p4" />
+    <option name="useCustomPathToExec" value="false" />
+    <option name="SYNC_FORCE" value="false" />
+    <option name="SYNC_RUN_RESOLVE" value="true" />
+    <option name="REVERT_UNCHANGED_FILES" value="true" />
+    <option name="CHARSET" value="none" />
+    <option name="SHOW_BRANCHES_HISTORY" value="true" />
+    <option name="ENABLED" value="true" />
+    <option name="USE_LOGIN" value="false" />
+    <option name="LOGIN_SILENTLY" value="false" />
+    <option name="INTEGRATE_RUN_RESOLVE" value="true" />
+    <option name="INTEGRATE_REVERT_UNCHANGED" value="true" />
+    <option name="SERVER_TIMEOUT" value="20000" />
+  </component>
+  <component name="ProjectLevelVcsManager">
+    <OptionsSetting value="true" id="Add" />
+    <OptionsSetting value="true" id="Remove" />
+    <OptionsSetting value="true" id="Checkin" />
+    <OptionsSetting value="true" id="Checkout" />
+    <OptionsSetting value="true" id="Update" />
+    <OptionsSetting value="true" id="Status" />
+    <OptionsSetting value="true" id="Edit" />
+    <ConfirmationsSetting value="0" id="Add" />
+    <ConfirmationsSetting value="0" id="Remove" />
+  </component>
+  <component name="ProjectPane">
+    <subPane>
+      <PATH>
+        <PATH_ELEMENT>
+          <option name="myItemId" value="ACTIVITY_NAME.ipr" />
+          <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+        </PATH_ELEMENT>
+        <PATH_ELEMENT>
+          <option name="myItemId" value="ACTIVITY_NAME" />
+          <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
+        </PATH_ELEMENT>
+      </PATH>
+    </subPane>
+  </component>
+  <component name="ProjectReloadState">
+    <option name="STATE" value="0" />
+  </component>
+  <component name="ProjectView">
+    <navigator currentView="ProjectPane" proportions="0.1" version="1" splitterProportion="0.5">
+      <flattenPackages />
+      <showMembers />
+      <showModules />
+      <showLibraryContents />
+      <hideEmptyPackages />
+      <abbreviatePackageNames />
+      <showStructure PackagesPane="false" ProjectPane="false" />
+      <autoscrollToSource />
+      <autoscrollFromSource />
+      <sortByType />
+    </navigator>
+  </component>
+  <component name="PropertiesComponent">
+    <property name="MemberChooser.copyJavadoc" value="false" />
+    <property name="GoToClass.includeLibraries" value="false" />
+    <property name="MemberChooser.showClasses" value="true" />
+    <property name="MemberChooser.sorted" value="false" />
+    <property name="GoToFile.includeJavaFiles" value="false" />
+    <property name="GoToClass.toSaveIncludeLibraries" value="false" />
+  </component>
+  <component name="ReadonlyStatusHandler">
+    <option name="SHOW_DIALOG" value="true" />
+  </component>
+  <component name="RecentsManager" />
+  <component name="RestoreUpdateTree" />
+  <component name="RunManager">
+    <configuration default="true" type="Application" factoryName="Application" enabled="false" merge="false">
+      <option name="MAIN_CLASS_NAME" />
+      <option name="VM_PARAMETERS" />
+      <option name="PROGRAM_PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="ENABLE_SWING_INSPECTOR" value="false" />
+      <module name="" />
+    </configuration>
+    <configuration default="true" type="Applet" factoryName="Applet">
+      <module name="" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="HTML_FILE_NAME" />
+      <option name="HTML_USED" value="false" />
+      <option name="WIDTH" value="400" />
+      <option name="HEIGHT" value="300" />
+      <option name="POLICY_FILE" value="/Developer/Applications/IntelliJ IDEA 6.0.4.app/bin/appletviewer.policy" />
+      <option name="VM_PARAMETERS" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+    </configuration>
+    <configuration default="true" type="JUnit" factoryName="JUnit" enabled="false" merge="false">
+      <module name="" />
+      <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+      <option name="ALTERNATIVE_JRE_PATH" />
+      <option name="PACKAGE_NAME" />
+      <option name="MAIN_CLASS_NAME" />
+      <option name="METHOD_NAME" />
+      <option name="TEST_OBJECT" value="class" />
+      <option name="VM_PARAMETERS" />
+      <option name="PARAMETERS" />
+      <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+      <option name="ADDITIONAL_CLASS_PATH" />
+      <option name="TEST_SEARCH_SCOPE">
+        <value defaultName="wholeProject" />
+      </option>
+    </configuration>
+    <configuration default="true" type="Remote" factoryName="Remote">
+      <option name="USE_SOCKET_TRANSPORT" value="true" />
+      <option name="SERVER_MODE" value="false" />
+      <option name="SHMEM_ADDRESS" value="javadebug" />
+      <option name="HOST" value="localhost" />
+      <option name="PORT" value="5005" />
+    </configuration>
+  </component>
+  <component name="ScopeViewComponent" />
+  <component name="SelectInManager" />
+  <component name="StarteamConfiguration">
+    <option name="SERVER" value="" />
+    <option name="PORT" value="49201" />
+    <option name="USER" value="" />
+    <option name="PASSWORD" value="" />
+    <option name="PROJECT" value="" />
+    <option name="VIEW" value="" />
+    <option name="ALTERNATIVE_WORKING_PATH" value="" />
+    <option name="LOCK_ON_CHECKOUT" value="false" />
+    <option name="UNLOCK_ON_CHECKIN" value="false" />
+  </component>
+  <component name="StructuralSearchPlugin" />
+  <component name="StructureViewFactory">
+    <option name="AUTOSCROLL_MODE" value="true" />
+    <option name="AUTOSCROLL_FROM_SOURCE" value="false" />
+    <option name="ACTIVE_ACTIONS" value="" />
+  </component>
+  <component name="Struts Assistant">
+    <option name="showInputs" value="true" />
+    <option name="resources">
+      <value>
+        <option name="strutsPath" />
+        <option name="strutsHelp" />
+      </value>
+    </option>
+    <option name="selectedTaglibs" />
+    <option name="selectedTaglibs" />
+    <option name="myStrutsValidationEnabled" value="true" />
+    <option name="myTilesValidationEnabled" value="true" />
+    <option name="myValidatorValidationEnabled" value="true" />
+    <option name="myReportErrorsAsWarnings" value="true" />
+  </component>
+  <component name="SvnChangesBrowserSettings">
+    <option name="USE_AUTHOR_FIELD" value="true" />
+    <option name="AUTHOR" value="" />
+    <option name="LOCATION" value="" />
+    <option name="USE_PROJECT_SETTINGS" value="true" />
+    <option name="USE_ALTERNATE_LOCATION" value="false" />
+  </component>
+  <component name="SvnConfiguration">
+    <option name="USER" value="" />
+    <option name="PASSWORD" value="" />
+    <option name="PROCESS_UNRESOLVED" value="false" />
+    <option name="LAST_MERGED_REVISION" />
+    <option name="UPDATE_RUN_STATUS" value="false" />
+    <option name="UPDATE_RECURSIVELY" value="true" />
+    <option name="MERGE_DRY_RUN" value="false" />
+    <upgradeMode>auto</upgradeMode>
+  </component>
+  <component name="TodoView" selected-index="0">
+    <todo-panel id="selected-file">
+      <are-packages-shown value="false" />
+      <are-modules-shown value="false" />
+      <flatten-packages value="false" />
+      <is-autoscroll-to-source value="true" />
+    </todo-panel>
+    <todo-panel id="all">
+      <are-packages-shown value="true" />
+      <are-modules-shown value="false" />
+      <flatten-packages value="false" />
+      <is-autoscroll-to-source value="true" />
+    </todo-panel>
+  </component>
+  <component name="ToolWindowManager">
+    <frame x="0" y="22" width="1440" height="834" extended-state="0" />
+    <editor active="false" />
+    <layout>
+      <window_info id="UI Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
+      <window_info id="CVS" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
+      <window_info id="IDEtalk" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
+      <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="7" />
+      <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.24946082" order="0" />
+      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="1" />
+      <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="1" />
+      <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
+      <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" order="6" />
+      <window_info id="Module Dependencies" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
+      <window_info id="Dependency Viewer" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
+      <window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
+      <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="1" />
+      <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
+      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="2" />
+      <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="2" />
+      <window_info id="File View" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
+      <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" order="4" />
+      <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" order="0" />
+      <window_info id="IDEtalk Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
+      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
+      <window_info id="Web" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="2" />
+      <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="0" />
+      <window_info id="EJB" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="3" />
+      <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="5" />
+    </layout>
+  </component>
+  <component name="VCS.FileViewConfiguration">
+    <option name="SELECTED_STATUSES" value="DEFAULT" />
+    <option name="SELECTED_COLUMNS" value="DEFAULT" />
+    <option name="SHOW_FILTERS" value="true" />
+    <option name="CUSTOMIZE_VIEW" value="true" />
+    <option name="SHOW_FILE_HISTORY_AS_TREE" value="true" />
+  </component>
+  <component name="VcsManagerConfiguration">
+    <option name="OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT" value="true" />
+    <option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="true" />
+    <option name="PERFORM_UPDATE_IN_BACKGROUND" value="false" />
+    <option name="PERFORM_COMMIT_IN_BACKGROUND" value="false" />
+    <option name="PUT_FOCUS_INTO_COMMENT" value="false" />
+    <option name="FORCE_NON_EMPTY_COMMENT" value="false" />
+    <option name="LAST_COMMIT_MESSAGE" />
+    <option name="SAVE_LAST_COMMIT_MESSAGE" value="true" />
+    <option name="CHECKIN_DIALOG_SPLITTER_PROPORTION" value="0.8" />
+    <option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="false" />
+    <option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="false" />
+    <option name="REFORMAT_BEFORE_FILE_COMMIT" value="false" />
+    <option name="FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION" value="0.8" />
+    <option name="FILE_HISTORY_DIALOG_SPLITTER_PROPORTION" value="0.5" />
+    <option name="ERROR_OCCURED" value="false" />
+    <option name="ACTIVE_VCS_NAME" value="CVS" />
+    <option name="UPDATE_GROUP_BY_PACKAGES" value="false" />
+    <option name="SHOW_FILE_HISTORY_AS_TREE" value="false" />
+    <option name="FILE_HISTORY_SPLITTER_PROPORTION" value="0.6" />
+  </component>
+  <component name="XPathView.XPathProjectComponent">
+    <history />
+    <find-history />
+  </component>
+  <component name="XSLT-Support.FileAssociationsSettings" />
+  <component name="antWorkspaceConfiguration">
+    <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
+    <option name="FILTER_TARGETS" value="false" />
+  </component>
+  <component name="com.intellij.ide.util.scopeChooser.ScopeChooserConfigurable" proportions="" version="1">
+    <option name="myLastEditedConfigurable" />
+  </component>
+  <component name="com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectRootMasterDetailsConfigurable" proportions="0.1" version="1">
+    <option name="myPlainMode" value="false" />
+    <option name="myLastEditedConfigurable" value="android" />
+  </component>
+  <component name="com.intellij.profile.ui.ErrorOptionsConfigurable" proportions="" version="1">
+    <option name="myLastEditedConfigurable" />
+  </component>
+  <component name="editorHistoryManager" />
+</project>
\ No newline at end of file
diff --git a/tools/scripts/java_file.template b/tools/scripts/java_file.template
new file mode 100644
index 0000000..aeb541f
--- /dev/null
+++ b/tools/scripts/java_file.template
@@ -0,0 +1,15 @@
+package PACKAGE;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class ACTIVITY_NAME extends Activity
+{
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+    }
+}
diff --git a/tools/scripts/java_tests_file.template b/tools/scripts/java_tests_file.template
new file mode 100644
index 0000000..7781a33
--- /dev/null
+++ b/tools/scripts/java_tests_file.template
@@ -0,0 +1,21 @@
+package PACKAGE;
+
+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 PACKAGE.ACTIVITY_NAMETest \
+ * PACKAGE.tests/android.test.InstrumentationTestRunner
+ */
+public class ACTIVITY_NAMETest extends ActivityInstrumentationTestCase<ACTIVITY_NAME> {
+
+    public ACTIVITY_NAMETest() {
+        super("PACKAGE", ACTIVITY_NAME.class);
+    }
+
+}
\ No newline at end of file
diff --git a/tools/scripts/layout.template b/tools/scripts/layout.template
new file mode 100644
index 0000000..864e997
--- /dev/null
+++ b/tools/scripts/layout.template
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    >
+<TextView  
+    android:layout_width="fill_parent" 
+    android:layout_height="wrap_content" 
+    android:text="Hello World, ACTIVITY_NAME"
+    />
+</LinearLayout>
+
diff --git a/tools/scripts/plugin.prop b/tools/scripts/plugin.prop
new file mode 100644
index 0000000..99dba4a
--- /dev/null
+++ b/tools/scripts/plugin.prop
@@ -0,0 +1,4 @@
+# begin plugin.prop
+plugin.version=0.9.0
+plugin.platform=android
+# end plugin.prop
\ No newline at end of file
diff --git a/tools/scripts/sdk_clean.sh b/tools/scripts/sdk_clean.sh
new file mode 100755
index 0000000..467d560
--- /dev/null
+++ b/tools/scripts/sdk_clean.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+#
+# This script processes a set of files given as arguments as sample code to be  released
+# in the SDK.
+#
+# Note that these files are modified in-place.
+#
+
+DIR=$1
+
+#
+# Remove BEGIN_INCLUDE and END_INCLUDE lines used by the javadoc.
+#
+# This does it by replacing these lines with blank lines so line numbers aren't
+# changed in the process, making it easier to match 3rd party complaints/questions
+# with the source tree.
+#
+# sed on Mac OS takes -i SUFFIX and sed on Linux takes -iSUFFIX
+#
+if [ $HOST_OS = darwin ] ; then
+find $DIR -name "*.java" -o -name "*.xml" | xargs -n 1 \
+    sed \
+        -e "s/.*BEGIN_INCLUDE(.*//" \
+        -e "s/.*END_INCLUDE(.*//" \
+        -i ""
+else
+find $DIR -name "*.java" -o -name "*.xml" | xargs -n 1 \
+    sed \
+        -e "s/.*BEGIN_INCLUDE(.*//" \
+        -e "s/.*END_INCLUDE(.*//" \
+        -i
+fi
+
+#
+# Fix up the line endings of all text files
+#
+if [ $HOST_OS = windows ] ; then
+    ENDING_TYPE=dos
+else
+    ENDING_TYPE=unix
+fi
+find $DIR -name "*.aidl" -o -name "*.css" -o -name "*.html" -o -name "*.java" \
+                     -o -name "*.js" -o -name "*.prop" -o -name "*.py" \
+                     -o -name "*.template" -o -name "*.txt" -o -name "*.windows" \
+                     -o -name "*.xml" \
+        | xargs $HOST_OUT_EXECUTABLES/line_endings $ENDING_TYPE
+
+
diff --git a/tools/scripts/strings.template b/tools/scripts/strings.template
new file mode 100644
index 0000000..acc28e2
--- /dev/null
+++ b/tools/scripts/strings.template
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">ACTIVITY_NAME</string>
+</resources>
diff --git a/tools/scripts/test_divide_and_compress.py b/tools/scripts/test_divide_and_compress.py
new file mode 100755
index 0000000..d0d27b3
--- /dev/null
+++ b/tools/scripts/test_divide_and_compress.py
@@ -0,0 +1,490 @@
+#!/usr/bin/python2.4
+#
+# Copyright (C) 2008 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""Tests for divide_and_compress.py.
+
+TODO: Add tests for module methods.
+"""
+
+__author__ = 'jmatt@google.com (Justin Mattson)'
+
+import os
+import stat
+import unittest
+import zipfile
+from zipfile import ZipFile
+
+import divide_and_compress
+from mox import mox
+
+
+class BagOfParts(object):
+  """Just a generic class that I can use to assign random attributes to."""
+
+  def NoOp(self):
+    x = 1
+
+    
+class ValidAndRemoveTests(unittest.TestCase):
+  """Test the ArchiveIsValid and RemoveLastFile methods."""
+  
+  def setUp(self):
+    """Prepare the test.
+
+    Construct some mock objects for use with the tests.
+    """
+    self.my_mox = mox.Mox()
+    file1 = BagOfParts()
+    file1.filename = 'file1.txt'
+    file1.contents = 'This is a test file'
+    file2 = BagOfParts()
+    file2.filename = 'file2.txt'
+    file2.contents = ('akdjfk;djsf;kljdslkfjslkdfjlsfjkdvn;kn;2389rtu4i'
+                      'tn;ghf8:89H*hp748FJw80fu9WJFpwf39pujens;fihkhjfk'
+                      'sdjfljkgsc n;iself')
+    self.files = {'file1': file1, 'file2': file2}
+
+  def testArchiveIsValid(self):
+    """Test the DirectoryZipper.ArchiveIsValid method.
+
+    Run two tests, one that we expect to pass and one that we expect to fail
+    """
+    test_file_size = 1056730
+    self.my_mox.StubOutWithMock(os, 'stat')
+    os.stat('/foo/0.zip').AndReturn([test_file_size])
+    self.my_mox.StubOutWithMock(stat, 'ST_SIZE')
+    stat.ST_SIZE = 0
+    os.stat('/baz/0.zip').AndReturn([test_file_size])
+    mox.Replay(os.stat)
+    test_target = divide_and_compress.DirectoryZipper('/foo/', 'bar', 
+                                                      test_file_size - 1, True)
+
+    self.assertEqual(False, test_target.ArchiveIsValid(),
+                     msg=('ERROR: Test failed, ArchiveIsValid should have '
+                          'returned false, but returned true'))
+
+    test_target = divide_and_compress.DirectoryZipper('/baz/', 'bar',
+                                                      test_file_size + 1, True)
+    self.assertEqual(True, test_target.ArchiveIsValid(),
+                     msg=('ERROR: Test failed, ArchiveIsValid should have'
+                          ' returned true, but returned false'))
+
+  def testRemoveLastFile(self):
+    """Test DirectoryZipper.RemoveLastFile method.
+
+    Construct a ZipInfo mock object with two records, verify that write is
+    only called once on the new ZipFile object.
+    """
+    source = self.CreateZipSource()
+    dest = self.CreateZipDestination()
+    source_path = ''.join([os.getcwd(), '/0-old.zip'])
+    dest_path = ''.join([os.getcwd(), '/0.zip'])
+    test_target = divide_and_compress.DirectoryZipper(
+        ''.join([os.getcwd(), '/']), 'dummy', 1024*1024, True)
+    self.my_mox.StubOutWithMock(test_target, 'OpenZipFileAtPath')
+    test_target.OpenZipFileAtPath(source_path, mode='r').AndReturn(source)
+    test_target.OpenZipFileAtPath(dest_path,
+                                  compress=zipfile.ZIP_DEFLATED,
+                                  mode='w').AndReturn(dest)
+    self.my_mox.StubOutWithMock(os, 'rename')
+    os.rename(dest_path, source_path)
+    self.my_mox.StubOutWithMock(os, 'unlink')
+    os.unlink(source_path)
+    
+    self.my_mox.ReplayAll()
+    test_target.RemoveLastFile()
+    self.my_mox.VerifyAll()    
+
+  def CreateZipSource(self):
+    """Create a mock zip sourec object.
+
+    Read should only be called once, because the second file is the one
+    being removed.
+
+    Returns:
+      A configured mocked
+    """
+    
+    source_zip = self.my_mox.CreateMock(ZipFile)
+    source_zip.infolist().AndReturn([self.files['file1'], self.files['file1']])
+    source_zip.infolist().AndReturn([self.files['file1'], self.files['file1']])
+    source_zip.read(self.files['file1'].filename).AndReturn(
+        self.files['file1'].contents)
+    source_zip.close()
+    return source_zip
+
+  def CreateZipDestination(self):
+    """Create mock destination zip.
+
+    Write should only be called once, because there are two files in the
+    source zip and we expect the second to be removed.
+
+    Returns:
+      A configured mocked
+    """
+    
+    dest_zip = mox.MockObject(ZipFile)
+    dest_zip.writestr(self.files['file1'].filename,
+                      self.files['file1'].contents)
+    dest_zip.close()
+    return dest_zip
+
+  def tearDown(self):
+    """Remove any stubs we've created."""
+    self.my_mox.UnsetStubs()
+
+
+class FixArchiveTests(unittest.TestCase):
+  """Tests for the DirectoryZipper.FixArchive method."""
+  
+  def setUp(self):
+    """Create a mock file object."""
+    self.my_mox = mox.Mox()
+    self.file1 = BagOfParts()
+    self.file1.filename = 'file1.txt'
+    self.file1.contents = 'This is a test file'
+
+  def _InitMultiFileData(self):
+    """Create an array of mock file objects.
+
+    Create three mock file objects that we can use for testing.
+    """
+    self.multi_file_dir = []
+    
+    file1 = BagOfParts()
+    file1.filename = 'file1.txt'
+    file1.contents = 'kjaskl;jkdjfkja;kjsnbvjnvnbuewklriujalvjsd'
+    self.multi_file_dir.append(file1)
+
+    file2 = BagOfParts()
+    file2.filename = 'file2.txt'
+    file2.contents = ('He entered the room and there in the center, it was.'
+                      ' Looking upon the thing, suddenly he could not remember'
+                      ' whether he had actually seen it before or whether'
+                      ' his memory of it was merely the effect of something'
+                      ' so often being imagined that it had long since become '
+                      ' manifest in his mind.')
+    self.multi_file_dir.append(file2)
+
+    file3 = BagOfParts()
+    file3.filename = 'file3.txt'
+    file3.contents = 'Whoa, what is \'file2.txt\' all about?'
+    self.multi_file_dir.append(file3)
+    
+  def testSingleFileArchive(self):
+    """Test behavior of FixArchive when the archive has a single member.
+
+    We expect that when this method is called with an archive that has a
+    single member that it will return False and unlink the archive.
+    """
+    test_target = divide_and_compress.DirectoryZipper(
+        ''.join([os.getcwd(), '/']), 'dummy', 1024*1024, True)
+    self.my_mox.StubOutWithMock(test_target, 'OpenZipFileAtPath')
+    test_target.OpenZipFileAtPath(
+        ''.join([os.getcwd(), '/0.zip']), mode='r').AndReturn(
+            self.CreateSingleFileMock())
+    self.my_mox.StubOutWithMock(os, 'unlink')
+    os.unlink(''.join([os.getcwd(), '/0.zip']))
+    self.my_mox.ReplayAll()
+    self.assertEqual(False, test_target.FixArchive('SIZE'))
+    self.my_mox.VerifyAll()
+
+  def CreateSingleFileMock(self):
+    """Create a mock ZipFile object for testSingleFileArchive.
+
+    We just need it to return a single member infolist twice
+
+    Returns:
+      A configured mock object
+    """
+    mock_zip = self.my_mox.CreateMock(ZipFile)
+    mock_zip.infolist().AndReturn([self.file1])
+    mock_zip.infolist().AndReturn([self.file1])
+    mock_zip.close()
+    return mock_zip
+
+  def testMultiFileArchive(self):
+    """Test behavior of DirectoryZipper.FixArchive with a multi-file archive.
+
+    We expect that FixArchive will rename the old archive, adding '-old' before
+    '.zip', read all the members except the last one of '-old' into a new
+    archive with the same name as the original, and then unlink the '-old' copy
+    """
+    test_target = divide_and_compress.DirectoryZipper(
+        ''.join([os.getcwd(), '/']), 'dummy', 1024*1024, True)
+    self.my_mox.StubOutWithMock(test_target, 'OpenZipFileAtPath')
+    test_target.OpenZipFileAtPath(
+        ''.join([os.getcwd(), '/0.zip']), mode='r').AndReturn(
+            self.CreateMultiFileMock())
+    self.my_mox.StubOutWithMock(test_target, 'RemoveLastFile')
+    test_target.RemoveLastFile(''.join([os.getcwd(), '/0.zip']))
+    self.my_mox.StubOutWithMock(os, 'stat')
+    os.stat(''.join([os.getcwd(), '/0.zip'])).AndReturn([49302])
+    self.my_mox.StubOutWithMock(stat, 'ST_SIZE')
+    stat.ST_SIZE = 0
+    self.my_mox.ReplayAll()
+    self.assertEqual(True, test_target.FixArchive('SIZE'))
+    self.my_mox.VerifyAll()
+
+  def CreateMultiFileMock(self):
+    """Create mock ZipFile object for use with testMultiFileArchive.
+
+    The mock just needs to return the infolist mock that is prepared in
+    InitMultiFileData()
+
+    Returns:
+      A configured mock object
+    """
+    self._InitMultiFileData()
+    mock_zip = self.my_mox.CreateMock(ZipFile)
+    mock_zip.infolist().AndReturn(self.multi_file_dir)
+    mock_zip.close()
+    return mock_zip
+
+  def tearDown(self):
+    """Unset any mocks that we've created."""
+    self.my_mox.UnsetStubs()
+
+
+class AddFileToArchiveTest(unittest.TestCase):
+  """Test behavior of method to add a file to an archive."""
+
+  def setUp(self):
+    """Setup the arguments for the DirectoryZipper object."""
+    self.my_mox = mox.Mox()
+    self.output_dir = '%s/' % os.getcwd()
+    self.file_to_add = 'file.txt'
+    self.input_dir = '/foo/bar/baz/'
+
+  def testAddFileToArchive(self):
+    """Test the DirectoryZipper.AddFileToArchive method.
+
+    We are testing a pretty trivial method, we just expect it to look at the
+    file its adding, so that it possible can through out a warning.
+    """
+    test_target = divide_and_compress.DirectoryZipper(self.output_dir,
+                                                      self.input_dir,
+                                                      1024*1024, True)
+    self.my_mox.StubOutWithMock(test_target, 'OpenZipFileAtPath')
+    archive_mock = self.CreateArchiveMock()
+    test_target.OpenZipFileAtPath(
+        ''.join([self.output_dir, '0.zip']),
+        compress=zipfile.ZIP_DEFLATED).AndReturn(archive_mock)
+    self.StubOutOsModule()
+    self.my_mox.ReplayAll()
+    test_target.AddFileToArchive(''.join([self.input_dir, self.file_to_add]),
+                                 zipfile.ZIP_DEFLATED)
+    self.my_mox.VerifyAll()
+
+  def StubOutOsModule(self):
+    """Create a mock for the os.path and os.stat objects.
+
+    Create a stub that will return the type (file or directory) and size of the
+    object that is to be added.
+    """
+    self.my_mox.StubOutWithMock(os.path, 'isfile')
+    os.path.isfile(''.join([self.input_dir, self.file_to_add])).AndReturn(True)
+    self.my_mox.StubOutWithMock(os, 'stat')
+    os.stat(''.join([self.input_dir, self.file_to_add])).AndReturn([39480])
+    self.my_mox.StubOutWithMock(stat, 'ST_SIZE')
+    stat.ST_SIZE = 0
+    
+  def CreateArchiveMock(self):
+    """Create a mock ZipFile for use with testAddFileToArchive.
+
+    Just verify that write is called with the file we expect and that the
+    archive is closed after the file addition
+
+    Returns:
+      A configured mock object
+    """
+    archive_mock = self.my_mox.CreateMock(ZipFile)
+    archive_mock.write(''.join([self.input_dir, self.file_to_add]),
+                       self.file_to_add)
+    archive_mock.close()
+    return archive_mock
+
+  def tearDown(self):
+    self.my_mox.UnsetStubs()
+
+
+class CompressDirectoryTest(unittest.TestCase):
+  """Test the master method of the class.
+
+  Testing with the following directory structure.
+  /dir1/
+  /dir1/file1.txt
+  /dir1/file2.txt
+  /dir1/dir2/
+  /dir1/dir2/dir3/
+  /dir1/dir2/dir4/
+  /dir1/dir2/dir4/file3.txt
+  /dir1/dir5/
+  /dir1/dir5/file4.txt
+  /dir1/dir5/file5.txt
+  /dir1/dir5/file6.txt
+  /dir1/dir5/file7.txt
+  /dir1/dir6/
+  /dir1/dir6/file8.txt
+
+  file1.txt., file2.txt, file3.txt should be in 0.zip
+  file4.txt should be in 1.zip
+  file5.txt, file6.txt should be in 2.zip
+  file7.txt will not be stored since it will be too large compressed
+  file8.txt should b in 3.zip
+  """
+
+  def setUp(self):
+    """Setup all the mocks for this test."""
+    self.my_mox = mox.Mox()
+
+    self.base_dir = '/dir1'
+    self.output_path = '/out_dir/'
+    self.test_target = divide_and_compress.DirectoryZipper(
+        self.output_path, self.base_dir, 1024*1024, True)
+    
+    self.InitArgLists()
+    self.InitOsDotPath()
+    self.InitArchiveIsValid()
+    self.InitWriteIndexRecord()
+    self.InitAddFileToArchive()
+
+  def tearDown(self):
+    self.my_mox.UnsetStubs()
+
+  def testCompressDirectory(self):
+    """Test the DirectoryZipper.CompressDirectory method."""
+    self.my_mox.ReplayAll()
+    for arguments in self.argument_lists:
+      self.test_target.CompressDirectory(None, arguments[0], arguments[1])
+    self.my_mox.VerifyAll()
+
+  def InitAddFileToArchive(self):
+    """Setup mock for DirectoryZipper.AddFileToArchive.
+
+    Make sure that the files are added in the order we expect.
+    """
+    self.my_mox.StubOutWithMock(self.test_target, 'AddFileToArchive')
+    self.test_target.AddFileToArchive('/dir1/file1.txt', zipfile.ZIP_DEFLATED)
+    self.test_target.AddFileToArchive('/dir1/file2.txt', zipfile.ZIP_DEFLATED)
+    self.test_target.AddFileToArchive('/dir1/dir2/dir4/file3.txt',
+                                      zipfile.ZIP_DEFLATED)
+    self.test_target.AddFileToArchive('/dir1/dir5/file4.txt',
+                                      zipfile.ZIP_DEFLATED)
+    self.test_target.AddFileToArchive('/dir1/dir5/file4.txt',
+                                      zipfile.ZIP_DEFLATED)
+    self.test_target.AddFileToArchive('/dir1/dir5/file5.txt',
+                                      zipfile.ZIP_DEFLATED)
+    self.test_target.AddFileToArchive('/dir1/dir5/file5.txt',
+                                      zipfile.ZIP_DEFLATED)
+    self.test_target.AddFileToArchive('/dir1/dir5/file6.txt',
+                                      zipfile.ZIP_DEFLATED)
+    self.test_target.AddFileToArchive('/dir1/dir5/file7.txt',
+                                      zipfile.ZIP_DEFLATED)
+    self.test_target.AddFileToArchive('/dir1/dir5/file7.txt',
+                                      zipfile.ZIP_DEFLATED)
+    self.test_target.AddFileToArchive('/dir1/dir6/file8.txt',
+                                      zipfile.ZIP_DEFLATED)
+  
+  def InitWriteIndexRecord(self):
+    """Setup mock for DirectoryZipper.WriteIndexRecord."""
+    self.my_mox.StubOutWithMock(self.test_target, 'WriteIndexRecord')
+
+    # we are trying to compress 8 files, but we should only attempt to
+    # write an index record 7 times, because one file is too large to be stored
+    self.test_target.WriteIndexRecord().AndReturn(True)
+    self.test_target.WriteIndexRecord().AndReturn(False)
+    self.test_target.WriteIndexRecord().AndReturn(False)
+    self.test_target.WriteIndexRecord().AndReturn(True)
+    self.test_target.WriteIndexRecord().AndReturn(True)
+    self.test_target.WriteIndexRecord().AndReturn(False)
+    self.test_target.WriteIndexRecord().AndReturn(True)
+
+  def InitArchiveIsValid(self):
+    """Mock out DirectoryZipper.ArchiveIsValid and DirectoryZipper.FixArchive.
+
+    Mock these methods out such that file1, file2, and file3 go into one
+    archive. file4 then goes into the next archive, file5 and file6 in the
+    next, file 7 should appear too large to compress into an archive, and
+    file8 goes into the final archive
+    """
+    self.my_mox.StubOutWithMock(self.test_target, 'ArchiveIsValid')
+    self.my_mox.StubOutWithMock(self.test_target, 'FixArchive')
+    self.test_target.ArchiveIsValid().AndReturn(True)
+    self.test_target.ArchiveIsValid().AndReturn(True)
+    self.test_target.ArchiveIsValid().AndReturn(True)
+
+    # should be file4.txt
+    self.test_target.ArchiveIsValid().AndReturn(False)
+    self.test_target.FixArchive('SIZE').AndReturn(True)
+    self.test_target.ArchiveIsValid().AndReturn(True)
+
+    # should be file5.txt
+    self.test_target.ArchiveIsValid().AndReturn(False)
+    self.test_target.FixArchive('SIZE').AndReturn(True)
+    self.test_target.ArchiveIsValid().AndReturn(True)
+    self.test_target.ArchiveIsValid().AndReturn(True)
+
+    # should be file7.txt
+    self.test_target.ArchiveIsValid().AndReturn(False)
+    self.test_target.FixArchive('SIZE').AndReturn(True)
+    self.test_target.ArchiveIsValid().AndReturn(False)
+    self.test_target.FixArchive('SIZE').AndReturn(False)
+    self.test_target.ArchiveIsValid().AndReturn(True)
+    
+  def InitOsDotPath(self):
+    """Mock out os.path.isfile.
+
+    Mock this out so the things we want to appear as files appear as files and
+    the things we want to appear as directories appear as directories. Also
+    make sure that the order of file visits is as we expect (which is why
+    InAnyOrder isn't used here).
+    """
+    self.my_mox.StubOutWithMock(os.path, 'isfile')
+    os.path.isfile('/dir1/dir2').AndReturn(False)
+    os.path.isfile('/dir1/dir5').AndReturn(False)
+    os.path.isfile('/dir1/dir6').AndReturn(False)
+    os.path.isfile('/dir1/file1.txt').AndReturn(True)
+    os.path.isfile('/dir1/file2.txt').AndReturn(True)
+    os.path.isfile('/dir1/dir2/dir3').AndReturn(False)
+    os.path.isfile('/dir1/dir2/dir4').AndReturn(False)
+    os.path.isfile('/dir1/dir2/dir4/file3.txt').AndReturn(True)
+    os.path.isfile('/dir1/dir5/file4.txt').AndReturn(True)
+    os.path.isfile('/dir1/dir5/file4.txt').AndReturn(True)
+    os.path.isfile('/dir1/dir5/file5.txt').AndReturn(True)
+    os.path.isfile('/dir1/dir5/file5.txt').AndReturn(True)
+    os.path.isfile('/dir1/dir5/file6.txt').AndReturn(True)
+    os.path.isfile('/dir1/dir5/file7.txt').AndReturn(True)
+    os.path.isfile('/dir1/dir5/file7.txt').AndReturn(True)
+    os.path.isfile('/dir1/dir6/file8.txt').AndReturn(True)
+
+  def InitArgLists(self):
+    """Create the directory path => directory contents mappings."""
+    self.argument_lists = []
+    self.argument_lists.append(['/dir1',
+                                ['file1.txt', 'file2.txt', 'dir2', 'dir5',
+                                 'dir6']])
+    self.argument_lists.append(['/dir1/dir2', ['dir3', 'dir4']])
+    self.argument_lists.append(['/dir1/dir2/dir3', []])
+    self.argument_lists.append(['/dir1/dir2/dir4', ['file3.txt']])
+    self.argument_lists.append(['/dir1/dir5',
+                                ['file4.txt', 'file5.txt', 'file6.txt',
+                                 'file7.txt']])
+    self.argument_lists.append(['/dir1/dir6', ['file8.txt']])
+      
+if __name__ == '__main__':
+  unittest.main()
diff --git a/tools/sdkmanager/Android.mk b/tools/sdkmanager/Android.mk
new file mode 100644
index 0000000..30df7f1
--- /dev/null
+++ b/tools/sdkmanager/Android.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+SDKMANAGER_LOCAL_DIR := $(call my-dir)
+include $(SDKMANAGER_LOCAL_DIR)/app/Android.mk
+include $(SDKMANAGER_LOCAL_DIR)/libs/Android.mk
diff --git a/tools/sdkmanager/MODULE_LICENSE_APACHE2 b/tools/sdkmanager/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/sdkmanager/MODULE_LICENSE_APACHE2
diff --git a/tools/sdkmanager/app/.classpath b/tools/sdkmanager/app/.classpath
new file mode 100644
index 0000000..cbd9d37
--- /dev/null
+++ b/tools/sdkmanager/app/.classpath
@@ -0,0 +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>
diff --git a/tools/sdkmanager/app/.project b/tools/sdkmanager/app/.project
new file mode 100644
index 0000000..e12c17d
--- /dev/null
+++ b/tools/sdkmanager/app/.project
@@ -0,0 +1,17 @@
+<?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>
diff --git a/tools/sdkmanager/app/Android.mk b/tools/sdkmanager/app/Android.mk
new file mode 100644
index 0000000..24ba61f
--- /dev/null
+++ b/tools/sdkmanager/app/Android.mk
@@ -0,0 +1,5 @@
+# Copyright 2007 The Android Open Source Project
+#
+SDKMANAGERAPP_LOCAL_DIR := $(call my-dir)
+include $(SDKMANAGERAPP_LOCAL_DIR)/etc/Android.mk
+include $(SDKMANAGERAPP_LOCAL_DIR)/src/Android.mk
diff --git a/tools/sdkmanager/app/etc/Android.mk b/tools/sdkmanager/app/etc/Android.mk
new file mode 100644
index 0000000..8723cd8
--- /dev/null
+++ b/tools/sdkmanager/app/etc/Android.mk
@@ -0,0 +1,8 @@
+# Copyright 2008 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_EXECUTABLES := android
+include $(BUILD_HOST_PREBUILT)
+
diff --git a/tools/sdkmanager/app/etc/android b/tools/sdkmanager/app/etc/android
new file mode 100755
index 0000000..af4042b
--- /dev/null
+++ b/tools/sdkmanager/app/etc/android
@@ -0,0 +1,84 @@
+#!/bin/sh
+# Copyright 2005-2007, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+    newProg=`/bin/ls -ld "${prog}"`
+    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+    if expr "x${newProg}" : 'x/' >/dev/null; then
+        prog="${newProg}"
+    else
+        progdir=`dirname "${prog}"`
+        prog="${progdir}/${newProg}"
+    fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+jarfile=sdkmanager.jar
+frameworkdir="$progdir"
+libdir="$progdir"
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/tools/lib
+    libdir=`dirname "$progdir"`/tools/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/framework
+    libdir=`dirname "$progdir"`/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    echo `basename "$prog"`": can't find $jarfile"
+    exit 1
+fi
+
+
+# Check args.
+if [ debug = "$1" ]; then
+    # add this in for debugging
+    java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
+    shift 1
+else
+    java_debug=
+fi
+
+# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
+if [ `uname` = "Darwin" ]; then
+    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"
+else
+    os_opts=
+    java_cmd="java"
+fi
+
+if [ "$OSTYPE" = "cygwin" ] ; then
+    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
+    progdir=`cygpath -w  "$progdir"`
+else
+    jarpath="$frameworkdir/$jarfile"
+fi
+
+# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
+# might need more memory, e.g. -Xmx128M
+exec "$java_cmd" -Xmx256M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -Dcom.android.sdkmanager.toolsdir="$progdir" -jar "$jarpath" "$@"
diff --git a/tools/sdkmanager/app/etc/android.bat b/tools/sdkmanager/app/etc/android.bat
new file mode 100755
index 0000000..de950ed
--- /dev/null
+++ b/tools/sdkmanager/app/etc/android.bat
@@ -0,0 +1,51 @@
+@echo off
+rem Copyright (C) 2007 The Android Open Source Project
+rem
+rem Licensed under the Apache License, Version 2.0 (the "License");
+rem you may not use this file except in compliance with the License.
+rem You may obtain a copy of the License at
+rem
+rem      http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+
+rem don't modify the caller's environment
+setlocal
+
+rem Set up prog to be the path of this script, including following symlinks,
+rem and set up progdir to be the fully-qualified pathname of its directory.
+set prog=%~f0
+
+rem Grab current directory before we change it
+set workdir=%cd%
+
+rem Change current directory and drive to where the script is, to avoid
+rem issues with directories containing whitespaces.
+cd /d %~dp0
+
+set jarfile=sdkmanager.jar
+set frameworkdir=
+set libdir=
+
+if exist %frameworkdir%%jarfile% goto JarFileOk
+    set frameworkdir=lib\
+    set libdir=lib\
+
+if exist %frameworkdir%%jarfile% goto JarFileOk
+    set frameworkdir=..\framework\
+    set libdir=..\lib\
+
+:JarFileOk
+
+if debug NEQ "%1" goto NoDebug
+    set java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
+    shift 1
+:NoDebug
+
+set jarpath=%frameworkdir%%jarfile%
+
+call java %java_debug% -Djava.ext.dirs=%frameworkdir% -Djava.library.path=%libdir% -Dcom.android.sdkmanager.toolsdir= -Dcom.android.sdkmanager.workdir="%workdir%" -jar %jarpath% %*
diff --git a/tools/sdkmanager/app/etc/manifest.txt b/tools/sdkmanager/app/etc/manifest.txt
new file mode 100644
index 0000000..5676634
--- /dev/null
+++ b/tools/sdkmanager/app/etc/manifest.txt
@@ -0,0 +1 @@
+Main-Class: com.android.sdkmanager.Main
diff --git a/tools/sdkmanager/app/src/Android.mk b/tools/sdkmanager/app/src/Android.mk
new file mode 100644
index 0000000..b508076
--- /dev/null
+++ b/tools/sdkmanager/app/src/Android.mk
@@ -0,0 +1,16 @@
+# Copyright 2007 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAR_MANIFEST := ../etc/manifest.txt
+LOCAL_JAVA_LIBRARIES := \
+	androidprefs \
+	sdklib \
+	sdkuilib
+LOCAL_MODULE := sdkmanager
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java b/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java
new file mode 100644
index 0000000..9f3fb99
--- /dev/null
+++ b/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java
@@ -0,0 +1,791 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdkmanager;
+
+import com.android.sdklib.ISdkLog;
+
+import java.util.HashMap;
+import java.util.Map.Entry;
+
+/**
+ * Parses the command-line and stores flags needed or requested.
+ * <p/>
+ * This is a base class. To be useful you want to:
+ * <ul>
+ * <li>override it.
+ * <li>pass an action array to the constructor.
+ * <li>define flags for your actions.
+ * </ul> 
+ * <p/>
+ * To use, call {@link #parseArgs(String[])} and then
+ * call {@link #getValue(String, String, String)}.
+ */
+public class CommandLineProcessor {
+
+    /** Internal verb name for internally hidden flags. */
+    public final static String GLOBAL_FLAG_VERB = "@@internal@@";
+    
+    /** String to use when the verb doesn't need any object. */
+    public final static String NO_VERB_OBJECT = "";
+    
+    /** The global help flag. */ 
+    public static final String KEY_HELP = "help";
+    /** The global verbose flag. */
+    public static final String KEY_VERBOSE = "verbose";
+    /** The global silent flag. */
+    public static final String KEY_SILENT = "silent";
+    
+    /** Verb requested by the user. Null if none specified, which will be an error. */
+    private String mVerbRequested;
+    /** Direct object requested by the user. Can be null. */
+    private String mDirectObjectRequested;
+
+    /**
+     * Action definitions.
+     * <p/>
+     * Each entry is a string array with:
+     * <ul>
+     * <li> the verb.
+     * <li> a direct object (use #NO_VERB_OBJECT if there's no object).
+     * <li> a description.
+     * <li> an alternate form for the object (e.g. plural).
+     * </ul>
+     */
+    private final String[][] mActions;
+    
+    private static final int ACTION_VERB_INDEX = 0;
+    private static final int ACTION_OBJECT_INDEX = 1;
+    private static final int ACTION_DESC_INDEX = 2;
+    private static final int ACTION_ALT_OBJECT_INDEX = 3;
+
+    /**
+     * The map of all defined arguments.
+     * <p/>
+     * The key is a string "verb/directObject/longName".
+     */
+    private final HashMap<String, Arg> mArguments = new HashMap<String, Arg>();
+    /** Logger */
+    private final ISdkLog mLog;
+    
+    public CommandLineProcessor(ISdkLog logger, String[][] actions) {
+        mLog = logger;
+        mActions = actions;
+
+        define(MODE.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "v", KEY_VERBOSE,
+                "Verbose mode: errors, warnings and informational messages are printed.",
+                false);
+        define(MODE.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "s", KEY_SILENT,
+                "Silent mode: only errors are printed out.",
+                false);
+        define(MODE.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "h", KEY_HELP,
+                "This help.",
+                false);
+    }
+    
+    //------------------
+    // Helpers to get flags values
+
+    /** Helper that returns true if --verbose was requested. */
+    public boolean isVerbose() {
+        return ((Boolean) getValue(GLOBAL_FLAG_VERB, NO_VERB_OBJECT, KEY_VERBOSE)).booleanValue();
+    }
+
+    /** Helper that returns true if --silent was requested. */
+    public boolean isSilent() {
+        return ((Boolean) getValue(GLOBAL_FLAG_VERB, NO_VERB_OBJECT, KEY_SILENT)).booleanValue();
+    }
+
+    /** Helper that returns true if --help was requested. */
+    public boolean isHelpRequested() {
+        return ((Boolean) getValue(GLOBAL_FLAG_VERB, NO_VERB_OBJECT, KEY_HELP)).booleanValue();
+    }
+    
+    /** Returns the verb name from the command-line. Can be null. */
+    public String getVerb() {
+        return mVerbRequested;
+    }
+
+    /** Returns the direct object name from the command-line. Can be null. */
+    public String getDirectObject() {
+        return mDirectObjectRequested;
+    }
+    
+    //------------------
+    
+    /**
+     * Raw access to parsed parameter values.
+     * <p/>
+     * The default is to scan all parameters. Parameters that have been explicitly set on the
+     * command line are returned first. Otherwise one with a non-null value is returned.
+     * <p/>
+     * Both a verb and a direct object filter can be specified. When they are non-null they limit
+     * the scope of the search. 
+     * <p/>
+     * If nothing has been found, return the last default value seen matching the filter.
+     * 
+     * @param verb The verb name, including {@link #GLOBAL_FLAG_VERB}. If null, all possible
+     *             verbs that match the direct object condition will be examined and the first
+     *             value set will be used.
+     * @param directObject The direct object name, including {@link #NO_VERB_OBJECT}. If null,
+     *             all possible direct objects that match the verb condition will be examined and
+     *             the first value set will be used.
+     * @param longFlagName The long flag name for the given action. Mandatory. Cannot be null.
+     * @return The current value object stored in the parameter, which depends on the argument mode.
+     */
+    public Object getValue(String verb, String directObject, String longFlagName) {
+
+        if (verb != null && directObject != null) {
+            String key = verb + "/" + directObject + "/" + longFlagName;
+            Arg arg = mArguments.get(key);
+            return arg.getCurrentValue();
+        }
+        
+        Object lastDefault = null;
+        for (Arg arg : mArguments.values()) {
+            if (arg.getLongArg().equals(longFlagName)) {
+                if (verb == null || arg.getVerb().equals(verb)) {
+                    if (directObject == null || arg.getDirectObject().equals(directObject)) {
+                        if (arg.isInCommandLine()) {
+                            return arg.getCurrentValue();
+                        }
+                        if (arg.getCurrentValue() != null) {
+                            lastDefault = arg.getCurrentValue();
+                        }
+                    }
+                }
+            }
+        }
+        
+        return lastDefault;
+    }
+
+    /**
+     * Internal setter for raw parameter value.
+     * @param verb The verb name, including {@link #GLOBAL_FLAG_VERB}.
+     * @param directObject The direct object name, including {@link #NO_VERB_OBJECT}.
+     * @param longFlagName The long flag name for the given action.
+     * @param value The new current value object stored in the parameter, which depends on the
+     *              argument mode.
+     */
+    protected void setValue(String verb, String directObject, String longFlagName, Object value) {
+        String key = verb + "/" + directObject + "/" + longFlagName;
+        Arg arg = mArguments.get(key);
+        arg.setCurrentValue(value);
+    }
+
+    /**
+     * Parses the command-line arguments.
+     * <p/>
+     * This method will exit and not return if a parsing error arise.
+     * 
+     * @param args The arguments typically received by a main method.
+     */
+    public void parseArgs(String[] args) {
+        String needsHelp = null;
+        String verb = null;
+        String directObject = null;
+
+        try {
+            int n = args.length;
+            for (int i = 0; i < n; i++) {
+                Arg arg = null;
+                String a = args[i];
+                if (a.startsWith("--")) {
+                    arg = findLongArg(verb, directObject, a.substring(2));
+                } else if (a.startsWith("-")) {
+                    arg = findShortArg(verb, directObject, a.substring(1));
+                }
+                
+                // No matching argument name found
+                if (arg == null) {
+                    // Does it looks like a dashed parameter?
+                    if (a.startsWith("-")) {
+                        if (verb == null || directObject == null) {
+                            // It looks like a dashed parameter and we don't have a a verb/object
+                            // set yet, the parameter was just given too early.
+    
+                            needsHelp = String.format(
+                                "Flag '%1$s' is not a valid global flag. Did you mean to specify it after the verb/object name?",
+                                a);
+                            return;
+                        } else {
+                            // It looks like a dashed parameter and but it is unknown by this
+                            // verb-object combination
+                            
+                            needsHelp = String.format(
+                                    "Flag '%1$s' is not valid for '%2$s %3$s'.",
+                                    a, verb, directObject);
+                            return;
+                        }
+                    }
+                    
+                    if (verb == null) {
+                        // Fill verb first. Find it.
+                        for (String[] actionDesc : mActions) {
+                            if (actionDesc[ACTION_VERB_INDEX].equals(a)) {
+                                verb = a;
+                                break;
+                            }
+                        }
+                        
+                        // Error if it was not a valid verb
+                        if (verb == null) {
+                            needsHelp = String.format(
+                                "Expected verb after global parameters but found '%1$s' instead.",
+                                a);
+                            return;
+                        }
+    
+                    } else if (directObject == null) {
+                        // Then fill the direct object. Find it.
+                        for (String[] actionDesc : mActions) {
+                            if (actionDesc[ACTION_VERB_INDEX].equals(verb)) {
+                                if (actionDesc[ACTION_OBJECT_INDEX].equals(a)) {
+                                    directObject = a;
+                                    break;
+                                } else if (actionDesc.length > ACTION_ALT_OBJECT_INDEX &&
+                                        actionDesc[ACTION_ALT_OBJECT_INDEX].equals(a)) {
+                                    // if the alternate form exist and is used, we internally
+                                    // only memorize the default direct object form.
+                                    directObject = actionDesc[ACTION_OBJECT_INDEX];
+                                    break;
+                                }
+                            }
+                        }
+                        
+                        // Error if it was not a valid object for that verb
+                        if (directObject == null) {
+                            needsHelp = String.format(
+                                "Expected verb after global parameters but found '%1$s' instead.",
+                                a);
+                            return;
+                            
+                        }
+                    }
+                } else if (arg != null) {
+                    // This argument was present on the command line
+                    arg.setInCommandLine(true);
+                    
+                    // Process keyword
+                    String error = null;
+                    if (arg.getMode().needsExtra()) {
+                        if (++i >= n) {
+                            needsHelp = String.format("Missing argument for flag %1$s.", a);
+                            return;
+                        }
+                        
+                        error = arg.getMode().process(arg, args[i]);
+                    } else {
+                        error = arg.getMode().process(arg, null);
+    
+                        // If we just toggled help, we want to exit now without printing any error.
+                        // We do this test here only when a Boolean flag is toggled since booleans
+                        // are the only flags that don't take parameters and help is a boolean.
+                        if (isHelpRequested()) {
+                            printHelpAndExit(null);
+                            // The call above should terminate however in unit tests we override
+                            // it so we still need to return here.
+                            return;
+                        }
+                    }
+                    
+                    if (error != null) {
+                        needsHelp = String.format("Invalid usage for flag %1$s: %2$s.", a, error);
+                        return;
+                    }
+                }
+            }
+        
+            if (needsHelp == null) {
+                if (verb == null) {
+                    needsHelp = "Missing verb name.";
+                } else {
+                    if (directObject == null) {
+                        // Make sure this verb has an optional direct object
+                        for (String[] actionDesc : mActions) {
+                            if (actionDesc[ACTION_VERB_INDEX].equals(verb) &&
+                                    actionDesc[ACTION_OBJECT_INDEX].equals(NO_VERB_OBJECT)) {
+                                directObject = NO_VERB_OBJECT;
+                                break;
+                            }
+                        }
+    
+                        if (directObject == null) {
+                            needsHelp = String.format("Missing object name for verb '%1$s'.", verb);
+                            return;
+                        }
+                    }
+                    
+                    // Validate that all mandatory arguments are non-null for this action
+                    String missing = null;
+                    boolean plural = false;
+                    for (Entry<String, Arg> entry : mArguments.entrySet()) {
+                        Arg arg = entry.getValue();
+                        if (arg.getVerb().equals(verb) &&
+                                arg.getDirectObject().equals(directObject)) {
+                            if (arg.isMandatory() && arg.getCurrentValue() == null) {
+                                if (missing == null) {
+                                    missing = "--" + arg.getLongArg();
+                                } else {
+                                    missing += ", --" + arg.getLongArg();
+                                    plural = true;
+                                }
+                            }
+                        }
+                    }
+    
+                    if (missing != null) {
+                        needsHelp  = String.format(
+                                "The %1$s %2$s must be defined for action '%3$s %4$s'",
+                                plural ? "parameters" : "parameter",
+                                missing,
+                                verb,
+                                directObject);
+                    }
+
+                    mVerbRequested = verb;
+                    mDirectObjectRequested = directObject;
+                }
+            }
+        } finally {
+            if (needsHelp != null) {
+                printHelpAndExitForAction(verb, directObject, needsHelp);
+            }
+        }
+    }
+    
+    /**
+     * Finds an {@link Arg} given an action name and a long flag name.
+     * @return The {@link Arg} found or null.
+     */
+    protected Arg findLongArg(String verb, String directObject, String longName) {
+        if (verb == null) {
+            verb = GLOBAL_FLAG_VERB;
+        }
+        if (directObject == null) {
+            directObject = NO_VERB_OBJECT;
+        }
+        String key = verb + "/" + directObject + "/" + longName;
+        return mArguments.get(key);
+    }
+
+    /**
+     * Finds an {@link Arg} given an action name and a short flag name.
+     * @return The {@link Arg} found or null.
+     */
+    protected Arg findShortArg(String verb, String directObject, String shortName) {
+        if (verb == null) {
+            verb = GLOBAL_FLAG_VERB;
+        }
+        if (directObject == null) {
+            directObject = NO_VERB_OBJECT;
+        }
+
+        for (Entry<String, Arg> entry : mArguments.entrySet()) {
+            Arg arg = entry.getValue();
+            if (arg.getVerb().equals(verb) && arg.getDirectObject().equals(directObject)) {
+                if (shortName.equals(arg.getShortArg())) {
+                    return arg;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Prints the help/usage and exits.
+     * 
+     * @param errorFormat Optional error message to print prior to usage using String.format 
+     * @param args Arguments for String.format
+     */
+    public void printHelpAndExit(String errorFormat, Object... args) {
+        printHelpAndExitForAction(null /*verb*/, null /*directObject*/, errorFormat, args);
+    }
+    
+    /**
+     * Prints the help/usage and exits.
+     * 
+     * @param verb If null, displays help for all verbs. If not null, display help only
+     *          for that specific verb. In all cases also displays general usage and action list.
+     * @param directObject If null, displays help for all verb objects.
+     *          If not null, displays help only for that specific action
+     *          In all cases also display general usage and action list.
+     * @param errorFormat Optional error message to print prior to usage using String.format 
+     * @param args Arguments for String.format
+     */
+    public void printHelpAndExitForAction(String verb, String directObject,
+            String errorFormat, Object... args) {
+        if (errorFormat != null) {
+            stderr(errorFormat, args);
+        }
+        
+        /*
+         * usage should fit in 80 columns
+         *   12345678901234567890123456789012345678901234567890123456789012345678901234567890
+         */
+        stdout("\n" +
+            "Usage:\n" +
+            "  android [global options] action [action options]\n" +
+            "\n" +
+            "Global options:");
+        listOptions(GLOBAL_FLAG_VERB, NO_VERB_OBJECT);
+
+        if (verb == null || directObject == null) {
+            stdout("\nValid actions are composed of a verb and an optional direct object:");
+            for (String[] action : mActions) {
+                
+                stdout("- %1$6s %2$-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])) {
+                    stdout("\nAction \"%1$s %2$s\":",
+                            action[ACTION_VERB_INDEX],
+                            action[ACTION_OBJECT_INDEX]);
+                    stdout("  %1$s", action[ACTION_DESC_INDEX]);
+                    stdout("Options:");
+                    listOptions(action[ACTION_VERB_INDEX], action[ACTION_OBJECT_INDEX]);
+                }
+            }
+        }
+        
+        exit();
+    }
+
+    /**
+     * Internal helper to print all the option flags for a given action name.
+     */
+    protected void listOptions(String verb, String directObject) {
+        int numOptions = 0;
+        for (Entry<String, Arg> entry : mArguments.entrySet()) {
+            Arg arg = entry.getValue();
+            if (arg.getVerb().equals(verb) && arg.getDirectObject().equals(directObject)) {
+                
+                String value = "";
+                if (arg.getDefaultValue() instanceof String[]) {
+                    for (String v : (String[]) arg.getDefaultValue()) {
+                        if (value.length() > 0) {
+                            value += ", ";
+                        }
+                        value += v;
+                    }
+                } else if (arg.getDefaultValue() != null) {
+                    value = arg.getDefaultValue().toString();
+                }
+                if (value.length() > 0) {
+                    value = " (" + value + ")";
+                }
+                
+                String required = arg.isMandatory() ? " [required]" : "";
+
+                stdout("  -%1$s %2$-10s %3$s%4$s%5$s",
+                        arg.getShortArg(),
+                        "--" + arg.getLongArg(),
+                        arg.getDescription(),
+                        value,
+                        required);
+                numOptions++;
+            }
+        }
+        
+        if (numOptions == 0) {
+            stdout("  No options");
+        }
+    }
+
+    //----
+    
+    /**
+     * The mode of an argument specifies the type of variable it represents,
+     * whether an extra parameter is required after the flag and how to parse it.
+     */
+    static enum MODE {
+        /** Argument value is a Boolean. Default value is a Boolean. */
+        BOOLEAN {
+            @Override
+            public boolean needsExtra() {
+                return false;
+            }
+            @Override
+            public String process(Arg arg, String extra) {
+                // Toggle the current value
+                arg.setCurrentValue(! ((Boolean) arg.getCurrentValue()).booleanValue());
+                return null;
+            }
+        },
+
+        /** Argument value is an Integer. Default value is an Integer. */
+        INTEGER {
+            @Override
+            public boolean needsExtra() {
+                return true;
+            }
+            @Override
+            public String process(Arg arg, String extra) {
+                try {
+                    arg.setCurrentValue(Integer.parseInt(extra));
+                    return null;
+                } catch (NumberFormatException e) {
+                    return String.format("Failed to parse '%1$s' as an integer: %2%s",
+                            extra, e.getMessage());
+                }
+            }
+        },
+        
+        /** Argument value is a String. Default value is a String[]. */
+        ENUM {
+            @Override
+            public boolean needsExtra() {
+                return true;
+            }
+            @Override
+            public String process(Arg arg, String extra) {
+                StringBuilder desc = new StringBuilder();
+                String[] values = (String[]) arg.getDefaultValue();
+                for (String value : values) {
+                    if (value.equals(extra)) {
+                        arg.setCurrentValue(extra);
+                        return null;
+                    }
+                    
+                    if (desc.length() != 0) {
+                        desc.append(", ");
+                    }
+                    desc.append(value);
+                }
+
+                return String.format("'%1$s' is not one of %2$s", extra, desc.toString());
+            }
+        },
+        
+        /** Argument value is a String. Default value is a null. */
+        STRING {
+            @Override
+            public boolean needsExtra() {
+                return true;
+            }
+            @Override
+            public String process(Arg arg, String extra) {
+                arg.setCurrentValue(extra);
+                return null;
+            }
+        };
+        
+        /**
+         * Returns true if this mode requires an extra parameter.
+         */
+        public abstract boolean needsExtra();
+
+        /**
+         * Processes the flag for this argument.
+         * 
+         * @param arg The argument being processed.
+         * @param extra The extra parameter. Null if {@link #needsExtra()} returned false. 
+         * @return An error string or null if there's no error.
+         */
+        public abstract String process(Arg arg, String extra);
+    }
+
+    /**
+     * An argument accepted by the command-line, also called "a flag".
+     * Arguments must have a short version (one letter), a long version name and a description.
+     * They can have a default value, or it can be null.
+     * Depending on the {@link MODE}, the default value can be a Boolean, an Integer, a String
+     * or a String array (in which case the first item is the current by default.)  
+     */
+    static class Arg {
+        /** Verb for that argument. Never null. */
+        private final String mVerb;
+        /** Direct Object for that argument. Never null, but can be empty string. */
+        private final String mDirectObject;
+        /** The 1-letter short name of the argument, e.g. -v. */
+        private final String mShortName;
+        /** The long name of the argument, e.g. --verbose. */
+        private final String mLongName;
+        /** A description. Never null. */
+        private final String mDescription;
+        /** A default value. Can be null. */
+        private final Object mDefaultValue;
+        /** The argument mode (type + process method). Never null. */
+        private final MODE mMode;
+        /** True if this argument is mandatory for this verb/directobject. */
+        private final boolean mMandatory;
+        /** Current value. Initially set to the default value. */
+        private Object mCurrentValue;
+        /** True if the argument has been used on the command line. */
+        private boolean mInCommandLine;
+
+        /**
+         * Creates a new argument flag description.
+         * 
+         * @param mode The {@link MODE} for the argument.
+         * @param mandatory True if this argument is mandatory for this action. 
+         * @param directObject The action name. Can be #NO_VERB_OBJECT or #INTERNAL_FLAG.
+         * @param shortName The one-letter short argument name. Cannot be empty nor null.
+         * @param longName The long argument name. Cannot be empty nor null.
+         * @param description The description. Cannot be null.
+         * @param defaultValue The default value (or values), which depends on the selected {@link MODE}.
+         */
+        public Arg(MODE mode,
+                   boolean mandatory,
+                   String verb,
+                   String directObject,
+                   String shortName,
+                   String longName,
+                   String description,
+                   Object defaultValue) {
+            mMode = mode;
+            mMandatory = mandatory;
+            mVerb = verb;
+            mDirectObject = directObject;
+            mShortName = shortName;
+            mLongName = longName;
+            mDescription = description;
+            mDefaultValue = defaultValue;
+            mInCommandLine = false;
+            if (defaultValue instanceof String[]) {
+                mCurrentValue = ((String[])defaultValue)[0];
+            } else {
+                mCurrentValue = mDefaultValue;
+            }
+        }
+        
+        /** Return true if this argument is mandatory for this verb/directobject. */
+        public boolean isMandatory() {
+            return mMandatory;
+        }
+        
+        /** Returns the 1-letter short name of the argument, e.g. -v. */
+        public String getShortArg() {
+            return mShortName;
+        }
+        
+        /** Returns the long name of the argument, e.g. --verbose. */
+        public String getLongArg() {
+            return mLongName;
+        }
+        
+        /** Returns the description. Never null. */
+        public String getDescription() {
+            return mDescription;
+        }
+        
+        /** Returns the verb for that argument. Never null. */
+        public String getVerb() {
+            return mVerb;
+        }
+
+        /** Returns the direct Object for that argument. Never null, but can be empty string. */
+        public String getDirectObject() {
+            return mDirectObject;
+        }
+        
+        /** Returns the default value. Can be null. */
+        public Object getDefaultValue() {
+            return mDefaultValue;
+        }
+        
+        /** Returns the current value. Initially set to the default value. Can be null. */
+        public Object getCurrentValue() {
+            return mCurrentValue;
+        }
+
+        /** Sets the current value. Can be null. */
+        public void setCurrentValue(Object currentValue) {
+            mCurrentValue = currentValue;
+        }
+        
+        /** Returns the argument mode (type + process method). Never null. */
+        public MODE getMode() {
+            return mMode;
+        }
+        
+        /** Returns true if the argument has been used on the command line. */
+        public boolean isInCommandLine() {
+            return mInCommandLine;
+        }
+        
+        /** Sets if the argument has been used on the command line. */
+        public void setInCommandLine(boolean inCommandLine) {
+            mInCommandLine = inCommandLine;
+        }
+    }
+    
+    /**
+     * Internal helper to define a new argument for a give action.
+     * 
+     * @param mode The {@link MODE} for the argument.
+     * @param verb The verb name. Can be #INTERNAL_VERB.
+     * @param directObject The action name. Can be #NO_VERB_OBJECT or #INTERNAL_FLAG.
+     * @param shortName The one-letter short argument name. Cannot be empty nor null.
+     * @param longName The long argument name. Cannot be empty nor null.
+     * @param description The description. Cannot be null.
+     * @param defaultValue The default value (or values), which depends on the selected {@link MODE}.
+     */
+    protected void define(MODE mode,
+            boolean mandatory,
+            String verb,
+            String directObject,
+            String shortName, String longName,
+            String description, Object defaultValue) {
+        assert(mandatory || mode == MODE.BOOLEAN); // a boolean mode cannot be mandatory
+        
+        if (directObject == null) {
+            directObject = NO_VERB_OBJECT;
+        }
+        
+        String key = verb + "/" + directObject + "/" + longName;
+        mArguments.put(key, new Arg(mode, mandatory,
+                verb, directObject, shortName, longName, description, defaultValue));
+    }
+
+    /**
+     * Exits in case of error.
+     * This is protected so that it can be overridden in unit tests.
+     */
+    protected void exit() {
+        System.exit(1);
+    }
+
+    /**
+     * Prints a line to stdout.
+     * This is protected so that it can be overridden in unit tests.
+     * 
+     * @param format The string to be formatted. Cannot be null.
+     * @param args Format arguments.
+     */
+    protected void stdout(String format, Object...args) {
+        mLog.printf(format + "\n", args);
+    }
+
+    /**
+     * Prints a line to stderr.
+     * This is protected so that it can be overridden in unit tests.
+     * 
+     * @param format The string to be formatted. Cannot be null.
+     * @param args Format arguments.
+     */
+    protected void stderr(String format, Object...args) {
+        mLog.error(null, format, args);
+    }
+}
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
new file mode 100644
index 0000000..154788e
--- /dev/null
+++ b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
@@ -0,0 +1,813 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdkmanager;
+
+import com.android.prefs.AndroidLocation;
+import com.android.prefs.AndroidLocation.AndroidLocationException;
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.ISdkLog;
+import com.android.sdklib.SdkConstants;
+import com.android.sdklib.SdkManager;
+import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
+import com.android.sdklib.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 java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Main class for the 'android' application.
+ */
+class Main {
+
+    /** Java property that defines the location of the sdk/tools directory. */
+    private final static String TOOLSDIR = "com.android.sdkmanager.toolsdir";
+    /** Java property that defines the working directory. On Windows the current working directory
+     *  is actually the tools dir, in which case this is used to get the original CWD. */
+    private final static String WORKDIR = "com.android.sdkmanager.workdir";
+    
+    private final static String[] BOOLEAN_YES_REPLIES = new String[] { "yes", "y" };
+    private final static String[] BOOLEAN_NO_REPLIES = new String[] { "no", "n" };
+
+    /** Path to the SDK folder. This is the parent of {@link #TOOLSDIR}. */
+    private String mSdkFolder;
+    /** Logger object. Use this to print normal output, warnings or errors. */
+    private ISdkLog mSdkLog;
+    /** The SDK manager parses the SDK folder and gives access to the content. */
+    private SdkManager mSdkManager;
+    /** Command-line processor with options specific to SdkManager. */
+    private SdkCommandLine mSdkCommandLine;
+    /** The working directory, either null or set to an existing absolute canonical directory. */
+    private File mWorkDir;
+
+    public static void main(String[] args) {
+        new Main().run(args);
+    }
+    
+    /**
+     * Runs the sdk manager app
+     */
+    private void run(String[] args) {
+        createLogger();
+        init();
+        mSdkCommandLine.parseArgs(args);
+        parseSdk();
+        doAction();
+    }
+
+    /**
+     * Creates the {@link #mSdkLog} object.
+     * <p/>
+     * This must be done before {@link #init()} as it will be used to report errors.
+     */
+    private void createLogger() {
+        mSdkLog = new ISdkLog() {
+            public void error(Throwable t, String errorFormat, Object... args) {
+                if (errorFormat != null) {
+                    System.err.printf("Error: " + errorFormat, args);
+                    if (!errorFormat.endsWith("\n")) {
+                        System.err.printf("\n");
+                    }
+                }
+                if (t != null) {
+                    System.err.printf("Error: %s\n", t.getMessage());
+                }
+            }
+
+            public void warning(String warningFormat, Object... args) {
+                if (mSdkCommandLine.isVerbose()) {
+                    System.out.printf("Warning: " + warningFormat, args);
+                    if (!warningFormat.endsWith("\n")) {
+                        System.out.printf("\n");
+                    }
+                }
+            }
+
+            public void printf(String msgFormat, Object... args) {
+                System.out.printf(msgFormat, args);
+            }
+        };
+    }
+
+    /**
+     * Init the application by making sure the SDK path is available and
+     * doing basic parsing of the SDK.
+     */
+    private void init() {
+        mSdkCommandLine = new SdkCommandLine(mSdkLog);
+
+        // We get passed a property for the tools dir
+        String toolsDirProp = System.getProperty(TOOLSDIR);
+        if (toolsDirProp == null) {
+            // for debugging, it's easier to override using the process environment
+            toolsDirProp = System.getenv(TOOLSDIR);
+        }
+    
+        if (toolsDirProp != null) {
+            // got back a level for the SDK folder
+            File tools;
+            if (toolsDirProp.length() > 0) {
+                tools = new File(toolsDirProp);
+                mSdkFolder = tools.getParent();
+            } else {
+                try {
+                    tools = new File(".").getCanonicalFile();
+                    mSdkFolder = tools.getParent();
+                } catch (IOException e) {
+                    // Will print an error below since mSdkFolder is not defined
+                }
+            }
+        }
+
+        if (mSdkFolder == null) {
+            errorAndExit("The tools directory property is not set, please make sure you are executing %1$s",
+                SdkConstants.androidCmdName());
+        }
+        
+        // We might get passed a property for the working directory
+        // Either it is a valid directory and mWorkDir is set to it's absolute canonical value
+        // or mWorkDir remains null.
+        String workDirProp = System.getProperty(WORKDIR);
+        if (workDirProp == null) {
+            workDirProp = System.getenv(WORKDIR);
+        }
+        if (workDirProp != null) {
+            // This should be a valid directory
+            mWorkDir = new File(workDirProp);
+            try {
+                mWorkDir = mWorkDir.getCanonicalFile().getAbsoluteFile();
+            } catch (IOException e) {
+                mWorkDir = null;
+            }
+            if (mWorkDir == null || !mWorkDir.isDirectory()) {
+                errorAndExit("The working directory does not seem to be valid: '%1$s", workDirProp);
+            }
+        }
+    }
+
+    /**
+     * Does the basic SDK parsing required for all actions
+     */
+    private void parseSdk() {
+        mSdkManager = SdkManager.createManager(mSdkFolder, mSdkLog);
+        
+        if (mSdkManager == null) {
+            errorAndExit("Unable to parse SDK content.");
+        }
+    }
+    
+    /**
+     * Actually do an action...
+     */
+    private void doAction() {
+        String verb = mSdkCommandLine.getVerb();
+        String directObject = mSdkCommandLine.getDirectObject();
+        
+        if (SdkCommandLine.VERB_LIST.equals(verb)) {
+            // list action.
+            if (SdkCommandLine.OBJECT_TARGET.equals(directObject)) {
+                displayTargetList();
+            } else if (SdkCommandLine.OBJECT_AVD.equals(directObject)) {
+                displayAvdList();
+            } else {
+                displayTargetList();
+                displayAvdList();
+            }
+
+        } else if (SdkCommandLine.VERB_CREATE.equals(verb) &&
+                SdkCommandLine.OBJECT_AVD.equals(directObject)) {
+            createAvd();
+
+        } else if (SdkCommandLine.VERB_DELETE.equals(verb) &&
+                SdkCommandLine.OBJECT_AVD.equals(directObject)) {
+            deleteAvd();
+
+        } else if (SdkCommandLine.VERB_MOVE.equals(verb) &&
+                SdkCommandLine.OBJECT_AVD.equals(directObject)) {
+            moveAvd();
+
+        } else if (SdkCommandLine.VERB_CREATE.equals(verb) &&
+                SdkCommandLine.OBJECT_PROJECT.equals(directObject)) {
+            createProject();
+
+        } else if (SdkCommandLine.VERB_UPDATE.equals(verb) &&
+                SdkCommandLine.OBJECT_PROJECT.equals(directObject)) {
+            updateProject();
+        } else {
+            mSdkCommandLine.printHelpAndExit(null);
+        }
+    }
+
+    /**
+     * Creates a new Android project based on command-line parameters 
+     */
+    private void createProject() {
+        // get the target and try to resolve it.
+        int targetId = mSdkCommandLine.getParamTargetId();
+        IAndroidTarget[] targets = mSdkManager.getTargets();
+        if (targetId < 1 || targetId > targets.length) {
+            errorAndExit("Target id is not valid. Use '%s list targets' to get the target ids.",
+                    SdkConstants.androidCmdName());
+        }
+        IAndroidTarget target = targets[targetId - 1];
+        
+        ProjectCreator creator = new ProjectCreator(mSdkFolder,
+                mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
+                    mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
+                        OutputLevel.NORMAL,
+                mSdkLog);
+
+        String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
+        
+        creator.createProject(projectDir,
+                mSdkCommandLine.getParamName(),
+                mSdkCommandLine.getParamProjectPackage(),
+                mSdkCommandLine.getParamProjectActivity(),
+                target,
+                false /* isTestProject*/);
+    }
+
+    /**
+     * Updates an existing Android project based on command-line parameters 
+     */
+    private void updateProject() {
+        // get the target and try to resolve it.
+        IAndroidTarget target = null;
+        int targetId = mSdkCommandLine.getParamTargetId();
+        if (targetId >= 0) {
+            IAndroidTarget[] targets = mSdkManager.getTargets();
+            if (targetId < 1 || targetId > targets.length) {
+                errorAndExit("Target id is not valid. Use '%s list targets' to get the target ids.",
+                        SdkConstants.androidCmdName());
+            }
+            target = targets[targetId - 1];
+        }
+        
+        ProjectCreator creator = new ProjectCreator(mSdkFolder,
+                mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
+                    mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
+                        OutputLevel.NORMAL,
+                mSdkLog);
+
+        String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
+        
+        creator.updateProject(projectDir,
+                target,
+                mSdkCommandLine.getParamName());
+    }
+
+    /**
+     * Adjusts the project location to make it absolute & canonical relative to the
+     * working directory, if any.
+     * 
+     * @return The project absolute path relative to {@link #mWorkDir} or the original
+     *         newProjectLocation otherwise.
+     */
+    private String getProjectLocation(String newProjectLocation) {
+        
+        // If the new project location is absolute, use it as-is
+        File projectDir = new File(newProjectLocation);
+        if (projectDir.isAbsolute()) {
+            return newProjectLocation;
+        }
+
+        // if there's no working directory, just use the project location as-is.
+        if (mWorkDir == null) {
+            return newProjectLocation;
+        }
+
+        // Combine then and get an absolute canonical directory
+        try {
+            projectDir = new File(mWorkDir, newProjectLocation).getCanonicalFile();
+            
+            return projectDir.getPath();
+        } catch (IOException e) {
+            errorAndExit("Failed to combine working directory '%1$s' with project location '%2$s': %3$s",
+                    mWorkDir.getPath(),
+                    newProjectLocation,
+                    e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * Displays the list of available Targets (Platforms and Add-ons)
+     */
+    private void displayTargetList() {
+        mSdkLog.printf("Available Android targets:\n");
+
+        int index = 1;
+        for (IAndroidTarget target : mSdkManager.getTargets()) {
+            if (target.isPlatform()) {
+                mSdkLog.printf("[%d] %s\n", index, target.getName());
+                mSdkLog.printf("     API level: %d\n", target.getApiVersionNumber());
+            } else {
+                mSdkLog.printf("[%d] Add-on: %s\n", index, target.getName());
+                mSdkLog.printf("     Vendor: %s\n", target.getVendor());
+                if (target.getDescription() != null) {
+                    mSdkLog.printf("     Description: %s\n", target.getDescription());
+                }
+                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) {
+                    mSdkLog.printf("     Libraries:\n");
+                    for (IOptionalLibrary library : libraries) {
+                        mSdkLog.printf("     * %1$s (%2$s)\n",
+                                library.getName(), library.getJarName());
+                        mSdkLog.printf(String.format(
+                                "         %1$s\n", library.getDescription()));
+                    }
+                }
+            }
+
+            // get the target skins
+            displaySkinList(target, "     Skins: ");
+            
+            index++;
+        }
+    }
+
+    /**
+     * Displays the skins valid for the given target.
+     */
+    private void displaySkinList(IAndroidTarget target, String message) {
+        String[] skins = target.getSkins();
+        String defaultSkin = target.getDefaultSkin();
+        mSdkLog.printf(message);
+        if (skins != null) {
+            boolean first = true;
+            for (String skin : skins) {
+                if (first == false) {
+                    mSdkLog.printf(", ");
+                } else {
+                    first = false;
+                }
+                mSdkLog.printf(skin);
+                
+                if (skin.equals(defaultSkin)) {
+                    mSdkLog.printf(" (default)");
+                }
+            }
+            mSdkLog.printf("\n");
+        } else {
+            mSdkLog.printf("no skins.\n");
+        }
+    }
+    
+    /**
+     * Displays the list of available AVDs.
+     */
+    private void displayAvdList() {
+        try {
+            AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
+
+            mSdkLog.printf("Available Android Virtual Devices:\n");
+
+            AvdInfo[] avds = avdManager.getAvds();
+            for (int index = 0 ; index < avds.length ; index++) {
+                AvdInfo info = avds[index];
+                if (index > 0) {
+                    mSdkLog.printf("---------\n");
+                }
+                mSdkLog.printf("    Name: %s\n", info.getName());
+                mSdkLog.printf("    Path: %s\n", info.getPath());
+
+                // get the target of the AVD
+                IAndroidTarget target = info.getTarget();
+                if (target.isPlatform()) {
+                    mSdkLog.printf("  Target: %s (API level %d)\n", target.getName(),
+                            target.getApiVersionNumber());
+                } else {
+                    mSdkLog.printf("  Target: %s (%s)\n", target.getName(), target
+                            .getVendor());
+                    mSdkLog.printf("          Based on Android %s (API level %d)\n", target
+                            .getApiVersionName(), target.getApiVersionNumber());
+                }
+                
+                // display some extra values.
+                Map<String, String> properties = info.getProperties();
+                String skin = properties.get(AvdManager.AVD_INI_SKIN_NAME);
+                if (skin != null) {
+                    mSdkLog.printf("    Skin: %s\n", skin);
+                }
+                String sdcard = properties.get(AvdManager.AVD_INI_SDCARD_SIZE);
+                if (sdcard == null) {
+                    sdcard = properties.get(AvdManager.AVD_INI_SDCARD_PATH);
+                }
+                if (sdcard != null) {
+                    mSdkLog.printf("  Sdcard: %s\n", sdcard);
+                }
+            }
+        } catch (AndroidLocationException e) {
+            errorAndExit(e.getMessage());
+        }
+    }
+    
+    /**
+     * Creates a new AVD. This is a text based creation with command line prompt.
+     */
+    private void createAvd() {
+        // find a matching target
+        int targetId = mSdkCommandLine.getParamTargetId();
+        IAndroidTarget target = null;
+        
+        if (targetId >= 1 && targetId <= mSdkManager.getTargets().length) {
+            target = mSdkManager.getTargets()[targetId-1]; // target it is 1-based
+        } else {
+            errorAndExit("Target id is not valid. Use '%s list targets' to get the target ids.",
+                    SdkConstants.androidCmdName());
+        }
+
+        try {
+            boolean removePrevious = false;
+            AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
+
+            String avdName = mSdkCommandLine.getParamName();
+            AvdInfo info = avdManager.getAvd(avdName);
+            if (info != null) {
+                if (mSdkCommandLine.getFlagForce()) {
+                    removePrevious = true;
+                    mSdkLog.warning(
+                            "Android Virtual Device '%s' already exists and will be replaced.",
+                            avdName);
+                } else {
+                    errorAndExit("Android Virtual Device '%s' already exists.", avdName);
+                    return;
+                }
+            }
+
+            String paramFolderPath = mSdkCommandLine.getParamLocationPath();
+            File avdFolder = null;
+            if (paramFolderPath != null) {
+                avdFolder = new File(paramFolderPath);
+            } else {
+                avdFolder = new File(AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD,
+                        avdName + AvdManager.AVD_FOLDER_EXTENSION);
+            }
+
+            Map<String, String> hardwareConfig = null;
+            if (target.isPlatform()) {
+                try {
+                    hardwareConfig = promptForHardware(target);
+                } catch (IOException e) {
+                    errorAndExit(e.getMessage());
+                }
+            }
+
+            AvdInfo oldAvdInfo = null;
+            if (removePrevious) {
+                oldAvdInfo = avdManager.getAvd(avdName);
+            }
+            
+            // Validate skin is either default (empty) or NNNxMMM or a valid skin name.
+            String skin = mSdkCommandLine.getParamSkin();
+            if (skin != null && skin.length() == 0) {
+                skin = null;
+            }
+            if (skin != null) {
+                boolean valid = false;
+                // Is it a know skin name for this target?
+                for (String s : target.getSkins()) {
+                    if (skin.equalsIgnoreCase(s)) {
+                        skin = s;  // Make skin names case-insensitive.
+                        valid = true;
+                        break;
+                    }
+                }
+                
+                // Is it NNNxMMM?
+                if (!valid) {
+                    valid = AvdManager.NUMERIC_SKIN_SIZE.matcher(skin).matches();
+                }
+
+                if (!valid) {
+                    displaySkinList(target, "Valid skins: ");
+                    errorAndExit("'%s' is not a valid skin name or size (NNNxMMM)", skin);
+                    return;
+                }
+            }
+            
+            AvdInfo newAvdInfo = avdManager.createAvd(avdFolder,
+                    avdName,
+                    target,
+                    skin,
+                    mSdkCommandLine.getParamSdCard(),
+                    hardwareConfig,
+                    removePrevious,
+                    mSdkLog);
+            
+            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());
+        }
+    }
+
+    /**
+     * Delete an AVD.
+     */
+    private void deleteAvd() {
+        try {
+            String avdName = mSdkCommandLine.getParamName();
+            AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
+            AvdInfo info = avdManager.getAvd(avdName);
+    
+            if (info == null) {
+                errorAndExit("There is no Android Virtual Device named '%s'.", avdName);
+                return;
+            }
+    
+            avdManager.deleteAvd(info, mSdkLog);
+        } catch (AndroidLocationException e) {
+            errorAndExit(e.getMessage());
+        }
+    }
+    
+    /**
+     * Move an AVD.
+     */
+    private void moveAvd() {
+        try {
+            String avdName = mSdkCommandLine.getParamName();
+            AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
+            AvdInfo info = avdManager.getAvd(avdName);
+    
+            if (info == null) {
+                errorAndExit("There is no Android Virtual Device named '%s'.", avdName);
+                return;
+            }
+            
+            // This is a rename if there's a new name for the AVD
+            String newName = mSdkCommandLine.getParamMoveNewName();
+            if (newName != null && newName.equals(info.getName())) {
+                // same name, not actually a rename operation
+                newName = null;
+            }
+
+            // This is a move (of the data files) if there's a new location path
+            String paramFolderPath = mSdkCommandLine.getParamLocationPath();
+            if (paramFolderPath != null) {
+                // check if paths are the same. Use File methods to account for OS idiosyncrasies.
+                try {
+                    File f1 = new File(paramFolderPath).getCanonicalFile();
+                    File f2 = new File(info.getPath()).getCanonicalFile();
+                    if (f1.equals(f2)) {
+                        // same canonical path, so not actually a move
+                        paramFolderPath = null;
+                    }
+                } catch (IOException e) {
+                    // Fail to resolve canonical path. Fail now since a move operation might fail
+                    // later and be harder to recover from. 
+                    errorAndExit(e.getMessage());
+                    return;
+                }
+            }
+            
+            if (newName == null && paramFolderPath == null) {
+                mSdkLog.warning("Move operation aborted: same AVD name, same canonical data path");
+                return;
+            }
+            
+            // If a rename was requested and no data move was requested, check if the original
+            // data path is our default constructed from the AVD name. In this case we still want
+            // to rename that folder too.
+            if (newName != null && paramFolderPath == null) {
+                // Compute the original data path
+                File originalFolder = new File(
+                        AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD,
+                        info.getName() + AvdManager.AVD_FOLDER_EXTENSION);
+                if (originalFolder.equals(info.getPath())) {
+                    try {
+                        // The AVD is using the default data folder path based on the AVD name.
+                        // That folder needs to be adjusted to use the new name.
+                        File f = new File(AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD,
+                                     newName + AvdManager.AVD_FOLDER_EXTENSION);
+                        paramFolderPath = f.getCanonicalPath();
+                    } catch (IOException e) {
+                        // Fail to resolve canonical path. Fail now rather than later. 
+                        errorAndExit(e.getMessage());
+                    }
+                }
+            }
+            
+            // Check for conflicts
+            
+            if (newName != null && avdManager.getAvd(newName) != null) {
+                errorAndExit("There is already an AVD named '%s'.", newName);
+                return;
+            }
+            if (newName != null) {
+                if (avdManager.getAvd(newName) != null) {
+                    errorAndExit("There is already an AVD named '%s'.", newName);
+                    return;
+                }
+
+                File ini = info.getIniFile();
+                if (ini.equals(AvdInfo.getIniFile(newName))) {
+                    errorAndExit("The AVD file '%s' is in the way.", ini.getCanonicalPath());
+                    return;
+                }
+            }
+
+            if (paramFolderPath != null && new File(paramFolderPath).exists()) {
+                errorAndExit(
+                        "There is already a file or directory at '%s'.\nUse --path to specify a different data folder.",
+                        paramFolderPath);
+            }
+            
+            avdManager.moveAvd(info, newName, paramFolderPath, mSdkLog);
+        } catch (AndroidLocationException e) {
+            errorAndExit(e.getMessage());
+        } catch (IOException e) {
+            errorAndExit(e.getMessage());
+        }
+    }
+    
+    /**
+     * Prompts the user to setup a hardware config for a Platform-based AVD.
+     * @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) {
+            result = defaultAnswer;
+        }
+
+        if (getBooleanReply(result) == false) {
+            // no custom config.
+            return null;
+        }
+        
+        mSdkLog.printf("\n"); // empty line
+        
+        // get the list of possible hardware properties
+        File hardwareDefs = new File (mSdkFolder + 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);
+
+            String description = property.getDescription();
+            if (description != null) {
+                mSdkLog.printf("%s: %s\n", property.getAbstract(), description);
+            } else {
+                mSdkLog.printf("%s\n", property.getAbstract());
+            }
+
+            String defaultValue = property.getDefault();
+            
+            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) {
+                    mSdkLog.printf("\n"); // empty line
+                    i++; // go to the next property if we have a valid default value.
+                         // if there's no default, we'll redo this property
+                }
+                continue;
+            }
+            
+            switch (property.getType()) {
+                case BOOLEAN:
+                    try {
+                        if (getBooleanReply(result)) {
+                            map.put(property.getName(), "yes");
+                            i++; // valid reply, move to next property
+                        } else {
+                            map.put(property.getName(), "no");
+                            i++; // valid reply, move to next property
+                        }
+                    } catch (IOException e) {
+                        // display error, and do not increment i to redo this property
+                        mSdkLog.printf("\n%s\n", e.getMessage());
+                    }
+                    break;
+                case INTEGER:
+                    try {
+                        Integer.parseInt(result);
+                        map.put(property.getName(), result);
+                        i++; // valid reply, move to next property
+                    } catch (NumberFormatException e) {
+                        // display error, and do not increment i to redo this property
+                        mSdkLog.printf("\n%s\n", e.getMessage());
+                    }
+                    break;
+                case DISKSIZE:
+                    // TODO check validity
+                    map.put(property.getName(), result);
+                    i++; // valid reply, move to next property
+                    break;
+            }
+            
+            mSdkLog.printf("\n"); // empty line
+        }
+
+        return map;
+    }
+    
+    /**
+     * Reads the line from the input stream.
+     * @param buffer
+     * @throws IOException
+     */
+    private String readLine(byte[] buffer) throws IOException {
+        int count = System.in.read(buffer);
+        
+        // is the input longer than the buffer?
+        if (count == buffer.length && buffer[count-1] != 10) {
+            // create a new temp buffer
+            byte[] tempBuffer = new byte[256];
+
+            // and read the rest
+            String secondHalf = readLine(tempBuffer);
+            
+            // return a concat of both
+            return new String(buffer, 0, count) + secondHalf;
+        }
+
+        // ignore end whitespace
+        while (count > 0 && (buffer[count-1] == '\r' || buffer[count-1] == '\n')) {
+            count--;
+        }
+        
+        return new String(buffer, 0, count);
+    }
+    
+    /**
+     * Returns the boolean value represented by the string.
+     * @throws IOException If the value is not a boolean string.
+     */
+    private boolean getBooleanReply(String reply) throws IOException {
+        
+        for (String valid : BOOLEAN_YES_REPLIES) {
+            if (valid.equalsIgnoreCase(reply)) {
+                return true;
+            }
+        }
+
+        for (String valid : BOOLEAN_NO_REPLIES) {
+            if (valid.equalsIgnoreCase(reply)) {
+                return false;
+            }
+        }
+
+        throw new IOException(String.format("%s is not a valid reply", reply));
+    }
+    
+    private void errorAndExit(String format, Object...args) {
+        mSdkLog.error(null, format, args);
+        System.exit(1);
+    }
+}
\ 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
new file mode 100644
index 0000000..34a69bd
--- /dev/null
+++ b/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdkmanager;
+
+import com.android.sdklib.ISdkLog;
+import com.android.sdklib.SdkManager;
+
+
+/**
+ * Specific command-line flags for the {@link SdkManager}.
+ */
+public class SdkCommandLine extends CommandLineProcessor {
+
+    public final static String VERB_LIST   = "list";
+    public final static String VERB_CREATE = "create";
+    public final static String VERB_MOVE   = "move";
+    public final static String VERB_DELETE = "delete";
+    public final static String VERB_UPDATE = "update";
+
+    public static final String OBJECT_AVD      = "avd";
+    public static final String OBJECT_AVDS     = "avds";
+    public static final String OBJECT_TARGET   = "target";
+    public static final String OBJECT_TARGETS  = "targets";
+    public static final String OBJECT_PROJECT  = "project";
+
+    public static final String ARG_ALIAS    = "alias";
+    public static final String ARG_ACTIVITY = "activity";
+
+    public static final String KEY_ACTIVITY  = ARG_ACTIVITY;
+    public static final String KEY_PACKAGE   = "package";
+    public static final String KEY_MODE      = "mode";
+    public static final String KEY_TARGET_ID = OBJECT_TARGET;
+    public static final String KEY_NAME      = "name";
+    public static final String KEY_PATH      = "path";
+    public static final String KEY_FILTER    = "filter";
+    public static final String KEY_SKIN      = "skin";
+    public static final String KEY_SDCARD    = "sdcard";
+    public static final String KEY_FORCE     = "force";
+    public static final String KEY_RENAME    = "rename";
+
+    /**
+     * Action definitions for SdkManager command line.
+     * <p/>
+     * Each entry is a string array with:
+     * <ul>
+     * <li> the verb.
+     * <li> an object (use #NO_VERB_OBJECT if there's no object).
+     * <li> a description.
+     * <li> an alternate form for the object (e.g. plural).
+     * </ul>
+     */
+    private final static String[][] ACTIONS = {
+            { VERB_LIST, NO_VERB_OBJECT,
+                "Lists existing targets or virtual devices." },
+            { VERB_LIST, OBJECT_AVD,
+                "Lists existing Android Virtual Devices.",
+                OBJECT_AVDS },
+            { VERB_LIST, OBJECT_TARGET,
+                "Lists existing targets.",
+                OBJECT_TARGETS },
+    
+            { VERB_CREATE, OBJECT_AVD,
+                "Creates a new Android Virtual Device." },
+            { VERB_MOVE, OBJECT_AVD,
+                "Moves or renames an Android Virtual Device." },
+            { VERB_DELETE, OBJECT_AVD,
+                "Deletes an Android Virtual Device." },
+    
+            { VERB_CREATE, OBJECT_PROJECT,
+                "Creates a new Android Project." },
+            { VERB_UPDATE, OBJECT_PROJECT,
+                "Updates an Android Project (must have an AndroidManifest.xml)." },
+        };
+    
+    public SdkCommandLine(ISdkLog logger) {
+        super(logger, ACTIONS);
+
+        // --- create avd ---
+        
+        define(MODE.STRING, false, 
+                VERB_CREATE, OBJECT_AVD, "p", KEY_PATH,
+                "Location path of the directory where the new AVD will be created", null);
+        define(MODE.STRING, true, 
+                VERB_CREATE, OBJECT_AVD, "n", KEY_NAME,
+                "Name of the new AVD", null);
+        define(MODE.INTEGER, true, 
+                VERB_CREATE, OBJECT_AVD, "t", KEY_TARGET_ID,
+                "Target id of the new AVD", null);
+        define(MODE.STRING, false, 
+                VERB_CREATE, OBJECT_AVD, "s", KEY_SKIN,
+                "Skin of the new AVD", null);
+        define(MODE.STRING, false, 
+                VERB_CREATE, OBJECT_AVD, "c", KEY_SDCARD,
+                "Path to a shared SD card image, or size of a new sdcard for the new AVD", null);
+        define(MODE.BOOLEAN, false, 
+                VERB_CREATE, OBJECT_AVD, "f", KEY_FORCE,
+                "Force creation (override an existing AVD)", false);
+
+        // --- delete avd ---
+        
+        define(MODE.STRING, true, 
+                VERB_DELETE, OBJECT_AVD, "n", KEY_NAME,
+                "Name of the AVD to delete", null);
+
+        // --- move avd ---
+        
+        define(MODE.STRING, true, 
+                VERB_MOVE, OBJECT_AVD, "n", KEY_NAME,
+                "Name of the AVD to move or rename", null);
+        define(MODE.STRING, false, 
+                VERB_MOVE, OBJECT_AVD, "r", KEY_RENAME,
+                "New name of the AVD to rename", null);
+        define(MODE.STRING, false, 
+                VERB_MOVE, OBJECT_AVD, "p", KEY_PATH,
+                "New location path of the directory where to move the AVD", null);
+
+        // --- create project ---
+
+        define(MODE.ENUM, true, 
+                VERB_CREATE, OBJECT_PROJECT, "m", KEY_MODE,
+                "Project mode", new String[] { ARG_ACTIVITY, ARG_ALIAS });
+        define(MODE.STRING, true, 
+                VERB_CREATE, OBJECT_PROJECT,
+                "p", KEY_PATH,
+                "Location path of new project", null);
+        define(MODE.INTEGER, true, 
+                VERB_CREATE, OBJECT_PROJECT, "t", KEY_TARGET_ID,
+                "Target id of the new project", null);
+        define(MODE.STRING, true, 
+                VERB_CREATE, OBJECT_PROJECT, "k", KEY_PACKAGE,
+                "Package name", null);
+        define(MODE.STRING, true, 
+                VERB_CREATE, OBJECT_PROJECT, "a", KEY_ACTIVITY,
+                "Activity name", null);
+        define(MODE.STRING, false, 
+                VERB_CREATE, OBJECT_PROJECT, "n", KEY_NAME,
+                "Project name", null);
+
+        // --- update project ---
+
+        define(MODE.STRING, true, 
+                VERB_UPDATE, OBJECT_PROJECT,
+                "p", KEY_PATH,
+                "Location path of the project", null);
+        define(MODE.INTEGER, true, 
+                VERB_UPDATE, OBJECT_PROJECT,
+                "t", KEY_TARGET_ID,
+                "Target id to set for the project", -1);
+        define(MODE.STRING, false, 
+                VERB_UPDATE, OBJECT_PROJECT,
+                "n", KEY_NAME,
+                "Project name", null);
+    }
+    
+    // -- 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();
+    }
+
+    /** Helper to retrieve the --name value. */
+    public String getParamName() {
+        return ((String) getValue(null, null, KEY_NAME));
+    }
+    
+    /** Helper to retrieve the --skin value. */
+    public String getParamSkin() {
+        return ((String) getValue(null, null, KEY_SKIN));
+    }
+
+    /** Helper to retrieve the --sdcard value. */
+    public String getParamSdCard() {
+        return ((String) getValue(null, null, KEY_SDCARD));
+    }
+    
+    /** Helper to retrieve the --force flag. */
+    public boolean getFlagForce() {
+        return ((Boolean) getValue(null, null, KEY_FORCE)).booleanValue();
+    }
+
+    // -- some helpers for avd action flags
+
+    /** Helper to retrieve the --rename value for a move verb. */
+    public String getParamMoveNewName() {
+        return ((String) getValue(VERB_MOVE, null, KEY_RENAME));
+    }
+
+
+    // -- some helpers for project action flags
+    
+    /** Helper to retrieve the --package value. */
+    public String getParamProjectPackage() {
+        return ((String) getValue(null, OBJECT_PROJECT, KEY_PACKAGE));
+    }
+
+    /** Helper to retrieve the --activity for the new project action. */
+    public String getParamProjectActivity() {
+        return ((String) getValue(null, OBJECT_PROJECT, KEY_ACTIVITY));
+    }
+}
diff --git a/tools/sdkmanager/app/tests/com/android/sdkmanager/CommandLineProcessorTest.java b/tools/sdkmanager/app/tests/com/android/sdkmanager/CommandLineProcessorTest.java
new file mode 100644
index 0000000..918591b
--- /dev/null
+++ b/tools/sdkmanager/app/tests/com/android/sdkmanager/CommandLineProcessorTest.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdkmanager;
+
+import com.android.sdklib.ISdkLog;
+
+import junit.framework.TestCase;
+
+
+public class CommandLineProcessorTest extends TestCase {
+
+    private MockStdLogger mLog;
+    
+    /**
+     * A mock version of the {@link CommandLineProcessor} class that does not
+     * exits and captures its stdout/stderr output.
+     */
+    public static class MockCommandLineProcessor extends CommandLineProcessor {
+        private boolean mExitCalled;
+        private boolean mHelpCalled;
+        private String mStdOut = "";
+        private String mStdErr = "";
+        
+        public MockCommandLineProcessor(ISdkLog logger) {
+            super(logger,
+                  new String[][] {
+                    { "verb1", "action1", "Some action" },
+                    { "verb1", "action2", "Another action" },
+            });
+            define(MODE.STRING, false /*mandatory*/,
+                    "verb1", "action1", "1", "first", "non-mandatory flag", null);
+            define(MODE.STRING, true /*mandatory*/,
+                    "verb1", "action1", "2", "second", "mandatory flag", null);
+        }
+        
+        @Override
+        public void printHelpAndExitForAction(String verb, String directObject,
+                String errorFormat, Object... args) {
+            mHelpCalled = true;
+            super.printHelpAndExitForAction(verb, directObject, errorFormat, args);
+        }
+        
+        @Override
+        protected void exit() {
+            mExitCalled = true;
+        }
+        
+        @Override
+        protected void stdout(String format, Object... args) {
+            String s = String.format(format, args);
+            mStdOut += s + "\n";
+            // don't call super to avoid printing stuff
+        }
+        
+        @Override
+        protected void stderr(String format, Object... args) {
+            String s = String.format(format, args);
+            mStdErr += s + "\n";
+            // don't call super to avoid printing stuff
+        }
+        
+        public boolean wasHelpCalled() {
+            return mHelpCalled;
+        }
+        
+        public boolean wasExitCalled() {
+            return mExitCalled;
+        }
+        
+        public String getStdOut() {
+            return mStdOut;
+        }
+        
+        public String getStdErr() {
+            return mStdErr;
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        mLog = new MockStdLogger();
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public final void testPrintHelpAndExit() {
+        MockCommandLineProcessor c = new MockCommandLineProcessor(mLog);        
+        assertFalse(c.wasExitCalled());
+        assertFalse(c.wasHelpCalled());
+        assertTrue(c.getStdOut().equals(""));
+        assertTrue(c.getStdErr().equals(""));
+        c.printHelpAndExit(null);
+        assertTrue(c.getStdOut().indexOf("-v") != -1);
+        assertTrue(c.getStdOut().indexOf("--verbose") != -1);
+        assertTrue(c.getStdErr().equals(""));
+        assertTrue(c.wasExitCalled());
+
+        c = new MockCommandLineProcessor(mLog);        
+        assertFalse(c.wasExitCalled());
+        assertTrue(c.getStdOut().equals(""));
+        assertTrue(c.getStdErr().indexOf("Missing parameter") == -1);
+
+        c.printHelpAndExit("Missing %s", "parameter");
+        assertTrue(c.wasExitCalled());
+        assertFalse(c.getStdOut().equals(""));
+        assertTrue(c.getStdErr().indexOf("Missing parameter") != -1);
+    }
+    
+    public final void testVerbose() {
+        MockCommandLineProcessor c = new MockCommandLineProcessor(mLog);        
+
+        assertFalse(c.isVerbose());
+        c.parseArgs(new String[] { "-v" });
+        assertTrue(c.isVerbose());
+        assertTrue(c.wasExitCalled());
+        assertTrue(c.wasHelpCalled());
+        assertTrue(c.getStdErr().indexOf("Missing verb name.") != -1);
+
+        c = new MockCommandLineProcessor(mLog);        
+        c.parseArgs(new String[] { "--verbose" });
+        assertTrue(c.isVerbose());
+        assertTrue(c.wasExitCalled());
+        assertTrue(c.wasHelpCalled());
+        assertTrue(c.getStdErr().indexOf("Missing verb name.") != -1);
+    }
+    
+    public final void testHelp() {
+        MockCommandLineProcessor c = new MockCommandLineProcessor(mLog);        
+
+        c.parseArgs(new String[] { "-h" });
+        assertTrue(c.wasExitCalled());
+        assertTrue(c.wasHelpCalled());
+        assertTrue(c.getStdErr().indexOf("Missing verb name.") == -1);
+
+        c = new MockCommandLineProcessor(mLog);        
+        c.parseArgs(new String[] { "--help" });
+        assertTrue(c.wasExitCalled());
+        assertTrue(c.wasHelpCalled());
+        assertTrue(c.getStdErr().indexOf("Missing verb name.") == -1);
+    }
+
+    public final void testMandatory() {
+        MockCommandLineProcessor c = new MockCommandLineProcessor(mLog);        
+
+        c.parseArgs(new String[] { "verb1", "action1", "-1", "value1", "-2", "value2" });
+        assertFalse(c.wasExitCalled());
+        assertFalse(c.wasHelpCalled());
+        assertEquals("", c.getStdErr());
+        assertEquals("value1", c.getValue("verb1", "action1", "first"));
+        assertEquals("value2", c.getValue("verb1", "action1", "second"));
+
+        c = new MockCommandLineProcessor(mLog);        
+        c.parseArgs(new String[] { "verb1", "action1", "-2", "value2" });
+        assertFalse(c.wasExitCalled());
+        assertFalse(c.wasHelpCalled());
+        assertEquals("", c.getStdErr());
+        assertEquals(null, c.getValue("verb1", "action1", "first"));
+        assertEquals("value2", c.getValue("verb1", "action1", "second"));
+
+        c = new MockCommandLineProcessor(mLog);        
+        c.parseArgs(new String[] { "verb1", "action1" });
+        assertTrue(c.wasExitCalled());
+        assertTrue(c.wasHelpCalled());
+        assertTrue(c.getStdErr().indexOf("must be defined") != -1);
+        assertEquals(null, c.getValue("verb1", "action1", "first"));
+        assertEquals(null, c.getValue("verb1", "action1", "second"));
+    }
+}
diff --git a/tools/sdkmanager/app/tests/com/android/sdkmanager/MockStdLogger.java b/tools/sdkmanager/app/tests/com/android/sdkmanager/MockStdLogger.java
new file mode 100644
index 0000000..961e88d
--- /dev/null
+++ b/tools/sdkmanager/app/tests/com/android/sdkmanager/MockStdLogger.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.sdkmanager;
+
+import com.android.sdklib.ISdkLog;
+
+/**
+ * 
+ */
+public class MockStdLogger implements ISdkLog {
+
+    public void error(Throwable t, String errorFormat, Object... args) {
+        if (errorFormat != null) {
+            System.err.printf("Error: " + errorFormat, args);
+            if (!errorFormat.endsWith("\n")) {
+                System.err.printf("\n");
+            }
+        }
+        if (t != null) {
+            System.err.printf("Error: %s\n", t.getMessage());
+        }
+    }
+
+    public void warning(String warningFormat, Object... args) {
+        System.out.printf("Warning: " + warningFormat, args);
+        if (!warningFormat.endsWith("\n")) {
+            System.out.printf("\n");
+        }
+    }
+
+    public void printf(String msgFormat, Object... args) {
+        System.out.printf(msgFormat, args);
+    }
+}
diff --git a/tools/sdkmanager/app/tests/com/android/sdkmanager/SdkCommandLineTest.java b/tools/sdkmanager/app/tests/com/android/sdkmanager/SdkCommandLineTest.java
new file mode 100644
index 0000000..07a32e0
--- /dev/null
+++ b/tools/sdkmanager/app/tests/com/android/sdkmanager/SdkCommandLineTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdkmanager;
+
+import com.android.sdklib.ISdkLog;
+
+import junit.framework.TestCase;
+
+public class SdkCommandLineTest extends TestCase {
+
+    private MockStdLogger mLog;
+    
+    /**
+     * A mock version of the {@link SdkCommandLine} class that does not
+     * exits and discards its stdout/stderr output.
+     */
+    public static class MockSdkCommandLine extends SdkCommandLine {
+        private boolean mExitCalled;
+        private boolean mHelpCalled;
+        
+        public MockSdkCommandLine(ISdkLog logger) {
+            super(logger);
+        }
+
+        @Override
+        public void printHelpAndExitForAction(String verb, String directObject,
+                String errorFormat, Object... args) {
+            mHelpCalled = true;
+            super.printHelpAndExitForAction(verb, directObject, errorFormat, args);
+        }
+
+        @Override
+        protected void exit() {
+            mExitCalled = true;
+        }
+        
+        @Override
+        protected void stdout(String format, Object... args) {
+            // discard
+        }
+        
+        @Override
+        protected void stderr(String format, Object... args) {
+            // discard
+        }
+
+        public boolean wasExitCalled() {
+            return mExitCalled;
+        }
+        
+        public boolean wasHelpCalled() {
+            return mHelpCalled;
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        mLog = new MockStdLogger();
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /** Test list */
+    public final void testList_Avd_Verbose() {
+        MockSdkCommandLine c = new MockSdkCommandLine(mLog);
+        c.parseArgs(new String[] { "-v", "list", "avd" });
+        assertFalse(c.wasHelpCalled());
+        assertFalse(c.wasExitCalled());
+        assertEquals("list", c.getVerb());
+        assertEquals("avd", c.getDirectObject());
+        assertTrue(c.isVerbose());
+    }
+
+    public final void testList_Target() {
+        MockSdkCommandLine c = new MockSdkCommandLine(mLog);
+        c.parseArgs(new String[] { "list", "target" });
+        assertFalse(c.wasHelpCalled());
+        assertFalse(c.wasExitCalled());
+        assertEquals("list", c.getVerb());
+        assertEquals("target", c.getDirectObject());
+        assertFalse(c.isVerbose());
+    }
+
+    public final void testList_None() {
+        MockSdkCommandLine c = new MockSdkCommandLine(mLog);
+        c.parseArgs(new String[] { "list" });
+        assertFalse(c.wasHelpCalled());
+        assertFalse(c.wasExitCalled());
+        assertEquals("list", c.getVerb());
+        assertEquals("", c.getDirectObject());
+        assertFalse(c.isVerbose());
+    }
+
+    public final void testList_Invalid() {
+        MockSdkCommandLine c = new MockSdkCommandLine(mLog);
+        c.parseArgs(new String[] { "list", "unknown" });
+        assertTrue(c.wasHelpCalled());
+        assertTrue(c.wasExitCalled());
+        assertEquals(null, c.getVerb());
+        assertEquals(null, c.getDirectObject());
+        assertFalse(c.isVerbose());
+    }
+
+    public final void testList_Plural() {
+        MockSdkCommandLine c = new MockSdkCommandLine(mLog);
+        c.parseArgs(new String[] { "list", "avds" });
+        assertFalse(c.wasHelpCalled());
+        assertFalse(c.wasExitCalled());
+        assertEquals("list", c.getVerb());
+        // we get the non-plural form
+        assertEquals("avd", c.getDirectObject());
+        assertFalse(c.isVerbose());
+
+        c = new MockSdkCommandLine(mLog);
+        c.parseArgs(new String[] { "list", "targets" });
+        assertFalse(c.wasHelpCalled());
+        assertFalse(c.wasExitCalled());
+        assertEquals("list", c.getVerb());
+        // we get the non-plural form
+        assertEquals("target", c.getDirectObject());
+        assertFalse(c.isVerbose());
+    }
+}
diff --git a/tools/sdkmanager/libs/Android.mk b/tools/sdkmanager/libs/Android.mk
new file mode 100644
index 0000000..a934aa7
--- /dev/null
+++ b/tools/sdkmanager/libs/Android.mk
@@ -0,0 +1,18 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+SDKLIBS_LOCAL_DIR := $(call my-dir)
+include $(SDKLIBS_LOCAL_DIR)/sdklib/Android.mk
+include $(SDKLIBS_LOCAL_DIR)/sdkuilib/Android.mk
diff --git a/tools/sdkmanager/libs/sdklib/.classpath b/tools/sdkmanager/libs/sdklib/.classpath
new file mode 100644
index 0000000..fc17a43
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/AndroidPrefs"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/sdkmanager/libs/sdklib/.project b/tools/sdkmanager/libs/sdklib/.project
new file mode 100644
index 0000000..97a8578
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>SdkLib</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/sdkmanager/libs/sdklib/Android.mk b/tools/sdkmanager/libs/sdklib/Android.mk
new file mode 100644
index 0000000..509c573
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/Android.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+SDKLIB_LOCAL_DIR := $(call my-dir)
+include $(SDKLIB_LOCAL_DIR)/src/Android.mk
diff --git a/tools/sdkmanager/libs/sdklib/src/Android.mk b/tools/sdkmanager/libs/sdklib/src/Android.mk
new file mode 100644
index 0000000..a059a46
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/Android.mk
@@ -0,0 +1,27 @@
+#
+# Copyright (C) 2008 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES := \
+        androidprefs
+
+LOCAL_MODULE := sdklib
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java
new file mode 100644
index 0000000..0a59107
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdklib;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Represents an add-on target in the SDK.
+ * An add-on extends a standard {@link PlatformTarget}.
+ */
+final class AddOnTarget implements IAndroidTarget {
+    /**
+     * String to compute hash for add-on targets.
+     * Format is vendor:name:apiVersion
+     * */
+    private final static String ADD_ON_FORMAT = "%s:%s:%d"; //$NON-NLS-1$
+    
+    private final static class OptionalLibrary implements IOptionalLibrary {
+        private final String mJarName;
+        private final String mJarPath;
+        private final String mName;
+        private final String mDescription;
+
+        OptionalLibrary(String jarName, String jarPath, String name, String description) {
+            mJarName = jarName;
+            mJarPath = jarPath;
+            mName = name;
+            mDescription = description;
+        }
+
+        public String getJarName() {
+            return mJarName;
+        }
+
+        public String getJarPath() {
+            return mJarPath;
+        }
+
+        public String getName() {
+            return mName;
+        }
+        
+        public String getDescription() {
+            return mDescription;
+        }
+    }
+    
+    private final String mLocation;
+    private final PlatformTarget mBasePlatform;
+    private final String mName;
+    private final String mVendor;
+    private final String mDescription;
+    private String[] mSkins;
+    private String mDefaultSkin;
+    private IOptionalLibrary[] mLibraries;
+
+    /**
+     * Creates a new add-on
+     * @param location the OS path location of the add-on
+     * @param name the name of the add-on
+     * @param vendor the vendor name of the add-on
+     * @param description the add-on description
+     * @param libMap A map containing the optional libraries. The map key is the fully-qualified
+     * library name. The value is a 2 string array with the .jar filename, and the description.
+     * @param basePlatform the platform the add-on is extending.
+     */
+    AddOnTarget(String location, String name, String vendor, String description,
+            Map<String, String[]> libMap, PlatformTarget basePlatform) {
+        if (location.endsWith(File.separator) == false) {
+            location = location + File.separator;
+        }
+
+        mLocation = location;
+        mName = name;
+        mVendor = vendor;
+        mDescription = description;
+        mBasePlatform = basePlatform;
+        
+        // handle the optional libraries.
+        if (libMap != null) {
+            mLibraries = new IOptionalLibrary[libMap.size()];
+            int index = 0;
+            for (Entry<String, String[]> entry : libMap.entrySet()) {
+                String jarFile = entry.getValue()[0];
+                String desc = entry.getValue()[1];
+                mLibraries[index++] = new OptionalLibrary(jarFile,
+                        mLocation + SdkConstants.OS_ADDON_LIBS_FOLDER + jarFile,
+                        entry.getKey(), desc);
+            }
+        }
+    }
+    
+    public String getLocation() {
+        return mLocation;
+    }
+    
+    public String getName() {
+        return mName;
+    }
+    
+    public String getVendor() {
+        return mVendor;
+    }
+    
+    public String getFullName() {
+        return String.format("%1$s (%2$s)", mName, mVendor);
+    }
+    
+    public String getDescription() {
+        return mDescription;
+    }
+
+    public String getApiVersionName() {
+        // this is always defined by the base platform
+        return mBasePlatform.getApiVersionName();
+    }
+
+    public int getApiVersionNumber() {
+        // 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:
+                return mLocation + SdkConstants.OS_IMAGES_FOLDER;
+            case SKINS:
+                return mLocation + SdkConstants.OS_SKINS_FOLDER;
+            case DOCS:
+                return mLocation + SdkConstants.FD_DOCS + File.separator;
+            default :
+                return mBasePlatform.getPath(pathId);
+        }
+    }
+
+    public String[] getSkins() {
+        return mSkins;
+    }
+    
+    public String getDefaultSkin() {
+        return mDefaultSkin;
+    }
+
+    public IOptionalLibrary[] getOptionalLibraries() {
+        return mLibraries;
+    }
+    
+    public boolean isCompatibleBaseFor(IAndroidTarget target) {
+        // basic test
+        if (target == this) {
+            return true;
+        }
+
+        // if the receiver has no optional library, then anything with api version number >= to
+        // the receiver is compatible.
+        if (mLibraries.length == 0) {
+            return target.getApiVersionNumber() >= getApiVersionNumber();
+        }
+
+        // Otherwise, target is only compatible if the vendor and name are equals with the api
+        // number greater or equal (ie target is a newer version of this add-on).
+        if (target.isPlatform() == false) {
+            return (mVendor.equals(target.getVendor()) && mName.equals(target.getName()) &&
+                    target.getApiVersionNumber() >= getApiVersionNumber());
+        }
+
+        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.
+     * (non-Javadoc)
+     * @see java.lang.Comparable#compareTo(java.lang.Object)
+     */
+    public int compareTo(IAndroidTarget target) {
+        if (target.isPlatform()) {
+            return +1;
+        }
+        
+        // vendor
+        int value = mVendor.compareTo(target.getVendor());
+
+        // name
+        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) {
+        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()]);
+    }
+}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java
new file mode 100644
index 0000000..fa462bd
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdklib;
+
+
+/**
+ * A version of Android that application 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. */
+    public static int ANDROID_AIDL        = 2;
+    /** OS Path to "images" folder which contains the emulator system images. */
+    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. */ 
+    public static int SKINS               = 5;
+    /** OS Path to the "templates" folder which contains the templates for new projects. */
+    public static int TEMPLATES           = 6;
+    /** OS Path to the "data" folder which contains data & libraries for the SDK tools. */
+    public static int DATA                = 7;
+    /** OS Path to the "attrs.xml" file. */
+    public static int ATTRIBUTES          = 8;
+    /** OS Path to the "attrs_manifest.xml" file. */
+    public static int MANIFEST_ATTRIBUTES = 9;
+    /** OS Path to the "data/layoutlib.jar" library. */
+    public static int LAYOUT_LIB          = 10;
+    /** OS Path to the "data/res" folder. */
+    public static int RESOURCES           = 11;
+    /** OS Path to the "data/fonts" folder. */
+    public static int FONTS               = 12;
+    /** OS Path to the "data/widgets.txt" file. */
+    public static int WIDGETS             = 13;
+    /** OS Path to the "data/activity_actions.txt" file. */
+    public static int ACTIONS_ACTIVITY    = 14;
+    /** OS Path to the "data/broadcast_actions.txt" file. */
+    public static int ACTIONS_BROADCAST   = 15;
+    /** OS Path to the "data/service_actions.txt" file. */
+    public static int ACTIONS_SERVICE     = 16;
+    /** OS Path to the "data/categories.txt" file. */
+    public static int CATEGORIES          = 17;
+    /** OS Path to the "sources" folder. */
+    public static int SOURCES             = 18;
+    /** OS Path to the target specific docs */
+    public static int DOCS                = 19;
+    /** OS Path to the target's version of the aapt tool. */
+    public static int AAPT                = 20;
+    /** OS Path to the target's version of the aidl tool. */
+    public static int AIDL                = 21;
+    /** OS Path to the target's version of the dx too. */
+    public static int DX                  = 22;
+    /** OS Path to the target's version of the dx.jar file. */
+    public static int DX_JAR              = 23;
+    
+    public interface IOptionalLibrary {
+        String getName();
+        String getJarName();
+        String getJarPath();
+        String getDescription();
+    }
+
+    /**
+     * Returns the target location.
+     */
+    String getLocation();
+
+    /**
+     * Returns the name of the vendor of the target.
+     */
+    String getVendor();
+
+    /**
+     * Returns the name of the target.
+     */
+    String getName();
+    
+    /**
+     * Returns the full name of the target, possibly including vendor name.
+     */
+    String getFullName();
+    
+    /**
+     * Returns the description of the target.
+     */
+    String getDescription();
+    
+    /**
+     * Returns the api version as an integer.
+     */
+    int getApiVersionNumber();
+
+    /**
+     * 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 whether the given target is compatible with the receiver.
+     * <p/>A target is considered compatible if applications developed for the receiver can run on
+     * the given target.
+     *
+     * @param target the IAndroidTarget to test.
+     */
+    boolean isCompatibleBaseFor(IAndroidTarget target);
+    
+    /**
+     * Returns a string able to uniquely identify a target.
+     * Typically the target will encode information such as api level, whether it's a platform
+     * or add-on, and if it's an add-on vendor and add-on name.
+     */
+    String hashString();
+}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/ISdkLog.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/ISdkLog.java
new file mode 100644
index 0000000..4894517
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/ISdkLog.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdklib;
+
+import java.util.Formatter;
+
+/**
+ * Interface used to display warnings/errors while parsing the SDK content.
+ */
+public interface ISdkLog {
+    
+    /**
+     * Prints a warning message on stdout.
+     * <p/>
+     * Implementations should only display warnings in verbose mode.
+     * The message should be prefixed with "Warning:".
+     * 
+     * @param warningFormat is an optional error format. If non-null, it will be printed
+     *          using a {@link Formatter} with the provided arguments.
+     * @param args provides the arguments for warningFormat.
+     */
+    void warning(String warningFormat, Object... args);
+    
+    /**
+     * Prints an error message on stderr.
+     * <p/>
+     * Implementation should always display errors, independent of verbose mode.
+     * The message should be prefixed with "Error:".
+     * 
+     * @param t is an optional {@link Throwable} or {@link Exception}. If non-null, it's
+     *          message will be printed out.
+     * @param errorFormat is an optional error format. If non-null, it will be printed
+     *          using a {@link Formatter} with the provided arguments.
+     * @param args provides the arguments for errorFormat.
+     */
+    void error(Throwable t, String errorFormat, Object... args);
+    
+    /**
+     * Prints a message as-is on stdout.
+     * <p/>
+     * Implementation should always display errors, independent of verbose mode.
+     * No prefix is used, the message is printed as-is after formatting.
+     * 
+     * @param msgFormat is an optional error format. If non-null, it will be printed
+     *          using a {@link Formatter} with the provided arguments.
+     * @param args provides the arguments for msgFormat.
+     */
+    void printf(String msgFormat, Object... args);
+}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java
new file mode 100644
index 0000000..a3da70e
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdklib;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Represents a platform target in the SDK. 
+ */
+final class PlatformTarget implements IAndroidTarget {
+    /** String used to get a hash to the platform target */
+    private final static String PLATFORM_HASH = "android-%d";
+    
+    private final static String PLATFORM_VENDOR = "Android";
+    private final static String PLATFORM_NAME = "Android %s";
+
+    private final String mLocation;
+    private final String mName;
+    private final int mApiVersionNumber;
+    private final String mApiVersionName;
+    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);
+        if (location.endsWith(File.separator) == false) {
+            location = location + File.separator;
+        }
+        mLocation = location;
+        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);
+        mPaths.put(ANDROID_AIDL, mLocation + SdkConstants.FN_FRAMEWORK_AIDL);
+        mPaths.put(IMAGES, mLocation + SdkConstants.OS_IMAGES_FOLDER);
+        mPaths.put(SAMPLES, mLocation + SdkConstants.OS_PLATFORM_SAMPLES_FOLDER);
+        mPaths.put(SKINS, mLocation + SdkConstants.OS_SKINS_FOLDER);
+        mPaths.put(TEMPLATES, mLocation + SdkConstants.OS_PLATFORM_TEMPLATES_FOLDER);
+        mPaths.put(DATA, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER);
+        mPaths.put(ATTRIBUTES, mLocation + SdkConstants.OS_PLATFORM_ATTRS_XML);
+        mPaths.put(MANIFEST_ATTRIBUTES, mLocation + SdkConstants.OS_PLATFORM_ATTRS_MANIFEST_XML);
+        mPaths.put(RESOURCES, mLocation + SdkConstants.OS_PLATFORM_RESOURCES_FOLDER);
+        mPaths.put(FONTS, mLocation + SdkConstants.OS_PLATFORM_FONTS_FOLDER);
+        mPaths.put(LAYOUT_LIB, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
+                SdkConstants.FN_LAYOUTLIB_JAR);
+        mPaths.put(WIDGETS, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
+                SdkConstants.FN_WIDGETS);
+        mPaths.put(ACTIONS_ACTIVITY, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
+                SdkConstants.FN_INTENT_ACTIONS_ACTIVITY);
+        mPaths.put(ACTIONS_BROADCAST, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
+                SdkConstants.FN_INTENT_ACTIONS_BROADCAST);
+        mPaths.put(ACTIONS_SERVICE, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
+                SdkConstants.FN_INTENT_ACTIONS_SERVICE);
+        mPaths.put(CATEGORIES, mLocation + SdkConstants.OS_PLATFORM_DATA_FOLDER +
+                SdkConstants.FN_INTENT_CATEGORIES);
+        mPaths.put(AAPT, mLocation + SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_AAPT);
+        mPaths.put(AIDL, mLocation + SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_AIDL);
+        mPaths.put(DX, mLocation + SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_DX);
+        mPaths.put(DX_JAR, mLocation + SdkConstants.OS_SDK_TOOLS_LIB_FOLDER +
+                SdkConstants.FN_DX_JAR);
+    }
+    
+    public String getLocation() {
+        return mLocation;
+    }
+    
+    /*
+     * (non-Javadoc)
+     * 
+     * For Platform, the vendor name is always "Android".
+     * 
+     * @see com.android.sdklib.IAndroidTarget#getVendor()
+     */
+    public String getVendor() {
+        return PLATFORM_VENDOR;
+    }
+
+    public String getName() {
+        return mName;
+    }
+    
+    public String getFullName() {
+        return mName;
+    }
+
+    /*
+     * (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)
+     * @see com.android.sdklib.IAndroidTarget#getOptionalLibraries()
+     */
+    public IOptionalLibrary[] getOptionalLibraries() {
+        return null;
+    }
+    
+    public boolean isCompatibleBaseFor(IAndroidTarget target) {
+        // basic test
+        if (target == this) {
+            return true;
+        }
+
+        // target is compatible wit the receiver as long as its api version number is greater or
+        // equal.
+        return target.getApiVersionNumber() >= mApiVersionNumber;
+    }
+    
+    public String hashString() {
+        return String.format(PLATFORM_HASH, mApiVersionNumber);
+    }
+
+    @Override
+    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);
+    }
+
+    /*
+     * Always return -1 if the object we compare to is an addon.
+     * Otherwise, compare api level.
+     * (non-Javadoc)
+     * @see java.lang.Comparable#compareTo(java.lang.Object)
+     */
+    public int compareTo(IAndroidTarget target) {
+        if (target.isPlatform() == false) {
+            return -1;
+        }
+
+        return mApiVersionNumber - target.getApiVersionNumber();
+    }
+
+    // ---- platform only methods.
+    
+    public String getProperty(String name) {
+        return mProperties.get(name);
+    }
+    
+    public Map<String, String> getProperties() {
+        return mProperties; // mProperties is unmodifiable.
+    }
+
+    void setSkins(String[] skins) {
+        mSkins = skins;
+    }
+}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java
new file mode 100644
index 0000000..00594d1
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdklib;
+
+import java.io.File;
+
+/**
+ * Constant definition class.<br>
+ * <br>
+ * Most constants have a prefix defining the content.
+ * <ul>
+ * <li><code>OS_</code> OS path constant. These paths are different depending on the platform.</li>
+ * <li><code>FN_</code> File name constant.</li>
+ * <li><code>FD_</code> Folder name constant.</li>
+ * </ul>
+ *
+ */
+public final class SdkConstants {
+    public final static int PLATFORM_UNKNOWN = 0;
+    public final static int PLATFORM_LINUX = 1;
+    public final static int PLATFORM_WINDOWS = 2;
+    public final static int PLATFORM_DARWIN = 3;
+
+    /**
+     * Returns current platform, one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
+     * {@link #PLATFORM_LINUX} or {@link #PLATFORM_UNKNOWN}.
+     */
+    public final static int CURRENT_PLATFORM = currentPlatform();
+
+    
+    /** An SDK Project's AndroidManifest.xml file */
+    public static final String FN_ANDROID_MANIFEST_XML= "AndroidManifest.xml";
+    /** An SDK Project's build.xml file */
+    public final static String FN_BUILD_XML = "build.xml";
+
+    /** Name of the framework library, i.e. "android.jar" */
+    public static final String FN_FRAMEWORK_LIBRARY = "android.jar";
+    /** Name of the layout attributes, i.e. "attrs.xml" */
+    public static final String FN_ATTRS_XML = "attrs.xml";
+    /** Name of the layout attributes, i.e. "attrs_manifest.xml" */
+    public static final String FN_ATTRS_MANIFEST_XML = "attrs_manifest.xml";
+    /** framework aidl import file */
+    public static final String FN_FRAMEWORK_AIDL = "framework.aidl";
+    /** layoutlib.jar file */
+    public static final String FN_LAYOUTLIB_JAR = "layoutlib.jar";
+    /** widget list file */
+    public static final String FN_WIDGETS = "widgets.txt";
+    /** Intent activity actions list file */
+    public static final String FN_INTENT_ACTIONS_ACTIVITY = "activity_actions.txt";
+    /** Intent broadcast actions list file */
+    public static final String FN_INTENT_ACTIONS_BROADCAST = "broadcast_actions.txt";
+    /** Intent service actions list file */
+    public static final String FN_INTENT_ACTIONS_SERVICE = "service_actions.txt";
+    /** Intent category list file */
+    public static final String FN_INTENT_CATEGORIES = "categories.txt";
+
+    /** platform build property file */
+    public final static String FN_BUILD_PROP = "build.prop";
+    /** plugin properties file */
+    public final static String FN_PLUGIN_PROP = "plugin.prop";
+    /** add-on manifest file */
+    public final static String FN_MANIFEST_INI = "manifest.ini";
+    /** hardware properties definition file */
+    public final static String FN_HARDWARE_INI = "hardware-properties.ini";
+
+    /** Skin layout file */
+    public final static String FN_SKIN_LAYOUT = "layout";//$NON-NLS-1$
+
+    /** dex.jar file */
+    public static final String FN_DX_JAR = "dx.jar"; //$NON-NLS-1$
+
+    /** dx executable */
+    public final static String FN_DX = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
+            "dx.bat" : "dx"; //$NON-NLS-1$ //$NON-NLS-2$
+
+    /** aapt executable */
+    public final static String FN_AAPT = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
+            "aapt.exe" : "aapt"; //$NON-NLS-1$ //$NON-NLS-2$
+
+    /** aidl executable */
+    public final static String FN_AIDL = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ?
+            "aidl.exe" : "aidl"; //$NON-NLS-1$ //$NON-NLS-2$
+
+    /* Folder Names for Android Projects . */
+
+    /** Resources folder name, i.e. "res". */
+    public final static String FD_RESOURCES = "res"; //$NON-NLS-1$
+    /** Assets folder name, i.e. "assets" */
+    public final static String FD_ASSETS = "assets"; //$NON-NLS-1$
+    /** Default source folder name, i.e. "src" */
+    public final static String FD_SOURCES = "src"; //$NON-NLS-1$
+    /** Default generated source folder name, i.e. "gen" */
+    public final static String FD_GEN_SOURCES = "gen"; //$NON-NLS-1$
+    /** Default native library folder name inside the project, i.e. "libs"
+     * While the folder inside the .apk is "lib", we call that one libs because
+     * that's what we use in ant for both .jar and .so and we need to make the 2 development ways
+     * compatible. */
+    public final static String FD_NATIVE_LIBS = "libs"; //$NON-NLS-1$
+    /** Native lib folder inside the APK: "lib" */
+    public final static String FD_APK_NATIVE_LIBS = "lib"; //$NON-NLS-1$
+    /** Default output folder name, i.e. "bin" */
+    public final static String FD_OUTPUT = "bin"; //$NON-NLS-1$
+    /** Default anim resource folder name, i.e. "anim" */
+    public final static String FD_ANIM = "anim"; //$NON-NLS-1$
+    /** Default color resource folder name, i.e. "color" */
+    public final static String FD_COLOR = "color"; //$NON-NLS-1$
+    /** Default drawable resource folder name, i.e. "drawable" */
+    public final static String FD_DRAWABLE = "drawable"; //$NON-NLS-1$
+    /** Default layout resource folder name, i.e. "layout" */
+    public final static String FD_LAYOUT = "layout"; //$NON-NLS-1$
+    /** Default menu resource folder name, i.e. "menu" */
+    public final static String FD_MENU = "menu"; //$NON-NLS-1$
+    /** Default values resource folder name, i.e. "values" */
+    public final static String FD_VALUES = "values"; //$NON-NLS-1$
+    /** Default xml resource folder name, i.e. "xml" */
+    public final static String FD_XML = "xml"; //$NON-NLS-1$
+    /** Default raw resource folder name, i.e. "raw" */
+    public final static String FD_RAW = "raw"; //$NON-NLS-1$
+
+    /* Folder Names for the Android SDK */
+    
+    /** Name of the SDK platforms folder. */
+    public final static String FD_PLATFORMS = "platforms";
+    /** Name of the SDK addons folder. */
+    public final static String FD_ADDONS = "add-ons";
+    /** Name of the SDK tools folder. */
+    public final static String FD_TOOLS = "tools";
+    /** Name of the SDK tools/lib folder. */
+    public final static String FD_LIB = "lib";
+    /** Name of the SDK docs folder. */
+    public final static String FD_DOCS = "docs";
+    /** Name of the SDK images folder. */
+    public final static String FD_IMAGES = "images";
+    /** Name of the SDK skins folder. */
+    public final static String FD_SKINS = "skins";
+    /** Name of the SDK samples folder. */
+    public final static String FD_SAMPLES = "samples";
+    /** Name of the SDK templates folder, i.e. "templates" */
+    public final static String FD_TEMPLATES = "templates";
+    /** Name of the SDK data folder, i.e. "data" */
+    public final static String FD_DATA = "data";
+    /** Name of the SDK resources folder, i.e. "res" */
+    public final static String FD_RES = "res";
+    /** Name of the SDK font folder, i.e. "fonts" */
+    public final static String FD_FONTS = "fonts";
+    /** Name of the android sources directory */
+    public static final String FD_ANDROID_SOURCES = "sources";
+    /** Name of the addon libs folder. */
+    public final static String FD_ADDON_LIBS = "libs";
+
+    /** Namespace for the resource XML, i.e. "http://schemas.android.com/apk/res/android" */
+    public final static String NS_RESOURCES = "http://schemas.android.com/apk/res/android";
+
+    /* Folder path relative to the SDK root */
+    /** Path of the documentation directory relative to the sdk folder.
+     *  This is an OS path, ending with a separator. */
+    public final static String OS_SDK_DOCS_FOLDER = FD_DOCS + File.separator;
+
+    /** Path of the tools directory relative to the sdk folder, or to a platform folder.
+     *  This is an OS path, ending with a separator. */
+    public final static String OS_SDK_TOOLS_FOLDER = FD_TOOLS + File.separator;
+
+    /** Path of the lib directory relative to the sdk folder, or to a platform folder.
+     *  This is an OS path, ending with a separator. */
+    public final static String OS_SDK_TOOLS_LIB_FOLDER =
+            OS_SDK_TOOLS_FOLDER + FD_LIB + File.separator;
+
+    /* Folder paths relative to a platform or add-on folder */
+    
+    /** Path of the images directory relative to a platform or addon folder.
+     *  This is an OS path, ending with a separator. */
+    public final static String OS_IMAGES_FOLDER = FD_IMAGES + File.separator;
+
+    /** Path of the skin directory relative to a platform or addon folder.
+     *  This is an OS path, ending with a separator. */
+    public final static String OS_SKINS_FOLDER = FD_SKINS + File.separator;
+
+    /* Folder paths relative to a Platform folder */
+
+    /** Path of the data directory relative to a platform folder.
+     *  This is an OS path, ending with a separator. */
+    public final static String OS_PLATFORM_DATA_FOLDER = FD_DATA + File.separator;
+
+    /** Path of the samples directory relative to a platform folder.
+     *  This is an OS path, ending with a separator. */
+    public final static String OS_PLATFORM_SAMPLES_FOLDER = FD_SAMPLES + File.separator;
+
+    /** Path of the resources directory relative to a platform folder.
+     *  This is an OS path, ending with a separator. */
+    public final static String OS_PLATFORM_RESOURCES_FOLDER =
+            OS_PLATFORM_DATA_FOLDER + FD_RES + File.separator;
+
+    /** Path of the fonts directory relative to a platform folder.
+     *  This is an OS path, ending with a separator. */
+    public final static String OS_PLATFORM_FONTS_FOLDER =
+            OS_PLATFORM_DATA_FOLDER + FD_FONTS + File.separator;
+
+    /** Path of the android source directory relative to a platform folder.
+     *  This is an OS path, ending with a separator. */
+    public final static String OS_PLATFORM_SOURCES_FOLDER = FD_ANDROID_SOURCES + File.separator;
+
+    /** Path of the android templates directory relative to a platform folder.
+     *  This is an OS path, ending with a separator. */
+    public final static String OS_PLATFORM_TEMPLATES_FOLDER = FD_TEMPLATES + File.separator;
+
+    /** Path of the attrs.xml file relative to a platform folder. */
+    public final static String OS_PLATFORM_ATTRS_XML =
+            OS_PLATFORM_RESOURCES_FOLDER + FD_VALUES + File.separator + FN_ATTRS_XML;
+
+    /** Path of the attrs_manifest.xml file relative to a platform folder. */
+    public final static String OS_PLATFORM_ATTRS_MANIFEST_XML =
+            OS_PLATFORM_RESOURCES_FOLDER + FD_VALUES + File.separator + FN_ATTRS_MANIFEST_XML;
+
+    /** Path of the layoutlib.jar file relative to a platform folder. */
+    public final static String OS_PLATFORM_LAYOUTLIB_JAR =
+            OS_PLATFORM_DATA_FOLDER + FN_LAYOUTLIB_JAR;
+    
+    /* Folder paths relative to a addon folder */
+
+    /** Path of the images directory relative to a folder folder.
+     *  This is an OS path, ending with a separator. */
+    public final static String OS_ADDON_LIBS_FOLDER = FD_ADDON_LIBS + File.separator;
+    
+    
+    /** Skin default **/
+    public final static String SKIN_DEFAULT = "default";
+
+    /** Returns the appropriate name for the 'android' command, which is 'android.bat' for
+     * Windows and 'android' for all other platforms. */
+    public static String androidCmdName() {
+        String os = System.getProperty("os.name");
+        String cmd = "android";
+        if (os.startsWith("Windows")) {
+            cmd += ".bat";
+        }
+        return cmd;
+    }
+
+    /** Returns the appropriate name for the 'mksdcard' command, which is 'mksdcard.exe' for
+     * Windows and 'mkdsdcard' for all other platforms. */
+    public static String mkSdCardCmdName() {
+        String os = System.getProperty("os.name");
+        String cmd = "mksdcard";
+        if (os.startsWith("Windows")) {
+            cmd += ".exe";
+        }
+        return cmd;
+    }
+
+    /**
+     * Returns current platform
+     * 
+     * @return one of {@link #PLATFORM_WINDOWS}, {@link #PLATFORM_DARWIN},
+     * {@link #PLATFORM_LINUX} or {@link #PLATFORM_UNKNOWN}.
+     */
+    private static int currentPlatform() {
+        String os = System.getProperty("os.name");          //$NON-NLS-1$
+        if (os.startsWith("Mac OS")) {                      //$NON-NLS-1$
+            return PLATFORM_DARWIN;
+        } else if (os.startsWith("Windows")) {              //$NON-NLS-1$
+            return PLATFORM_WINDOWS;
+        } else if (os.startsWith("Linux")) {                //$NON-NLS-1$
+            return PLATFORM_LINUX;
+        }
+
+        return PLATFORM_UNKNOWN;
+    }
+}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java
new file mode 100644
index 0000000..28227c6
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java
@@ -0,0 +1,511 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdklib;
+
+import java.io.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.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * The SDK manager parses the SDK folder and gives access to the content.
+ * @see PlatformTarget
+ * @see AddOnTarget 
+ */
+public final class SdkManager {
+    
+    public final static String PROP_VERSION_SDK = "ro.build.version.sdk";
+    public final static String PROP_VERSION_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 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);
+    
+    /** List of items in the platform to check when parsing it. These paths are relative to the
+     * platform root folder. */
+    private final static String[] sPlatformContentList = new String[] {
+        SdkConstants.FN_FRAMEWORK_LIBRARY,
+        SdkConstants.FN_FRAMEWORK_AIDL,
+        SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_AAPT,
+        SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_AIDL,
+        SdkConstants.OS_SDK_TOOLS_FOLDER + SdkConstants.FN_DX,
+        SdkConstants.OS_SDK_TOOLS_LIB_FOLDER + SdkConstants.FN_DX_JAR,
+    };
+
+    /** the location of the SDK */
+    private final String mSdkLocation;
+    private IAndroidTarget[] mTargets;
+
+    /**
+     * Creates an {@link SdkManager} for a given sdk location.
+     * @param sdkLocation the location of the SDK.
+     * @param log the ISdkLog object receiving warning/error from the parsing.
+     * @return the created {@link SdkManager} or null if the location is not valid.
+     */
+    public static SdkManager createManager(String sdkLocation, ISdkLog log) {
+        try {
+            SdkManager manager = new SdkManager(sdkLocation);
+            ArrayList<IAndroidTarget> list = new ArrayList<IAndroidTarget>();
+            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.
+     */
+    public IAndroidTarget getTargetFromHashString(String hash) {
+        if (hash != null) {
+            for (IAndroidTarget target : mTargets) {
+                if (hash.equals(target.hashString())) {
+                    return target;
+                }
+            }
+        }
+
+        return null;
+    }
+
+
+    private SdkManager(String sdkLocation) {
+        mSdkLocation = sdkLocation;
+    }
+    
+    private void setTargets(IAndroidTarget[] targets) {
+        mTargets = targets;
+    }
+
+    /**
+     * Loads the Platforms from the SDK.
+     * @param list the list to fill with the platforms.
+     * @param log the ISdkLog object receiving warning/error from the parsing.
+     */
+    private void loadPlatforms(ArrayList<IAndroidTarget> list, ISdkLog log) {
+        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);
+                    if (target != null) {
+                        list.add(target);
+                    }
+                } else if (log != null) {
+                    log.warning("Ignoring platform '%1$s', not a folder.", platform.getName());
+                }
+            }
+            
+            return;
+        }
+
+        String message = null;
+        if (platformFolder.exists() == false) {
+            message = "%s is missing.";
+        } else {
+            message = "%s is not a folder.";
+        }
+
+        throw new IllegalArgumentException(String.format(message,
+                platformFolder.getAbsolutePath()));
+    }
+
+    /**
+     * Loads a specific Platform at a given location.
+     * @param platform the location of the platform.
+     * @param log the ISdkLog object receiving warning/error from the parsing.
+     */
+    private 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 {
+                    String apiNumber = map.get(PROP_VERSION_SDK);
+                    String apiName = map.get(PROP_VERSION_RELEASE);
+                    if (apiNumber != null && apiName != null) {
+                        // api number and name looks valid, perform a few more checks
+                        if (checkPlatformContent(platform, log) == false) {
+                            return null;
+                        }
+                        // create the target.
+                        PlatformTarget target = new PlatformTarget(
+                                platform.getAbsolutePath(),
+                                map,
+                                Integer.parseInt(apiNumber),
+                                apiName);
+                        
+                        // need to parse the skins.
+                        String[] skins = parseSkinFolder(target.getPath(IAndroidTarget.SKINS));
+                        target.setSkins(skins);
+
+                        return target;
+                    }
+                } catch (NumberFormatException e) {
+                    // looks like apiNumber does not parse to a number.
+                    // Ignore this platform.
+                    if (log != null) {
+                        log.error(null,
+                                "Ignoring platform '%1$s': %2$s is not a valid number in %3$s.",
+                                platform.getName(), PROP_VERSION_SDK, SdkConstants.FN_BUILD_PROP);
+                    }
+                }
+            }
+        } else if (log != null) {
+            log.error(null, "Ignoring platform '%1$s': %2$s is missing.", platform.getName(),
+                    SdkConstants.FN_BUILD_PROP);
+        }
+        
+        return null;
+    }
+
+    /**
+     * Loads the Add-on from the SDK.
+     * @param list the list to fill with the add-ons.
+     * @param log the ISdkLog object receiving warning/error from the parsing.
+     */
+    private void loadAddOns(ArrayList<IAndroidTarget> list, ISdkLog log) {
+        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()) {
+                    AddOnTarget target = loadAddon(addon, list, log);
+                    if (target != null) {
+                        list.add(target);
+                    }
+                }
+            }
+
+            return;
+        }
+
+        String message = null;
+        if (addonFolder.exists() == false) {
+            message = "%s is missing.";
+        } else {
+            message = "%s is not a folder.";
+        }
+
+        throw new IllegalArgumentException(String.format(message,
+                addonFolder.getAbsolutePath()));
+    }
+    
+    /**
+     * Loads a specific Add-on at a given location.
+     * @param addon the location of the addon.
+     * @param list 
+     * @param log 
+     */
+    private AddOnTarget loadAddon(File addon, ArrayList<IAndroidTarget> list, ISdkLog log) {
+        File addOnManifest = new File(addon, SdkConstants.FN_MANIFEST_INI);
+        
+        if (addOnManifest.isFile()) {
+            Map<String, String> propertyMap = parsePropertyFile(addOnManifest, log);
+            
+            if (propertyMap != null) {
+                // look for some specific values in the map.
+                // we require name, vendor, and api
+                String name = propertyMap.get(ADDON_NAME);
+                if (name == null) {
+                    displayAddonManifestError(log, addon.getName(), ADDON_NAME);
+                    return null;
+                }
+                
+                String vendor = propertyMap.get(ADDON_VENDOR);
+                if (vendor == null) {
+                    displayAddonManifestError(log, addon.getName(), ADDON_VENDOR);
+                    return null;
+                }
+
+                String api = propertyMap.get(ADDON_API);
+                PlatformTarget baseTarget = null;
+                if (api == null) {
+                    displayAddonManifestError(log, addon.getName(), ADDON_API);
+                    return null;
+                } else {
+                    try {
+                        int apiValue = Integer.parseInt(api);
+                        for (IAndroidTarget target : list) {
+                            if (target.isPlatform() &&
+                                    target.getApiVersionNumber() == apiValue) {
+                                baseTarget = (PlatformTarget)target;
+                                break;
+                            }
+                        }
+                        
+                        if (baseTarget == null) {
+                            if (log != null) {
+                                log.error(null,
+                                        "Ignoring add-on '%1$s': Unable to find base platform with API level %2$d",
+                                        addon.getName(), apiValue);
+                            }
+
+                            return null;
+                        }
+                    } catch (NumberFormatException e) {
+                        // looks like apiNumber does not parse to a number.
+                        // Ignore this add-on.
+                        if (log != null) {
+                            log.error(null,
+                                    "Ignoring add-on '%1$s': %2$s is not a valid number in %3$s.",
+                                    addon.getName(), ADDON_API, SdkConstants.FN_BUILD_PROP);
+                        }
+                        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) {
+                        // split in the string into the libraries name
+                        String[] libraries = librariesValue.split(";");
+                        if (libraries.length > 0) {
+                            libMap = new HashMap<String, String[]>();
+                            for (String libName : libraries) {
+                                libName = libName.trim();
+
+                                // get the library data from the properties
+                                String libData = propertyMap.get(libName);
+                                
+                                if (libData != null) {
+                                    // split the jar file from the description
+                                    Matcher m = PATTERN_LIB_DATA.matcher(libData);
+                                    if (m.matches()) {
+                                        libMap.put(libName, new String[] {
+                                                m.group(1), m.group(2) });
+                                    } else if (log != null) {
+                                        log.error(null,
+                                                "Ignoring library '%1$s', property value has wrong format\n\t%2$s",
+                                                libName, libData);
+                                    }
+                                } else if (log != null) {
+                                    log.error(null,
+                                            "Ignoring library '%1$s', missing property value",
+                                            libName, libData);
+                                }
+                            }
+                        }
+                    }
+                }
+
+                AddOnTarget target = new AddOnTarget(addon.getAbsolutePath(), name, vendor,
+                        description, libMap, baseTarget);
+                
+                // need to parse the skins.
+                String[] skins = parseSkinFolder(target.getPath(IAndroidTarget.SKINS));
+                
+                // get the default skin, or take it from the base platform if needed.
+                String defaultSkin = propertyMap.get(ADDON_DEFAULT_SKIN);
+                
+                if (defaultSkin == null) {
+                    if (skins.length == 1) {
+                        defaultSkin = skins[1];
+                    } else {
+                        defaultSkin = baseTarget.getDefaultSkin();
+                    }
+                }
+                
+                target.setSkins(skins, defaultSkin);
+
+                return target;
+            }
+        } else if (log != null) {
+            log.error(null, "Ignoring add-on '%1$s': %2$s is missing.", addon.getName(),
+                    SdkConstants.FN_MANIFEST_INI);
+        }
+        
+        return null;
+    }
+    
+    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.
+     * <p/>This checks the presence of the following files: android.jar, framework.aidl, aapt(.exe),
+     * aidl(.exe), dx(.bat), and dx.jar
+     */
+    private boolean checkPlatformContent(File platform, ISdkLog log) {
+        for (String relativePath : sPlatformContentList) {
+            File f = new File(platform, relativePath);
+            if (f.exists() == false) {
+                log.error(null,
+                        "Ignoring platform '%1$s': %2$s is missing.",
+                        platform.getName(), relativePath);
+                return false;
+            }
+            
+        }
+        return true;
+    }
+
+    
+    /**
+     * Parses a property file and returns
+     * @param buildProp the property file to parse
+     * @param log the ISdkLog object receiving warning/error from the parsing.
+     * @return the map of (key,value) pairs, or null if the parsing failed.
+     */
+    public static Map<String, String> parsePropertyFile(File buildProp, ISdkLog log) {
+        FileInputStream fis = null;
+        BufferedReader reader = null;
+        try {
+            fis = new FileInputStream(buildProp);
+            reader = new BufferedReader(new InputStreamReader(fis));
+
+            String line = null;
+            Map<String, String> map = new HashMap<String, String>();
+            while ((line = reader.readLine()) != null) {
+                if (line.length() > 0 && line.charAt(0) != '#') {
+                    
+                    Matcher m = PATTERN_PROP.matcher(line);
+                    if (m.matches()) {
+                        map.put(m.group(1), m.group(2));
+                    } else {
+                        log.warning("Error parsing '%1$s': \"%2$s\" is not a valid syntax",
+                                buildProp.getAbsolutePath(), line);
+                        return null;
+                    }
+                }
+            }
+            
+            return map;
+        } catch (FileNotFoundException e) {
+            // this should not happen since we usually test the file existence before
+            // calling the method.
+            // Return null below.
+        } catch (IOException e) {
+            if (log != null) {
+                log.warning("Error parsing '%1$s': %2$s.", buildProp.getAbsolutePath(),
+                        e.getMessage());
+            }
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                    // pass
+                }
+            }
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException e) {
+                    // pass
+                }
+            }
+        }
+
+        return null;
+    }
+    
+    /**
+     * Parses the skin folder and builds the skin list.
+     * @param osPath The path of the skin root folder.
+     */
+    private String[] parseSkinFolder(String osPath) {
+        File skinRootFolder = new File(osPath);
+
+        if (skinRootFolder.isDirectory()) {
+            ArrayList<String> skinList = new ArrayList<String>();
+
+            File[] files = skinRootFolder.listFiles();
+
+            for (File skinFolder : files) {
+                if (skinFolder.isDirectory()) {
+                    // check for layout file
+                    File layout = new File(skinFolder, SdkConstants.FN_SKIN_LAYOUT);
+
+                    if (layout.isFile()) {
+                        // for now we don't parse the content of the layout and
+                        // simply add the directory to the list.
+                        skinList.add(skinFolder.getName());
+                    }
+                }
+            }
+
+            return skinList.toArray(new String[skinList.size()]);
+        }
+        
+        return new String[0];
+    }
+}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java
new file mode 100644
index 0000000..0ea89d1
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java
@@ -0,0 +1,800 @@
+/*
+ * 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 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.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 {
+    
+    public static final String AVD_FOLDER_EXTENSION = ".avd";
+
+    private final static String AVD_INFO_PATH = "path";
+    private final static String AVD_INFO_TARGET = "target";
+    
+    public final static String AVD_INI_SKIN_PATH = "skin.path";
+    public final static String AVD_INI_SKIN_NAME = "skin.name";
+    public final static String AVD_INI_SDCARD_PATH = "sdcard.path";
+    public final static String AVD_INI_SDCARD_SIZE = "sdcard.size";
+    public final static String AVD_INI_IMAGES_1 = "image.sysdir.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 SDCARD_SIZE_PATTERN = Pattern.compile("\\d+[MK]?");
+
+    /** An immutable structure describing an Android Virtual Device. */
+    public static final class AvdInfo {
+        private final String mName;
+        private final String mPath;
+        private final IAndroidTarget mTarget;
+        private final Map<String, String> mProperties;
+        
+        /** Creates a new AVD info. Values are immutable. 
+         * @param properties */
+        public AvdInfo(String name, String path, IAndroidTarget target,
+                Map<String, String> properties) {
+            mName = name;
+            mPath = path;
+            mTarget = target;
+            mProperties = properties;
+        }
+
+        /** 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 of the AVD. */
+        public IAndroidTarget getTarget() {
+            return mTarget;
+        }
+
+        /** 
+         * 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);
+        }
+        
+        /**
+         * Returns a map of properties for the AVD.
+         */
+        public Map<String, String> getProperties() {
+            return mProperties;
+        }
+    }
+
+    private final ArrayList<AvdInfo> mAvdList = new ArrayList<AvdInfo>();
+    private ISdkLog mSdkLog;
+    private final SdkManager mSdk;
+
+    public AvdManager(SdkManager sdk, ISdkLog sdkLog) throws AndroidLocationException {
+        mSdk = sdk;
+        mSdkLog = sdkLog;
+        buildAvdList();
+    }
+
+    /**
+     * Returns the existing AVDs.
+     * @return a newly allocated array containing all the AVDs.
+     */
+    public AvdInfo[] getAvds() {
+        return mAvdList.toArray(new AvdInfo[mAvdList.size()]);
+    }
+
+    /**
+     * Returns the {@link AvdInfo} matching the given <var>name</var>.
+     * @return the matching AvdInfo or <code>null</code> if none were found.
+     */
+    public AvdInfo getAvd(String name) {
+        for (AvdInfo info : mAvdList) {
+            if (info.getName().equals(name)) {
+                return info;
+            }
+        }
+        
+        return 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
+     * @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, ISdkLog log) {
+        
+        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 (log != null) {
+                        log.error(null,
+                                "Folder %s is in the way. Use --force if you want to overwrite.",
+                                avdFolder.getAbsolutePath());
+                    }
+                    return null;
+                }
+            } else {
+                // create the AVD folder.
+                avdFolder.mkdir();
+            }
+
+            // actually write the ini file
+            iniFile = createAvdIniFile(name, avdFolder, target);
+
+            // writes the userdata.img in it.
+            String imagePath = target.getPath(IAndroidTarget.IMAGES);
+            File userdataSrc = new File(imagePath, USERDATA_IMG);
+            
+            if (userdataSrc.exists() == false && target.isPlatform() == false) {
+                imagePath = target.getParent().getPath(IAndroidTarget.IMAGES);
+                userdataSrc = new File(imagePath, USERDATA_IMG);
+            }
+            
+            if (userdataSrc.exists() == false) {
+                log.error(null, "Unable to find a '%1$s' file to copy into the AVD folder.",
+                        USERDATA_IMG);
+                needCleanup = true;
+                return null;
+            }
+            
+            FileInputStream fis = new FileInputStream(userdataSrc);
+            
+            File userdataDest = new File(avdFolder, USERDATA_IMG);
+            FileOutputStream fos = new FileOutputStream(userdataDest);
+            
+            byte[] buffer = new byte[4096];
+            int count;
+            while ((count = fis.read(buffer)) != -1) {
+                fos.write(buffer, 0, count);
+            }
+            
+            fos.close();
+            fis.close();
+            
+            // Config file.
+            HashMap<String, String> values = new HashMap<String, String>();
+
+            // First the image folders of the target itself
+            imagePath = getImageRelativePath(target, log);
+            if (imagePath == null) {
+                needCleanup = true;
+                return null;
+            }
+            
+            values.put(AVD_INI_IMAGES_1, imagePath);
+            
+            // 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, log);
+                if (imagePath == null) {
+                    needCleanup = true;
+                    return null;
+                }
+
+                values.put(AVD_INI_IMAGES_2, imagePath);
+            }
+            
+            
+            // Now the skin.
+            if (skinName == null) {
+                skinName = target.getDefaultSkin();
+            }
+
+            if (NUMERIC_SKIN_SIZE.matcher(skinName).matches()) {
+                // Skin name is an actual screen resolution, no skin.path
+                values.put(AVD_INI_SKIN_NAME, skinName);
+            } else {
+                // get the path of the skin (relative to the SDK)
+                // assume skin name is valid
+                String skinPath = getSkinRelativePath(skinName, target, log);
+                if (skinPath == null) {
+                    needCleanup = true;
+                    return null;
+                }
+
+                values.put(AVD_INI_SKIN_PATH, skinPath);
+                values.put(AVD_INI_SKIN_NAME, skinName);
+            }
+
+            if (sdcard != null) {
+                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) {
+                            log.error(null, "'%1$s' is missing from the SDK tools folder.",
+                                    mkSdCard.getName());
+                            needCleanup = true;
+                            return null;
+                        }
+                        
+                        if (createSdCard(mkSdCard.getAbsolutePath(), sdcard, path, log) == false) {
+                            needCleanup = true;
+                            return null; // mksdcard output has already been displayed, no need to
+                                         // output anything else.
+                        }
+                        
+                        // add a property containing the size of the sdcard for display purpose
+                        // only when the dev does 'android list avd'
+                        values.put(AVD_INI_SDCARD_SIZE, sdcard);
+                    } else {
+                        log.error(null,
+                                "'%1$s' is not recognized as a valid sdcard value.\n" +
+                                "Value should be:\n" +
+                                "1. path to an sdcard.\n" +
+                                "2. size of the sdcard to create: <size>[K|M]",
+                                sdcard);
+                        needCleanup = true;
+                        return null;
+                    }
+                }
+            }
+
+            if (hardwareConfig != null) {
+                values.putAll(hardwareConfig);
+            }
+
+            File configIniFile = new File(avdFolder, CONFIG_INI);
+            createConfigIni(configIniFile, values);
+            
+            if (log != null) {
+                if (target.isPlatform()) {
+                    log.printf("Created AVD '%s' based on %s\n", name, target.getName());
+                } else {
+                    log.printf("Created AVD '%s' based on %s (%s)\n", name, target.getName(),
+                               target.getVendor());
+                }
+            }
+            
+            // create the AvdInfo object, and add it to the list
+            AvdInfo avdInfo = new AvdInfo(name, avdFolder.getAbsolutePath(), target, values);
+            
+            mAvdList.add(avdInfo);
+            
+            return avdInfo;
+        } catch (AndroidLocationException e) {
+            if (log != null) {
+                log.error(e, null);
+            }
+        } catch (IOException e) {
+            if (log != null) {
+                log.error(e, null);
+            }
+        } finally {
+            if (needCleanup) {
+                if (iniFile != null && iniFile.exists()) {
+                    iniFile.delete();
+                }
+                
+                recursiveDelete(avdFolder);
+                avdFolder.delete();
+            }
+        }
+        
+        return null;
+    }
+
+    /**
+     * Returns the path to the target images folder as a relative path to the SDK.
+     */
+    private String getImageRelativePath(IAndroidTarget target, ISdkLog log) {
+        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.
+            log.error(null, "Target location is not inside the SDK.");
+            assert false;
+            return null;
+        }
+
+        imageFullPath = imageFullPath.substring(sdkLocation.length());
+        if (imageFullPath.charAt(0) == File.separatorChar) {
+            imageFullPath = imageFullPath.substring(1);
+        }
+        return imageFullPath;
+    }
+    
+    /**
+     * Returns the path to the skin, as a relative path to the SDK.
+     */
+    private String getSkinRelativePath(String skinName, IAndroidTarget target, ISdkLog log) {
+        // 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) {
+            log.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.
+            log.error(null, "Target location is not inside the SDK.");
+            assert false;
+            return null;
+        }
+
+        path = path.substring(sdkLocation.length());
+        if (path.charAt(0) == File.separatorChar) {
+            path = path.substring(1);
+        }
+        return path;
+    }
+
+    /**
+     * 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());
+        createConfigIni(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.
+     * 
+     * @param avdInfo the information on the AVD to delete
+     */
+    public void deleteAvd(AvdInfo avdInfo, ISdkLog log) {
+        try {
+            File f = avdInfo.getIniFile();
+            if (f.exists()) {
+                log.warning("Deleting file %s", f.getCanonicalPath());
+                if (!f.delete()) {
+                    log.error(null, "Failed to delete %s", f.getCanonicalPath());
+                }
+            }
+            
+            f = new File(avdInfo.getPath());
+            if (f.exists()) {
+                log.warning("Deleting folder %s", f.getCanonicalPath());
+                recursiveDelete(f);
+                if (!f.delete()) {
+                    log.error(null, "Failed to delete %s", f.getCanonicalPath());
+                }
+            }
+
+            removeAvd(avdInfo);
+        } 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 '%s' to '%s'.", avdInfo.getPath(), paramFolderPath);
+                if (!f.renameTo(new File(paramFolderPath))) {
+                    log.error(null, "Failed to move '%s' to '%s'.",
+                            avdInfo.getPath(), paramFolderPath);
+                    return false;
+                }
+    
+                // update avd info
+                AvdInfo info = new AvdInfo(avdInfo.getName(), paramFolderPath, avdInfo.getTarget(),
+                        avdInfo.getProperties());
+                mAvdList.remove(avdInfo);
+                mAvdList.add(info);
+                avdInfo = info;
+
+                // update the ini file
+                createAvdIniFile(avdInfo);
+            }
+
+            if (newName != null) {
+                File oldIniFile = avdInfo.getIniFile();
+                File newIniFile = AvdInfo.getIniFile(newName);
+                
+                log.warning("Moving '%s' to '%s'.", oldIniFile.getPath(), newIniFile.getPath());
+                if (!oldIniFile.renameTo(newIniFile)) {
+                    log.error(null, "Failed to move '%s' to '%s'.", 
+                            oldIniFile.getPath(), newIniFile.getPath());
+                    return false;
+                }
+
+                // update avd info
+                AvdInfo info = new AvdInfo(newName, avdInfo.getPath(), avdInfo.getTarget(),
+                        avdInfo.getProperties());
+                mAvdList.remove(avdInfo);
+                mAvdList.add(info);
+            }
+        } 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();
+        }
+    }
+
+    private void buildAvdList() throws AndroidLocationException {
+        // get the Android prefs location.
+        String avdRoot = AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD;
+
+        final boolean avdListDebug = System.getenv("AVD_LIST_DEBUG") != null;
+        if (avdListDebug) {
+            mSdkLog.printf("[AVD LIST DEBUG] AVD root: '%s'\n", avdRoot);
+        }
+        
+        // ensure folder validity.
+        File folder = new File(avdRoot);
+        if (folder.isFile()) {
+            if (avdListDebug) {
+                mSdkLog.printf("[AVD LIST DEBUG] AVD root is a file.\n");
+            }
+            throw new AndroidLocationException(String.format("%s is not a valid folder.", avdRoot));
+        } else if (folder.exists() == false) {
+            if (avdListDebug) {
+                mSdkLog.printf("[AVD LIST DEBUG] AVD root folder doesn't exist, creating.\n");
+            }
+            // folder is not there, we create it and return
+            folder.mkdirs();
+            return;
+        }
+        
+        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();
+                    if (avdListDebug) {
+                        mSdkLog.printf("[AVD LIST DEBUG] Item '%s': %s\n",
+                                name, isFile ? "accepted file" : "rejected");
+                    }
+                    return isFile;
+                }
+
+                return false;
+            }
+        });
+        
+        for (File avd : avds) {
+            AvdInfo info = parseAvdInfo(avd);
+            if (info != null) {
+                mAvdList.add(info);
+                if (avdListDebug) {
+                    mSdkLog.printf("[AVD LIST DEBUG] Added AVD '%s'\n", info.getPath());
+                }
+            } else if (avdListDebug) {
+                mSdkLog.printf("[AVD LIST DEBUG] Failed to parse AVD '%s'\n", avd.getPath());
+            }
+        }
+    }
+    
+    private AvdInfo parseAvdInfo(File path) {
+        Map<String, String> map = SdkManager.parsePropertyFile(path, mSdkLog);
+        
+        String avdPath = map.get(AVD_INFO_PATH);
+        if (avdPath == null) {
+            return null;
+        }
+        
+        String targetHash = map.get(AVD_INFO_TARGET);
+        if (targetHash == null) {
+            return null;
+        }
+
+        IAndroidTarget target = mSdk.getTargetFromHashString(targetHash);
+        if (target == null) {
+            return null;
+        }
+        
+        // load the avd properties.
+        File configIniFile = new File(avdPath, CONFIG_INI);
+        Map<String, String> properties = SdkManager.parsePropertyFile(configIniFile, mSdkLog);
+
+        Matcher matcher = INI_NAME_PATTERN.matcher(path.getName());
+
+        AvdInfo info = new AvdInfo(
+                matcher.matches() ? matcher.group(1) : path.getName(), // should not happen
+                avdPath,
+                target,
+                properties);
+        
+        return info;
+    }
+
+    private static void createConfigIni(File iniFile, Map<String, String> values)
+            throws IOException {
+        FileWriter writer = new FileWriter(iniFile);
+        
+        for (Entry<String, String> entry : values.entrySet()) {
+            writer.write(String.format("%s=%s\n", entry.getKey(), entry.getValue()));
+        }
+        writer.close();
+
+    }
+    
+    private boolean createSdCard(String toolLocation, String size, String location, ISdkLog log) {
+        try {
+            String[] command = new String[3];
+            command[0] = toolLocation;
+            command[1] = size;
+            command[2] = location;
+            Process process = Runtime.getRuntime().exec(command);
+    
+            ArrayList<String> errorOutput = new ArrayList<String>();
+            ArrayList<String> stdOutput = new ArrayList<String>();
+            int status = grabProcessOutput(process, errorOutput, stdOutput,
+                    true /* waitForReaders */);
+    
+            if (status != 0) {
+                log.error(null, "Failed to create the SD card.");
+                for (String error : errorOutput) {
+                    log.error(null, error);
+                }
+                
+                return false;
+            }
+
+            return true;
+        } catch (InterruptedException e) {
+            log.error(null, "Failed to create the SD card.");
+        } catch (IOException e) {
+            log.error(null, "Failed to create the SD card.");
+        }
+        
+        return false;
+    }
+    
+    /**
+     * Gets the stderr/stdout outputs of a process and returns when the process is done.
+     * Both <b>must</b> be read or the process will block on windows.
+     * @param process The process to get the ouput from
+     * @param errorOutput The array to store the stderr output. cannot be null.
+     * @param stdOutput The array to store the stdout output. cannot be null.
+     * @param waitforReaders if true, this will wait for the reader threads. 
+     * @return the process return code.
+     * @throws InterruptedException
+     */
+    private int grabProcessOutput(final Process process, final ArrayList<String> errorOutput,
+            final ArrayList<String> stdOutput, boolean waitforReaders)
+            throws InterruptedException {
+        assert errorOutput != null;
+        assert stdOutput != null;
+        // read the lines as they come. if null is returned, it's
+        // because the process finished
+        Thread t1 = new Thread("") { //$NON-NLS-1$
+            @Override
+            public void run() {
+                // create a buffer to read the stderr output
+                InputStreamReader is = new InputStreamReader(process.getErrorStream());
+                BufferedReader errReader = new BufferedReader(is);
+
+                try {
+                    while (true) {
+                        String line = errReader.readLine();
+                        if (line != null) {
+                            errorOutput.add(line);
+                        } else {
+                            break;
+                        }
+                    }
+                } catch (IOException e) {
+                    // do nothing.
+                }
+            }
+        };
+
+        Thread t2 = new Thread("") { //$NON-NLS-1$
+            @Override
+            public void run() {
+                InputStreamReader is = new InputStreamReader(process.getInputStream());
+                BufferedReader outReader = new BufferedReader(is);
+
+                try {
+                    while (true) {
+                        String line = outReader.readLine();
+                        if (line != null) {
+                            stdOutput.add(line);
+                        } else {
+                            break;
+                        }
+                    }
+                } catch (IOException e) {
+                    // do nothing.
+                }
+            }
+        };
+
+        t1.start();
+        t2.start();
+
+        // it looks like on windows process#waitFor() can return
+        // before the thread have filled the arrays, so we wait for both threads and the
+        // process itself.
+        if (waitforReaders) {
+            try {
+                t1.join();
+            } catch (InterruptedException e) {
+            }
+            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) {
+        return mAvdList.remove(avdInfo);
+    }
+
+}
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
new file mode 100644
index 0000000..ed5b949
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/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.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/project/ApkConfigurationHelper.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ApkConfigurationHelper.java
new file mode 100644
index 0000000..b89d3bd
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/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.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
new file mode 100644
index 0000000..7489b65
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java
@@ -0,0 +1,742 @@
+/*
+ * 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";
+    
+    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.
+     * 
+     * @param folderPath the folder of the project to create.
+     * @param projectName the name of the project.
+     * @param packageName the package of the project.
+     * @param activityName the activity of the project as it will appear in the manifest.
+     * @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
new file mode 100644
index 0000000..69a16be
--- /dev/null
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectProperties.java
@@ -0,0 +1,263 @@
+/*
+ * 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);
+            }
+            writer.write(String.format("%s=%s\n", entry.getKey(), entry.getValue()));
+        }
+        
+        // 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/sdkuilib/.classpath b/tools/sdkmanager/libs/sdkuilib/.classpath
new file mode 100644
index 0000000..eb5af7e
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/.classpath
@@ -0,0 +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>
diff --git a/tools/sdkmanager/libs/sdkuilib/.project b/tools/sdkmanager/libs/sdkuilib/.project
new file mode 100644
index 0000000..da430c8
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>SdkUiLib</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/sdkmanager/libs/sdkuilib/Android.mk b/tools/sdkmanager/libs/sdkuilib/Android.mk
new file mode 100644
index 0000000..8e0bc23
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/Android.mk
@@ -0,0 +1,4 @@
+# Copyright 2008 The Android Open Source Project
+#
+SDKUILIB_LOCAL_DIR := $(call my-dir)
+include $(SDKUILIB_LOCAL_DIR)/src/Android.mk
diff --git a/tools/sdkmanager/libs/sdkuilib/README b/tools/sdkmanager/libs/sdkuilib/README
new file mode 100644
index 0000000..d66b84a
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/README
@@ -0,0 +1,11 @@
+Using the Eclipse projects for ddmuilib.
+
+ddmuilib requires SWT to compile.
+
+SWT is available in the depot under prebuild/<platform>/swt
+
+Because the build path cannot contain relative path that are not inside the project directory,
+the .classpath file references a user library called ANDROID_SWT.
+
+In order to compile the project, make a user library called ANDROID_SWT containing the jar
+available at prebuild/<platform>/swt.
\ No newline at end of file
diff --git a/tools/sdkmanager/libs/sdkuilib/src/Android.mk b/tools/sdkmanager/libs/sdkuilib/src/Android.mk
new file mode 100644
index 0000000..2d3c774
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/Android.mk
@@ -0,0 +1,21 @@
+# Copyright 2008 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+# no resources yet.
+# LOCAL_JAVA_RESOURCE_DIRS := resources
+
+LOCAL_JAVA_LIBRARIES := \
+	sdklib \
+	swt \
+	org.eclipse.jface_3.2.0.I20060605-1400 \
+	org.eclipse.equinox.common_3.2.0.v20060603 \
+	org.eclipse.core.commands_3.2.0.I20060605-1400
+	
+LOCAL_MODULE := sdkuilib
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ApkConfigEditDialog.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ApkConfigEditDialog.java
new file mode 100644
index 0000000..1460fd7
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ApkConfigEditDialog.java
@@ -0,0 +1,177 @@
+/*
+ * 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;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * Edit dialog to create/edit APK configuration. The dialog displays 2 text fields for the config
+ * name and its filter.
+ */
+class ApkConfigEditDialog extends Dialog implements ModifyListener, VerifyListener {
+
+    private String mName;
+    private String mFilter;
+    private Text mNameField;
+    private Text mFilterField;
+    private Button mOkButton;
+    
+    /**
+     * Creates an edit dialog with optional initial values for the name and filter.
+     * @param name optional value for the name. Can be null.
+     * @param filter optional value for the filter. Can be null.
+     * @param parentShell the parent shell.
+     */
+    protected ApkConfigEditDialog(String name, String filter, Shell parentShell) {
+        super(parentShell);
+        mName = name;
+        mFilter = filter;
+    }
+    
+    /**
+     * Returns the name of the config. This is only valid if the user clicked OK and {@link #open()}
+     * returned {@link Window#OK}
+     */
+    public String getName() {
+        return mName;
+    }
+    
+    /**
+     * Returns the filter for the config. This is only valid if the user clicked OK and
+     * {@link #open()} returned {@link Window#OK}
+     */
+    public String getFilter() {
+        return mFilter;
+    }
+    
+    @Override
+    protected Control createContents(Composite parent) {
+        Control control = super.createContents(parent);
+
+        mOkButton = getButton(IDialogConstants.OK_ID);
+        validateButtons();
+
+        return control;
+    }
+    
+    @Override
+    protected Control createDialogArea(Composite parent) {
+        Composite composite = new Composite(parent, SWT.NONE);
+        GridLayout layout;
+        composite.setLayout(layout = new GridLayout(2, false));
+        layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
+        layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
+        layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
+        layout.horizontalSpacing = convertHorizontalDLUsToPixels(
+                IDialogConstants.HORIZONTAL_SPACING);
+
+        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+        
+        Label l = new Label(composite, SWT.NONE);
+        l.setText("Name");
+        
+        mNameField = new Text(composite, SWT.BORDER);
+        mNameField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        mNameField.addVerifyListener(this);
+        if (mName != null) {
+            mNameField.setText(mName);
+        }
+        mNameField.addModifyListener(this);
+
+        l = new Label(composite, SWT.NONE);
+        l.setText("Filter");
+        
+        mFilterField = new Text(composite, SWT.BORDER);
+        mFilterField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        if (mFilter != null) {
+            mFilterField.setText(mFilter);
+        }
+        mFilterField.addVerifyListener(this);
+        mFilterField.addModifyListener(this);
+        
+        applyDialogFont(composite);
+        return composite;
+    }
+    
+    /**
+     * Validates the OK button based on the content of the 2 text fields.
+     */
+    private void validateButtons() {
+        mOkButton.setEnabled(mNameField.getText().trim().length() > 0 &&
+                mFilterField.getText().trim().length() > 0);
+    }
+
+    @Override
+    protected void okPressed() {
+        mName = mNameField.getText();
+        mFilter = mFilterField.getText().trim();
+        super.okPressed();
+    }
+
+    /**
+     * Callback for text modification in the 2 text fields.
+     */
+    public void modifyText(ModifyEvent e) {
+        validateButtons();
+    }
+
+    /**
+     * Callback to ensure the content of the text field are proper.
+     */
+    public void verifyText(VerifyEvent e) {
+        Text source = ((Text)e.getSource());
+        if (source == mNameField) {
+            // check for a-zA-Z0-9.
+            final String text = e.text;
+            final int len = text.length();
+            for (int i = 0 ; i < len; i++) {
+                char letter = text.charAt(i);
+                if (letter > 255 || Character.isLetterOrDigit(letter) == false) {
+                    e.doit = false;
+                    return;
+                }
+            }
+        } else if (source == mFilterField) {
+            // we can't validate the content as its typed, but we can at least ensure the characters
+            // are valid. Same as mNameFiled + the comma.
+            final String text = e.text;
+            final int len = text.length();
+            for (int i = 0 ; i < len; i++) {
+                char letter = text.charAt(i);
+                if (letter > 255 || (Character.isLetterOrDigit(letter) == false && letter != ',')) {
+                    e.doit = false;
+                    return;
+                }
+            }
+        }
+    }
+}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ApkConfigWidget.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ApkConfigWidget.java
new file mode 100644
index 0000000..6bf1df3
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ApkConfigWidget.java
@@ -0,0 +1,211 @@
+/*
+ * 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;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+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.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The APK Configuration widget is a table that is added to the given parent composite.
+ * <p/>
+ * To use, create it using {@link #ApkConfigWidget(Composite)} then
+ * call {@link #fillTable(Map) to set the initial list of configurations.
+ */
+public class ApkConfigWidget {
+    private final static int INDEX_NAME = 0;
+    private final static int INDEX_FILTER = 1;
+    
+    private Table mApkConfigTable;
+    private Button mEditButton;
+    private Button mDelButton;
+
+    public ApkConfigWidget(final Composite parent) {
+        final Composite apkConfigComp = new Composite(parent, SWT.NONE);
+        apkConfigComp.setLayoutData(new GridData(GridData.FILL_BOTH));
+        apkConfigComp.setLayout(new GridLayout(2, false));
+        
+        mApkConfigTable = new Table(apkConfigComp, SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER);
+        mApkConfigTable.setHeaderVisible(true);
+        mApkConfigTable.setLinesVisible(true);
+
+        GridData data = new GridData();
+        data.grabExcessVerticalSpace = true;
+        data.grabExcessHorizontalSpace = true;
+        data.horizontalAlignment = GridData.FILL;
+        data.verticalAlignment = GridData.FILL;
+        mApkConfigTable.setLayoutData(data);
+
+        // create the table columns
+        final TableColumn column0 = new TableColumn(mApkConfigTable, SWT.NONE);
+        column0.setText("Name");
+        column0.setWidth(100);
+        final TableColumn column1 = new TableColumn(mApkConfigTable, SWT.NONE);
+        column1.setText("Configuration");
+        column1.setWidth(100);
+
+        Composite buttonComp = new Composite(apkConfigComp, SWT.NONE);
+        buttonComp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+        GridLayout gl;
+        buttonComp.setLayout(gl = new GridLayout(1, false));
+        gl.marginHeight = gl.marginWidth = 0;
+
+        Button newButton = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
+        newButton.setText("New...");
+        newButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        mEditButton = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
+        mEditButton.setText("Edit...");
+        mEditButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        mDelButton = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
+        mDelButton.setText("Delete");
+        mDelButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+        
+        newButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                ApkConfigEditDialog dlg = new ApkConfigEditDialog(null /*name*/, null /*filter*/,
+                        apkConfigComp.getShell());
+                if (dlg.open() == Dialog.OK) {
+                    TableItem item = new TableItem(mApkConfigTable, SWT.NONE);
+                    item.setText(INDEX_NAME, dlg.getName());
+                    item.setText(INDEX_FILTER, dlg.getFilter());
+                    
+                    onSelectionChanged();
+                }
+            }
+        });
+        
+        mEditButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // get the current selection (single mode so we don't care about any item beyond
+                // index 0).
+                TableItem[] items = mApkConfigTable.getSelection();
+                if (items.length != 0) {
+                    ApkConfigEditDialog dlg = new ApkConfigEditDialog(
+                            items[0].getText(INDEX_NAME), items[0].getText(INDEX_FILTER),
+                            apkConfigComp.getShell());
+                    if (dlg.open() == Dialog.OK) {
+                        items[0].setText(INDEX_NAME, dlg.getName());
+                        items[0].setText(INDEX_FILTER, dlg.getFilter());
+                    }
+                }
+            }
+        });
+        
+        mDelButton.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                // get the current selection (single mode so we don't care about any item beyond
+                // index 0).
+                int[] indices = mApkConfigTable.getSelectionIndices();
+                if (indices.length != 0) {
+                    TableItem item = mApkConfigTable.getItem(indices[0]);
+                    if (MessageDialog.openQuestion(parent.getShell(),
+                            "Apk Configuration deletion",
+                            String.format(
+                                    "Are you sure you want to delete configuration '%1$s'?",
+                                    item.getText(INDEX_NAME)))) {
+                        // delete the item.
+                        mApkConfigTable.remove(indices[0]);
+                        
+                        onSelectionChanged();
+                    }
+                }
+            }
+        });
+        
+        // Add a listener to resize the column to the full width of the table
+        mApkConfigTable.addControlListener(new ControlAdapter() {
+            @Override
+            public void controlResized(ControlEvent e) {
+                Rectangle r = mApkConfigTable.getClientArea();
+                column0.setWidth(r.width * 30 / 100); // 30%  
+                column1.setWidth(r.width * 70 / 100); // 70%
+            }
+        });
+        
+        // add a selection listener on the table, to enable/disable buttons.
+        mApkConfigTable.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                onSelectionChanged();
+            }
+        });
+    }
+    
+    public void fillTable(Map<String, String> apkConfigMap) {
+        // get the names in a list so that we can sort them.
+        if (apkConfigMap != null) {
+            Set<String> keys = apkConfigMap.keySet();
+            String[] keyArray = keys.toArray(new String[keys.size()]);
+            Arrays.sort(keyArray);
+            
+            for (String key : keyArray) {
+                TableItem item = new TableItem(mApkConfigTable, SWT.NONE);
+                item.setText(INDEX_NAME, key);
+                item.setText(INDEX_FILTER, apkConfigMap.get(key));
+            }
+        }
+        
+        onSelectionChanged();
+    }
+
+    public Map<String, String> getApkConfigs() {
+        // go through all the items from the table and fill a new map
+        HashMap<String, String> map = new HashMap<String, String>();
+        
+        TableItem[] items = mApkConfigTable.getItems();
+        for (TableItem item : items) {
+            map.put(item.getText(INDEX_NAME), item.getText(INDEX_FILTER));
+        }
+
+        return map;
+    }
+    
+    /**
+     * Handles table selection changes.
+     */
+    private void onSelectionChanged() {
+        if (mApkConfigTable.getSelectionCount() > 0) {
+            mEditButton.setEnabled(true);
+            mDelButton.setEnabled(true);
+        } else {
+            mEditButton.setEnabled(false);
+            mDelButton.setEnabled(false);
+        }
+    }
+}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/AvdSelector.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/AvdSelector.java
new file mode 100644
index 0000000..9d0b928
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/AvdSelector.java
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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;
+
+import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.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.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+import java.util.ArrayList;
+
+
+/**
+ * The AVD selector is a table that is added to the given parent composite.
+ * <p/>
+ * To use, create it using {@link #AvdSelector(Composite, AvdInfo[], boolean)} then
+ * call {@link #setSelection(AvdInfo)}, {@link #setSelectionListener(SelectionListener)}
+ * and finally use {@link #getFirstSelected()} or {@link #getAllSelected()} to retrieve the
+ * selection.
+ */
+public final class AvdSelector {
+    
+    private AvdInfo[] mAvds;
+    private final boolean mAllowMultipleSelection;
+    private SelectionListener mSelectionListener;
+    private Table mTable;
+    private Label mDescription;
+
+    /**
+     * 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.
+     * @param allowMultipleSelection True if more than one SDK target can be selected at the same
+     *        time.
+     */
+    public AvdSelector(Composite parent, AvdInfo[] avds, IAndroidTarget filter,
+            boolean allowMultipleSelection) {
+        mAvds = avds;
+
+        // Layout has 1 column
+        Composite group = new Composite(parent, SWT.NONE);
+        group.setLayout(new GridLayout());
+        group.setLayoutData(new GridData(GridData.FILL_BOTH));
+        group.setFont(parent.getFont());
+        
+        mAllowMultipleSelection = allowMultipleSelection;
+        mTable = new Table(group, SWT.CHECK | SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER);
+        mTable.setHeaderVisible(true);
+        mTable.setLinesVisible(false);
+
+        GridData data = new GridData();
+        data.grabExcessVerticalSpace = true;
+        data.grabExcessHorizontalSpace = true;
+        data.horizontalAlignment = GridData.FILL;
+        data.verticalAlignment = GridData.FILL;
+        mTable.setLayoutData(data);
+
+        mDescription = new Label(group, SWT.WRAP);
+        mDescription.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        // create the table columns
+        final TableColumn column0 = new TableColumn(mTable, SWT.NONE);
+        column0.setText("AVD Name");
+        final TableColumn column1 = new TableColumn(mTable, SWT.NONE);
+        column1.setText("Target Name");
+        final TableColumn column2 = new TableColumn(mTable, SWT.NONE);
+        column2.setText("API Level");
+        final TableColumn column3 = new TableColumn(mTable, SWT.NONE);
+        column3.setText("SDK");
+
+        adjustColumnsWidth(mTable, column0, column1, column2, column3);
+        setupSelectionListener(mTable);
+        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.
+     * @param allowMultipleSelection True if more than one SDK target can be selected at the same
+     *        time.
+     */
+    public AvdSelector(Composite parent, AvdInfo[] avds, boolean allowMultipleSelection) {
+        this(parent, avds, null /* filter */, allowMultipleSelection);
+    }
+
+    
+    public void setTableHeightHint(int heightHint) {
+        GridData data = new GridData();
+        data.heightHint = heightHint;
+        data.grabExcessVerticalSpace = true;
+        data.grabExcessHorizontalSpace = true;
+        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.
+     * 
+     * @param avds The list of AVDs. This is <em>not</em> copied, the caller must not modify.
+     * @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) {
+        mAvds = avds;
+        fillTable(mTable, filter);
+    }
+
+    /**
+     * Returns the list of known AVDs.
+     * <p/>
+     * This is not a copy. Callers must <em>not</em> modify this array.
+     */
+    public AvdInfo[] getAvds() {
+        return mAvds;
+    }
+
+    /**
+     * Sets a selection listener. Set it to null to remove it.
+     * The listener will be called <em>after</em> this table processed its selection
+     * events so that the caller can see the updated state.
+     * <p/>
+     * The event's item contains a {@link TableItem}.
+     * The {@link TableItem#getData()} contains an {@link IAndroidTarget}.
+     * <p/>
+     * It is recommended that the caller uses the {@link #getFirstSelected()} and
+     * {@link #getAllSelected()} methods instead.
+     * 
+     * @param selectionListener The new listener or null to remove it.
+     */
+    public void setSelectionListener(SelectionListener selectionListener) {
+        mSelectionListener = selectionListener;
+    }
+    
+    /**
+     * Sets the current target selection.
+     * <p/>
+     * If the selection is actually changed, this will invoke the selection listener
+     * (if any) with a null event.
+     * 
+     * @param target the target to be selection
+     * @return true if the target could be selected, false otherwise.
+     */
+    public boolean setSelection(AvdInfo target) {
+        boolean found = false;
+        boolean modified = false;
+        for (TableItem i : mTable.getItems()) {
+            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);
+        }
+        
+        return found;
+    }
+
+    /**
+     * Returns all selected items.
+     * This is useful when the table is in multiple-selection mode.
+     * 
+     * @see #getFirstSelected()
+     * @return An array of selected items. The list can be empty but not null.
+     */
+    public AvdInfo[] getAllSelected() {
+        ArrayList<IAndroidTarget> list = new ArrayList<IAndroidTarget>();
+        for (TableItem i : mTable.getItems()) {
+            if (i.getChecked()) {
+                list.add((IAndroidTarget) i.getData());
+            }
+        }
+        return list.toArray(new AvdInfo[list.size()]);
+    }
+
+    /**
+     * Returns the first selected item.
+     * This is useful when the table is in single-selection mode.
+     * 
+     * @see #getAllSelected()
+     * @return The first selected item or null.
+     */
+    public AvdInfo getFirstSelected() {
+        for (TableItem i : mTable.getItems()) {
+            if (i.getChecked()) {
+                return (AvdInfo) i.getData();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Enables the receiver if the argument is true, and disables it otherwise.
+     * A disabled control is typically not selectable from the user interface
+     * and draws with an inactive or "grayed" look.
+     * 
+     * @param enabled the new enabled state.
+     */
+    public void setEnabled(boolean enabled) {
+        mTable.setEnabled(enabled);
+        mDescription.setEnabled(enabled);
+    }
+
+    /**
+     * Adds a listener to adjust the columns width when the parent is resized.
+     * <p/>
+     * If we need something more fancy, we might want to use this:
+     * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet77.java?view=co
+     */
+    private void adjustColumnsWidth(final Table table,
+            final TableColumn column0,
+            final TableColumn column1,
+            final TableColumn column2,
+            final TableColumn column3) {
+        // Add a listener to resize the column to the full width of the table
+        table.addControlListener(new ControlAdapter() {
+            @Override
+            public void controlResized(ControlEvent e) {
+                Rectangle r = table.getClientArea();
+                column0.setWidth(r.width * 30 / 100); // 30%  
+                column1.setWidth(r.width * 45 / 100); // 45%
+                column2.setWidth(r.width * 15 / 100); // 15%
+                column3.setWidth(r.width * 10 / 100); // 10%
+            }
+        });
+    }
+
+
+    /**
+     * Creates a selection listener that will check or uncheck the whole line when
+     * double-clicked (aka "the default selection").
+     */
+    private void setupSelectionListener(final Table table) {
+        // Add a selection listener that will check/uncheck items when they are double-clicked
+        table.addSelectionListener(new SelectionListener() {
+            /** Default selection means double-click on "most" platforms */
+            public void widgetDefaultSelected(SelectionEvent e) {
+                if (e.item instanceof TableItem) {
+                    TableItem i = (TableItem) e.item;
+                    i.setChecked(!i.getChecked());
+                    enforceSingleSelection(i);
+                    updateDescription(i);
+                }
+
+                if (mSelectionListener != null) {
+                    mSelectionListener.widgetDefaultSelected(e);
+                }
+            }
+            
+            public void widgetSelected(SelectionEvent e) {
+                if (e.item instanceof TableItem) {
+                    TableItem i = (TableItem) e.item;
+                    enforceSingleSelection(i);
+                    updateDescription(i);
+                }
+
+                if (mSelectionListener != null) {
+                    mSelectionListener.widgetSelected(e);
+                }
+            }
+
+            /**
+             * If we're not in multiple selection mode, uncheck all other
+             * items when this one is selected.
+             */
+            private void enforceSingleSelection(TableItem item) {
+                if (!mAllowMultipleSelection && item.getChecked()) {
+                    Table parentTable = item.getParent();
+                    for (TableItem i2 : parentTable.getItems()) {
+                        if (i2 != item && i2.getChecked()) {
+                            i2.setChecked(false);
+                        }
+                    }
+                }
+            }
+        });
+    }
+
+    /**
+     * Fills the table with all AVD.
+     * The table columns are:
+     * <ul>
+     * <li>column 0: sdk name
+     * <li>column 1: sdk vendor
+     * <li>column 2: sdk api name
+     * <li>column 3: sdk version
+     * </ul>
+     */
+    private void fillTable(final Table table, IAndroidTarget filter) {
+        table.removeAll();
+        if (mAvds != null && mAvds.length > 0) {
+            table.setEnabled(true);
+            for (AvdInfo avd : mAvds) {
+                if (filter == null || filter.isCompatibleBaseFor(avd.getTarget())) {
+                    TableItem item = new TableItem(table, SWT.NONE);
+                    item.setData(avd);
+                    item.setText(0, avd.getName());
+                    IAndroidTarget target = avd.getTarget();
+                    item.setText(1, target.getFullName());
+                    item.setText(2, target.getApiVersionName());
+                    item.setText(3, Integer.toString(target.getApiVersionNumber()));
+                }
+            }
+        }
+        
+        if (table.getItemCount() == 0) {
+            table.setEnabled(false);
+            TableItem item = new TableItem(table, SWT.NONE);
+            item.setData(null);
+            item.setText(0, "--");
+            item.setText(1, "No AVD available");
+            item.setText(2, "--");
+            item.setText(3, "--");
+        }
+    }
+
+    /**
+     * Sets up a tooltip that displays the current item description.
+     * <p/>
+     * Displaying a tooltip over the table looks kind of odd here. Instead we actually
+     * display the description in a label under the table.
+     */
+    private void setupTooltip(final Table table) {
+        /*
+         * Reference: 
+         * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet125.java?view=markup
+         */
+        
+        final Listener listener = new Listener() {
+            public void handleEvent(Event event) {
+                
+                switch(event.type) {
+                case SWT.KeyDown:
+                case SWT.MouseExit:
+                case SWT.MouseDown:
+                    return;
+                    
+                case SWT.MouseHover:
+                    updateDescription(table.getItem(new Point(event.x, event.y)));
+                    break;
+                    
+                case SWT.Selection:
+                    if (event.item instanceof TableItem) {
+                        updateDescription((TableItem) event.item);
+                    }
+                    break;
+                    
+                default:
+                    return;
+                }
+
+            }
+        };
+        
+        table.addListener(SWT.Dispose, listener);
+        table.addListener(SWT.KeyDown, listener);
+        table.addListener(SWT.MouseMove, listener);
+        table.addListener(SWT.MouseHover, listener);
+    }
+
+    /**
+     * Updates the description label with the path of the item's AVD, if any.
+     */
+    private void updateDescription(TableItem item) {
+        if (item != null) {
+            Object data = item.getData();
+            if (data instanceof AvdInfo) {
+                String newTooltip = ((AvdInfo) data).getPath();
+                mDescription.setText(newTooltip == null ? "" : newTooltip);  //$NON-NLS-1$
+            }
+        }
+    }
+}
diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java
new file mode 100644
index 0000000..5f9e9c2
--- /dev/null
+++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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;
+
+import com.android.sdklib.IAndroidTarget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+import java.util.ArrayList;
+
+
+/**
+ * The SDK target selector is a table that is added to the given parent composite.
+ * <p/>
+ * To use, create it using {@link #SdkTargetSelector(Composite, IAndroidTarget[], boolean)} then
+ * call {@link #setSelection(IAndroidTarget)}, {@link #setSelectionListener(SelectionListener)}
+ * and finally use {@link #getFirstSelected()} or {@link #getAllSelected()} to retrieve the
+ * selection.
+ */
+public class SdkTargetSelector {
+    
+    private IAndroidTarget[] mTargets;
+    private final boolean mAllowSelection;
+    private final boolean mAllowMultipleSelection;
+    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.
+     * @param allowMultipleSelection True if more than one SDK target can be selected at the same
+     *        time.
+     */
+    public SdkTargetSelector(Composite parent, IAndroidTarget[] targets,
+            boolean allowMultipleSelection) {
+        this(parent, targets, true /*allowSelection*/, allowMultipleSelection);
+    }
+
+    /**
+     * Creates a new SDK Target Selector.
+     * 
+     * @param parent The parent composite where the selector will be added.
+     * @param targets The list of targets. This is <em>not</em> copied, the caller must not modify.
+     *                Targets can be null or an empty array, in which case the table is disabled.
+     * @param allowSelection True if selection is enabled.
+     * @param allowMultipleSelection True if more than one SDK target can be selected at the same
+     *        time. Used only if allowSelection is true.
+     */
+    public SdkTargetSelector(Composite parent, IAndroidTarget[] targets,
+            boolean allowSelection,
+            boolean allowMultipleSelection) {
+        // Layout has 1 column
+        mInnerGroup = new Composite(parent, SWT.NONE);
+        mInnerGroup.setLayout(new GridLayout());
+        mInnerGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
+        mInnerGroup.setFont(parent.getFont());
+        
+        mAllowSelection = allowSelection;
+        mAllowMultipleSelection = allowMultipleSelection;
+        int style = SWT.BORDER;
+        if (allowSelection) {
+            style |= SWT.CHECK | SWT.FULL_SELECTION;
+        }
+        if (!mAllowMultipleSelection) {
+            style |= SWT.SINGLE;
+        }
+        mTable = new Table(mInnerGroup, style);
+        mTable.setHeaderVisible(true);
+        mTable.setLinesVisible(false);
+
+        GridData data = new GridData();
+        data.grabExcessVerticalSpace = true;
+        data.grabExcessHorizontalSpace = true;
+        data.horizontalAlignment = GridData.FILL;
+        data.verticalAlignment = GridData.FILL;
+        mTable.setLayoutData(data);
+
+        mDescription = new Label(mInnerGroup, SWT.WRAP);
+        mDescription.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        // create the table columns
+        final TableColumn column0 = new TableColumn(mTable, SWT.NONE);
+        column0.setText("SDK Target");
+        final TableColumn column1 = new TableColumn(mTable, SWT.NONE);
+        column1.setText("Vendor");
+        final TableColumn column2 = new TableColumn(mTable, SWT.NONE);
+        column2.setText("Version");
+        final TableColumn column3 = new TableColumn(mTable, SWT.NONE);
+        column3.setText("API Level");
+
+        adjustColumnsWidth(mTable, column0, column1, column2, column3);
+        setupSelectionListener(mTable);
+        setTargets(targets);
+        setupTooltip(mTable);
+    }
+    
+    /**
+     * Returns the layout data of the inner composite widget that contains the target selector.
+     * By default the layout data is set to a {@link GridData} with a {@link GridData#FILL_BOTH}
+     * mode.
+     * <p/>
+     * This can be useful if you want to change the {@link GridData#horizontalSpan} for example.
+     */
+    public Object getLayoutData() {
+        return mInnerGroup.getLayoutData();
+    }
+
+    /**
+     * Returns the list of known targets.
+     * <p/>
+     * This is not a copy. Callers must <em>not</em> modify this array.
+     */
+    public IAndroidTarget[] getTargets() {
+        return mTargets;
+    }
+
+    /**
+     * Changes the targets of the SDK Target Selector.
+     * 
+     * @param targets The list of targets. This is <em>not</em> copied, the caller must not modify.
+     */
+    public void setTargets(IAndroidTarget[] targets) {
+        mTargets = targets;
+        fillTable(mTable);
+    }
+
+    /**
+     * Sets a selection listener. Set it to null to remove it.
+     * The listener will be called <em>after</em> this table processed its selection
+     * events so that the caller can see the updated state.
+     * <p/>
+     * The event's item contains a {@link TableItem}.
+     * The {@link TableItem#getData()} contains an {@link IAndroidTarget}.
+     * <p/>
+     * It is recommended that the caller uses the {@link #getFirstSelected()} and
+     * {@link #getAllSelected()} methods instead.
+     * 
+     * @param selectionListener The new listener or null to remove it.
+     */
+    public void setSelectionListener(SelectionListener selectionListener) {
+        mSelectionListener = selectionListener;
+    }
+    
+    /**
+     * Sets the current target selection.
+     * <p/>
+     * If the selection is actually changed, this will invoke the selection listener
+     * (if any) with a null event.
+     * 
+     * @param target the target to be selection
+     * @return true if the target could be selected, false otherwise.
+     */
+    public boolean setSelection(IAndroidTarget target) {
+        if (!mAllowSelection) {
+            return false;
+        }
+
+        boolean found = false;
+        boolean modified = false;
+        for (TableItem i : mTable.getItems()) {
+            if ((IAndroidTarget) i.getData() == target) {
+                found = true;
+                if (!i.getChecked()) {
+                    modified = true;
+                    i.setChecked(true);
+                }
+            } else if (i.getChecked()) {
+                modified = true;
+                i.setChecked(false);
+            }
+        }
+        
+        if (modified && mSelectionListener != null) {
+            mSelectionListener.widgetSelected(null);
+        }
+        
+        return found;
+    }
+
+    /**
+     * Returns all selected items.
+     * This is useful when the table is in multiple-selection mode.
+     * 
+     * @see #getFirstSelected()
+     * @return An array of selected items. The list can be empty but not null.
+     */
+    public IAndroidTarget[] getAllSelected() {
+        ArrayList<IAndroidTarget> list = new ArrayList<IAndroidTarget>();
+        for (TableItem i : mTable.getItems()) {
+            if (i.getChecked()) {
+                list.add((IAndroidTarget) i.getData());
+            }
+        }
+        return list.toArray(new IAndroidTarget[list.size()]);
+    }
+
+    /**
+     * Returns the first selected item.
+     * This is useful when the table is in single-selection mode.
+     * 
+     * @see #getAllSelected()
+     * @return The first selected item or null.
+     */
+    public IAndroidTarget getFirstSelected() {
+        for (TableItem i : mTable.getItems()) {
+            if (i.getChecked()) {
+                return (IAndroidTarget) i.getData();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Adds a listener to adjust the columns width when the parent is resized.
+     * <p/>
+     * If we need something more fancy, we might want to use this:
+     * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet77.java?view=co
+     */
+    private void adjustColumnsWidth(final Table table,
+            final TableColumn column0,
+            final TableColumn column1,
+            final TableColumn column2,
+            final TableColumn column3) {
+        // Add a listener to resize the column to the full width of the table
+        table.addControlListener(new ControlAdapter() {
+            @Override
+            public void controlResized(ControlEvent e) {
+                Rectangle r = table.getClientArea();
+                column0.setWidth(r.width * 30 / 100); // 30%  
+                column1.setWidth(r.width * 45 / 100); // 45%
+                column2.setWidth(r.width * 15 / 100); // 15%
+                column3.setWidth(r.width * 10 / 100); // 10%
+            }
+        });
+    }
+
+
+    /**
+     * Creates a selection listener that will check or uncheck the whole line when
+     * double-clicked (aka "the default selection").
+     */
+    private void setupSelectionListener(final Table table) {
+        if (!mAllowSelection) {
+            return;
+        }
+
+        // Add a selection listener that will check/uncheck items when they are double-clicked
+        table.addSelectionListener(new SelectionListener() {
+            /** Default selection means double-click on "most" platforms */
+            public void widgetDefaultSelected(SelectionEvent e) {
+                if (e.item instanceof TableItem) {
+                    TableItem i = (TableItem) e.item;
+                    i.setChecked(!i.getChecked());
+                    enforceSingleSelection(i);
+                    updateDescription(i);
+                }
+
+                if (mSelectionListener != null) {
+                    mSelectionListener.widgetDefaultSelected(e);
+                }
+            }
+            
+            public void widgetSelected(SelectionEvent e) {
+                if (e.item instanceof TableItem) {
+                    TableItem i = (TableItem) e.item;
+                    enforceSingleSelection(i);
+                    updateDescription(i);
+                }
+
+                if (mSelectionListener != null) {
+                    mSelectionListener.widgetSelected(e);
+                }
+            }
+
+            /**
+             * If we're not in multiple selection mode, uncheck all other
+             * items when this one is selected.
+             */
+            private void enforceSingleSelection(TableItem item) {
+                if (!mAllowMultipleSelection && item.getChecked()) {
+                    Table parentTable = item.getParent();
+                    for (TableItem i2 : parentTable.getItems()) {
+                        if (i2 != item && i2.getChecked()) {
+                            i2.setChecked(false);
+                        }
+                    }
+                }
+            }
+        });
+    }
+
+
+    /**
+     * Fills the table with all SDK targets.
+     * The table columns are:
+     * <ul>
+     * <li>column 0: sdk name
+     * <li>column 1: sdk vendor
+     * <li>column 2: sdk api name
+     * <li>column 3: sdk version
+     * </ul>
+     */
+    private void fillTable(final Table table) {
+        
+        table.removeAll();
+        
+        if (mTargets != null && mTargets.length > 0) {
+            table.setEnabled(true);
+            for (IAndroidTarget target : mTargets) {
+                TableItem item = new TableItem(table, SWT.NONE);
+                item.setData(target);
+                item.setText(0, target.getName());
+                item.setText(1, target.getVendor());
+                item.setText(2, target.getApiVersionName());
+                item.setText(3, Integer.toString(target.getApiVersionNumber()));
+            }
+        } else {
+            table.setEnabled(false);
+            TableItem item = new TableItem(table, SWT.NONE);
+            item.setData(null);
+            item.setText(0, "--");
+            item.setText(1, "No target available");
+            item.setText(2, "--");
+            item.setText(3, "--");
+        }
+    }
+
+    /**
+     * Sets up a tooltip that displays the current item description.
+     * <p/>
+     * Displaying a tooltip over the table looks kind of odd here. Instead we actually
+     * display the description in a label under the table.
+     */
+    private void setupTooltip(final Table table) {
+        /*
+         * Reference: 
+         * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet125.java?view=markup
+         */
+        
+        final Listener listener = new Listener() {
+            public void handleEvent(Event event) {
+                
+                switch(event.type) {
+                case SWT.KeyDown:
+                case SWT.MouseExit:
+                case SWT.MouseDown:
+                    return;
+                    
+                case SWT.MouseHover:
+                    updateDescription(table.getItem(new Point(event.x, event.y)));
+                    break;
+                    
+                case SWT.Selection:
+                    if (event.item instanceof TableItem) {
+                        updateDescription((TableItem) event.item);
+                    }
+                    break;
+                    
+                default:
+                    return;
+                }
+
+            }
+        };
+        
+        table.addListener(SWT.Dispose, listener);
+        table.addListener(SWT.KeyDown, listener);
+        table.addListener(SWT.MouseMove, listener);
+        table.addListener(SWT.MouseHover, listener);
+    }
+
+    /**
+     * Updates the description label with the description of the item's android target, if any.
+     */
+    private void updateDescription(TableItem item) {
+        if (item != null) {
+            Object data = item.getData();
+            if (data instanceof IAndroidTarget) {
+                String newTooltip = ((IAndroidTarget) data).getDescription();
+                mDescription.setText(newTooltip == null ? "" : newTooltip);  //$NON-NLS-1$
+            }
+        }
+    }
+}
diff --git a/tools/sdkstats/.classpath b/tools/sdkstats/.classpath
new file mode 100644
index 0000000..73b1af5
--- /dev/null
+++ b/tools/sdkstats/.classpath
@@ -0,0 +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="/AndroidPrefs"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/sdkstats/.project b/tools/sdkstats/.project
new file mode 100644
index 0000000..4dbfa87
--- /dev/null
+++ b/tools/sdkstats/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>SdkStatsService</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/sdkstats/Android.mk b/tools/sdkstats/Android.mk
new file mode 100644
index 0000000..f4cabdc
--- /dev/null
+++ b/tools/sdkstats/Android.mk
@@ -0,0 +1,4 @@
+# Copyright 2007 The Android Open Source Project
+#
+SDKSTATS_LOCAL_DIR := $(call my-dir)
+include $(SDKSTATS_LOCAL_DIR)/src/Android.mk
diff --git a/tools/sdkstats/README b/tools/sdkstats/README
new file mode 100644
index 0000000..8ed0880
--- /dev/null
+++ b/tools/sdkstats/README
@@ -0,0 +1,11 @@
+How to use the Eclipse projects for SdkStats.
+
+SdkStats requires SWT to compile.
+
+SWT is available in the depot under //device/prebuild/<platform>/swt
+
+Because the build path cannot contain relative path that are not inside the project directory,
+the .classpath file references a user library called ANDROID_SWT.
+
+In order to compile the project, make a user library called ANDROID_SWT containing the jar
+available at //device/prebuild/<platform>/swt.
diff --git a/tools/sdkstats/src/Android.mk b/tools/sdkstats/src/Android.mk
new file mode 100644
index 0000000..bff43f3
--- /dev/null
+++ b/tools/sdkstats/src/Android.mk
@@ -0,0 +1,15 @@
+# Copyright 2007 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_JAVA_LIBRARIES := \
+	androidprefs \
+	swt \
+	org.eclipse.jface_3.2.0.I20060605-1400 \
+	org.eclipse.equinox.common_3.2.0.v20060603 \
+	org.eclipse.core.commands_3.2.0.I20060605-1400
+LOCAL_MODULE := sdkstats
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/sdkstats/src/com/android/sdkstats/SdkStatsService.java b/tools/sdkstats/src/com/android/sdkstats/SdkStatsService.java
new file mode 100644
index 0000000..0b3d41b
--- /dev/null
+++ b/tools/sdkstats/src/com/android/sdkstats/SdkStatsService.java
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sdkstats;
+
+import com.android.prefs.AndroidLocation;
+import com.android.prefs.AndroidLocation.AndroidLocationException;
+
+import org.eclipse.jface.preference.PreferenceStore;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.program.Program;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.Shell;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.Random;
+
+/** Utility class to send "ping" usage reports to the server. */
+public class SdkStatsService {
+
+    /** Minimum interval between ping, in milliseconds. */
+    private static final long PING_INTERVAL_MSEC = 86400 * 1000;  // 1 day
+
+    /* Text strings displayed in the opt-out dialog. */
+    private static final String WINDOW_TITLE_TEXT =
+        "Android SDK";
+
+    private static final String HEADER_TEXT =
+        "Thanks for using the Android SDK!";
+
+    private static final String NOTICE_TEXT =
+        "We know you just want to get started but please read this first.";
+
+    /** Used in the preference pane (PrefsDialog) as well. */
+    public static final String BODY_TEXT =
+        "By choosing to send certain usage statistics to Google, you can " +
+        "help us improve the Android SDK.  These usage statistics let us " +
+        "measure things like active usage of the SDK and let us know things " +
+        "like which versions of the SDK are in use and which tools are the " +
+        "most popular with developers.  This limited data is not associated " +
+        "with personal information about you, is examined on an aggregate " +
+        "basis, and is maintained in accordance with the " +
+        "<a href=\"http://www.google.com/intl/en/privacy.html\">Google " +
+        "Privacy Policy</a>.";
+
+    /** Used in the preference pane (PrefsDialog) as well. */
+    public static final String CHECKBOX_TEXT =
+        "Send usage statistics to Google.";
+
+    private static final String FOOTER_TEXT =
+        "If you later decide to change this setting, you can do so in the " +
+        "\"ddms\" tool under \"File\" > \"Preferences\" > \"Usage Stats\".";
+
+    private static final String BUTTON_TEXT =
+        "   Proceed   ";
+
+    /** List of Linux browser commands to try, in order (see openUrl). */
+    private static final String[] LINUX_BROWSERS = new String[] {
+        "firefox -remote openurl(%URL%,new-window)",  // $NON-NLS-1$ running FF
+        "mozilla -remote openurl(%URL%,new-window)",  // $NON-NLS-1$ running Moz
+        "firefox %URL%",                              // $NON-NLS-1$ new FF
+        "mozilla %URL%",                              // $NON-NLS-1$ new Moz
+        "kfmclient openURL %URL%",                    // $NON-NLS-1$ Konqueror
+        "opera -newwindow %URL%",                     // $NON-NLS-1$ Opera
+    };
+    
+    public final static String PING_OPT_IN = "pingOptIn"; //$NON-NLS-1$
+    public final static String PING_TIME = "pingTime"; //$NON-NLS-1$
+    public final static String PING_ID = "pingId"; //$NON-NLS-1$
+
+
+    private static PreferenceStore sPrefStore;
+    
+    /**
+     * Send a "ping" to the Google toolbar server, if enough time has
+     * elapsed since the last ping, and if the user has not opted out.
+     * If this is the first time, notify the user and offer an opt-out.
+     * Note: UI operations (if any) are synchronous, but the actual ping
+     * (if any) is sent in a <i>non-daemon</i> background thread.
+     *
+     * @param app name to report in the ping
+     * @param version to report in the ping
+     */
+    public static void ping(final String app, final String version) {
+        // Validate the application and version input.
+        final String normalVersion = normalizeVersion(app, version);
+
+        // Unique, randomly assigned ID for this installation.
+        PreferenceStore prefs = getPreferenceStore();
+        if (prefs != null) {
+            if (!prefs.contains(PING_ID)) {
+                // First time: make up a new ID.  TODO: Use something more random?
+                prefs.setValue(PING_ID, new Random().nextLong());
+    
+                // Also give them a chance to opt out.
+                prefs.setValue(PING_OPT_IN, getUserPermission());
+                try {
+                    prefs.save();
+                }
+                catch (IOException ioe) {
+                }
+            }
+    
+            // If the user has not opted in, do nothing and quietly return.
+            if (!prefs.getBoolean(PING_OPT_IN)) {
+                // user opted out.
+                return;
+            }
+    
+            // If the last ping *for this app* was too recent, do nothing.
+            String timePref = PING_TIME + "." + app;  // $NON-NLS-1$
+            long now = System.currentTimeMillis();
+            long then = prefs.getLong(timePref);
+            if (now - then < PING_INTERVAL_MSEC) {
+                // too soon after a ping.
+                return;
+            }
+    
+            // Record the time of the attempt, whether or not it succeeds.
+            prefs.setValue(timePref, now);
+            try {
+                prefs.save();
+            }
+            catch (IOException ioe) {
+            }
+    
+            // Send the ping itself in the background (don't block if the
+            // network is down or slow or confused).
+            final long id = prefs.getLong(PING_ID);
+            new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        actuallySendPing(app, normalVersion, id);
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }.start();
+        }
+    }
+    
+    /**
+     * Returns the DDMS {@link PreferenceStore}.
+     */
+    public static synchronized PreferenceStore getPreferenceStore() {
+        if (sPrefStore == null) {
+            // get the location of the preferences
+            String homeDir = null;
+            try {
+                homeDir = AndroidLocation.getFolder();
+            } catch (AndroidLocationException e1) {
+                // pass, we'll do a dummy store since homeDir is null
+            }
+
+            if (homeDir != null) {
+                String rcFileName = homeDir + "ddms.cfg"; //$NON-NLS-1$
+                
+                // also look for an old pref file in the previous location
+                String oldPrefPath = System.getProperty("user.home") //$NON-NLS-1$
+                    + File.separator + ".ddmsrc"; //$NON-NLS-1$
+                File oldPrefFile = new File(oldPrefPath);
+                if (oldPrefFile.isFile()) {
+                    try {
+                        PreferenceStore oldStore = new PreferenceStore(oldPrefPath);
+                        oldStore.load();
+                        
+                        oldStore.save(new FileOutputStream(rcFileName), "");
+                        oldPrefFile.delete();
+                        
+                        PreferenceStore newStore = new PreferenceStore(rcFileName);
+                        newStore.load();
+                        sPrefStore = newStore;
+                    } catch (IOException e) {
+                        // create a new empty store.
+                        sPrefStore = new PreferenceStore(rcFileName);
+                    }
+                } else {
+                    sPrefStore = new PreferenceStore(rcFileName);
+
+                    try {
+                        sPrefStore.load();
+                    } catch (IOException e) {
+                        System.err.println("Error Loading Preferences");
+                    }
+                }
+            } else {
+                sPrefStore = new PreferenceStore();
+            }
+        }
+        
+        return sPrefStore;
+    }
+    
+    /**
+     * Unconditionally send a "ping" request to the Google toolbar server.
+     *
+     * @param app name to report in the ping
+     * @param version to report in the ping (dotted numbers, no more than four)
+     * @param id of the local installation
+     * @throws IOException if the ping failed
+     */
+    @SuppressWarnings("deprecation")
+    private static void actuallySendPing(String app, String version, long id)
+        throws IOException {
+        // Detect and report the host OS.
+        String os = System.getProperty("os.name");          // $NON-NLS-1$
+        if (os.startsWith("Mac OS")) {                      // $NON-NLS-1$
+            os = "mac";                                     // $NON-NLS-1$
+        } else if (os.startsWith("Windows")) {              // $NON-NLS-1$
+            os = "win";                                     // $NON-NLS-1$
+        } else if (os.startsWith("Linux")) {                // $NON-NLS-1$
+            os = "linux";                                   // $NON-NLS-1$
+        } else {
+            // Unknown -- surprising -- send it verbatim so we can see it.
+            os = URLEncoder.encode(os);
+        }
+
+        // Include the application's name as part of the as= value.
+        // Share the user ID for all apps, to allow unified activity reports.
+
+        URL url = new URL(
+            "http",                                         // $NON-NLS-1$
+            "tools.google.com",                             // $NON-NLS-1$
+            "/service/update?as=androidsdk_" + app +        // $NON-NLS-1$
+                "&id=" + Long.toHexString(id) +             // $NON-NLS-1$
+                "&version=" + version +                     // $NON-NLS-1$
+                "&os=" + os);                               // $NON-NLS-1$
+
+        // Discard the actual response, but make sure it reads OK
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+
+        // Believe it or not, a 404 response indicates success:
+        // the ping was logged, but no update is configured.
+        if (conn.getResponseCode() != HttpURLConnection.HTTP_OK &&
+            conn.getResponseCode() != HttpURLConnection.HTTP_NOT_FOUND) {
+            throw new IOException(
+                conn.getResponseMessage() + ": " + url);    // $NON-NLS-1$
+        }
+    }
+
+    /**
+     * 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);
+
+        // 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();
+            }
+        });
+
+        // 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];
+    }
+
+    /**
+     * Open a URL in an external browser.
+     * @param url to open - MUST be sanitized and properly formed!
+     */
+    public static void openUrl(final String url) {
+        // TODO: consider using something like BrowserLauncher2
+        // (http://browserlaunch2.sourceforge.net/) instead of these hacks.
+
+        // SWT's Program.launch() should work on Mac, Windows, and GNOME
+        // (because the OS shell knows how to launch a default browser).
+        if (!Program.launch(url)) {
+            // Must be Linux non-GNOME (or something else broke).
+            // Try a few Linux browser commands in the background.
+            new Thread() {
+                @Override
+                public void run() {
+                    for (String cmd : LINUX_BROWSERS) {
+                        cmd = cmd.replaceAll("%URL%", url);  // $NON-NLS-1$
+                        try {
+                            Process proc = Runtime.getRuntime().exec(cmd);
+                            if (proc.waitFor() == 0) break;  // Success!
+                        } catch (InterruptedException e) {
+                            // Should never happen!
+                            throw new RuntimeException(e);
+                        } catch (IOException e) {
+                            // Swallow the exception and try the next browser.
+                        }
+                    }
+
+                    // TODO: Pop up some sort of error here?
+                    // (We're in a new thread; can't use the existing Display.)
+                }
+            }.start();
+        }
+    }
+
+    /**
+     * Validate the supplied application version, and normalize the version.
+     * @param app to report
+     * @param version supplied by caller
+     * @return normalized dotted quad version
+     */
+    private static String normalizeVersion(String app, String version) {
+        // Application name must contain only word characters (no punctuaation)
+        if (!app.matches("\\w+")) {
+            throw new IllegalArgumentException("Bad app name: " + app);
+        }
+
+        // Version must be between 1 and 4 dotted numbers
+        String[] numbers = version.split("\\.");
+        if (numbers.length > 4) {
+            throw new IllegalArgumentException("Bad version: " + version);
+        }
+        for (String part: numbers) {
+            if (!part.matches("\\d+")) {
+                throw new IllegalArgumentException("Bad version: " + version);
+            }
+        }
+
+        // Always output 4 numbers, even if fewer were supplied (pad with .0)
+        StringBuffer normal = new StringBuffer(numbers[0]);
+        for (int i = 1; i < 4; i++) {
+            normal.append(".").append(i < numbers.length ? numbers[i] : "0");
+        }
+        return normal.toString();
+    }
+}
diff --git a/tools/traceview/.classpath b/tools/traceview/.classpath
new file mode 100644
index 0000000..e71cb61
--- /dev/null
+++ b/tools/traceview/.classpath
@@ -0,0 +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="/SdkStatsService"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/tools/traceview/.project b/tools/traceview/.project
new file mode 100644
index 0000000..692297f
--- /dev/null
+++ b/tools/traceview/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>traceview</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/tools/traceview/Android.mk b/tools/traceview/Android.mk
new file mode 100644
index 0000000..2ce7b80
--- /dev/null
+++ b/tools/traceview/Android.mk
@@ -0,0 +1,5 @@
+# Copyright 2007 The Android Open Source Project
+#
+TRACEVIEW_LOCAL_DIR := $(call my-dir)
+include $(TRACEVIEW_LOCAL_DIR)/etc/Android.mk
+include $(TRACEVIEW_LOCAL_DIR)/src/Android.mk
diff --git a/tools/traceview/README b/tools/traceview/README
new file mode 100644
index 0000000..6f4576a
--- /dev/null
+++ b/tools/traceview/README
@@ -0,0 +1,11 @@
+Using the Eclipse projects for traceview.
+
+traceview requires SWT to compile.
+
+SWT is available in the depot under //device/prebuild/<platform>/swt
+
+Because the build path cannot contain relative path that are not inside the project directory,
+the .classpath file references a user library called ANDROID_SWT.
+
+In order to compile the project, make a user library called ANDROID_SWT containing the jar
+available at //device/prebuild/<platform>/swt.
diff --git a/tools/traceview/etc/Android.mk b/tools/traceview/etc/Android.mk
new file mode 100644
index 0000000..f26b19e
--- /dev/null
+++ b/tools/traceview/etc/Android.mk
@@ -0,0 +1,8 @@
+# Copyright 2007 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_EXECUTABLES := traceview
+include $(BUILD_HOST_PREBUILT)
+
diff --git a/tools/traceview/etc/manifest.txt b/tools/traceview/etc/manifest.txt
new file mode 100644
index 0000000..6cdbc7e
--- /dev/null
+++ b/tools/traceview/etc/manifest.txt
@@ -0,0 +1,2 @@
+Main-Class: com.android.traceview.MainWindow
+Class-Path: swt.jar org.eclipse.equinox.common_3.2.0.v20060603.jar org.eclipse.jface_3.2.0.I20060605-1400.jar org.eclipse.core.commands_3.2.0.I20060605-1400.jar
diff --git a/tools/traceview/etc/traceview b/tools/traceview/etc/traceview
new file mode 100755
index 0000000..1cc913d
--- /dev/null
+++ b/tools/traceview/etc/traceview
@@ -0,0 +1,101 @@
+#!/bin/bash
+#
+# Copyright 2005-2006, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This script assumes that the path to this script is something like:
+#
+# /somepath/outdir/archdir/hostdir/bindir/traceview
+#
+# where "somepath" is some pathname (like "/work/android/device/")
+#       "outdir"   is a subdirectory (like "out")
+#       "archdir"  is a subdirectory (like "linux-x86-release")
+#       "hostdir"  is a subdirectory (like "host")
+#       "bindir"   is a subdirectory (like "bin")
+#
+# e.g. /work/android/device/out/linux-x86-release/host/bin/traceview
+#
+# and that the following directories also exist:
+#
+# /somepath/outdir/archdir/hostdir/lib/
+# /somepath/outdir/archdir/hostdir/framework/
+#
+# where:
+#       "lib", and "framework" are at the same level as "bindir",
+#        and are the literal names.
+
+# Set up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+    newProg=`/bin/ls -ld "${prog}"`
+    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+    if expr "x${newProg}" : 'x/' >/dev/null; then
+        prog="${newProg}"
+    else
+        progdir=`dirname "${prog}"`
+        prog="${progdir}/${newProg}"
+    fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+progname=`basename "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/"${progname}"
+cd "${oldwd}"
+
+jarfile=traceview.jar
+frameworkdir="$progdir"
+libdir="$progdir"
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/tools/lib
+    libdir=`dirname "$progdir"`/tools/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    frameworkdir=`dirname "$progdir"`/framework
+    libdir=`dirname "$progdir"`/lib
+fi
+if [ ! -r "$frameworkdir/$jarfile" ]
+then
+    echo "${progname}: can't find $jarfile"
+    exit 1
+fi
+
+os=`uname`
+if [ $os == 'Darwin' ]; then
+  javaOpts="-Xmx1600M -XstartOnFirstThread"
+  javaCmd="/System/Library/Frameworks/JavaVM.framework/Versions/1.5/Commands/java"
+else
+  javaOpts="-Xmx1600M"
+  javaCmd="java"
+fi
+
+while expr "x$1" : 'x-J' >/dev/null; do
+    opt=`expr "$1" : '-J\(.*\)'`
+    javaOpts="${javaOpts} -${opt}"
+    shift
+done
+
+if [ "$OSTYPE" = "cygwin" ] ; then
+    jarpath=`cygpath -w  "$frameworkdir/$jarfile"`
+    progdir=`cygpath -w  "$progdir"`
+else
+    jarpath="$frameworkdir/$jarfile"
+fi
+
+
+exec "$javaCmd" $javaOpts -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -jar "$jarpath" "$@"
diff --git a/tools/traceview/etc/traceview.bat b/tools/traceview/etc/traceview.bat
new file mode 100755
index 0000000..a9b573d
--- /dev/null
+++ b/tools/traceview/etc/traceview.bat
@@ -0,0 +1,43 @@
+@echo off
+rem Copyright (C) 2007 The Android Open Source Project
+rem
+rem Licensed under the Apache License, Version 2.0 (the "License");
+rem you may not use this file except in compliance with the License.
+rem You may obtain a copy of the License at
+rem
+rem      http://www.apache.org/licenses/LICENSE-2.0
+rem
+rem Unless required by applicable law or agreed to in writing, software
+rem distributed under the License is distributed on an "AS IS" BASIS,
+rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+rem See the License for the specific language governing permissions and
+rem limitations under the License.
+
+rem don't modify the caller's environment
+setlocal
+
+rem Set up prog to be the path of this script, including following symlinks,
+rem and set up progdir to be the fully-qualified pathname of its directory.
+set prog=%~f0
+
+rem Change current directory and drive to where traceview.bat is, to avoid
+rem issues with directories containing whitespaces.
+cd /d %~dp0
+
+set jarfile=traceview.jar
+set frameworkdir=
+set libdir=
+
+if exist %frameworkdir%%jarfile% goto JarFileOk
+    set frameworkdir=lib\
+    set libdir=lib\
+
+if exist %frameworkdir%%jarfile% goto JarFileOk
+    set frameworkdir=..\framework\
+    set libdir=..\lib\
+
+:JarFileOk
+
+set jarpath=%frameworkdir%%jarfile%
+
+java -Djava.ext.dirs=%frameworkdir% -Djava.library.path=%libdir% -jar %jarpath% %*
diff --git a/tools/traceview/src/Android.mk b/tools/traceview/src/Android.mk
new file mode 100644
index 0000000..7a006de
--- /dev/null
+++ b/tools/traceview/src/Android.mk
@@ -0,0 +1,19 @@
+# Copyright 2007 The Android Open Source Project
+#
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_JAVA_RESOURCE_DIRS := resources
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_JAR_MANIFEST := ../etc/manifest.txt
+LOCAL_JAVA_LIBRARIES := \
+	androidprefs \
+	sdkstats \
+	swt \
+	org.eclipse.jface_3.2.0.I20060605-1400 \
+	org.eclipse.equinox.common_3.2.0.v20060603 \
+	org.eclipse.core.commands_3.2.0.I20060605-1400
+LOCAL_MODULE := traceview
+
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/traceview/src/com/android/traceview/Call.java b/tools/traceview/src/com/android/traceview/Call.java
new file mode 100644
index 0000000..40ac244
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/Call.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+import org.eclipse.swt.graphics.Color;
+
+class Call implements TimeLineView.Block {
+    
+    // Values for bits within the mFlags field.
+    private static final int METHOD_ACTION_MASK = 0x3;
+    private static final int IS_RECURSIVE = 0x10;
+
+    private int mThreadId;
+    private int mFlags;
+    MethodData mMethodData;
+    
+    /** 0-based thread-local start time */
+    long mThreadStartTime;
+    
+    /**  global start time */
+    long mGlobalStartTime;
+
+    /** global end time */
+    long mGlobalEndTime;
+    
+    private String mName;
+
+    /**
+     * This constructor is used for the root of a Call tree. The name is
+     * the name of the corresponding thread. 
+     */
+    Call(String name, MethodData methodData) {
+        mName = name;
+        mMethodData = methodData;
+    }
+
+    Call() {
+    }
+    
+    Call(int threadId, MethodData methodData, long time, int methodAction) {
+        mThreadId = threadId;
+        mMethodData = methodData;
+        mThreadStartTime = time;
+        mFlags = methodAction & METHOD_ACTION_MASK;
+        mName = methodData.getProfileName();
+    }
+    
+    public void set(int threadId, MethodData methodData, long time, int methodAction) {
+        mThreadId = threadId;
+        mMethodData = methodData;
+        mThreadStartTime = time;
+        mFlags = methodAction & METHOD_ACTION_MASK;
+        mName = methodData.getProfileName();
+    }
+
+    public void updateName() {
+        mName = mMethodData.getProfileName();
+    }
+
+    public double addWeight(int x, int y, double weight) {
+        return mMethodData.addWeight(x, y, weight);
+    }
+
+    public void clearWeight() {
+        mMethodData.clearWeight();
+    }
+
+    public long getStartTime() {
+        return mGlobalStartTime;
+    }
+
+    public long getEndTime() {
+        return mGlobalEndTime;
+    }
+
+    public Color getColor() {
+        return mMethodData.getColor();
+    }
+
+    public void addExclusiveTime(long elapsed) {
+        mMethodData.addElapsedExclusive(elapsed);
+        if ((mFlags & IS_RECURSIVE) == 0) {
+            mMethodData.addTopExclusive(elapsed);
+        }
+    }
+
+    public void addInclusiveTime(long elapsed, Call parent) {
+        boolean isRecursive = (mFlags & IS_RECURSIVE) != 0;
+        mMethodData.addElapsedInclusive(elapsed, isRecursive, parent);
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    public void setName(String name) {
+        mName = name;
+    }
+
+    int getThreadId() {
+        return mThreadId;
+    }
+
+    public MethodData getMethodData() {
+        return mMethodData;
+    }
+
+    int getMethodAction() {
+        return mFlags & METHOD_ACTION_MASK;
+    }
+
+    public void dump() {
+        System.out.printf("%s [%d, %d]\n", mName, mGlobalStartTime, mGlobalEndTime);
+    }
+
+    public void setRecursive(boolean isRecursive) {
+        if (isRecursive) {
+            mFlags |= IS_RECURSIVE;
+        } else {
+            mFlags &= ~IS_RECURSIVE;
+        }
+    }
+
+    public boolean isRecursive() {
+        return (mFlags & IS_RECURSIVE) != 0;
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/ColorController.java b/tools/traceview/src/com/android/traceview/ColorController.java
new file mode 100644
index 0000000..f5e4c0d
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/ColorController.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+import java.util.HashMap;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+public class ColorController {
+    private static final int[] systemColors = { SWT.COLOR_BLUE, SWT.COLOR_RED,
+        SWT.COLOR_GREEN, SWT.COLOR_CYAN, SWT.COLOR_MAGENTA, SWT.COLOR_DARK_BLUE,
+        SWT.COLOR_DARK_RED, SWT.COLOR_DARK_GREEN, SWT.COLOR_DARK_YELLOW,
+        SWT.COLOR_DARK_CYAN, SWT.COLOR_DARK_MAGENTA, SWT.COLOR_BLACK };
+
+    private static RGB[] rgbColors = { new RGB(90, 90, 255), // blue
+            new RGB(0, 240, 0), // green
+            new RGB(255, 0, 0), // red
+            new RGB(0, 255, 255), // cyan
+            new RGB(255, 80, 255), // magenta
+            new RGB(200, 200, 0), // yellow
+            new RGB(40, 0, 200), // dark blue
+            new RGB(150, 255, 150), // light green
+            new RGB(150, 0, 0), // dark red
+            new RGB(30, 150, 150), // dark cyan
+            new RGB(200, 200, 255), // light blue
+            new RGB(0, 120, 0), // dark green
+            new RGB(255, 150, 150), // light red
+            new RGB(140, 80, 140), // dark magenta
+            new RGB(150, 100, 50), // brown
+            new RGB(70, 70, 70), // dark grey
+    };
+
+    private static HashMap<Integer, Color> colorCache = new HashMap<Integer, Color>();
+    private static HashMap<Integer, Image> imageCache = new HashMap<Integer, Image>();
+
+    public ColorController() {
+    }
+
+    public static Color requestColor(Display display, RGB rgb) {
+        return requestColor(display, rgb.red, rgb.green, rgb.blue);
+    }
+
+    public static Image requestColorSquare(Display display, RGB rgb) {
+        return requestColorSquare(display, rgb.red, rgb.green, rgb.blue);
+    }
+
+    public static Color requestColor(Display display, int red, int green, int blue) {
+        int key = (red << 16) | (green << 8) | blue;
+        Color color = colorCache.get(key);
+        if (color == null) {
+            color = new Color(display, red, green, blue);
+            colorCache.put(key, color);
+        }
+        return color;
+    }
+
+    public static Image requestColorSquare(Display display, int red, int green, int blue) {
+        int key = (red << 16) | (green << 8) | blue;
+        Image image = imageCache.get(key);
+        if (image == null) {
+            image = new Image(display, 8, 14);
+            GC gc = new GC(image);
+            Color color = requestColor(display, red, green, blue);
+            gc.setBackground(color);
+            gc.fillRectangle(image.getBounds());
+            gc.dispose();
+            imageCache.put(key, image);
+        }
+        return image;
+    }
+
+    public static void assignMethodColors(Display display, MethodData[] methods) {
+        int nextColorIndex = 0;
+        for (MethodData md : methods) {
+            RGB rgb = rgbColors[nextColorIndex];
+            if (++nextColorIndex == rgbColors.length)
+                nextColorIndex = 0;
+            Color color = requestColor(display, rgb);
+            Image image = requestColorSquare(display, rgb);
+            md.setColor(color);
+            md.setImage(image);
+
+            // Compute and set a faded color
+            int fadedRed = 150 + rgb.red / 4;
+            int fadedGreen = 150 + rgb.green / 4;
+            int fadedBlue = 150 + rgb.blue / 4;
+            RGB faded = new RGB(fadedRed, fadedGreen, fadedBlue);
+            color = requestColor(display, faded);
+            image = requestColorSquare(display, faded);
+            md.setFadedColor(color);
+            md.setFadedImage(image);
+        }
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/DmTraceReader.java b/tools/traceview/src/com/android/traceview/DmTraceReader.java
new file mode 100644
index 0000000..5a19c19
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/DmTraceReader.java
@@ -0,0 +1,602 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteOrder;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DmTraceReader extends TraceReader {
+
+    private int mVersionNumber = 0;
+    private boolean mDebug = false;
+    private static final int TRACE_MAGIC = 0x574f4c53;
+    private boolean mRegression;
+    private ProfileProvider mProfileProvider;
+    private String mTraceFileName;
+    private MethodData mTopLevel;
+    private ArrayList<Call> mCallList;
+    private ArrayList<Call> mSwitchList;
+    private HashMap<Integer, MethodData> mMethodMap;
+    private HashMap<Integer, ThreadData> mThreadMap;
+    private ThreadData[] mSortedThreads;
+    private MethodData[] mSortedMethods;
+    private long mGlobalEndTime;
+    private MethodData mContextSwitch;
+    private int mOffsetToData;
+    private byte[] mBytes = new byte[8];
+
+    // A regex for matching the thread "id name" lines in the .key file
+    private static final Pattern mIdNamePattern = Pattern.compile("(\\d+)\t(.*)");  // $NON-NLS-1$
+
+    DmTraceReader(String traceFileName, boolean regression) {
+        mTraceFileName = traceFileName;
+        mRegression = regression;
+        mMethodMap = new HashMap<Integer, MethodData>();
+        mThreadMap = new HashMap<Integer, ThreadData>();
+
+        // Create a single top-level MethodData object to hold the profile data
+        // for time spent in the unknown caller.
+        mTopLevel = new MethodData(0, "(toplevel)");
+        mContextSwitch = new MethodData(-1, "(context switch)");
+        mMethodMap.put(0, mTopLevel);
+        generateTrees();
+        // dumpTrees();
+    }
+
+    void generateTrees() {
+        try {
+            long offset = parseKeys();
+            parseData(offset);
+            analyzeData();
+        } catch (IOException e) {
+            System.err.println(e.getMessage());
+            System.exit(1);
+        }
+    }
+
+    @Override
+    public ProfileProvider getProfileProvider() {
+        if (mProfileProvider == null)
+            mProfileProvider = new ProfileProvider(this);
+        return mProfileProvider;
+    }
+
+    Call readCall(MappedByteBuffer buffer, Call call) {
+        int threadId;
+        int methodId;
+        long time;
+        
+        try {
+            if (mVersionNumber == 1)
+                threadId = buffer.get();
+            else
+                threadId = buffer.getShort();
+            methodId = buffer.getInt();
+            time = buffer.getInt();
+        } catch (BufferUnderflowException ex) {
+            return null;
+        }
+        
+        int methodAction = methodId & 0x03;
+        methodId = methodId & ~0x03;
+        MethodData methodData = mMethodMap.get(methodId);
+        if (methodData == null) {
+            String name = String.format("(0x%1$x)", methodId);  // $NON-NLS-1$
+            methodData = new MethodData(methodId, name);
+        }
+        
+        if (call != null) {
+            call.set(threadId, methodData, time, methodAction);
+        } else {
+            call = new Call(threadId, methodData, time, methodAction);
+        }
+        return call;
+    }
+    
+    private MappedByteBuffer mapFile(String filename, long offset) {
+        MappedByteBuffer buffer = null;
+        try {
+            FileInputStream dataFile = new FileInputStream(filename);
+            File file = new File(filename);
+            FileChannel fc = dataFile.getChannel();
+            buffer = fc.map(FileChannel.MapMode.READ_ONLY, offset, file.length() - offset);
+            buffer.order(ByteOrder.LITTLE_ENDIAN);
+        } catch (FileNotFoundException ex) {
+            System.err.println(ex.getMessage());
+            System.exit(1);
+        } catch (IOException ex) {
+            System.err.println(ex.getMessage());
+            System.exit(1);
+        }
+        
+        return buffer;
+    }
+    
+    private void readDataFileHeader(MappedByteBuffer buffer) {
+        int magic = buffer.getInt();
+        if (magic != TRACE_MAGIC) {
+            System.err.printf(
+                    "Error: magic number mismatch; got 0x%x, expected 0x%x\n",
+                    magic, TRACE_MAGIC);
+            throw new RuntimeException();
+        }
+        // read version
+        int version = buffer.getShort();
+        
+        // read offset
+        mOffsetToData = buffer.getShort() - 16;
+        
+        // read startWhen
+        buffer.getLong();
+        
+        // Skip over "mOffsetToData" bytes
+        for (int ii = 0; ii < mOffsetToData; ii++) {
+            buffer.get();
+        }
+        
+        // Save this position so that we can re-read the data later
+        buffer.mark();
+    }
+
+    private void parseData(long offset) {
+        MappedByteBuffer buffer = mapFile(mTraceFileName, offset);
+        readDataFileHeader(buffer);
+        parseDataPass1(buffer);
+        
+        buffer.reset();
+        parseDataPass2(buffer);
+    }
+    
+    private void parseDataPass1(MappedByteBuffer buffer) {
+        mSwitchList = new ArrayList<Call>();
+
+        // Read the first call so that we can set "prevThreadData"
+        Call call = new Call();
+        call = readCall(buffer, call);
+        if (call == null)
+            return;
+        long callTime = call.mThreadStartTime;
+        long prevCallTime = 0;
+        ThreadData threadData = mThreadMap.get(call.getThreadId());
+        if (threadData == null) {
+            String name = String.format("[%1$d]", call.getThreadId());  // $NON-NLS-1$
+            threadData = new ThreadData(call.getThreadId(), name, mTopLevel);
+            mThreadMap.put(call.getThreadId(), threadData);
+        }
+        ThreadData prevThreadData = threadData;
+        while (true) {
+            // If a context switch occurred, then insert a placeholder "call"
+            // record so that we can do something reasonable with the global
+            // timestamps.
+            if (prevThreadData != threadData) {
+                Call switchEnter = new Call(prevThreadData.getId(),
+                        mContextSwitch, prevCallTime, 0);
+                prevThreadData.setLastContextSwitch(switchEnter);
+                mSwitchList.add(switchEnter);
+                Call contextSwitch = threadData.getLastContextSwitch();
+                if (contextSwitch != null) {
+                    long prevStartTime = contextSwitch.mThreadStartTime;
+                    long elapsed = callTime - prevStartTime;
+                    long beforeSwitch = elapsed / 2;
+                    long afterSwitch = elapsed - beforeSwitch;
+                    long exitTime = callTime - afterSwitch;
+                    contextSwitch.mThreadStartTime = prevStartTime + beforeSwitch;
+                    Call switchExit = new Call(threadData.getId(),
+                            mContextSwitch, exitTime, 1);
+                    
+                    mSwitchList.add(switchExit);
+                }
+                prevThreadData = threadData;
+            }
+
+            // Read the next call
+            call = readCall(buffer, call);
+            if (call == null) {
+                break;
+            }
+            prevCallTime = callTime;
+            callTime = call.mThreadStartTime;
+
+            threadData = mThreadMap.get(call.getThreadId());
+            if (threadData == null) {
+                String name = String.format("[%d]", call.getThreadId());
+                threadData = new ThreadData(call.getThreadId(), name, mTopLevel);
+                mThreadMap.put(call.getThreadId(), threadData);
+            }
+        }
+    }
+
+    void parseDataPass2(MappedByteBuffer buffer) {
+        mCallList = new ArrayList<Call>();
+
+        // Read the first call so that we can set "prevThreadData"
+        Call call = readCall(buffer, null);
+        long callTime = call.mThreadStartTime;
+        long prevCallTime = callTime;
+        ThreadData threadData = mThreadMap.get(call.getThreadId());
+        ThreadData prevThreadData = threadData;
+        threadData.setGlobalStartTime(0);
+        
+        int nthContextSwitch = 0;
+
+        // Assign a global timestamp to each event.
+        long globalTime = 0;
+        while (true) {
+            long elapsed = callTime - prevCallTime;
+            if (threadData != prevThreadData) {
+                // Get the next context switch.  This one is entered
+                // by the previous thread.
+                Call contextSwitch = mSwitchList.get(nthContextSwitch++);
+                mCallList.add(contextSwitch);
+                elapsed = contextSwitch.mThreadStartTime - prevCallTime;
+                globalTime += elapsed;
+                elapsed = 0;
+                contextSwitch.mGlobalStartTime = globalTime;
+                prevThreadData.handleCall(contextSwitch, globalTime);
+                
+                if (!threadData.isEmpty()) {
+                    // This context switch is exited by the current thread.
+                    contextSwitch = mSwitchList.get(nthContextSwitch++);
+                    mCallList.add(contextSwitch);
+                    contextSwitch.mGlobalStartTime = globalTime;
+                    elapsed = callTime - contextSwitch.mThreadStartTime;
+                    threadData.handleCall(contextSwitch, globalTime);
+                }
+
+                // If the thread's global start time has not been set yet,
+                // then set it.
+                if (threadData.getGlobalStartTime() == -1)
+                    threadData.setGlobalStartTime(globalTime);
+                prevThreadData = threadData;
+            }
+
+            globalTime += elapsed;
+            call.mGlobalStartTime = globalTime;
+            
+            threadData.handleCall(call, globalTime);
+            mCallList.add(call);
+            
+            // Read the next call
+            call = readCall(buffer, null);
+            if (call == null) {
+                break;
+            }
+            prevCallTime = callTime;
+            callTime = call.mThreadStartTime;
+            threadData = mThreadMap.get(call.getThreadId());
+        }
+
+        // Allow each thread to do any cleanup of the call stack.
+        // Also add the elapsed time for each thread to the toplevel
+        // method's inclusive time.
+        for (int id : mThreadMap.keySet()) {
+            threadData = mThreadMap.get(id);
+            long endTime = threadData.endTrace();
+            if (endTime > 0)
+                mTopLevel.addElapsedInclusive(endTime, false, null);
+        }
+
+        mGlobalEndTime = globalTime;
+        
+        if (mRegression) {
+            dumpCallTimes();
+        }
+    }
+
+    static final int PARSE_VERSION = 0;
+    static final int PARSE_THREADS = 1;
+    static final int PARSE_METHODS = 2;
+    static final int PARSE_OPTIONS = 4;
+
+    long parseKeys() throws IOException {
+        BufferedReader in = null;
+        try {
+            in = new BufferedReader(new FileReader(mTraceFileName));
+        } catch (FileNotFoundException ex) {
+            System.err.println(ex.getMessage());
+        }
+
+        long offset = 0;
+        int mode = PARSE_VERSION;
+        String line = null;
+        while (true) {
+            line = in.readLine();
+            if (line == null) {
+                throw new IOException("Key section does not have an *end marker");
+            }
+            
+            // Calculate how much we have read from the file so far.  The
+            // extra byte is for the line ending not included by readLine().
+            offset += line.length() + 1;
+            if (line.startsWith("*")) {
+                if (line.equals("*version")) {
+                    mode = PARSE_VERSION;
+                    continue;
+                }
+                if (line.equals("*threads")) {
+                    mode = PARSE_THREADS;
+                    continue;
+                }
+                if (line.equals("*methods")) {
+                    mode = PARSE_METHODS;
+                    continue;
+                }
+                if (line.equals("*end")) {
+                    return offset;
+                }
+            }
+            switch (mode) {
+            case PARSE_VERSION:
+                mVersionNumber = Integer.decode(line);
+                mode = PARSE_OPTIONS;
+                break;
+            case PARSE_THREADS:
+                parseThread(line);
+                break;
+            case PARSE_METHODS:
+                parseMethod(line);
+                break;
+            case PARSE_OPTIONS:
+                break;
+            }
+        }
+    }
+
+    void parseThread(String line) {
+        String idStr = null;
+        String name = null;
+        Matcher matcher = mIdNamePattern.matcher(line);
+        if (matcher.find()) {
+            idStr = matcher.group(1);
+            name = matcher.group(2);
+        }
+        if (idStr == null) return;
+        if (name == null) name = "(unknown)";
+
+        int id = Integer.decode(idStr);
+        mThreadMap.put(id, new ThreadData(id, name, mTopLevel));
+    }
+
+    void parseMethod(String line) {
+        String[] tokens = line.split("\t");
+        int id = Long.decode(tokens[0]).intValue();
+        String className = tokens[1];
+        String methodName = null;
+        String signature = null;
+        String pathname = null;
+        int lineNumber = -1;
+        if (tokens.length == 6) {
+            methodName = tokens[2];
+            signature = tokens[3];
+            pathname = tokens[4];
+            lineNumber = Integer.decode(tokens[5]);
+            pathname = constructPathname(className, pathname);
+        } else if (tokens.length > 2) {
+            if (tokens[3].startsWith("(")) {
+                methodName = tokens[2];
+                signature = tokens[3];
+            } else {
+                pathname = tokens[2];
+                lineNumber = Integer.decode(tokens[3]);
+            }
+        }
+
+        mMethodMap.put(id, new MethodData(id, className, methodName, signature,
+                pathname, lineNumber));
+    }
+
+    private String constructPathname(String className, String pathname) {
+        int index = className.lastIndexOf('/');
+        if (index > 0 && index < className.length() - 1
+                && pathname.endsWith(".java"))
+            pathname = className.substring(0, index + 1) + pathname;
+        return pathname;
+    }
+
+    private void analyzeData() {
+        // Sort the threads into decreasing cpu time
+        Collection<ThreadData> tv = mThreadMap.values();
+        mSortedThreads = tv.toArray(new ThreadData[tv.size()]);
+        Arrays.sort(mSortedThreads, new Comparator<ThreadData>() {
+            public int compare(ThreadData td1, ThreadData td2) {
+                if (td2.getCpuTime() > td1.getCpuTime())
+                    return 1;
+                if (td2.getCpuTime() < td1.getCpuTime())
+                    return -1;
+                return td2.getName().compareTo(td1.getName());
+            }
+        });
+
+        // Analyze the call tree so that we can label the "worst" children.
+        // Also set all the root pointers in each node in the call tree.
+        long sum = 0;
+        for (ThreadData t : mSortedThreads) {
+            if (t.isEmpty() == false) {
+                Call root = t.getCalltreeRoot();
+                root.mGlobalStartTime = t.getGlobalStartTime();
+            }
+        }
+
+        // Sort the methods into decreasing inclusive time
+        Collection<MethodData> mv = mMethodMap.values();
+        MethodData[] methods;
+        methods = mv.toArray(new MethodData[mv.size()]);
+        Arrays.sort(methods, new Comparator<MethodData>() {
+            public int compare(MethodData md1, MethodData md2) {
+                if (md2.getElapsedInclusive() > md1.getElapsedInclusive())
+                    return 1;
+                if (md2.getElapsedInclusive() < md1.getElapsedInclusive())
+                    return -1;
+                return md1.getName().compareTo(md2.getName());
+            }
+        });
+
+        // Count the number of methods with non-zero inclusive time
+        int nonZero = 0;
+        for (MethodData md : methods) {
+            if (md.getElapsedInclusive() == 0)
+                break;
+            nonZero += 1;
+        }
+
+        // Copy the methods with non-zero time
+        mSortedMethods = new MethodData[nonZero];
+        int ii = 0;
+        for (MethodData md : methods) {
+            if (md.getElapsedInclusive() == 0)
+                break;
+            md.setRank(ii);
+            mSortedMethods[ii++] = md;
+        }
+
+        // Let each method analyze its profile data
+        for (MethodData md : mSortedMethods) {
+            md.analyzeData();
+        }
+
+        // Update all the calls to include the method rank in
+        // their name.
+        for (Call call : mCallList) {
+            call.updateName();
+        }
+        
+        if (mRegression) {
+            dumpMethodStats();
+        }
+    }
+
+    /*
+     * This method computes a list of records that describe the the execution
+     * timeline for each thread. Each record is a pair: (row, block) where: row:
+     * is the ThreadData object block: is the call (containing the start and end
+     * times)
+     */
+    @Override
+    public ArrayList<TimeLineView.Record> getThreadTimeRecords() {
+        TimeLineView.Record record;
+        ArrayList<TimeLineView.Record> timeRecs;
+        timeRecs = new ArrayList<TimeLineView.Record>();
+
+        // For each thread, push a "toplevel" call that encompasses the
+        // entire execution of the thread.
+        for (ThreadData threadData : mSortedThreads) {
+            if (!threadData.isEmpty() && threadData.getId() != 0) {
+                Call call = new Call(threadData.getId(), mTopLevel,
+                        threadData.getGlobalStartTime(), 0);
+                call.mGlobalStartTime = threadData.getGlobalStartTime();
+                call.mGlobalEndTime = threadData.getGlobalEndTime();
+                record = new TimeLineView.Record(threadData, call);
+                timeRecs.add(record);
+            }
+        }
+
+        for (Call call : mCallList) {
+            if (call.getMethodAction() != 0 || call.getThreadId() == 0)
+                continue;
+            ThreadData threadData = mThreadMap.get(call.getThreadId());
+            record = new TimeLineView.Record(threadData, call);
+            timeRecs.add(record);
+        }
+        
+        if (mRegression) {
+            dumpTimeRecs(timeRecs);
+            System.exit(0);
+        }
+        return timeRecs;
+    }
+        
+    private void dumpCallTimes() {
+        String action;
+        
+        System.out.format("id thread  global start,end   method\n");
+        for (Call call : mCallList) {
+            if (call.getMethodAction() == 0) {
+                action = "+";
+            } else {
+                action = " ";
+            }
+            long callTime = call.mThreadStartTime;
+            System.out.format("%2d %6d %8d %8d %s %s\n",
+                    call.getThreadId(), callTime, call.mGlobalStartTime,
+                    call.mGlobalEndTime, action, call.getMethodData().getName());
+//            if (call.getMethodAction() == 0 && call.getGlobalEndTime() < call.getGlobalStartTime()) {
+//                System.out.printf("endtime %d < startTime %d\n",
+//                        call.getGlobalEndTime(), call.getGlobalStartTime());
+//            }
+        }
+    }
+    
+    private void dumpMethodStats() {
+        System.out.format("\nExclusive Inclusive     Calls  Method\n");
+        for (MethodData md : mSortedMethods) {
+            System.out.format("%9d %9d %9s  %s\n",
+                    md.getElapsedExclusive(), md.getElapsedInclusive(),
+                    md.getCalls(), md.getProfileName());
+        }
+    }
+
+    private void dumpTimeRecs(ArrayList<TimeLineView.Record> timeRecs) {
+        System.out.format("\nid thread  global start,end  method\n");
+        for (TimeLineView.Record record : timeRecs) {
+            Call call = (Call) record.block;
+            long callTime = call.mThreadStartTime;
+            System.out.format("%2d %6d %8d %8d  %s\n",
+                    call.getThreadId(), callTime,
+                    call.mGlobalStartTime, call.mGlobalEndTime,
+                    call.getMethodData().getName());
+        }
+    }
+
+    @Override
+    public HashMap<Integer, String> getThreadLabels() {
+        HashMap<Integer, String> labels = new HashMap<Integer, String>();
+        for (ThreadData t : mThreadMap.values()) {
+            labels.put(t.getId(), t.getName());
+        }
+        return labels;
+    }
+
+    @Override
+    public MethodData[] getMethods() {
+        return mSortedMethods;
+    }
+
+    @Override
+    public ThreadData[] getThreads() {
+        return mSortedThreads;
+    }
+
+    @Override
+    public long getEndTime() {
+        return mGlobalEndTime;
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/MainWindow.java b/tools/traceview/src/com/android/traceview/MainWindow.java
new file mode 100644
index 0000000..b0c24e9
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/MainWindow.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+import com.android.sdkstats.SdkStatsService;
+
+import org.eclipse.jface.window.ApplicationWindow;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.nio.channels.FileChannel;
+import java.util.HashMap;
+
+public class MainWindow extends ApplicationWindow {
+    
+    private final static String PING_NAME = "Traceview";
+    private final static String PING_VERSION = "1.0";
+
+    private TraceReader mReader;
+    private String mTraceName;
+
+    // A global cache of string names.
+    public static HashMap<String, String> sStringCache = new HashMap<String, String>();
+
+    public MainWindow(String traceName, TraceReader reader) {
+        super(null);
+        mReader = reader;
+        mTraceName = traceName;
+    }
+
+    public void run() {
+        setBlockOnOpen(true);
+        open();
+        Display.getCurrent().dispose();
+    }
+
+    @Override
+    protected void configureShell(Shell shell) {
+        super.configureShell(shell);
+        shell.setText("Traceview: " + mTraceName);
+        shell.setBounds(100, 10, 1282, 900);
+    }
+
+    @Override
+    protected Control createContents(Composite parent) {
+        ColorController.assignMethodColors(parent.getDisplay(), mReader.getMethods());
+        SelectionController selectionController = new SelectionController();
+
+        GridLayout gridLayout = new GridLayout(1, false);
+        gridLayout.marginWidth = 0;
+        gridLayout.marginHeight = 0;
+        gridLayout.horizontalSpacing = 0;
+        gridLayout.verticalSpacing = 0;
+        parent.setLayout(gridLayout);
+
+        Display display = parent.getDisplay();
+        Color darkGray = display.getSystemColor(SWT.COLOR_DARK_GRAY);
+
+        // Create a sash form to separate the timeline view (on top)
+        // and the profile view (on bottom)
+        SashForm sashForm1 = new SashForm(parent, SWT.VERTICAL);
+        sashForm1.setBackground(darkGray);
+        sashForm1.SASH_WIDTH = 3;
+        GridData data = new GridData(GridData.FILL_BOTH);
+        sashForm1.setLayoutData(data);
+
+        // Create the timeline view
+        new TimeLineView(sashForm1, mReader, selectionController);
+
+        // Create the profile view
+        new ProfileView(sashForm1, mReader, selectionController);
+        return sashForm1;
+    }
+
+    /**
+     * Convert the old two-file format into the current concatenated one.
+     * 
+     * @param base Base path of the two files, i.e. base.key and base.data
+     * @return Path to a temporary file that will be deleted on exit.
+     * @throws IOException 
+     */
+    private static String makeTempTraceFile(String base) throws IOException {
+        // Make a temporary file that will go away on exit and prepare to
+        // write into it.
+        File temp = File.createTempFile(base, ".trace");
+        temp.deleteOnExit();
+        FileChannel dstChannel = new FileOutputStream(temp).getChannel();
+
+        // First copy the contents of the key file into our temp file.
+        FileChannel srcChannel = new FileInputStream(base + ".key").getChannel();
+        long size = dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
+        srcChannel.close();
+
+        // Then concatenate the data file.
+        srcChannel = new FileInputStream(base + ".data").getChannel();
+        dstChannel.transferFrom(srcChannel, size, srcChannel.size());
+
+        // Clean up.
+        srcChannel.close();
+        dstChannel.close();
+
+        // Return the path of the temp file.
+        return temp.getPath();
+    }
+    
+    public static void main(String[] args) {
+        TraceReader reader = null;
+        boolean regression = false;
+        
+        // ping the usage server
+        SdkStatsService.ping(PING_NAME, PING_VERSION);
+
+        // Process command line arguments
+        int argc = 0;
+        int len = args.length;
+        while (argc < len) {
+            String arg = args[argc];
+            if (arg.charAt(0) != '-') {
+                break;
+            }
+            if (arg.equals("-r")) {
+                regression = true;
+            } else {
+                break;
+            }
+            argc++;
+        }
+        if (argc != len - 1) {
+            System.out.printf("Usage: java %s [-r] trace%n", MainWindow.class.getName());
+            System.out.printf("  -r   regression only%n");
+            return;
+        }
+
+        String traceName = args[len - 1];
+        File file = new File(traceName);
+        if (file.exists() && file.isDirectory()) {
+            System.out.printf("Qemu trace files not supported yet.\n");
+            System.exit(1);
+            // reader = new QtraceReader(traceName);
+        } else {
+            // If the filename as given doesn't exist...
+            if (!file.exists()) {
+                // Try appending .trace.
+                if (new File(traceName + ".trace").exists()) {
+                    traceName = traceName + ".trace";
+                // Next, see if it is the old two-file trace.
+                } else if (new File(traceName + ".data").exists()
+                    && new File(traceName + ".key").exists()) {
+                    try {
+                        traceName = makeTempTraceFile(traceName);
+                    } catch (IOException e) {
+                        System.err.printf("cannot convert old trace file '%s'\n", traceName);
+                        System.exit(1);
+                    }
+                // Otherwise, give up.
+                } else {
+                    System.err.printf("trace file '%s' not found\n", traceName);
+                    System.exit(1);
+                }
+            }
+
+            reader = new DmTraceReader(traceName, regression);
+        }
+        reader.getTraceUnits().setTimeScale(TraceUnits.TimeScale.MilliSeconds);
+        new MainWindow(traceName, reader).run();
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/MethodData.java b/tools/traceview/src/com/android/traceview/MethodData.java
new file mode 100644
index 0000000..0bc9853
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/MethodData.java
@@ -0,0 +1,458 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+
+public class MethodData {
+
+    private int mId;
+    private int mRank = -1;
+    private String mClassName;
+    private String mMethodName;
+    private String mSignature;
+    private String mName;
+    private String mProfileName;
+    private String mPathname;
+    private int mLineNumber;
+    private long mElapsedExclusive;
+    private long mElapsedInclusive;
+    private long mTopExclusive;
+    private int[] mNumCalls = new int[2]; // index 0=normal, 1=recursive
+    private Color mColor;
+    private Color mFadedColor;
+    private Image mImage;
+    private Image mFadedImage;
+    private HashMap<Integer, ProfileData> mParents;
+    private HashMap<Integer, ProfileData> mChildren;
+    
+    // The parents of this method when this method was in a recursive call
+    private HashMap<Integer, ProfileData> mRecursiveParents;
+    
+    // The children of this method when this method was in a recursive call
+    private HashMap<Integer, ProfileData> mRecursiveChildren;
+
+    private ProfileNode[] mProfileNodes;
+    private int mX;
+    private int mY;
+    private double mWeight;
+
+    public MethodData(int id, String className) {
+        mId = id;
+        mClassName = className;
+        mMethodName = null;
+        mSignature = null;
+        mPathname = null;
+        mLineNumber = -1;
+        computeName();
+        computeProfileName();
+    }
+
+    public MethodData(int id, String className, String methodName,
+            String signature, String pathname, int lineNumber) {
+        mId = id;
+        mClassName = className;
+        mMethodName = methodName;
+        mSignature = signature;
+        mPathname = pathname;
+        mLineNumber = lineNumber;
+        computeName();
+        computeProfileName();
+    }
+
+    private Comparator<ProfileData> mByElapsedInclusive = new Comparator<ProfileData>() {
+        public int compare(ProfileData pd1, ProfileData pd2) {
+            if (pd2.getElapsedInclusive() > pd1.getElapsedInclusive())
+                return 1;
+            if (pd2.getElapsedInclusive() < pd1.getElapsedInclusive())
+                return -1;
+            return 0;
+        }
+    };
+
+    public double addWeight(int x, int y, double weight) {
+        if (mX == x && mY == y)
+            mWeight += weight;
+        else {
+            mX = x;
+            mY = y;
+            mWeight = weight;
+        }
+        return mWeight;
+    }
+
+    public void clearWeight() {
+        mWeight = 0;
+    }
+
+    public int getRank() {
+        return mRank;
+    }
+
+    public void setRank(int rank) {
+        mRank = rank;
+        computeProfileName();
+    }
+
+    public void addElapsedExclusive(long time) {
+        mElapsedExclusive += time;
+    }
+
+    public void addElapsedInclusive(long time, boolean isRecursive, Call parent) {
+        if (isRecursive == false) {
+            mElapsedInclusive += time;
+            mNumCalls[0] += 1;
+        } else {
+            mNumCalls[1] += 1;
+        }
+
+        if (parent == null)
+            return;
+
+        // Find the child method in the parent
+        MethodData parentMethod = parent.mMethodData;
+        if (parent.isRecursive()) {
+            parentMethod.mRecursiveChildren = updateInclusive(time,
+                    parentMethod, this, false,
+                    parentMethod.mRecursiveChildren);
+        } else {
+            parentMethod.mChildren = updateInclusive(time,
+                    parentMethod, this, false, parentMethod.mChildren);
+        }
+
+        // Find the parent method in the child
+        if (isRecursive) {
+            mRecursiveParents = updateInclusive(time, this, parentMethod, true,
+                    mRecursiveParents);
+        } else {
+            mParents = updateInclusive(time, this, parentMethod, true,
+                    mParents);
+        }
+    }
+    
+    private HashMap<Integer, ProfileData> updateInclusive(long time,
+            MethodData contextMethod, MethodData elementMethod,
+            boolean elementIsParent, HashMap<Integer, ProfileData> map) {
+        if (map == null) {
+            map = new HashMap<Integer, ProfileData>(4);
+        } else {
+            ProfileData profileData = map.get(elementMethod.mId);
+            if (profileData != null) {
+                profileData.addElapsedInclusive(time);
+                return map;
+            }
+        }
+
+        ProfileData elementData = new ProfileData(contextMethod,
+                elementMethod, elementIsParent);
+        elementData.setElapsedInclusive(time);
+        elementData.setNumCalls(1);
+        map.put(elementMethod.mId, elementData);
+        return map;
+    }
+
+    public void analyzeData() {
+        // Sort the parents and children into decreasing inclusive time
+        ProfileData[] sortedParents;
+        ProfileData[] sortedChildren;
+        ProfileData[] sortedRecursiveParents;
+        ProfileData[] sortedRecursiveChildren;
+        
+        sortedParents = sortProfileData(mParents);
+        sortedChildren = sortProfileData(mChildren);
+        sortedRecursiveParents = sortProfileData(mRecursiveParents);
+        sortedRecursiveChildren = sortProfileData(mRecursiveChildren);
+        
+        // Add "self" time to the top of the sorted children
+        sortedChildren = addSelf(sortedChildren);
+        
+        // Create the ProfileNode objects that we need
+        ArrayList<ProfileNode> nodes = new ArrayList<ProfileNode>();
+        ProfileNode profileNode;
+        if (mParents != null) {
+            profileNode = new ProfileNode("Parents", this, sortedParents,
+                    true, false);
+            nodes.add(profileNode);
+        }
+        if (mChildren != null) {
+            profileNode = new ProfileNode("Children", this, sortedChildren,
+                    false, false);
+            nodes.add(profileNode);
+        }
+        if (mRecursiveParents!= null) {
+            profileNode = new ProfileNode("Parents while recursive", this,
+                    sortedRecursiveParents, true, true);
+            nodes.add(profileNode);
+        }
+        if (mRecursiveChildren != null) {
+            profileNode = new ProfileNode("Children while recursive", this,
+                    sortedRecursiveChildren, false, true);
+            nodes.add(profileNode);
+        }
+        mProfileNodes = nodes.toArray(new ProfileNode[nodes.size()]);
+    }
+    
+    // Create and return a ProfileData[] array that is a sorted copy
+    // of the given HashMap values.
+    private ProfileData[] sortProfileData(HashMap<Integer, ProfileData> map) {
+        if (map == null)
+            return null;
+
+        // Convert the hash values to an array of ProfileData
+        Collection<ProfileData> values = map.values();
+        ProfileData[] sorted = values.toArray(new ProfileData[values.size()]);
+        
+        // Sort the array by elapsed inclusive time
+        Arrays.sort(sorted, mByElapsedInclusive);
+        return sorted;
+    }
+    
+    private ProfileData[] addSelf(ProfileData[] children) {
+        ProfileData[] pdata;
+        if (children == null) {
+            pdata = new ProfileData[1];
+        } else {
+            pdata = new ProfileData[children.length + 1];
+            System.arraycopy(children, 0, pdata, 1, children.length);
+        }
+        pdata[0] = new ProfileSelf(this);
+        return pdata;
+    }
+
+    public void addTopExclusive(long time) {
+        mTopExclusive += time;
+    }
+
+    public long getTopExclusive() {
+        return mTopExclusive;
+    }
+
+    public int getId() {
+        return mId;
+    }
+
+    private void computeName() {
+        if (mMethodName == null) {
+            mName = mClassName;
+            return;
+        }
+
+        StringBuilder sb = new StringBuilder();
+        sb.append(mClassName);
+        sb.append(".");  //$NON-NLS-1$
+        sb.append(mMethodName);
+        sb.append(" ");  //$NON-NLS-1$
+        sb.append(mSignature);
+        mName = sb.toString();
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    public String getClassName() {
+        return mClassName;
+    }
+
+    public String getMethodName() {
+        return mMethodName;
+    }
+
+    public String getProfileName() {
+        return mProfileName;
+    }
+
+    public void computeProfileName() {
+        if (mRank == -1) {
+            mProfileName = mName;
+            return;
+        }
+        
+        StringBuilder sb = new StringBuilder();
+        sb.append(mRank);
+        sb.append(" ");  //$NON-NLS-1$
+        sb.append(getName());
+        mProfileName = sb.toString();
+    }
+
+    public String getCalls() {
+        return String.format("%d+%d", mNumCalls[0], mNumCalls[1]);
+    }
+
+    public int getTotalCalls() {
+        return mNumCalls[0] + mNumCalls[1];
+    }
+
+    public Color getColor() {
+        return mColor;
+    }
+
+    public void setColor(Color color) {
+        mColor = color;
+    }
+
+    public void setImage(Image image) {
+        mImage = image;
+    }
+
+    public Image getImage() {
+        return mImage;
+    }
+
+    @Override
+    public String toString() {
+        return getName();
+    }
+
+    public long getElapsedExclusive() {
+        return mElapsedExclusive;
+    }
+
+    public long getElapsedInclusive() {
+        return mElapsedInclusive;
+    }
+
+    public void setFadedColor(Color fadedColor) {
+        mFadedColor = fadedColor;
+    }
+
+    public Color getFadedColor() {
+        return mFadedColor;
+    }
+
+    public void setFadedImage(Image fadedImage) {
+        mFadedImage = fadedImage;
+    }
+
+    public Image getFadedImage() {
+        return mFadedImage;
+    }
+
+    public void setPathname(String pathname) {
+        mPathname = pathname;
+    }
+
+    public String getPathname() {
+        return mPathname;
+    }
+
+    public void setLineNumber(int lineNumber) {
+        mLineNumber = lineNumber;
+    }
+
+    public int getLineNumber() {
+        return mLineNumber;
+    }
+
+    public ProfileNode[] getProfileNodes() {
+        return mProfileNodes;
+    }
+
+    public static class Sorter implements Comparator<MethodData> {
+        public int compare(MethodData md1, MethodData md2) {
+            if (mColumn == Column.BY_NAME) {
+                int result = md1.getName().compareTo(md2.getName());
+                return (mDirection == Direction.INCREASING) ? result : -result;
+            }
+            if (mColumn == Column.BY_INCLUSIVE) {
+                if (md2.getElapsedInclusive() > md1.getElapsedInclusive())
+                    return (mDirection == Direction.INCREASING) ? -1 : 1;
+                if (md2.getElapsedInclusive() < md1.getElapsedInclusive())
+                    return (mDirection == Direction.INCREASING) ? 1 : -1;
+                return md1.getName().compareTo(md2.getName());
+            }
+            if (mColumn == Column.BY_EXCLUSIVE) {
+                if (md2.getElapsedExclusive() > md1.getElapsedExclusive())
+                    return (mDirection == Direction.INCREASING) ? -1 : 1;
+                if (md2.getElapsedExclusive() < md1.getElapsedExclusive())
+                    return (mDirection == Direction.INCREASING) ? 1 : -1;
+                return md1.getName().compareTo(md2.getName());
+            }
+            if (mColumn == Column.BY_CALLS) {
+                int result = md1.getTotalCalls() - md2.getTotalCalls();
+                if (result == 0)
+                    return md1.getName().compareTo(md2.getName());
+                return (mDirection == Direction.INCREASING) ? result : -result;
+            }
+            if (mColumn == Column.BY_TIME_PER_CALL) {
+                double time1 = md1.getElapsedInclusive();
+                time1 = time1 / md1.getTotalCalls();
+                double time2 = md2.getElapsedInclusive();
+                time2 = time2 / md2.getTotalCalls();
+                double diff = time1 - time2;
+                int result = 0;
+                if (diff < 0)
+                    result = -1;
+                else if (diff > 0)
+                    result = 1;
+                if (result == 0)
+                    return md1.getName().compareTo(md2.getName());
+                return (mDirection == Direction.INCREASING) ? result : -result;
+            }
+            return 0;
+        }
+
+        public void setColumn(Column column) {
+            // If the sort column specified is the same as last time,
+            // then reverse the sort order.
+            if (mColumn == column) {
+                // Reverse the sort order
+                if (mDirection == Direction.INCREASING)
+                    mDirection = Direction.DECREASING;
+                else
+                    mDirection = Direction.INCREASING;
+            } else {
+                // Sort names into increasing order, data into decreasing order.
+                if (column == Column.BY_NAME)
+                    mDirection = Direction.INCREASING;
+                else
+                    mDirection = Direction.DECREASING;
+            }
+            mColumn = column;
+        }
+
+        public Column getColumn() {
+            return mColumn;
+        }
+
+        public void setDirection(Direction direction) {
+            mDirection = direction;
+        }
+
+        public Direction getDirection() {
+            return mDirection;
+        }
+
+        public static enum Column {
+            BY_NAME, BY_EXCLUSIVE, BY_INCLUSIVE, BY_CALLS, BY_TIME_PER_CALL
+        };
+
+        public static enum Direction {
+            INCREASING, DECREASING
+        };
+
+        private Column mColumn;
+        private Direction mDirection;
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/ProfileData.java b/tools/traceview/src/com/android/traceview/ProfileData.java
new file mode 100644
index 0000000..f0c1d61
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/ProfileData.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+
+public class ProfileData {
+
+    protected MethodData mElement;
+    
+    /** mContext is either the parent or child of mElement */
+    protected MethodData mContext;
+    protected boolean mElementIsParent;
+    protected long mElapsedInclusive;
+    protected int mNumCalls;
+
+    public ProfileData() {
+    }
+
+    public ProfileData(MethodData context, MethodData element,
+            boolean elementIsParent) {
+        mContext = context;
+        mElement = element;
+        mElementIsParent = elementIsParent;
+    }
+
+    public String getProfileName() {
+        return mElement.getProfileName();
+    }
+
+    public MethodData getMethodData() {
+        return mElement;
+    }
+
+    public void addElapsedInclusive(long elapsedInclusive) {
+        mElapsedInclusive += elapsedInclusive;
+        mNumCalls += 1;
+    }
+
+    public void setElapsedInclusive(long elapsedInclusive) {
+        mElapsedInclusive = elapsedInclusive;
+    }
+
+    public long getElapsedInclusive() {
+        return mElapsedInclusive;
+    }
+
+    public void setNumCalls(int numCalls) {
+        mNumCalls = numCalls;
+    }
+
+    public String getNumCalls() {
+        int totalCalls;
+        if (mElementIsParent)
+            totalCalls = mContext.getTotalCalls();
+        else
+            totalCalls = mElement.getTotalCalls();
+        return String.format("%d/%d", mNumCalls, totalCalls);
+    }
+
+    public boolean isParent() {
+        return mElementIsParent;
+    }
+
+    public MethodData getContext() {
+        return mContext;
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/ProfileNode.java b/tools/traceview/src/com/android/traceview/ProfileNode.java
new file mode 100644
index 0000000..7cb0b5d
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/ProfileNode.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+public class ProfileNode {
+
+    private String mLabel;
+    private MethodData mMethodData;
+    private ProfileData[] mChildren;
+    private boolean mIsParent;
+    private boolean mIsRecursive;
+
+    public ProfileNode(String label, MethodData methodData,
+            ProfileData[] children, boolean isParent, boolean isRecursive) {
+        mLabel = label;
+        mMethodData = methodData;
+        mChildren = children;
+        mIsParent = isParent;
+        mIsRecursive = isRecursive;
+    }
+
+    public String getLabel() {
+        return mLabel;
+    }
+    
+    public ProfileData[] getChildren() {
+        return mChildren;
+    }
+
+    public boolean isParent() {
+        return mIsParent;
+    }
+
+    public boolean isRecursive() {
+        return mIsRecursive;
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/ProfileProvider.java b/tools/traceview/src/com/android/traceview/ProfileProvider.java
new file mode 100644
index 0000000..fe5c832
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/ProfileProvider.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+
+class ProfileProvider implements ITreeContentProvider {
+
+    private MethodData[] mRoots;
+    private SelectionAdapter mListener;
+    private TreeViewer mTreeViewer;
+    private TraceReader mReader;
+    private Image mSortUp;
+    private Image mSortDown;
+    private String mColumnNames[] = { "Name", "Incl %", "Inclusive", "Excl %",
+            "Exclusive", "Calls+Recur\nCalls/Total", "Time/Call" };
+    private int mColumnWidths[] = { 370, 70, 70, 70, 70, 90, 70 };
+    private int mColumnAlignments[] = { SWT.LEFT, SWT.RIGHT, SWT.RIGHT,
+            SWT.RIGHT, SWT.RIGHT, SWT.CENTER, SWT.RIGHT };
+    private static final int COL_NAME = 0;
+    private static final int COL_INCLUSIVE_PER = 1;
+    private static final int COL_INCLUSIVE = 2;
+    private static final int COL_EXCLUSIVE_PER = 3;
+    private static final int COL_EXCLUSIVE = 4;
+    private static final int COL_CALLS = 5;
+    private static final int COL_TIME_PER_CALL = 6;
+    private long mTotalTime;
+    private Pattern mUppercase;
+    private int mPrevMatchIndex = -1;
+
+    public ProfileProvider(TraceReader reader) {
+        mRoots = reader.getMethods();
+        mReader = reader;
+        mTotalTime = reader.getEndTime();
+        Display display = Display.getCurrent();
+        InputStream in = getClass().getClassLoader().getResourceAsStream(
+                "icons/sort_up.png");
+        mSortUp = new Image(display, in);
+        in = getClass().getClassLoader().getResourceAsStream(
+                "icons/sort_down.png");
+        mSortDown = new Image(display, in);
+        mUppercase = Pattern.compile("[A-Z]");
+    }
+
+    private MethodData doMatchName(String name, int startIndex) {
+        // Check if the given "name" has any uppercase letters
+        boolean hasUpper = mUppercase.matcher(name).matches();
+        for (int ii = startIndex; ii < mRoots.length; ++ii) {
+            MethodData md = mRoots[ii];
+            String fullName = md.getName();
+            // If there were no upper case letters in the given name,
+            // then ignore case when matching.
+            if (!hasUpper)
+                fullName = fullName.toLowerCase();
+            if (fullName.indexOf(name) != -1) {
+                mPrevMatchIndex = ii;
+                return md;
+            }
+        }
+        mPrevMatchIndex = -1;
+        return null;
+    }
+
+    public MethodData findMatchingName(String name) {
+        return doMatchName(name, 0);
+    }
+
+    public MethodData findNextMatchingName(String name) {
+        return doMatchName(name, mPrevMatchIndex + 1);
+    }
+
+    public MethodData findMatchingTreeItem(TreeItem item) {
+        if (item == null)
+            return null;
+        String text = item.getText();
+        if (Character.isDigit(text.charAt(0)) == false)
+            return null;
+        int spaceIndex = text.indexOf(' ');
+        String numstr = text.substring(0, spaceIndex);
+        int rank = Integer.valueOf(numstr);
+        for (MethodData md : mRoots) {
+            if (md.getRank() == rank)
+                return md;
+        }
+        return null;
+    }
+
+    public void setTreeViewer(TreeViewer treeViewer) {
+        mTreeViewer = treeViewer;
+    }
+
+    public String[] getColumnNames() {
+        return mColumnNames;
+    }
+
+    public int[] getColumnWidths() {
+        return mColumnWidths;
+    }
+
+    public int[] getColumnAlignments() {
+        return mColumnAlignments;
+    }
+
+    public Object[] getChildren(Object element) {
+        if (element instanceof MethodData) {
+            MethodData md = (MethodData) element;
+            return md.getProfileNodes();
+        }
+        if (element instanceof ProfileNode) {
+            ProfileNode pn = (ProfileNode) element;
+            return pn.getChildren();
+        }
+        return new Object[0];
+    }
+
+    public Object getParent(Object element) {
+        return null;
+    }
+
+    public boolean hasChildren(Object element) {
+        if (element instanceof MethodData)
+            return true;
+        if (element instanceof ProfileNode)
+            return true;
+        return false;
+    }
+
+    public Object[] getElements(Object element) {
+        return mRoots;
+    }
+
+    public void dispose() {
+    }
+
+    public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
+    }
+
+    public Object getRoot() {
+        return "root";
+    }
+
+    public SelectionAdapter getColumnListener() {
+        if (mListener == null)
+            mListener = new ColumnListener();
+        return mListener;
+    }
+
+    public LabelProvider getLabelProvider() {
+        return new ProfileLabelProvider();
+    }
+
+    class ProfileLabelProvider extends LabelProvider implements
+            ITableLabelProvider, IColorProvider {
+        Color colorRed;
+        Color colorParentsBack;
+        Color colorChildrenBack;
+        TraceUnits traceUnits;
+
+        public ProfileLabelProvider() {
+            Display display = Display.getCurrent();
+            colorRed = display.getSystemColor(SWT.COLOR_RED);
+            colorParentsBack = new Color(display, 230, 230, 255); // blue
+            colorChildrenBack = new Color(display, 255, 255, 210); // yellow
+            traceUnits = mReader.getTraceUnits();
+        }
+
+        public String getColumnText(Object element, int col) {
+            if (element instanceof MethodData) {
+                MethodData md = (MethodData) element;
+                if (col == COL_NAME)
+                    return md.getProfileName();
+                if (col == COL_EXCLUSIVE) {
+                    double val = md.getElapsedExclusive();
+                    val = traceUnits.getScaledValue(val);
+                    return String.format("%.3f", val);
+                }
+                if (col == COL_EXCLUSIVE_PER) {
+                    double val = md.getElapsedExclusive();
+                    double per = val * 100.0 / mTotalTime;
+                    return String.format("%.1f%%", per);
+                }
+                if (col == COL_INCLUSIVE) {
+                    double val = md.getElapsedInclusive();
+                    val = traceUnits.getScaledValue(val);
+                    return String.format("%.3f", val);
+                }
+                if (col == COL_INCLUSIVE_PER) {
+                    double val = md.getElapsedInclusive();
+                    double per = val * 100.0 / mTotalTime;
+                    return String.format("%.1f%%", per);
+                }
+                if (col == COL_CALLS)
+                    return md.getCalls();
+                if (col == COL_TIME_PER_CALL) {
+                    int numCalls = md.getTotalCalls();
+                    double val = md.getElapsedInclusive();
+                    val = val / numCalls;
+                    val = traceUnits.getScaledValue(val);
+                    return String.format("%.3f", val);
+                }
+            } else if (element instanceof ProfileSelf) {
+                ProfileSelf ps = (ProfileSelf) element;
+                if (col == COL_NAME)
+                    return ps.getProfileName();
+                if (col == COL_INCLUSIVE) {
+                    double val = ps.getElapsedInclusive();
+                    val = traceUnits.getScaledValue(val);
+                    return String.format("%.3f", val);
+                }
+                if (col == COL_INCLUSIVE_PER) {
+                    double total;
+                    double val = ps.getElapsedInclusive();
+                    MethodData context = ps.getContext();
+                    total = context.getElapsedInclusive();
+                    double per = val * 100.0 / total;
+                    return String.format("%.1f%%", per);
+                }
+                return "";
+            } else if (element instanceof ProfileData) {
+                ProfileData pd = (ProfileData) element;
+                if (col == COL_NAME)
+                    return pd.getProfileName();
+                if (col == COL_INCLUSIVE) {
+                    double val = pd.getElapsedInclusive();
+                    val = traceUnits.getScaledValue(val);
+                    return String.format("%.3f", val);
+                }
+                if (col == COL_INCLUSIVE_PER) {
+                    double total;
+                    double val = pd.getElapsedInclusive();
+                    MethodData context = pd.getContext();
+                    total = context.getElapsedInclusive();
+                    double per = val * 100.0 / total;
+                    return String.format("%.1f%%", per);
+                }
+                if (col == COL_CALLS)
+                    return pd.getNumCalls();
+                return "";
+            } else if (element instanceof ProfileNode) {
+                ProfileNode pn = (ProfileNode) element;
+                if (col == COL_NAME)
+                    return pn.getLabel();
+                return "";
+            }
+            return "col" + col;
+        }
+
+        public Image getColumnImage(Object element, int col) {
+            if (col != COL_NAME)
+                return null;
+            if (element instanceof MethodData) {
+                MethodData md = (MethodData) element;
+                return md.getImage();
+            }
+            if (element instanceof ProfileData) {
+                ProfileData pd = (ProfileData) element;
+                MethodData md = pd.getMethodData();
+                return md.getImage();
+            }
+            return null;
+        }
+
+        public Color getForeground(Object element) {
+            return null;
+        }
+
+        public Color getBackground(Object element) {
+            if (element instanceof ProfileData) {
+                ProfileData pd = (ProfileData) element;
+                if (pd.isParent())
+                    return colorParentsBack;
+                return colorChildrenBack;
+            }
+            if (element instanceof ProfileNode) {
+                ProfileNode pn = (ProfileNode) element;
+                if (pn.isParent())
+                    return colorParentsBack;
+                return colorChildrenBack;
+            }
+            return null;
+        }
+    }
+
+    class ColumnListener extends SelectionAdapter {
+        MethodData.Sorter sorter = new MethodData.Sorter();
+
+        @Override
+        public void widgetSelected(SelectionEvent event) {
+            TreeColumn column = (TreeColumn) event.widget;
+            String name = column.getText();
+            Tree tree = column.getParent();
+            tree.setRedraw(false);
+            TreeColumn[] columns = tree.getColumns();
+            for (TreeColumn col : columns) {
+                col.setImage(null);
+            }
+            if (name == mColumnNames[COL_NAME]) {
+                // Sort names alphabetically
+                sorter.setColumn(MethodData.Sorter.Column.BY_NAME);
+                Arrays.sort(mRoots, sorter);
+            } else if (name == mColumnNames[COL_EXCLUSIVE]) {
+                sorter.setColumn(MethodData.Sorter.Column.BY_EXCLUSIVE);
+                Arrays.sort(mRoots, sorter);
+            } else if (name == mColumnNames[COL_EXCLUSIVE_PER]) {
+                sorter.setColumn(MethodData.Sorter.Column.BY_EXCLUSIVE);
+                Arrays.sort(mRoots, sorter);
+            } else if (name == mColumnNames[COL_INCLUSIVE]) {
+                sorter.setColumn(MethodData.Sorter.Column.BY_INCLUSIVE);
+                Arrays.sort(mRoots, sorter);
+            } else if (name == mColumnNames[COL_INCLUSIVE_PER]) {
+                sorter.setColumn(MethodData.Sorter.Column.BY_INCLUSIVE);
+                Arrays.sort(mRoots, sorter);
+            } else if (name == mColumnNames[COL_CALLS]) {
+                sorter.setColumn(MethodData.Sorter.Column.BY_CALLS);
+                Arrays.sort(mRoots, sorter);
+            } else if (name == mColumnNames[COL_TIME_PER_CALL]) {
+                sorter.setColumn(MethodData.Sorter.Column.BY_TIME_PER_CALL);
+                Arrays.sort(mRoots, sorter);
+            }
+            MethodData.Sorter.Direction direction = sorter.getDirection();
+            if (direction == MethodData.Sorter.Direction.INCREASING)
+                column.setImage(mSortDown);
+            else
+                column.setImage(mSortUp);
+            tree.setRedraw(true);
+            mTreeViewer.refresh();
+        }
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/ProfileSelf.java b/tools/traceview/src/com/android/traceview/ProfileSelf.java
new file mode 100644
index 0000000..3a4f3d9
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/ProfileSelf.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+public class ProfileSelf extends ProfileData {
+    public ProfileSelf(MethodData methodData) {
+        mElement = methodData;
+        mContext = methodData;
+    }
+
+    @Override
+    public String getProfileName() {
+        return "self";
+    }
+
+    @Override
+    public long getElapsedInclusive() {
+        return mElement.getTopExclusive();
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/ProfileView.java b/tools/traceview/src/com/android/traceview/ProfileView.java
new file mode 100644
index 0000000..e48cb56
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/ProfileView.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+import java.util.ArrayList;
+import java.util.Observable;
+import java.util.Observer;
+
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeViewerListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeExpansionEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+
+public class ProfileView extends Composite implements Observer {
+    
+    private TreeViewer mTreeViewer;
+    private Text mSearchBox;
+    private SelectionController mSelectionController;
+    private ProfileProvider mProfileProvider;
+    private Color mColorNoMatch;
+    private Color mColorMatch;
+    private MethodData mCurrentHighlightedMethod;
+
+    public ProfileView(Composite parent, TraceReader reader,
+            SelectionController selectController) {
+        super(parent, SWT.NONE);
+        setLayout(new GridLayout(1, false));
+        this.mSelectionController = selectController;
+        mSelectionController.addObserver(this);
+
+        // Add a tree viewer at the top
+        mTreeViewer = new TreeViewer(this, SWT.MULTI | SWT.NONE);
+        mTreeViewer.setUseHashlookup(true);
+        mProfileProvider = reader.getProfileProvider();
+        mProfileProvider.setTreeViewer(mTreeViewer);
+        SelectionAdapter listener = mProfileProvider.getColumnListener();
+        final Tree tree = mTreeViewer.getTree();
+        tree.setHeaderVisible(true);
+        tree.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+        // Get the column names from the ProfileProvider
+        String[] columnNames = mProfileProvider.getColumnNames();
+        int[] columnWidths = mProfileProvider.getColumnWidths();
+        int[] columnAlignments = mProfileProvider.getColumnAlignments();
+        for (int ii = 0; ii < columnWidths.length; ++ii) {
+            TreeColumn column = new TreeColumn(tree, SWT.LEFT);
+            column.setText(columnNames[ii]);
+            column.setWidth(columnWidths[ii]);
+            column.setMoveable(true);
+            column.addSelectionListener(listener);
+            column.setAlignment(columnAlignments[ii]);
+        }
+
+        // Add a listener to the tree so that we can make the row
+        // height smaller.
+        tree.addListener(SWT.MeasureItem, new Listener() {
+            public void handleEvent(Event event) {
+                int fontHeight = event.gc.getFontMetrics().getHeight();
+                event.height = fontHeight;
+            }
+        });
+
+        mTreeViewer.setContentProvider(mProfileProvider);
+        mTreeViewer.setLabelProvider(mProfileProvider.getLabelProvider());
+        mTreeViewer.setInput(mProfileProvider.getRoot());
+
+        // Create another composite to hold the label and text box
+        Composite composite = new Composite(this, SWT.NONE);
+        composite.setLayout(new GridLayout(2, false));
+        composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        // Add a label for the search box
+        Label label = new Label(composite, SWT.NONE);
+        label.setText("Find:");
+
+        // Add a text box for searching for method names
+        mSearchBox = new Text(composite, SWT.BORDER);
+        mSearchBox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        Display display = getDisplay();
+        mColorNoMatch = new Color(display, 255, 200, 200);
+        mColorMatch = mSearchBox.getBackground();
+
+        mSearchBox.addModifyListener(new ModifyListener() {
+            public void modifyText(ModifyEvent ev) {
+                String query = mSearchBox.getText();
+                if (query.length() == 0)
+                    return;
+                findName(query);
+            }
+        });
+
+        // Add a key listener to the text box so that we can clear
+        // the text box if the user presses <ESC>.
+        mSearchBox.addKeyListener(new KeyAdapter() {
+            @Override
+            public void keyPressed(KeyEvent event) {
+                if (event.keyCode == SWT.ESC) {
+                    mSearchBox.setText("");
+                } else if (event.keyCode == SWT.CR) {
+                    String query = mSearchBox.getText();
+                    if (query.length() == 0)
+                        return;
+                    findNextName(query);
+                }
+            }
+        });
+
+        // Also add a key listener to the tree viewer so that the
+        // user can just start typing anywhere in the tree view.
+        tree.addKeyListener(new KeyAdapter() {
+            @Override
+            public void keyPressed(KeyEvent event) {
+                if (event.keyCode == SWT.ESC) {
+                    mSearchBox.setText("");
+                } else if (event.keyCode == SWT.BS) {
+                    // Erase the last character from the search box
+                    String text = mSearchBox.getText();
+                    int len = text.length();
+                    String chopped;
+                    if (len <= 1)
+                        chopped = "";
+                    else
+                        chopped = text.substring(0, len - 1);
+                    mSearchBox.setText(chopped);
+                } else if (event.keyCode == SWT.CR) {
+                    String query = mSearchBox.getText();
+                    if (query.length() == 0)
+                        return;
+                    findNextName(query);
+                } else {
+                    // Append the given character to the search box
+                    String str = String.valueOf(event.character);
+                    mSearchBox.append(str);
+                }
+                event.doit = false;
+            }
+        });
+
+        // Add a selection listener to the tree so that the user can click
+        // on a method that is a child or parent and jump to that method.
+        mTreeViewer
+                .addSelectionChangedListener(new ISelectionChangedListener() {
+                    public void selectionChanged(SelectionChangedEvent ev) {
+                        ISelection sel = ev.getSelection();
+                        if (sel.isEmpty())
+                            return;
+                        if (sel instanceof IStructuredSelection) {
+                            IStructuredSelection selection = (IStructuredSelection) sel;
+                            Object element = selection.getFirstElement();
+                            if (element == null)
+                                return;
+                            if (element instanceof MethodData) {
+                                MethodData md = (MethodData) element;
+                                highlightMethod(md, true);
+                            }
+                            if (element instanceof ProfileData) {
+                                MethodData md = ((ProfileData) element)
+                                        .getMethodData();
+                                highlightMethod(md, true);
+                            }
+                        }
+                    }
+                });
+        
+        // Add a tree listener so that we can expand the parents and children
+        // of a method when a method is expanded.
+        mTreeViewer.addTreeListener(new ITreeViewerListener() {
+            public void treeExpanded(TreeExpansionEvent event) {
+                Object element = event.getElement();
+                if (element instanceof MethodData) {
+                    MethodData md = (MethodData) element;
+                    expandNode(md);
+                }
+            }
+            public void treeCollapsed(TreeExpansionEvent event) {
+            }
+        });
+
+        tree.addListener(SWT.MouseDown, new Listener() {
+            public void handleEvent(Event event) {
+                Point point = new Point(event.x, event.y);
+                TreeItem treeItem = tree.getItem(point);
+                MethodData md = mProfileProvider.findMatchingTreeItem(treeItem);
+                if (md == null)
+                    return;
+                ArrayList<Selection> selections = new ArrayList<Selection>();
+                selections.add(Selection.highlight("MethodData", md));
+                mSelectionController.change(selections, "ProfileView");
+            }
+        });
+    }
+
+    private void findName(String query) {
+        MethodData md = mProfileProvider.findMatchingName(query);
+        selectMethod(md);
+    }
+
+    private void findNextName(String query) {
+        MethodData md = mProfileProvider.findNextMatchingName(query);
+        selectMethod(md);
+    }
+
+    private void selectMethod(MethodData md) {
+        if (md == null) {
+            mSearchBox.setBackground(mColorNoMatch);
+            return;
+        }
+        mSearchBox.setBackground(mColorMatch);
+        highlightMethod(md, false);
+    }
+
+    public void update(Observable objservable, Object arg) {
+        // Ignore updates from myself
+        if (arg == "ProfileView")
+            return;
+        // System.out.printf("profileview update from %s\n", arg);
+        ArrayList<Selection> selections;
+        selections = mSelectionController.getSelections();
+        for (Selection selection : selections) {
+            Selection.Action action = selection.getAction();
+            if (action != Selection.Action.Highlight)
+                continue;
+            String name = selection.getName();
+            if (name == "MethodData") {
+                MethodData md = (MethodData) selection.getValue();
+                highlightMethod(md, true);
+                return;
+            }
+            if (name == "Call") {
+                Call call = (Call) selection.getValue();
+                MethodData md = call.mMethodData;
+                highlightMethod(md, true);
+                return;
+            }
+        }
+    }
+
+    private void highlightMethod(MethodData md, boolean clearSearch) {
+        if (md == null)
+            return;
+        // Avoid an infinite recursion
+        if (md == mCurrentHighlightedMethod)
+            return;
+        if (clearSearch) {
+            mSearchBox.setText("");
+            mSearchBox.setBackground(mColorMatch);
+        }
+        mCurrentHighlightedMethod = md;
+        mTreeViewer.collapseAll();
+        // Expand this node and its children
+        expandNode(md);
+        StructuredSelection sel = new StructuredSelection(md);
+        mTreeViewer.setSelection(sel, true);
+        Tree tree = mTreeViewer.getTree();
+        TreeItem[] items = tree.getSelection();
+        tree.setTopItem(items[0]);
+        // workaround a Mac bug by adding showItem().
+        tree.showItem(items[0]);
+    }
+
+    private void expandNode(MethodData md) {
+        ProfileNode[] nodes = md.getProfileNodes();
+        mTreeViewer.setExpandedState(md, true);
+        // Also expand the "Parents" and "Children" nodes.
+        for (ProfileNode node : nodes) {
+            if (node.isRecursive() == false)
+                mTreeViewer.setExpandedState(node, true);
+        }
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/QtraceReader.java b/tools/traceview/src/com/android/traceview/QtraceReader.java
new file mode 100644
index 0000000..c4db4a2
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/QtraceReader.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class QtraceReader extends TraceReader {
+    QtraceReader(String traceName) {
+    }
+
+    @Override
+    public MethodData[] getMethods() {
+        return null;
+    }
+
+    @Override
+    public HashMap<Integer, String> getThreadLabels() {
+        return null;
+    }
+
+    @Override
+    public ArrayList<TimeLineView.Record> getThreadTimeRecords() {
+        return null;
+    }
+
+    @Override
+    public ProfileProvider getProfileProvider() {
+        return null;
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/Selection.java b/tools/traceview/src/com/android/traceview/Selection.java
new file mode 100644
index 0000000..3764619
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/Selection.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+public class Selection {
+
+    private Action mAction;
+    private String mName;
+    private Object mValue;
+
+    public Selection(Action action, String name, Object value) {
+        mAction = action;
+        mName = name;
+        mValue = value;
+    }
+
+    public static Selection highlight(String name, Object value) {
+        return new Selection(Action.Highlight, name, value);
+    }
+
+    public static Selection include(String name, Object value) {
+        return new Selection(Action.Include, name, value);
+    }
+
+    public static Selection exclude(String name, Object value) {
+        return new Selection(Action.Exclude, name, value);
+    }
+
+    public void setName(String name) {
+        mName = name;
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    public void setValue(Object value) {
+        mValue = value;
+    }
+
+    public Object getValue() {
+        return mValue;
+    }
+
+    public void setAction(Action action) {
+        mAction = action;
+    }
+
+    public Action getAction() {
+        return mAction;
+    }
+
+    public static enum Action {
+        Highlight, Include, Exclude, Aggregate
+    };
+}
diff --git a/tools/traceview/src/com/android/traceview/SelectionController.java b/tools/traceview/src/com/android/traceview/SelectionController.java
new file mode 100644
index 0000000..4c930ea
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/SelectionController.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+import java.util.ArrayList;
+import java.util.Observable;
+
+public class SelectionController extends Observable {
+
+    private ArrayList<Selection> mSelections;
+
+    public void change(ArrayList<Selection> selections, Object arg) {
+        this.mSelections = selections;
+        setChanged();
+        notifyObservers(arg);
+    }
+
+    public ArrayList<Selection> getSelections() {
+        return mSelections;
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/ThreadData.java b/tools/traceview/src/com/android/traceview/ThreadData.java
new file mode 100644
index 0000000..54ea891
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/ThreadData.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+class ThreadData implements TimeLineView.Row {
+
+    private int mId;
+    private String mName;
+    private long mGlobalStartTime = -1;
+    private long mGlobalEndTime = -1;
+    private long mLastEventTime;
+    private long mCpuTime;
+    private Call mRoot;
+    private Call mCurrent;
+    private Call mLastContextSwitch;
+    private ArrayList<Call> mStack = new ArrayList<Call>();
+    
+    // This is a hash of all the methods that are currently on the stack.
+    private HashMap<MethodData, Integer> mStackMethods = new HashMap<MethodData, Integer>();
+    
+    // True if no calls have ever been added to this thread
+    private boolean mIsEmpty;
+
+    ThreadData(int id, String name, MethodData topLevel) {
+        mId = id;
+        mName = String.format("[%d] %s", id, name);
+        mRoot = new Call(mName, topLevel);
+        mCurrent = mRoot;
+        mIsEmpty = true;
+    }
+
+    public boolean isEmpty() {
+        return mIsEmpty;
+    }
+
+    public String getName() {
+        return mName;
+    }
+
+    public Call getCalltreeRoot() {
+        return mRoot;
+    }
+
+    void handleCall(Call call, long globalTime) {
+        mIsEmpty = false;
+        long currentTime = call.mThreadStartTime;
+        if (currentTime < mLastEventTime) {
+            System.err
+            .printf(
+                    "ThreadData: '%1$s' call time (%2$d) is less than previous time (%3$d) for thread '%4$s'\n",
+                    call.getName(), currentTime, mLastEventTime, mName);
+            System.exit(1);
+        }
+        long elapsed = currentTime - mLastEventTime;
+        mCpuTime += elapsed;
+        if (call.getMethodAction() == 0) {
+            // This is a method entry.
+            enter(call, elapsed);
+        } else {
+            // This is a method exit.
+            exit(call, elapsed, globalTime);
+        }
+        mLastEventTime = currentTime;
+        mGlobalEndTime = globalTime;
+    }
+
+    private void enter(Call c, long elapsed) {
+        Call caller = mCurrent;
+        push(c);
+        
+        // Check the stack for a matching method to determine if this call
+        // is recursive.
+        MethodData md = c.mMethodData;
+        Integer num = mStackMethods.get(md);
+        if (num == null) {
+            num = 0;
+        } else if (num > 0) {
+            c.setRecursive(true);
+        }
+        num += 1;
+        mStackMethods.put(md, num);
+        mCurrent = c;
+
+        // Add the elapsed time to the caller's exclusive time
+        caller.addExclusiveTime(elapsed);
+    }
+
+    private void exit(Call c, long elapsed, long globalTime) {
+        mCurrent.mGlobalEndTime = globalTime;
+        Call top = pop();
+        if (top == null) {
+            return;
+        }
+
+        if (mCurrent.mMethodData != c.mMethodData) {
+            String error = "Method exit (" + c.getName()
+                    + ") does not match current method (" + mCurrent.getName()
+                    + ")";
+            throw new RuntimeException(error);
+        } else {
+            long duration = c.mThreadStartTime - mCurrent.mThreadStartTime;
+            Call caller = top();
+            mCurrent.addExclusiveTime(elapsed);
+            mCurrent.addInclusiveTime(duration, caller);
+            if (caller == null) {
+                caller = mRoot;
+            }
+            mCurrent = caller;
+        }
+    }
+
+    public void push(Call c) {
+        mStack.add(c);
+    }
+
+    public Call pop() {
+        ArrayList<Call> stack = mStack;
+        if (stack.size() == 0)
+            return null;
+        Call top = stack.get(stack.size() - 1);
+        stack.remove(stack.size() - 1);
+        
+        // Decrement the count on the method in the hash table and remove
+        // the entry when it goes to zero.
+        MethodData md = top.mMethodData;
+        Integer num = mStackMethods.get(md);
+        if (num != null) {
+            num -= 1;
+            if (num <= 0) {
+                mStackMethods.remove(md);
+            } else {
+                mStackMethods.put(md, num);
+            }
+        }
+        return top;
+    }
+
+    public Call top() {
+        ArrayList<Call> stack = mStack;
+        if (stack.size() == 0)
+            return null;
+        return stack.get(stack.size() - 1);
+    }
+
+    public long endTrace() {
+        // If we have calls on the stack when the trace ends, then clean up
+        // the stack and compute the inclusive time of the methods by pretending
+        // that we are exiting from their methods now.
+        while (mCurrent != mRoot) {
+            long duration = mLastEventTime - mCurrent.mThreadStartTime;
+            pop();
+            Call caller = top();
+            mCurrent.addInclusiveTime(duration, caller);
+            mCurrent.mGlobalEndTime = mGlobalEndTime;
+            if (caller == null) {
+                caller = mRoot;
+            }
+            mCurrent = caller;
+        }
+        return mLastEventTime;
+    }
+
+    @Override
+    public String toString() {
+        return mName;
+    }
+
+    public int getId() {
+        return mId;
+    }
+
+    public void setCpuTime(long cpuTime) {
+        mCpuTime = cpuTime;
+    }
+
+    public long getCpuTime() {
+        return mCpuTime;
+    }
+
+    public void setGlobalStartTime(long globalStartTime) {
+        mGlobalStartTime = globalStartTime;
+    }
+
+    public long getGlobalStartTime() {
+        return mGlobalStartTime;
+    }
+
+    public void setLastEventTime(long lastEventTime) {
+        mLastEventTime = lastEventTime;
+    }
+
+    public long getLastEventTime() {
+        return mLastEventTime;
+    }
+
+    public void setGlobalEndTime(long globalEndTime) {
+        mGlobalEndTime = globalEndTime;
+    }
+
+    public long getGlobalEndTime() {
+        return mGlobalEndTime;
+    }
+
+    public void setLastContextSwitch(Call lastContextSwitch) {
+        mLastContextSwitch = lastContextSwitch;
+    }
+
+    public Call getLastContextSwitch() {
+        return mLastContextSwitch;
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/TickScaler.java b/tools/traceview/src/com/android/traceview/TickScaler.java
new file mode 100644
index 0000000..79fa160
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/TickScaler.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+class TickScaler {
+
+    private double mMinVal; // required input
+    private double mMaxVal; // required input
+    private double mRangeVal;
+    private int mNumPixels; // required input
+    private int mPixelsPerTick; // required input
+    private double mPixelsPerRange;
+    private double mTickIncrement;
+    private double mMinMajorTick;
+
+    TickScaler(double minVal, double maxVal, int numPixels, int pixelsPerTick) {
+        mMinVal = minVal;
+        mMaxVal = maxVal;
+        mNumPixels = numPixels;
+        mPixelsPerTick = pixelsPerTick;
+    }
+
+    public void setMinVal(double minVal) {
+        mMinVal = minVal;
+    }
+
+    public double getMinVal() {
+        return mMinVal;
+    }
+
+    public void setMaxVal(double maxVal) {
+        mMaxVal = maxVal;
+    }
+
+    public double getMaxVal() {
+        return mMaxVal;
+    }
+
+    public void setNumPixels(int numPixels) {
+        mNumPixels = numPixels;
+    }
+
+    public int getNumPixels() {
+        return mNumPixels;
+    }
+
+    public void setPixelsPerTick(int pixelsPerTick) {
+        mPixelsPerTick = pixelsPerTick;
+    }
+
+    public int getPixelsPerTick() {
+        return mPixelsPerTick;
+    }
+
+    public void setPixelsPerRange(double pixelsPerRange) {
+        mPixelsPerRange = pixelsPerRange;
+    }
+
+    public double getPixelsPerRange() {
+        return mPixelsPerRange;
+    }
+
+    public void setTickIncrement(double tickIncrement) {
+        mTickIncrement = tickIncrement;
+    }
+
+    public double getTickIncrement() {
+        return mTickIncrement;
+    }
+
+    public void setMinMajorTick(double minMajorTick) {
+        mMinMajorTick = minMajorTick;
+    }
+
+    public double getMinMajorTick() {
+        return mMinMajorTick;
+    }
+
+    // Convert a time value to a 0-based pixel value
+    public int valueToPixel(double value) {
+        return (int) Math.ceil(mPixelsPerRange * (value - mMinVal) - 0.5);
+    }
+
+    // Convert a time value to a 0-based fractional pixel
+    public double valueToPixelFraction(double value) {
+        return mPixelsPerRange * (value - mMinVal);
+    }
+
+    // Convert a 0-based pixel value to a time value
+    public double pixelToValue(int pixel) {
+        return mMinVal + (pixel / mPixelsPerRange);
+    }
+
+    public void computeTicks(boolean useGivenEndPoints) {
+        int numTicks = mNumPixels / mPixelsPerTick;
+        mRangeVal = mMaxVal - mMinVal;
+        mTickIncrement = mRangeVal / numTicks;
+        double dlogTickIncrement = Math.log10(mTickIncrement);
+        int logTickIncrement = (int) Math.floor(dlogTickIncrement);
+        double scale = Math.pow(10, logTickIncrement);
+        double scaledTickIncr = mTickIncrement / scale;
+        if (scaledTickIncr > 5.0)
+            scaledTickIncr = 10;
+        else if (scaledTickIncr > 2)
+            scaledTickIncr = 5;
+        else if (scaledTickIncr > 1)
+            scaledTickIncr = 2;
+        else
+            scaledTickIncr = 1;
+        mTickIncrement = scaledTickIncr * scale;
+
+        if (!useGivenEndPoints) {
+            // Round up the max val to the next minor tick
+            double minorTickIncrement = mTickIncrement / 5;
+            double dval = mMaxVal / minorTickIncrement;
+            int ival = (int) dval;
+            if (ival != dval)
+                mMaxVal = (ival + 1) * minorTickIncrement;
+
+            // Round down the min val to a multiple of tickIncrement
+            ival = (int) (mMinVal / mTickIncrement);
+            mMinVal = ival * mTickIncrement;
+            mMinMajorTick = mMinVal;
+        } else {
+            int ival = (int) (mMinVal / mTickIncrement);
+            mMinMajorTick = ival * mTickIncrement;
+            if (mMinMajorTick < mMinVal)
+                mMinMajorTick = mMinMajorTick + mTickIncrement;
+        }
+
+        mRangeVal = mMaxVal - mMinVal;
+        mPixelsPerRange = (double) mNumPixels / mRangeVal;
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/TimeLineView.java b/tools/traceview/src/com/android/traceview/TimeLineView.java
new file mode 100644
index 0000000..67dc97b
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/TimeLineView.java
@@ -0,0 +1,1961 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+import org.eclipse.jface.resource.FontRegistry;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Cursor;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.ScrollBar;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Observable;
+import java.util.Observer;
+
+public class TimeLineView extends Composite implements Observer {
+
+    private HashMap<String, RowData> mRowByName;
+    private double mTotalElapsed;
+    private RowData[] mRows;
+    private Segment[] mSegments;
+    private ArrayList<Segment> mSegmentList = new ArrayList<Segment>();
+    private HashMap<Integer, String> mThreadLabels;
+    private Timescale mTimescale;
+    private Surface mSurface;
+    private RowLabels mLabels;
+    private SashForm mSashForm;
+    private int mScrollOffsetY;
+
+    public static final int PixelsPerTick = 50;
+    private TickScaler mScaleInfo = new TickScaler(0, 0, 0, PixelsPerTick);
+    private static final int LeftMargin = 10; // blank space on left
+    private static final int RightMargin = 60; // blank space on right
+
+    private Color mColorBlack;
+    private Color mColorGray;
+    private Color mColorDarkGray;
+    private Color mColorForeground;
+    private Color mColorRowBack;
+    private Color mColorZoomSelection;
+    private FontRegistry mFontRegistry;
+
+    /** vertical height of drawn blocks in each row */
+    private static final int rowHeight = 20;
+
+    /** the blank space between rows */
+    private static final int rowYMargin = 12;
+    private static final int rowYMarginHalf = rowYMargin / 2;
+
+    /** total vertical space for row */
+    private static final int rowYSpace = rowHeight + rowYMargin;
+    private static final int majorTickLength = 8;
+    private static final int minorTickLength = 4;
+    private static final int timeLineOffsetY = 38;
+    private static final int tickToFontSpacing = 2;
+
+    /** start of first row */
+    private static final int topMargin = 70;
+    private int mMouseRow = -1;
+    private int mNumRows;
+    private int mStartRow;
+    private int mEndRow;
+    private TraceUnits mUnits;
+    private int mSmallFontWidth;
+    private int mSmallFontHeight;
+    private int mMediumFontWidth;
+    private SelectionController mSelectionController;
+    private MethodData mHighlightMethodData;
+    private Call mHighlightCall;
+    private static final int MinInclusiveRange = 3;
+
+    /** Setting the fonts looks good on Linux but bad on Macs */
+    private boolean mSetFonts = false;
+
+    public static interface Block {
+        public String getName();
+        public MethodData getMethodData();
+        public long getStartTime();
+        public long getEndTime();
+        public Color getColor();
+        public double addWeight(int x, int y, double weight);
+        public void clearWeight();
+    }
+
+    public static interface Row {
+        public int getId();
+        public String getName();
+    }
+
+    public static class Record {
+        Row row;
+        Block block;
+
+        public Record(Row row, Block block) {
+            this.row = row;
+            this.block = block;
+        }
+    }
+
+    public TimeLineView(Composite parent, TraceReader reader,
+            SelectionController selectionController) {
+        super(parent, SWT.NONE);
+        mRowByName = new HashMap<String, RowData>();
+        this.mSelectionController = selectionController;
+        selectionController.addObserver(this);
+        mUnits = reader.getTraceUnits();
+        mThreadLabels = reader.getThreadLabels();
+
+        Display display = getDisplay();
+        mColorGray = display.getSystemColor(SWT.COLOR_GRAY);
+        mColorDarkGray = display.getSystemColor(SWT.COLOR_DARK_GRAY);
+        mColorBlack = display.getSystemColor(SWT.COLOR_BLACK);
+        // mColorBackground = display.getSystemColor(SWT.COLOR_WHITE);
+        mColorForeground = display.getSystemColor(SWT.COLOR_BLACK);
+        mColorRowBack = new Color(display, 240, 240, 255);
+        mColorZoomSelection = new Color(display, 230, 230, 230);
+
+        mFontRegistry = new FontRegistry(display);
+        mFontRegistry.put("small",  // $NON-NLS-1$
+                new FontData[] { new FontData("Arial", 8, SWT.NORMAL) });  // $NON-NLS-1$
+        mFontRegistry.put("courier8",  // $NON-NLS-1$
+                new FontData[] { new FontData("Courier New", 8, SWT.BOLD) });  // $NON-NLS-1$
+        mFontRegistry.put("medium",  // $NON-NLS-1$
+                new FontData[] { new FontData("Courier New", 10, SWT.NORMAL) });  // $NON-NLS-1$
+
+        Image image = new Image(display, new Rectangle(100, 100, 100, 100));
+        GC gc = new GC(image);
+        if (mSetFonts) {
+            gc.setFont(mFontRegistry.get("small"));  // $NON-NLS-1$
+        }
+        mSmallFontWidth = gc.getFontMetrics().getAverageCharWidth();
+        mSmallFontHeight = gc.getFontMetrics().getHeight();
+
+        if (mSetFonts) {
+            gc.setFont(mFontRegistry.get("medium"));  // $NON-NLS-1$
+        }
+        mMediumFontWidth = gc.getFontMetrics().getAverageCharWidth();
+
+        image.dispose();
+        gc.dispose();
+
+        setLayout(new FillLayout());
+
+        // Create a sash form for holding two canvas views, one for the
+        // thread labels and one for the thread timeline.
+        mSashForm = new SashForm(this, SWT.HORIZONTAL);
+        mSashForm.setBackground(mColorGray);
+        mSashForm.SASH_WIDTH = 3;
+
+        // Create a composite for the left side of the sash
+        Composite composite = new Composite(mSashForm, SWT.NONE);
+        GridLayout layout = new GridLayout(1, true /* make columns equal width */);
+        layout.marginHeight = 0;
+        layout.marginWidth = 0;
+        layout.verticalSpacing = 1;
+        composite.setLayout(layout);
+        
+        // Create a blank corner space in the upper left corner
+        BlankCorner corner = new BlankCorner(composite);
+        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+        gridData.heightHint = topMargin;
+        corner.setLayoutData(gridData);
+        
+        // Add the thread labels below the blank corner.
+        mLabels = new RowLabels(composite);
+        gridData = new GridData(GridData.FILL_BOTH);
+        mLabels.setLayoutData(gridData);
+        
+        // Create another composite for the right side of the sash
+        composite = new Composite(mSashForm, SWT.NONE);
+        layout = new GridLayout(1, true /* make columns equal width */);
+        layout.marginHeight = 0;
+        layout.marginWidth = 0;
+        layout.verticalSpacing = 1;
+        composite.setLayout(layout);
+
+        mTimescale = new Timescale(composite);
+        gridData = new GridData(GridData.FILL_HORIZONTAL);
+        gridData.heightHint = topMargin;
+        mTimescale.setLayoutData(gridData);
+
+        mSurface = new Surface(composite);
+        gridData = new GridData(GridData.FILL_BOTH);
+        mSurface.setLayoutData(gridData);
+        mSashForm.setWeights(new int[] { 1, 5 });
+
+        final ScrollBar vBar = mSurface.getVerticalBar();
+        vBar.addListener(SWT.Selection, new Listener() {
+           public void handleEvent(Event e) {
+               mScrollOffsetY = vBar.getSelection();
+               Point dim = mSurface.getSize();
+               int newScrollOffsetY = computeVisibleRows(dim.y);
+               if (newScrollOffsetY != mScrollOffsetY) {
+                   mScrollOffsetY = newScrollOffsetY;
+                   vBar.setSelection(newScrollOffsetY);
+               }
+               mLabels.redraw();
+               mSurface.redraw();
+           }
+        });
+        
+        mSurface.addListener(SWT.Resize, new Listener() {
+            public void handleEvent(Event e) {
+                Point dim = mSurface.getSize();
+                
+                // If we don't need the scroll bar then don't display it.
+                if (dim.y >= mNumRows * rowYSpace) {
+                    vBar.setVisible(false);
+                } else {
+                    vBar.setVisible(true);
+                }
+                int newScrollOffsetY = computeVisibleRows(dim.y);
+                if (newScrollOffsetY != mScrollOffsetY) {
+                    mScrollOffsetY = newScrollOffsetY;
+                    vBar.setSelection(newScrollOffsetY);
+                }
+                
+                int spaceNeeded = mNumRows * rowYSpace;
+                vBar.setMaximum(spaceNeeded);
+                vBar.setThumb(dim.y);
+
+                mLabels.redraw();
+                mSurface.redraw();
+            }
+        });
+
+        mSurface.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseUp(MouseEvent me) {
+                mSurface.mouseUp(me);
+            }
+
+            @Override
+            public void mouseDown(MouseEvent me) {
+                mSurface.mouseDown(me);
+            }
+
+            @Override
+            public void mouseDoubleClick(MouseEvent me) {
+                mSurface.mouseDoubleClick(me);
+            }
+        });
+        
+        mSurface.addMouseMoveListener(new MouseMoveListener() {
+            public void mouseMove(MouseEvent me) {
+                mSurface.mouseMove(me);
+            }
+        });
+
+        mTimescale.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseUp(MouseEvent me) {
+                mTimescale.mouseUp(me);
+            }
+
+            @Override
+            public void mouseDown(MouseEvent me) {
+                mTimescale.mouseDown(me);
+            }
+
+            @Override
+            public void mouseDoubleClick(MouseEvent me) {
+                mTimescale.mouseDoubleClick(me);
+            }
+        });
+        
+        mTimescale.addMouseMoveListener(new MouseMoveListener() {
+            public void mouseMove(MouseEvent me) {
+                mTimescale.mouseMove(me);
+            }
+        });
+
+        mLabels.addMouseMoveListener(new MouseMoveListener() {
+            public void mouseMove(MouseEvent me) {
+                mLabels.mouseMove(me);
+            }
+        });
+
+        setData(reader.getThreadTimeRecords());
+    }
+
+    public void update(Observable objservable, Object arg) {
+        // Ignore updates from myself
+        if (arg == "TimeLineView")  // $NON-NLS-1$
+            return;
+        // System.out.printf("timeline update from %s\n", arg);
+        boolean foundHighlight = false;
+        ArrayList<Selection> selections;
+        selections = mSelectionController.getSelections();
+        for (Selection selection : selections) {
+            Selection.Action action = selection.getAction();
+            if (action != Selection.Action.Highlight)
+                continue;
+            String name = selection.getName();
+            // System.out.printf(" timeline highlight %s from %s\n", name, arg);
+            if (name == "MethodData") {  // $NON-NLS-1$
+                foundHighlight = true;
+                mHighlightMethodData = (MethodData) selection.getValue();
+                // System.out.printf(" method %s\n",
+                // highlightMethodData.getName());
+                mHighlightCall = null;
+                startHighlighting();
+            } else if (name == "Call") {  // $NON-NLS-1$
+                foundHighlight = true;
+                mHighlightCall = (Call) selection.getValue();
+                // System.out.printf(" call %s\n", highlightCall.getName());
+                mHighlightMethodData = null;
+                startHighlighting();
+            }
+        }
+        if (foundHighlight == false)
+            mSurface.clearHighlights();
+    }
+
+    public void setData(ArrayList<Record> records) {
+        if (records == null)
+            records = new ArrayList<Record>();
+
+        if (false) {
+            System.out.println("TimelineView() list of records:");  // $NON-NLS-1$
+            for (Record r : records) {
+                System.out.printf("row '%s' block '%s' [%d, %d]\n", r.row  // $NON-NLS-1$
+                        .getName(), r.block.getName(), r.block.getStartTime(),
+                        r.block.getEndTime());
+                if (r.block.getStartTime() > r.block.getEndTime()) {
+                    System.err.printf("Error: block startTime > endTime\n");  // $NON-NLS-1$
+                    System.exit(1);
+                }
+            }
+        }
+
+        // Sort the records into increasing start time, and decreasing end time
+        Collections.sort(records, new Comparator<Record>() {
+            public int compare(Record r1, Record r2) {
+                long start1 = r1.block.getStartTime();
+                long start2 = r2.block.getStartTime();
+                if (start1 > start2)
+                    return 1;
+                if (start1 < start2)
+                    return -1;
+
+                // The start times are the same, so compare the end times
+                long end1 = r1.block.getEndTime();
+                long end2 = r2.block.getEndTime();
+                if (end1 > end2)
+                    return -1;
+                if (end1 < end2)
+                    return 1;
+
+                return 0;
+            }
+        });
+
+        // The records are sorted into increasing start time,
+        // so the minimum start time is the start time of the first record.
+        double minVal = 0;
+        if (records.size() > 0)
+            minVal = records.get(0).block.getStartTime();
+
+        // Sum the time spent in each row and block, and
+        // keep track of the maximum end time.
+        double maxVal = 0;
+        for (Record rec : records) {
+            Row row = rec.row;
+            Block block = rec.block;
+            String rowName = row.getName();
+            RowData rd = mRowByName.get(rowName);
+            if (rd == null) {
+                rd = new RowData(row);
+                mRowByName.put(rowName, rd);
+            }
+            long blockStartTime = block.getStartTime();
+            long blockEndTime = block.getEndTime();
+            if (blockEndTime > rd.mEndTime) {
+                long start = Math.max(blockStartTime, rd.mEndTime);
+                rd.mElapsed += blockEndTime - start;
+                mTotalElapsed += blockEndTime - start;
+                rd.mEndTime = blockEndTime;
+            }
+            if (blockEndTime > maxVal)
+                maxVal = blockEndTime;
+
+            // Keep track of nested blocks by using a stack (for each row).
+            // Create a Segment object for each visible part of a block.
+            Block top = rd.top();
+            if (top == null) {
+                rd.push(block);
+                continue;
+            }
+
+            long topStartTime = top.getStartTime();
+            long topEndTime = top.getEndTime();
+            if (topEndTime >= blockStartTime) {
+                // Add this segment if it has a non-zero elapsed time.
+                if (topStartTime < blockStartTime) {
+                    Segment segment = new Segment(rd, top, topStartTime,
+                            blockStartTime);
+                    mSegmentList.add(segment);
+                }
+
+                // If this block starts where the previous (top) block ends,
+                // then pop off the top block.
+                if (topEndTime == blockStartTime)
+                    rd.pop();
+                rd.push(block);
+            } else {
+                // We may have to pop several frames here.
+                popFrames(rd, top, blockStartTime);
+                rd.push(block);
+            }
+        }
+
+        // Clean up the stack of each row
+        for (RowData rd : mRowByName.values()) {
+            Block top = rd.top();
+            popFrames(rd, top, Integer.MAX_VALUE);
+        }
+
+        mSurface.setRange(minVal, maxVal);
+        mSurface.setLimitRange(minVal, maxVal);
+
+        // Sort the rows into decreasing elapsed time
+        Collection<RowData> rv = mRowByName.values();
+        mRows = rv.toArray(new RowData[rv.size()]);
+        Arrays.sort(mRows, new Comparator<RowData>() {
+            public int compare(RowData rd1, RowData rd2) {
+                return (int) (rd2.mElapsed - rd1.mElapsed);
+            }
+        });
+
+        // Assign ranks to the sorted rows
+        for (int ii = 0; ii < mRows.length; ++ii) {
+            mRows[ii].mRank = ii;
+        }
+
+        // Compute the number of rows with data
+        mNumRows = 0;
+        for (int ii = 0; ii < mRows.length; ++ii) {
+            if (mRows[ii].mElapsed == 0)
+                break;
+            mNumRows += 1;
+        }
+
+        // Sort the blocks into increasing rows, and within rows into
+        // increasing start values.
+        mSegments = mSegmentList.toArray(new Segment[mSegmentList.size()]);
+        Arrays.sort(mSegments, new Comparator<Segment>() {
+            public int compare(Segment bd1, Segment bd2) {
+                RowData rd1 = bd1.mRowData;
+                RowData rd2 = bd2.mRowData;
+                int diff = rd1.mRank - rd2.mRank;
+                if (diff == 0) {
+                    long timeDiff = bd1.mStartTime - bd2.mStartTime;
+                    if (timeDiff == 0)
+                        timeDiff = bd1.mEndTime - bd2.mEndTime;
+                    return (int) timeDiff;
+                }
+                return diff;
+            }
+        });
+
+        if (false) {
+            for (Segment segment : mSegments) {
+                System.out.printf("seg '%s' [%6d, %6d] %s\n",
+                        segment.mRowData.mName, segment.mStartTime,
+                        segment.mEndTime, segment.mBlock.getName());
+                if (segment.mStartTime > segment.mEndTime) {
+                    System.err.printf("Error: segment startTime > endTime\n");
+                    System.exit(1);
+                }
+            }
+        }
+    }
+
+    private void popFrames(RowData rd, Block top, long startTime) {
+        long topEndTime = top.getEndTime();
+        long lastEndTime = top.getStartTime();
+        while (topEndTime <= startTime) {
+            if (topEndTime > lastEndTime) {
+                Segment segment = new Segment(rd, top, lastEndTime, topEndTime);
+                mSegmentList.add(segment);
+                lastEndTime = topEndTime;
+            }
+            rd.pop();
+            top = rd.top();
+            if (top == null)
+                return;
+            topEndTime = top.getEndTime();
+        }
+
+        // If we get here, then topEndTime > startTime
+        if (lastEndTime < startTime) {
+            Segment bd = new Segment(rd, top, lastEndTime, startTime);
+            mSegmentList.add(bd);
+        }
+    }
+
+    private class RowLabels extends Canvas {
+
+        /** The space between the row label and the sash line */
+        private static final int labelMarginX = 2;
+
+        public RowLabels(Composite parent) {
+            super(parent, SWT.NO_BACKGROUND);
+            addPaintListener(new PaintListener() {
+                public void paintControl(PaintEvent pe) {
+                    draw(pe.display, pe.gc);
+                }
+            });
+        }
+
+        private void mouseMove(MouseEvent me) {
+            int rownum = (me.y + mScrollOffsetY) / rowYSpace;
+            if (mMouseRow != rownum) {
+                mMouseRow = rownum;
+                redraw();
+                mSurface.redraw();
+            }
+        }
+
+        private void draw(Display display, GC gc) {
+            if (mSegments.length == 0) {
+                // gc.setBackground(colorBackground);
+                // gc.fillRectangle(getBounds());
+                return;
+            }
+            Point dim = getSize();
+
+            // Create an image for double-buffering
+            Image image = new Image(display, getBounds());
+
+            // Set up the off-screen gc
+            GC gcImage = new GC(image);
+            if (mSetFonts)
+                gcImage.setFont(mFontRegistry.get("medium"));  // $NON-NLS-1$
+
+            if (mNumRows > 2) {
+                // Draw the row background stripes
+                gcImage.setBackground(mColorRowBack);
+                for (int ii = 1; ii < mNumRows; ii += 2) {
+                    RowData rd = mRows[ii];
+                    int y1 = rd.mRank * rowYSpace - mScrollOffsetY;
+                    gcImage.fillRectangle(0, y1, dim.x, rowYSpace);
+                }
+            }
+
+            // Draw the row labels
+            int offsetY = rowYMarginHalf - mScrollOffsetY;
+            for (int ii = mStartRow; ii <= mEndRow; ++ii) {
+                RowData rd = mRows[ii];
+                int y1 = rd.mRank * rowYSpace + offsetY;
+                Point extent = gcImage.stringExtent(rd.mName);
+                int x1 = dim.x - extent.x - labelMarginX;
+                gcImage.drawString(rd.mName, x1, y1, true);
+            }
+
+            // Draw a highlight box on the row where the mouse is.
+            if (mMouseRow >= mStartRow && mMouseRow <= mEndRow) {
+                gcImage.setForeground(mColorGray);
+                int y1 = mMouseRow * rowYSpace - mScrollOffsetY;
+                gcImage.drawRectangle(0, y1, dim.x, rowYSpace);
+            }
+
+            // Draw the off-screen buffer to the screen
+            gc.drawImage(image, 0, 0);
+
+            // Clean up
+            image.dispose();
+            gcImage.dispose();
+        }
+    }
+    
+    private class BlankCorner extends Canvas {
+        public BlankCorner(Composite parent) {
+            //super(parent, SWT.NO_BACKGROUND);
+            super(parent, SWT.NONE);
+            addPaintListener(new PaintListener() {
+                public void paintControl(PaintEvent pe) {
+                    draw(pe.display, pe.gc);
+                }
+            });
+        }
+
+        private void draw(Display display, GC gc) {
+            // Create a blank image and draw it to the canvas
+            Image image = new Image(display, getBounds());
+            gc.drawImage(image, 0, 0);
+
+            // Clean up
+            image.dispose();
+        }
+    }
+
+    private class Timescale extends Canvas {
+        private Point mMouse = new Point(LeftMargin, 0);
+        private Cursor mZoomCursor;
+        private String mMethodName = null;
+        private Color mMethodColor = null;
+        private int mMethodStartY;
+        private int mMarkStartX;
+        private int mMarkEndX;
+        
+        /** The space between the colored block and the method name */
+        private static final int METHOD_BLOCK_MARGIN = 10;
+
+        public Timescale(Composite parent) {
+            //super(parent, SWT.NO_BACKGROUND);
+            super(parent, SWT.NONE);
+            Display display = getDisplay();
+            mZoomCursor = new Cursor(display, SWT.CURSOR_SIZEWE);
+            setCursor(mZoomCursor);
+            mMethodStartY = mSmallFontHeight + 1;
+            addPaintListener(new PaintListener() {
+                public void paintControl(PaintEvent pe) {
+                    draw(pe.display, pe.gc);
+                }
+            });
+        }
+
+        public void setVbarPosition(int x) {
+            mMouse.x = x;
+        }
+
+        public void setMarkStart(int x) {
+            mMarkStartX = x;
+        }
+
+        public void setMarkEnd(int x) {
+            mMarkEndX = x;
+        }
+        
+        public void setMethodName(String name) {
+            mMethodName = name;
+        }
+        
+        public void setMethodColor(Color color) {
+            mMethodColor = color;
+        }
+        
+        private void mouseMove(MouseEvent me) {
+            me.y = -1;
+            mSurface.mouseMove(me);
+        }
+        
+        private void mouseDown(MouseEvent me) {
+            mSurface.startScaling(me.x);
+            mSurface.redraw();
+        }
+        
+        private void mouseUp(MouseEvent me) {
+            mSurface.stopScaling(me.x);
+        }
+        
+        private void mouseDoubleClick(MouseEvent me) {
+            mSurface.resetScale();
+            mSurface.redraw();
+        }
+
+        private void draw(Display display, GC gc) {
+            Point dim = getSize();
+
+            // Create an image for double-buffering
+            Image image = new Image(display, getBounds());
+
+            // Set up the off-screen gc
+            GC gcImage = new GC(image);
+            if (mSetFonts)
+                gcImage.setFont(mFontRegistry.get("medium"));  // $NON-NLS-1$
+
+            if (mSurface.drawingSelection()) {
+                drawSelection(display, gcImage);
+            }
+            
+            drawTicks(display, gcImage);
+
+            // Draw the vertical bar where the mouse is
+            gcImage.setForeground(mColorDarkGray);
+            gcImage.drawLine(mMouse.x, timeLineOffsetY, mMouse.x, dim.y);
+            
+            // Draw the current millseconds
+            drawTickLegend(display, gcImage);
+            
+            // Draw the method name and color, if needed
+            drawMethod(display, gcImage);
+            
+            // Draw the off-screen buffer to the screen
+            gc.drawImage(image, 0, 0);
+
+            // Clean up
+            image.dispose();
+            gcImage.dispose();
+        }
+        
+        private void drawSelection(Display display, GC gc) {
+            Point dim = getSize();
+            gc.setForeground(mColorGray);
+            gc.drawLine(mMarkStartX, timeLineOffsetY, mMarkStartX, dim.y);
+            gc.setBackground(mColorZoomSelection);
+            int x, width;
+            if (mMarkStartX < mMarkEndX) {
+                x = mMarkStartX;
+                width = mMarkEndX - mMarkStartX;
+            } else {
+                x = mMarkEndX;
+                width = mMarkStartX - mMarkEndX;
+            }
+            if (width > 1) {
+                gc.fillRectangle(x, timeLineOffsetY, width, dim.y);
+            }
+        }
+
+        private void drawTickLegend(Display display, GC gc) {
+            int mouseX = mMouse.x - LeftMargin;
+            double mouseXval = mScaleInfo.pixelToValue(mouseX);
+            String info = mUnits.labelledString(mouseXval);
+            gc.setForeground(mColorForeground);
+            gc.drawString(info, LeftMargin + 2, 1, true);
+
+            // Display the maximum data value
+            double maxVal = mScaleInfo.getMaxVal();
+            info = mUnits.labelledString(maxVal);
+            info = String.format(" max %s ", info);  // $NON-NLS-1$
+            Point extent = gc.stringExtent(info);
+            Point dim = getSize();
+            int x1 = dim.x - RightMargin - extent.x;
+            gc.drawString(info, x1, 1, true);
+        }
+        
+        private void drawMethod(Display display, GC gc) {
+            if (mMethodName == null) {
+                return;
+            }
+
+            int x1 = LeftMargin;
+            int y1 = mMethodStartY;
+            gc.setBackground(mMethodColor);
+            int width = 2 * mSmallFontWidth;
+            gc.fillRectangle(x1, y1, width, mSmallFontHeight);
+            x1 += width + METHOD_BLOCK_MARGIN;
+            gc.drawString(mMethodName, x1, y1, true);
+        }
+        
+        private void drawTicks(Display display, GC gc) {
+            Point dim = getSize();
+            int y2 = majorTickLength + timeLineOffsetY;
+            int y3 = minorTickLength + timeLineOffsetY;
+            int y4 = y2 + tickToFontSpacing;
+            gc.setForeground(mColorForeground);
+            gc.drawLine(LeftMargin, timeLineOffsetY, dim.x - RightMargin,
+                    timeLineOffsetY);
+            double minVal = mScaleInfo.getMinVal();
+            double maxVal = mScaleInfo.getMaxVal();
+            double minMajorTick = mScaleInfo.getMinMajorTick();
+            double tickIncrement = mScaleInfo.getTickIncrement();
+            double minorTickIncrement = tickIncrement / 5;
+            double pixelsPerRange = mScaleInfo.getPixelsPerRange();
+            
+            // Draw the initial minor ticks, if any
+            if (minVal < minMajorTick) {
+                gc.setForeground(mColorGray);
+                double xMinor = minMajorTick;
+                for (int ii = 1; ii <= 4; ++ii) {
+                    xMinor -= minorTickIncrement;
+                    if (xMinor < minVal)
+                        break;
+                    int x1 = LeftMargin
+                            + (int) (0.5 + (xMinor - minVal) * pixelsPerRange);
+                    gc.drawLine(x1, timeLineOffsetY, x1, y3);
+                }
+            }
+            
+            if (tickIncrement <= 10) {
+                // TODO avoid rendering the loop when tickIncrement is invalid. It can be zero
+                // or too small.
+                // System.out.println(String.format("Timescale.drawTicks error: tickIncrement=%1f", tickIncrement));
+                return;
+            }
+            for (double x = minMajorTick; x <= maxVal; x += tickIncrement) {
+                int x1 = LeftMargin
+                        + (int) (0.5 + (x - minVal) * pixelsPerRange);
+
+                // Draw a major tick
+                gc.setForeground(mColorForeground);
+                gc.drawLine(x1, timeLineOffsetY, x1, y2);
+                if (x > maxVal)
+                    break;
+
+                // Draw the tick text
+                String tickString = mUnits.valueOf(x);
+                gc.drawString(tickString, x1, y4, true);
+
+                // Draw 4 minor ticks between major ticks
+                gc.setForeground(mColorGray);
+                double xMinor = x;
+                for (int ii = 1; ii <= 4; ii++) {
+                    xMinor += minorTickIncrement;
+                    if (xMinor > maxVal)
+                        break;
+                    x1 = LeftMargin
+                            + (int) (0.5 + (xMinor - minVal) * pixelsPerRange);
+                    gc.drawLine(x1, timeLineOffsetY, x1, y3);
+                }
+            }
+        }
+    }
+
+    private static enum GraphicsState {
+        Normal, Marking, Scaling, Animating
+    };
+
+    private class Surface extends Canvas {
+
+        public Surface(Composite parent) {
+            super(parent, SWT.NO_BACKGROUND | SWT.V_SCROLL);
+            Display display = getDisplay();
+            mNormalCursor = new Cursor(display, SWT.CURSOR_CROSS);
+            mIncreasingCursor = new Cursor(display, SWT.CURSOR_SIZEE);
+            mDecreasingCursor = new Cursor(display, SWT.CURSOR_SIZEW);
+
+            initZoomFractionsWithExp();
+
+            addPaintListener(new PaintListener() {
+                public void paintControl(PaintEvent pe) {
+                    draw(pe.display, pe.gc);
+                }
+            });
+
+            mZoomAnimator = new Runnable() {
+                public void run() {
+                    animateZoom();
+                }
+            };
+
+            mHighlightAnimator = new Runnable() {
+                public void run() {
+                    animateHighlight();
+                }
+            };
+        }
+
+        private void initZoomFractionsWithExp() {
+            mZoomFractions = new double[ZOOM_STEPS];
+            int next = 0;
+            for (int ii = 0; ii < ZOOM_STEPS / 2; ++ii, ++next) {
+                mZoomFractions[next] = (double) (1 << ii)
+                        / (double) (1 << (ZOOM_STEPS / 2));
+                // System.out.printf("%d %f\n", next, zoomFractions[next]);
+            }
+            for (int ii = 2; ii < 2 + ZOOM_STEPS / 2; ++ii, ++next) {
+                mZoomFractions[next] = (double) ((1 << ii) - 1)
+                        / (double) (1 << ii);
+                // System.out.printf("%d %f\n", next, zoomFractions[next]);
+            }
+        }
+
+        @SuppressWarnings("unused")
+        private void initZoomFractionsWithSinWave() {
+            mZoomFractions = new double[ZOOM_STEPS];
+            for (int ii = 0; ii < ZOOM_STEPS; ++ii) {
+                double offset = Math.PI * (double) ii / (double) ZOOM_STEPS;
+                mZoomFractions[ii] = (Math.sin((1.5 * Math.PI + offset)) + 1.0) / 2.0;
+                // System.out.printf("%d %f\n", ii, zoomFractions[ii]);
+            }
+        }
+
+        public void setRange(double minVal, double maxVal) {
+            mMinDataVal = minVal;
+            mMaxDataVal = maxVal;
+            mScaleInfo.setMinVal(minVal);
+            mScaleInfo.setMaxVal(maxVal);
+        }
+
+        public void setLimitRange(double minVal, double maxVal) {
+            mLimitMinVal = minVal;
+            mLimitMaxVal = maxVal;
+        }
+        
+        public void resetScale() {
+            mScaleInfo.setMinVal(mLimitMinVal);
+            mScaleInfo.setMaxVal(mLimitMaxVal);
+        }
+
+        private void draw(Display display, GC gc) {
+            if (mSegments.length == 0) {
+                // gc.setBackground(colorBackground);
+                // gc.fillRectangle(getBounds());
+                return;
+            }
+
+            // Create an image for double-buffering
+            Image image = new Image(display, getBounds());
+
+            // Set up the off-screen gc
+            GC gcImage = new GC(image);
+            if (mSetFonts)
+                gcImage.setFont(mFontRegistry.get("small"));  // $NON-NLS-1$
+
+            // Draw the background
+            // gcImage.setBackground(colorBackground);
+            // gcImage.fillRectangle(image.getBounds());
+
+            if (mGraphicsState == GraphicsState.Scaling) {
+                double diff = mMouse.x - mMouseMarkStartX;
+                if (diff > 0) {
+                    double newMinVal = mScaleMinVal - diff / mScalePixelsPerRange;
+                    if (newMinVal < mLimitMinVal)
+                        newMinVal = mLimitMinVal;
+                    mScaleInfo.setMinVal(newMinVal);
+                    // System.out.printf("diff %f scaleMin %f newMin %f\n",
+                    // diff, scaleMinVal, newMinVal);
+                } else if (diff < 0) {
+                    double newMaxVal = mScaleMaxVal - diff / mScalePixelsPerRange;
+                    if (newMaxVal > mLimitMaxVal)
+                        newMaxVal = mLimitMaxVal;
+                    mScaleInfo.setMaxVal(newMaxVal);
+                    // System.out.printf("diff %f scaleMax %f newMax %f\n",
+                    // diff, scaleMaxVal, newMaxVal);
+                }
+            }
+
+            // Recompute the ticks and strips only if the size has changed,
+            // or we scrolled so that a new row is visible.
+            Point dim = getSize();
+            if (mStartRow != mCachedStartRow || mEndRow != mCachedEndRow 
+                    || mScaleInfo.getMinVal() != mCachedMinVal
+                    || mScaleInfo.getMaxVal() != mCachedMaxVal) {
+                mCachedStartRow = mStartRow;
+                mCachedEndRow = mEndRow;
+                int xdim = dim.x - TotalXMargin;
+                mScaleInfo.setNumPixels(xdim);
+                boolean forceEndPoints = (mGraphicsState == GraphicsState.Scaling
+                        || mGraphicsState == GraphicsState.Animating);
+                mScaleInfo.computeTicks(forceEndPoints);
+                mCachedMinVal = mScaleInfo.getMinVal();
+                mCachedMaxVal = mScaleInfo.getMaxVal();
+                if (mLimitMinVal > mScaleInfo.getMinVal())
+                    mLimitMinVal = mScaleInfo.getMinVal();
+                if (mLimitMaxVal < mScaleInfo.getMaxVal())
+                    mLimitMaxVal = mScaleInfo.getMaxVal();
+
+                // Compute the strips
+                computeStrips();
+            }
+
+            if (mNumRows > 2) {
+                // Draw the row background stripes
+                gcImage.setBackground(mColorRowBack);
+                for (int ii = 1; ii < mNumRows; ii += 2) {
+                    RowData rd = mRows[ii];
+                    int y1 = rd.mRank * rowYSpace - mScrollOffsetY;
+                    gcImage.fillRectangle(0, y1, dim.x, rowYSpace);
+                }
+            }
+
+            if (drawingSelection()) {
+                drawSelection(display, gcImage);
+            }
+
+            String blockName = null;
+            Color blockColor = null;
+
+            if (mDebug) {
+                double pixelsPerRange = mScaleInfo.getPixelsPerRange();
+                System.out
+                        .printf(
+                                "dim.x %d pixels %d minVal %f, maxVal %f ppr %f rpp %f\n",
+                                dim.x, dim.x - TotalXMargin, mScaleInfo
+                                        .getMinVal(), mScaleInfo.getMaxVal(),
+                                pixelsPerRange, 1.0 / pixelsPerRange);
+            }
+
+            // Draw the strips
+            Block selectBlock = null;
+            for (Strip strip : mStripList) {
+                if (strip.mColor == null) {
+                    // System.out.printf("strip.color is null\n");
+                    continue;
+                }
+                gcImage.setBackground(strip.mColor);
+                gcImage.fillRectangle(strip.mX, strip.mY - mScrollOffsetY, strip.mWidth,
+                        strip.mHeight);
+                if (mMouseRow == strip.mRowData.mRank) {
+                    if (mMouse.x >= strip.mX
+                            && mMouse.x < strip.mX + strip.mWidth) {
+                        blockName = strip.mSegment.mBlock.getName();
+                        blockColor = strip.mColor;
+                    }
+                    if (mMouseSelect.x >= strip.mX
+                            && mMouseSelect.x < strip.mX + strip.mWidth) {
+                        selectBlock = strip.mSegment.mBlock;
+                    }
+                }
+            }
+            mMouseSelect.x = 0;
+            mMouseSelect.y = 0;
+
+            if (selectBlock != null) {
+                ArrayList<Selection> selections = new ArrayList<Selection>();
+                // Get the row label
+                RowData rd = mRows[mMouseRow];
+                selections.add(Selection.highlight("Thread", rd.mName));  // $NON-NLS-1$
+                selections.add(Selection.highlight("Call", selectBlock));  // $NON-NLS-1$
+
+                int mouseX = mMouse.x - LeftMargin;
+                double mouseXval = mScaleInfo.pixelToValue(mouseX);
+                selections.add(Selection.highlight("Time", mouseXval));  // $NON-NLS-1$
+                
+                mSelectionController.change(selections, "TimeLineView");  // $NON-NLS-1$
+                mHighlightMethodData = null;
+                mHighlightCall = (Call) selectBlock;
+                startHighlighting();
+            }
+
+            // Draw a highlight box on the row where the mouse is.
+            // Except don't draw the box if we are animating the
+            // highlighing of a call or method because the inclusive
+            // highlight bar passes through the highlight box and
+            // causes an annoying flashing artifact.
+            if (mMouseRow >= 0 && mMouseRow < mNumRows && mHighlightStep == 0) {
+                gcImage.setForeground(mColorGray);
+                int y1 = mMouseRow * rowYSpace - mScrollOffsetY;
+                gcImage.drawLine(0, y1, dim.x, y1);
+                gcImage.drawLine(0, y1 + rowYSpace, dim.x, y1 + rowYSpace);
+            }
+
+            // Highlight a selected method, if any
+            drawHighlights(gcImage, dim);
+
+            // Draw a vertical line where the mouse is.
+            gcImage.setForeground(mColorDarkGray);
+            int lineEnd = Math.min(dim.y, mNumRows * rowYSpace);
+            gcImage.drawLine(mMouse.x, 0, mMouse.x, lineEnd);
+
+            if (blockName != null) {
+                mTimescale.setMethodName(blockName);
+                mTimescale.setMethodColor(blockColor);
+                mShowHighlightName = false;
+            } else if (mShowHighlightName) {
+                // Draw the highlighted method name
+                MethodData md = mHighlightMethodData;
+                if (md == null && mHighlightCall != null)
+                    md = mHighlightCall.getMethodData();
+                if (md == null)
+                    System.out.printf("null highlight?\n");  // $NON-NLS-1$
+                if (md != null) {
+                    mTimescale.setMethodName(md.getProfileName());
+                    mTimescale.setMethodColor(md.getColor());
+                }
+            } else {
+                mTimescale.setMethodName(null);
+                mTimescale.setMethodColor(null);
+            }
+            mTimescale.redraw();
+
+            // Draw the off-screen buffer to the screen
+            gc.drawImage(image, 0, 0);
+
+            // Clean up
+            image.dispose();
+            gcImage.dispose();
+        }
+
+        private void drawHighlights(GC gc, Point dim) {
+            int height = highlightHeight;
+            if (height <= 0)
+                return;
+            for (Range range : mHighlightExclusive) {
+                gc.setBackground(range.mColor);
+                int xStart = range.mXdim.x;
+                int width = range.mXdim.y;
+                gc.fillRectangle(xStart, range.mY - height - mScrollOffsetY, width, height);
+            }
+
+            // Draw the inclusive lines a bit shorter
+            height -= 1;
+            if (height <= 0)
+                height = 1;
+
+            // Highlight the inclusive ranges
+            gc.setForeground(mColorDarkGray);
+            gc.setBackground(mColorDarkGray);
+            for (Range range : mHighlightInclusive) {
+                int x1 = range.mXdim.x;
+                int x2 = range.mXdim.y;
+                boolean drawLeftEnd = false;
+                boolean drawRightEnd = false;
+                if (x1 >= LeftMargin)
+                    drawLeftEnd = true;
+                else
+                    x1 = LeftMargin;
+                if (x2 >= LeftMargin)
+                    drawRightEnd = true;
+                else
+                    x2 = dim.x - RightMargin;
+                int y1 = range.mY + rowHeight + 2 - mScrollOffsetY;
+
+                // If the range is very narrow, then just draw a small
+                // rectangle.
+                if (x2 - x1 < MinInclusiveRange) {
+                    int width = x2 - x1;
+                    if (width < 2)
+                        width = 2;
+                    gc.fillRectangle(x1, y1, width, height);
+                    continue;
+                }
+                if (drawLeftEnd) {
+                    if (drawRightEnd) {
+                        // Draw both ends
+                        int[] points = { x1, y1, x1, y1 + height, x2,
+                                y1 + height, x2, y1 };
+                        gc.drawPolyline(points);
+                    } else {
+                        // Draw the left end
+                        int[] points = { x1, y1, x1, y1 + height, x2,
+                                y1 + height };
+                        gc.drawPolyline(points);
+                    }
+                } else {
+                    if (drawRightEnd) {
+                        // Draw the right end
+                        int[] points = { x1, y1 + height, x2, y1 + height, x2,
+                                y1 };
+                        gc.drawPolyline(points);
+                    } else {
+                        // Draw neither end, just the line
+                        int[] points = { x1, y1 + height, x2, y1 + height };
+                        gc.drawPolyline(points);
+                    }
+                }
+
+                // Draw the arrowheads, if necessary
+                if (drawLeftEnd == false) {
+                    int[] points = { x1 + 7, y1 + height - 4, x1, y1 + height,
+                            x1 + 7, y1 + height + 4 };
+                    gc.fillPolygon(points);
+                }
+                if (drawRightEnd == false) {
+                    int[] points = { x2 - 7, y1 + height - 4, x2, y1 + height,
+                            x2 - 7, y1 + height + 4 };
+                    gc.fillPolygon(points);
+                }
+            }
+        }
+
+        private boolean drawingSelection() {
+            return mGraphicsState == GraphicsState.Marking
+                    || mGraphicsState == GraphicsState.Animating;
+        }
+        
+        private void drawSelection(Display display, GC gc) {
+            Point dim = getSize();
+            gc.setForeground(mColorGray);
+            gc.drawLine(mMouseMarkStartX, 0, mMouseMarkStartX, dim.y);
+            gc.setBackground(mColorZoomSelection);
+            int width;
+            int mouseX = (mGraphicsState == GraphicsState.Animating) ? mMouseMarkEndX : mMouse.x;
+            int x;
+            if (mMouseMarkStartX < mouseX) {
+                x = mMouseMarkStartX;
+                width = mouseX - mMouseMarkStartX;
+            } else {
+                x = mouseX;
+                width = mMouseMarkStartX - mouseX;
+            }
+            gc.fillRectangle(x, 0, width, dim.y);
+        }
+
+        private void computeStrips() {
+            double minVal = mScaleInfo.getMinVal();
+            double maxVal = mScaleInfo.getMaxVal();
+
+            // Allocate space for the pixel data
+            Pixel[] pixels = new Pixel[mNumRows];
+            for (int ii = 0; ii < mNumRows; ++ii)
+                pixels[ii] = new Pixel();
+
+            // Clear the per-block pixel data
+            for (int ii = 0; ii < mSegments.length; ++ii) {
+                mSegments[ii].mBlock.clearWeight();
+            }
+
+            mStripList.clear();
+            mHighlightExclusive.clear();
+            mHighlightInclusive.clear();
+            MethodData callMethod = null;
+            long callStart = 0;
+            long callEnd = -1;
+            RowData callRowData = null;
+            int prevMethodStart = -1;
+            int prevCallStart = -1;
+            if (mHighlightCall != null) {
+                int callPixelStart = -1;
+                int callPixelEnd = -1;
+                callStart = mHighlightCall.mGlobalStartTime;
+                callEnd = mHighlightCall.mGlobalEndTime;
+                callMethod = mHighlightCall.mMethodData;
+                if (callStart >= minVal)
+                    callPixelStart = mScaleInfo.valueToPixel(callStart);
+                if (callEnd <= maxVal)
+                    callPixelEnd = mScaleInfo.valueToPixel(callEnd);
+                // System.out.printf("callStart,End %d,%d minVal,maxVal %f,%f
+                // callPixelStart,End %d,%d\n",
+                // callStart, callEnd, minVal, maxVal, callPixelStart,
+                // callPixelEnd);
+                int threadId = mHighlightCall.getThreadId();
+                String threadName = mThreadLabels.get(threadId);
+                callRowData = mRowByName.get(threadName);
+                int y1 = callRowData.mRank * rowYSpace + rowYMarginHalf;
+                Color color = callMethod.getColor();
+                mHighlightInclusive.add(new Range(callPixelStart + LeftMargin,
+                        callPixelEnd + LeftMargin, y1, color));
+            }
+            for (Segment segment : mSegments) {
+                if (segment.mEndTime <= minVal)
+                    continue;
+                if (segment.mStartTime >= maxVal)
+                    continue;
+                Block block = segment.mBlock;
+                Color color = block.getColor();
+                if (color == null)
+                    continue;
+
+                double recordStart = Math.max(segment.mStartTime, minVal);
+                double recordEnd = Math.min(segment.mEndTime, maxVal);
+                if (recordStart == recordEnd)
+                    continue;
+                int pixelStart = mScaleInfo.valueToPixel(recordStart);
+                int pixelEnd = mScaleInfo.valueToPixel(recordEnd);
+                int width = pixelEnd - pixelStart;
+
+                RowData rd = segment.mRowData;
+                MethodData md = block.getMethodData();
+
+                // We will add the scroll offset later when we draw the strips
+                int y1 = rd.mRank * rowYSpace + rowYMarginHalf;
+
+                // If we can't display any more rows, then quit
+                if (rd.mRank > mEndRow)
+                    break;
+
+                // System.out.printf("segment %s val: [%.1f, %.1f] frac [%f, %f]
+                // pixel: [%d, %d] pix.start %d weight %.2f %s\n",
+                // block.getName(), recordStart, recordEnd,
+                // scaleInfo.valueToPixelFraction(recordStart),
+                // scaleInfo.valueToPixelFraction(recordEnd),
+                // pixelStart, pixelEnd, pixels[rd.rank].start,
+                // pixels[rd.rank].maxWeight,
+                // pixels[rd.rank].segment != null
+                // ? pixels[rd.rank].segment.block.getName()
+                // : "null");
+
+                if (mHighlightMethodData != null) {
+                    if (mHighlightMethodData == md) {
+                        if (prevMethodStart != pixelStart) {
+                            prevMethodStart = pixelStart;
+                            int rangeWidth = width;
+                            if (rangeWidth == 0)
+                                rangeWidth = 1;
+                            mHighlightExclusive.add(new Range(pixelStart
+                                    + LeftMargin, rangeWidth, y1, color));
+                            Call call = (Call) block;
+                            callStart = call.mGlobalStartTime;
+                            int callPixelStart = -1;
+                            if (callStart >= minVal)
+                                callPixelStart = mScaleInfo.valueToPixel(callStart);
+                            if (prevCallStart != callPixelStart) {
+                                prevCallStart = callPixelStart;
+                                int callPixelEnd = -1;
+                                callEnd = call.mGlobalEndTime;
+                                if (callEnd <= maxVal)
+                                    callPixelEnd = mScaleInfo.valueToPixel(callEnd);
+                                mHighlightInclusive.add(new Range(
+                                        callPixelStart + LeftMargin,
+                                        callPixelEnd + LeftMargin, y1, color));
+                            }
+                        }
+                    } else if (mFadeColors) {
+                        color = md.getFadedColor();
+                    }
+                } else if (mHighlightCall != null) {
+                    if (segment.mStartTime >= callStart
+                            && segment.mEndTime <= callEnd && callMethod == md
+                            && callRowData == rd) {
+                        if (prevMethodStart != pixelStart) {
+                            prevMethodStart = pixelStart;
+                            int rangeWidth = width;
+                            if (rangeWidth == 0)
+                                rangeWidth = 1;
+                            mHighlightExclusive.add(new Range(pixelStart
+                                    + LeftMargin, rangeWidth, y1, color));
+                        }
+                    } else if (mFadeColors) {
+                        color = md.getFadedColor();
+                    }
+                }
+
+                // Cases:
+                // 1. This segment starts on a different pixel than the
+                // previous segment started on. In this case, emit
+                // the pixel strip, if any, and:
+                // A. If the width is 0, then add this segment's
+                // weight to the Pixel.
+                // B. If the width > 0, then emit a strip for this
+                // segment (no partial Pixel data).
+                //
+                // 2. Otherwise (the new segment starts on the same
+                // pixel as the previous segment): add its "weight"
+                // to the current pixel, and:
+                // A. If the new segment has width 1,
+                // then emit the pixel strip and then
+                // add the segment's weight to the pixel.
+                // B. If the new segment has width > 1,
+                // then emit the pixel strip, and emit the rest
+                // of the strip for this segment (no partial Pixel
+                // data).
+
+                Pixel pix = pixels[rd.mRank];
+                if (pix.mStart != pixelStart) {
+                    if (pix.mSegment != null) {
+                        // Emit the pixel strip. This also clears the pixel.
+                        emitPixelStrip(rd, y1, pix);
+                    }
+
+                    if (width == 0) {
+                        // Compute the "weight" of this segment for the first
+                        // pixel. For a pixel N, the "weight" of a segment is
+                        // how much of the region [N - 0.5, N + 0.5] is covered
+                        // by the segment.
+                        double weight = computeWeight(recordStart, recordEnd,
+                                pixelStart);
+                        weight = block.addWeight(pixelStart, rd.mRank, weight);
+                        if (weight > pix.mMaxWeight) {
+                            pix.setFields(pixelStart, weight, segment, color,
+                                    rd);
+                        }
+                    } else {
+                        int x1 = pixelStart + LeftMargin;
+                        Strip strip = new Strip(x1, y1, width, rowHeight, rd,
+                                segment, color);
+                        mStripList.add(strip);
+                    }
+                } else {
+                    double weight = computeWeight(recordStart, recordEnd,
+                            pixelStart);
+                    weight = block.addWeight(pixelStart, rd.mRank, weight);
+                    if (weight > pix.mMaxWeight) {
+                        pix.setFields(pixelStart, weight, segment, color, rd);
+                    }
+                    if (width == 1) {
+                        // Emit the pixel strip. This also clears the pixel.
+                        emitPixelStrip(rd, y1, pix);
+
+                        // Compute the weight for the next pixel
+                        pixelStart += 1;
+                        weight = computeWeight(recordStart, recordEnd,
+                                pixelStart);
+                        weight = block.addWeight(pixelStart, rd.mRank, weight);
+                        pix.setFields(pixelStart, weight, segment, color, rd);
+                    } else if (width > 1) {
+                        // Emit the pixel strip. This also clears the pixel.
+                        emitPixelStrip(rd, y1, pix);
+
+                        // Emit a strip for the rest of the segment.
+                        pixelStart += 1;
+                        width -= 1;
+                        int x1 = pixelStart + LeftMargin;
+                        Strip strip = new Strip(x1, y1, width, rowHeight, rd,
+                                segment, color);
+                        mStripList.add(strip);
+                    }
+                }
+            }
+
+            // Emit the last pixels of each row, if any
+            for (int ii = 0; ii < mNumRows; ++ii) {
+                Pixel pix = pixels[ii];
+                if (pix.mSegment != null) {
+                    RowData rd = pix.mRowData;
+                    int y1 = rd.mRank * rowYSpace + rowYMarginHalf;
+                    // Emit the pixel strip. This also clears the pixel.
+                    emitPixelStrip(rd, y1, pix);
+                }
+            }
+
+            if (false) {
+                System.out.printf("computeStrips()\n");
+                for (Strip strip : mStripList) {
+                    System.out.printf("%3d, %3d width %3d height %d %s\n",
+                            strip.mX, strip.mY, strip.mWidth, strip.mHeight,
+                            strip.mSegment.mBlock.getName());
+                }
+            }
+        }
+
+        private double computeWeight(double start, double end, int pixel) {
+            double pixelStartFraction = mScaleInfo.valueToPixelFraction(start);
+            double pixelEndFraction = mScaleInfo.valueToPixelFraction(end);
+            double leftEndPoint = Math.max(pixelStartFraction, pixel - 0.5);
+            double rightEndPoint = Math.min(pixelEndFraction, pixel + 0.5);
+            double weight = rightEndPoint - leftEndPoint;
+            return weight;
+        }
+
+        private void emitPixelStrip(RowData rd, int y, Pixel pixel) {
+            Strip strip;
+
+            if (pixel.mSegment == null)
+                return;
+
+            int x = pixel.mStart + LeftMargin;
+            // Compute the percentage of the row height proportional to
+            // the weight of this pixel. But don't let the proportion
+            // exceed 3/4 of the row height so that we can easily see
+            // if a given time range includes more than one method.
+            int height = (int) (pixel.mMaxWeight * rowHeight * 0.75);
+            if (height < mMinStripHeight)
+                height = mMinStripHeight;
+            int remainder = rowHeight - height;
+            if (remainder > 0) {
+                strip = new Strip(x, y, 1, remainder, rd, pixel.mSegment,
+                        mFadeColors ? mColorGray : mColorBlack);
+                mStripList.add(strip);
+                // System.out.printf("emitPixel (%d, %d) height %d black\n",
+                // x, y, remainder);
+            }
+            strip = new Strip(x, y + remainder, 1, height, rd, pixel.mSegment,
+                    pixel.mColor);
+            mStripList.add(strip);
+            // System.out.printf("emitPixel (%d, %d) height %d %s\n",
+            // x, y + remainder, height, pixel.segment.block.getName());
+            pixel.mSegment = null;
+            pixel.mMaxWeight = 0.0;
+        }
+
+        private void mouseMove(MouseEvent me) {
+            if (false) {
+                if (mHighlightMethodData != null) {
+                    mHighlightMethodData = null;
+                    // Force a recomputation of the strip colors
+                    mCachedEndRow = -1;
+                }
+            }
+            Point dim = mSurface.getSize();
+            int x = me.x;
+            if (x < LeftMargin)
+                x = LeftMargin;
+            if (x > dim.x - RightMargin)
+                x = dim.x - RightMargin;
+            mMouse.x = x;
+            mMouse.y = me.y;
+            mTimescale.setVbarPosition(x);
+            if (mGraphicsState == GraphicsState.Marking) {
+                mTimescale.setMarkEnd(x);
+            }
+
+            if (mGraphicsState == GraphicsState.Normal) {
+                // Set the cursor to the normal state.
+                mSurface.setCursor(mNormalCursor);
+            } else if (mGraphicsState == GraphicsState.Marking) {
+                // Make the cursor point in the direction of the sweep
+                if (mMouse.x >= mMouseMarkStartX)
+                    mSurface.setCursor(mIncreasingCursor);
+                else
+                    mSurface.setCursor(mDecreasingCursor);
+            }
+            int rownum = (mMouse.y + mScrollOffsetY) / rowYSpace;
+            if (me.y < 0 || me.y >= dim.y) {
+                rownum = -1;
+            }
+            if (mMouseRow != rownum) {
+                mMouseRow = rownum;
+                mLabels.redraw();
+            }
+            redraw();
+        }
+
+        private void mouseDown(MouseEvent me) {
+            Point dim = mSurface.getSize();
+            int x = me.x;
+            if (x < LeftMargin)
+                x = LeftMargin;
+            if (x > dim.x - RightMargin)
+                x = dim.x - RightMargin;
+            mMouseMarkStartX = x;
+            mGraphicsState = GraphicsState.Marking;
+            mSurface.setCursor(mIncreasingCursor);
+            mTimescale.setMarkStart(mMouseMarkStartX);
+            mTimescale.setMarkEnd(mMouseMarkStartX);
+            redraw();
+        }
+
+        private void mouseUp(MouseEvent me) {
+            mSurface.setCursor(mNormalCursor);
+            if (mGraphicsState != GraphicsState.Marking) {
+                mGraphicsState = GraphicsState.Normal;
+                return;
+            }
+            mGraphicsState = GraphicsState.Animating;
+            Point dim = mSurface.getSize();
+
+            // If the user released the mouse outside the drawing area then
+            // cancel the zoom.
+            if (me.y <= 0 || me.y >= dim.y) {
+                mGraphicsState = GraphicsState.Normal;
+                redraw();
+                return;
+            }
+
+            int x = me.x;
+            if (x < LeftMargin)
+                x = LeftMargin;
+            if (x > dim.x - RightMargin)
+                x = dim.x - RightMargin;
+            mMouseMarkEndX = x;
+
+            // If the user clicked and released the mouse at the same point
+            // (+/- a pixel or two) then cancel the zoom (but select the
+            // method).
+            int dist = mMouseMarkEndX - mMouseMarkStartX;
+            if (dist < 0)
+                dist = -dist;
+            if (dist <= 2) {
+                mGraphicsState = GraphicsState.Normal;
+
+                // Select the method underneath the mouse
+                mMouseSelect.x = mMouseMarkStartX;
+                mMouseSelect.y = me.y;
+                redraw();
+                return;
+            }
+
+            // Make mouseEndX be the higher end point
+            if (mMouseMarkEndX < mMouseMarkStartX) {
+                int temp = mMouseMarkEndX;
+                mMouseMarkEndX = mMouseMarkStartX;
+                mMouseMarkStartX = temp;
+            }
+
+            // If the zoom area is the whole window (or nearly the whole
+            // window) then cancel the zoom.
+            if (mMouseMarkStartX <= LeftMargin + MinZoomPixelMargin
+                    && mMouseMarkEndX >= dim.x - RightMargin - MinZoomPixelMargin) {
+                mGraphicsState = GraphicsState.Normal;
+                redraw();
+                return;
+            }
+
+            // Compute some variables needed for zooming.
+            // It's probably easiest to explain by an example. There
+            // are two scales (or dimensions) involved: one for the pixels
+            // and one for the values (microseconds). To keep the example
+            // simple, suppose we have pixels in the range [0,16] and
+            // values in the range [100, 260], and suppose the user
+            // selects a zoom window from pixel 4 to pixel 8.
+            //
+            // usec: 100 140 180 260
+            // |-------|ZZZZZZZ|---------------|
+            // pixel: 0 4 8 16
+            //
+            // I've drawn the pixels starting at zero for simplicity, but
+            // in fact the drawable area is offset from the left margin
+            // by the value of "LeftMargin".
+            //
+            // The "pixels-per-range" (ppr) in this case is 0.1 (a tenth of
+            // a pixel per usec). What we want is to redraw the screen in
+            // several steps, each time increasing the zoom window until the
+            // zoom window fills the screen. For simplicity, assume that
+            // we want to zoom in four equal steps. Then the snapshots
+            // of the screen at each step would look something like this:
+            //
+            // usec: 100 140 180 260
+            // |-------|ZZZZZZZ|---------------|
+            // pixel: 0 4 8 16
+            //
+            // usec: ? 140 180 ?
+            // |-----|ZZZZZZZZZZZZZ|-----------|
+            // pixel: 0 3 10 16
+            //
+            // usec: ? 140 180 ?
+            // |---|ZZZZZZZZZZZZZZZZZZZ|-------|
+            // pixel: 0 2 12 16
+            //
+            // usec: ?140 180 ?
+            // |-|ZZZZZZZZZZZZZZZZZZZZZZZZZ|---|
+            // pixel: 0 1 14 16
+            //
+            // usec: 140 180
+            // |ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ|
+            // pixel: 0 16
+            //
+            // The problem is how to compute the endpoints (denoted by ?)
+            // for each step. This is a little tricky. We first need to
+            // compute the "fixed point": this is the point in the selection
+            // that doesn't move left or right. Then we can recompute the
+            // "ppr" (pixels per range) at each step and then find the
+            // endpoints. The computation of the end points is done
+            // in animateZoom(). This method computes the fixed point
+            // and some other variables needed in animateZoom().
+
+            double minVal = mScaleInfo.getMinVal();
+            double maxVal = mScaleInfo.getMaxVal();
+            double ppr = mScaleInfo.getPixelsPerRange();
+            mZoomMin = minVal + ((mMouseMarkStartX - LeftMargin) / ppr);
+            mZoomMax = minVal + ((mMouseMarkEndX - LeftMargin) / ppr);
+
+            // Clamp the min and max values to the actual data min and max
+            if (mZoomMin < mMinDataVal)
+                mZoomMin = mMinDataVal;
+            if (mZoomMax > mMaxDataVal)
+                mZoomMax = mMaxDataVal;
+
+            // Snap the min and max points to the grid determined by the
+            // TickScaler
+            // before we zoom.
+            int xdim = dim.x - TotalXMargin;
+            TickScaler scaler = new TickScaler(mZoomMin, mZoomMax, xdim,
+                    PixelsPerTick);
+            scaler.computeTicks(false);
+            mZoomMin = scaler.getMinVal();
+            mZoomMax = scaler.getMaxVal();
+
+            // Also snap the mouse points (in pixel space) to be consistent with
+            // zoomMin and zoomMax (in value space).
+            mMouseMarkStartX = (int) ((mZoomMin - minVal) * ppr + LeftMargin);
+            mMouseMarkEndX = (int) ((mZoomMax - minVal) * ppr + LeftMargin);
+            mTimescale.setMarkStart(mMouseMarkStartX);
+            mTimescale.setMarkEnd(mMouseMarkEndX);
+
+            // Compute the mouse selection end point distances
+            mMouseEndDistance = dim.x - RightMargin - mMouseMarkEndX;
+            mMouseStartDistance = mMouseMarkStartX - LeftMargin;
+            mZoomMouseStart = mMouseMarkStartX;
+            mZoomMouseEnd = mMouseMarkEndX;
+            mZoomStep = 0;
+
+            // Compute the fixed point in both value space and pixel space.
+            mMin2ZoomMin = mZoomMin - minVal;
+            mZoomMax2Max = maxVal - mZoomMax;
+            mZoomFixed = mZoomMin + (mZoomMax - mZoomMin) * mMin2ZoomMin
+                    / (mMin2ZoomMin + mZoomMax2Max);
+            mZoomFixedPixel = (mZoomFixed - minVal) * ppr + LeftMargin;
+            mFixedPixelStartDistance = mZoomFixedPixel - LeftMargin;
+            mFixedPixelEndDistance = dim.x - RightMargin - mZoomFixedPixel;
+
+            mZoomMin2Fixed = mZoomFixed - mZoomMin;
+            mFixed2ZoomMax = mZoomMax - mZoomFixed;
+
+            getDisplay().timerExec(ZOOM_TIMER_INTERVAL, mZoomAnimator);
+            redraw();
+            update();
+        }
+
+        // No defined behavior yet for double-click.
+        private void mouseDoubleClick(MouseEvent me) {
+        }
+        
+        public void startScaling(int mouseX) {
+            Point dim = mSurface.getSize();
+            int x = mouseX;
+            if (x < LeftMargin)
+                x = LeftMargin;
+            if (x > dim.x - RightMargin)
+                x = dim.x - RightMargin;
+            mMouseMarkStartX = x;
+            mGraphicsState = GraphicsState.Scaling;
+            mScalePixelsPerRange = mScaleInfo.getPixelsPerRange();
+            mScaleMinVal = mScaleInfo.getMinVal();
+            mScaleMaxVal = mScaleInfo.getMaxVal();
+        }
+
+        public void stopScaling(int mouseX) {
+            mGraphicsState = GraphicsState.Normal;
+        }
+        
+        private void animateHighlight() {
+            mHighlightStep += 1;
+            if (mHighlightStep >= HIGHLIGHT_STEPS) {
+                mFadeColors = false;
+                mHighlightStep = 0;
+                // Force a recomputation of the strip colors
+                mCachedEndRow = -1;
+            } else {
+                mFadeColors = true;
+                mShowHighlightName = true;
+                highlightHeight = highlightHeights[mHighlightStep];
+                getDisplay().timerExec(HIGHLIGHT_TIMER_INTERVAL, mHighlightAnimator);
+            }
+            redraw();
+        }
+
+        private void clearHighlights() {
+            // System.out.printf("clearHighlights()\n");
+            mShowHighlightName = false;
+            highlightHeight = 0;
+            mHighlightMethodData = null;
+            mHighlightCall = null;
+            mFadeColors = false;
+            mHighlightStep = 0;
+            // Force a recomputation of the strip colors
+            mCachedEndRow = -1;
+            redraw();
+        }
+
+        private void animateZoom() {
+            mZoomStep += 1;
+            if (mZoomStep > ZOOM_STEPS) {
+                mGraphicsState = GraphicsState.Normal;
+                // Force a normal recomputation
+                mCachedMinVal = mScaleInfo.getMinVal() + 1;
+            } else if (mZoomStep == ZOOM_STEPS) {
+                mScaleInfo.setMinVal(mZoomMin);
+                mScaleInfo.setMaxVal(mZoomMax);
+                mMouseMarkStartX = LeftMargin;
+                Point dim = getSize();
+                mMouseMarkEndX = dim.x - RightMargin;
+                mTimescale.setMarkStart(mMouseMarkStartX);
+                mTimescale.setMarkEnd(mMouseMarkEndX);
+                getDisplay().timerExec(ZOOM_TIMER_INTERVAL, mZoomAnimator);
+            } else {
+                // Zoom in slowly at first, then speed up, then slow down.
+                // The zoom fractions are precomputed to save time.
+                double fraction = mZoomFractions[mZoomStep];
+                mMouseMarkStartX = (int) (mZoomMouseStart - fraction * mMouseStartDistance);
+                mMouseMarkEndX = (int) (mZoomMouseEnd + fraction * mMouseEndDistance);
+                mTimescale.setMarkStart(mMouseMarkStartX);
+                mTimescale.setMarkEnd(mMouseMarkEndX);
+
+                // Compute the new pixels-per-range. Avoid division by zero.
+                double ppr;
+                if (mZoomMin2Fixed >= mFixed2ZoomMax)
+                    ppr = (mZoomFixedPixel - mMouseMarkStartX) / mZoomMin2Fixed;
+                else
+                    ppr = (mMouseMarkEndX - mZoomFixedPixel) / mFixed2ZoomMax;
+                double newMin = mZoomFixed - mFixedPixelStartDistance / ppr;
+                double newMax = mZoomFixed + mFixedPixelEndDistance / ppr;
+                mScaleInfo.setMinVal(newMin);
+                mScaleInfo.setMaxVal(newMax);
+
+                getDisplay().timerExec(ZOOM_TIMER_INTERVAL, mZoomAnimator);
+            }
+            redraw();
+        }
+
+        private static final int TotalXMargin = LeftMargin + RightMargin;
+        private static final int yMargin = 1; // blank space on top
+        // The minimum margin on each side of the zoom window, in pixels.
+        private static final int MinZoomPixelMargin = 10;
+        private GraphicsState mGraphicsState = GraphicsState.Normal;
+        private Point mMouse = new Point(LeftMargin, 0);
+        private int mMouseMarkStartX;
+        private int mMouseMarkEndX;
+        private boolean mDebug = false;
+        private ArrayList<Strip> mStripList = new ArrayList<Strip>();
+        private ArrayList<Range> mHighlightExclusive = new ArrayList<Range>();
+        private ArrayList<Range> mHighlightInclusive = new ArrayList<Range>();
+        private int mMinStripHeight = 2;
+        private double mCachedMinVal;
+        private double mCachedMaxVal;
+        private int mCachedStartRow;
+        private int mCachedEndRow;
+        private double mScalePixelsPerRange;
+        private double mScaleMinVal;
+        private double mScaleMaxVal;
+        private double mLimitMinVal;
+        private double mLimitMaxVal;
+        private double mMinDataVal;
+        private double mMaxDataVal;
+        private Cursor mNormalCursor;
+        private Cursor mIncreasingCursor;
+        private Cursor mDecreasingCursor;
+        private static final int ZOOM_TIMER_INTERVAL = 10;
+        private static final int HIGHLIGHT_TIMER_INTERVAL = 50;
+        private static final int ZOOM_STEPS = 8; // must be even
+        private int highlightHeight = 4;
+        private final int[] highlightHeights = { 0, 2, 4, 5, 6, 5, 4, 2, 4, 5,
+                6 };
+        private final int HIGHLIGHT_STEPS = highlightHeights.length;
+        private boolean mFadeColors;
+        private boolean mShowHighlightName;
+        private double[] mZoomFractions;
+        private int mZoomStep;
+        private int mZoomMouseStart;
+        private int mZoomMouseEnd;
+        private int mMouseStartDistance;
+        private int mMouseEndDistance;
+        private Point mMouseSelect = new Point(0, 0);
+        private double mZoomFixed;
+        private double mZoomFixedPixel;
+        private double mFixedPixelStartDistance;
+        private double mFixedPixelEndDistance;
+        private double mZoomMin2Fixed;
+        private double mMin2ZoomMin;
+        private double mFixed2ZoomMax;
+        private double mZoomMax2Max;
+        private double mZoomMin;
+        private double mZoomMax;
+        private Runnable mZoomAnimator;
+        private Runnable mHighlightAnimator;
+        private int mHighlightStep;
+    }
+
+    private int computeVisibleRows(int ydim) {
+        // If we resize, then move the bottom row down.  Don't allow the scroll
+        // to waste space at the bottom.
+        int offsetY = mScrollOffsetY;
+        int spaceNeeded = mNumRows * rowYSpace;
+        if (offsetY + ydim > spaceNeeded) {
+            offsetY = spaceNeeded - ydim;
+            if (offsetY < 0) {
+                offsetY = 0;
+            }
+        }
+        mStartRow = offsetY / rowYSpace;
+        mEndRow = (offsetY + ydim) / rowYSpace;
+        if (mEndRow >= mNumRows) {
+            mEndRow = mNumRows - 1;
+        }
+        
+        return offsetY;
+    }
+
+    private void startHighlighting() {
+        // System.out.printf("startHighlighting()\n");
+        mSurface.mHighlightStep = 0;
+        mSurface.mFadeColors = true;
+        // Force a recomputation of the color strips
+        mSurface.mCachedEndRow = -1;
+        getDisplay().timerExec(0, mSurface.mHighlightAnimator);
+    }
+
+    private static class RowData {
+        RowData(Row row) {
+            mName = row.getName();
+            mStack = new ArrayList<Block>();
+        }
+
+        public void push(Block block) {
+            mStack.add(block);
+        }
+
+        public Block top() {
+            if (mStack.size() == 0)
+                return null;
+            return mStack.get(mStack.size() - 1);
+        }
+
+        public void pop() {
+            if (mStack.size() == 0)
+                return;
+            mStack.remove(mStack.size() - 1);
+        }
+
+        private String mName;
+        private int mRank;
+        private long mElapsed;
+        private long mEndTime;
+        private ArrayList<Block> mStack;
+    }
+
+    private static class Segment {
+        Segment(RowData rowData, Block block, long startTime, long endTime) {
+            mRowData = rowData;
+            mBlock = block;
+            mStartTime = startTime;
+            mEndTime = endTime;
+        }
+
+        private RowData mRowData;
+        private Block mBlock;
+        private long mStartTime;
+        private long mEndTime;
+    }
+
+    private static class Strip {
+        Strip(int x, int y, int width, int height, RowData rowData,
+                Segment segment, Color color) {
+            mX = x;
+            mY = y;
+            mWidth = width;
+            mHeight = height;
+            mRowData = rowData;
+            mSegment = segment;
+            mColor = color;
+        }
+
+        int mX;
+        int mY;
+        int mWidth;
+        int mHeight;
+        RowData mRowData;
+        Segment mSegment;
+        Color mColor;
+    }
+
+    private static class Pixel {
+        public void setFields(int start, double weight, Segment segment,
+                Color color, RowData rowData) {
+            mStart = start;
+            mMaxWeight = weight;
+            mSegment = segment;
+            mColor = color;
+            mRowData = rowData;
+        }
+
+        int mStart = -2; // some value that won't match another pixel
+        double mMaxWeight;
+        Segment mSegment;
+        Color mColor; // we need the color here because it may be faded
+        RowData mRowData;
+    }
+
+    private static class Range {
+        Range(int xStart, int width, int y, Color color) {
+            mXdim.x = xStart;
+            mXdim.y = width;
+            mY = y;
+            mColor = color;
+        }
+
+        Point mXdim = new Point(0, 0);
+        int mY;
+        Color mColor;
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/TraceReader.java b/tools/traceview/src/com/android/traceview/TraceReader.java
new file mode 100644
index 0000000..ae75876
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/TraceReader.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public abstract class TraceReader {
+
+    private TraceUnits mTraceUnits;
+
+    public TraceUnits getTraceUnits() {
+        if (mTraceUnits == null)
+            mTraceUnits = new TraceUnits();
+        return mTraceUnits;
+    }
+
+    public ArrayList<TimeLineView.Record> getThreadTimeRecords() {
+        return null;
+    }
+
+    public HashMap<Integer, String> getThreadLabels() {
+        return null;
+    }
+
+    public MethodData[] getMethods() {
+        return null;
+    }
+
+    public ThreadData[] getThreads() {
+        return null;
+    }
+
+    public long getEndTime() {
+        return 0;
+    }
+
+    public ProfileProvider getProfileProvider() {
+        return null;
+    }
+}
diff --git a/tools/traceview/src/com/android/traceview/TraceUnits.java b/tools/traceview/src/com/android/traceview/TraceUnits.java
new file mode 100644
index 0000000..20938f5
--- /dev/null
+++ b/tools/traceview/src/com/android/traceview/TraceUnits.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.traceview;
+
+import java.text.DecimalFormat;
+
+// This should be a singleton.
+public class TraceUnits {
+
+    private TimeScale mTimeScale = TimeScale.MicroSeconds;
+    private double mScale = 1.0;
+    DecimalFormat mFormatter = new DecimalFormat();
+
+    public double getScaledValue(long value) {
+        return value * mScale;
+    }
+
+    public double getScaledValue(double value) {
+        return value * mScale;
+    }
+
+    public String valueOf(long value) {
+        return valueOf((double) value);
+    }
+
+    public String valueOf(double value) {
+        String pattern;
+        double scaled = value * mScale;
+        if ((int) scaled == scaled)
+            pattern = "###,###";
+        else
+            pattern = "###,###.###";
+        mFormatter.applyPattern(pattern);
+        return mFormatter.format(scaled);
+    }
+
+    public String labelledString(double value) {
+        String units = label();
+        String num = valueOf(value);
+        return String.format("%s: %s", units, num);
+    }
+
+    public String labelledString(long value) {
+        return labelledString((double) value);
+    }
+
+    public String label() {
+        if (mScale == 1.0)
+            return "usec";
+        if (mScale == 0.001)
+            return "msec";
+        if (mScale == 0.000001)
+            return "sec";
+        return null;
+    }
+
+    public void setTimeScale(TimeScale val) {
+        mTimeScale = val;
+        switch (val) {
+        case Seconds:
+            mScale = 0.000001;
+            break;
+        case MilliSeconds:
+            mScale = 0.001;
+            break;
+        case MicroSeconds:
+            mScale = 1.0;
+            break;
+        }
+    }
+
+    public TimeScale getTimeScale() {
+        return mTimeScale;
+    }
+
+    public enum TimeScale {
+        Seconds, MilliSeconds, MicroSeconds
+    };
+}
diff --git a/tools/traceview/src/resources/icons/sort_down.png b/tools/traceview/src/resources/icons/sort_down.png
new file mode 100644
index 0000000..de6a2a0
--- /dev/null
+++ b/tools/traceview/src/resources/icons/sort_down.png
Binary files differ
diff --git a/tools/traceview/src/resources/icons/sort_up.png b/tools/traceview/src/resources/icons/sort_up.png
new file mode 100644
index 0000000..8578a87
--- /dev/null
+++ b/tools/traceview/src/resources/icons/sort_up.png
Binary files differ
diff --git a/tools/zoneinfo/ZoneCompactor.java b/tools/zoneinfo/ZoneCompactor.java
new file mode 100644
index 0000000..eea7dd4
--- /dev/null
+++ b/tools/zoneinfo/ZoneCompactor.java
@@ -0,0 +1,158 @@
+
+import java.io.*;
+import java.util.*;
+
+// usage: java ZoneCompiler <setup file> <top-level directory>
+//
+// Compile a set of tzfile-formatted files into a single file plus
+// an index file.
+//
+// The compilation is controlled by a setup file, which is provided as a
+// command-line argument.  The setup file has the form:
+//
+// Link <toName> <fromName>
+// ...
+// <zone filename>
+// ...
+//
+// Note that the links must be declared prior to the zone names.  A
+// zone name is a filename relative to the source directory such as
+// 'GMT', 'Africa/Dakar', or 'America/Argentina/Jujuy'.
+//
+// Use the 'zic' command-line tool to convert from flat files
+// (e.g., 'africa', 'northamerica') into a suitable source directory
+// hierarchy for this tool (e.g., 'data/Africa/Abidjan').
+//
+// Example:
+//     zic -d data tz2007h
+//     javac ZoneCompactor.java
+//     java ZoneCompactor setup data
+//     <produces zoneinfo.dat and zoneinfo.idx>
+
+public class ZoneCompactor {
+
+    // Zone name synonyms
+    Map<String,String> links = new HashMap<String,String>();
+
+    // File starting bytes by zone name
+    Map<String,Integer> starts = new HashMap<String,Integer>();
+
+    // File lengths by zone name
+    Map<String,Integer> lengths = new HashMap<String,Integer>();
+
+    // Raw GMT offsets by zone name
+    Map<String,Integer> offsets = new HashMap<String,Integer>();
+    int start = 0;
+
+    // Maximum number of characters in a zone name, including '\0' terminator
+    private static final int MAXNAME = 40;
+
+    // Concatenate the contents of 'inFile' onto 'out'
+    private static void copyFile(File inFile, OutputStream out)
+        throws Exception {
+        InputStream in = new FileInputStream(inFile);
+        byte[] buf = new byte[8192];
+        while (true) {
+            int nbytes = in.read(buf);
+            if (nbytes == -1) {
+                break;
+            }
+            out.write(buf, 0, nbytes);
+        }
+        out.flush();
+        return;
+    }
+    
+    // Write a 32-bit integer in network byte order
+    private void writeInt(OutputStream os, int x) throws IOException {
+        os.write((x >> 24) & 0xff);
+        os.write((x >> 16) & 0xff);
+        os.write((x >>  8) & 0xff);
+        os.write( x        & 0xff);
+    }
+
+    public ZoneCompactor(String setupFilename, String dirName)
+        throws Exception {
+        File zoneInfoFile = new File("zoneinfo.dat");
+        zoneInfoFile.delete();
+        OutputStream zoneInfo = new FileOutputStream(zoneInfoFile);
+
+        BufferedReader rdr = new BufferedReader(new FileReader(setupFilename));
+    
+        String s;
+        while ((s = rdr.readLine()) != null) {
+            s = s.trim();
+            if (s.startsWith("Link")) {
+                StringTokenizer st = new StringTokenizer(s);
+                st.nextToken();
+                String to = st.nextToken();
+                String from = st.nextToken();
+                links.put(from, to);
+            } else {
+                String link = links.get(s);
+                if (link == null) {
+                    File f = new File(dirName, s);
+                    long length = f.length();
+                    starts.put(s, new Integer(start));
+                    lengths.put(s, new Integer((int)length));
+
+                    TimeZone tz = TimeZone.getTimeZone(s);
+                    int gmtOffset = tz.getRawOffset();
+                    offsets.put(s, new Integer(gmtOffset));
+
+                    start += length;
+                    copyFile(f, zoneInfo);
+                }
+            }
+        }
+        zoneInfo.close();
+
+        // Fill in fields for links
+        Iterator<String> iter = links.keySet().iterator();
+        while (iter.hasNext()) {
+            String from = iter.next();
+            String to = links.get(from);
+
+            starts.put(from, starts.get(to));
+            lengths.put(from, lengths.get(to));
+            offsets.put(from, offsets.get(to));
+        }
+
+        File idxFile = new File("zoneinfo.idx");
+        idxFile.delete();
+        FileOutputStream idx = new FileOutputStream(idxFile);
+
+        ArrayList l = new ArrayList();
+        l.addAll(starts.keySet());
+        Collections.sort(l);
+        Iterator<String> ziter = l.iterator();
+        while (ziter.hasNext()) {
+            String zname = ziter.next();
+            if (zname.length() >= MAXNAME) {
+                System.err.println("Error - zone filename exceeds " +
+                                   (MAXNAME - 1) + " characters!");
+            }
+
+            byte[] znameBuf = new byte[MAXNAME];
+            for (int i = 0; i < zname.length(); i++) {
+                znameBuf[i] = (byte)zname.charAt(i);
+            }
+            idx.write(znameBuf);
+            writeInt(idx, starts.get(zname).intValue());
+            writeInt(idx, lengths.get(zname).intValue());
+            writeInt(idx, offsets.get(zname).intValue());
+        }
+        idx.close();
+
+        // System.out.println("maxLength = " + maxLength);
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (args.length != 2) {
+            System.err.println("usage: java ZoneCompactor <setup> <data dir>");
+            System.exit(0);
+        }
+        new ZoneCompactor(args[0], args[1]);
+    }
+
+}
diff --git a/tools/zoneinfo/generate b/tools/zoneinfo/generate
new file mode 100755
index 0000000..0b087a8
--- /dev/null
+++ b/tools/zoneinfo/generate
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+version=tzdata2008h
+
+mkdir data
+
+for i in $version/africa \
+    $version/antarctica \
+    $version/asia \
+    $version/australasia \
+    $version/etcetera \
+    $version/europe \
+    $version/factory \
+    $version/northamerica \
+    $version/solar87 \
+    $version/solar88 \
+    $version/solar89 \
+    $version/southamerica
+do
+    zic -d data $i
+done
+
+javac -target 1.5 ZoneCompactor.java
+
+(
+    cat $version/* | grep '^Link' | awk '{print $1, $2, $3}'
+    (
+        cat $version/* | grep '^Zone' | awk '{print $2}'
+        cat $version/* | grep '^Link' | awk '{print $3}'
+    ) | LC_ALL="C" sort
+) | grep -v Riyadh8 > setup
+
+java ZoneCompactor setup data
+
+cp zoneinfo.dat zoneinfo.idx ../../../data/zoneinfo
diff --git a/tools/zoneinfo/tzdata2008h/MODULE_LICENSE_PUBLIC_DOMAIN b/tools/zoneinfo/tzdata2008h/MODULE_LICENSE_PUBLIC_DOMAIN
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/MODULE_LICENSE_PUBLIC_DOMAIN
diff --git a/tools/zoneinfo/tzdata2008h/africa b/tools/zoneinfo/tzdata2008h/africa
new file mode 100644
index 0000000..34a62b9
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/africa
@@ -0,0 +1,840 @@
+# @(#)africa	8.17
+# <pre>
+
+# This data is by no means authoritative; if you think you know better,
+# go ahead and edit the file (and please send any changes to
+# tz@elsie.nci.nih.gov for general use in the future).
+
+# From Paul Eggert (2006-03-22):
+#
+# A good source for time zone historical data outside the U.S. is
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
+# San Diego: ACS Publications, Inc. (2003).
+#
+# Gwillim Law writes that a good source
+# for recent time zone data is the International Air Transport
+# Association's Standard Schedules Information Manual (IATA SSIM),
+# published semiannually.  Law sent in several helpful summaries
+# of the IATA's data after 1990.
+#
+# Except where otherwise noted, Shanks & Pottenger is the source for
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
+#
+# Another source occasionally used is Edward W. Whitman, World Time Differences,
+# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
+# I found in the UCLA library.
+#
+# A reliable and entertaining source about time zones is
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
+#
+# Previous editions of this database used WAT, CAT, SAT, and EAT
+# for +0:00 through +3:00, respectively,
+# but Mark R V Murray reports that
+# `SAST' is the official abbreviation for +2:00 in the country of South Africa,
+# `CAT' is commonly used for +2:00 in countries north of South Africa, and
+# `WAT' is probably the best name for +1:00, as the common phrase for
+# the area that includes Nigeria is ``West Africa''.
+# He has heard of ``Western Sahara Time'' for +0:00 but can find no reference.
+#
+# To make things confusing, `WAT' seems to have been used for -1:00 long ago;
+# I'd guess that this was because people needed _some_ name for -1:00,
+# and at the time, far west Africa was the only major land area in -1:00.
+# This usage is now obsolete, as the last use of -1:00 on the African
+# mainland seems to have been 1976 in Western Sahara.
+#
+# To summarize, the following abbreviations seem to have some currency:
+#	-1:00	WAT	West Africa Time (no longer used)
+#	 0:00	GMT	Greenwich Mean Time
+#	 2:00	CAT	Central Africa Time
+#	 2:00	SAST	South Africa Standard Time
+# and Murray suggests the following abbreviation:
+#	 1:00	WAT	West Africa Time
+# I realize that this leads to `WAT' being used for both -1:00 and 1:00
+# for times before 1976, but this is the best I can think of
+# until we get more information.
+#
+# I invented the following abbreviations; corrections are welcome!
+#	 2:00	WAST	West Africa Summer Time
+#	 2:30	BEAT	British East Africa Time (no longer used)
+#	 2:44:45 BEAUT	British East Africa Unified Time (no longer used)
+#	 3:00	CAST	Central Africa Summer Time (no longer used)
+#	 3:00	SAST	South Africa Summer Time (no longer used)
+#	 3:00	EAT	East Africa Time
+#	 4:00	EAST	East Africa Summer Time (no longer used)
+
+# Algeria
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Algeria	1916	only	-	Jun	14	23:00s	1:00	S
+Rule	Algeria	1916	1919	-	Oct	Sun>=1	23:00s	0	-
+Rule	Algeria	1917	only	-	Mar	24	23:00s	1:00	S
+Rule	Algeria	1918	only	-	Mar	 9	23:00s	1:00	S
+Rule	Algeria	1919	only	-	Mar	 1	23:00s	1:00	S
+Rule	Algeria	1920	only	-	Feb	14	23:00s	1:00	S
+Rule	Algeria	1920	only	-	Oct	23	23:00s	0	-
+Rule	Algeria	1921	only	-	Mar	14	23:00s	1:00	S
+Rule	Algeria	1921	only	-	Jun	21	23:00s	0	-
+Rule	Algeria	1939	only	-	Sep	11	23:00s	1:00	S
+Rule	Algeria	1939	only	-	Nov	19	 1:00	0	-
+Rule	Algeria	1944	1945	-	Apr	Mon>=1	 2:00	1:00	S
+Rule	Algeria	1944	only	-	Oct	 8	 2:00	0	-
+Rule	Algeria	1945	only	-	Sep	16	 1:00	0	-
+Rule	Algeria	1971	only	-	Apr	25	23:00s	1:00	S
+Rule	Algeria	1971	only	-	Sep	26	23:00s	0	-
+Rule	Algeria	1977	only	-	May	 6	 0:00	1:00	S
+Rule	Algeria	1977	only	-	Oct	21	 0:00	0	-
+Rule	Algeria	1978	only	-	Mar	24	 1:00	1:00	S
+Rule	Algeria	1978	only	-	Sep	22	 3:00	0	-
+Rule	Algeria	1980	only	-	Apr	25	 0:00	1:00	S
+Rule	Algeria	1980	only	-	Oct	31	 2:00	0	-
+# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
+# more precise 0:09:21.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Algiers	0:12:12 -	LMT	1891 Mar 15 0:01
+			0:09:21	-	PMT	1911 Mar 11    # Paris Mean Time
+			0:00	Algeria	WE%sT	1940 Feb 25 2:00
+			1:00	Algeria	CE%sT	1946 Oct  7
+			0:00	-	WET	1956 Jan 29
+			1:00	-	CET	1963 Apr 14
+			0:00	Algeria	WE%sT	1977 Oct 21
+			1:00	Algeria	CE%sT	1979 Oct 26
+			0:00	Algeria	WE%sT	1981 May
+			1:00	-	CET
+
+# Angola
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Luanda	0:52:56	-	LMT	1892
+			0:52:04	-	AOT	1911 May 26 # Angola Time
+			1:00	-	WAT
+
+# Benin
+# Whitman says they switched to 1:00 in 1946, not 1934;
+# go with Shanks & Pottenger.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Porto-Novo	0:10:28	-	LMT	1912
+			0:00	-	GMT	1934 Feb 26
+			1:00	-	WAT
+
+# Botswana
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Gaborone	1:43:40 -	LMT	1885
+			2:00	-	CAT	1943 Sep 19 2:00
+			2:00	1:00	CAST	1944 Mar 19 2:00
+			2:00	-	CAT
+
+# Burkina Faso
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Ouagadougou	-0:06:04 -	LMT	1912
+			 0:00	-	GMT
+
+# Burundi
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Bujumbura	1:57:28	-	LMT	1890
+			2:00	-	CAT
+
+# Cameroon
+# Whitman says they switched to 1:00 in 1920; go with Shanks & Pottenger.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Douala	0:38:48	-	LMT	1912
+			1:00	-	WAT
+
+# Cape Verde
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Atlantic/Cape_Verde -1:34:04 -	LMT	1907			# Praia
+			-2:00	-	CVT	1942 Sep
+			-2:00	1:00	CVST	1945 Oct 15
+			-2:00	-	CVT	1975 Nov 25 2:00
+			-1:00	-	CVT
+
+# Central African Republic
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Bangui	1:14:20	-	LMT	1912
+			1:00	-	WAT
+
+# Chad
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Ndjamena	1:00:12 -	LMT	1912
+			1:00	-	WAT	1979 Oct 14
+			1:00	1:00	WAST	1980 Mar  8
+			1:00	-	WAT
+
+# Comoros
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Indian/Comoro	2:53:04 -	LMT	1911 Jul   # Moroni, Gran Comoro
+			3:00	-	EAT
+
+# Democratic Republic of Congo
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Kinshasa	1:01:12 -	LMT	1897 Nov 9
+			1:00	-	WAT
+Zone Africa/Lubumbashi	1:49:52 -	LMT	1897 Nov 9
+			2:00	-	CAT
+
+# Republic of the Congo
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Brazzaville	1:01:08 -	LMT	1912
+			1:00	-	WAT
+
+# Cote D'Ivoire
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Abidjan	-0:16:08 -	LMT	1912
+			 0:00	-	GMT
+
+# Djibouti
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Djibouti	2:52:36 -	LMT	1911 Jul
+			3:00	-	EAT
+
+###############################################################################
+
+# Egypt
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Egypt	1940	only	-	Jul	15	0:00	1:00	S
+Rule	Egypt	1940	only	-	Oct	 1	0:00	0	-
+Rule	Egypt	1941	only	-	Apr	15	0:00	1:00	S
+Rule	Egypt	1941	only	-	Sep	16	0:00	0	-
+Rule	Egypt	1942	1944	-	Apr	 1	0:00	1:00	S
+Rule	Egypt	1942	only	-	Oct	27	0:00	0	-
+Rule	Egypt	1943	1945	-	Nov	 1	0:00	0	-
+Rule	Egypt	1945	only	-	Apr	16	0:00	1:00	S
+Rule	Egypt	1957	only	-	May	10	0:00	1:00	S
+Rule	Egypt	1957	1958	-	Oct	 1	0:00	0	-
+Rule	Egypt	1958	only	-	May	 1	0:00	1:00	S
+Rule	Egypt	1959	1981	-	May	 1	1:00	1:00	S
+Rule	Egypt	1959	1965	-	Sep	30	3:00	0	-
+Rule	Egypt	1966	1994	-	Oct	 1	3:00	0	-
+Rule	Egypt	1982	only	-	Jul	25	1:00	1:00	S
+Rule	Egypt	1983	only	-	Jul	12	1:00	1:00	S
+Rule	Egypt	1984	1988	-	May	 1	1:00	1:00	S
+Rule	Egypt	1989	only	-	May	 6	1:00	1:00	S
+Rule	Egypt	1990	1994	-	May	 1	1:00	1:00	S
+# IATA (after 1990) says transitions are at 0:00.
+# Go with IATA starting in 1995, except correct 1995 entry from 09-30 to 09-29.
+Rule	Egypt	1995	max	-	Apr	lastFri	 0:00s	1:00	S
+Rule	Egypt	1995	2005	-	Sep	lastThu	23:00s	0	-
+# From Steffen Thorsen (2006-09-19):
+# The Egyptian Gazette, issue 41,090 (2006-09-18), page 1, reports:
+# Egypt will turn back clocks by one hour at the midnight of Thursday
+# after observing the daylight saving time since May.
+# http://news.gom.com.eg/gazette/pdf/2006/09/18/01.pdf
+Rule	Egypt	2006	only	-	Sep	21	23:00s	0	-
+# From Dirk Losch (2007-08-14):
+# I received a mail from an airline which says that the daylight
+# saving time in Egypt will end in the night of 2007-09-06 to 2007-09-07.
+# From Jesper Norgaard Welen (2007-08-15): [The following agree:]
+# http://www.nentjes.info/Bill/bill5.htm 
+# http://www.timeanddate.com/worldclock/city.html?n=53
+# From Steffen Thorsen (2007-09-04): The official information...:
+# http://www.sis.gov.eg/En/EgyptOnline/Miscellaneous/000002/0207000000000000001580.htm
+Rule	Egypt	2007	only	-	Sep	Thu>=1	23:00s	0	-
+# From Abdelrahman Hassan (2007-09-06):
+# Due to the Hijri (lunar Islamic calendar) year being 11 days shorter
+# than the year of the Gregorian calendar, Ramadan shifts earlier each
+# year. This year it will be observed September 13 (September is quite
+# hot in Egypt), and the idea is to make fasting easier for workers by
+# shifting business hours one hour out of daytime heat. Consequently,
+# unless discontinued, next DST may end Thursday 28 August 2008.
+# From Paul Eggert (2007-08-17):
+# For lack of better info, assume the new rule is last Thursday in August.
+Rule	Egypt	2008	max	-	Aug	lastThu	23:00s	0	-
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Cairo	2:05:00 -	LMT	1900 Oct
+			2:00	Egypt	EE%sT
+
+# Equatorial Guinea
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Malabo	0:35:08 -	LMT	1912
+			0:00	-	GMT	1963 Dec 15
+			1:00	-	WAT
+
+# Eritrea
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Asmara	2:35:32 -	LMT	1870
+			2:35:32	-	AMT	1890	      # Asmara Mean Time
+			2:35:20	-	ADMT	1936 May 5    # Adis Dera MT
+			3:00	-	EAT
+
+# Ethiopia
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger write that Ethiopia had six narrowly-spaced time zones
+# between 1870 and 1890, and that they merged to 38E50 (2:35:20) in 1890.
+# We'll guess that 38E50 is for Adis Dera.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Addis_Ababa	2:34:48 -	LMT	1870
+			2:35:20	-	ADMT	1936 May 5    # Adis Dera MT
+			3:00	-	EAT
+
+# Gabon
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Libreville	0:37:48 -	LMT	1912
+			1:00	-	WAT
+
+# Gambia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Banjul	-1:06:36 -	LMT	1912
+			-1:06:36 -	BMT	1935	# Banjul Mean Time
+			-1:00	-	WAT	1964
+			 0:00	-	GMT
+
+# Ghana
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# Whitman says DST was observed from 1931 to ``the present'';
+# go with Shanks & Pottenger.
+Rule	Ghana	1936	1942	-	Sep	 1	0:00	0:20	GHST
+Rule	Ghana	1936	1942	-	Dec	31	0:00	0	GMT
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Accra	-0:00:52 -	LMT	1918
+			 0:00	Ghana	%s
+
+# Guinea
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Conakry	-0:54:52 -	LMT	1912
+			 0:00	-	GMT	1934 Feb 26
+			-1:00	-	WAT	1960
+			 0:00	-	GMT
+
+# Guinea-Bissau
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Bissau	-1:02:20 -	LMT	1911 May 26
+			-1:00	-	WAT	1975
+			 0:00	-	GMT
+
+# Kenya
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Nairobi	2:27:16	-	LMT	1928 Jul
+			3:00	-	EAT	1930
+			2:30	-	BEAT	1940
+			2:44:45	-	BEAUT	1960
+			3:00	-	EAT
+
+# Lesotho
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Maseru	1:50:00 -	LMT	1903 Mar
+			2:00	-	SAST	1943 Sep 19 2:00
+			2:00	1:00	SAST	1944 Mar 19 2:00
+			2:00	-	SAST
+
+# Liberia
+# From Paul Eggert (2006-03-22):
+# In 1972 Liberia was the last country to switch
+# from a UTC offset that was not a multiple of 15 or 20 minutes.
+# Howse reports that it was in honor of their president's birthday.
+# Shank & Pottenger report the date as May 1, whereas Howse reports Jan;
+# go with Shanks & Pottenger.
+# For Liberia before 1972, Shanks & Pottenger report -0:44, whereas Howse and
+# Whitman each report -0:44:30; go with the more precise figure.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Monrovia	-0:43:08 -	LMT	1882
+			-0:43:08 -	MMT	1919 Mar # Monrovia Mean Time
+			-0:44:30 -	LRT	1972 May # Liberia Time
+			 0:00	-	GMT
+
+###############################################################################
+
+# Libya
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Libya	1951	only	-	Oct	14	2:00	1:00	S
+Rule	Libya	1952	only	-	Jan	 1	0:00	0	-
+Rule	Libya	1953	only	-	Oct	 9	2:00	1:00	S
+Rule	Libya	1954	only	-	Jan	 1	0:00	0	-
+Rule	Libya	1955	only	-	Sep	30	0:00	1:00	S
+Rule	Libya	1956	only	-	Jan	 1	0:00	0	-
+Rule	Libya	1982	1984	-	Apr	 1	0:00	1:00	S
+Rule	Libya	1982	1985	-	Oct	 1	0:00	0	-
+Rule	Libya	1985	only	-	Apr	 6	0:00	1:00	S
+Rule	Libya	1986	only	-	Apr	 4	0:00	1:00	S
+Rule	Libya	1986	only	-	Oct	 3	0:00	0	-
+Rule	Libya	1987	1989	-	Apr	 1	0:00	1:00	S
+Rule	Libya	1987	1989	-	Oct	 1	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Tripoli	0:52:44 -	LMT	1920
+			1:00	Libya	CE%sT	1959
+			2:00	-	EET	1982
+			1:00	Libya	CE%sT	1990 May  4
+# The following entries are from Shanks & Pottenger;
+# the IATA SSIM data contain some obvious errors.
+			2:00	-	EET	1996 Sep 30
+			1:00	-	CET	1997 Apr  4
+			1:00	1:00	CEST	1997 Oct  4
+			2:00	-	EET
+
+# Madagascar
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Indian/Antananarivo 3:10:04 -	LMT	1911 Jul
+			3:00	-	EAT	1954 Feb 27 23:00s
+			3:00	1:00	EAST	1954 May 29 23:00s
+			3:00	-	EAT
+
+# Malawi
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Blantyre	2:20:00 -	LMT	1903 Mar
+			2:00	-	CAT
+
+# Mali
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Bamako	-0:32:00 -	LMT	1912
+			 0:00	-	GMT	1934 Feb 26
+			-1:00	-	WAT	1960 Jun 20
+			 0:00	-	GMT
+
+# Mauritania
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Nouakchott	-1:03:48 -	LMT	1912
+			 0:00	-	GMT	1934 Feb 26
+			-1:00	-	WAT	1960 Nov 28
+			 0:00	-	GMT
+
+# Mauritius
+
+# From Steffen Thorsen (2008-06-25):
+# Mauritius plans to observe DST from 2008-11-01 to 2009-03-31 on a trial
+# basis....
+# It seems that Mauritius observed daylight saving time from 1982-10-10 to 
+# 1983-03-20 as well, but that was not successful....
+# http://www.timeanddate.com/news/time/mauritius-daylight-saving-time.html
+
+# From Alex Krivenyshev (2008-06-25):
+# http://economicdevelopment.gov.mu/portal/site/Mainhomepage/menuitem.a42b24128104d9845dabddd154508a0c/?content_id=0a7cee8b5d69a110VgnVCM1000000a04a8c0RCRD
+
+# From Arthur David Olson (2008-06-30):
+# The www.timeanddate.com article cited by Steffen Thorsen notes that "A
+# final decision has yet to be made on the times that daylight saving
+# would begin and end on these dates." As a place holder, use midnight.
+
+# From Paul Eggert (2008-06-30):
+# Follow Thorsen on DST in 1982/1983, instead of Shanks & Pottenger.
+
+# From Steffen Thorsen (2008-07-10):
+# According to
+# <a href="http://www.lexpress.mu/display_article.php?news_id=111216">
+# http://www.lexpress.mu/display_article.php?news_id=111216
+# </a>
+# (in French), Mauritius will start and end their DST a few days earlier
+# than previously announced (2008-11-01 to 2009-03-31).  The new start
+# date is 2008-10-26 at 02:00 and the new end date is 2009-03-27 (no time
+# given, but it is probably at either 2 or 3 wall clock time).
+# 
+# A little strange though, since the article says that they moved the date 
+# to align itself with Europe and USA which also change time on that date, 
+# but that means they have not paid attention to what happened in 
+# USA/Canada last year (DST ends first Sunday in November). I also wonder 
+# why that they end on a Friday, instead of aligning with Europe which 
+# changes two days later.
+
+# From Alex Krivenyshev (2008-07-11):
+# Seems that English language article "The revival of daylight saving
+# time:  Energy conservation?"-# No. 16578 (07/11/2008) was originally
+# published on Monday, June 30, 2008...
+#
+# I guess that article in French "Le gouvernement avance l'introduction
+# de l'heure d'ete" stating that DST in Mauritius starting on October 26
+# and ending on March 27, 2009 is the most recent one.
+# ...
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_mauritius02.html">
+# http://www.worldtimezone.com/dst_news/dst_news_mauritius02.html
+# </a>
+
+# From Riad M. Hossen Ally (2008-08-03):
+# The Government of Mauritius weblink
+# <a href="http://www.gov.mu/portal/site/pmosite/menuitem.4ca0efdee47462e7440a600248a521ca/?content_id=3D4728ca68b2a5b110VgnVCM1000000a04a8c0RCRD">
+# http://www.gov.mu/portal/site/pmosite/menuitem.4ca0efdee47462e7440a600248a521ca/?content_id=3D4728ca68b2a5b110VgnVCM1000000a04a8c0RCRD
+# </a>
+# Cabinet Decision of July 18th, 2008 states as follows:
+#
+# 4. ...Cabinet has agreed to the introduction into the National Assembly
+# of the Time Bill which provides for the introduction of summer time in
+# Mauritius. The summer time period which will be of one hour ahead of
+# the standard time, will be aligned with that in Europe and the United
+# States of America. It will start at two o'clock in the morning on the
+# last Sunday of October and will end at two o'clock in the morning on
+# the last Sunday of March the following year. The summer time for the
+# year 2008 - 2009 will, therefore, be effective as from 26 October 2008
+# and end on 29 March 2009.
+
+# From Ed Maste (2008-10-07):
+# THE TIME BILL (No. XXVII of 2008) Explanatory Memorandum states the
+# beginning / ending of summer time is 2 o'clock standard time in the
+# morning of the last Sunday of October / last Sunday of March.
+# <a href="http://www.gov.mu/portal/goc/assemblysite/file/bill2708.pdf">
+# http://www.gov.mu/portal/goc/assemblysite/file/bill2708.pdf
+# </a>
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule Mauritius	1982	only	-	Oct	10	0:00	1:00	S
+Rule Mauritius	1983	only	-	Mar	21	0:00	0	-
+Rule Mauritius	2008	max	-	Oct	lastSun	2:00s	1:00	S
+Rule Mauritius	2009	max	-	Mar	lastSun	2:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Indian/Mauritius	3:50:00 -	LMT	1907		# Port Louis
+			4:00 Mauritius	MU%sT	# Mauritius Time
+# Agalega Is, Rodriguez
+# no information; probably like Indian/Mauritius
+
+# Mayotte
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Indian/Mayotte	3:00:56 -	LMT	1911 Jul	# Mamoutzou
+			3:00	-	EAT
+
+# Morocco
+# See the `europe' file for Spanish Morocco (Africa/Ceuta).
+
+# From Alex Krivenyshev (2008-05-09):
+# Here is an article that Morocco plan to introduce Daylight Saving Time between
+# 1 June, 2008 and 27 September, 2008.
+#
+# "... Morocco is to save energy by adjusting its clock during summer so it will
+# be one hour ahead of GMT between 1 June and 27 September, according to
+# Communication Minister and Gov ernment Spokesman, Khalid Naciri...."
+#
+# <a href="http://www.worldtimezone.net/dst_news/dst_news_morocco01.html">
+# http://www.worldtimezone.net/dst_news/dst_news_morocco01.html
+# </a>
+# OR
+# <a href="http://en.afrik.com/news11892.html">
+# http://en.afrik.com/news11892.html
+# </a>
+
+# From Alex Krivenyshev (2008-05-09):
+# The Morocco time change can be confirmed on Morocco web site Maghreb Arabe Presse:
+# <a href="http://www.map.ma/eng/sections/box3/morocco_shifts_to_da/view">
+# http://www.map.ma/eng/sections/box3/morocco_shifts_to_da/view
+# </a>
+#
+# Morocco shifts to daylight time on June 1st through September 27, Govt.
+# spokesman.
+
+# From Patrice Scattolin (2008-05-09):
+# According to this article:
+# <a href="http://www.avmaroc.com/actualite/heure-dete-comment-a127896.html">
+# http://www.avmaroc.com/actualite/heure-dete-comment-a127896.html
+# </a>
+# (and republished here:
+# <a href="http://www.actu.ma/heure-dete-comment_i127896_0.html">
+# http://www.actu.ma/heure-dete-comment_i127896_0.html
+# </a>
+# )
+# the changes occurs at midnight:
+#
+# saturday night may 31st at midnight (which in french is to be
+# intrepreted as the night between saturday and sunday)
+# sunday night the 28th  at midnight
+#
+# Seeing that the 28th is monday, I am guessing that she intends to say
+# the midnight of the 28th which is the midnight between sunday and
+# monday, which jives with other sources that say that it's inclusive
+# june1st to sept 27th.
+#
+# The decision was taken by decree *2-08-224 *but I can't find the decree
+# published on the web.
+#
+# It's also confirmed here:
+# <a href="http://www.maroc.ma/NR/exeres/FACF141F-D910-44B0-B7FA-6E03733425D1.htm">
+# http://www.maroc.ma/NR/exeres/FACF141F-D910-44B0-B7FA-6E03733425D1.htm
+# </a>
+# on a government portal as being  between june 1st and sept 27th (not yet
+# posted in english).
+#
+# The following google query will generate many relevant hits:
+# <a href="http://www.google.com/search?hl=en&q=Conseil+de+gouvernement+maroc+heure+avance&btnG=Search">
+# http://www.google.com/search?hl=en&q=Conseil+de+gouvernement+maroc+heure+avance&btnG=Search
+# </a>
+
+# From Alex Krivenyshev (2008-05-09):
+# Is Western Sahara (part which administrated by Morocco) going to follow
+# Morocco DST changes?  Any information?  What about other part of
+# Western Sahara - under administration of POLISARIO Front (also named
+# SADR Saharawi Arab Democratic Republic)?
+
+# From Arthur David Olson (2008-05-09):
+# XXX--guess that it is only Morocco for now; guess only 2008 for now.
+
+# From Steffen Thorsen (2008-08-27):
+# Morocco will change the clocks back on the midnight between August 31 
+# and September 1. They originally planned to observe DST to near the end 
+# of September:
+#
+# One article about it (in French):
+# <a href="http://www.menara.ma/fr/Actualites/Maroc/Societe/ci.retour_a_l_heure_gmt_a_partir_du_dimanche_31_aout_a_minuit_officiel_.default">
+# http://www.menara.ma/fr/Actualites/Maroc/Societe/ci.retour_a_l_heure_gmt_a_partir_du_dimanche_31_aout_a_minuit_officiel_.default
+# </a>
+#
+# We have some further details posted here:
+# <a href="http://www.timeanddate.com/news/time/morocco-ends-dst-early-2008.html">
+# http://www.timeanddate.com/news/time/morocco-ends-dst-early-2008.html
+# </a>
+# RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+
+Rule	Morocco	1939	only	-	Sep	12	 0:00	1:00	S
+Rule	Morocco	1939	only	-	Nov	19	 0:00	0	-
+Rule	Morocco	1940	only	-	Feb	25	 0:00	1:00	S
+Rule	Morocco	1945	only	-	Nov	18	 0:00	0	-
+Rule	Morocco	1950	only	-	Jun	11	 0:00	1:00	S
+Rule	Morocco	1950	only	-	Oct	29	 0:00	0	-
+Rule	Morocco	1967	only	-	Jun	 3	12:00	1:00	S
+Rule	Morocco	1967	only	-	Oct	 1	 0:00	0	-
+Rule	Morocco	1974	only	-	Jun	24	 0:00	1:00	S
+Rule	Morocco	1974	only	-	Sep	 1	 0:00	0	-
+Rule	Morocco	1976	1977	-	May	 1	 0:00	1:00	S
+Rule	Morocco	1976	only	-	Aug	 1	 0:00	0	-
+Rule	Morocco	1977	only	-	Sep	28	 0:00	0	-
+Rule	Morocco	1978	only	-	Jun	 1	 0:00	1:00	S
+Rule	Morocco	1978	only	-	Aug	 4	 0:00	0	-
+Rule	Morocco	2008	only	-	Jun	 1	 0:00	1:00	S
+Rule	Morocco	2008	only	-	Sep	 1	 0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Casablanca	-0:30:20 -	LMT	1913 Oct 26
+			 0:00	Morocco	WE%sT	1984 Mar 16
+			 1:00	-	CET	1986
+			 0:00	Morocco	WE%sT
+# Western Sahara
+Zone Africa/El_Aaiun	-0:52:48 -	LMT	1934 Jan
+			-1:00	-	WAT	1976 Apr 14
+			 0:00	-	WET
+
+# Mozambique
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Maputo	2:10:20 -	LMT	1903 Mar
+			2:00	-	CAT
+
+# Namibia
+# The 1994-04-03 transition is from Shanks & Pottenger.
+# Shanks & Pottenger report no DST after 1998-04; go with IATA.
+
+# From Petronella Sibeene (2007-03-30) in
+# <http://allafrica.com/stories/200703300178.html>:
+# While the entire country changes its time, Katima Mulilo and other
+# settlements in Caprivi unofficially will not because the sun there
+# rises and sets earlier compared to other regions.  Chief of
+# Forecasting Riaan van Zyl explained that the far eastern parts of
+# the country are close to 40 minutes earlier in sunrise than the rest
+# of the country.
+# 
+# From Paul Eggert (2007-03-31):
+# Apparently the Caprivi Strip informally observes Botswana time, but
+# we have no details.  In the meantime people there can use Africa/Gaborone.
+
+# RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Namibia	1994	max	-	Sep	Sun>=1	2:00	1:00	S
+Rule	Namibia	1995	max	-	Apr	Sun>=1	2:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Windhoek	1:08:24 -	LMT	1892 Feb 8
+			1:30	-	SWAT	1903 Mar	# SW Africa Time
+			2:00	-	SAST	1942 Sep 20 2:00
+			2:00	1:00	SAST	1943 Mar 21 2:00
+			2:00	-	SAST	1990 Mar 21 # independence
+			2:00	-	CAT	1994 Apr  3
+			1:00	Namibia	WA%sT
+
+# Niger
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Niamey	 0:08:28 -	LMT	1912
+			-1:00	-	WAT	1934 Feb 26
+			 0:00	-	GMT	1960
+			 1:00	-	WAT
+
+# Nigeria
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Lagos	0:13:36 -	LMT	1919 Sep
+			1:00	-	WAT
+
+# Reunion
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Indian/Reunion	3:41:52 -	LMT	1911 Jun	# Saint-Denis
+			4:00	-	RET	# Reunion Time
+#
+# Scattered Islands (Iles Eparses) administered from Reunion are as follows.
+# The following information about them is taken from
+# Iles Eparses (www.outre-mer.gouv.fr/domtom/ile.htm, 1997-07-22, in French;
+# no longer available as of 1999-08-17).
+# We have no info about their time zone histories.
+#
+# Bassas da India - uninhabited
+# Europa Island - inhabited from 1905 to 1910 by two families
+# Glorioso Is - inhabited until at least 1958
+# Juan de Nova - uninhabited
+# Tromelin - inhabited until at least 1958
+
+# Rwanda
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Kigali	2:00:16 -	LMT	1935 Jun
+			2:00	-	CAT
+
+# St Helena
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Atlantic/St_Helena	-0:22:48 -	LMT	1890		# Jamestown
+			-0:22:48 -	JMT	1951	# Jamestown Mean Time
+			 0:00	-	GMT
+# The other parts of the St Helena territory are similar:
+#	Tristan da Cunha: on GMT, say Whitman and the CIA
+#	Ascension: on GMT, says usno1995 and the CIA
+#	Gough (scientific station since 1955; sealers wintered previously):
+#		on GMT, says the CIA
+#	Inaccessible, Nightingale: no information, but probably GMT
+
+# Sao Tome and Principe
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Sao_Tome	 0:26:56 -	LMT	1884
+			-0:36:32 -	LMT	1912	# Lisbon Mean Time
+			 0:00	-	GMT
+
+# Senegal
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Dakar	-1:09:44 -	LMT	1912
+			-1:00	-	WAT	1941 Jun
+			 0:00	-	GMT
+
+# Seychelles
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Indian/Mahe	3:41:48 -	LMT	1906 Jun	# Victoria
+			4:00	-	SCT	# Seychelles Time
+# From Paul Eggert (2001-05-30):
+# Aldabra, Farquhar, and Desroches, originally dependencies of the
+# Seychelles, were transferred to the British Indian Ocean Territory
+# in 1965 and returned to Seychelles control in 1976.  We don't know
+# whether this affected their time zone, so omit this for now.
+# Possibly the islands were uninhabited.
+
+# Sierra Leone
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# Whitman gives Mar 31 - Aug 31 for 1931 on; go with Shanks & Pottenger.
+Rule	SL	1935	1942	-	Jun	 1	0:00	0:40	SLST
+Rule	SL	1935	1942	-	Oct	 1	0:00	0	WAT
+Rule	SL	1957	1962	-	Jun	 1	0:00	1:00	SLST
+Rule	SL	1957	1962	-	Sep	 1	0:00	0	GMT
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Freetown	-0:53:00 -	LMT	1882
+			-0:53:00 -	FMT	1913 Jun # Freetown Mean Time
+			-1:00	SL	%s	1957
+			 0:00	SL	%s
+
+# Somalia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Mogadishu	3:01:28 -	LMT	1893 Nov
+			3:00	-	EAT	1931
+			2:30	-	BEAT	1957
+			3:00	-	EAT
+
+# South Africa
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	SA	1942	1943	-	Sep	Sun>=15	2:00	1:00	-
+Rule	SA	1943	1944	-	Mar	Sun>=15	2:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Johannesburg 1:52:00 -	LMT	1892 Feb 8
+			1:30	-	SAST	1903 Mar
+			2:00	SA	SAST
+# Marion and Prince Edward Is
+# scientific station since 1947
+# no information
+
+# Sudan
+#
+# From <a href="http://www.sunanews.net/sn13jane.html">
+# Sudan News Agency (2000-01-13)
+# </a>, also reported by Michael De Beukelaer-Dossche via Steffen Thorsen:
+# Clocks will be moved ahead for 60 minutes all over the Sudan as of noon
+# Saturday....  This was announced Thursday by Caretaker State Minister for
+# Manpower Abdul-Rahman Nur-Eddin.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Sudan	1970	only	-	May	 1	0:00	1:00	S
+Rule	Sudan	1970	1985	-	Oct	15	0:00	0	-
+Rule	Sudan	1971	only	-	Apr	30	0:00	1:00	S
+Rule	Sudan	1972	1985	-	Apr	lastSun	0:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Khartoum	2:10:08 -	LMT	1931
+			2:00	Sudan	CA%sT	2000 Jan 15 12:00
+			3:00	-	EAT
+
+# Swaziland
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Mbabane	2:04:24 -	LMT	1903 Mar
+			2:00	-	SAST
+
+# Tanzania
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Africa/Dar_es_Salaam 2:37:08 -	LMT	1931
+			3:00	-	EAT	1948
+			2:44:45	-	BEAUT	1961
+			3:00	-	EAT
+
+# Togo
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Lome	0:04:52 -	LMT	1893
+			0:00	-	GMT
+
+# Tunisia
+
+# From Gwillim Law (2005-04-30):
+# My correspondent, Risto Nykanen, has alerted me to another adoption of DST,
+# this time in Tunisia.  According to Yahoo France News
+# <http://fr.news.yahoo.com/050426/5/4dumk.html>, in a story attributed to AP
+# and dated 2005-04-26, "Tunisia has decided to advance its official time by
+# one hour, starting on Sunday, May 1.  Henceforth, Tunisian time will be
+# UTC+2 instead of UTC+1.  The change will take place at 23:00 UTC next
+# Saturday."  (My translation)
+#
+# From Oscar van Vlijmen (2005-05-02):
+# LaPresse, the first national daily newspaper ...
+# <http://www.lapresse.tn/archives/archives280405/actualites/lheure.html>
+# ... DST for 2005: on: Sun May 1 0h standard time, off: Fri Sept. 30,
+# 1h standard time.
+#
+# From Atef Loukil (2006-03-28):
+# The daylight saving time will be the same each year:
+# Beginning      : the last Sunday of March at 02:00
+# Ending         : the last Sunday of October at 03:00 ...
+# http://www.tap.info.tn/en/index.php?option=com_content&task=view&id=1188&Itemid=50
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Tunisia	1939	only	-	Apr	15	23:00s	1:00	S
+Rule	Tunisia	1939	only	-	Nov	18	23:00s	0	-
+Rule	Tunisia	1940	only	-	Feb	25	23:00s	1:00	S
+Rule	Tunisia	1941	only	-	Oct	 6	 0:00	0	-
+Rule	Tunisia	1942	only	-	Mar	 9	 0:00	1:00	S
+Rule	Tunisia	1942	only	-	Nov	 2	 3:00	0	-
+Rule	Tunisia	1943	only	-	Mar	29	 2:00	1:00	S
+Rule	Tunisia	1943	only	-	Apr	17	 2:00	0	-
+Rule	Tunisia	1943	only	-	Apr	25	 2:00	1:00	S
+Rule	Tunisia	1943	only	-	Oct	 4	 2:00	0	-
+Rule	Tunisia	1944	1945	-	Apr	Mon>=1	 2:00	1:00	S
+Rule	Tunisia	1944	only	-	Oct	 8	 0:00	0	-
+Rule	Tunisia	1945	only	-	Sep	16	 0:00	0	-
+Rule	Tunisia	1977	only	-	Apr	30	 0:00s	1:00	S
+Rule	Tunisia	1977	only	-	Sep	24	 0:00s	0	-
+Rule	Tunisia	1978	only	-	May	 1	 0:00s	1:00	S
+Rule	Tunisia	1978	only	-	Oct	 1	 0:00s	0	-
+Rule	Tunisia	1988	only	-	Jun	 1	 0:00s	1:00	S
+Rule	Tunisia	1988	1990	-	Sep	lastSun	 0:00s	0	-
+Rule	Tunisia	1989	only	-	Mar	26	 0:00s	1:00	S
+Rule	Tunisia	1990	only	-	May	 1	 0:00s	1:00	S
+Rule	Tunisia	2005	only	-	May	 1	 0:00s	1:00	S
+Rule	Tunisia	2005	only	-	Sep	30	 1:00s	0	-
+Rule	Tunisia	2006	max	-	Mar	lastSun	 2:00s	1:00	S
+Rule	Tunisia	2006	max	-	Oct	lastSun	 2:00s	0	-
+# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
+# more precise 0:09:21.
+# Shanks & Pottenger say the 1911 switch was on Mar 9; go with Howse's Mar 11.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Tunis	0:40:44 -	LMT	1881 May 12
+			0:09:21	-	PMT	1911 Mar 11    # Paris Mean Time
+			1:00	Tunisia	CE%sT
+
+# Uganda
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Kampala	2:09:40 -	LMT	1928 Jul
+			3:00	-	EAT	1930
+			2:30	-	BEAT	1948
+			2:44:45	-	BEAUT	1957
+			3:00	-	EAT
+
+# Zambia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Lusaka	1:53:08 -	LMT	1903 Mar
+			2:00	-	CAT
+
+# Zimbabwe
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Africa/Harare	2:04:12 -	LMT	1903 Mar
+			2:00	-	CAT
diff --git a/tools/zoneinfo/tzdata2008h/antarctica b/tools/zoneinfo/tzdata2008h/antarctica
new file mode 100644
index 0000000..ef279cb
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/antarctica
@@ -0,0 +1,327 @@
+# @(#)antarctica	8.4
+# <pre>
+
+# From Paul Eggert (1999-11-15):
+# To keep things manageable, we list only locations occupied year-round; see
+# <a href="http://www.comnap.aq/comnap/comnap.nsf/P/Stations/">
+# COMNAP - Stations and Bases
+# </a>
+# and
+# <a href="http://www.spri.cam.ac.uk/bob/periant.htm">
+# Summary of the Peri-Antarctic Islands (1998-07-23)
+# </a>
+# for information.
+# Unless otherwise specified, we have no time zone information.
+#
+# Except for the French entries,
+# I made up all time zone abbreviations mentioned here; corrections welcome!
+# FORMAT is `zzz' and GMTOFF is 0 for locations while uninhabited.
+
+# These rules are stolen from the `europe' file.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	RussAQ	1981	1984	-	Apr	 1	 0:00	1:00	S
+Rule	RussAQ	1981	1983	-	Oct	 1	 0:00	0	-
+Rule	RussAQ	1984	1991	-	Sep	lastSun	 2:00s	0	-
+Rule	RussAQ	1985	1991	-	Mar	lastSun	 2:00s	1:00	S
+Rule	RussAQ	1992	only	-	Mar	lastSat	 23:00	1:00	S
+Rule	RussAQ	1992	only	-	Sep	lastSat	 23:00	0	-
+Rule	RussAQ	1993	max	-	Mar	lastSun	 2:00s	1:00	S
+Rule	RussAQ	1993	1995	-	Sep	lastSun	 2:00s	0	-
+Rule	RussAQ	1996	max	-	Oct	lastSun	 2:00s	0	-
+
+# These rules are stolen from the `southamerica' file.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	ArgAQ	1964	1966	-	Mar	 1	0:00	0	-
+Rule	ArgAQ	1964	1966	-	Oct	15	0:00	1:00	S
+Rule	ArgAQ	1967	only	-	Apr	 2	0:00	0	-
+Rule	ArgAQ	1967	1968	-	Oct	Sun>=1	0:00	1:00	S
+Rule	ArgAQ	1968	1969	-	Apr	Sun>=1	0:00	0	-
+Rule	ArgAQ	1974	only	-	Jan	23	0:00	1:00	S
+Rule	ArgAQ	1974	only	-	May	 1	0:00	0	-
+Rule	ChileAQ	1972	1986	-	Mar	Sun>=9	3:00u	0	-
+Rule	ChileAQ	1974	1987	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	ChileAQ	1987	only	-	Apr	12	3:00u	0	-
+Rule	ChileAQ	1988	1989	-	Mar	Sun>=9	3:00u	0	-
+Rule	ChileAQ	1988	only	-	Oct	Sun>=1	4:00u	1:00	S
+Rule	ChileAQ	1989	only	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	ChileAQ	1990	only	-	Mar	18	3:00u	0	-
+Rule	ChileAQ	1990	only	-	Sep	16	4:00u	1:00	S
+Rule	ChileAQ	1991	1996	-	Mar	Sun>=9	3:00u	0	-
+Rule	ChileAQ	1991	1997	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	ChileAQ	1997	only	-	Mar	30	3:00u	0	-
+Rule	ChileAQ	1998	only	-	Mar	Sun>=9	3:00u	0	-
+Rule	ChileAQ	1998	only	-	Sep	27	4:00u	1:00	S
+Rule	ChileAQ	1999	only	-	Apr	 4	3:00u	0	-
+Rule	ChileAQ	1999	max	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	ChileAQ	2000	max	-	Mar	Sun>=9	3:00u	0	-
+
+
+# Argentina - year-round bases
+# Belgrano II, Confin Coast, -770227-0343737, since 1972-02-05
+# Esperanza, San Martin Land, -6323-05659, since 1952-12-17
+# Jubany, Potter Peninsula, King George Island, -6414-0602320, since 1982-01
+# Marambio, Seymour I, -6414-05637, since 1969-10-29
+# Orcadas, Laurie I, -6016-04444, since 1904-02-22
+# San Martin, Debenham I, -6807-06708, since 1951-03-21
+#	(except 1960-03 / 1976-03-21)
+
+# Australia - territories
+# Heard Island, McDonald Islands (uninhabited)
+#	previously sealers and scientific personnel wintered
+#	<a href="http://web.archive.org/web/20021204222245/http://www.dstc.qut.edu.au/DST/marg/daylight.html">
+#	Margaret Turner reports
+#	</a> (1999-09-30) that they're UTC+5, with no DST;
+#	presumably this is when they have visitors.
+#
+# year-round bases
+# Casey, Bailey Peninsula, -6617+11032, since 1969
+# Davis, Vestfold Hills, -6835+07759, since 1957-01-13
+#	(except 1964-11 - 1969-02)
+# Mawson, Holme Bay, -6736+06253, since 1954-02-13
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/Casey	0	-	zzz	1969
+			8:00	-	WST	# Western (Aus) Standard Time
+Zone Antarctica/Davis	0	-	zzz	1957 Jan 13
+			7:00	-	DAVT	1964 Nov # Davis Time
+			0	-	zzz	1969 Feb
+			7:00	-	DAVT
+Zone Antarctica/Mawson	0	-	zzz	1954 Feb 13
+			6:00	-	MAWT	# Mawson Time
+# References:
+# <a href="http://www.antdiv.gov.au/aad/exop/sfo/casey/casey_aws.html">
+# Casey Weather (1998-02-26)
+# </a>
+# <a href="http://www.antdiv.gov.au/aad/exop/sfo/davis/video.html">
+# Davis Station, Antarctica (1998-02-26)
+# </a>
+# <a href="http://www.antdiv.gov.au/aad/exop/sfo/mawson/video.html">
+# Mawson Station, Antarctica (1998-02-25)
+# </a>
+
+# Brazil - year-round base
+# Comandante Ferraz, King George Island, -6205+05824, since 1983/4
+
+# Chile - year-round bases and towns
+# Escudero, South Shetland Is, -621157-0585735, since 1994
+# Presidente Eduadro Frei, King George Island, -6214-05848, since 1969-03-07
+# General Bernardo O'Higgins, Antarctic Peninsula, -6319-05704, since 1948-02
+# Capitan Arturo Prat, -6230-05941
+# Villa Las Estrellas (a town), around the Frei base, since 1984-04-09
+# These locations have always used Santiago time; use TZ='America/Santiago'.
+
+# China - year-round bases
+# Great Wall, King George Island, -6213-05858, since 1985-02-20
+# Zhongshan, Larsemann Hills, Prydz Bay, -6922+07623, since 1989-02-26
+
+# France - year-round bases
+#
+# From Antoine Leca (1997-01-20):
+# Time data are from Nicole Pailleau at the IFRTP
+# (French Institute for Polar Research and Technology).
+# She confirms that French Southern Territories and Terre Adelie bases
+# don't observe daylight saving time, even if Terre Adelie supplies came
+# from Tasmania.
+#
+# French Southern Territories with year-round inhabitants
+#
+# Martin-de-Vivies Base, Amsterdam Island, -374105+0773155, since 1950
+# Alfred-Faure Base, Crozet Islands, -462551+0515152, since 1964
+# Port-aux-Francais, Kerguelen Islands, -492110+0701303, since 1951;
+#	whaling & sealing station operated 1908/1914, 1920/1929, and 1951/1956
+#
+# St Paul Island - near Amsterdam, uninhabited
+#	fishing stations operated variously 1819/1931
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Indian/Kerguelen	0	-	zzz	1950	# Port-aux-Francais
+			5:00	-	TFT	# ISO code TF Time
+#
+# year-round base in the main continent
+# Dumont-d'Urville, Ile des Petrels, -6640+14001, since 1956-11
+#
+# Another base at Port-Martin, 50km east, began operation in 1947.
+# It was destroyed by fire on 1952-01-14.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/DumontDUrville 0 -	zzz	1947
+			10:00	-	PMT	1952 Jan 14 # Port-Martin Time
+			0	-	zzz	1956 Nov
+			10:00	-	DDUT	# Dumont-d'Urville Time
+# Reference:
+# <a href="http://en.wikipedia.org/wiki/Dumont_d'Urville_Station">
+# Dumont d'Urville Station (2005-12-05)
+# </a>
+
+# Germany - year-round base
+# Georg von Neumayer, -7039-00815
+
+# India - year-round base
+# Dakshin Gangotri, -7005+01200
+
+# Japan - year-round bases
+# Dome Fuji, -7719+03942
+# Syowa, -690022+0393524
+#
+# From Hideyuki Suzuki (1999-02-06):
+# In all Japanese stations, +0300 is used as the standard time.
+#
+# Syowa station, which is the first antarctic station of Japan,
+# was established on 1957-01-29.  Since Syowa station is still the main
+# station of Japan, it's appropriate for the principal location.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/Syowa	0	-	zzz	1957 Jan 29
+			3:00	-	SYOT	# Syowa Time
+# See:
+# <a href="http://www.nipr.ac.jp/english/ara01.html">
+# NIPR Antarctic Research Activities (1999-08-17)
+# </a>
+
+# S Korea - year-round base
+# King Sejong, King George Island, -6213-05847, since 1988
+
+# New Zealand - claims
+# Balleny Islands (never inhabited)
+# Scott Island (never inhabited)
+#
+# year-round base
+# Scott, Ross Island, since 1957-01, is like Antarctica/McMurdo.
+#
+# These rules for New Zealand are stolen from the `australasia' file.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	NZAQ	1974	only	-	Nov	 3	2:00s	1:00	D
+Rule	NZAQ	1975	1988	-	Oct	lastSun	2:00s	1:00	D
+Rule	NZAQ	1989	only	-	Oct	 8	2:00s	1:00	D
+Rule	NZAQ	1990	2006	-	Oct	Sun>=1	2:00s	1:00	D
+Rule	NZAQ	1975	only	-	Feb	23	2:00s	0	S
+Rule	NZAQ	1976	1989	-	Mar	Sun>=1	2:00s	0	S
+Rule	NZAQ	1990	2007	-	Mar	Sun>=15	2:00s	0	S
+Rule	NZAQ	2007	max	-	Sep	lastSun	2:00s	1:00	D
+Rule	NZAQ	2008	max	-	Apr	Sun>=1	2:00s	0	S
+
+# Norway - territories
+# Bouvet (never inhabited)
+#
+# claims
+# Peter I Island (never inhabited)
+
+# Poland - year-round base
+# Arctowski, King George Island, -620945-0582745, since 1977
+
+# Russia - year-round bases
+# Bellingshausen, King George Island, -621159-0585337, since 1968-02-22
+# Mirny, Davis coast, -6633+09301, since 1956-02
+# Molodezhnaya, Alasheyev Bay, -6740+04551,
+#	year-round from 1962-02 to 1999-07-01
+# Novolazarevskaya, Queen Maud Land, -7046+01150,
+#	year-round from 1960/61 to 1992
+
+# Vostok, since 1957-12-16, temporarily closed 1994-02/1994-11
+# <a href="http://quest.arc.nasa.gov/antarctica/QA/computers/Directions,Time,ZIP">
+# From Craig Mundell (1994-12-15)</a>:
+# Vostok, which is one of the Russian stations, is set on the same
+# time as Moscow, Russia.
+#
+# From Lee Hotz (2001-03-08):
+# I queried the folks at Columbia who spent the summer at Vostok and this is
+# what they had to say about time there:
+# ``in the US Camp (East Camp) we have been on New Zealand (McMurdo)
+# time, which is 12 hours ahead of GMT. The Russian Station Vostok was
+# 6 hours behind that (although only 2 miles away, i.e. 6 hours ahead
+# of GMT). This is a time zone I think two hours east of Moscow. The
+# natural time zone is in between the two: 8 hours ahead of GMT.''
+#
+# From Paul Eggert (2001-05-04):
+# This seems to be hopelessly confusing, so I asked Lee Hotz about it
+# in person.  He said that some Antartic locations set their local
+# time so that noon is the warmest part of the day, and that this
+# changes during the year and does not necessarily correspond to mean
+# solar noon.  So the Vostok time might have been whatever the clocks
+# happened to be during their visit.  So we still don't really know what time
+# it is at Vostok.  But we'll guess UTC+6.
+#
+Zone Antarctica/Vostok	0	-	zzz	1957 Dec 16
+			6:00	-	VOST	# Vostok time
+
+# S Africa - year-round bases
+# Marion Island, -4653+03752
+# Sanae, -7141-00250
+
+# UK
+#
+# British Antarctic Territories (BAT) claims
+# South Orkney Islands
+#	scientific station from 1903
+#	whaling station at Signy I 1920/1926
+# South Shetland Islands
+#
+# year-round bases
+# Bird Island, South Georgia, -5400-03803, since 1983
+# Deception Island, -6259-06034, whaling station 1912/1931,
+#	scientific station 1943/1967,
+#	previously sealers and a scientific expedition wintered by accident,
+#	and a garrison was deployed briefly
+# Halley, Coates Land, -7535-02604, since 1956-01-06
+#	Halley is on a moving ice shelf and is periodically relocated
+#	so that it is never more than 10km from its nominal location.
+# Rothera, Adelaide Island, -6734-6808, since 1976-12-01
+#
+# From Paul Eggert (2002-10-22)
+# <http://webexhibits.org/daylightsaving/g.html> says Rothera is -03 all year.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/Rothera	0	-	zzz	1976 Dec  1
+			-3:00	-	ROTT	# Rothera time
+
+# Uruguay - year round base
+# Artigas, King George Island, -621104-0585107
+
+# USA - year-round bases
+#
+# Palmer, Anvers Island, since 1965 (moved 2 miles in 1968)
+#
+# From Ethan Dicks (1996-10-06):
+# It keeps the same time as Punta Arenas, Chile, because, just like us
+# and the South Pole, that's the other end of their supply line....
+# I verified with someone who was there that since 1980,
+# Palmer has followed Chile.  Prior to that, before the Falklands War,
+# Palmer used to be supplied from Argentina.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/Palmer	0	-	zzz	1965
+			-4:00	ArgAQ	AR%sT	1969 Oct 5
+			-3:00	ArgAQ	AR%sT	1982 May
+			-4:00	ChileAQ	CL%sT
+#
+#
+# McMurdo, Ross Island, since 1955-12
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/McMurdo	0	-	zzz	1956
+			12:00	NZAQ	NZ%sT
+#
+# Amundsen-Scott, South Pole, continuously occupied since 1956-11-20
+#
+# From Paul Eggert (1996-09-03):
+# Normally it wouldn't have a separate entry, since it's like the
+# larger Antarctica/McMurdo since 1970, but it's too famous to omit.
+#
+# From Chris Carrier (1996-06-27):
+# Siple, the first commander of the South Pole station,
+# stated that he would have liked to have kept GMT at the station,
+# but that he found it more convenient to keep GMT+12
+# as supplies for the station were coming from McMurdo Sound,
+# which was on GMT+12 because New Zealand was on GMT+12 all year
+# at that time (1957).  (Source: Siple's book 90 degrees SOUTH.)
+#
+# From Susan Smith
+# http://www.cybertours.com/whs/pole10.html
+# (1995-11-13 16:24:56 +1300, no longer available):
+# We use the same time as McMurdo does.
+# And they use the same time as Christchurch, NZ does....
+# One last quirk about South Pole time.
+# All the electric clocks are usually wrong.
+# Something about the generators running at 60.1hertz or something
+# makes all of the clocks run fast.  So every couple of days,
+# we have to go around and set them back 5 minutes or so.
+# Maybe if we let them run fast all of the time, we'd get to leave here sooner!!
+#
+Link	Antarctica/McMurdo	Antarctica/South_Pole
diff --git a/tools/zoneinfo/tzdata2008h/asia b/tools/zoneinfo/tzdata2008h/asia
new file mode 100644
index 0000000..eb9f411
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/asia
@@ -0,0 +1,2043 @@
+# @(#)asia	8.24
+# <pre>
+
+# This data is by no means authoritative; if you think you know better,
+# go ahead and edit the file (and please send any changes to
+# tz@elsie.nci.nih.gov for general use in the future).
+
+# From Paul Eggert (2006-03-22):
+#
+# A good source for time zone historical data outside the U.S. is
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
+# San Diego: ACS Publications, Inc. (2003).
+#
+# Gwillim Law writes that a good source
+# for recent time zone data is the International Air Transport
+# Association's Standard Schedules Information Manual (IATA SSIM),
+# published semiannually.  Law sent in several helpful summaries
+# of the IATA's data after 1990.
+#
+# Except where otherwise noted, Shanks & Pottenger is the source for
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
+#
+# Another source occasionally used is Edward W. Whitman, World Time Differences,
+# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
+# I found in the UCLA library.
+#
+# A reliable and entertaining source about time zones is
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
+#
+# I invented the abbreviations marked `*' in the following table;
+# the rest are from earlier versions of this file, or from other sources.
+# Corrections are welcome!
+#	     std  dst
+#	     LMT	Local Mean Time
+#	2:00 EET  EEST	Eastern European Time
+#	2:00 IST  IDT	Israel
+#	3:00 AST  ADT	Arabia*
+#	3:30 IRST IRDT	Iran
+#	4:00 GST	Gulf*
+#	5:30 IST	India
+#	7:00 ICT	Indochina*
+#	7:00 WIT	west Indonesia
+#	8:00 CIT	central Indonesia
+#	8:00 CST	China
+#	9:00 CJT	Central Japanese Time (1896/1937)*
+#	9:00 EIT	east Indonesia
+#	9:00 JST  JDT	Japan
+#	9:00 KST  KDT	Korea
+#	9:30 CST	(Australian) Central Standard Time
+#
+# See the `europe' file for Russia and Turkey in Asia.
+
+# From Guy Harris:
+# Incorporates data for Singapore from Robert Elz' asia 1.1, as well as
+# additional information from Tom Yap, Sun Microsystems Intercontinental
+# Technical Support (including a page from the Official Airline Guide -
+# Worldwide Edition).  The names for time zones are guesses.
+
+###############################################################################
+
+# These rules are stolen from the `europe' file.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	EUAsia	1981	max	-	Mar	lastSun	 1:00u	1:00	S
+Rule	EUAsia	1979	1995	-	Sep	lastSun	 1:00u	0	-
+Rule	EUAsia	1996	max	-	Oct	lastSun	 1:00u	0	-
+Rule E-EurAsia	1981	max	-	Mar	lastSun	 0:00	1:00	S
+Rule E-EurAsia	1979	1995	-	Sep	lastSun	 0:00	0	-
+Rule E-EurAsia	1996	max	-	Oct	lastSun	 0:00	0	-
+Rule RussiaAsia	1981	1984	-	Apr	1	 0:00	1:00	S
+Rule RussiaAsia	1981	1983	-	Oct	1	 0:00	0	-
+Rule RussiaAsia	1984	1991	-	Sep	lastSun	 2:00s	0	-
+Rule RussiaAsia	1985	1991	-	Mar	lastSun	 2:00s	1:00	S
+Rule RussiaAsia	1992	only	-	Mar	lastSat	23:00	1:00	S
+Rule RussiaAsia	1992	only	-	Sep	lastSat	23:00	0	-
+Rule RussiaAsia	1993	max	-	Mar	lastSun	 2:00s	1:00	S
+Rule RussiaAsia	1993	1995	-	Sep	lastSun	 2:00s	0	-
+Rule RussiaAsia	1996	max	-	Oct	lastSun	 2:00s	0	-
+
+# Afghanistan
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Kabul	4:36:48 -	LMT	1890
+			4:00	-	AFT	1945
+			4:30	-	AFT
+
+# Armenia
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger have Yerevan switching to 3:00 (with Russian DST)
+# in spring 1991, then to 4:00 with no DST in fall 1995, then
+# readopting Russian DST in 1997.  Go with Shanks & Pottenger, even
+# when they disagree with others.  Edgar Der-Danieliantz
+# reported (1996-05-04) that Yerevan probably wouldn't use DST
+# in 1996, though it did use DST in 1995.  IATA SSIM (1991/1998) reports that
+# Armenia switched from 3:00 to 4:00 in 1998 and observed DST after 1991,
+# but started switching at 3:00s in 1998.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Yerevan	2:58:00 -	LMT	1924 May  2
+			3:00	-	YERT	1957 Mar    # Yerevan Time
+			4:00 RussiaAsia YER%sT	1991 Mar 31 2:00s
+			3:00	1:00	YERST	1991 Sep 23 # independence
+			3:00 RussiaAsia	AM%sT	1995 Sep 24 2:00s
+			4:00	-	AMT	1997
+			4:00 RussiaAsia	AM%sT
+
+# Azerbaijan
+# From Rustam Aliyev of the Azerbaijan Internet Forum (2005-10-23):
+# According to the resolution of Cabinet of Ministers, 1997
+# Resolution available at: http://aif.az/docs/daylight_res.pdf
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Azer	1997	max	-	Mar	lastSun	 4:00	1:00	S
+Rule	Azer	1997	max	-	Oct	lastSun	 5:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Baku	3:19:24 -	LMT	1924 May  2
+			3:00	-	BAKT	1957 Mar    # Baku Time
+			4:00 RussiaAsia BAK%sT	1991 Mar 31 2:00s
+			3:00	1:00	BAKST	1991 Aug 30 # independence
+			3:00 RussiaAsia	AZ%sT	1992 Sep lastSat 23:00
+			4:00	-	AZT	1996 # Azerbaijan time
+			4:00	EUAsia	AZ%sT	1997
+			4:00	Azer	AZ%sT
+
+# Bahrain
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Bahrain	3:22:20 -	LMT	1920		# Al Manamah
+			4:00	-	GST	1972 Jun
+			3:00	-	AST
+
+# Bangladesh
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Dhaka	6:01:40 -	LMT	1890
+			5:53:20	-	HMT	1941 Oct    # Howrah Mean Time?
+			6:30	-	BURT	1942 May 15 # Burma Time
+			5:30	-	IST	1942 Sep
+			6:30	-	BURT	1951 Sep 30
+			6:00	-	DACT	1971 Mar 26 # Dacca Time
+			6:00	-	BDT	# Bangladesh Time
+
+# Bhutan
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Thimphu	5:58:36 -	LMT	1947 Aug 15 # or Thimbu
+			5:30	-	IST	1987 Oct
+			6:00	-	BTT	# Bhutan Time
+
+# British Indian Ocean Territory
+# Whitman and the 1995 CIA time zone map say 5:00, but the
+# 1997 and later maps say 6:00.  Assume the switch occurred in 1996.
+# We have no information as to when standard time was introduced;
+# assume it occurred in 1907, the same year as Mauritius (which
+# then contained the Chagos Archipelago).
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Indian/Chagos	4:49:40	-	LMT	1907
+			5:00	-	IOT	1996 # BIOT Time
+			6:00	-	IOT
+
+# Brunei
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Brunei	7:39:40 -	LMT	1926 Mar   # Bandar Seri Begawan
+			7:30	-	BNT	1933
+			8:00	-	BNT
+
+# Burma / Myanmar
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Rangoon	6:24:40 -	LMT	1880		# or Yangon
+			6:24:36	-	RMT	1920	   # Rangoon Mean Time?
+			6:30	-	BURT	1942 May   # Burma Time
+			9:00	-	JST	1945 May 3
+			6:30	-	MMT		   # Myanmar Time
+
+# Cambodia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Phnom_Penh	6:59:40 -	LMT	1906 Jun  9
+			7:06:20	-	SMT	1911 Mar 11 0:01 # Saigon MT?
+			7:00	-	ICT	1912 May
+			8:00	-	ICT	1931 May
+			7:00	-	ICT
+
+# China
+
+# From Guy Harris:
+# People's Republic of China.  Yes, they really have only one time zone.
+
+# From Bob Devine (1988-01-28):
+# No they don't.  See TIME mag, 1986-02-17 p.52.  Even though
+# China is across 4 physical time zones, before Feb 1, 1986 only the
+# Peking (Bejing) time zone was recognized.  Since that date, China
+# has two of 'em -- Peking's and Urumqi (named after the capital of
+# the Xinjiang Uyghur Autonomous Region).  I don't know about DST for it.
+#
+# . . .I just deleted the DST table and this editor makes it too
+# painful to suck in another copy..  So, here is what I have for
+# DST start/end dates for Peking's time zone (info from AP):
+#
+#     1986 May 4 - Sept 14
+#     1987 mid-April - ??
+
+# From U. S. Naval Observatory (1989-01-19):
+# CHINA               8 H  AHEAD OF UTC  ALL OF CHINA, INCL TAIWAN
+# CHINA               9 H  AHEAD OF UTC  APR 17 - SEP 10
+
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger write that China (except for Hong Kong and Macau)
+# has had a single time zone since 1980 May 1, observing summer DST
+# from 1986 through 1991; this contradicts Devine's
+# note about Time magazine, though apparently _something_ happened in 1986.
+# Go with Shanks & Pottenger for now.  I made up names for the other
+# pre-1980 time zones.
+
+# From Shanks & Pottenger:
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Shang	1940	only	-	Jun	 3	0:00	1:00	D
+Rule	Shang	1940	1941	-	Oct	 1	0:00	0	S
+Rule	Shang	1941	only	-	Mar	16	0:00	1:00	D
+Rule	PRC	1986	only	-	May	 4	0:00	1:00	D
+Rule	PRC	1986	1991	-	Sep	Sun>=11	0:00	0	S
+Rule	PRC	1987	1991	-	Apr	Sun>=10	0:00	1:00	D
+
+# From Anthony Fok (2001-12-20):
+# BTW, I did some research on-line and found some info regarding these five
+# historic timezones from some Taiwan websites.  And yes, there are official
+# Chinese names for these locales (before 1949).
+#
+# From Jesper Norgaard Welen (2006-07-14):
+# I have investigated the timezones around 1970 on the
+# http://www.astro.com/atlas site [with provinces and county
+# boundaries summarized below]....  A few other exceptions were two
+# counties on the Sichuan side of the Xizang-Sichuan border,
+# counties Dege and Baiyu which lies on the Sichuan side and are
+# therefore supposed to be GMT+7, Xizang region being GMT+6, but Dege
+# county is GMT+8 according to astro.com while Baiyu county is GMT+6
+# (could be true), for the moment I am assuming that those two
+# counties are mistakes in the astro.com data.
+
+# From Paul Eggert (2008-02-11):
+# I just now checked Google News for western news sources that talk
+# about China's single time zone, and couldn't find anything before 1986
+# talking about China being in one time zone.  (That article was: Jim
+# Mann, "A clumsy embrace for another western custom: China on daylight
+# time--sort of", Los Angeles Times, 1986-05-05.  By the way, this
+# article confirms the tz database's data claiming that China began
+# observing daylight saving time in 1986.
+#
+# From Thomas S. Mullaney (2008-02-11):
+# I think you're combining two subjects that need to treated 
+# separately: daylight savings (which, you're correct, wasn't 
+# implemented until the 1980s) and the unified time zone centered near 
+# Beijing (which was implemented in 1949). Briefly, there was also a 
+# "Lhasa Time" in Tibet and "Urumqi Time" in Xinjiang. The first was 
+# ceased, and the second eventually recognized (again, in the 1980s).
+#
+# From Paul Eggert (2008-06-30):
+# There seems to be a good chance China switched to a single time zone in 1949
+# rather than in 1980 as Shanks & Pottenger have it, but we don't have a
+# reliable documentary source saying so yet, so for now we still go with
+# Shanks & Pottenger.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# Changbai Time ("Long-white Time", Long-white = Heilongjiang area)
+# Heilongjiang (except Mohe county), Jilin
+Zone	Asia/Harbin	8:26:44	-	LMT	1928 # or Haerbin
+			8:30	-	CHAT	1932 Mar # Changbai Time
+			8:00	-	CST	1940
+			9:00	-	CHAT	1966 May
+			8:30	-	CHAT	1980 May
+			8:00	PRC	C%sT
+# Zhongyuan Time ("Central plain Time")
+# most of China
+Zone	Asia/Shanghai	8:05:52	-	LMT	1928
+			8:00	Shang	C%sT	1949
+			8:00	PRC	C%sT
+# Long-shu Time (probably due to Long and Shu being two names of that area)
+# Guangxi, Guizhou, Hainan, Ningxia, Sichuan, Shaanxi, and Yunnan;
+# most of Gansu; west Inner Mongolia; west Qinghai; and the Guangdong
+# counties Deqing, Enping, Kaiping, Luoding, Taishan, Xinxing,
+# Yangchun, Yangjiang, Yu'nan, and Yunfu.
+Zone	Asia/Chongqing	7:06:20	-	LMT	1928 # or Chungking
+			7:00	-	LONT	1980 May # Long-shu Time
+			8:00	PRC	C%sT
+# Xin-zang Time ("Xinjiang-Tibet Time")
+# The Gansu counties Aksay, Anxi, Dunhuang, Subei; west Qinghai;
+# the Guangdong counties  Xuwen, Haikang, Suixi, Lianjiang,
+# Zhanjiang, Wuchuan, Huazhou, Gaozhou, Maoming, Dianbai, and Xinyi;
+# east Tibet, including Lhasa, Chamdo, Shigaise, Jimsar, Shawan and Hutubi;
+# east Xinjiang, including Urumqi, Turpan, Karamay, Korla, Minfeng, Jinghe,
+# Wusu, Qiemo, Xinyan, Wulanwusu, Jinghe, Yumin, Tacheng, Tuoli, Emin,
+# Shihezi, Changji, Yanqi, Heshuo, Tuokexun, Tulufan, Shanshan, Hami,
+# Fukang, Kuitun, Kumukuli, Miquan, Qitai, and Turfan.
+Zone	Asia/Urumqi	5:50:20	-	LMT	1928 # or Urumchi
+			6:00	-	URUT	1980 May # Urumqi Time
+			8:00	PRC	C%sT
+# Kunlun Time
+# West Tibet, including Pulan, Aheqi, Shufu, Shule;
+# West Xinjiang, including Aksu, Atushi, Yining, Hetian, Cele, Luopu, Nileke,
+# Zhaosu, Tekesi, Gongliu, Chabuchaer, Huocheng, Bole, Pishan, Suiding,
+# and Yarkand.
+Zone	Asia/Kashgar	5:03:56	-	LMT	1928 # or Kashi or Kaxgar
+			5:30	-	KAST	1940	 # Kashgar Time
+			5:00	-	KAST	1980 May
+			8:00	PRC	C%sT
+
+# Hong Kong (Xianggang)
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	HK	1946	only	-	Apr	20	3:30	1:00	S
+Rule	HK	1946	only	-	Dec	1	3:30	0	-
+Rule	HK	1947	only	-	Apr	13	3:30	1:00	S
+Rule	HK	1947	only	-	Dec	30	3:30	0	-
+Rule	HK	1948	only	-	May	2	3:30	1:00	S
+Rule	HK	1948	1952	-	Oct	lastSun	3:30	0	-
+Rule	HK	1949	1953	-	Apr	Sun>=1	3:30	1:00	S
+Rule	HK	1953	only	-	Nov	1	3:30	0	-
+Rule	HK	1954	1964	-	Mar	Sun>=18	3:30	1:00	S
+Rule	HK	1954	only	-	Oct	31	3:30	0	-
+Rule	HK	1955	1964	-	Nov	Sun>=1	3:30	0	-
+Rule	HK	1965	1977	-	Apr	Sun>=16	3:30	1:00	S
+Rule	HK	1965	1977	-	Oct	Sun>=16	3:30	0	-
+Rule	HK	1979	1980	-	May	Sun>=8	3:30	1:00	S
+Rule	HK	1979	1980	-	Oct	Sun>=16	3:30	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Hong_Kong	7:36:36 -	LMT	1904 Oct 30
+			8:00	HK	HK%sT
+
+
+###############################################################################
+
+# Taiwan
+
+# Shanks & Pottenger write that Taiwan observed DST during 1945, when it
+# was still controlled by Japan.  This is hard to believe, but we don't
+# have any other information.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Taiwan	1945	1951	-	May	1	0:00	1:00	D
+Rule	Taiwan	1945	1951	-	Oct	1	0:00	0	S
+Rule	Taiwan	1952	only	-	Mar	1	0:00	1:00	D
+Rule	Taiwan	1952	1954	-	Nov	1	0:00	0	S
+Rule	Taiwan	1953	1959	-	Apr	1	0:00	1:00	D
+Rule	Taiwan	1955	1961	-	Oct	1	0:00	0	S
+Rule	Taiwan	1960	1961	-	Jun	1	0:00	1:00	D
+Rule	Taiwan	1974	1975	-	Apr	1	0:00	1:00	D
+Rule	Taiwan	1974	1975	-	Oct	1	0:00	0	S
+Rule	Taiwan	1980	only	-	Jun	30	0:00	1:00	D
+Rule	Taiwan	1980	only	-	Sep	30	0:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Taipei	8:06:00 -	LMT	1896 # or Taibei or T'ai-pei
+			8:00	Taiwan	C%sT
+
+# Macau (Macao, Aomen)
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Macau	1961	1962	-	Mar	Sun>=16	3:30	1:00	S
+Rule	Macau	1961	1964	-	Nov	Sun>=1	3:30	0	-
+Rule	Macau	1963	only	-	Mar	Sun>=16	0:00	1:00	S
+Rule	Macau	1964	only	-	Mar	Sun>=16	3:30	1:00	S
+Rule	Macau	1965	only	-	Mar	Sun>=16	0:00	1:00	S
+Rule	Macau	1965	only	-	Oct	31	0:00	0	-
+Rule	Macau	1966	1971	-	Apr	Sun>=16	3:30	1:00	S
+Rule	Macau	1966	1971	-	Oct	Sun>=16	3:30	0	-
+Rule	Macau	1972	1974	-	Apr	Sun>=15	0:00	1:00	S
+Rule	Macau	1972	1973	-	Oct	Sun>=15	0:00	0	-
+Rule	Macau	1974	1977	-	Oct	Sun>=15	3:30	0	-
+Rule	Macau	1975	1977	-	Apr	Sun>=15	3:30	1:00	S
+Rule	Macau	1978	1980	-	Apr	Sun>=15	0:00	1:00	S
+Rule	Macau	1978	1980	-	Oct	Sun>=15	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Macau	7:34:20 -	LMT	1912
+			8:00	Macau	MO%sT	1999 Dec 20 # return to China
+			8:00	PRC	C%sT
+
+
+###############################################################################
+
+# Cyprus
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Cyprus	1975	only	-	Apr	13	0:00	1:00	S
+Rule	Cyprus	1975	only	-	Oct	12	0:00	0	-
+Rule	Cyprus	1976	only	-	May	15	0:00	1:00	S
+Rule	Cyprus	1976	only	-	Oct	11	0:00	0	-
+Rule	Cyprus	1977	1980	-	Apr	Sun>=1	0:00	1:00	S
+Rule	Cyprus	1977	only	-	Sep	25	0:00	0	-
+Rule	Cyprus	1978	only	-	Oct	2	0:00	0	-
+Rule	Cyprus	1979	1997	-	Sep	lastSun	0:00	0	-
+Rule	Cyprus	1981	1998	-	Mar	lastSun	0:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Nicosia	2:13:28 -	LMT	1921 Nov 14
+			2:00	Cyprus	EE%sT	1998 Sep
+			2:00	EUAsia	EE%sT
+# IATA SSIM (1998-09) has Cyprus using EU rules for the first time.
+
+# Classically, Cyprus belongs to Asia; e.g. see Herodotus, Histories, I.72.
+# However, for various reasons many users expect to find it under Europe.
+Link	Asia/Nicosia	Europe/Nicosia
+
+# Georgia
+# From Paul Eggert (1994-11-19):
+# Today's _Economist_ (p 60) reports that Georgia moved its clocks forward
+# an hour recently, due to a law proposed by Zurab Murvanidze,
+# an MP who went on a hunger strike for 11 days to force discussion about it!
+# We have no details, but we'll guess they didn't move the clocks back in fall.
+#
+# From Mathew Englander, quoting AP (1996-10-23 13:05-04):
+# Instead of putting back clocks at the end of October, Georgia
+# will stay on daylight savings time this winter to save energy,
+# President Eduard Shevardnadze decreed Wednesday.
+#
+# From the BBC via Joseph S. Myers (2004-06-27):
+#
+# Georgia moved closer to Western Europe on Sunday...  The former Soviet
+# republic has changed its time zone back to that of Moscow.  As a result it
+# is now just four hours ahead of Greenwich Mean Time, rather than five hours
+# ahead.  The switch was decreed by the pro-Western president of Georgia,
+# Mikhail Saakashvili, who said the change was partly prompted by the process
+# of integration into Europe.
+
+# From Teimuraz Abashidze (2005-11-07):
+# Government of Georgia ... decided to NOT CHANGE daylight savings time on
+# [Oct.] 30, as it was done before during last more than 10 years.
+# Currently, we are in fact GMT +4:00, as before 30 October it was GMT
+# +3:00.... The problem is, there is NO FORMAL LAW or governmental document
+# about it.  As far as I can find, I was told, that there is no document,
+# because we just DIDN'T ISSUE document about switching to winter time....
+# I don't know what can be done, especially knowing that some years ago our
+# DST rules where changed THREE TIMES during one month.
+
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Tbilisi	2:59:16 -	LMT	1880
+			2:59:16	-	TBMT	1924 May  2 # Tbilisi Mean Time
+			3:00	-	TBIT	1957 Mar    # Tbilisi Time
+			4:00 RussiaAsia TBI%sT	1991 Mar 31 2:00s
+			3:00	1:00	TBIST	1991 Apr  9 # independence
+			3:00 RussiaAsia GE%sT	1992 # Georgia Time
+			3:00 E-EurAsia	GE%sT	1994 Sep lastSun
+			4:00 E-EurAsia	GE%sT	1996 Oct lastSun
+			4:00	1:00	GEST	1997 Mar lastSun
+			4:00 E-EurAsia	GE%sT	2004 Jun 27
+			3:00 RussiaAsia	GE%sT	2005 Mar lastSun 2:00
+			4:00	-	GET
+
+# East Timor
+
+# See Indonesia for the 1945 transition.
+
+# From Joao Carrascalao, brother of the former governor of East Timor, in
+# <a href="http://etan.org/et99c/december/26-31/30ETMAY.htm">
+# East Timor may be late for its millennium
+# </a> (1999-12-26/31):
+# Portugal tried to change the time forward in 1974 because the sun
+# rises too early but the suggestion raised a lot of problems with the
+# Timorese and I still don't think it would work today because it
+# conflicts with their way of life.
+
+# From Paul Eggert (2000-12-04):
+# We don't have any record of the above attempt.
+# Most likely our records are incomplete, but we have no better data.
+
+# <a href="http://www.hri.org/news/world/undh/last/00-08-16.undh.html">
+# From Manoel de Almeida e Silva, Deputy Spokesman for the UN Secretary-General
+# (2000-08-16)</a>:
+# The Cabinet of the East Timor Transition Administration decided
+# today to advance East Timor's time by one hour.  The time change,
+# which will be permanent, with no seasonal adjustment, will happen at
+# midnight on Saturday, September 16.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Dili	8:22:20 -	LMT	1912
+			8:00	-	TLT	1942 Feb 21 23:00 # E Timor Time
+			9:00	-	JST	1945 Sep 23
+			9:00	-	TLT	1976 May  3
+			8:00	-	CIT	2000 Sep 17 00:00
+			9:00	-	TLT
+
+# India
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Kolkata	5:53:28 -	LMT	1880	# Kolkata
+			5:53:20	-	HMT	1941 Oct    # Howrah Mean Time?
+			6:30	-	BURT	1942 May 15 # Burma Time
+			5:30	-	IST	1942 Sep
+			5:30	1:00	IST	1945 Oct 15
+			5:30	-	IST
+# The following are like Asia/Kolkata:
+#	Andaman Is
+#	Lakshadweep (Laccadive, Minicoy and Amindivi Is)
+#	Nicobar Is
+
+# Indonesia
+#
+# From Gwillim Law (2001-05-28), overriding Shanks & Pottenger:
+# <http://www.sumatera-inc.com/go_to_invest/about_indonesia.asp#standtime>
+# says that Indonesia's time zones changed on 1988-01-01.  Looking at some
+# time zone maps, I think that must refer to Western Borneo (Kalimantan Barat
+# and Kalimantan Tengah) switching from UTC+8 to UTC+7.
+#
+# From Paul Eggert (2007-03-10):
+# Here is another correction to Shanks & Pottenger.
+# JohnTWB writes that Japanese forces did not surrender control in
+# Indonesia until 1945-09-01 00:00 at the earliest (in Jakarta) and
+# other formal surrender ceremonies were September 9, 11, and 13, plus
+# September 12 for the regional surrender to Mountbatten in Singapore.
+# These would be the earliest possible times for a change.
+# Regimes horaires pour le monde entier, by Henri Le Corre, (Editions
+# Traditionnelles, 1987, Paris) says that Java and Madura switched
+# from JST to UTC+07:30 on 1945-09-23, and gives 1944-09-01 for Jayapura
+# (Hollandia).  For now, assume all Indonesian locations other than Jayapura
+# switched on 1945-09-23.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Asia/Jakarta	7:07:12 -	LMT	1867 Aug 10
+# Shanks & Pottenger say the next transition was at 1924 Jan 1 0:13,
+# but this must be a typo.
+			7:07:12	-	JMT	1923 Dec 31 23:47:12 # Jakarta
+			7:20	-	JAVT	1932 Nov	 # Java Time
+			7:30	-	WIT	1942 Mar 23
+			9:00	-	JST	1945 Sep 23
+			7:30	-	WIT	1948 May
+			8:00	-	WIT	1950 May
+			7:30	-	WIT	1964
+			7:00	-	WIT
+Zone Asia/Pontianak	7:17:20	-	LMT	1908 May
+			7:17:20	-	PMT	1932 Nov    # Pontianak MT
+			7:30	-	WIT	1942 Jan 29
+			9:00	-	JST	1945 Sep 23
+			7:30	-	WIT	1948 May
+			8:00	-	WIT	1950 May
+			7:30	-	WIT	1964
+			8:00	-	CIT	1988 Jan  1
+			7:00	-	WIT
+Zone Asia/Makassar	7:57:36 -	LMT	1920
+			7:57:36	-	MMT	1932 Nov    # Macassar MT
+			8:00	-	CIT	1942 Feb  9
+			9:00	-	JST	1945 Sep 23
+			8:00	-	CIT
+Zone Asia/Jayapura	9:22:48 -	LMT	1932 Nov
+			9:00	-	EIT	1944 Sep  1
+			9:30	-	CST	1964
+			9:00	-	EIT
+
+# Iran
+
+# From Roozbeh Pournader (2003-03-15):
+# This is an English translation of what I just found (originally in Persian).
+# The Gregorian dates in brackets are mine:
+#
+#	Official Newspaper No. 13548-1370/6/25 [1991-09-16]
+#	No. 16760/T233 H				1370/6/10 [1991-09-01]
+#
+#	The Rule About Change of the Official Time of the Country
+#
+#	The Board of Ministers, in the meeting dated 1370/5/23 [1991-08-14],
+#	based on the suggestion number 2221/D dated 1370/4/22 [1991-07-13]
+#	of the Country's Organization for Official and Employment Affairs,
+#	and referring to the law for equating the working hours of workers
+#	and officers in the whole country dated 1359/4/23 [1980-07-14], and
+#	for synchronizing the official times of the country, agreed that:
+#
+#	The official time of the country will should move forward one hour
+#	at the 24[:00] hours of the first day of Farvardin and should return
+#	to its previous state at the 24[:00] hours of the 30th day of
+#	Shahrivar.
+#
+#	First Deputy to the President - Hassan Habibi
+#
+# From personal experience, that agrees with what has been followed
+# for at least the last 5 years.  Before that, for a few years, the
+# date used was the first Thursday night of Farvardin and the last
+# Thursday night of Shahrivar, but I can't give exact dates....
+# I have also changed the abbreviations to what is considered correct
+# here in Iran, IRST for regular time and IRDT for daylight saving time.
+#
+# From Roozbeh Pournader (2005-04-05):
+# The text of the Iranian law, in effect since 1925, clearly mentions
+# that the true solar year is the measure, and there is no arithmetic
+# leap year calculation involved.  There has never been any serious
+# plan to change that law....
+#
+# From Paul Eggert (2006-03-22):
+# Go with Shanks & Pottenger before Sept. 1991, and with Pournader thereafter.
+# I used Ed Reingold's cal-persia in GNU Emacs 21.2 to check Persian dates,
+# stopping after 2037 when 32-bit time_t's overflow.
+# That cal-persia used Birashk's approximation, which disagrees with the solar
+# calendar predictions for the year 2025, so I corrected those dates by hand.
+#
+# From Oscar van Vlijmen (2005-03-30), writing about future
+# discrepancies between cal-persia and the Iranian calendar:
+# For 2091 solar-longitude-after yields 2091-03-20 08:40:07.7 UT for
+# the vernal equinox and that gets so close to 12:00 some local
+# Iranian time that the definition of the correct location needs to be
+# known exactly, amongst other factors.  2157 is even closer:
+# 2157-03-20 08:37:15.5 UT.  But the Gregorian year 2025 should give
+# no interpretation problem whatsoever.  By the way, another instant
+# in the near future where there will be a discrepancy between
+# arithmetical and astronomical Iranian calendars will be in 2058:
+# vernal equinox on 2058-03-20 09:03:05.9 UT.  The Java version of
+# Reingold's/Dershowitz' calculator gives correctly the Gregorian date
+# 2058-03-21 for 1 Farvardin 1437 (astronomical).
+#
+# From Steffen Thorsen (2006-03-22):
+# Several of my users have reported that Iran will not observe DST anymore:
+# http://www.irna.ir/en/news/view/line-17/0603193812164948.htm
+#
+# From Reuters (2007-09-16), with a heads-up from Jesper Norgaard Welen:
+# ... the Guardian Council ... approved a law on Sunday to re-introduce
+# daylight saving time ...
+# http://uk.reuters.com/article/oilRpt/idUKBLA65048420070916
+#
+# From Roozbeh Pournader (2007-11-05):
+# This is quoted from Official Gazette of the Islamic Republic of
+# Iran, Volume 63, Number 18242, dated Tuesday 1386/6/24
+# [2007-10-16]. I am doing the best translation I can:...
+# The official time of the country will be moved forward for one hour
+# on the 24 hours of the first day of the month of Farvardin and will
+# be changed back to its previous state on the 24 hours of the
+# thirtieth day of Shahrivar.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Iran	1978	1980	-	Mar	21	0:00	1:00	D
+Rule	Iran	1978	only	-	Oct	21	0:00	0	S
+Rule	Iran	1979	only	-	Sep	19	0:00	0	S
+Rule	Iran	1980	only	-	Sep	23	0:00	0	S
+Rule	Iran	1991	only	-	May	 3	0:00	1:00	D
+Rule	Iran	1992	1995	-	Mar	22	0:00	1:00	D
+Rule	Iran	1991	1995	-	Sep	22	0:00	0	S
+Rule	Iran	1996	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	1996	only	-	Sep	21	0:00	0	S
+Rule	Iran	1997	1999	-	Mar	22	0:00	1:00	D
+Rule	Iran	1997	1999	-	Sep	22	0:00	0	S
+Rule	Iran	2000	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	2000	only	-	Sep	21	0:00	0	S
+Rule	Iran	2001	2003	-	Mar	22	0:00	1:00	D
+Rule	Iran	2001	2003	-	Sep	22	0:00	0	S
+Rule	Iran	2004	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	2004	only	-	Sep	21	0:00	0	S
+Rule	Iran	2005	only	-	Mar	22	0:00	1:00	D
+Rule	Iran	2005	only	-	Sep	22	0:00	0	S
+Rule	Iran	2008	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	2008	only	-	Sep	21	0:00	0	S
+Rule	Iran	2009	2011	-	Mar	22	0:00	1:00	D
+Rule	Iran	2009	2011	-	Sep	22	0:00	0	S
+Rule	Iran	2012	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	2012	only	-	Sep	21	0:00	0	S
+Rule	Iran	2013	2015	-	Mar	22	0:00	1:00	D
+Rule	Iran	2013	2015	-	Sep	22	0:00	0	S
+Rule	Iran	2016	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	2016	only	-	Sep	21	0:00	0	S
+Rule	Iran	2017	2019	-	Mar	22	0:00	1:00	D
+Rule	Iran	2017	2019	-	Sep	22	0:00	0	S
+Rule	Iran	2020	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	2020	only	-	Sep	21	0:00	0	S
+Rule	Iran	2021	2023	-	Mar	22	0:00	1:00	D
+Rule	Iran	2021	2023	-	Sep	22	0:00	0	S
+Rule	Iran	2024	only	-	Mar	21	0:00	1:00	D
+Rule	Iran	2024	only	-	Sep	21	0:00	0	S
+Rule	Iran	2025	2027	-	Mar	22	0:00	1:00	D
+Rule	Iran	2025	2027	-	Sep	22	0:00	0	S
+Rule	Iran	2028	2029	-	Mar	21	0:00	1:00	D
+Rule	Iran	2028	2029	-	Sep	21	0:00	0	S
+Rule	Iran	2030	2031	-	Mar	22	0:00	1:00	D
+Rule	Iran	2030	2031	-	Sep	22	0:00	0	S
+Rule	Iran	2032	2033	-	Mar	21	0:00	1:00	D
+Rule	Iran	2032	2033	-	Sep	21	0:00	0	S
+Rule	Iran	2034	2035	-	Mar	22	0:00	1:00	D
+Rule	Iran	2034	2035	-	Sep	22	0:00	0	S
+Rule	Iran	2036	2037	-	Mar	21	0:00	1:00	D
+Rule	Iran	2036	2037	-	Sep	21	0:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Tehran	3:25:44	-	LMT	1916
+			3:25:44	-	TMT	1946	# Tehran Mean Time
+			3:30	-	IRST	1977 Nov
+			4:00	Iran	IR%sT	1979
+			3:30	Iran	IR%sT
+
+
+# Iraq
+#
+# From Jonathan Lennox (2000-06-12):
+# An article in this week's Economist ("Inside the Saddam-free zone", p. 50 in
+# the U.S. edition) on the Iraqi Kurds contains a paragraph:
+# "The three northern provinces ... switched their clocks this spring and
+# are an hour ahead of Baghdad."
+#
+# But Rives McDow (2000-06-18) quotes a contact in Iraqi-Kurdistan as follows:
+# In the past, some Kurdish nationalists, as a protest to the Iraqi
+# Government, did not adhere to daylight saving time.  They referred
+# to daylight saving as Saddam time.  But, as of today, the time zone
+# in Iraqi-Kurdistan is on standard time with Baghdad, Iraq.
+#
+# So we'll ignore the Economist's claim.
+
+# From Steffen Thorsen (2008-03-10):
+# The cabinet in Iraq abolished DST last week, according to the following
+# news sources (in Arabic):
+# <a href="http://www.aljeeran.net/wesima_articles/news-20080305-98602.html">
+# http://www.aljeeran.net/wesima_articles/news-20080305-98602.html
+# </a>
+# <a href="http://www.aswataliraq.info/look/article.tpl?id=2047&IdLanguage=17&IdPublication=4&NrArticle=71743&NrIssue=1&NrSection=10">
+# http://www.aswataliraq.info/look/article.tpl?id=2047&IdLanguage=17&IdPublication=4&NrArticle=71743&NrIssue=1&NrSection=10
+# </a>
+#
+# We have published a short article in English about the change:
+# <a href="http://www.timeanddate.com/news/time/iraq-dumps-daylight-saving.html">
+# http://www.timeanddate.com/news/time/iraq-dumps-daylight-saving.html
+# </a>
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Iraq	1982	only	-	May	1	0:00	1:00	D
+Rule	Iraq	1982	1984	-	Oct	1	0:00	0	S
+Rule	Iraq	1983	only	-	Mar	31	0:00	1:00	D
+Rule	Iraq	1984	1985	-	Apr	1	0:00	1:00	D
+Rule	Iraq	1985	1990	-	Sep	lastSun	1:00s	0	S
+Rule	Iraq	1986	1990	-	Mar	lastSun	1:00s	1:00	D
+# IATA SSIM (1991/1996) says Apr 1 12:01am UTC; guess the `:01' is a typo.
+# Shanks & Pottenger say Iraq did not observe DST 1992/1997; ignore this.
+#
+Rule	Iraq	1991	2007	-	Apr	 1	3:00s	1:00	D
+Rule	Iraq	1991	2007	-	Oct	 1	3:00s	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Baghdad	2:57:40	-	LMT	1890
+			2:57:36	-	BMT	1918	    # Baghdad Mean Time?
+			3:00	-	AST	1982 May
+			3:00	Iraq	A%sT
+
+
+###############################################################################
+
+# Israel
+
+# From Ephraim Silverberg (2001-01-11):
+#
+# I coined "IST/IDT" circa 1988.  Until then there were three
+# different abbreviations in use:
+#
+# JST  Jerusalem Standard Time [Danny Braniss, Hebrew University]
+# IZT  Israel Zonal (sic) Time [Prof. Haim Papo, Technion]
+# EEST Eastern Europe Standard Time [used by almost everyone else]
+#
+# Since timezones should be called by country and not capital cities,
+# I ruled out JST.  As Israel is in Asia Minor and not Eastern Europe,
+# EEST was equally unacceptable.  Since "zonal" was not compatible with
+# any other timezone abbreviation, I felt that 'IST' was the way to go
+# and, indeed, it has received almost universal acceptance in timezone
+# settings in Israeli computers.
+#
+# In any case, I am happy to share timezone abbreviations with India,
+# high on my favorite-country list (and not only because my wife's
+# family is from India).
+
+# From Shanks & Pottenger:
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Zion	1940	only	-	Jun	 1	0:00	1:00	D
+Rule	Zion	1942	1944	-	Nov	 1	0:00	0	S
+Rule	Zion	1943	only	-	Apr	 1	2:00	1:00	D
+Rule	Zion	1944	only	-	Apr	 1	0:00	1:00	D
+Rule	Zion	1945	only	-	Apr	16	0:00	1:00	D
+Rule	Zion	1945	only	-	Nov	 1	2:00	0	S
+Rule	Zion	1946	only	-	Apr	16	2:00	1:00	D
+Rule	Zion	1946	only	-	Nov	 1	0:00	0	S
+Rule	Zion	1948	only	-	May	23	0:00	2:00	DD
+Rule	Zion	1948	only	-	Sep	 1	0:00	1:00	D
+Rule	Zion	1948	1949	-	Nov	 1	2:00	0	S
+Rule	Zion	1949	only	-	May	 1	0:00	1:00	D
+Rule	Zion	1950	only	-	Apr	16	0:00	1:00	D
+Rule	Zion	1950	only	-	Sep	15	3:00	0	S
+Rule	Zion	1951	only	-	Apr	 1	0:00	1:00	D
+Rule	Zion	1951	only	-	Nov	11	3:00	0	S
+Rule	Zion	1952	only	-	Apr	20	2:00	1:00	D
+Rule	Zion	1952	only	-	Oct	19	3:00	0	S
+Rule	Zion	1953	only	-	Apr	12	2:00	1:00	D
+Rule	Zion	1953	only	-	Sep	13	3:00	0	S
+Rule	Zion	1954	only	-	Jun	13	0:00	1:00	D
+Rule	Zion	1954	only	-	Sep	12	0:00	0	S
+Rule	Zion	1955	only	-	Jun	11	2:00	1:00	D
+Rule	Zion	1955	only	-	Sep	11	0:00	0	S
+Rule	Zion	1956	only	-	Jun	 3	0:00	1:00	D
+Rule	Zion	1956	only	-	Sep	30	3:00	0	S
+Rule	Zion	1957	only	-	Apr	29	2:00	1:00	D
+Rule	Zion	1957	only	-	Sep	22	0:00	0	S
+Rule	Zion	1974	only	-	Jul	 7	0:00	1:00	D
+Rule	Zion	1974	only	-	Oct	13	0:00	0	S
+Rule	Zion	1975	only	-	Apr	20	0:00	1:00	D
+Rule	Zion	1975	only	-	Aug	31	0:00	0	S
+Rule	Zion	1985	only	-	Apr	14	0:00	1:00	D
+Rule	Zion	1985	only	-	Sep	15	0:00	0	S
+Rule	Zion	1986	only	-	May	18	0:00	1:00	D
+Rule	Zion	1986	only	-	Sep	 7	0:00	0	S
+Rule	Zion	1987	only	-	Apr	15	0:00	1:00	D
+Rule	Zion	1987	only	-	Sep	13	0:00	0	S
+Rule	Zion	1988	only	-	Apr	 9	0:00	1:00	D
+Rule	Zion	1988	only	-	Sep	 3	0:00	0	S
+
+# From Ephraim Silverberg
+# (1997-03-04, 1998-03-16, 1998-12-28, 2000-01-17, 2000-07-25, 2004-12-22,
+# and 2005-02-17):
+
+# According to the Office of the Secretary General of the Ministry of
+# Interior, there is NO set rule for Daylight-Savings/Standard time changes.
+# One thing is entrenched in law, however: that there must be at least 150
+# days of daylight savings time annually.  From 1993-1998, the change to
+# daylight savings time was on a Friday morning from midnight IST to
+# 1 a.m IDT; up until 1998, the change back to standard time was on a
+# Saturday night from midnight daylight savings time to 11 p.m. standard
+# time.  1996 is an exception to this rule where the change back to standard
+# time took place on Sunday night instead of Saturday night to avoid
+# conflicts with the Jewish New Year.  In 1999, the change to
+# daylight savings time was still on a Friday morning but from
+# 2 a.m. IST to 3 a.m. IDT; furthermore, the change back to standard time
+# was also on a Friday morning from 2 a.m. IDT to 1 a.m. IST for
+# 1999 only.  In the year 2000, the change to daylight savings time was
+# similar to 1999, but although the change back will be on a Friday, it
+# will take place from 1 a.m. IDT to midnight IST.  Starting in 2001, all
+# changes to/from will take place at 1 a.m. old time, but now there is no
+# rule as to what day of the week it will take place in as the start date
+# (except in 2003) is the night after the Passover Seder (i.e. the eve
+# of the 16th of Nisan in the lunar Hebrew calendar) and the end date
+# (except in 2002) is three nights before Yom Kippur [Day of Atonement]
+# (the eve of the 7th of Tishrei in the lunar Hebrew calendar).
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Zion	1989	only	-	Apr	30	0:00	1:00	D
+Rule	Zion	1989	only	-	Sep	 3	0:00	0	S
+Rule	Zion	1990	only	-	Mar	25	0:00	1:00	D
+Rule	Zion	1990	only	-	Aug	26	0:00	0	S
+Rule	Zion	1991	only	-	Mar	24	0:00	1:00	D
+Rule	Zion	1991	only	-	Sep	 1	0:00	0	S
+Rule	Zion	1992	only	-	Mar	29	0:00	1:00	D
+Rule	Zion	1992	only	-	Sep	 6	0:00	0	S
+Rule	Zion	1993	only	-	Apr	 2	0:00	1:00	D
+Rule	Zion	1993	only	-	Sep	 5	0:00	0	S
+
+# The dates for 1994-1995 were obtained from Office of the Spokeswoman for the
+# Ministry of Interior, Jerusalem, Israel.  The spokeswoman can be reached by
+# calling the office directly at 972-2-6701447 or 972-2-6701448.
+
+# Rule	NAME    FROM    TO      TYPE    IN      ON      AT      SAVE    LETTER/S
+Rule	Zion	1994	only	-	Apr	 1	0:00	1:00	D
+Rule	Zion	1994	only	-	Aug	28	0:00	0	S
+Rule	Zion	1995	only	-	Mar	31	0:00	1:00	D
+Rule	Zion	1995	only	-	Sep	 3	0:00	0	S
+
+# The dates for 1996 were determined by the Minister of Interior of the
+# time, Haim Ramon.  The official announcement regarding 1996-1998
+# (with the dates for 1997-1998 no longer being relevant) can be viewed at:
+#
+#   ftp://ftp.cs.huji.ac.il/pub/tz/announcements/1996-1998.ramon.ps.gz
+#
+# The dates for 1997-1998 were altered by his successor, Rabbi Eli Suissa.
+#
+# The official announcements for the years 1997-1999 can be viewed at:
+#
+#   ftp://ftp.cs.huji.ac.il/pub/tz/announcements/YYYY.ps.gz
+#
+#       where YYYY is the relevant year.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Zion	1996	only	-	Mar	15	0:00	1:00	D
+Rule	Zion	1996	only	-	Sep	16	0:00	0	S
+Rule	Zion	1997	only	-	Mar	21	0:00	1:00	D
+Rule	Zion	1997	only	-	Sep	14	0:00	0	S
+Rule	Zion	1998	only	-	Mar	20	0:00	1:00	D
+Rule	Zion	1998	only	-	Sep	 6	0:00	0	S
+Rule	Zion	1999	only	-	Apr	 2	2:00	1:00	D
+Rule	Zion	1999	only	-	Sep	 3	2:00	0	S
+
+# The Knesset Interior Committee has changed the dates for 2000 for
+# the third time in just over a year and have set new dates for the
+# years 2001-2004 as well.
+#
+# The official announcement for the start date of 2000 can be viewed at:
+#
+#	ftp://ftp.cs.huji.ac.il/pub/tz/announcements/2000-start.ps.gz
+#
+# The official announcement for the end date of 2000 and the dates
+# for the years 2001-2004 can be viewed at:
+#
+#	ftp://ftp.cs.huji.ac.il/pub/tz/announcements/2000-2004.ps.gz
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Zion	2000	only	-	Apr	14	2:00	1:00	D
+Rule	Zion	2000	only	-	Oct	 6	1:00	0	S
+Rule	Zion	2001	only	-	Apr	 9	1:00	1:00	D
+Rule	Zion	2001	only	-	Sep	24	1:00	0	S
+Rule	Zion	2002	only	-	Mar	29	1:00	1:00	D
+Rule	Zion	2002	only	-	Oct	 7	1:00	0	S
+Rule	Zion	2003	only	-	Mar	28	1:00	1:00	D
+Rule	Zion	2003	only	-	Oct	 3	1:00	0	S
+Rule	Zion	2004	only	-	Apr	 7	1:00	1:00	D
+Rule	Zion	2004	only	-	Sep	22	1:00	0	S
+
+# The proposed law agreed upon by the Knesset Interior Committee on
+# 2005-02-14 is that, for 2005 and beyond, DST starts at 02:00 the
+# last Friday before April 2nd (i.e. the last Friday in March or April
+# 1st itself if it falls on a Friday) and ends at 02:00 on the Saturday
+# night _before_ the fast of Yom Kippur.
+#
+# Those who can read Hebrew can view the announcement at:
+#
+#	ftp://ftp.cs.huji.ac.il/pub/tz/announcements/2005+beyond.ps
+
+# From Paul Eggert (2005-02-22):
+# I used Ephraim Silverberg's dst-israel.el program
+# <ftp://ftp.cs.huji.ac.il/pub/tz/software/dst-israel.el> (2005-02-20)
+# along with Ed Reingold's cal-hebrew in GNU Emacs 21.4,
+# to generate the transitions in this list.
+# (I replaced "lastFri" with "Fri>=26" by hand.)
+# The spring transitions below all correspond to the following Rule:
+#
+# Rule	Zion	2005	max	-	Mar	Fri>=26	2:00	1:00	D
+#
+# but older zic implementations (e.g., Solaris 8) do not support
+# "Fri>=26" to mean April 1 in years like 2005, so for now we list the
+# springtime transitions explicitly.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Zion	2005	only	-	Apr	 1	2:00	1:00	D
+Rule	Zion	2005	only	-	Oct	 9	2:00	0	S
+Rule	Zion	2006	2010	-	Mar	Fri>=26	2:00	1:00	D
+Rule	Zion	2006	only	-	Oct	 1	2:00	0	S
+Rule	Zion	2007	only	-	Sep	16	2:00	0	S
+Rule	Zion	2008	only	-	Oct	 5	2:00	0	S
+Rule	Zion	2009	only	-	Sep	27	2:00	0	S
+Rule	Zion	2010	only	-	Sep	12	2:00	0	S
+Rule	Zion	2011	only	-	Apr	 1	2:00	1:00	D
+Rule	Zion	2011	only	-	Oct	 2	2:00	0	S
+Rule	Zion	2012	2015	-	Mar	Fri>=26	2:00	1:00	D
+Rule	Zion	2012	only	-	Sep	23	2:00	0	S
+Rule	Zion	2013	only	-	Sep	 8	2:00	0	S
+Rule	Zion	2014	only	-	Sep	28	2:00	0	S
+Rule	Zion	2015	only	-	Sep	20	2:00	0	S
+Rule	Zion	2016	only	-	Apr	 1	2:00	1:00	D
+Rule	Zion	2016	only	-	Oct	 9	2:00	0	S
+Rule	Zion	2017	2021	-	Mar	Fri>=26	2:00	1:00	D
+Rule	Zion	2017	only	-	Sep	24	2:00	0	S
+Rule	Zion	2018	only	-	Sep	16	2:00	0	S
+Rule	Zion	2019	only	-	Oct	 6	2:00	0	S
+Rule	Zion	2020	only	-	Sep	27	2:00	0	S
+Rule	Zion	2021	only	-	Sep	12	2:00	0	S
+Rule	Zion	2022	only	-	Apr	 1	2:00	1:00	D
+Rule	Zion	2022	only	-	Oct	 2	2:00	0	S
+Rule	Zion	2023	2032	-	Mar	Fri>=26	2:00	1:00	D
+Rule	Zion	2023	only	-	Sep	24	2:00	0	S
+Rule	Zion	2024	only	-	Oct	 6	2:00	0	S
+Rule	Zion	2025	only	-	Sep	28	2:00	0	S
+Rule	Zion	2026	only	-	Sep	20	2:00	0	S
+Rule	Zion	2027	only	-	Oct	10	2:00	0	S
+Rule	Zion	2028	only	-	Sep	24	2:00	0	S
+Rule	Zion	2029	only	-	Sep	16	2:00	0	S
+Rule	Zion	2030	only	-	Oct	 6	2:00	0	S
+Rule	Zion	2031	only	-	Sep	21	2:00	0	S
+Rule	Zion	2032	only	-	Sep	12	2:00	0	S
+Rule	Zion	2033	only	-	Apr	 1	2:00	1:00	D
+Rule	Zion	2033	only	-	Oct	 2	2:00	0	S
+Rule	Zion	2034	2037	-	Mar	Fri>=26	2:00	1:00	D
+Rule	Zion	2034	only	-	Sep	17	2:00	0	S
+Rule	Zion	2035	only	-	Oct	 7	2:00	0	S
+Rule	Zion	2036	only	-	Sep	28	2:00	0	S
+Rule	Zion	2037	only	-	Sep	13	2:00	0	S
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Jerusalem	2:20:56 -	LMT	1880
+			2:20:40	-	JMT	1918	# Jerusalem Mean Time?
+			2:00	Zion	I%sT
+
+
+
+###############################################################################
+
+# Japan
+
+# `9:00' and `JST' is from Guy Harris.
+
+# From Paul Eggert (1995-03-06):
+# Today's _Asahi Evening News_ (page 4) reports that Japan had
+# daylight saving between 1948 and 1951, but ``the system was discontinued
+# because the public believed it would lead to longer working hours.''
+
+# From Mayumi Negishi in the 2005-08-10 Japan Times
+# <http://www.japantimes.co.jp/cgi-bin/getarticle.pl5?nn20050810f2.htm>:
+# Occupation authorities imposed daylight-saving time on Japan on
+# [1948-05-01]....  But lack of prior debate and the execution of
+# daylight-saving time just three days after the bill was passed generated
+# deep hatred of the concept....  The Diet unceremoniously passed a bill to
+# dump the unpopular system in October 1951, less than a month after the San
+# Francisco Peace Treaty was signed.  (A government poll in 1951 showed 53%
+# of the Japanese wanted to scrap daylight-saving time, as opposed to 30% who
+# wanted to keep it.)
+
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger write that DST in Japan during those years was as follows:
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Japan	1948	only	-	May	Sun>=1	2:00	1:00	D
+Rule	Japan	1948	1951	-	Sep	Sat>=8	2:00	0	S
+Rule	Japan	1949	only	-	Apr	Sun>=1	2:00	1:00	D
+Rule	Japan	1950	1951	-	May	Sun>=1	2:00	1:00	D
+# but the only locations using it (for birth certificates, presumably, since
+# their audience is astrologers) were US military bases.  For now, assume
+# that for most purposes daylight-saving time was observed; otherwise, what
+# would have been the point of the 1951 poll?
+
+# From Hideyuki Suzuki (1998-11-09):
+# 'Tokyo' usually stands for the former location of Tokyo Astronomical
+# Observatory: E 139 44' 40".90 (9h 18m 58s.727), N 35 39' 16".0.
+# This data is from 'Rika Nenpyou (Chronological Scientific Tables) 1996'
+# edited by National Astronomical Observatory of Japan....
+# JST (Japan Standard Time) has been used since 1888-01-01 00:00 (JST).
+# The law is enacted on 1886-07-07.
+
+# From Hideyuki Suzuki (1998-11-16):
+# The ordinance No. 51 (1886) established "standard time" in Japan,
+# which stands for the time on E 135 degree.
+# In the ordinance No. 167 (1895), "standard time" was renamed to "central
+# standard time".  And the same ordinance also established "western standard
+# time", which stands for the time on E 120 degree....  But "western standard
+# time" was abolished in the ordinance No. 529 (1937).  In the ordinance No.
+# 167, there is no mention regarding for what place western standard time is
+# standard....
+#
+# I wrote "ordinance" above, but I don't know how to translate.
+# In Japanese it's "chokurei", which means ordinance from emperor.
+
+# Shanks & Pottenger claim JST in use since 1896, and that a few
+# places (e.g. Ishigaki) use +0800; go with Suzuki.  Guess that all
+# ordinances took effect on Jan 1.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Tokyo	9:18:59	-	LMT	1887 Dec 31 15:00u
+			9:00	-	JST	1896
+			9:00	-	CJT	1938
+			9:00	Japan	J%sT
+# Since 1938, all Japanese possessions have been like Asia/Tokyo.
+
+# Jordan
+#
+# From <a href="http://star.arabia.com/990701/JO9.html">
+# Jordan Week (1999-07-01) </a> via Steffen Thorsen (1999-09-09):
+# Clocks in Jordan were forwarded one hour on Wednesday at midnight,
+# in accordance with the government's decision to implement summer time
+# all year round.
+#
+# From <a href="http://star.arabia.com/990930/JO9.html">
+# Jordan Week (1999-09-30) </a> via Steffen Thorsen (1999-11-09):
+# Winter time starts today Thursday, 30 September. Clocks will be turned back
+# by one hour.  This is the latest government decision and it's final!
+# The decision was taken because of the increase in working hours in
+# government's departments from six to seven hours.
+#
+# From Paul Eggert (2005-11-22):
+# Starting 2003 transitions are from Steffen Thorsen's web site timeanddate.com.
+#
+# From Steffen Thorsen (2005-11-23):
+# For Jordan I have received multiple independent user reports every year
+# about DST end dates, as the end-rule is different every year.
+#
+# From Steffen Thorsen (2006-10-01), after a heads-up from Hilal Malawi:
+# http://www.petranews.gov.jo/nepras/2006/Sep/05/4000.htm
+# "Jordan will switch to winter time on Friday, October 27".
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Jordan	1973	only	-	Jun	6	0:00	1:00	S
+Rule	Jordan	1973	1975	-	Oct	1	0:00	0	-
+Rule	Jordan	1974	1977	-	May	1	0:00	1:00	S
+Rule	Jordan	1976	only	-	Nov	1	0:00	0	-
+Rule	Jordan	1977	only	-	Oct	1	0:00	0	-
+Rule	Jordan	1978	only	-	Apr	30	0:00	1:00	S
+Rule	Jordan	1978	only	-	Sep	30	0:00	0	-
+Rule	Jordan	1985	only	-	Apr	1	0:00	1:00	S
+Rule	Jordan	1985	only	-	Oct	1	0:00	0	-
+Rule	Jordan	1986	1988	-	Apr	Fri>=1	0:00	1:00	S
+Rule	Jordan	1986	1990	-	Oct	Fri>=1	0:00	0	-
+Rule	Jordan	1989	only	-	May	8	0:00	1:00	S
+Rule	Jordan	1990	only	-	Apr	27	0:00	1:00	S
+Rule	Jordan	1991	only	-	Apr	17	0:00	1:00	S
+Rule	Jordan	1991	only	-	Sep	27	0:00	0	-
+Rule	Jordan	1992	only	-	Apr	10	0:00	1:00	S
+Rule	Jordan	1992	1993	-	Oct	Fri>=1	0:00	0	-
+Rule	Jordan	1993	1998	-	Apr	Fri>=1	0:00	1:00	S
+Rule	Jordan	1994	only	-	Sep	Fri>=15	0:00	0	-
+Rule	Jordan	1995	1998	-	Sep	Fri>=15	0:00s	0	-
+Rule	Jordan	1999	only	-	Jul	 1	0:00s	1:00	S
+Rule	Jordan	1999	2002	-	Sep	lastThu	0:00s	0	-
+Rule	Jordan	2000	max	-	Mar	lastThu	0:00s	1:00	S
+Rule	Jordan	2003	only	-	Oct	24	0:00s	0	-
+Rule	Jordan	2004	only	-	Oct	15	0:00s	0	-
+Rule	Jordan	2005	only	-	Sep	lastFri	0:00s	0	-
+Rule	Jordan	2006	max	-	Oct	lastFri	0:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Amman	2:23:44 -	LMT	1931
+			2:00	Jordan	EE%sT
+
+
+# Kazakhstan
+
+# From Paul Eggert (1996-11-22):
+# Andrew Evtichov (1996-04-13) writes that Kazakhstan
+# stayed in sync with Moscow after 1990, and that Aqtobe (formerly Aktyubinsk)
+# and Aqtau (formerly Shevchenko) are the largest cities in their zones.
+# Guess that Aqtau and Aqtobe diverged in 1995, since that's the first time
+# IATA SSIM mentions a third time zone in Kazakhstan.
+
+# From Paul Eggert (2006-03-22):
+# German Iofis, ELSI, Almaty (2001-10-09) reports that Kazakhstan uses
+# RussiaAsia rules, instead of switching at 00:00 as the IATA has it.
+# Go with Shanks & Pottenger, who have them always using RussiaAsia rules.
+# Also go with the following claims of Shanks & Pottenger:
+#
+# - Kazakhstan did not observe DST in 1991.
+# - Qyzylorda switched from +5:00 to +6:00 on 1992-01-19 02:00.
+# - Oral switched from +5:00 to +4:00 in spring 1989.
+
+# <a href="http://www.kazsociety.org.uk/news/2005/03/30.htm">
+# From Kazakhstan Embassy's News Bulletin #11 (2005-03-21):
+# </a>
+# The Government of Kazakhstan passed a resolution March 15 abolishing
+# daylight saving time citing lack of economic benefits and health
+# complications coupled with a decrease in productivity.
+#
+# From Branislav Kojic (in Astana) via Gwillim Law (2005-06-28):
+# ... what happened was that the former Kazakhstan Eastern time zone
+# was "blended" with the Central zone.  Therefore, Kazakhstan now has
+# two time zones, and difference between them is one hour.  The zone
+# closer to UTC is the former Western zone (probably still called the
+# same), encompassing four provinces in the west: Aqtobe, Atyrau,
+# Mangghystau, and West Kazakhstan.  The other zone encompasses
+# everything else....  I guess that would make Kazakhstan time zones
+# de jure UTC+5 and UTC+6 respectively.
+
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+#
+# Almaty (formerly Alma-Ata), representing most locations in Kazakhstan
+Zone	Asia/Almaty	5:07:48 -	LMT	1924 May  2 # or Alma-Ata
+			5:00	-	ALMT	1930 Jun 21 # Alma-Ata Time
+			6:00 RussiaAsia ALM%sT	1991
+			6:00	-	ALMT	1992
+			6:00 RussiaAsia	ALM%sT	2005 Mar 15
+			6:00	-	ALMT
+# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.)
+Zone	Asia/Qyzylorda	4:21:52 -	LMT	1924 May  2
+			4:00	-	KIZT	1930 Jun 21 # Kizilorda Time
+			5:00	-	KIZT	1981 Apr  1
+			5:00	1:00	KIZST	1981 Oct  1
+			6:00	-	KIZT	1982 Apr  1
+			5:00 RussiaAsia	KIZ%sT	1991
+			5:00	-	KIZT	1991 Dec 16 # independence
+			5:00	-	QYZT	1992 Jan 19 2:00
+			6:00 RussiaAsia	QYZ%sT	2005 Mar 15
+			6:00	-	QYZT
+# Aqtobe (aka Aktobe, formerly Akt'ubinsk)
+Zone	Asia/Aqtobe	3:48:40	-	LMT	1924 May  2
+			4:00	-	AKTT	1930 Jun 21 # Aktyubinsk Time
+			5:00	-	AKTT	1981 Apr  1
+			5:00	1:00	AKTST	1981 Oct  1
+			6:00	-	AKTT	1982 Apr  1
+			5:00 RussiaAsia	AKT%sT	1991
+			5:00	-	AKTT	1991 Dec 16 # independence
+			5:00 RussiaAsia	AQT%sT	2005 Mar 15 # Aqtobe Time
+			5:00	-	AQTT
+# Mangghystau
+# Aqtau was not founded until 1963, but it represents an inhabited region,
+# so include time stamps before 1963.
+Zone	Asia/Aqtau	3:21:04	-	LMT	1924 May  2
+			4:00	-	FORT	1930 Jun 21 # Fort Shevchenko T
+			5:00	-	FORT	1963
+			5:00	-	SHET	1981 Oct  1 # Shevchenko Time
+			6:00	-	SHET	1982 Apr  1
+			5:00 RussiaAsia	SHE%sT	1991
+			5:00	-	SHET	1991 Dec 16 # independence
+			5:00 RussiaAsia	AQT%sT	1995 Mar lastSun 2:00 # Aqtau Time
+			4:00 RussiaAsia	AQT%sT	2005 Mar 15
+			5:00	-	AQTT
+# West Kazakhstan
+Zone	Asia/Oral	3:25:24	-	LMT	1924 May  2 # or Ural'sk
+			4:00	-	URAT	1930 Jun 21 # Ural'sk time
+			5:00	-	URAT	1981 Apr  1
+			5:00	1:00	URAST	1981 Oct  1
+			6:00	-	URAT	1982 Apr  1
+			5:00 RussiaAsia	URA%sT	1989 Mar 26 2:00
+			4:00 RussiaAsia	URA%sT	1991
+			4:00	-	URAT	1991 Dec 16 # independence
+			4:00 RussiaAsia	ORA%sT	2005 Mar 15 # Oral Time
+			5:00	-	ORAT
+
+# Kyrgyzstan (Kirgizstan)
+# Transitions through 1991 are from Shanks & Pottenger.
+
+# From Paul Eggert (2005-08-15):
+# According to an article dated today in the Kyrgyzstan Development Gateway
+# <http://eng.gateway.kg/cgi-bin/page.pl?id=1&story_name=doc9979.shtml>
+# Kyrgyzstan is canceling the daylight saving time system.  I take the article
+# to mean that they will leave their clocks at 6 hours ahead of UTC.
+# From Malik Abdugaliev (2005-09-21):
+# Our government cancels daylight saving time 6th of August 2005.
+# From 2005-08-12 our GMT-offset is +6, w/o any daylight saving.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Kyrgyz	1992	1996	-	Apr	Sun>=7	0:00s	1:00	S
+Rule	Kyrgyz	1992	1996	-	Sep	lastSun	0:00	0	-
+Rule	Kyrgyz	1997	2005	-	Mar	lastSun	2:30	1:00	S
+Rule	Kyrgyz	1997	2004	-	Oct	lastSun	2:30	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Bishkek	4:58:24 -	LMT	1924 May  2
+			5:00	-	FRUT	1930 Jun 21 # Frunze Time
+			6:00 RussiaAsia FRU%sT	1991 Mar 31 2:00s
+			5:00	1:00	FRUST	1991 Aug 31 2:00 # independence
+			5:00	Kyrgyz	KG%sT	2005 Aug 12    # Kyrgyzstan Time
+			6:00	-	KGT
+
+###############################################################################
+
+# Korea (North and South)
+
+# From Annie I. Bang (2006-07-10) in
+# <http://www.koreaherald.co.kr/SITE/data/html_dir/2006/07/10/200607100012.asp>:
+# The Ministry of Commerce, Industry and Energy has already
+# commissioned a research project [to reintroduce DST] and has said
+# the system may begin as early as 2008....  Korea ran a daylight
+# saving program from 1949-61 but stopped it during the 1950-53 Korean War.
+
+# From Shanks & Pottenger:
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	ROK	1960	only	-	May	15	0:00	1:00	D
+Rule	ROK	1960	only	-	Sep	13	0:00	0	S
+Rule	ROK	1987	1988	-	May	Sun>=8	0:00	1:00	D
+Rule	ROK	1987	1988	-	Oct	Sun>=8	0:00	0	S
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Seoul	8:27:52	-	LMT	1890
+			8:30	-	KST	1904 Dec
+			9:00	-	KST	1928
+			8:30	-	KST	1932
+			9:00	-	KST	1954 Mar 21
+			8:00	ROK	K%sT	1961 Aug 10
+			8:30	-	KST	1968 Oct
+			9:00	ROK	K%sT
+Zone	Asia/Pyongyang	8:23:00 -	LMT	1890
+			8:30	-	KST	1904 Dec
+			9:00	-	KST	1928
+			8:30	-	KST	1932
+			9:00	-	KST	1954 Mar 21
+			8:00	-	KST	1961 Aug 10
+			9:00	-	KST
+
+###############################################################################
+
+# Kuwait
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# From the Arab Times (2007-03-14):
+# The Civil Service Commission (CSC) has approved a proposal forwarded
+# by MP Ahmad Baqer on implementing the daylight saving time (DST) in
+# Kuwait starting from April until the end of Sept this year, reports Al-Anba.
+# <http://www.arabtimesonline.com/arabtimes/kuwait/Viewdet.asp?ID=9950>.
+# From Paul Eggert (2007-03-29):
+# We don't know the details, or whether the approval means it'll happen,
+# so for now we assume no DST.
+Zone	Asia/Kuwait	3:11:56 -	LMT	1950
+			3:00	-	AST
+
+# Laos
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Vientiane	6:50:24 -	LMT	1906 Jun  9 # or Viangchan
+			7:06:20	-	SMT	1911 Mar 11 0:01 # Saigon MT?
+			7:00	-	ICT	1912 May
+			8:00	-	ICT	1931 May
+			7:00	-	ICT
+
+# Lebanon
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Lebanon	1920	only	-	Mar	28	0:00	1:00	S
+Rule	Lebanon	1920	only	-	Oct	25	0:00	0	-
+Rule	Lebanon	1921	only	-	Apr	3	0:00	1:00	S
+Rule	Lebanon	1921	only	-	Oct	3	0:00	0	-
+Rule	Lebanon	1922	only	-	Mar	26	0:00	1:00	S
+Rule	Lebanon	1922	only	-	Oct	8	0:00	0	-
+Rule	Lebanon	1923	only	-	Apr	22	0:00	1:00	S
+Rule	Lebanon	1923	only	-	Sep	16	0:00	0	-
+Rule	Lebanon	1957	1961	-	May	1	0:00	1:00	S
+Rule	Lebanon	1957	1961	-	Oct	1	0:00	0	-
+Rule	Lebanon	1972	only	-	Jun	22	0:00	1:00	S
+Rule	Lebanon	1972	1977	-	Oct	1	0:00	0	-
+Rule	Lebanon	1973	1977	-	May	1	0:00	1:00	S
+Rule	Lebanon	1978	only	-	Apr	30	0:00	1:00	S
+Rule	Lebanon	1978	only	-	Sep	30	0:00	0	-
+Rule	Lebanon	1984	1987	-	May	1	0:00	1:00	S
+Rule	Lebanon	1984	1991	-	Oct	16	0:00	0	-
+Rule	Lebanon	1988	only	-	Jun	1	0:00	1:00	S
+Rule	Lebanon	1989	only	-	May	10	0:00	1:00	S
+Rule	Lebanon	1990	1992	-	May	1	0:00	1:00	S
+Rule	Lebanon	1992	only	-	Oct	4	0:00	0	-
+Rule	Lebanon	1993	max	-	Mar	lastSun	0:00	1:00	S
+Rule	Lebanon	1993	1998	-	Sep	lastSun	0:00	0	-
+Rule	Lebanon	1999	max	-	Oct	lastSun	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Beirut	2:22:00 -	LMT	1880
+			2:00	Lebanon	EE%sT
+
+# Malaysia
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	NBorneo	1935	1941	-	Sep	14	0:00	0:20	TS # one-Third Summer
+Rule	NBorneo	1935	1941	-	Dec	14	0:00	0	-
+#
+# peninsular Malaysia
+# The data here are taken from Mok Ly Yng (2003-10-30)
+# <http://www.math.nus.edu.sg/aslaksen/teaching/timezone.html>.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Asia/Kuala_Lumpur	6:46:46 -	LMT	1901 Jan  1
+			6:55:25	-	SMT	1905 Jun  1 # Singapore M.T.
+			7:00	-	MALT	1933 Jan  1 # Malaya Time
+			7:00	0:20	MALST	1936 Jan  1
+			7:20	-	MALT	1941 Sep  1
+			7:30	-	MALT	1942 Feb 16
+			9:00	-	JST	1945 Sep 12
+			7:30	-	MALT	1982 Jan  1
+			8:00	-	MYT	# Malaysia Time
+# Sabah & Sarawak
+# From Paul Eggert (2006-03-22):
+# The data here are mostly from Shanks & Pottenger, but the 1942, 1945 and 1982
+# transition dates are from Mok Ly Yng.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Asia/Kuching	7:21:20	-	LMT	1926 Mar
+			7:30	-	BORT	1933	# Borneo Time
+			8:00	NBorneo	BOR%sT	1942 Feb 16
+			9:00	-	JST	1945 Sep 12
+			8:00	-	BORT	1982 Jan  1
+			8:00	-	MYT
+
+# Maldives
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Indian/Maldives	4:54:00 -	LMT	1880	# Male
+			4:54:00	-	MMT	1960	# Male Mean Time
+			5:00	-	MVT		# Maldives Time
+
+# Mongolia
+
+# Shanks & Pottenger say that Mongolia has three time zones, but
+# usno1995 and the CIA map Standard Time Zones of the World (2005-03)
+# both say that it has just one.
+
+# From Oscar van Vlijmen (1999-12-11):
+# <a href="http://www.mongoliatourism.gov.mn/general.htm">
+# General Information Mongolia
+# </a> (1999-09)
+# "Time: Mongolia has two time zones. Three westernmost provinces of
+# Bayan-Ulgii, Uvs, and Hovd are one hour earlier than the capital city, and
+# the rest of the country follows the Ulaanbaatar time, which is UTC/GMT plus
+# eight hours."
+
+# From Rives McDow (1999-12-13):
+# Mongolia discontinued the use of daylight savings time in 1999; 1998
+# being the last year it was implemented.  The dates of implementation I am
+# unsure of, but most probably it was similar to Russia, except for the time
+# of implementation may have been different....
+# Some maps in the past have indicated that there was an additional time
+# zone in the eastern part of Mongolia, including the provinces of Dornod,
+# Suhbaatar, and possibly Khentij.
+
+# From Paul Eggert (1999-12-15):
+# Naming and spelling is tricky in Mongolia.
+# We'll use Hovd (also spelled Chovd and Khovd) to represent the west zone;
+# the capital of the Hovd province is sometimes called Hovd, sometimes Dund-Us,
+# and sometimes Jirgalanta (with variant spellings), but the name Hovd
+# is good enough for our purposes.
+
+# From Rives McDow (2001-05-13):
+# In addition to Mongolia starting daylight savings as reported earlier
+# (adopted DST on 2001-04-27 02:00 local time, ending 2001-09-28),
+# there are three time zones.
+#
+# Provinces [at 7:00]: Bayan-ulgii, Uvs, Khovd, Zavkhan, Govi-Altai
+# Provinces [at 8:00]: Khovsgol, Bulgan, Arkhangai, Khentii, Tov,
+#	Bayankhongor, Ovorkhangai, Dundgovi, Dornogovi, Omnogovi
+# Provinces [at 9:00]: Dornod, Sukhbaatar
+#
+# [The province of Selenge is omitted from the above lists.]
+
+# From Ganbold Ts., Ulaanbaatar (2004-04-17):
+# Daylight saving occurs at 02:00 local time last Saturday of March.
+# It will change back to normal at 02:00 local time last Saturday of
+# September.... As I remember this rule was changed in 2001.
+#
+# From Paul Eggert (2004-04-17):
+# For now, assume Rives McDow's informant got confused about Friday vs
+# Saturday, and that his 2001 dates should have 1 added to them.
+
+# From Paul Eggert (2005-07-26):
+# We have wildly conflicting information about Mongolia's time zones.
+# Bill Bonnet (2005-05-19) reports that the US Embassy in Ulaanbaatar says
+# there is only one time zone and that DST is observed, citing Microsoft
+# Windows XP as the source.  Risto Nykanen (2005-05-16) reports that
+# travelmongolia.org says there are two time zones (UTC+7, UTC+8) with no DST.
+# Oscar van Vlijmen (2005-05-20) reports that the Mongolian Embassy in
+# Washington, DC says there are two time zones, with DST observed.
+# He also found
+# <http://ubpost.mongolnews.mn/index.php?subaction=showcomments&id=1111634894&archive=&start_from=&ucat=1&>
+# which also says that there is DST, and which has a comment by "Toddius"
+# (2005-03-31 06:05 +0700) saying "Mongolia actually has 3.5 time zones.
+# The West (OLGII) is +7 GMT, most of the country is ULAT is +8 GMT
+# and some Eastern provinces are +9 GMT but Sukhbaatar Aimag is SUHK +8.5 GMT.
+# The SUKH timezone is new this year, it is one of the few things the
+# parliament passed during the tumultuous winter session."
+# For now, let's ignore this information, until we have more confirmation.
+
+# From Ganbold Ts. (2007-02-26):
+# Parliament of Mongolia has just changed the daylight-saving rule in February.
+# They decided not to adopt daylight-saving time....
+# http://www.mongolnews.mn/index.php?module=unuudur&sec=view&id=15742
+
+# From Deborah Goldsmith (2008-03-30):
+# We received a bug report claiming that the tz database UTC offset for
+# Asia/Choibalsan (GMT+09:00) is incorrect, and that it should be GMT
+# +08:00 instead. Different sources appear to disagree with the tz
+# database on this, e.g.:
+#
+# <a href="http://www.timeanddate.com/worldclock/city.html?n=1026">
+# http://www.timeanddate.com/worldclock/city.html?n=1026
+# </a>
+# <a href="http://www.worldtimeserver.com/current_time_in_MN.aspx">
+# http://www.worldtimeserver.com/current_time_in_MN.aspx
+# </a>
+#
+# both say GMT+08:00.
+
+# From Steffen Thorsen (2008-03-31):
+# eznis airways, which operates several domestic flights, has a flight
+# schedule here:
+# <a href="http://www.eznis.com/Container.jsp?id=112">
+# http://www.eznis.com/Container.jsp?id=112
+# </a>
+# (click the English flag for English)
+#
+# There it appears that flights between Choibalsan and Ulaanbatar arrive
+# about 1:35 - 1:50 hours later in local clock time, no matter the
+# direction, while Ulaanbaatar-Khvod takes 2 hours in the Eastern
+# direction and 3:35 back, which indicates that Ulaanbatar and Khvod are
+# in different time zones (like we know about), while Choibalsan and
+# Ulaanbatar are in the same time zone (correction needed).
+
+# From Arthur David Olson (2008-05-19):
+# Assume that Choibalsan is indeed offset by 8:00.
+# XXX--in the absence of better information, assume that transition
+# was at the start of 2008-03-31 (the day of Steffen Thorsen's report);
+# this is almost surely wrong.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Mongol	1983	1984	-	Apr	1	0:00	1:00	S
+Rule	Mongol	1983	only	-	Oct	1	0:00	0	-
+# Shanks & Pottenger and IATA SSIM say 1990s switches occurred at 00:00,
+# but McDow says the 2001 switches occurred at 02:00.  Also, IATA SSIM
+# (1996-09) says 1996-10-25.  Go with Shanks & Pottenger through 1998.
+#
+# Shanks & Pottenger say that the Sept. 1984 through Sept. 1990 switches
+# in Choibalsan (more precisely, in Dornod and Sukhbaatar) took place
+# at 02:00 standard time, not at 00:00 local time as in the rest of
+# the country.  That would be odd, and possibly is a result of their
+# correction of 02:00 (in the previous edition) not being done correctly
+# in the latest edition; so ignore it for now.
+
+Rule	Mongol	1985	1998	-	Mar	lastSun	0:00	1:00	S
+Rule	Mongol	1984	1998	-	Sep	lastSun	0:00	0	-
+# IATA SSIM (1999-09) says Mongolia no longer observes DST.
+Rule	Mongol	2001	only	-	Apr	lastSat	2:00	1:00	S
+Rule	Mongol	2001	2006	-	Sep	lastSat	2:00	0	-
+Rule	Mongol	2002	2006	-	Mar	lastSat	2:00	1:00	S
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# Hovd, a.k.a. Chovd, Dund-Us, Dzhargalant, Khovd, Jirgalanta
+Zone	Asia/Hovd	6:06:36 -	LMT	1905 Aug
+			6:00	-	HOVT	1978	# Hovd Time
+			7:00	Mongol	HOV%sT
+# Ulaanbaatar, a.k.a. Ulan Bataar, Ulan Bator, Urga
+Zone	Asia/Ulaanbaatar 7:07:32 -	LMT	1905 Aug
+			7:00	-	ULAT	1978	# Ulaanbaatar Time
+			8:00	Mongol	ULA%sT
+# Choibalsan, a.k.a. Bajan Tuemen, Bajan Tumen, Chojbalsan,
+# Choybalsan, Sanbejse, Tchoibalsan
+Zone	Asia/Choibalsan	7:38:00 -	LMT	1905 Aug
+			7:00	-	ULAT	1978
+			8:00	-	ULAT	1983 Apr
+			9:00	Mongol	CHO%sT	2008 Mar 31 # Choibalsan Time
+			8:00	Mongol	CHO%sT
+
+# Nepal
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Katmandu	5:41:16 -	LMT	1920
+			5:30	-	IST	1986
+			5:45	-	NPT	# Nepal Time
+
+# Oman
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Muscat	3:54:20 -	LMT	1920
+			4:00	-	GST
+
+# Pakistan
+
+# From Rives McDow (2002-03-13):
+# I have been advised that Pakistan has decided to adopt dst on a
+# TRIAL basis for one year, starting 00:01 local time on April 7, 2002
+# and ending at 00:01 local time October 6, 2002.  This is what I was
+# told, but I believe that the actual time of change may be 00:00; the
+# 00:01 was to make it clear which day it was on.
+
+# From Paul Eggert (2002-03-15):
+# Jesper Norgaard found this URL:
+# http://www.pak.gov.pk/public/news/app/app06_dec.htm
+# (dated 2001-12-06) which says that the Cabinet adopted a scheme "to
+# advance the clocks by one hour on the night between the first
+# Saturday and Sunday of April and revert to the original position on
+# 15th October each year".  This agrees with McDow's 04-07 at 00:00,
+# but disagrees about the October transition, and makes it sound like
+# it's not on a trial basis.  Also, the "between the first Saturday
+# and Sunday of April" phrase, if taken literally, means that the
+# transition takes place at 00:00 on the first Sunday on or after 04-02.
+
+# From Paul Eggert (2003-02-09):
+# DAWN <http://www.dawn.com/2002/10/06/top13.htm> reported on 2002-10-05
+# that 2002 DST ended that day at midnight.  Go with McDow for now.
+
+# From Steffen Thorsen (2003-03-14):
+# According to http://www.dawn.com/2003/03/07/top15.htm
+# there will be no DST in Pakistan this year:
+#
+# ISLAMABAD, March 6: Information and Media Development Minister Sheikh
+# Rashid Ahmed on Thursday said the cabinet had reversed a previous
+# decision to advance clocks by one hour in summer and put them back by
+# one hour in winter with the aim of saving light hours and energy.
+#
+# The minister told a news conference that the experiment had rather
+# shown 8 per cent higher consumption of electricity.
+
+# From Alex Krivenyshev (2008-05-15):
+# 
+# Here is an article that Pakistan plan to introduce Daylight Saving Time 
+# on June 1, 2008 for 3 months.
+# 
+# "... The federal cabinet on Wednesday announced a new conservation plan to help 
+# reduce load shedding by approving the closure of commercial centres at 9pm and 
+# moving clocks forward by one hour for the next three months. 
+# ...."
+# 
+# <a href="http://www.worldtimezone.net/dst_news/dst_news_pakistan01.html">
+# http://www.worldtimezone.net/dst_news/dst_news_pakistan01.html
+# </a>
+# OR
+# <a href="http://www.dailytimes.com.pk/default.asp?page=2008%5C05%5C15%5Cstory_15-5-2008_pg1_4">
+# http://www.dailytimes.com.pk/default.asp?page=2008%5C05%5C15%5Cstory_15-5-2008_pg1_4
+# </a>
+
+# From Arthur David Olson (2008-05-19):
+# XXX--midnight transitions is a guess; 2008 only is a guess.
+
+# From Alexander Krivenyshev (2008-08-28):
+# Pakistan government has decided to keep the watches one-hour advanced
+# for another 2 months--plan to return to Standard Time on October 31
+# instead of August 31.
+#
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_pakistan02.html">
+# http://www.worldtimezone.com/dst_news/dst_news_pakistan02.html
+# </a>
+# OR
+# <a href="http://dailymailnews.com/200808/28/news/dmbrn03.html">
+# http://dailymailnews.com/200808/28/news/dmbrn03.html
+# </a>
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule Pakistan	2002	only	-	Apr	Sun>=2	0:01	1:00	S
+Rule Pakistan	2002	only	-	Oct	Sun>=2	0:01	0	-
+Rule Pakistan	2008	only	-	Jun	1	0:00	1:00	S
+Rule Pakistan	2008	only	-	Nov	1	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Karachi	4:28:12 -	LMT	1907
+			5:30	-	IST	1942 Sep
+			5:30	1:00	IST	1945 Oct 15
+			5:30	-	IST	1951 Sep 30
+			5:00	-	KART	1971 Mar 26 # Karachi Time
+			5:00 Pakistan	PK%sT	# Pakistan Time
+
+# Palestine
+
+# From Amos Shapir (1998-02-15):
+#
+# From 1917 until 1948-05-15, all of Palestine, including the parts now
+# known as the Gaza Strip and the West Bank, was under British rule.
+# Therefore the rules given for Israel for that period, apply there too...
+#
+# The Gaza Strip was under Egyptian rule between 1948-05-15 until 1967-06-05
+# (except a short occupation by Israel from 1956-11 till 1957-03, but no
+# time zone was affected then).  It was never formally annexed to Egypt,
+# though.
+#
+# The rest of Palestine was under Jordanian rule at that time, formally
+# annexed in 1950 as the West Bank (and the word "Trans" was dropped from
+# the country's previous name of "the Hashemite Kingdom of the
+# Trans-Jordan").  So the rules for Jordan for that time apply.  Major
+# towns in that area are Nablus (Shchem), El-Halil (Hebron), Ramallah, and
+# East Jerusalem.
+#
+# Both areas were occupied by Israel in June 1967, but not annexed (except
+# for East Jerusalem).  They were on Israel time since then; there might
+# have been a Military Governor's order about time zones, but I'm not aware
+# of any (such orders may have been issued semi-annually whenever summer
+# time was in effect, but maybe the legal aspect of time was just neglected).
+#
+# The Palestinian Authority was established in 1993, and got hold of most
+# towns in the West Bank and Gaza by 1995.  I know that in order to
+# demonstrate...independence, they have been switching to
+# summer time and back on a different schedule than Israel's, but I don't
+# know when this was started, or what algorithm is used (most likely the
+# Jordanian one).
+#
+# To summarize, the table should probably look something like that:
+#
+# Area \ when | 1918-1947 | 1948-1967 | 1967-1995 | 1996-
+# ------------+-----------+-----------+-----------+-----------
+# Israel      | Zion      | Zion      | Zion      | Zion
+# West bank   | Zion      | Jordan    | Zion      | Jordan
+# Gaza        | Zion      | Egypt     | Zion      | Jordan
+#
+# I guess more info may be available from the PA's web page (if/when they
+# have one).
+
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger write that Gaza did not observe DST until 1957, but go
+# with Shapir and assume that it observed DST from 1940 through 1947,
+# and that it used Jordanian rules starting in 1996.
+# We don't yet need a separate entry for the West Bank, since
+# the only differences between it and Gaza that we know about
+# occurred before our cutoff date of 1970.
+# However, as we get more information, we may need to add entries
+# for parts of the West Bank as they transitioned from Israel's rules
+# to Palestine's rules.  If you have more info about this, please
+# send it to tz@elsie.nci.nih.gov for incorporation into future editions.
+
+# From IINS News Service - Israel - 1998-03-23 10:38:07 Israel time,
+# forwarded by Ephraim Silverberg:
+#
+# Despite the fact that Israel changed over to daylight savings time
+# last week, the PLO Authority (PA) has decided not to turn its clocks
+# one-hour forward at this time.  As a sign of independence from Israeli rule,
+# the PA has decided to implement DST in April.
+
+# From Paul Eggert (1999-09-20):
+# Daoud Kuttab writes in
+# <a href="http://www.jpost.com/com/Archive/22.Apr.1999/Opinion/Article-2.html">
+# Holiday havoc
+# </a> (Jerusalem Post, 1999-04-22) that
+# the Palestinian National Authority changed to DST on 1999-04-15.
+# I vaguely recall that they switch back in October (sorry, forgot the source).
+# For now, let's assume that the spring switch was at 24:00,
+# and that they switch at 0:00 on the 3rd Fridays of April and October.
+
+# From Paul Eggert (2005-11-22):
+# Starting 2004 transitions are from Steffen Thorsen's web site timeanddate.com.
+
+# From Steffen Thorsen (2005-11-23):
+# A user from Gaza reported that Gaza made the change early because of
+# the Ramadan.  Next year Ramadan will be even earlier, so I think
+# there is a good chance next year's end date will be around two weeks
+# earlier--the same goes for Jordan.
+
+# From Steffen Thorsen (2006-08-17):
+# I was informed by a user in Bethlehem that in Bethlehem it started the
+# same day as Israel, and after checking with other users in the area, I
+# was informed that they started DST one day after Israel.  I was not
+# able to find any authoritative sources at the time, nor details if
+# Gaza changed as well, but presumed Gaza to follow the same rules as
+# the West Bank.
+
+# From Steffen Thorsen (2006-09-26):
+# according to the Palestine News Network (2006-09-19):
+# http://english.pnn.ps/index.php?option=com_content&task=view&id=596&Itemid=5
+# > The Council of Ministers announced that this year its winter schedule
+# > will begin early, as of midnight Thursday.  It is also time to turn
+# > back the clocks for winter.  Friday will begin an hour late this week.
+# I guess it is likely that next year's date will be moved as well,
+# because of the Ramadan.
+
+# From Jesper Norgaard Welen (2007-09-18):
+# According to Steffen Thorsen's web site the Gaza Strip and the rest of the
+# Palestinian territories left DST early on 13.th. of September at 2:00.
+
+# From Paul Eggert (2007-09-20):
+# My understanding is that Gaza and the West Bank disagree even over when
+# the weekend is (Thursday+Friday versus Friday+Saturday), so I'd be a bit
+# surprised if they agreed about DST.  But for now, assume they agree.
+# For lack of better information, predict that future changes will be
+# the 2nd Thursday of September at 02:00.
+
+# From Alexander Krivenyshev (2008-08-28):
+# Here is an article, that Mideast running on different clocks at Ramadan.
+#
+# Gaza Strip (as Egypt) ended DST at midnight Thursday (Aug 28, 2008), while
+# the West Bank will end Daylight Saving Time at midnight Sunday (Aug 31, 2008).
+#
+# <a href="http://www.guardian.co.uk/world/feedarticle/7759001">
+# http://www.guardian.co.uk/world/feedarticle/7759001
+# </a>
+# <a href="http://www.abcnews.go.com/International/wireStory?id=5676087">
+# http://www.abcnews.go.com/International/wireStory?id=5676087
+# </a>
+# or
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_gazastrip01.html">
+# http://www.worldtimezone.com/dst_news/dst_news_gazastrip01.html
+# </a>
+
+# The rules for Egypt are stolen from the `africa' file.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule EgyptAsia	1957	only	-	May	10	0:00	1:00	S
+Rule EgyptAsia	1957	1958	-	Oct	 1	0:00	0	-
+Rule EgyptAsia	1958	only	-	May	 1	0:00	1:00	S
+Rule EgyptAsia	1959	1967	-	May	 1	1:00	1:00	S
+Rule EgyptAsia	1959	1965	-	Sep	30	3:00	0	-
+Rule EgyptAsia	1966	only	-	Oct	 1	3:00	0	-
+
+Rule Palestine	1999	2005	-	Apr	Fri>=15	0:00	1:00	S
+Rule Palestine	1999	2003	-	Oct	Fri>=15	0:00	0	-
+Rule Palestine	2004	only	-	Oct	 1	1:00	0	-
+Rule Palestine	2005	only	-	Oct	 4	2:00	0	-
+Rule Palestine	2006	max	-	Apr	 1	0:00	1:00	S
+Rule Palestine	2006	only	-	Sep	22	0:00	0	-
+Rule Palestine	2007	only	-	Sep	Thu>=8	2:00	0	-
+Rule Palestine	2008	max	-	Aug	lastThu	2:00	0	-
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
+			2:00	Zion	EET	1948 May 15
+			2:00 EgyptAsia	EE%sT	1967 Jun  5
+			2:00	Zion	I%sT	1996
+			2:00	Jordan	EE%sT	1999
+			2:00 Palestine	EE%sT
+
+# Paracel Is
+# no information
+
+# Philippines
+# On 1844-08-16, Narciso Claveria, governor-general of the
+# Philippines, issued a proclamation announcing that 1844-12-30 was to
+# be immediately followed by 1845-01-01.  Robert H. van Gent has a
+# transcript of the decree in <http://www.phys.uu.nl/~vgent/idl/idl.htm>.
+# The rest of the data are from Shanks & Pottenger.
+
+# From Paul Eggert (2006-04-25):
+# Tomorrow's Manila Standard reports that the Philippines Department of
+# Trade and Industry is considering adopting DST this June when the
+# rainy season begins.  See
+# <http://www.manilastandardtoday.com/?page=politics02_april26_2006>.
+# For now, we'll ignore this, since it's not definite and we lack details.
+#
+# From Jesper Norgaard Welen (2006-04-26):
+# ... claims that Philippines had DST last time in 1990:
+# http://story.philippinetimes.com/p.x/ct/9/id/145be20cc6b121c0/cid/3e5bbccc730d258c/
+# [a story dated 2006-04-25 by Cris Larano of Dow Jones Newswires,
+# but no details]
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Phil	1936	only	-	Nov	1	0:00	1:00	S
+Rule	Phil	1937	only	-	Feb	1	0:00	0	-
+Rule	Phil	1954	only	-	Apr	12	0:00	1:00	S
+Rule	Phil	1954	only	-	Jul	1	0:00	0	-
+Rule	Phil	1978	only	-	Mar	22	0:00	1:00	S
+Rule	Phil	1978	only	-	Sep	21	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Manila	-15:56:00 -	LMT	1844 Dec 31
+			8:04:00 -	LMT	1899 May 11
+			8:00	Phil	PH%sT	1942 May
+			9:00	-	JST	1944 Nov
+			8:00	Phil	PH%sT
+
+# Qatar
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Qatar	3:26:08 -	LMT	1920	# Al Dawhah / Doha
+			4:00	-	GST	1972 Jun
+			3:00	-	AST
+
+# Saudi Arabia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Riyadh	3:06:52 -	LMT	1950
+			3:00	-	AST
+
+# Singapore
+# The data here are taken from Mok Ly Yng (2003-10-30)
+# <http://www.math.nus.edu.sg/aslaksen/teaching/timezone.html>.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Singapore	6:55:25 -	LMT	1901 Jan  1
+			6:55:25	-	SMT	1905 Jun  1 # Singapore M.T.
+			7:00	-	MALT	1933 Jan  1 # Malaya Time
+			7:00	0:20	MALST	1936 Jan  1
+			7:20	-	MALT	1941 Sep  1
+			7:30	-	MALT	1942 Feb 16
+			9:00	-	JST	1945 Sep 12
+			7:30	-	MALT	1965 Aug  9 # independence
+			7:30	-	SGT	1982 Jan  1 # Singapore Time
+			8:00	-	SGT
+
+# Spratly Is
+# no information
+
+# Sri Lanka
+# From Paul Eggert (1996-09-03):
+# "Sri Lanka advances clock by an hour to avoid blackout"
+# (www.virtual-pc.com/lankaweb/news/items/240596-2.html, 1996-05-24,
+# no longer available as of 1999-08-17)
+# reported ``the country's standard time will be put forward by one hour at
+# midnight Friday (1830 GMT) `in the light of the present power crisis'.''
+#
+# From Dharmasiri Senanayake, Sri Lanka Media Minister (1996-10-24), as quoted
+# by Shamindra in
+# <a href="news:54rka5$m5h@mtinsc01-mgt.ops.worldnet.att.net">
+# Daily News - Hot News Section (1996-10-26)
+# </a>:
+# With effect from 12.30 a.m. on 26th October 1996
+# Sri Lanka will be six (06) hours ahead of GMT.
+
+# From Jesper Norgaard Welen (2006-04-14), quoting Sri Lanka News Online
+# <http://news.sinhalaya.com/wmview.php?ArtID=11002> (2006-04-13):
+# 0030 hrs on April 15, 2006 (midnight of April 14, 2006 +30 minutes)
+# at present, become 2400 hours of April 14, 2006 (midnight of April 14, 2006).
+
+# From Peter Apps and Ranga Sirila of Reuters (2006-04-12) in:
+# <http://today.reuters.co.uk/news/newsArticle.aspx?type=scienceNews&storyID=2006-04-12T172228Z_01_COL295762_RTRIDST_0_SCIENCE-SRILANKA-TIME-DC.XML>
+# [The Tamil Tigers] never accepted the original 1996 time change and simply
+# kept their clocks set five and a half hours ahead of Greenwich Mean
+# Time (GMT), in line with neighbor India.
+# From Paul Eggert (2006-04-18):
+# People who live in regions under Tamil control can use [TZ='Asia/Kolkata'],
+# as that zone has agreed with the Tamil areas since our cutoff date of 1970.
+
+# From K Sethu (2006-04-25):
+# I think the abbreviation LKT originated from the world of computers at
+# the time of or subsequent to the time zone changes by SL Government
+# twice in 1996 and probably SL Government or its standardization
+# agencies never declared an abbreviation as a national standard.
+#
+# I recollect before the recent change the government annoucemments
+# mentioning it as simply changing Sri Lanka Standard Time or Sri Lanka
+# Time and no mention was made about the abbreviation.
+#
+# If we look at Sri Lanka Department of Government's "Official News
+# Website of Sri Lanka" ... http://www.news.lk/ we can see that they
+# use SLT as abbreviation in time stamp at the beginning of each news
+# item....
+#
+# Within Sri Lanka I think LKT is well known among computer users and
+# adminsitrators.  In my opinion SLT may not be a good choice because the
+# nation's largest telcom / internet operator Sri Lanka Telcom is well
+# known by that abbreviation - simply as SLT (there IP domains are
+# slt.lk and sltnet.lk).
+#
+# But if indeed our government has adopted SLT as standard abbreviation
+# (that we have not known so far) then  it is better that it be used for
+# all computers.
+
+# From Paul Eggert (2006-04-25):
+# One possibility is that we wait for a bit for the dust to settle down
+# and then see what people actually say in practice.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Colombo	5:19:24 -	LMT	1880
+			5:19:32	-	MMT	1906	# Moratuwa Mean Time
+			5:30	-	IST	1942 Jan  5
+			5:30	0:30	IHST	1942 Sep
+			5:30	1:00	IST	1945 Oct 16 2:00
+			5:30	-	IST	1996 May 25 0:00
+			6:30	-	LKT	1996 Oct 26 0:30
+			6:00	-	LKT	2006 Apr 15 0:30
+			5:30	-	IST
+
+# Syria
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Syria	1920	1923	-	Apr	Sun>=15	2:00	1:00	S
+Rule	Syria	1920	1923	-	Oct	Sun>=1	2:00	0	-
+Rule	Syria	1962	only	-	Apr	29	2:00	1:00	S
+Rule	Syria	1962	only	-	Oct	1	2:00	0	-
+Rule	Syria	1963	1965	-	May	1	2:00	1:00	S
+Rule	Syria	1963	only	-	Sep	30	2:00	0	-
+Rule	Syria	1964	only	-	Oct	1	2:00	0	-
+Rule	Syria	1965	only	-	Sep	30	2:00	0	-
+Rule	Syria	1966	only	-	Apr	24	2:00	1:00	S
+Rule	Syria	1966	1976	-	Oct	1	2:00	0	-
+Rule	Syria	1967	1978	-	May	1	2:00	1:00	S
+Rule	Syria	1977	1978	-	Sep	1	2:00	0	-
+Rule	Syria	1983	1984	-	Apr	9	2:00	1:00	S
+Rule	Syria	1983	1984	-	Oct	1	2:00	0	-
+Rule	Syria	1986	only	-	Feb	16	2:00	1:00	S
+Rule	Syria	1986	only	-	Oct	9	2:00	0	-
+Rule	Syria	1987	only	-	Mar	1	2:00	1:00	S
+Rule	Syria	1987	1988	-	Oct	31	2:00	0	-
+Rule	Syria	1988	only	-	Mar	15	2:00	1:00	S
+Rule	Syria	1989	only	-	Mar	31	2:00	1:00	S
+Rule	Syria	1989	only	-	Oct	1	2:00	0	-
+Rule	Syria	1990	only	-	Apr	1	2:00	1:00	S
+Rule	Syria	1990	only	-	Sep	30	2:00	0	-
+Rule	Syria	1991	only	-	Apr	 1	0:00	1:00	S
+Rule	Syria	1991	1992	-	Oct	 1	0:00	0	-
+Rule	Syria	1992	only	-	Apr	 8	0:00	1:00	S
+Rule	Syria	1993	only	-	Mar	26	0:00	1:00	S
+Rule	Syria	1993	only	-	Sep	25	0:00	0	-
+# IATA SSIM (1998-02) says 1998-04-02;
+# (1998-09) says 1999-03-29 and 1999-09-29; (1999-02) says 1999-04-02,
+# 2000-04-02, and 2001-04-02; (1999-09) says 2000-03-31 and 2001-03-31;
+# (2006) says 2006-03-31 and 2006-09-22;
+# for now ignore all these claims and go with Shanks & Pottenger,
+# except for the 2006-09-22 claim (which seems right for Ramadan).
+Rule	Syria	1994	1996	-	Apr	 1	0:00	1:00	S
+Rule	Syria	1994	2005	-	Oct	 1	0:00	0	-
+Rule	Syria	1997	1998	-	Mar	lastMon	0:00	1:00	S
+Rule	Syria	1999	2006	-	Apr	 1	0:00	1:00	S
+# From Stephen Colebourne (2006-09-18):
+# According to IATA data, Syria will change DST on 21st September [21:00 UTC]
+# this year [only]....  This is probably related to Ramadan, like Egypt.
+Rule	Syria	2006	only	-	Sep	22	0:00	0	-
+# From Paul Eggert (2007-03-29):
+# Today the AP reported "Syria will switch to summertime at midnight Thursday."
+# http://www.iht.com/articles/ap/2007/03/29/africa/ME-GEN-Syria-Time-Change.php
+Rule	Syria	2007	only	-	Mar	lastFri	0:00	1:00	S
+# From Jesper Norgard (2007-10-27):
+# The sister center ICARDA of my work CIMMYT is confirming that Syria DST will
+# not take place 1.st November at 0:00 o'clock but 1.st November at 24:00 or
+# rather Midnight between Thursday and Friday. This does make more sence than
+# having it between Wednesday and Thursday (two workdays in Syria) since the
+# weekend in Syria is not Saturday and Sunday, but Friday and Saturday. So now
+# it is implemented at midnight of the last workday before weekend...
+# 
+# From Steffen Thorsen (2007-10-27):
+# Jesper Norgaard Welen wrote:
+# 
+# > "Winter local time in Syria will be observed at midnight of Thursday 1
+# > November 2007, and the clock will be put back 1 hour."
+# 
+# I found confirmation on this in this gov.sy-article (Arabic):
+# http://wehda.alwehda.gov.sy/_print_veiw.asp?FileName=12521710520070926111247
+# 
+# which using Google's translate tools says:
+# Council of Ministers also approved the commencement of work on 
+# identifying the winter time as of Friday, 2/11/2007 where the 60th 
+# minute delay at midnight Thursday 1/11/2007.
+Rule	Syria	2007	only	-	Nov	 Fri>=1	0:00	0	-
+
+# From Stephen Colebourne (2008-03-17):
+# For everyone's info, I saw an IATA time zone change for [Syria] for
+# this month (March 2008) in the last day or so...This is the data IATA
+# are now using:
+# Country     Time Standard   --- DST Start ---   --- DST End ---  DST
+# Name        Zone Variation   Time    Date        Time    Date
+# Variation
+# Syrian Arab
+# Republic    SY    +0200      2200  03APR08       2100  30SEP08   +0300
+#                              2200  02APR09       2100  30SEP09   +0300
+#                              2200  01APR10       2100  30SEP10   +0300
+
+# From Arthur David Olson (2008-03-17):
+# Here's a link to English-language coverage by the Syrian Arab News
+# Agency (SANA)...
+# <a href="http://www.sana.sy/eng/21/2008/03/11/165173.htm">
+# http://www.sana.sy/eng/21/2008/03/11/165173.htm
+# </a>...which reads (in part) "The Cabinet approved the suggestion of the
+# Ministry of Electricity to begin daylight savings time on Friday April
+# 4th, advancing clocks one hour ahead on midnight of Thursday April 3rd."
+# Since Syria is two hours east of UTC, the 2200 and 2100 transition times
+# shown above match up with midnight in Syria.
+
+# From Arthur David Olson (2008-03-18):
+# My buest guess at a Syrian rule is "the Friday nearest April 1";
+# coding that involves either using a "Mar Fri>=29" construct that old time zone
+# compilers can't handle  or having multiple Rules (a la Israel).
+# For now, use "Apr Fri>=1", and go with IATA on a uniform Sep 30 end.
+
+# From Steffen Thorsen (2008-10-07):
+# Syria has now officially decided to end DST on 2008-11-01 this year,
+# according to the following article in the Syrian Arab News Agency (SANA).
+#
+# The article is in Arabic, and seems to tell that they will go back to
+# winter time on 2008-11-01 at 00:00 local daylight time (delaying/setting
+# clocks back 60 minutes).
+#
+# <a href="http://sana.sy/ara/2/2008/10/07/195459.htm">
+# http://sana.sy/ara/2/2008/10/07/195459.htm
+# </a>
+
+Rule	Syria	2008	max	-	Apr	Fri>=1	0:00	1:00	S
+Rule	Syria	2008	max	-	Nov	1	0:00	0	-
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Damascus	2:25:12 -	LMT	1920	# Dimashq
+			2:00	Syria	EE%sT
+
+# Tajikistan
+# From Shanks & Pottenger.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Dushanbe	4:35:12 -	LMT	1924 May  2
+			5:00	-	DUST	1930 Jun 21 # Dushanbe Time
+			6:00 RussiaAsia DUS%sT	1991 Mar 31 2:00s
+			5:00	1:00	DUSST	1991 Sep  9 2:00s
+			5:00	-	TJT		    # Tajikistan Time
+
+# Thailand
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Bangkok	6:42:04	-	LMT	1880
+			6:42:04	-	BMT	1920 Apr # Bangkok Mean Time
+			7:00	-	ICT
+
+# Turkmenistan
+# From Shanks & Pottenger.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Ashgabat	3:53:32 -	LMT	1924 May  2 # or Ashkhabad
+			4:00	-	ASHT	1930 Jun 21 # Ashkhabad Time
+			5:00 RussiaAsia	ASH%sT	1991 Mar 31 2:00
+			4:00 RussiaAsia	ASH%sT	1991 Oct 27 # independence
+			4:00 RussiaAsia	TM%sT	1992 Jan 19 2:00
+			5:00	-	TMT
+
+# United Arab Emirates
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Dubai	3:41:12 -	LMT	1920
+			4:00	-	GST
+
+# Uzbekistan
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Samarkand	4:27:12 -	LMT	1924 May  2
+			4:00	-	SAMT	1930 Jun 21 # Samarkand Time
+			5:00	-	SAMT	1981 Apr  1
+			5:00	1:00	SAMST	1981 Oct  1
+			6:00	-	TAST	1982 Apr  1 # Tashkent Time
+			5:00 RussiaAsia	SAM%sT	1991 Sep  1 # independence
+			5:00 RussiaAsia	UZ%sT	1992
+			5:00	-	UZT
+Zone	Asia/Tashkent	4:37:12 -	LMT	1924 May  2
+			5:00	-	TAST	1930 Jun 21 # Tashkent Time
+			6:00 RussiaAsia	TAS%sT	1991 Mar 31 2:00
+			5:00 RussiaAsia	TAS%sT	1991 Sep  1 # independence
+			5:00 RussiaAsia	UZ%sT	1992
+			5:00	-	UZT
+
+# Vietnam
+
+# From Arthur David Olson (2008-03-18):
+# The English-language name of Vietnam's most populous city is "Ho Chi Min City";
+# we use Ho_Chi_Minh below to avoid a name of more than 14 characters.
+
+# From Shanks & Pottenger:
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Ho_Chi_Minh	7:06:40 -	LMT	1906 Jun  9
+			7:06:20	-	SMT	1911 Mar 11 0:01 # Saigon MT?
+			7:00	-	ICT	1912 May
+			8:00	-	ICT	1931 May
+			7:00	-	ICT
+
+# Yemen
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Asia/Aden	3:00:48	-	LMT	1950
+			3:00	-	AST
diff --git a/tools/zoneinfo/tzdata2008h/australasia b/tools/zoneinfo/tzdata2008h/australasia
new file mode 100644
index 0000000..41608cd
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/australasia
@@ -0,0 +1,1454 @@
+# @(#)australasia	8.9
+# <pre>
+
+# This file also includes Pacific islands.
+
+# Notes are at the end of this file
+
+###############################################################################
+
+# Australia
+
+# Please see the notes below for the controversy about "EST" versus "AEST" etc.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Aus	1917	only	-	Jan	 1	0:01	1:00	-
+Rule	Aus	1917	only	-	Mar	25	2:00	0	-
+Rule	Aus	1942	only	-	Jan	 1	2:00	1:00	-
+Rule	Aus	1942	only	-	Mar	29	2:00	0	-
+Rule	Aus	1942	only	-	Sep	27	2:00	1:00	-
+Rule	Aus	1943	1944	-	Mar	lastSun	2:00	0	-
+Rule	Aus	1943	only	-	Oct	 3	2:00	1:00	-
+# Go with Whitman and the Australian National Standards Commission, which
+# says W Australia didn't use DST in 1943/1944.  Ignore Whitman's claim that
+# 1944/1945 was just like 1943/1944.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# Northern Territory
+Zone Australia/Darwin	 8:43:20 -	LMT	1895 Feb
+			 9:00	-	CST	1899 May
+			 9:30	Aus	CST
+# Western Australia
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	AW	1974	only	-	Oct	lastSun	2:00s	1:00	-
+Rule	AW	1975	only	-	Mar	Sun>=1	2:00s	0	-
+Rule	AW	1983	only	-	Oct	lastSun	2:00s	1:00	-
+Rule	AW	1984	only	-	Mar	Sun>=1	2:00s	0	-
+Rule	AW	1991	only	-	Nov	17	2:00s	1:00	-
+Rule	AW	1992	only	-	Mar	Sun>=1	2:00s	0	-
+Rule	AW	2006	only	-	Dec	 3	2:00s	1:00	-
+Rule	AW	2007	2009	-	Mar	lastSun	2:00s	0	-
+Rule	AW	2007	2008	-	Oct	lastSun	2:00s	1:00	-
+Zone Australia/Perth	 7:43:24 -	LMT	1895 Dec
+			 8:00	Aus	WST	1943 Jul
+			 8:00	AW	WST
+Zone Australia/Eucla	 8:35:28 -	LMT	1895 Dec
+			 8:45	Aus	CWST	1943 Jul
+			 8:45	AW	CWST
+
+# Queensland
+#
+# From Alex Livingston (1996-11-01):
+# I have heard or read more than once that some resort islands off the coast
+# of Queensland chose to keep observing daylight-saving time even after
+# Queensland ceased to.
+#
+# From Paul Eggert (1996-11-22):
+# IATA SSIM (1993-02/1994-09) say that the Holiday Islands (Hayman, Lindeman,
+# Hamilton) observed DST for two years after the rest of Queensland stopped.
+# Hamilton is the largest, but there is also a Hamilton in Victoria,
+# so use Lindeman.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	AQ	1971	only	-	Oct	lastSun	2:00s	1:00	-
+Rule	AQ	1972	only	-	Feb	lastSun	2:00s	0	-
+Rule	AQ	1989	1991	-	Oct	lastSun	2:00s	1:00	-
+Rule	AQ	1990	1992	-	Mar	Sun>=1	2:00s	0	-
+Rule	Holiday	1992	1993	-	Oct	lastSun	2:00s	1:00	-
+Rule	Holiday	1993	1994	-	Mar	Sun>=1	2:00s	0	-
+Zone Australia/Brisbane	10:12:08 -	LMT	1895
+			10:00	Aus	EST	1971
+			10:00	AQ	EST
+Zone Australia/Lindeman  9:55:56 -	LMT	1895
+			10:00	Aus	EST	1971
+			10:00	AQ	EST	1992 Jul
+			10:00	Holiday	EST
+
+# South Australia
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	AS	1971	1985	-	Oct	lastSun	2:00s	1:00	-
+Rule	AS	1986	only	-	Oct	19	2:00s	1:00	-
+Rule	AS	1987	2007	-	Oct	lastSun	2:00s	1:00	-
+Rule	AS	1972	only	-	Feb	27	2:00s	0	-
+Rule	AS	1973	1985	-	Mar	Sun>=1	2:00s	0	-
+Rule	AS	1986	1989	-	Mar	Sun>=15	2:00s	0	-
+Rule	AS	1990	only	-	Mar	Sun>=18	2:00s	0	-
+Rule	AS	1991	only	-	Mar	Sun>=1	2:00s	0	-
+Rule	AS	1992	only	-	Mar	Sun>=18	2:00s	0	-
+Rule	AS	1993	only	-	Mar	Sun>=1	2:00s	0	-
+Rule	AS	1994	only	-	Mar	Sun>=18	2:00s	0	-
+Rule	AS	1995	2005	-	Mar	lastSun	2:00s	0	-
+Rule	AS	2006	only	-	Apr	Sun>=1	2:00s	0	-
+Rule	AS	2007	only	-	Mar	lastSun	2:00s	0	-
+Rule	AS	2008	max	-	Apr	Sun>=1	2:00s	0	-
+Rule	AS	2008	max	-	Oct	Sun>=1	2:00s	1:00	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Australia/Adelaide	9:14:20 -	LMT	1895 Feb
+			9:00	-	CST	1899 May
+			9:30	Aus	CST	1971
+			9:30	AS	CST
+
+# Tasmania
+#
+# From Paul Eggert (2005-08-16):
+# <http://www.bom.gov.au/climate/averages/tables/dst_times.shtml>
+# says King Island didn't observe DST from WWII until late 1971.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	AT	1967	only	-	Oct	Sun>=1	2:00s	1:00	-
+Rule	AT	1968	only	-	Mar	lastSun	2:00s	0	-
+Rule	AT	1968	1985	-	Oct	lastSun	2:00s	1:00	-
+Rule	AT	1969	1971	-	Mar	Sun>=8	2:00s	0	-
+Rule	AT	1972	only	-	Feb	lastSun	2:00s	0	-
+Rule	AT	1973	1981	-	Mar	Sun>=1	2:00s	0	-
+Rule	AT	1982	1983	-	Mar	lastSun	2:00s	0	-
+Rule	AT	1984	1986	-	Mar	Sun>=1	2:00s	0	-
+Rule	AT	1986	only	-	Oct	Sun>=15	2:00s	1:00	-
+Rule	AT	1987	1990	-	Mar	Sun>=15	2:00s	0	-
+Rule	AT	1987	only	-	Oct	Sun>=22	2:00s	1:00	-
+Rule	AT	1988	1990	-	Oct	lastSun	2:00s	1:00	-
+Rule	AT	1991	1999	-	Oct	Sun>=1	2:00s	1:00	-
+Rule	AT	1991	2005	-	Mar	lastSun	2:00s	0	-
+Rule	AT	2000	only	-	Aug	lastSun	2:00s	1:00	-
+Rule	AT	2001	max	-	Oct	Sun>=1	2:00s	1:00	-
+Rule	AT	2006	only	-	Apr	Sun>=1	2:00s	0	-
+Rule	AT	2007	only	-	Mar	lastSun	2:00s	0	-
+Rule	AT	2008	max	-	Apr	Sun>=1	2:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Australia/Hobart	9:49:16	-	LMT	1895 Sep
+			10:00	-	EST	1916 Oct 1 2:00
+			10:00	1:00	EST	1917 Feb
+			10:00	Aus	EST	1967
+			10:00	AT	EST
+Zone Australia/Currie	9:35:28	-	LMT	1895 Sep
+			10:00	-	EST	1916 Oct 1 2:00
+			10:00	1:00	EST	1917 Feb
+			10:00	Aus	EST	1971 Jul
+			10:00	AT	EST
+
+# Victoria
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	AV	1971	1985	-	Oct	lastSun	2:00s	1:00	-
+Rule	AV	1972	only	-	Feb	lastSun	2:00s	0	-
+Rule	AV	1973	1985	-	Mar	Sun>=1	2:00s	0	-
+Rule	AV	1986	1990	-	Mar	Sun>=15	2:00s	0	-
+Rule	AV	1986	1987	-	Oct	Sun>=15	2:00s	1:00	-
+Rule	AV	1988	1999	-	Oct	lastSun	2:00s	1:00	-
+Rule	AV	1991	1994	-	Mar	Sun>=1	2:00s	0	-
+Rule	AV	1995	2005	-	Mar	lastSun	2:00s	0	-
+Rule	AV	2000	only	-	Aug	lastSun	2:00s	1:00	-
+Rule	AV	2001	2007	-	Oct	lastSun	2:00s	1:00	-
+Rule	AV	2006	only	-	Apr	Sun>=1	2:00s	0	-
+Rule	AV	2007	only	-	Mar	lastSun	2:00s	0	-
+Rule	AV	2008	max	-	Apr	Sun>=1	2:00s	0	-
+Rule	AV	2008	max	-	Oct	Sun>=1	2:00s	1:00	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Australia/Melbourne 9:39:52 -	LMT	1895 Feb
+			10:00	Aus	EST	1971
+			10:00	AV	EST
+
+# New South Wales
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	AN	1971	1985	-	Oct	lastSun	2:00s	1:00	-
+Rule	AN	1972	only	-	Feb	27	2:00s	0	-
+Rule	AN	1973	1981	-	Mar	Sun>=1	2:00s	0	-
+Rule	AN	1982	only	-	Apr	Sun>=1	2:00s	0	-
+Rule	AN	1983	1985	-	Mar	Sun>=1	2:00s	0	-
+Rule	AN	1986	1989	-	Mar	Sun>=15	2:00s	0	-
+Rule	AN	1986	only	-	Oct	19	2:00s	1:00	-
+Rule	AN	1987	1999	-	Oct	lastSun	2:00s	1:00	-
+Rule	AN	1990	1995	-	Mar	Sun>=1	2:00s	0	-
+Rule	AN	1996	2005	-	Mar	lastSun	2:00s	0	-
+Rule	AN	2000	only	-	Aug	lastSun	2:00s	1:00	-
+Rule	AN	2001	2007	-	Oct	lastSun	2:00s	1:00	-
+Rule	AN	2006	only	-	Apr	Sun>=1	2:00s	0	-
+Rule	AN	2007	only	-	Mar	lastSun	2:00s	0	-
+Rule	AN	2008	max	-	Apr	Sun>=1	2:00s	0	-
+Rule	AN	2008	max	-	Oct	Sun>=1	2:00s	1:00	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Australia/Sydney	10:04:52 -	LMT	1895 Feb
+			10:00	Aus	EST	1971
+			10:00	AN	EST
+Zone Australia/Broken_Hill 9:25:48 -	LMT	1895 Feb
+			10:00	-	EST	1896 Aug 23
+			9:00	-	CST	1899 May
+			9:30	Aus	CST	1971
+			9:30	AN	CST	2000
+			9:30	AS	CST
+
+# Lord Howe Island
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	LH	1981	1984	-	Oct	lastSun	2:00	1:00	-
+Rule	LH	1982	1985	-	Mar	Sun>=1	2:00	0	-
+Rule	LH	1985	only	-	Oct	lastSun	2:00	0:30	-
+Rule	LH	1986	1989	-	Mar	Sun>=15	2:00	0	-
+Rule	LH	1986	only	-	Oct	19	2:00	0:30	-
+Rule	LH	1987	1999	-	Oct	lastSun	2:00	0:30	-
+Rule	LH	1990	1995	-	Mar	Sun>=1	2:00	0	-
+Rule	LH	1996	2005	-	Mar	lastSun	2:00	0	-
+Rule	LH	2000	only	-	Aug	lastSun	2:00	0:30	-
+Rule	LH	2001	2007	-	Oct	lastSun	2:00	0:30	-
+Rule	LH	2006	only	-	Apr	Sun>=1	2:00	0	-
+Rule	LH	2007	only	-	Mar	lastSun	2:00	0	-
+Rule	LH	2008	max	-	Apr	Sun>=1	2:00	0	-
+Rule	LH	2008	max	-	Oct	Sun>=1	2:00	0:30	-
+Zone Australia/Lord_Howe 10:36:20 -	LMT	1895 Feb
+			10:00	-	EST	1981 Mar
+			10:30	LH	LHST
+
+# Australian miscellany
+#
+# Ashmore Is, Cartier
+# no indigenous inhabitants; only seasonal caretakers
+# no times are set
+#
+# Coral Sea Is
+# no indigenous inhabitants; only meteorologists
+# no times are set
+#
+# Macquarie
+# permanent occupation (scientific station) since 1948;
+# sealing and penguin oil station operated 1888/1917
+# like Australia/Hobart
+
+# Christmas
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Indian/Christmas	7:02:52 -	LMT	1895 Feb
+			7:00	-	CXT	# Christmas Island Time
+
+# Cook Is
+# From Shanks & Pottenger:
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Cook	1978	only	-	Nov	12	0:00	0:30	HS
+Rule	Cook	1979	1991	-	Mar	Sun>=1	0:00	0	-
+Rule	Cook	1979	1990	-	Oct	lastSun	0:00	0:30	HS
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Rarotonga	-10:39:04 -	LMT	1901		# Avarua
+			-10:30	-	CKT	1978 Nov 12	# Cook Is Time
+			-10:00	Cook	CK%sT
+
+# Cocos
+# These islands were ruled by the Ross family from about 1830 to 1978.
+# We don't know when standard time was introduced; for now, we guess 1900.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Indian/Cocos	6:27:40	-	LMT	1900
+			6:30	-	CCT	# Cocos Islands Time
+
+# Fiji
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Fiji	1998	1999	-	Nov	Sun>=1	2:00	1:00	S
+Rule	Fiji	1999	2000	-	Feb	lastSun	3:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Fiji	11:53:40 -	LMT	1915 Oct 26	# Suva
+			12:00	Fiji	FJ%sT	# Fiji Time
+
+# French Polynesia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Gambier	 -8:59:48 -	LMT	1912 Oct	# Rikitea
+			 -9:00	-	GAMT	# Gambier Time
+Zone	Pacific/Marquesas -9:18:00 -	LMT	1912 Oct
+			 -9:30	-	MART	# Marquesas Time
+Zone	Pacific/Tahiti	 -9:58:16 -	LMT	1912 Oct	# Papeete
+			-10:00	-	TAHT	# Tahiti Time
+# Clipperton (near North America) is administered from French Polynesia;
+# it is uninhabited.
+
+# Guam
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Guam	-14:21:00 -	LMT	1844 Dec 31
+			 9:39:00 -	LMT	1901		# Agana
+			10:00	-	GST	2000 Dec 23	# Guam
+			10:00	-	ChST	# Chamorro Standard Time
+
+# Kiribati
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Tarawa	 11:32:04 -	LMT	1901		# Bairiki
+			 12:00	-	GILT		 # Gilbert Is Time
+Zone Pacific/Enderbury	-11:24:20 -	LMT	1901
+			-12:00	-	PHOT	1979 Oct # Phoenix Is Time
+			-11:00	-	PHOT	1995
+			 13:00	-	PHOT
+Zone Pacific/Kiritimati	-10:29:20 -	LMT	1901
+			-10:40	-	LINT	1979 Oct # Line Is Time
+			-10:00	-	LINT	1995
+			 14:00	-	LINT
+
+# N Mariana Is
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Saipan	-14:17:00 -	LMT	1844 Dec 31
+			 9:43:00 -	LMT	1901
+			 9:00	-	MPT	1969 Oct # N Mariana Is Time
+			10:00	-	MPT	2000 Dec 23
+			10:00	-	ChST	# Chamorro Standard Time
+
+# Marshall Is
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Majuro	11:24:48 -	LMT	1901
+			11:00	-	MHT	1969 Oct # Marshall Islands Time
+			12:00	-	MHT
+Zone Pacific/Kwajalein	11:09:20 -	LMT	1901
+			11:00	-	MHT	1969 Oct
+			-12:00	-	KWAT	1993 Aug 20	# Kwajalein Time
+			12:00	-	MHT
+
+# Micronesia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Truk	10:07:08 -	LMT	1901
+			10:00	-	TRUT			# Truk Time
+Zone Pacific/Ponape	10:32:52 -	LMT	1901		# Kolonia
+			11:00	-	PONT			# Ponape Time
+Zone Pacific/Kosrae	10:51:56 -	LMT	1901
+			11:00	-	KOST	1969 Oct	# Kosrae Time
+			12:00	-	KOST	1999
+			11:00	-	KOST
+
+# Nauru
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Nauru	11:07:40 -	LMT	1921 Jan 15	# Uaobe
+			11:30	-	NRT	1942 Mar 15	# Nauru Time
+			9:00	-	JST	1944 Aug 15
+			11:30	-	NRT	1979 May
+			12:00	-	NRT
+
+# New Caledonia
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	NC	1977	1978	-	Dec	Sun>=1	0:00	1:00	S
+Rule	NC	1978	1979	-	Feb	27	0:00	0	-
+Rule	NC	1996	only	-	Dec	 1	2:00s	1:00	S
+# Shanks & Pottenger say the following was at 2:00; go with IATA.
+Rule	NC	1997	only	-	Mar	 2	2:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Noumea	11:05:48 -	LMT	1912 Jan 13
+			11:00	NC	NC%sT
+
+
+###############################################################################
+
+# New Zealand
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	NZ	1927	only	-	Nov	 6	2:00	1:00	S
+Rule	NZ	1928	only	-	Mar	 4	2:00	0	M
+Rule	NZ	1928	1933	-	Oct	Sun>=8	2:00	0:30	S
+Rule	NZ	1929	1933	-	Mar	Sun>=15	2:00	0	M
+Rule	NZ	1934	1940	-	Apr	lastSun	2:00	0	M
+Rule	NZ	1934	1940	-	Sep	lastSun	2:00	0:30	S
+Rule	NZ	1946	only	-	Jan	 1	0:00	0	S
+# Since 1957 Chatham has been 45 minutes ahead of NZ, but there's no
+# convenient notation for this so we must duplicate the Rule lines.
+Rule	NZ	1974	only	-	Nov	Sun>=1	2:00s	1:00	D
+Rule	Chatham	1974	only	-	Nov	Sun>=1	2:45s	1:00	D
+Rule	NZ	1975	only	-	Feb	lastSun	2:00s	0	S
+Rule	Chatham	1975	only	-	Feb	lastSun	2:45s	0	S
+Rule	NZ	1975	1988	-	Oct	lastSun	2:00s	1:00	D
+Rule	Chatham	1975	1988	-	Oct	lastSun	2:45s	1:00	D
+Rule	NZ	1976	1989	-	Mar	Sun>=1	2:00s	0	S
+Rule	Chatham	1976	1989	-	Mar	Sun>=1	2:45s	0	S
+Rule	NZ	1989	only	-	Oct	Sun>=8	2:00s	1:00	D
+Rule	Chatham	1989	only	-	Oct	Sun>=8	2:45s	1:00	D
+Rule	NZ	1990	2006	-	Oct	Sun>=1	2:00s	1:00	D
+Rule	Chatham	1990	2006	-	Oct	Sun>=1	2:45s	1:00	D
+Rule	NZ	1990	2007	-	Mar	Sun>=15	2:00s	0	S
+Rule	Chatham	1990	2007	-	Mar	Sun>=15	2:45s	0	S
+Rule	NZ	2007	max	-	Sep	lastSun	2:00s	1:00	D
+Rule	Chatham	2007	max	-	Sep	lastSun	2:45s	1:00	D
+Rule	NZ	2008	max	-	Apr	Sun>=1	2:00s	0	S
+Rule	Chatham	2008	max	-	Apr	Sun>=1	2:45s	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Auckland	11:39:04 -	LMT	1868 Nov  2
+			11:30	NZ	NZ%sT	1946 Jan  1
+			12:00	NZ	NZ%sT
+Zone Pacific/Chatham	12:13:48 -	LMT	1957 Jan  1
+			12:45	Chatham	CHA%sT
+
+
+# Auckland Is
+# uninhabited; Maori and Moriori, colonial settlers, pastoralists, sealers,
+# and scientific personnel have wintered
+
+# Campbell I
+# minor whaling stations operated 1909/1914
+# scientific station operated 1941/1995;
+# previously whalers, sealers, pastoralists, and scientific personnel wintered
+# was probably like Pacific/Auckland
+
+###############################################################################
+
+
+# Niue
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Niue	-11:19:40 -	LMT	1901		# Alofi
+			-11:20	-	NUT	1951	# Niue Time
+			-11:30	-	NUT	1978 Oct 1
+			-11:00	-	NUT
+
+# Norfolk
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Norfolk	11:11:52 -	LMT	1901		# Kingston
+			11:12	-	NMT	1951	# Norfolk Mean Time
+			11:30	-	NFT		# Norfolk Time
+
+# Palau (Belau)
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Palau	8:57:56 -	LMT	1901		# Koror
+			9:00	-	PWT	# Palau Time
+
+# Papua New Guinea
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Port_Moresby 9:48:40 -	LMT	1880
+			9:48:32	-	PMMT	1895	# Port Moresby Mean Time
+			10:00	-	PGT		# Papua New Guinea Time
+
+# Pitcairn
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Pitcairn	-8:40:20 -	LMT	1901		# Adamstown
+			-8:30	-	PNT	1998 Apr 27 00:00
+			-8:00	-	PST	# Pitcairn Standard Time
+
+# American Samoa
+Zone Pacific/Pago_Pago	 12:37:12 -	LMT	1879 Jul  5
+			-11:22:48 -	LMT	1911
+			-11:30	-	SAMT	1950		# Samoa Time
+			-11:00	-	NST	1967 Apr	# N=Nome
+			-11:00	-	BST	1983 Nov 30	# B=Bering
+			-11:00	-	SST			# S=Samoa
+
+# Samoa
+Zone Pacific/Apia	 12:33:04 -	LMT	1879 Jul  5
+			-11:26:56 -	LMT	1911
+			-11:30	-	SAMT	1950		# Samoa Time
+			-11:00	-	WST			# Samoa Time
+
+# Solomon Is
+# excludes Bougainville, for which see Papua New Guinea
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Guadalcanal 10:39:48 -	LMT	1912 Oct	# Honiara
+			11:00	-	SBT	# Solomon Is Time
+
+# Tokelau Is
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Fakaofo	-11:24:56 -	LMT	1901
+			-10:00	-	TKT	# Tokelau Time
+
+# Tonga
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Tonga	1999	only	-	Oct	 7	2:00s	1:00	S
+Rule	Tonga	2000	only	-	Mar	19	2:00s	0	-
+Rule	Tonga	2000	2001	-	Nov	Sun>=1	2:00	1:00	S
+Rule	Tonga	2001	2002	-	Jan	lastSun	2:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Tongatapu	12:19:20 -	LMT	1901
+			12:20	-	TOT	1941 # Tonga Time
+			13:00	-	TOT	1999
+			13:00	Tonga	TO%sT
+
+# Tuvalu
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Funafuti	11:56:52 -	LMT	1901
+			12:00	-	TVT	# Tuvalu Time
+
+
+# US minor outlying islands
+
+# Howland, Baker
+# Howland was mined for guano by American companies 1857-1878 and British
+# 1886-1891; Baker was similar but exact dates are not known.
+# Inhabited by civilians 1935-1942; U.S. military bases 1943-1944;
+# uninhabited thereafter.
+# Howland observed Hawaii Standard Time (UTC-10:30) in 1937;
+# see page 206 of Elgen M. Long and Marie K. Long,
+# Amelia Earhart: the Mystery Solved, Simon & Schuster (2000).
+# So most likely Howland and Baker observed Hawaii Time from 1935
+# until they were abandoned after the war.
+
+# Jarvis
+# Mined for guano by American companies 1857-1879 and British 1883?-1891?.
+# Inhabited by civilians 1935-1942; IGY scientific base 1957-1958;
+# uninhabited thereafter.
+# no information; was probably like Pacific/Kiritimati
+
+# Johnston
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Pacific/Johnston	-10:00	-	HST
+
+# Kingman
+# uninhabited
+
+# Midway
+#
+# From Mark Brader (2005-01-23):
+# [Fallacies and Fantasies of Air Transport History, by R.E.G. Davies,
+# published 1994 by Paladwr Press, McLean, VA, USA; ISBN 0-9626483-5-3]
+# reproduced a Pan American Airways timeables from 1936, for their weekly
+# "Orient Express" flights between San Francisco and Manila, and connecting
+# flights to Chicago and the US East Coast.  As it uses some time zone
+# designations that I've never seen before:....
+# Fri. 6:30A Lv. HONOLOLU (Pearl Harbor), H.I.   H.L.T. Ar. 5:30P Sun.
+#  "   3:00P Ar. MIDWAY ISLAND . . . . . . . . . M.L.T. Lv. 6:00A  "
+#
+Zone Pacific/Midway	-11:49:28 -	LMT	1901
+			-11:00	-	NST	1956 Jun  3
+			-11:00	1:00	NDT	1956 Sep  2
+			-11:00	-	NST	1967 Apr	# N=Nome
+			-11:00	-	BST	1983 Nov 30	# B=Bering
+			-11:00	-	SST			# S=Samoa
+
+# Palmyra
+# uninhabited since World War II; was probably like Pacific/Kiritimati
+
+# Wake
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Wake	11:06:28 -	LMT	1901
+			12:00	-	WAKT	# Wake Time
+
+
+# Vanuatu
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Vanuatu	1983	only	-	Sep	25	0:00	1:00	S
+Rule	Vanuatu	1984	1991	-	Mar	Sun>=23	0:00	0	-
+Rule	Vanuatu	1984	only	-	Oct	23	0:00	1:00	S
+Rule	Vanuatu	1985	1991	-	Sep	Sun>=23	0:00	1:00	S
+Rule	Vanuatu	1992	1993	-	Jan	Sun>=23	0:00	0	-
+Rule	Vanuatu	1992	only	-	Oct	Sun>=23	0:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Efate	11:13:16 -	LMT	1912 Jan 13		# Vila
+			11:00	Vanuatu	VU%sT	# Vanuatu Time
+
+# Wallis and Futuna
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Pacific/Wallis	12:15:20 -	LMT	1901
+			12:00	-	WFT	# Wallis & Futuna Time
+
+###############################################################################
+
+# NOTES
+
+# This data is by no means authoritative; if you think you know better,
+# go ahead and edit the file (and please send any changes to
+# tz@elsie.nci.nih.gov for general use in the future).
+
+# From Paul Eggert (2006-03-22):
+# A good source for time zone historical data outside the U.S. is
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
+# San Diego: ACS Publications, Inc. (2003).
+#
+# Gwillim Law writes that a good source
+# for recent time zone data is the International Air Transport
+# Association's Standard Schedules Information Manual (IATA SSIM),
+# published semiannually.  Law sent in several helpful summaries
+# of the IATA's data after 1990.
+#
+# Except where otherwise noted, Shanks & Pottenger is the source for
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
+#
+# Another source occasionally used is Edward W. Whitman, World Time Differences,
+# Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which
+# I found in the UCLA library.
+#
+# A reliable and entertaining source about time zones is
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
+#
+# I invented the abbreviations marked `*' in the following table;
+# the rest are from earlier versions of this file, or from other sources.
+# Corrections are welcome!
+#		std dst
+#		LMT	Local Mean Time
+#	  8:00	WST WST	Western Australia
+#	  8:45	CWST CWST Central Western Australia*
+#	  9:00	JST	Japan
+#	  9:30	CST CST	Central Australia
+#	 10:00	EST EST	Eastern Australia
+#	 10:00	ChST	Chamorro
+#	 10:30	LHST LHST Lord Howe*
+#	 11:30	NZMT NZST New Zealand through 1945
+#	 12:00	NZST NZDT New Zealand 1946-present
+#	 12:45	CHAST CHADT Chatham*
+#	-11:00	SST	Samoa
+#	-10:00	HST	Hawaii
+#	- 8:00	PST	Pitcairn*
+#
+# See the `northamerica' file for Hawaii.
+# See the `southamerica' file for Easter I and the Galapagos Is.
+
+###############################################################################
+
+# Australia
+
+# From Paul Eggert (2005-12-08):
+# <a href="http://www.bom.gov.au/climate/averages/tables/dst_times.shtml">
+# Implementation Dates of Daylight Saving Time within Australia
+# </a> summarizes daylight saving issues in Australia.
+
+# From Arthur David Olson (2005-12-12):
+# <a href="http://www.lawlink.nsw.gov.au/lawlink/Corporate/ll_agdinfo.nsf/pages/community_relations_daylight_saving">
+# Lawlink NSW:Daylight Saving in New South Wales
+# </a> covers New South Wales in particular.
+
+# From John Mackin (1991-03-06):
+# We in Australia have _never_ referred to DST as `daylight' time.
+# It is called `summer' time.  Now by a happy coincidence, `summer'
+# and `standard' happen to start with the same letter; hence, the
+# abbreviation does _not_ change...
+# The legislation does not actually define abbreviations, at least
+# in this State, but the abbreviation is just commonly taken to be the
+# initials of the phrase, and the legislation here uniformly uses
+# the phrase `summer time' and does not use the phrase `daylight
+# time'.
+# Announcers on the Commonwealth radio network, the ABC (for Australian
+# Broadcasting Commission), use the phrases `Eastern Standard Time'
+# or `Eastern Summer Time'.  (Note, though, that as I say in the
+# current australasia file, there is really no such thing.)  Announcers
+# on its overseas service, Radio Australia, use the same phrases
+# prefixed by the word `Australian' when referring to local times;
+# time announcements on that service, naturally enough, are made in UTC.
+
+# From Arthur David Olson (1992-03-08):
+# Given the above, what's chosen for year-round use is:
+#	CST	for any place operating at a GMTOFF of 9:30
+#	WST	for any place operating at a GMTOFF of 8:00
+#	EST	for any place operating at a GMTOFF of 10:00
+
+# From Chuck Soper (2006-06-01):
+# I recently found this Australian government web page on time zones:
+# <http://www.australia.gov.au/about-australia-13time>
+# And this government web page lists time zone names and abbreviations:
+# <http://www.bom.gov.au/climate/averages/tables/daysavtm.shtml>
+
+# From Paul Eggert (2001-04-05), summarizing a long discussion about "EST"
+# versus "AEST" etc.:
+#
+# I see the following points of dispute:
+#
+# * How important are unique time zone abbreviations?
+#
+#   Here I tend to agree with the point (most recently made by Chris
+#   Newman) that unique abbreviations should not be essential for proper
+#   operation of software.  We have other instances of ambiguity
+#   (e.g. "IST" denoting both "Israel Standard Time" and "Indian
+#   Standard Time"), and they are not likely to go away any time soon.
+#   In the old days, some software mistakenly relied on unique
+#   abbreviations, but this is becoming less true with time, and I don't
+#   think it's that important to cater to such software these days.
+#
+#   On the other hand, there is another motivation for unambiguous
+#   abbreviations: it cuts down on human confusion.  This is
+#   particularly true for Australia, where "EST" can mean one thing for
+#   time T and a different thing for time T plus 1 second.
+#
+# * Does the relevant legislation indicate which abbreviations should be used?
+#
+#   Here I tend to think that things are a mess, just as they are in
+#   many other countries.  We Americans are currently disagreeing about
+#   which abbreviation to use for the newly legislated Chamorro Standard
+#   Time, for example.
+#
+#   Personally, I would prefer to use common practice; I would like to
+#   refer to legislation only for examples of common practice, or as a
+#   tiebreaker.
+#
+# * Do Australians more often use "Eastern Daylight Time" or "Eastern
+#   Summer Time"?  Do they typically prefix the time zone names with
+#   the word "Australian"?
+#
+#   My own impression is that both "Daylight Time" and "Summer Time" are
+#   common and are widely understood, but that "Summer Time" is more
+#   popular; and that the leading "A" is also common but is omitted more
+#   often than not.  I just used AltaVista advanced search and got the
+#   following count of page hits:
+#
+#     1,103 "Eastern Summer Time" AND domain:au
+#       971 "Australian Eastern Summer Time" AND domain:au
+#       613 "Eastern Daylight Time" AND domain:au
+#       127 "Australian Eastern Daylight Time" AND domain:au
+#
+#   Here "Summer" seems quite a bit more popular than "Daylight",
+#   particularly when we know the time zone is Australian and not US,
+#   say.  The "Australian" prefix seems to be popular for Eastern Summer
+#   Time, but unpopular for Eastern Daylight Time.
+#
+#   For abbreviations, tools like AltaVista are less useful because of
+#   ambiguity.  Many hits are not really time zones, unfortunately, and
+#   many hits denote US time zones and not Australian ones.  But here
+#   are the hit counts anyway:
+#
+#     161,304 "EST" and domain:au
+#      25,156 "EDT" and domain:au
+#      18,263 "AEST" and domain:au
+#      10,416 "AEDT" and domain:au
+#
+#      14,538 "CST" and domain:au
+#       5,728 "CDT" and domain:au
+#         176 "ACST" and domain:au
+#          29 "ACDT" and domain:au
+#
+#       7,539 "WST" and domain:au
+#          68 "AWST" and domain:au
+#
+#   This data suggest that Australians tend to omit the "A" prefix in
+#   practice.  The situation for "ST" versus "DT" is less clear, given
+#   the ambiguities involved.
+#
+# * How do Australians feel about the abbreviations in the tz database?
+#
+#   If you just count Australians on this list, I count 2 in favor and 3
+#   against.  One of the "against" votes (David Keegel) counseled delay,
+#   saying that both AEST/AEDT and EST/EST are widely used and
+#   understood in Australia.
+
+# From Paul Eggert (1995-12-19):
+# Shanks & Pottenger report 2:00 for all autumn changes in Australia and NZ.
+# Mark Prior writes that his newspaper
+# reports that NSW's fall 1995 change will occur at 2:00,
+# but Robert Elz says it's been 3:00 in Victoria since 1970
+# and perhaps the newspaper's `2:00' is referring to standard time.
+# For now we'll continue to assume 2:00s for changes since 1960.
+
+# From Eric Ulevik (1998-01-05):
+#
+# Here are some URLs to Australian time legislation. These URLs are stable,
+# and should probably be included in the data file. There are probably more
+# relevant entries in this database.
+#
+# NSW (including LHI and Broken Hill):
+# <a href="http://www.austlii.edu.au/au/legis/nsw/consol_act/sta1987137/index.html">
+# Standard Time Act 1987 (updated 1995-04-04)
+# </a>
+# ACT
+# <a href="http://www.austlii.edu.au/au/legis/act/consol_act/stasta1972279/index.html">
+# Standard Time and Summer Time Act 1972
+# </a>
+# SA
+# <a href="http://www.austlii.edu.au/au/legis/sa/consol_act/sta1898137/index.html">
+# Standard Time Act, 1898
+# </a>
+
+# From David Grosz (2005-06-13):
+# It was announced last week that Daylight Saving would be extended by
+# one week next year to allow for the 2006 Commonwealth Games.
+# Daylight Saving is now to end for next year only on the first Sunday
+# in April instead of the last Sunday in March.
+#
+# From Gwillim Law (2005-06-14):
+# I did some Googling and found that all of those states (and territory) plan
+# to extend DST together in 2006.
+# ACT: http://www.cmd.act.gov.au/mediareleases/fileread.cfm?file=86.txt
+# New South Wales: http://www.thecouriermail.news.com.au/common/story_page/0,5936,15538869%255E1702,00.html
+# South Australia: http://www.news.com.au/story/0,10117,15555031-1246,00.html
+# Tasmania: http://www.media.tas.gov.au/release.php?id=14772
+# Victoria: I wasn't able to find anything separate, but the other articles
+# allude to it.
+# But not Queensland
+# http://www.news.com.au/story/0,10117,15564030-1248,00.html.
+
+# Northern Territory
+
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# # The NORTHERN TERRITORY..  [ Courtesy N.T. Dept of the Chief Minister ]
+# #					[ Nov 1990 ]
+# #	N.T. have never utilised any DST due to sub-tropical/tropical location.
+# ...
+# Zone        Australia/North         9:30    -       CST
+
+# From Bradley White (1991-03-04):
+# A recent excerpt from an Australian newspaper...
+# the Northern Territory do[es] not have daylight saving.
+
+# Western Australia
+
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# #  The state of WESTERN AUSTRALIA..  [ Courtesy W.A. dept Premier+Cabinet ]
+# #						[ Nov 1990 ]
+# #	W.A. suffers from a great deal of public and political opposition to
+# #	DST in principle. A bill is brought before parliament in most years, but
+# #	usually defeated either in the upper house, or in party caucus
+# #	before reaching parliament.
+# ...
+# Zone	Australia/West		8:00	AW	%sST
+# ...
+# Rule	AW	1974	only	-	Oct	lastSun	2:00	1:00	D
+# Rule	AW	1975	only	-	Mar	Sun>=1	3:00	0	W
+# Rule	AW	1983	only	-	Oct	lastSun	2:00	1:00	D
+# Rule	AW	1984	only	-	Mar	Sun>=1	3:00	0	W
+
+# From Bradley White (1991-03-04):
+# A recent excerpt from an Australian newspaper...
+# Western Australia...do[es] not have daylight saving.
+
+# From John D. Newman via Bradley White (1991-11-02):
+# Western Australia is still on "winter time". Some DH in Sydney
+# rang me at home a few days ago at 6.00am. (He had just arrived at
+# work at 9.00am.)
+# W.A. is switching to Summer Time on Nov 17th just to confuse
+# everybody again.
+
+# From Arthur David Olson (1992-03-08):
+# The 1992 ending date used in the rules is a best guess;
+# it matches what was used in the past.
+
+# <a href="http://www.bom.gov.au/faq/faqgen.htm">
+# The Australian Bureau of Meteorology FAQ
+# </a> (1999-09-27) writes that Giles Meteorological Station uses
+# South Australian time even though it's located in Western Australia.
+
+# Queensland
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# #   The state of QUEENSLAND.. [ Courtesy Qld. Dept Premier Econ&Trade Devel ]
+# #						[ Dec 1990 ]
+# ...
+# Zone	Australia/Queensland	10:00	AQ	%sST
+# ...
+# Rule	AQ	1971	only	-	Oct	lastSun	2:00	1:00	D
+# Rule	AQ	1972	only	-	Feb	lastSun	3:00	0	E
+# Rule	AQ	1989	max	-	Oct	lastSun	2:00	1:00	D
+# Rule	AQ	1990	max	-	Mar	Sun>=1	3:00	0	E
+
+# From Bradley White (1989-12-24):
+# "Australia/Queensland" now observes daylight time (i.e. from
+# October 1989).
+
+# From Bradley White (1991-03-04):
+# A recent excerpt from an Australian newspaper...
+# ...Queensland...[has] agreed to end daylight saving
+# at 3am tomorrow (March 3)...
+
+# From John Mackin (1991-03-06):
+# I can certainly confirm for my part that Daylight Saving in NSW did in fact
+# end on Sunday, 3 March.  I don't know at what hour, though.  (It surprised
+# me.)
+
+# From Bradley White (1992-03-08):
+# ...there was recently a referendum in Queensland which resulted
+# in the experimental daylight saving system being abandoned. So, ...
+# ...
+# Rule	QLD	1989	1991	-	Oct	lastSun	2:00	1:00	D
+# Rule	QLD	1990	1992	-	Mar	Sun>=1	3:00	0	S
+# ...
+
+# From Arthur David Olson (1992-03-08):
+# The chosen rules the union of the 1971/1972 change and the 1989-1992 changes.
+
+# From Christopher Hunt (2006-11-21), after an advance warning
+# from Jesper Norgaard Welen (2006-11-01):
+# WA are trialing DST for three years.
+# <http://www.parliament.wa.gov.au/parliament/bills.nsf/9A1B183144403DA54825721200088DF1/$File/Bill175-1B.pdf>
+
+# From Rives McDow (2002-04-09):
+# The most interesting region I have found consists of three towns on the
+# southern coast....  South Australia observes daylight saving time; Western
+# Australia does not.  The two states are one and a half hours apart.  The
+# residents decided to forget about this nonsense of changing the clock so
+# much and set the local time 20 hours and 45 minutes from the
+# international date line, or right in the middle of the time of South
+# Australia and Western Australia....
+#
+# From Paul Eggert (2002-04-09):
+# This is confirmed by the section entitled
+# "What's the deal with time zones???" in
+# <http://www.earthsci.unimelb.edu.au/~awatkins/null.html>.
+#
+# From Alex Livingston (2006-12-07):
+# ... it was just on four years ago that I drove along the Eyre Highway,
+# which passes through eastern Western Australia close to the southern
+# coast of the continent.
+#
+# I paid particular attention to the time kept there. There can be no
+# dispute that UTC+08:45 was considered "the time" from the border
+# village just inside the border with South Australia to as far west
+# as just east of Caiguna. There can also be no dispute that Eucla is
+# the largest population centre in this zone....
+#
+# Now that Western Australia is observing daylight saving, the
+# question arose whether this part of the state would follow suit. I
+# just called the border village and confirmed that indeed they have,
+# meaning that they are now observing UTC+09:45.
+#
+# (2006-12-09):
+# I personally doubt that either experimentation with daylight saving
+# in WA or its introduction in SA had anything to do with the genesis
+# of this time zone.  My hunch is that it's been around since well
+# before 1975.  I remember seeing it noted on road maps decades ago.
+
+# From Paul Eggert (2006-12-15):
+# For lack of better info, assume the tradition dates back to the
+# introduction of standard time in 1895.
+
+
+# southeast Australia
+#
+# From Paul Eggert (2007-07-23):
+# Starting autumn 2008 Victoria, NSW, South Australia, Tasmania and the ACT
+# end DST the first Sunday in April and start DST the first Sunday in October.
+# http://www.theage.com.au/news/national/daylight-savings-to-span-six-months/2007/06/27/1182623966703.html
+
+
+# South Australia
+
+# From Bradley White (1991-03-04):
+# A recent excerpt from an Australian newspaper...
+# ...South Australia...[has] agreed to end daylight saving
+# at 3am tomorrow (March 3)...
+
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# #   The state of SOUTH AUSTRALIA....[ Courtesy of S.A. Dept of Labour ]
+# #						[ Nov 1990 ]
+# ...
+# Zone	Australia/South		9:30	AS	%sST
+# ...
+# Rule	 AS	1971	max	-	Oct	lastSun	2:00	1:00	D
+# Rule	 AS	1972	1985	-	Mar	Sun>=1	3:00	0	C
+# Rule	 AS	1986	1990	-	Mar	Sun>=15	3:00	0	C
+# Rule	 AS	1991	max	-	Mar	Sun>=1	3:00	0	C
+
+# From Bradley White (1992-03-11):
+# Recent correspondence with a friend in Adelaide
+# contained the following exchange:  "Due to the Adelaide Festival,
+# South Australia delays setting back our clocks for a few weeks."
+
+# From Robert Elz (1992-03-13):
+# I heard that apparently (or at least, it appears that)
+# South Aus will have an extra 3 weeks daylight saving every even
+# numbered year (from 1990).  That's when the Adelaide Festival
+# is on...
+
+# From Robert Elz (1992-03-16, 00:57:07 +1000):
+# DST didn't end in Adelaide today (yesterday)....
+# But whether it's "4th Sunday" or "2nd last Sunday" I have no idea whatever...
+# (it's just as likely to be "the Sunday we pick for this year"...).
+
+# From Bradley White (1994-04-11):
+# If Sun, 15 March, 1992 was at +1030 as kre asserts, but yet Sun, 20 March,
+# 1994 was at +0930 as John Connolly's customer seems to assert, then I can
+# only conclude that the actual rule is more complicated....
+
+# From John Warburton (1994-10-07):
+# The new Daylight Savings dates for South Australia ...
+# was gazetted in the Government Hansard on Sep 26 1994....
+# start on last Sunday in October and end in last sunday in March.
+
+# From Paul Eggert (2007-07-23):
+# See "southeast Australia" above for 2008 and later.
+
+# Tasmania
+
+# The rules for 1967 through 1991 were reported by George Shepherd
+# via Simon Woodhead via Robert Elz (1991-03-06):
+# #  The state of TASMANIA.. [Courtesy Tasmanian Dept of Premier + Cabinet ]
+# #					[ Nov 1990 ]
+
+# From Bill Hart via Guy Harris (1991-10-10):
+# Oh yes, the new daylight savings rules are uniquely tasmanian, we have
+# 6 weeks a year now when we are out of sync with the rest of Australia
+# (but nothing new about that).
+
+# From Alex Livingston (1999-10-04):
+# I heard on the ABC (Australian Broadcasting Corporation) radio news on the
+# (long) weekend that Tasmania, which usually goes its own way in this regard,
+# has decided to join with most of NSW, the ACT, and most of Victoria
+# (Australia) and start daylight saving on the last Sunday in August in 2000
+# instead of the first Sunday in October.
+
+# Sim Alam (2000-07-03) reported a legal citation for the 2000/2001 rules:
+# http://www.thelaw.tas.gov.au/fragview/42++1968+GS3A@EN+2000070300
+
+# From Paul Eggert (2007-07-23):
+# See "southeast Australia" above for 2008 and later.
+
+# Victoria
+
+# The rules for 1971 through 1991 were reported by George Shepherd
+# via Simon Woodhead via Robert Elz (1991-03-06):
+# #   The state of VICTORIA.. [ Courtesy of Vic. Dept of Premier + Cabinet ]
+# #						[ Nov 1990 ]
+
+# From Scott Harrington (2001-08-29):
+# On KQED's "City Arts and Lectures" program last night I heard an
+# interesting story about daylight savings time.  Dr. John Heilbron was
+# discussing his book "The Sun in the Church: Cathedrals as Solar
+# Observatories"[1], and in particular the Shrine of Remembrance[2] located
+# in Melbourne, Australia.
+#
+# Apparently the shrine's main purpose is a beam of sunlight which
+# illuminates a special spot on the floor at the 11th hour of the 11th day
+# of the 11th month (Remembrance Day) every year in memory of Australia's
+# fallen WWI soldiers.  And if you go there on Nov. 11, at 11am local time,
+# you will indeed see the sunbeam illuminate the special spot at the
+# expected time.
+#
+# However, that is only because of some special mirror contraption that had
+# to be employed, since due to daylight savings time, the true solar time of
+# the remembrance moment occurs one hour later (or earlier?).  Perhaps
+# someone with more information on this jury-rig can tell us more.
+#
+# [1] http://www.hup.harvard.edu/catalog/HEISUN.html
+# [2] http://www.shrine.org.au
+
+# From Paul Eggert (2007-07-23):
+# See "southeast Australia" above for 2008 and later.
+
+# New South Wales
+
+# From Arthur David Olson:
+# New South Wales and subjurisdictions have their own ideas of a fun time.
+# Based on law library research by John Mackin,
+# who notes:
+#	In Australia, time is not legislated federally, but rather by the
+#	individual states.  Thus, while such terms as ``Eastern Standard Time''
+#	[I mean, of course, Australian EST, not any other kind] are in common
+#	use, _they have NO REAL MEANING_, as they are not defined in the
+#	legislation.  This is very important to understand.
+#	I have researched New South Wales time only...
+
+# From Eric Ulevik (1999-05-26):
+# DST will start in NSW on the last Sunday of August, rather than the usual
+# October in 2000.  [See: Matthew Moore,
+# <a href="http://www.smh.com.au/news/9905/26/pageone/pageone4.html">
+# Two months more daylight saving
+# </a>
+# Sydney Morning Herald (1999-05-26).]
+
+# From Paul Eggert (1999-09-27):
+# See the following official NSW source:
+# <a href="http://dir.gis.nsw.gov.au/cgi-bin/genobject/document/other/daylightsaving/tigGmZ">
+# Daylight Saving in New South Wales.
+# </a>
+#
+# Narrabri Shire (NSW) council has announced it will ignore the extension of
+# daylight saving next year.  See:
+# <a href="http://abc.net.au/news/regionals/neweng/monthly/regeng-22jul1999-1.htm">
+# Narrabri Council to ignore daylight saving
+# </a> (1999-07-22).  For now, we'll wait to see if this really happens.
+#
+# Victoria will following NSW.  See:
+# <a href="http://abc.net.au/local/news/olympics/1999/07/item19990728112314_1.htm">
+# Vic to extend daylight saving
+# </a> (1999-07-28).
+#
+# However, South Australia rejected the DST request.  See:
+# <a href="http://abc.net.au/news/olympics/1999/07/item19990719151754_1.htm">
+# South Australia rejects Olympics daylight savings request
+# </a> (1999-07-19).
+#
+# Queensland also will not observe DST for the Olympics.  See:
+# <a href="http://abc.net.au/news/olympics/1999/06/item19990601114608_1.htm">
+# Qld says no to daylight savings for Olympics
+# </a> (1999-06-01), which quotes Queensland Premier Peter Beattie as saying
+# ``Look you've got to remember in my family when this came up last time
+# I voted for it, my wife voted against it and she said to me it's all very
+# well for you, you don't have to worry about getting the children out of
+# bed, getting them to school, getting them to sleep at night.
+# I've been through all this argument domestically...my wife rules.''
+#
+# Broken Hill will stick with South Australian time in 2000.  See:
+# <a href="http://abc.net.au/news/regionals/brokenh/monthly/regbrok-21jul1999-6.htm">
+# Broken Hill to be behind the times
+# </a> (1999-07-21).
+
+# IATA SSIM (1998-09) says that the spring 2000 change for Australian
+# Capital Territory, New South Wales except Lord Howe Island and Broken
+# Hill, and Victoria will be August 27, presumably due to the Sydney Olympics.
+
+# From Eric Ulevik, referring to Sydney's Sun Herald (2000-08-13), page 29:
+# The Queensland Premier Peter Beattie is encouraging northern NSW
+# towns to use Queensland time.
+
+# From Paul Eggert (2007-07-23):
+# See "southeast Australia" above for 2008 and later.
+
+# Yancowinna
+
+# From John Mackin (1989-01-04):
+# `Broken Hill' means the County of Yancowinna.
+
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# # YANCOWINNA..  [ Confirmation courtesy of Broken Hill Postmaster ]
+# #					[ Dec 1990 ]
+# ...
+# # Yancowinna uses Central Standard Time, despite [its] location on the
+# # New South Wales side of the S.A. border. Most business and social dealings
+# # are with CST zones, therefore CST is legislated by local government
+# # although the switch to Summer Time occurs in line with N.S.W. There have
+# # been years when this did not apply, but the historical data is not
+# # presently available.
+# Zone	Australia/Yancowinna	9:30	 AY	%sST
+# ...
+# Rule	 AY	1971	1985	-	Oct	lastSun	2:00	1:00	D
+# Rule	 AY	1972	only	-	Feb	lastSun	3:00	0	C
+# [followed by other Rules]
+
+# Lord Howe Island
+
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# LHI...		[ Courtesy of Pauline Van Winsen ]
+#					[ Dec 1990 ]
+# Lord Howe Island is located off the New South Wales coast, and is half an
+# hour ahead of NSW time.
+
+# From James Lonergan, Secretary, Lord Howe Island Board (2000-01-27):
+# Lord Howe Island summer time in 2000/2001 will commence on the same
+# date as the rest of NSW (i.e. 2000-08-27).  For your information the
+# Lord Howe Island Board (controlling authority for the Island) is
+# seeking the community's views on various options for summer time
+# arrangements on the Island, e.g. advance clocks by 1 full hour
+# instead of only 30 minutes.  Dependant on the wishes of residents
+# the Board may approach the NSW government to change the existing
+# arrangements.  The starting date for summer time on the Island will
+# however always coincide with the rest of NSW.
+
+# From James Lonergan, Secretary, Lord Howe Island Board (2000-10-25):
+# Lord Howe Island advances clocks by 30 minutes during DST in NSW and retards
+# clocks by 30 minutes when DST finishes. Since DST was most recently
+# introduced in NSW, the "changeover" time on the Island has been 02:00 as
+# shown on clocks on LHI. I guess this means that for 30 minutes at the start
+# of DST, LHI is actually 1 hour ahead of the rest of NSW.
+
+# From Paul Eggert (2006-03-22):
+# For Lord Howe dates we use Shanks & Pottenger through 1989, and
+# Lonergan thereafter.  For times we use Lonergan.
+
+# From Paul Eggert (2007-07-23):
+# See "southeast Australia" above for 2008 and later.
+
+###############################################################################
+
+# New Zealand
+
+# From Mark Davies (1990-10-03):
+# the 1989/90 year was a trial of an extended "daylight saving" period.
+# This trial was deemed successful and the extended period adopted for
+# subsequent years (with the addition of a further week at the start).
+# source -- phone call to Ministry of Internal Affairs Head Office.
+
+# From George Shepherd via Simon Woodhead via Robert Elz (1991-03-06):
+# # The Country of New Zealand   (Australia's east island -) Gee they hate that!
+# #				   or is Australia the west island of N.Z.
+# #	[ courtesy of Geoff Tribble.. Auckland N.Z. ]
+# #				[ Nov 1990 ]
+# ...
+# Rule	NZ      1974    1988	-	Oct	lastSun	2:00	1:00	D
+# Rule	NZ	1989	max	-	Oct	Sun>=1	2:00	1:00	D
+# Rule	NZ      1975    1989	-	Mar	Sun>=1	3:00	0	S
+# Rule	NZ	1990	max	-	Mar	lastSun	3:00	0	S
+# ...
+# Zone	NZ			12:00	NZ		NZ%sT	# New Zealand
+# Zone	NZ-CHAT			12:45	-		NZ-CHAT # Chatham Island
+
+# From Arthur David Olson (1992-03-08):
+# The chosen rules use the Davies October 8 values for the start of DST in 1989
+# rather than the October 1 value.
+
+# From Paul Eggert (1995-12-19);
+# Shank & Pottenger report 2:00 for all autumn changes in Australia and NZ.
+# Robert Uzgalis writes that the New Zealand Daylight
+# Savings Time Order in Council dated 1990-06-18 specifies 2:00 standard
+# time on both the first Sunday in October and the third Sunday in March.
+# As with Australia, we'll assume the tradition is 2:00s, not 2:00.
+#
+# From Paul Eggert (2006-03-22):
+# The Department of Internal Affairs (DIA) maintains a brief history,
+# as does Carol Squires; see tz-link.htm for the full references.
+# Use these sources in preference to Shanks & Pottenger.
+#
+# For Chatham, IATA SSIM (1991/1999) gives the NZ rules but with
+# transitions at 2:45 local standard time; this confirms that Chatham
+# is always exactly 45 minutes ahead of Auckland.
+
+# From Colin Sharples (2007-04-30):
+# DST will now start on the last Sunday in September, and end on the
+# first Sunday in April.  The changes take effect this year, meaning
+# that DST will begin on 2007-09-30 2008-04-06.
+# http://www.dia.govt.nz/diawebsite.nsf/wpg_URL/Services-Daylight-Saving-Daylight-saving-to-be-extended
+
+###############################################################################
+
+
+# Fiji
+
+# Howse writes (p 153) that in 1879 the British governor of Fiji
+# enacted an ordinance standardizing the islands on Antipodean Time
+# instead of the American system (which was one day behind).
+
+# From Rives McDow (1998-10-08):
+# Fiji will introduce DST effective 0200 local time, 1998-11-01
+# until 0300 local time 1999-02-28.  Each year the DST period will
+# be from the first Sunday in November until the last Sunday in February.
+
+# From Paul Eggert (2000-01-08):
+# IATA SSIM (1999-09) says DST ends 0100 local time.  Go with McDow.
+
+# From the BBC World Service (1998-10-31 11:32 UTC):
+# The Fijiian government says the main reasons for the time change is to
+# improve productivity and reduce road accidents.  But correspondents say it
+# also hopes the move will boost Fiji's ability to compete with other pacific
+# islands in the effort to attract tourists to witness the dawning of the new
+# millenium.
+
+# http://www.fiji.gov.fj/press/2000_09/2000_09_13-05.shtml (2000-09-13)
+# reports that Fiji has discontinued DST.
+
+# Johnston
+
+# Johnston data is from usno1995.
+
+
+# Kiribati
+
+# From Paul Eggert (1996-01-22):
+# Today's _Wall Street Journal_ (page 1) reports that Kiribati
+# ``declared it the same day throught the country as of Jan. 1, 1995''
+# as part of the competition to be first into the 21st century.
+
+
+# Kwajalein
+
+# In comp.risks 14.87 (26 August 1993), Peter Neumann writes:
+# I wonder what happened in Kwajalein, where there was NO Friday,
+# 1993-08-20.  Thursday night at midnight Kwajalein switched sides with
+# respect to the International Date Line, to rejoin its fellow islands,
+# going from 11:59 p.m. Thursday to 12:00 m. Saturday in a blink.
+
+
+# N Mariana Is, Guam
+
+# Howse writes (p 153) ``The Spaniards, on the other hand, reached the
+# Philippines and the Ladrones from America,'' and implies that the Ladrones
+# (now called the Marianas) kept American date for quite some time.
+# For now, we assume the Ladrones switched at the same time as the Philippines;
+# see Asia/Manila.
+
+# US Public Law 106-564 (2000-12-23) made UTC+10 the official standard time,
+# under the name "Chamorro Standard Time".  There is no official abbreviation,
+# but Congressman Robert A. Underwood, author of the bill that became law,
+# wrote in a press release (2000-12-27) that he will seek the use of "ChST".
+
+
+# Micronesia
+
+# Alan Eugene Davis writes (1996-03-16),
+# ``I am certain, having lived there for the past decade, that "Truk"
+# (now properly known as Chuuk) ... is in the time zone GMT+10.''
+#
+# Shanks & Pottenger write that Truk switched from UTC+10 to UTC+11
+# on 1978-10-01; ignore this for now.
+
+# From Paul Eggert (1999-10-29):
+# The Federated States of Micronesia Visitors Board writes in
+# <a href="http://www.fsmgov.org/info/clocks.html">
+# The Federated States of Micronesia - Visitor Information
+# </a> (1999-01-26)
+# that Truk and Yap are UTC+10, and Ponape and Kosrae are UTC+11.
+# We don't know when Kosrae switched from UTC+12; assume January 1 for now.
+
+
+# Midway
+
+# From Charles T O'Connor, KMTH DJ (1956),
+# quoted in the KTMH section of the Radio Heritage Collection
+# <http://radiodx.com/spdxr/KMTH.htm> (2002-12-31):
+# For the past two months we've been on what is known as Daylight
+# Saving Time.  This time has put us on air at 5am in the morning,
+# your time down there in New Zealand.  Starting September 2, 1956
+# we'll again go back to Standard Time.  This'll mean that we'll go to
+# air at 6am your time.
+#
+# From Paul Eggert (2003-03-23):
+# We don't know the date of that quote, but we'll guess they
+# started DST on June 3.  Possibly DST was observed other years
+# in Midway, but we have no record of it.
+
+
+# Pitcairn
+
+# From Rives McDow (1999-11-08):
+# A Proclamation was signed by the Governor of Pitcairn on the 27th March 1998
+# with regard to Pitcairn Standard Time.  The Proclamation is as follows.
+#
+#	The local time for general purposes in the Islands shall be
+#	Co-ordinated Universal time minus 8 hours and shall be known
+#	as Pitcairn Standard Time.
+#
+# ... I have also seen Pitcairn listed as UTC minus 9 hours in several
+# references, and can only assume that this was an error in interpretation
+# somehow in light of this proclamation.
+
+# From Rives McDow (1999-11-09):
+# The Proclamation regarding Pitcairn time came into effect on 27 April 1998
+# ... at midnight.
+
+# From Howie Phelps (1999-11-10), who talked to a Pitcairner via shortwave:
+# Betty Christian told me yesterday that their local time is the same as
+# Pacific Standard Time. They used to be 1/2 hour different from us here in
+# Sacramento but it was changed a couple of years ago.
+
+
+# Samoa
+
+# Howse writes (p 153, citing p 10 of the 1883-11-18 New York Herald)
+# that in 1879 the King of Samoa decided to change
+# ``the date in his kingdom from the Antipodean to the American system,
+# ordaining -- by a masterpiece of diplomatic flattery -- that
+# the Fourth of July should be celebrated twice in that year.''
+
+
+# Tonga
+
+# From Paul Eggert (1996-01-22):
+# Today's _Wall Street Journal_ (p 1) reports that ``Tonga has been plotting
+# to sneak ahead of [New Zealanders] by introducing daylight-saving time.''
+# Since Kiribati has moved the Date Line it's not clear what Tonga will do.
+
+# Don Mundell writes in the 1997-02-20 Tonga Chronicle
+# <a href="http://www.tongatapu.net.to/tonga/homeland/timebegins.htm">
+# How Tonga became `The Land where Time Begins'
+# </a>:
+
+# Until 1941 Tonga maintained a standard time 50 minutes ahead of NZST
+# 12 hours and 20 minutes ahead of GMT.  When New Zealand adjusted its
+# standard time in 1940s, Tonga had the choice of subtracting from its
+# local time to come on the same standard time as New Zealand or of
+# advancing its time to maintain the differential of 13 degrees
+# (approximately 50 minutes ahead of New Zealand time).
+#
+# Because His Majesty King Taufa'ahau Tupou IV, then Crown Prince
+# Tungi, preferred to ensure Tonga's title as the land where time
+# begins, the Legislative Assembly approved the latter change.
+#
+# But some of the older, more conservative members from the outer
+# islands objected. "If at midnight on Dec. 31, we move ahead 40
+# minutes, as your Royal Highness wishes, what becomes of the 40
+# minutes we have lost?"
+#
+# The Crown Prince, presented an unanswerable argument: "Remember that
+# on the World Day of Prayer, you would be the first people on Earth
+# to say your prayers in the morning."
+
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger say the transition was on 1968-10-01; go with Mundell.
+
+# From Eric Ulevik (1999-05-03):
+# Tonga's director of tourism, who is also secretary of the National Millenium
+# Committee, has a plan to get Tonga back in front.
+# He has proposed a one-off move to tropical daylight saving for Tonga from
+# October to March, which has won approval in principle from the Tongan
+# Government.
+
+# From Steffen Thorsen (1999-09-09):
+# * Tonga will introduce DST in November
+#
+# I was given this link by John Letts:
+# <a href="http://news.bbc.co.uk/hi/english/world/asia-pacific/newsid_424000/424764.stm">
+# http://news.bbc.co.uk/hi/english/world/asia-pacific/newsid_424000/424764.stm
+# </a>
+#
+# I have not been able to find exact dates for the transition in November
+# yet. By reading this article it seems like Fiji will be 14 hours ahead
+# of UTC as well, but as far as I know Fiji will only be 13 hours ahead
+# (12 + 1 hour DST).
+
+# From Arthur David Olson (1999-09-20):
+# According to <a href="http://www.tongaonline.com/news/sept1799.html">
+# http://www.tongaonline.com/news/sept1799.html
+# </a>:
+# "Daylight Savings Time will take effect on Oct. 2 through April 15, 2000
+# and annually thereafter from the first Saturday in October through the
+# third Saturday of April.  Under the system approved by Privy Council on
+# Sept. 10, clocks must be turned ahead one hour on the opening day and
+# set back an hour on the closing date."
+# Alas, no indication of the time of day.
+
+# From Rives McDow (1999-10-06):
+# Tonga started its Daylight Saving on Saturday morning October 2nd at 0200am.
+# Daylight Saving ends on April 16 at 0300am which is Sunday morning.
+
+# From Steffen Thorsen (2000-10-31):
+# Back in March I found a notice on the website http://www.tongaonline.com
+# that Tonga changed back to standard time one month early, on March 19
+# instead of the original reported date April 16. Unfortunately, the article
+# is no longer available on the site, and I did not make a copy of the
+# text, and I have forgotten to report it here.
+# (Original URL was: http://www.tongaonline.com/news/march162000.htm )
+
+# From Rives McDow (2000-12-01):
+# Tonga is observing DST as of 2000-11-04 and will stop on 2001-01-27.
+
+# From Sione Moala-Mafi (2001-09-20) via Rives McDow:
+# At 2:00am on the first Sunday of November, the standard time in the Kingdom
+# shall be moved forward by one hour to 3:00am.  At 2:00am on the last Sunday
+# of January the standard time in the Kingdom shall be moved backward by one
+# hour to 1:00am.
+
+# From Pulu 'Anau (2002-11-05):
+# The law was for 3 years, supposedly to get renewed.  It wasn't.
+
+
+# Wake
+
+# From Vernice Anderson, Personal Secretary to Philip Jessup,
+# US Ambassador At Large (oral history interview, 1971-02-02):
+#
+# Saturday, the 14th [of October, 1950] -- ...  The time was all the
+# more confusing at that point, because we had crossed the
+# International Date Line, thus getting two Sundays.  Furthermore, we
+# discovered that Wake Island had two hours of daylight saving time
+# making calculation of time in Washington difficult if not almost
+# impossible.
+#
+# http://www.trumanlibrary.org/wake/meeting.htm
+
+# From Paul Eggert (2003-03-23):
+# We have no other report of DST in Wake Island, so omit this info for now.
+
+###############################################################################
+
+# The International Date Line
+
+# From Gwillim Law (2000-01-03):
+#
+# The International Date Line is not defined by any international standard,
+# convention, or treaty.  Mapmakers are free to draw it as they please.
+# Reputable mapmakers will simply ensure that every point of land appears on
+# the correct side of the IDL, according to the date legally observed there.
+#
+# When Kiribati adopted a uniform date in 1995, thereby moving the Phoenix and
+# Line Islands to the west side of the IDL (or, if you prefer, moving the IDL
+# to the east side of the Phoenix and Line Islands), I suppose that most
+# mapmakers redrew the IDL following the boundary of Kiribati.  Even that line
+# has a rather arbitrary nature.  The straight-line boundaries between Pacific
+# island nations that are shown on many maps are based on an international
+# convention, but are not legally binding national borders.... The date is
+# governed by the IDL; therefore, even on the high seas, there may be some
+# places as late as fourteen hours later than UTC.  And, since the IDL is not
+# an international standard, there are some places on the high seas where the
+# correct date is ambiguous.
+
+# From Wikipedia <http://en.wikipedia.org/wiki/Time_zone> (2005-08-31):
+# Before 1920, all ships kept local apparent time on the high seas by setting
+# their clocks at night or at the morning sight so that, given the ship's
+# speed and direction, it would be 12 o'clock when the Sun crossed the ship's
+# meridian (12 o'clock = local apparent noon).  During 1917, at the
+# Anglo-French Conference on Time-keeping at Sea, it was recommended that all
+# ships, both military and civilian, should adopt hourly standard time zones
+# on the high seas.  Whenever a ship was within the territorial waters of any
+# nation it would use that nation's standard time.  The captain was permitted
+# to change his ship's clocks at a time of his choice following his ship's
+# entry into another zone time--he often chose midnight.  These zones were
+# adopted by all major fleets between 1920 and 1925 but not by many
+# independent merchant ships until World War II.
+
+# From Paul Eggert, using references suggested by Oscar van Vlijmen
+# (2005-03-20):
+#
+# The American Practical Navigator (2002)
+# <http://pollux.nss.nima.mil/pubs/pubs_j_apn_sections.html?rid=187>
+# talks only about the 180-degree meridian with respect to ships in
+# international waters; it ignores the international date line.
diff --git a/tools/zoneinfo/tzdata2008h/backward b/tools/zoneinfo/tzdata2008h/backward
new file mode 100644
index 0000000..a65991c
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/backward
@@ -0,0 +1,112 @@
+# @(#)backward	8.6
+
+# This file provides links between current names for time zones
+# and their old names.  Many names changed in late 1993.
+
+Link	Africa/Asmara		Africa/Asmera
+Link	Africa/Bamako		Africa/Timbuktu
+Link	America/Argentina/Catamarca	America/Argentina/ComodRivadavia
+Link	America/Adak		America/Atka
+Link	America/Argentina/Buenos_Aires	America/Buenos_Aires
+Link	America/Argentina/Catamarca	America/Catamarca
+Link	America/Atikokan	America/Coral_Harbour
+Link	America/Argentina/Cordoba	America/Cordoba
+Link	America/Tijuana		America/Ensenada
+Link	America/Indiana/Indianapolis	America/Fort_Wayne
+Link	America/Indiana/Indianapolis	America/Indianapolis
+Link	America/Argentina/Jujuy	America/Jujuy
+Link	America/Indiana/Knox	America/Knox_IN
+Link	America/Kentucky/Louisville	America/Louisville
+Link	America/Argentina/Mendoza	America/Mendoza
+Link	America/Rio_Branco	America/Porto_Acre
+Link	America/Argentina/Cordoba	America/Rosario
+Link	America/St_Thomas	America/Virgin
+Link	Asia/Ashgabat		Asia/Ashkhabad
+Link	Asia/Chongqing		Asia/Chungking
+Link	Asia/Dhaka		Asia/Dacca
+Link	Asia/Kolkata		Asia/Calcutta
+Link	Asia/Macau		Asia/Macao
+Link	Asia/Jerusalem		Asia/Tel_Aviv
+Link	Asia/Ho_Chi_Minh	Asia/Saigon
+Link	Asia/Thimphu		Asia/Thimbu
+Link	Asia/Makassar		Asia/Ujung_Pandang
+Link	Asia/Ulaanbaatar	Asia/Ulan_Bator
+Link	Atlantic/Faroe		Atlantic/Faeroe
+Link	Europe/Oslo		Atlantic/Jan_Mayen
+Link	Australia/Sydney	Australia/ACT
+Link	Australia/Sydney	Australia/Canberra
+Link	Australia/Lord_Howe	Australia/LHI
+Link	Australia/Sydney	Australia/NSW
+Link	Australia/Darwin	Australia/North
+Link	Australia/Brisbane	Australia/Queensland
+Link	Australia/Adelaide	Australia/South
+Link	Australia/Hobart	Australia/Tasmania
+Link	Australia/Melbourne	Australia/Victoria
+Link	Australia/Perth		Australia/West
+Link	Australia/Broken_Hill	Australia/Yancowinna
+Link	America/Rio_Branco	Brazil/Acre
+Link	America/Noronha		Brazil/DeNoronha
+Link	America/Sao_Paulo	Brazil/East
+Link	America/Manaus		Brazil/West
+Link	America/Halifax		Canada/Atlantic
+Link	America/Winnipeg	Canada/Central
+Link	America/Regina		Canada/East-Saskatchewan
+Link	America/Toronto		Canada/Eastern
+Link	America/Edmonton	Canada/Mountain
+Link	America/St_Johns	Canada/Newfoundland
+Link	America/Vancouver	Canada/Pacific
+Link	America/Regina		Canada/Saskatchewan
+Link	America/Whitehorse	Canada/Yukon
+Link	America/Santiago	Chile/Continental
+Link	Pacific/Easter		Chile/EasterIsland
+Link	America/Havana		Cuba
+Link	Africa/Cairo		Egypt
+Link	Europe/Dublin		Eire
+Link	Europe/London		Europe/Belfast
+Link	Europe/Chisinau		Europe/Tiraspol
+Link	Europe/London		GB
+Link	Europe/London		GB-Eire
+Link	Etc/GMT			GMT+0
+Link	Etc/GMT			GMT-0
+Link	Etc/GMT			GMT0
+Link	Etc/GMT			Greenwich
+Link	Asia/Hong_Kong		Hongkong
+Link	Atlantic/Reykjavik	Iceland
+Link	Asia/Tehran		Iran
+Link	Asia/Jerusalem		Israel
+Link	America/Jamaica		Jamaica
+Link	Asia/Tokyo		Japan
+Link	Pacific/Kwajalein	Kwajalein
+Link	Africa/Tripoli		Libya
+Link	America/Tijuana		Mexico/BajaNorte
+Link	America/Mazatlan	Mexico/BajaSur
+Link	America/Mexico_City	Mexico/General
+Link	Pacific/Auckland	NZ
+Link	Pacific/Chatham		NZ-CHAT
+Link	America/Denver		Navajo
+Link	Asia/Shanghai		PRC
+Link	Pacific/Pago_Pago	Pacific/Samoa
+Link	Pacific/Truk		Pacific/Yap
+Link	Europe/Warsaw		Poland
+Link	Europe/Lisbon		Portugal
+Link	Asia/Taipei		ROC
+Link	Asia/Seoul		ROK
+Link	Asia/Singapore		Singapore
+Link	Europe/Istanbul		Turkey
+Link	Etc/UCT			UCT
+Link	America/Anchorage	US/Alaska
+Link	America/Adak		US/Aleutian
+Link	America/Phoenix		US/Arizona
+Link	America/Chicago		US/Central
+Link	America/Indiana/Indianapolis	US/East-Indiana
+Link	America/New_York	US/Eastern
+Link	Pacific/Honolulu	US/Hawaii
+Link	America/Indiana/Knox	US/Indiana-Starke
+Link	America/Detroit		US/Michigan
+Link	America/Denver		US/Mountain
+Link	America/Los_Angeles	US/Pacific
+Link	Pacific/Pago_Pago	US/Samoa
+Link	Etc/UTC			UTC
+Link	Etc/UTC			Universal
+Link	Europe/Moscow		W-SU
+Link	Etc/UTC			Zulu
diff --git a/tools/zoneinfo/tzdata2008h/etcetera b/tools/zoneinfo/tzdata2008h/etcetera
new file mode 100644
index 0000000..cddbe8a
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/etcetera
@@ -0,0 +1,80 @@
+# @(#)etcetera	8.1
+
+# These entries are mostly present for historical reasons, so that
+# people in areas not otherwise covered by the tz files could "zic -l"
+# to a time zone that was right for their area.  These days, the
+# tz files cover almost all the inhabited world, and the only practical
+# need now for the entries that are not on UTC are for ships at sea
+# that cannot use POSIX TZ settings.
+
+Zone	Etc/GMT		0	-	GMT
+Zone	Etc/UTC		0	-	UTC
+Zone	Etc/UCT		0	-	UCT
+
+# The following link uses older naming conventions,
+# but it belongs here, not in the file `backward',
+# as functions like gmtime load the "GMT" file to handle leap seconds properly.
+# We want this to work even on installations that omit the other older names.
+Link	Etc/GMT				GMT
+
+Link	Etc/UTC				Etc/Universal
+Link	Etc/UTC				Etc/Zulu
+
+Link	Etc/GMT				Etc/Greenwich
+Link	Etc/GMT				Etc/GMT-0
+Link	Etc/GMT				Etc/GMT+0
+Link	Etc/GMT				Etc/GMT0
+
+# We use POSIX-style signs in the Zone names and the output abbreviations,
+# even though this is the opposite of what many people expect.
+# POSIX has positive signs west of Greenwich, but many people expect
+# positive signs east of Greenwich.  For example, TZ='Etc/GMT+4' uses
+# the abbreviation "GMT+4" and corresponds to 4 hours behind UTC
+# (i.e. west of Greenwich) even though many people would expect it to
+# mean 4 hours ahead of UTC (i.e. east of Greenwich).
+#
+# In the draft 5 of POSIX 1003.1-200x, the angle bracket notation
+# (which is not yet supported by the tz code) allows for
+# TZ='<GMT-4>+4'; if you want time zone abbreviations conforming to
+# ISO 8601 you can use TZ='<-0400>+4'.  Thus the commonly-expected
+# offset is kept within the angle bracket (and is used for display)
+# while the POSIX sign is kept outside the angle bracket (and is used
+# for calculation).
+#
+# Do not use a TZ setting like TZ='GMT+4', which is four hours behind
+# GMT but uses the completely misleading abbreviation "GMT".
+
+# Earlier incarnations of this package were not POSIX-compliant,
+# and had lines such as
+#		Zone	GMT-12		-12	-	GMT-1200
+# We did not want things to change quietly if someone accustomed to the old
+# way does a
+#		zic -l GMT-12
+# so we moved the names into the Etc subdirectory.
+
+Zone	Etc/GMT-14	14	-	GMT-14	# 14 hours ahead of GMT
+Zone	Etc/GMT-13	13	-	GMT-13
+Zone	Etc/GMT-12	12	-	GMT-12
+Zone	Etc/GMT-11	11	-	GMT-11
+Zone	Etc/GMT-10	10	-	GMT-10
+Zone	Etc/GMT-9	9	-	GMT-9
+Zone	Etc/GMT-8	8	-	GMT-8
+Zone	Etc/GMT-7	7	-	GMT-7
+Zone	Etc/GMT-6	6	-	GMT-6
+Zone	Etc/GMT-5	5	-	GMT-5
+Zone	Etc/GMT-4	4	-	GMT-4
+Zone	Etc/GMT-3	3	-	GMT-3
+Zone	Etc/GMT-2	2	-	GMT-2
+Zone	Etc/GMT-1	1	-	GMT-1
+Zone	Etc/GMT+1	-1	-	GMT+1
+Zone	Etc/GMT+2	-2	-	GMT+2
+Zone	Etc/GMT+3	-3	-	GMT+3
+Zone	Etc/GMT+4	-4	-	GMT+4
+Zone	Etc/GMT+5	-5	-	GMT+5
+Zone	Etc/GMT+6	-6	-	GMT+6
+Zone	Etc/GMT+7	-7	-	GMT+7
+Zone	Etc/GMT+8	-8	-	GMT+8
+Zone	Etc/GMT+9	-9	-	GMT+9
+Zone	Etc/GMT+10	-10	-	GMT+10
+Zone	Etc/GMT+11	-11	-	GMT+11
+Zone	Etc/GMT+12	-12	-	GMT+12
diff --git a/tools/zoneinfo/tzdata2008h/europe b/tools/zoneinfo/tzdata2008h/europe
new file mode 100644
index 0000000..7bb9864
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/europe
@@ -0,0 +1,2594 @@
+# @(#)europe	8.18
+# <pre>
+
+# This data is by no means authoritative; if you think you know better,
+# go ahead and edit the file (and please send any changes to
+# tz@elsie.nci.nih.gov for general use in the future).
+
+# From Paul Eggert (2006-03-22):
+# A good source for time zone historical data outside the U.S. is
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
+# San Diego: ACS Publications, Inc. (2003).
+#
+# Gwillim Law writes that a good source
+# for recent time zone data is the International Air Transport
+# Association's Standard Schedules Information Manual (IATA SSIM),
+# published semiannually.  Law sent in several helpful summaries
+# of the IATA's data after 1990.
+#
+# Except where otherwise noted, Shanks & Pottenger is the source for
+# entries through 1991, and IATA SSIM is the source for entries afterwards.
+#
+# Other sources occasionally used include:
+#
+#	Edward W. Whitman, World Time Differences,
+#	Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated),
+#	which I found in the UCLA library.
+#
+#	<a href="http://www.pettswoodvillage.co.uk/Daylight_Savings_William_Willett.pdf">
+#	William Willett, The Waste of Daylight, 19th edition
+#	</a> (1914-03)
+#
+#	Brazil's Departamento Servico da Hora (DSH),
+#	<a href="http://pcdsh01.on.br/HISTHV.htm">
+#	History of Summer Time
+#	</a> (1998-09-21, in Portuguese)
+
+#
+# I invented the abbreviations marked `*' in the following table;
+# the rest are from earlier versions of this file, or from other sources.
+# Corrections are welcome!
+#                   std dst  2dst
+#                   LMT           Local Mean Time
+#       -4:00       AST ADT       Atlantic
+#       -3:00       WGT WGST      Western Greenland*
+#       -1:00       EGT EGST      Eastern Greenland*
+#        0:00       GMT BST  BDST Greenwich, British Summer
+#        0:00       GMT IST       Greenwich, Irish Summer
+#        0:00       WET WEST WEMT Western Europe
+#        0:19:32.13 AMT NST       Amsterdam, Netherlands Summer (1835-1937)*
+#        0:20       NET NEST      Netherlands (1937-1940)*
+#        1:00       CET CEST CEMT Central Europe
+#        1:00:14    SET           Swedish (1879-1899)*
+#        2:00       EET EEST      Eastern Europe
+#        3:00       MSK MSD       Moscow
+#
+# A reliable and entertaining source about time zones, especially in Britain,
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
+
+# From Peter Ilieve (1994-12-04),
+# The original six [EU members]: Belgium, France, (West) Germany, Italy,
+# Luxembourg, the Netherlands.
+# Plus, from 1 Jan 73: Denmark, Ireland, United Kingdom.
+# Plus, from 1 Jan 81: Greece.
+# Plus, from 1 Jan 86: Spain, Portugal.
+# Plus, from 1 Jan 95: Austria, Finland, Sweden. (Norway negotiated terms for
+# entry but in a referendum on 28 Nov 94 the people voted No by 52.2% to 47.8%
+# on a turnout of 88.6%. This was almost the same result as Norway's previous
+# referendum in 1972, they are the only country to have said No twice.
+# Referendums in the other three countries voted Yes.)
+# ...
+# Estonia ... uses EU dates but not at 01:00 GMT, they use midnight GMT.
+# I don't think they know yet what they will do from 1996 onwards.
+# ...
+# There shouldn't be any [current members who are not using EU rules].
+# A Directive has the force of law, member states are obliged to enact
+# national law to implement it. The only contentious issue was the
+# different end date for the UK and Ireland, and this was always allowed
+# in the Directive.
+
+
+###############################################################################
+
+# Britain (United Kingdom) and Ireland (Eire)
+
+# From Peter Ilieve (1994-07-06):
+#
+# On 17 Jan 1994 the Independent, a UK quality newspaper, had a piece about
+# historical vistas along the Thames in west London. There was a photo
+# and a sketch map showing some of the sightlines involved. One paragraph
+# of the text said:
+#
+# `An old stone obelisk marking a forgotten terrestrial meridian stands
+# beside the river at Kew. In the 18th century, before time and longitude
+# was standardised by the Royal Observatory in Greenwich, scholars observed
+# this stone and the movement of stars from Kew Observatory nearby. They
+# made their calculations and set the time for the Horse Guards and Parliament,
+# but now the stone is obscured by scrubwood and can only be seen by walking
+# along the towpath within a few yards of it.'
+#
+# I have a one inch to one mile map of London and my estimate of the stone's
+# position is 51 deg. 28' 30" N, 0 deg. 18' 45" W. The longitude should
+# be within about +-2". The Ordnance Survey grid reference is TQ172761.
+#
+# [This yields GMTOFF = -0:01:15 for London LMT in the 18th century.]
+
+# From Paul Eggert (1993-11-18):
+#
+# Howse writes that Britain was the first country to use standard time.
+# The railways cared most about the inconsistencies of local mean time,
+# and it was they who forced a uniform time on the country.
+# The original idea was credited to Dr. William Hyde Wollaston (1766-1828)
+# and was popularized by Abraham Follett Osler (1808-1903).
+# The first railway to adopt London time was the Great Western Railway
+# in November 1840; other railways followed suit, and by 1847 most
+# (though not all) railways used London time.  On 1847-09-22 the
+# Railway Clearing House, an industry standards body, recommended that GMT be
+# adopted at all stations as soon as the General Post Office permitted it.
+# The transition occurred on 12-01 for the L&NW, the Caledonian,
+# and presumably other railways; the January 1848 Bradshaw's lists many
+# railways as using GMT.  By 1855 the vast majority of public
+# clocks in Britain were set to GMT (though some, like the great clock
+# on Tom Tower at Christ Church, Oxford, were fitted with two minute hands,
+# one for local time and one for GMT).  The last major holdout was the legal
+# system, which stubbornly stuck to local time for many years, leading
+# to oddities like polls opening at 08:13 and closing at 16:13.
+# The legal system finally switched to GMT when the Statutes (Definition
+# of Time) Act took effect; it received the Royal Assent on 1880-08-02.
+#
+# In the tables below, we condense this complicated story into a single
+# transition date for London, namely 1847-12-01.  We don't know as much
+# about Dublin, so we use 1880-08-02, the legal transition time.
+
+# From Paul Eggert (2003-09-27):
+# Summer Time was first seriously proposed by William Willett (1857-1915),
+# a London builder and member of the Royal Astronomical Society
+# who circulated a pamphlet ``The Waste of Daylight'' (1907)
+# that proposed advancing clocks 20 minutes on each of four Sundays in April,
+# and retarding them by the same amount on four Sundays in September.
+# A bill was drafted in 1909 and introduced in Parliament several times,
+# but it met with ridicule and opposition, especially from farming interests.
+# Later editions of the pamphlet proposed one-hour summer time, and
+# it was eventually adopted as a wartime measure in 1916.
+# See: Summer Time Arrives Early, The Times (2000-05-18).
+# A monument to Willett was unveiled on 1927-05-21, in an open space in
+# a 45-acre wood near Chislehurst, Kent that was purchased by popular
+# subscription and open to the public.  On the south face of the monolith,
+# designed by G. W. Miller, is the the William Willett Memorial Sundial,
+# which is permanently set to Summer Time.
+
+# From Winston Churchill (1934-04-28):
+# It is one of the paradoxes of history that we should owe the boon of
+# summer time, which gives every year to the people of this country
+# between 160 and 170 hours more daylight leisure, to a war which
+# plunged Europe into darkness for four years, and shook the
+# foundations of civilization throughout the world.
+#	-- <a href="http://www.winstonchurchill.org/fh114willett.htm">
+#	"A Silent Toast to William Willett", Pictorial Weekly
+#	</a>
+
+# From Paul Eggert (1996-09-03):
+# The OED Supplement says that the English originally said ``Daylight Saving''
+# when they were debating the adoption of DST in 1908; but by 1916 this
+# term appears only in quotes taken from DST's opponents, whereas the
+# proponents (who eventually won the argument) are quoted as using ``Summer''.
+
+# From Arthur David Olson (1989-01-19):
+#
+# A source at the British Information Office in New York avers that it's
+# known as "British" Summer Time in all parts of the United Kingdom.
+
+# Date: 4 Jan 89 08:57:25 GMT (Wed)
+# From: Jonathan Leffler
+# [British Summer Time] is fixed annually by Act of Parliament.
+# If you can predict what Parliament will do, you should be in
+# politics making a fortune, not computing.
+
+# From Chris Carrier (1996-06-14):
+# I remember reading in various wartime issues of the London Times the
+# acronym BDST for British Double Summer Time.  Look for the published
+# time of sunrise and sunset in The Times, when BDST was in effect, and
+# if you find a zone reference it will say, "All times B.D.S.T."
+
+# From Joseph S. Myers (1999-09-02):
+# ... some military cables (WO 219/4100 - this is a copy from the
+# main SHAEF archives held in the US National Archives, SHAEF/5252/8/516)
+# agree that the usage is BDST (this appears in a message dated 17 Feb 1945).
+
+# From Joseph S. Myers (2000-10-03):
+# On 18th April 1941, Sir Stephen Tallents of the BBC wrote to Sir
+# Alexander Maxwell of the Home Office asking whether there was any
+# official designation; the reply of the 21st was that there wasn't
+# but he couldn't think of anything better than the "Double British
+# Summer Time" that the BBC had been using informally.
+# http://student.cusu.cam.ac.uk/~jsm28/british-time/bbc-19410418.png
+# http://student.cusu.cam.ac.uk/~jsm28/british-time/ho-19410421.png
+
+# From Sir Alexander Maxwell in the above-mentioned letter (1941-04-21):
+# [N]o official designation has as far as I know been adopted for the time
+# which is to be introduced in May....
+# I cannot think of anything better than "Double British Summer Time"
+# which could not be said to run counter to any official description.
+
+# From Paul Eggert (2000-10-02):
+# Howse writes (p 157) `DBST' too, but `BDST' seems to have been common
+# and follows the more usual convention of putting the location name first,
+# so we use `BDST'.
+
+# Peter Ilieve (1998-04-19) described at length
+# the history of summer time legislation in the United Kingdom.
+# Since 1998 Joseph S. Myers has been updating
+# and extending this list, which can be found in
+# <a href="http://student.cusu.cam.ac.uk/~jsm28/british-time/">
+# History of legal time in Britain
+# </a>
+
+# From Joseph S. Myers (1998-01-06):
+#
+# The legal time in the UK outside of summer time is definitely GMT, not UTC;
+# see Lord Tanlaw's speech
+# <a href="http://www.parliament.the-stationery-office.co.uk/pa/ld199697/ldhansrd/pdvn/lds97/text/70611-20.htm#70611-20_head0">
+# (Lords Hansard 11 June 1997 columns 964 to 976)
+# </a>.
+
+# From Paul Eggert (2006-03-22):
+#
+# For lack of other data, follow Shanks & Pottenger for Eire in 1940-1948.
+#
+# Given Ilieve and Myers's data, the following claims by Shanks & Pottenger
+# are incorrect:
+#     * Wales did not switch from GMT to daylight saving time until
+#	1921 Apr 3, when they began to conform with the rest of Great Britain.
+# Actually, Wales was identical after 1880.
+#     * Eire had two transitions on 1916 Oct 1.
+# It actually just had one transition.
+#     * Northern Ireland used single daylight saving time throughout WW II.
+# Actually, it conformed to Britain.
+#     * GB-Eire changed standard time to 1 hour ahead of GMT on 1968-02-18.
+# Actually, that date saw the usual switch to summer time.
+# Standard time was not changed until 1968-10-27 (the clocks didn't change).
+#
+# Here is another incorrect claim by Shanks & Pottenger:
+#     * Jersey, Guernsey, and the Isle of Man did not switch from GMT
+#	to daylight saving time until 1921 Apr 3, when they began to
+#	conform with Great Britain.
+# S.R.&O. 1916, No. 382 and HO 45/10811/312364 (quoted above) say otherwise.
+#
+# The following claim by Shanks & Pottenger is possible though doubtful;
+# we'll ignore it for now.
+#     * Dublin's 1971-10-31 switch was at 02:00, even though London's was 03:00.
+#
+#
+# Whitman says Dublin Mean Time was -0:25:21, which is more precise than
+# Shanks & Pottenger.
+# Perhaps this was Dunsink Observatory Time, as Dunsink Observatory
+# (8 km NW of Dublin's center) seemingly was to Dublin as Greenwich was
+# to London.  For example:
+#
+#   "Timeball on the ballast office is down.  Dunsink time."
+#   -- James Joyce, Ulysses
+
+# From Joseph S. Myers (2005-01-26):
+# Irish laws are available online at www.irishstatutebook.ie.  These include
+# various relating to legal time, for example:
+#
+# ZZA13Y1923.html ZZA12Y1924.html ZZA8Y1925.html ZZSIV20PG1267.html
+#
+# ZZSI71Y1947.html ZZSI128Y1948.html ZZSI23Y1949.html ZZSI41Y1950.html
+# ZZSI27Y1951.html ZZSI73Y1952.html
+#
+# ZZSI11Y1961.html ZZSI232Y1961.html ZZSI182Y1962.html
+# ZZSI167Y1963.html ZZSI257Y1964.html ZZSI198Y1967.html
+# ZZA23Y1968.html ZZA17Y1971.html
+#
+# ZZSI67Y1981.html ZZSI212Y1982.html ZZSI45Y1986.html
+# ZZSI264Y1988.html ZZSI52Y1990.html ZZSI371Y1992.html
+# ZZSI395Y1994.html ZZSI484Y1997.html ZZSI506Y2001.html
+#
+# [These are all relative to the root, e.g., the first is
+# <http://www.irishstatutebook.ie/ZZA13Y1923.html>.]
+#
+# (These are those I found, but there could be more.  In any case these
+# should allow various updates to the comments in the europe file to cover
+# the laws applicable in Ireland.)
+#
+# (Note that the time in the Republic of Ireland since 1968 has been defined
+# in terms of standard time being GMT+1 with a period of winter time when it
+# is GMT, rather than standard time being GMT with a period of summer time
+# being GMT+1.)
+
+# From Paul Eggert (1999-03-28):
+# Clive Feather (<news:859845706.26043.0@office.demon.net>, 1997-03-31)
+# reports that Folkestone (Cheriton) Shuttle Terminal uses Concession Time
+# (CT), equivalent to French civil time.
+# Julian Hill (<news:36118128.5A14@virgin.net>, 1998-09-30) reports that
+# trains between Dollands Moor (the freight facility next door)
+# and Frethun run in CT.
+# My admittedly uninformed guess is that the terminal has two authorities,
+# the French concession operators and the British civil authorities,
+# and that the time depends on who you're talking to.
+# If, say, the British police were called to the station for some reason,
+# I would expect the official police report to use GMT/BST and not CET/CEST.
+# This is a borderline case, but for now let's stick to GMT/BST.
+
+# From an anonymous contributor (1996-06-02):
+# The law governing time in Ireland is under Statutory Instrument SI 395/94,
+# which gives force to European Union 7th Council Directive # 94/21/EC.
+# Under this directive, the Minister for Justice in Ireland makes appropriate
+# regulations. I spoke this morning with the Secretary of the Department of
+# Justice (tel +353 1 678 9711) who confirmed to me that the correct name is
+# "Irish Summer Time", abbreviated to "IST".
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# Summer Time Act, 1916
+Rule	GB-Eire	1916	only	-	May	21	2:00s	1:00	BST
+Rule	GB-Eire	1916	only	-	Oct	 1	2:00s	0	GMT
+# S.R.&O. 1917, No. 358
+Rule	GB-Eire	1917	only	-	Apr	 8	2:00s	1:00	BST
+Rule	GB-Eire	1917	only	-	Sep	17	2:00s	0	GMT
+# S.R.&O. 1918, No. 274
+Rule	GB-Eire	1918	only	-	Mar	24	2:00s	1:00	BST
+Rule	GB-Eire	1918	only	-	Sep	30	2:00s	0	GMT
+# S.R.&O. 1919, No. 297
+Rule	GB-Eire	1919	only	-	Mar	30	2:00s	1:00	BST
+Rule	GB-Eire	1919	only	-	Sep	29	2:00s	0	GMT
+# S.R.&O. 1920, No. 458
+Rule	GB-Eire	1920	only	-	Mar	28	2:00s	1:00	BST
+# S.R.&O. 1920, No. 1844
+Rule	GB-Eire	1920	only	-	Oct	25	2:00s	0	GMT
+# S.R.&O. 1921, No. 363
+Rule	GB-Eire	1921	only	-	Apr	 3	2:00s	1:00	BST
+Rule	GB-Eire	1921	only	-	Oct	 3	2:00s	0	GMT
+# S.R.&O. 1922, No. 264
+Rule	GB-Eire	1922	only	-	Mar	26	2:00s	1:00	BST
+Rule	GB-Eire	1922	only	-	Oct	 8	2:00s	0	GMT
+# The Summer Time Act, 1922
+Rule	GB-Eire	1923	only	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1923	1924	-	Sep	Sun>=16	2:00s	0	GMT
+Rule	GB-Eire	1924	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1925	1926	-	Apr	Sun>=16	2:00s	1:00	BST
+# The Summer Time Act, 1925
+Rule	GB-Eire	1925	1938	-	Oct	Sun>=2	2:00s	0	GMT
+Rule	GB-Eire	1927	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1928	1929	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1930	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1931	1932	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1933	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1934	only	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1935	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1936	1937	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1938	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1939	only	-	Apr	Sun>=16	2:00s	1:00	BST
+# S.R.&O. 1939, No. 1379
+Rule	GB-Eire	1939	only	-	Nov	Sun>=16	2:00s	0	GMT
+# S.R.&O. 1940, No. 172 and No. 1883
+Rule	GB-Eire	1940	only	-	Feb	Sun>=23	2:00s	1:00	BST
+# S.R.&O. 1941, No. 476
+Rule	GB-Eire	1941	only	-	May	Sun>=2	1:00s	2:00	BDST
+Rule	GB-Eire	1941	1943	-	Aug	Sun>=9	1:00s	1:00	BST
+# S.R.&O. 1942, No. 506
+Rule	GB-Eire	1942	1944	-	Apr	Sun>=2	1:00s	2:00	BDST
+# S.R.&O. 1944, No. 932
+Rule	GB-Eire	1944	only	-	Sep	Sun>=16	1:00s	1:00	BST
+# S.R.&O. 1945, No. 312
+Rule	GB-Eire	1945	only	-	Apr	Mon>=2	1:00s	2:00	BDST
+Rule	GB-Eire	1945	only	-	Jul	Sun>=9	1:00s	1:00	BST
+# S.R.&O. 1945, No. 1208
+Rule	GB-Eire	1945	1946	-	Oct	Sun>=2	2:00s	0	GMT
+Rule	GB-Eire	1946	only	-	Apr	Sun>=9	2:00s	1:00	BST
+# The Summer Time Act, 1947
+Rule	GB-Eire	1947	only	-	Mar	16	2:00s	1:00	BST
+Rule	GB-Eire	1947	only	-	Apr	13	1:00s	2:00	BDST
+Rule	GB-Eire	1947	only	-	Aug	10	1:00s	1:00	BST
+Rule	GB-Eire	1947	only	-	Nov	 2	2:00s	0	GMT
+# Summer Time Order, 1948 (S.I. 1948/495)
+Rule	GB-Eire	1948	only	-	Mar	14	2:00s	1:00	BST
+Rule	GB-Eire	1948	only	-	Oct	31	2:00s	0	GMT
+# Summer Time Order, 1949 (S.I. 1949/373)
+Rule	GB-Eire	1949	only	-	Apr	 3	2:00s	1:00	BST
+Rule	GB-Eire	1949	only	-	Oct	30	2:00s	0	GMT
+# Summer Time Order, 1950 (S.I. 1950/518)
+# Summer Time Order, 1951 (S.I. 1951/430)
+# Summer Time Order, 1952 (S.I. 1952/451)
+Rule	GB-Eire	1950	1952	-	Apr	Sun>=14	2:00s	1:00	BST
+Rule	GB-Eire	1950	1952	-	Oct	Sun>=21	2:00s	0	GMT
+# revert to the rules of the Summer Time Act, 1925
+Rule	GB-Eire	1953	only	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1953	1960	-	Oct	Sun>=2	2:00s	0	GMT
+Rule	GB-Eire	1954	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1955	1956	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1957	only	-	Apr	Sun>=9	2:00s	1:00	BST
+Rule	GB-Eire	1958	1959	-	Apr	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1960	only	-	Apr	Sun>=9	2:00s	1:00	BST
+# Summer Time Order, 1961 (S.I. 1961/71)
+# Summer Time (1962) Order, 1961 (S.I. 1961/2465)
+# Summer Time Order, 1963 (S.I. 1963/81)
+Rule	GB-Eire	1961	1963	-	Mar	lastSun	2:00s	1:00	BST
+Rule	GB-Eire	1961	1968	-	Oct	Sun>=23	2:00s	0	GMT
+# Summer Time (1964) Order, 1963 (S.I. 1963/2101)
+# Summer Time Order, 1964 (S.I. 1964/1201)
+# Summer Time Order, 1967 (S.I. 1967/1148)
+Rule	GB-Eire	1964	1967	-	Mar	Sun>=19	2:00s	1:00	BST
+# Summer Time Order, 1968 (S.I. 1968/117)
+Rule	GB-Eire	1968	only	-	Feb	18	2:00s	1:00	BST
+# The British Standard Time Act, 1968
+#	(no summer time)
+# The Summer Time Act, 1972
+Rule	GB-Eire	1972	1980	-	Mar	Sun>=16	2:00s	1:00	BST
+Rule	GB-Eire	1972	1980	-	Oct	Sun>=23	2:00s	0	GMT
+# Summer Time Order, 1980 (S.I. 1980/1089)
+# Summer Time Order, 1982 (S.I. 1982/1673)
+# Summer Time Order, 1986 (S.I. 1986/223)
+# Summer Time Order, 1988 (S.I. 1988/931)
+Rule	GB-Eire	1981	1995	-	Mar	lastSun	1:00u	1:00	BST
+Rule	GB-Eire 1981	1989	-	Oct	Sun>=23	1:00u	0	GMT
+# Summer Time Order, 1989 (S.I. 1989/985)
+# Summer Time Order, 1992 (S.I. 1992/1729)
+# Summer Time Order 1994 (S.I. 1994/2798)
+Rule	GB-Eire 1990	1995	-	Oct	Sun>=22	1:00u	0	GMT
+# Summer Time Order 1997 (S.I. 1997/2982)
+# See EU for rules starting in 1996.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/London	-0:01:15 -	LMT	1847 Dec  1 0:00s
+			 0:00	GB-Eire	%s	1968 Oct 27
+			 1:00	-	BST	1971 Oct 31 2:00u
+			 0:00	GB-Eire	%s	1996
+			 0:00	EU	GMT/BST
+Link	Europe/London	Europe/Jersey
+Link	Europe/London	Europe/Guernsey
+Link	Europe/London	Europe/Isle_of_Man
+Zone	Europe/Dublin	-0:25:00 -	LMT	1880 Aug  2
+			-0:25:21 -	DMT	1916 May 21 2:00
+			-0:25:21 1:00	IST	1916 Oct  1 2:00s
+			 0:00	GB-Eire	%s	1921 Dec  6 # independence
+			 0:00	GB-Eire	GMT/IST	1940 Feb 25 2:00
+			 0:00	1:00	IST	1946 Oct  6 2:00
+			 0:00	-	GMT	1947 Mar 16 2:00
+			 0:00	1:00	IST	1947 Nov  2 2:00
+			 0:00	-	GMT	1948 Apr 18 2:00
+			 0:00	GB-Eire	GMT/IST	1968 Oct 27
+			 1:00	-	IST	1971 Oct 31 2:00u
+			 0:00	GB-Eire	GMT/IST	1996
+			 0:00	EU	GMT/IST
+
+###############################################################################
+
+# Europe
+
+# EU rules are for the European Union, previously known as the EC, EEC,
+# Common Market, etc.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	EU	1977	1980	-	Apr	Sun>=1	 1:00u	1:00	S
+Rule	EU	1977	only	-	Sep	lastSun	 1:00u	0	-
+Rule	EU	1978	only	-	Oct	 1	 1:00u	0	-
+Rule	EU	1979	1995	-	Sep	lastSun	 1:00u	0	-
+Rule	EU	1981	max	-	Mar	lastSun	 1:00u	1:00	S
+Rule	EU	1996	max	-	Oct	lastSun	 1:00u	0	-
+# The most recent directive covers the years starting in 2002.  See:
+# <a href="http://europa.eu.int/eur-lex/en/lif/dat/2000/en_300L0084.html">
+# Directive 2000/84/EC of the European Parliament and of the Council
+# of 19 January 2001 on summer-time arrangements.
+# </a>
+
+# W-Eur differs from EU only in that W-Eur uses standard time.
+Rule	W-Eur	1977	1980	-	Apr	Sun>=1	 1:00s	1:00	S
+Rule	W-Eur	1977	only	-	Sep	lastSun	 1:00s	0	-
+Rule	W-Eur	1978	only	-	Oct	 1	 1:00s	0	-
+Rule	W-Eur	1979	1995	-	Sep	lastSun	 1:00s	0	-
+Rule	W-Eur	1981	max	-	Mar	lastSun	 1:00s	1:00	S
+Rule	W-Eur	1996	max	-	Oct	lastSun	 1:00s	0	-
+
+# Older C-Eur rules are for convenience in the tables.
+# From 1977 on, C-Eur differs from EU only in that C-Eur uses standard time.
+Rule	C-Eur	1916	only	-	Apr	30	23:00	1:00	S
+Rule	C-Eur	1916	only	-	Oct	 1	 1:00	0	-
+Rule	C-Eur	1917	1918	-	Apr	Mon>=15	 2:00s	1:00	S
+Rule	C-Eur	1917	1918	-	Sep	Mon>=15	 2:00s	0	-
+Rule	C-Eur	1940	only	-	Apr	 1	 2:00s	1:00	S
+Rule	C-Eur	1942	only	-	Nov	 2	 2:00s	0	-
+Rule	C-Eur	1943	only	-	Mar	29	 2:00s	1:00	S
+Rule	C-Eur	1943	only	-	Oct	 4	 2:00s	0	-
+Rule	C-Eur	1944	1945	-	Apr	Mon>=1	 2:00s	1:00	S
+# Whitman gives 1944 Oct 7; go with Shanks & Pottenger.
+Rule	C-Eur	1944	only	-	Oct	 2	 2:00s	0	-
+# From Jesper Norgaard Welen (2008-07-13):
+#
+# I found what is probably a typo of 2:00 which should perhaps be 2:00s
+# in the C-Eur rule from tz database version 2008d (this part was
+# corrected in version 2008d). The circumstancial evidence is simply the
+# tz database itself, as seen below:
+#
+# Zone Europe/Paris 0:09:21 - LMT 1891 Mar 15  0:01
+#    0:00 France WE%sT 1945 Sep 16  3:00
+#
+# Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15
+#    0:00 France WE%sT 1945 Sep 16 3:00
+#
+# Zone Europe/Belgrade 1:22:00 - LMT 1884
+#    1:00 1:00 CEST 1945 Sep 16  2:00s
+#
+# Rule France 1945 only - Sep 16  3:00 0 -
+# Rule Belgium 1945 only - Sep 16  2:00s 0 -
+# Rule Neth 1945 only - Sep 16 2:00s 0 -
+#
+# The rule line to be changed is:
+#
+# Rule C-Eur 1945 only - Sep 16  2:00 0 -
+#
+# It seems that Paris, Monaco, Rule France, Rule Belgium all agree on
+# 2:00 standard time, e.g. 3:00 local time.  However there are no
+# countries that use C-Eur rules in September 1945, so the only items
+# affected are apparently these ficticious zones that translates acronyms
+# CET and MET:
+#
+# Zone CET  1:00 C-Eur CE%sT
+# Zone MET  1:00 C-Eur ME%sT
+#
+# It this is right then the corrected version would look like:
+#
+# Rule C-Eur 1945 only - Sep 16  2:00s 0 -
+#
+# A small step for mankind though 8-)
+Rule	C-Eur	1945	only	-	Sep	16	 2:00s	0	-
+Rule	C-Eur	1977	1980	-	Apr	Sun>=1	 2:00s	1:00	S
+Rule	C-Eur	1977	only	-	Sep	lastSun	 2:00s	0	-
+Rule	C-Eur	1978	only	-	Oct	 1	 2:00s	0	-
+Rule	C-Eur	1979	1995	-	Sep	lastSun	 2:00s	0	-
+Rule	C-Eur	1981	max	-	Mar	lastSun	 2:00s	1:00	S
+Rule	C-Eur	1996	max	-	Oct	lastSun	 2:00s	0	-
+
+# E-Eur differs from EU only in that E-Eur switches at midnight local time.
+Rule	E-Eur	1977	1980	-	Apr	Sun>=1	 0:00	1:00	S
+Rule	E-Eur	1977	only	-	Sep	lastSun	 0:00	0	-
+Rule	E-Eur	1978	only	-	Oct	 1	 0:00	0	-
+Rule	E-Eur	1979	1995	-	Sep	lastSun	 0:00	0	-
+Rule	E-Eur	1981	max	-	Mar	lastSun	 0:00	1:00	S
+Rule	E-Eur	1996	max	-	Oct	lastSun	 0:00	0	-
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Russia	1917	only	-	Jul	 1	23:00	1:00	MST	# Moscow Summer Time
+Rule	Russia	1917	only	-	Dec	28	 0:00	0	MMT	# Moscow Mean Time
+Rule	Russia	1918	only	-	May	31	22:00	2:00	MDST	# Moscow Double Summer Time
+Rule	Russia	1918	only	-	Sep	16	 1:00	1:00	MST
+Rule	Russia	1919	only	-	May	31	23:00	2:00	MDST
+Rule	Russia	1919	only	-	Jul	 1	 2:00	1:00	S
+Rule	Russia	1919	only	-	Aug	16	 0:00	0	-
+Rule	Russia	1921	only	-	Feb	14	23:00	1:00	S
+Rule	Russia	1921	only	-	Mar	20	23:00	2:00	M # Midsummer
+Rule	Russia	1921	only	-	Sep	 1	 0:00	1:00	S
+Rule	Russia	1921	only	-	Oct	 1	 0:00	0	-
+# Act No.925 of the Council of Ministers of the USSR (1980-10-24):
+Rule	Russia	1981	1984	-	Apr	 1	 0:00	1:00	S
+Rule	Russia	1981	1983	-	Oct	 1	 0:00	0	-
+# Act No.967 of the Council of Ministers of the USSR (1984-09-13), repeated in
+# Act No.227 of the Council of Ministers of the USSR (1989-03-14):
+Rule	Russia	1984	1991	-	Sep	lastSun	 2:00s	0	-
+Rule	Russia	1985	1991	-	Mar	lastSun	 2:00s	1:00	S
+#
+Rule	Russia	1992	only	-	Mar	lastSat	 23:00	1:00	S
+Rule	Russia	1992	only	-	Sep	lastSat	 23:00	0	-
+Rule	Russia	1993	max	-	Mar	lastSun	 2:00s	1:00	S
+Rule	Russia	1993	1995	-	Sep	lastSun	 2:00s	0	-
+Rule	Russia	1996	max	-	Oct	lastSun	 2:00s	0	-
+
+# These are for backward compatibility with older versions.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	WET		0:00	EU	WE%sT
+Zone	CET		1:00	C-Eur	CE%sT
+Zone	MET		1:00	C-Eur	ME%sT
+Zone	EET		2:00	EU	EE%sT
+
+# Previous editions of this database used abbreviations like MET DST
+# for Central European Summer Time, but this didn't agree with common usage.
+
+# From Markus Kuhn (1996-07-12):
+# The official German names ... are
+#
+#	Mitteleuropaeische Zeit (MEZ)         = UTC+01:00
+#	Mitteleuropaeische Sommerzeit (MESZ)  = UTC+02:00
+#
+# as defined in the German Time Act (Gesetz ueber die Zeitbestimmung (ZeitG),
+# 1978-07-25, Bundesgesetzblatt, Jahrgang 1978, Teil I, S. 1110-1111)....
+# I wrote ... to the German Federal Physical-Technical Institution
+#
+#	Physikalisch-Technische Bundesanstalt (PTB)
+#	Laboratorium 4.41 "Zeiteinheit"
+#	Postfach 3345
+#	D-38023 Braunschweig
+#	phone: +49 531 592-0
+#
+# ... I received today an answer letter from Dr. Peter Hetzel, head of the PTB
+# department for time and frequency transmission.  He explained that the
+# PTB translates MEZ and MESZ into English as
+#
+#	Central European Time (CET)         = UTC+01:00
+#	Central European Summer Time (CEST) = UTC+02:00
+
+
+# Albania
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Albania	1940	only	-	Jun	16	0:00	1:00	S
+Rule	Albania	1942	only	-	Nov	 2	3:00	0	-
+Rule	Albania	1943	only	-	Mar	29	2:00	1:00	S
+Rule	Albania	1943	only	-	Apr	10	3:00	0	-
+Rule	Albania	1974	only	-	May	 4	0:00	1:00	S
+Rule	Albania	1974	only	-	Oct	 2	0:00	0	-
+Rule	Albania	1975	only	-	May	 1	0:00	1:00	S
+Rule	Albania	1975	only	-	Oct	 2	0:00	0	-
+Rule	Albania	1976	only	-	May	 2	0:00	1:00	S
+Rule	Albania	1976	only	-	Oct	 3	0:00	0	-
+Rule	Albania	1977	only	-	May	 8	0:00	1:00	S
+Rule	Albania	1977	only	-	Oct	 2	0:00	0	-
+Rule	Albania	1978	only	-	May	 6	0:00	1:00	S
+Rule	Albania	1978	only	-	Oct	 1	0:00	0	-
+Rule	Albania	1979	only	-	May	 5	0:00	1:00	S
+Rule	Albania	1979	only	-	Sep	30	0:00	0	-
+Rule	Albania	1980	only	-	May	 3	0:00	1:00	S
+Rule	Albania	1980	only	-	Oct	 4	0:00	0	-
+Rule	Albania	1981	only	-	Apr	26	0:00	1:00	S
+Rule	Albania	1981	only	-	Sep	27	0:00	0	-
+Rule	Albania	1982	only	-	May	 2	0:00	1:00	S
+Rule	Albania	1982	only	-	Oct	 3	0:00	0	-
+Rule	Albania	1983	only	-	Apr	18	0:00	1:00	S
+Rule	Albania	1983	only	-	Oct	 1	0:00	0	-
+Rule	Albania	1984	only	-	Apr	 1	0:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Tirane	1:19:20 -	LMT	1914
+			1:00	-	CET	1940 Jun 16
+			1:00	Albania	CE%sT	1984 Jul
+			1:00	EU	CE%sT
+
+# Andorra
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Andorra	0:06:04 -	LMT	1901
+			0:00	-	WET	1946 Sep 30
+			1:00	-	CET	1985 Mar 31 2:00
+			1:00	EU	CE%sT
+
+# Austria
+
+# From Paul Eggert (2006-03-22): Shanks & Pottenger give 1918-06-16 and
+# 1945-11-18, but the Austrian Federal Office of Metrology and
+# Surveying (BEV) gives 1918-09-16 and for Vienna gives the "alleged"
+# date of 1945-04-12 with no time.  For the 1980-04-06 transition
+# Shanks & Pottenger give 02:00, the BEV 00:00.  Go with the BEV,
+# and guess 02:00 for 1945-04-12.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Austria	1920	only	-	Apr	 5	2:00s	1:00	S
+Rule	Austria	1920	only	-	Sep	13	2:00s	0	-
+Rule	Austria	1946	only	-	Apr	14	2:00s	1:00	S
+Rule	Austria	1946	1948	-	Oct	Sun>=1	2:00s	0	-
+Rule	Austria	1947	only	-	Apr	 6	2:00s	1:00	S
+Rule	Austria	1948	only	-	Apr	18	2:00s	1:00	S
+Rule	Austria	1980	only	-	Apr	 6	0:00	1:00	S
+Rule	Austria	1980	only	-	Sep	28	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Vienna	1:05:20 -	LMT	1893 Apr
+			1:00	C-Eur	CE%sT	1920
+			1:00	Austria	CE%sT	1940 Apr  1 2:00s
+			1:00	C-Eur	CE%sT	1945 Apr  2 2:00s
+			1:00	1:00	CEST	1945 Apr 12 2:00s
+			1:00	-	CET	1946
+			1:00	Austria	CE%sT	1981
+			1:00	EU	CE%sT
+
+# Belarus
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Minsk	1:50:16 -	LMT	1880
+			1:50	-	MMT	1924 May 2 # Minsk Mean Time
+			2:00	-	EET	1930 Jun 21
+			3:00	-	MSK	1941 Jun 28
+			1:00	C-Eur	CE%sT	1944 Jul  3
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1991 Mar 31 2:00s
+			2:00	1:00	EEST	1991 Sep 29 2:00s
+			2:00	-	EET	1992 Mar 29 0:00s
+			2:00	1:00	EEST	1992 Sep 27 0:00s
+			2:00	Russia	EE%sT
+
+# Belgium
+#
+# From Paul Eggert (1997-07-02):
+# Entries from 1918 through 1991 are taken from:
+#	Annuaire de L'Observatoire Royal de Belgique,
+#	Avenue Circulaire, 3, B-1180 BRUXELLES, CLVIIe annee, 1991
+#	(Imprimerie HAYEZ, s.p.r.l., Rue Fin, 4, 1080 BRUXELLES, MCMXC),
+#	pp 8-9.
+# LMT before 1892 was 0:17:30, according to the official journal of Belgium:
+#	Moniteur Belge, Samedi 30 Avril 1892, N.121.
+# Thanks to Pascal Delmoitie for these references.
+# The 1918 rules are listed for completeness; they apply to unoccupied Belgium.
+# Assume Brussels switched to WET in 1918 when the armistice took effect.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Belgium	1918	only	-	Mar	 9	 0:00s	1:00	S
+Rule	Belgium	1918	1919	-	Oct	Sat>=1	23:00s	0	-
+Rule	Belgium	1919	only	-	Mar	 1	23:00s	1:00	S
+Rule	Belgium	1920	only	-	Feb	14	23:00s	1:00	S
+Rule	Belgium	1920	only	-	Oct	23	23:00s	0	-
+Rule	Belgium	1921	only	-	Mar	14	23:00s	1:00	S
+Rule	Belgium	1921	only	-	Oct	25	23:00s	0	-
+Rule	Belgium	1922	only	-	Mar	25	23:00s	1:00	S
+Rule	Belgium	1922	1927	-	Oct	Sat>=1	23:00s	0	-
+Rule	Belgium	1923	only	-	Apr	21	23:00s	1:00	S
+Rule	Belgium	1924	only	-	Mar	29	23:00s	1:00	S
+Rule	Belgium	1925	only	-	Apr	 4	23:00s	1:00	S
+# DSH writes that a royal decree of 1926-02-22 specified the Sun following 3rd
+# Sat in Apr (except if it's Easter, in which case it's one Sunday earlier),
+# to Sun following 1st Sat in Oct, and that a royal decree of 1928-09-15
+# changed the transition times to 02:00 GMT.
+Rule	Belgium	1926	only	-	Apr	17	23:00s	1:00	S
+Rule	Belgium	1927	only	-	Apr	 9	23:00s	1:00	S
+Rule	Belgium	1928	only	-	Apr	14	23:00s	1:00	S
+Rule	Belgium	1928	1938	-	Oct	Sun>=2	 2:00s	0	-
+Rule	Belgium	1929	only	-	Apr	21	 2:00s	1:00	S
+Rule	Belgium	1930	only	-	Apr	13	 2:00s	1:00	S
+Rule	Belgium	1931	only	-	Apr	19	 2:00s	1:00	S
+Rule	Belgium	1932	only	-	Apr	 3	 2:00s	1:00	S
+Rule	Belgium	1933	only	-	Mar	26	 2:00s	1:00	S
+Rule	Belgium	1934	only	-	Apr	 8	 2:00s	1:00	S
+Rule	Belgium	1935	only	-	Mar	31	 2:00s	1:00	S
+Rule	Belgium	1936	only	-	Apr	19	 2:00s	1:00	S
+Rule	Belgium	1937	only	-	Apr	 4	 2:00s	1:00	S
+Rule	Belgium	1938	only	-	Mar	27	 2:00s	1:00	S
+Rule	Belgium	1939	only	-	Apr	16	 2:00s	1:00	S
+Rule	Belgium	1939	only	-	Nov	19	 2:00s	0	-
+Rule	Belgium	1940	only	-	Feb	25	 2:00s	1:00	S
+Rule	Belgium	1944	only	-	Sep	17	 2:00s	0	-
+Rule	Belgium	1945	only	-	Apr	 2	 2:00s	1:00	S
+Rule	Belgium	1945	only	-	Sep	16	 2:00s	0	-
+Rule	Belgium	1946	only	-	May	19	 2:00s	1:00	S
+Rule	Belgium	1946	only	-	Oct	 7	 2:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Brussels	0:17:30 -	LMT	1880
+			0:17:30	-	BMT	1892 May  1 12:00 # Brussels MT
+			0:00	-	WET	1914 Nov  8
+			1:00	-	CET	1916 May  1  0:00
+			1:00	C-Eur	CE%sT	1918 Nov 11 11:00u
+			0:00	Belgium	WE%sT	1940 May 20  2:00s
+			1:00	C-Eur	CE%sT	1944 Sep  3
+			1:00	Belgium	CE%sT	1977
+			1:00	EU	CE%sT
+
+# Bosnia and Herzegovina
+# see Serbia
+
+# Bulgaria
+#
+# From Plamen Simenov via Steffen Thorsen (1999-09-09):
+# A document of Government of Bulgaria (No.94/1997) says:
+# EET --> EETDST is in 03:00 Local time in last Sunday of March ...
+# EETDST --> EET is in 04:00 Local time in last Sunday of October
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Bulg	1979	only	-	Mar	31	23:00	1:00	S
+Rule	Bulg	1979	only	-	Oct	 1	 1:00	0	-
+Rule	Bulg	1980	1982	-	Apr	Sat>=1	23:00	1:00	S
+Rule	Bulg	1980	only	-	Sep	29	 1:00	0	-
+Rule	Bulg	1981	only	-	Sep	27	 2:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Sofia	1:33:16 -	LMT	1880
+			1:56:56	-	IMT	1894 Nov 30 # Istanbul MT?
+			2:00	-	EET	1942 Nov  2  3:00
+			1:00	C-Eur	CE%sT	1945
+			1:00	-	CET	1945 Apr 2 3:00
+			2:00	-	EET	1979 Mar 31 23:00
+			2:00	Bulg	EE%sT	1982 Sep 26  2:00
+			2:00	C-Eur	EE%sT	1991
+			2:00	E-Eur	EE%sT	1997
+			2:00	EU	EE%sT
+
+# Croatia
+# see Serbia
+
+# Cyprus
+# Please see the `asia' file for Asia/Nicosia.
+
+# Czech Republic
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Czech	1945	only	-	Apr	 8	2:00s	1:00	S
+Rule	Czech	1945	only	-	Nov	18	2:00s	0	-
+Rule	Czech	1946	only	-	May	 6	2:00s	1:00	S
+Rule	Czech	1946	1949	-	Oct	Sun>=1	2:00s	0	-
+Rule	Czech	1947	only	-	Apr	20	2:00s	1:00	S
+Rule	Czech	1948	only	-	Apr	18	2:00s	1:00	S
+Rule	Czech	1949	only	-	Apr	 9	2:00s	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Prague	0:57:44 -	LMT	1850
+			0:57:44	-	PMT	1891 Oct     # Prague Mean Time
+			1:00	C-Eur	CE%sT	1944 Sep 17 2:00s
+			1:00	Czech	CE%sT	1979
+			1:00	EU	CE%sT
+
+# Denmark, Faroe Islands, and Greenland
+
+# From Jesper Norgaard Welen (2005-04-26):
+# http://www.hum.aau.dk/~poe/tid/tine/DanskTid.htm says that the law
+# [introducing standard time] was in effect from 1894-01-01....
+# The page http://www.retsinfo.dk/_GETDOCI_/ACCN/A18930008330-REGL
+# confirms this, and states that the law was put forth 1893-03-29.
+#
+# The EU treaty with effect from 1973:
+# http://www.retsinfo.dk/_GETDOCI_/ACCN/A19722110030-REGL
+#
+# This provoked a new law from 1974 to make possible summer time changes
+# in subsequenet decrees with the law
+# http://www.retsinfo.dk/_GETDOCI_/ACCN/A19740022330-REGL
+#
+# It seems however that no decree was set forward until 1980.  I have
+# not found any decree, but in another related law, the effecting DST
+# changes are stated explicitly to be from 1980-04-06 at 02:00 to
+# 1980-09-28 at 02:00.  If this is true, this differs slightly from
+# the EU rule in that DST runs to 02:00, not 03:00.  We don't know
+# when Denmark began using the EU rule correctly, but we have only
+# confirmation of the 1980-time, so I presume it was correct in 1981:
+# The law is about the management of the extra hour, concerning
+# working hours reported and effect on obligatory-rest rules (which
+# was suspended on that night):
+# http://www.retsinfo.dk/_GETDOCI_/ACCN/C19801120554-REGL
+
+# From Jesper Norgaard Welen (2005-06-11):
+# The Herning Folkeblad (1980-09-26) reported that the night between
+# Saturday and Sunday the clock is set back from three to two.
+
+# From Paul Eggert (2005-06-11):
+# Hence the "02:00" of the 1980 law refers to standard time, not
+# wall-clock time, and so the EU rules were in effect in 1980.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Denmark	1916	only	-	May	14	23:00	1:00	S
+Rule	Denmark	1916	only	-	Sep	30	23:00	0	-
+Rule	Denmark	1940	only	-	May	15	 0:00	1:00	S
+Rule	Denmark	1945	only	-	Apr	 2	 2:00s	1:00	S
+Rule	Denmark	1945	only	-	Aug	15	 2:00s	0	-
+Rule	Denmark	1946	only	-	May	 1	 2:00s	1:00	S
+Rule	Denmark	1946	only	-	Sep	 1	 2:00s	0	-
+Rule	Denmark	1947	only	-	May	 4	 2:00s	1:00	S
+Rule	Denmark	1947	only	-	Aug	10	 2:00s	0	-
+Rule	Denmark	1948	only	-	May	 9	 2:00s	1:00	S
+Rule	Denmark	1948	only	-	Aug	 8	 2:00s	0	-
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Europe/Copenhagen	 0:50:20 -	LMT	1890
+			 0:50:20 -	CMT	1894 Jan  1 # Copenhagen MT
+			 1:00	Denmark	CE%sT	1942 Nov  2 2:00s
+			 1:00	C-Eur	CE%sT	1945 Apr  2 2:00
+			 1:00	Denmark	CE%sT	1980
+			 1:00	EU	CE%sT
+Zone Atlantic/Faroe	-0:27:04 -	LMT	1908 Jan 11	# Torshavn
+			 0:00	-	WET	1981
+			 0:00	EU	WE%sT
+#
+# From Paul Eggert (2004-10-31):
+# During World War II, Germany maintained secret manned weather stations in
+# East Greenland and Franz Josef Land, but we don't know their time zones.
+# My source for this is Wilhelm Dege's book mentioned under Svalbard.
+#
+# From Paul Eggert (2006-03-22):
+# Greenland joined the EU as part of Denmark, obtained home rule on 1979-05-01,
+# and left the EU on 1985-02-01.  It therefore should have been using EU
+# rules at least through 1984.  Shanks & Pottenger say Scoresbysund and Godthab
+# used C-Eur rules after 1980, but IATA SSIM (1991/1996) says they use EU
+# rules since at least 1991.  Assume EU rules since 1980.
+
+# From Gwillin Law (2001-06-06), citing
+# <http://www.statkart.no/efs/efshefter/2001/efs5-2001.pdf> (2001-03-15),
+# and with translations corrected by Steffen Thorsen:
+#
+# Greenland has four local times, and the relation to UTC
+# is according to the following time line:
+#
+# The military zone near Thule	UTC-4
+# Standard Greenland time	UTC-3
+# Scoresbysund			UTC-1
+# Danmarkshavn			UTC
+#
+# In the military area near Thule and in Danmarkshavn DST will not be
+# introduced.
+
+# From Rives McDow (2001-11-01):
+#
+# I correspond regularly with the Dansk Polarcenter, and wrote them at
+# the time to clarify the situation in Thule.  Unfortunately, I have
+# not heard back from them regarding my recent letter.  [But I have
+# info from earlier correspondence.]
+#
+# According to the center, a very small local time zone around Thule
+# Air Base keeps the time according to UTC-4, implementing daylight
+# savings using North America rules, changing the time at 02:00 local time....
+#
+# The east coast of Greenland north of the community of Scoresbysund
+# uses UTC in the same way as in Iceland, year round, with no dst.
+# There are just a few stations on this coast, including the
+# Danmarkshavn ICAO weather station mentioned in your September 29th
+# email.  The other stations are two sledge patrol stations in
+# Mestersvig and Daneborg, the air force base at Station Nord, and the
+# DPC research station at Zackenberg.
+#
+# Scoresbysund and two small villages nearby keep time UTC-1 and use
+# the same daylight savings time period as in West Greenland (Godthab).
+#
+# The rest of Greenland, including Godthab (this area, although it
+# includes central Greenland, is known as west Greenland), keeps time
+# UTC-3, with daylight savings methods according to European rules.
+#
+# It is common procedure to use UTC 0 in the wilderness of East and
+# North Greenland, because it is mainly Icelandic aircraft operators
+# maintaining traffic in these areas.  However, the official status of
+# this area is that it sticks with Godthab time.  This area might be
+# considered a dual time zone in some respects because of this.
+
+# From Rives McDow (2001-11-19):
+# I heard back from someone stationed at Thule; the time change took place
+# there at 2:00 AM.
+
+# From Paul Eggert (2006-03-22):
+# From 1997 on the CIA map shows Danmarkshavn on GMT;
+# the 1995 map as like Godthab.
+# For lack of better info, assume they were like Godthab before 1996.
+# startkart.no says Thule does not observe DST, but this is clearly an error,
+# so go with Shanks & Pottenger for Thule transitions until this year.
+# For 2007 on assume Thule will stay in sync with US DST rules.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Thule	1991	1992	-	Mar	lastSun	2:00	1:00	D
+Rule	Thule	1991	1992	-	Sep	lastSun	2:00	0	S
+Rule	Thule	1993	2006	-	Apr	Sun>=1	2:00	1:00	D
+Rule	Thule	1993	2006	-	Oct	lastSun	2:00	0	S
+Rule	Thule	2007	max	-	Mar	Sun>=8	2:00	1:00	D
+Rule	Thule	2007	max	-	Nov	Sun>=1	2:00	0	S
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Danmarkshavn -1:14:40 -	LMT	1916 Jul 28
+			-3:00	-	WGT	1980 Apr  6 2:00
+			-3:00	EU	WG%sT	1996
+			0:00	-	GMT
+Zone America/Scoresbysund -1:27:52 -	LMT	1916 Jul 28 # Ittoqqortoormiit
+			-2:00	-	CGT	1980 Apr  6 2:00
+			-2:00	C-Eur	CG%sT	1981 Mar 29
+			-1:00	EU	EG%sT
+Zone America/Godthab	-3:26:56 -	LMT	1916 Jul 28 # Nuuk
+			-3:00	-	WGT	1980 Apr  6 2:00
+			-3:00	EU	WG%sT
+Zone America/Thule	-4:35:08 -	LMT	1916 Jul 28 # Pituffik air base
+			-4:00	Thule	A%sT
+
+# Estonia
+# From Peter Ilieve (1994-10-15):
+# A relative in Tallinn confirms the accuracy of the data for 1989 onwards
+# [through 1994] and gives the legal authority for it,
+# a regulation of the Government of Estonia, No. 111 of 1989....
+#
+# From Peter Ilieve (1996-10-28):
+# [IATA SSIM (1992/1996) claims that the Baltic republics switch at 01:00s,
+# but a relative confirms that Estonia still switches at 02:00s, writing:]
+# ``I do not [know] exactly but there are some little different
+# (confusing) rules for International Air and Railway Transport Schedules
+# conversion in Sunday connected with end of summer time in Estonia....
+# A discussion is running about the summer time efficiency and effect on
+# human physiology.  It seems that Estonia maybe will not change to
+# summer time next spring.''
+
+# From Peter Ilieve (1998-11-04), heavily edited:
+# <a href="http://trip.rk.ee/cgi-bin/thw?${BASE}=akt&${OOHTML}=rtd&TA=1998&TO=1&AN=1390">
+# The 1998-09-22 Estonian time law
+# </a>
+# refers to the Eighth Directive and cites the association agreement between
+# the EU and Estonia, ratified by the Estonian law (RT II 1995, 22--27, 120).
+#
+# I also asked [my relative] whether they use any standard abbreviation
+# for their standard and summer times. He says no, they use "suveaeg"
+# (summer time) and "talveaeg" (winter time).
+
+# From <a href="http://www.baltictimes.com/">The Baltic Times</a> (1999-09-09)
+# via Steffen Thorsen:
+# This year will mark the last time Estonia shifts to summer time,
+# a council of the ruling coalition announced Sept. 6....
+# But what this could mean for Estonia's chances of joining the European
+# Union are still unclear.  In 1994, the EU declared summer time compulsory
+# for all member states until 2001.  Brussels has yet to decide what to do
+# after that.
+
+# From Mart Oruaas (2000-01-29):
+# Regulation no. 301 (1999-10-12) obsoletes previous regulation
+# no. 206 (1998-09-22) and thus sticks Estonia to +02:00 GMT for all
+# the year round.  The regulation is effective 1999-11-01.
+
+# From Toomas Soome (2002-02-21):
+# The Estonian government has changed once again timezone politics.
+# Now we are using again EU rules.
+#
+# From Urmet Jaanes (2002-03-28):
+# The legislative reference is Government decree No. 84 on 2002-02-21.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Tallinn	1:39:00	-	LMT	1880
+			1:39:00	-	TMT	1918 Feb # Tallinn Mean Time
+			1:00	C-Eur	CE%sT	1919 Jul
+			1:39:00	-	TMT	1921 May
+			2:00	-	EET	1940 Aug  6
+			3:00	-	MSK	1941 Sep 15
+			1:00	C-Eur	CE%sT	1944 Sep 22
+			3:00	Russia	MSK/MSD	1989 Mar 26 2:00s
+			2:00	1:00	EEST	1989 Sep 24 2:00s
+			2:00	C-Eur	EE%sT	1998 Sep 22
+			2:00	EU	EE%sT	1999 Nov  1
+			2:00	-	EET	2002 Feb 21
+			2:00	EU	EE%sT
+
+# Finland
+#
+# From Hannu Strang (1994-09-25 06:03:37 UTC):
+# Well, here in Helsinki we're just changing from summer time to regular one,
+# and it's supposed to change at 4am...
+#
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger say Finland has switched at 02:00 standard time
+# since 1981.  Go with Strang instead.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Finland	1942	only	-	Apr	3	0:00	1:00	S
+Rule	Finland	1942	only	-	Oct	3	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Helsinki	1:39:52 -	LMT	1878 May 31
+			1:39:52	-	HMT	1921 May    # Helsinki Mean Time
+			2:00	Finland	EE%sT	1981 Mar 29 2:00
+			2:00	EU	EE%sT
+
+# Aaland Is
+Link	Europe/Helsinki	Europe/Mariehamn
+
+
+# France
+
+# From Ciro Discepolo (2000-12-20):
+#
+# Henri Le Corre, Regimes Horaires pour le monde entier, Editions
+# Traditionnelles - Paris 2 books, 1993
+#
+# Gabriel, Traite de l'heure dans le monde, Guy Tredaniel editeur,
+# Paris, 1991
+#
+# Francoise Gauquelin, Problemes de l'heure resolus en astrologie,
+# Guy tredaniel, Paris 1987
+
+
+#
+# Shank & Pottenger seem to use `24:00' ambiguously; resolve it with Whitman.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	France	1916	only	-	Jun	14	23:00s	1:00	S
+Rule	France	1916	1919	-	Oct	Sun>=1	23:00s	0	-
+Rule	France	1917	only	-	Mar	24	23:00s	1:00	S
+Rule	France	1918	only	-	Mar	 9	23:00s	1:00	S
+Rule	France	1919	only	-	Mar	 1	23:00s	1:00	S
+Rule	France	1920	only	-	Feb	14	23:00s	1:00	S
+Rule	France	1920	only	-	Oct	23	23:00s	0	-
+Rule	France	1921	only	-	Mar	14	23:00s	1:00	S
+Rule	France	1921	only	-	Oct	25	23:00s	0	-
+Rule	France	1922	only	-	Mar	25	23:00s	1:00	S
+# DSH writes that a law of 1923-05-24 specified 3rd Sat in Apr at 23:00 to 1st
+# Sat in Oct at 24:00; and that in 1930, because of Easter, the transitions
+# were Apr 12 and Oct 5.  Go with Shanks & Pottenger.
+Rule	France	1922	1938	-	Oct	Sat>=1	23:00s	0	-
+Rule	France	1923	only	-	May	26	23:00s	1:00	S
+Rule	France	1924	only	-	Mar	29	23:00s	1:00	S
+Rule	France	1925	only	-	Apr	 4	23:00s	1:00	S
+Rule	France	1926	only	-	Apr	17	23:00s	1:00	S
+Rule	France	1927	only	-	Apr	 9	23:00s	1:00	S
+Rule	France	1928	only	-	Apr	14	23:00s	1:00	S
+Rule	France	1929	only	-	Apr	20	23:00s	1:00	S
+Rule	France	1930	only	-	Apr	12	23:00s	1:00	S
+Rule	France	1931	only	-	Apr	18	23:00s	1:00	S
+Rule	France	1932	only	-	Apr	 2	23:00s	1:00	S
+Rule	France	1933	only	-	Mar	25	23:00s	1:00	S
+Rule	France	1934	only	-	Apr	 7	23:00s	1:00	S
+Rule	France	1935	only	-	Mar	30	23:00s	1:00	S
+Rule	France	1936	only	-	Apr	18	23:00s	1:00	S
+Rule	France	1937	only	-	Apr	 3	23:00s	1:00	S
+Rule	France	1938	only	-	Mar	26	23:00s	1:00	S
+Rule	France	1939	only	-	Apr	15	23:00s	1:00	S
+Rule	France	1939	only	-	Nov	18	23:00s	0	-
+Rule	France	1940	only	-	Feb	25	 2:00	1:00	S
+# The French rules for 1941-1944 were not used in Paris, but Shanks & Pottenger
+# write that they were used in Monaco and in many French locations.
+# Le Corre writes that the upper limit of the free zone was Arneguy, Orthez,
+# Mont-de-Marsan, Bazas, Langon, Lamotte-Montravel, Marouil, La
+# Rochefoucault, Champagne-Mouton, La Roche-Posay, La Haye-Decartes,
+# Loches, Montrichard, Vierzon, Bourges, Moulins, Digoin,
+# Paray-le-Monial, Montceau-les-Mines, Chalons-sur-Saone, Arbois,
+# Dole, Morez, St-Claude, and Collognes (Haute-Savioe).
+Rule	France	1941	only	-	May	 5	 0:00	2:00	M # Midsummer
+# Shanks & Pottenger say this transition occurred at Oct 6 1:00,
+# but go with Denis Excoffier (1997-12-12),
+# who quotes the Ephemerides Astronomiques for 1998 from Bureau des Longitudes
+# as saying 5/10/41 22hUT.
+Rule	France	1941	only	-	Oct	 6	 0:00	1:00	S
+Rule	France	1942	only	-	Mar	 9	 0:00	2:00	M
+Rule	France	1942	only	-	Nov	 2	 3:00	1:00	S
+Rule	France	1943	only	-	Mar	29	 2:00	2:00	M
+Rule	France	1943	only	-	Oct	 4	 3:00	1:00	S
+Rule	France	1944	only	-	Apr	 3	 2:00	2:00	M
+Rule	France	1944	only	-	Oct	 8	 1:00	1:00	S
+Rule	France	1945	only	-	Apr	 2	 2:00	2:00	M
+Rule	France	1945	only	-	Sep	16	 3:00	0	-
+# Shanks & Pottenger give Mar 28 2:00 and Sep 26 3:00;
+# go with Excoffier's 28/3/76 0hUT and 25/9/76 23hUT.
+Rule	France	1976	only	-	Mar	28	 1:00	1:00	S
+Rule	France	1976	only	-	Sep	26	 1:00	0	-
+# Shanks & Pottenger give 0:09:20 for Paris Mean Time, and Whitman 0:09:05,
+# but Howse quotes the actual French legislation as saying 0:09:21.
+# Go with Howse.  Howse writes that the time in France was officially based
+# on PMT-0:09:21 until 1978-08-09, when the time base finally switched to UTC.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Paris	0:09:21 -	LMT	1891 Mar 15  0:01
+			0:09:21	-	PMT	1911 Mar 11  0:01  # Paris MT
+# Shanks & Pottenger give 1940 Jun 14 0:00; go with Excoffier and Le Corre.
+			0:00	France	WE%sT	1940 Jun 14 23:00
+# Le Corre says Paris stuck with occupied-France time after the liberation;
+# go with Shanks & Pottenger.
+			1:00	C-Eur	CE%sT	1944 Aug 25
+			0:00	France	WE%sT	1945 Sep 16  3:00
+			1:00	France	CE%sT	1977
+			1:00	EU	CE%sT
+
+# Germany
+
+# From Markus Kuhn (1998-09-29):
+# The German time zone web site by the Physikalisch-Technische
+# Bundesanstalt contains DST information back to 1916.
+# [See tz-link.htm for the URL.]
+
+# From Joerg Schilling (2002-10-23):
+# In 1945, Berlin was switched to Moscow Summer time (GMT+4) by
+# <a href="http://www.dhm.de/lemo/html/biografien/BersarinNikolai/">
+# General [Nikolai] Bersarin</a>.
+
+# From Paul Eggert (2003-03-08):
+# <a href="http://www.parlament-berlin.de/pds-fraktion.nsf/727459127c8b66ee8525662300459099/defc77cb784f180ac1256c2b0030274b/$FILE/bersarint.pdf">
+# http://www.parlament-berlin.de/pds-fraktion.nsf/727459127c8b66ee8525662300459099/defc77cb784f180ac1256c2b0030274b/$FILE/bersarint.pdf
+# </a>
+# says that Bersarin issued an order to use Moscow time on May 20.
+# However, Moscow did not observe daylight saving in 1945, so
+# this was equivalent to CEMT (GMT+3), not GMT+4.
+
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Germany	1946	only	-	Apr	14	2:00s	1:00	S
+Rule	Germany	1946	only	-	Oct	 7	2:00s	0	-
+Rule	Germany	1947	1949	-	Oct	Sun>=1	2:00s	0	-
+# http://www.ptb.de/de/org/4/44/441/salt.htm says the following transition
+# occurred at 3:00 MEZ, not the 2:00 MEZ given in Shanks & Pottenger.
+# Go with the PTB.
+Rule	Germany	1947	only	-	Apr	 6	3:00s	1:00	S
+Rule	Germany	1947	only	-	May	11	2:00s	2:00	M
+Rule	Germany	1947	only	-	Jun	29	3:00	1:00	S
+Rule	Germany	1948	only	-	Apr	18	2:00s	1:00	S
+Rule	Germany	1949	only	-	Apr	10	2:00s	1:00	S
+
+Rule SovietZone	1945	only	-	May	24	2:00	2:00	M # Midsummer
+Rule SovietZone	1945	only	-	Sep	24	3:00	1:00	S
+Rule SovietZone	1945	only	-	Nov	18	2:00s	0	-
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Berlin	0:53:28 -	LMT	1893 Apr
+			1:00	C-Eur	CE%sT	1945 May 24 2:00
+			1:00 SovietZone	CE%sT	1946
+			1:00	Germany	CE%sT	1980
+			1:00	EU	CE%sT
+
+# Georgia
+# Please see the "asia" file for Asia/Tbilisi.
+# Herodotus (Histories, IV.45) says Georgia north of the Phasis (now Rioni)
+# is in Europe.  Our reference location Tbilisi is in the Asian part.
+
+# Gibraltar
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Europe/Gibraltar	-0:21:24 -	LMT	1880 Aug  2 0:00s
+			0:00	GB-Eire	%s	1957 Apr 14 2:00
+			1:00	-	CET	1982
+			1:00	EU	CE%sT
+
+# Greece
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# Whitman gives 1932 Jul 5 - Nov 1; go with Shanks & Pottenger.
+Rule	Greece	1932	only	-	Jul	 7	0:00	1:00	S
+Rule	Greece	1932	only	-	Sep	 1	0:00	0	-
+# Whitman gives 1941 Apr 25 - ?; go with Shanks & Pottenger.
+Rule	Greece	1941	only	-	Apr	 7	0:00	1:00	S
+# Whitman gives 1942 Feb 2 - ?; go with Shanks & Pottenger.
+Rule	Greece	1942	only	-	Nov	 2	3:00	0	-
+Rule	Greece	1943	only	-	Mar	30	0:00	1:00	S
+Rule	Greece	1943	only	-	Oct	 4	0:00	0	-
+# Whitman gives 1944 Oct 3 - Oct 31; go with Shanks & Pottenger.
+Rule	Greece	1952	only	-	Jul	 1	0:00	1:00	S
+Rule	Greece	1952	only	-	Nov	 2	0:00	0	-
+Rule	Greece	1975	only	-	Apr	12	0:00s	1:00	S
+Rule	Greece	1975	only	-	Nov	26	0:00s	0	-
+Rule	Greece	1976	only	-	Apr	11	2:00s	1:00	S
+Rule	Greece	1976	only	-	Oct	10	2:00s	0	-
+Rule	Greece	1977	1978	-	Apr	Sun>=1	2:00s	1:00	S
+Rule	Greece	1977	only	-	Sep	26	2:00s	0	-
+Rule	Greece	1978	only	-	Sep	24	4:00	0	-
+Rule	Greece	1979	only	-	Apr	 1	9:00	1:00	S
+Rule	Greece	1979	only	-	Sep	29	2:00	0	-
+Rule	Greece	1980	only	-	Apr	 1	0:00	1:00	S
+Rule	Greece	1980	only	-	Sep	28	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Athens	1:34:52 -	LMT	1895 Sep 14
+			1:34:52	-	AMT	1916 Jul 28 0:01     # Athens MT
+			2:00	Greece	EE%sT	1941 Apr 30
+			1:00	Greece	CE%sT	1944 Apr  4
+			2:00	Greece	EE%sT	1981
+			# Shanks & Pottenger say it switched to C-Eur in 1981;
+			# go with EU instead, since Greece joined it on Jan 1.
+			2:00	EU	EE%sT
+
+# Hungary
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Hungary	1918	only	-	Apr	 1	 3:00	1:00	S
+Rule	Hungary	1918	only	-	Sep	29	 3:00	0	-
+Rule	Hungary	1919	only	-	Apr	15	 3:00	1:00	S
+Rule	Hungary	1919	only	-	Sep	15	 3:00	0	-
+Rule	Hungary	1920	only	-	Apr	 5	 3:00	1:00	S
+Rule	Hungary	1920	only	-	Sep	30	 3:00	0	-
+Rule	Hungary	1945	only	-	May	 1	23:00	1:00	S
+Rule	Hungary	1945	only	-	Nov	 3	 0:00	0	-
+Rule	Hungary	1946	only	-	Mar	31	 2:00s	1:00	S
+Rule	Hungary	1946	1949	-	Oct	Sun>=1	 2:00s	0	-
+Rule	Hungary	1947	1949	-	Apr	Sun>=4	 2:00s	1:00	S
+Rule	Hungary	1950	only	-	Apr	17	 2:00s	1:00	S
+Rule	Hungary	1950	only	-	Oct	23	 2:00s	0	-
+Rule	Hungary	1954	1955	-	May	23	 0:00	1:00	S
+Rule	Hungary	1954	1955	-	Oct	 3	 0:00	0	-
+Rule	Hungary	1956	only	-	Jun	Sun>=1	 0:00	1:00	S
+Rule	Hungary	1956	only	-	Sep	lastSun	 0:00	0	-
+Rule	Hungary	1957	only	-	Jun	Sun>=1	 1:00	1:00	S
+Rule	Hungary	1957	only	-	Sep	lastSun	 3:00	0	-
+Rule	Hungary	1980	only	-	Apr	 6	 1:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Budapest	1:16:20 -	LMT	1890 Oct
+			1:00	C-Eur	CE%sT	1918
+			1:00	Hungary	CE%sT	1941 Apr  6  2:00
+			1:00	C-Eur	CE%sT	1945
+			1:00	Hungary	CE%sT	1980 Sep 28  2:00s
+			1:00	EU	CE%sT
+
+# Iceland
+#
+# From Adam David (1993-11-06):
+# The name of the timezone in Iceland for system / mail / news purposes is GMT.
+#
+# (1993-12-05):
+# This material is paraphrased from the 1988 edition of the University of
+# Iceland Almanak.
+#
+# From January 1st, 1908 the whole of Iceland was standardised at 1 hour
+# behind GMT. Previously, local mean solar time was used in different parts
+# of Iceland, the almanak had been based on Reykjavik mean solar time which
+# was 1 hour and 28 minutes behind GMT.
+#
+# "first day of winter" referred to [below] means the first day of the 26 weeks
+# of winter, according to the old icelandic calendar that dates back to the
+# time the norsemen first settled Iceland.  The first day of winter is always
+# Saturday, but is not dependent on the Julian or Gregorian calendars.
+#
+# (1993-12-10):
+# I have a reference from the Oxford Icelandic-English dictionary for the
+# beginning of winter, which ties it to the ecclesiastical calendar (and thus
+# to the julian/gregorian calendar) over the period in question.
+#	the winter begins on the Saturday next before St. Luke's day
+#	(old style), or on St. Luke's day, if a Saturday.
+# St. Luke's day ought to be traceable from ecclesiastical sources. "old style"
+# might be a reference to the Julian calendar as opposed to Gregorian, or it
+# might mean something else (???).
+#
+# From Paul Eggert (2006-03-22):
+# The Iceland Almanak, Shanks & Pottenger, and Whitman disagree on many points.
+# We go with the Almanak, except for one claim from Shanks & Pottenger, namely
+# that Reykavik was 21W57 from 1837 to 1908, local mean time before that.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Iceland	1917	1918	-	Feb	19	23:00	1:00	S
+Rule	Iceland	1917	only	-	Oct	21	 1:00	0	-
+Rule	Iceland	1918	only	-	Nov	16	 1:00	0	-
+Rule	Iceland	1939	only	-	Apr	29	23:00	1:00	S
+Rule	Iceland	1939	only	-	Nov	29	 2:00	0	-
+Rule	Iceland	1940	only	-	Feb	25	 2:00	1:00	S
+Rule	Iceland	1940	only	-	Nov	 3	 2:00	0	-
+Rule	Iceland	1941	only	-	Mar	 2	 1:00s	1:00	S
+Rule	Iceland	1941	only	-	Nov	 2	 1:00s	0	-
+Rule	Iceland	1942	only	-	Mar	 8	 1:00s	1:00	S
+Rule	Iceland	1942	only	-	Oct	25	 1:00s	0	-
+# 1943-1946 - first Sunday in March until first Sunday in winter
+Rule	Iceland	1943	1946	-	Mar	Sun>=1	 1:00s	1:00	S
+Rule	Iceland	1943	1948	-	Oct	Sun>=22	 1:00s	0	-
+# 1947-1967 - first Sunday in April until first Sunday in winter
+Rule	Iceland	1947	1967	-	Apr	Sun>=1	 1:00s	1:00	S
+# 1949 Oct transition delayed by 1 week
+Rule	Iceland	1949	only	-	Oct	30	 1:00s	0	-
+Rule	Iceland	1950	1966	-	Oct	Sun>=22	 1:00s	0	-
+Rule	Iceland	1967	only	-	Oct	29	 1:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Atlantic/Reykjavik	-1:27:24 -	LMT	1837
+			-1:27:48 -	RMT	1908 # Reykjavik Mean Time?
+			-1:00	Iceland	IS%sT	1968 Apr 7 1:00s
+			 0:00	-	GMT
+
+# Italy
+#
+# From Paul Eggert (2001-03-06):
+# Sicily and Sardinia each had their own time zones from 1866 to 1893,
+# called Palermo Time (+00:53:28) and Cagliari Time (+00:36:32).
+# During World War II, German-controlled Italy used German time.
+# But these events all occurred before the 1970 cutoff,
+# so record only the time in Rome.
+#
+# From Paul Eggert (2006-03-22):
+# For Italian DST we have three sources: Shanks & Pottenger, Whitman, and
+# F. Pollastri
+# <a href="http://toi.iriti.cnr.it/uk/ienitlt.html">
+# Day-light Saving Time in Italy (2006-02-03)
+# </a>
+# (`FP' below), taken from an Italian National Electrotechnical Institute
+# publication. When the three sources disagree, guess who's right, as follows:
+#
+# year	FP	Shanks&P. (S)	Whitman (W)	Go with:
+# 1916	06-03	06-03 24:00	06-03 00:00	FP & W
+#	09-30	09-30 24:00	09-30 01:00	FP; guess 24:00s
+# 1917	04-01	03-31 24:00	03-31 00:00	FP & S
+#	09-30	09-29 24:00	09-30 01:00	FP & W
+# 1918	03-09	03-09 24:00	03-09 00:00	FP & S
+#	10-06	10-05 24:00	10-06 01:00	FP & W
+# 1919	03-01	03-01 24:00	03-01 00:00	FP & S
+#	10-04	10-04 24:00	10-04 01:00	FP; guess 24:00s
+# 1920	03-20	03-20 24:00	03-20 00:00	FP & S
+#	09-18	09-18 24:00	10-01 01:00	FP; guess 24:00s
+# 1944	04-02	04-03 02:00			S (see C-Eur)
+#	09-16	10-02 03:00			FP; guess 24:00s
+# 1945	09-14	09-16 24:00			FP; guess 24:00s
+# 1970	05-21	05-31 00:00			S
+#	09-20	09-27 00:00			S
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Italy	1916	only	-	Jun	 3	0:00s	1:00	S
+Rule	Italy	1916	only	-	Oct	 1	0:00s	0	-
+Rule	Italy	1917	only	-	Apr	 1	0:00s	1:00	S
+Rule	Italy	1917	only	-	Sep	30	0:00s	0	-
+Rule	Italy	1918	only	-	Mar	10	0:00s	1:00	S
+Rule	Italy	1918	1919	-	Oct	Sun>=1	0:00s	0	-
+Rule	Italy	1919	only	-	Mar	 2	0:00s	1:00	S
+Rule	Italy	1920	only	-	Mar	21	0:00s	1:00	S
+Rule	Italy	1920	only	-	Sep	19	0:00s	0	-
+Rule	Italy	1940	only	-	Jun	15	0:00s	1:00	S
+Rule	Italy	1944	only	-	Sep	17	0:00s	0	-
+Rule	Italy	1945	only	-	Apr	 2	2:00	1:00	S
+Rule	Italy	1945	only	-	Sep	15	0:00s	0	-
+Rule	Italy	1946	only	-	Mar	17	2:00s	1:00	S
+Rule	Italy	1946	only	-	Oct	 6	2:00s	0	-
+Rule	Italy	1947	only	-	Mar	16	0:00s	1:00	S
+Rule	Italy	1947	only	-	Oct	 5	0:00s	0	-
+Rule	Italy	1948	only	-	Feb	29	2:00s	1:00	S
+Rule	Italy	1948	only	-	Oct	 3	2:00s	0	-
+Rule	Italy	1966	1968	-	May	Sun>=22	0:00	1:00	S
+Rule	Italy	1966	1969	-	Sep	Sun>=22	0:00	0	-
+Rule	Italy	1969	only	-	Jun	 1	0:00	1:00	S
+Rule	Italy	1970	only	-	May	31	0:00	1:00	S
+Rule	Italy	1970	only	-	Sep	lastSun	0:00	0	-
+Rule	Italy	1971	1972	-	May	Sun>=22	0:00	1:00	S
+Rule	Italy	1971	only	-	Sep	lastSun	1:00	0	-
+Rule	Italy	1972	only	-	Oct	 1	0:00	0	-
+Rule	Italy	1973	only	-	Jun	 3	0:00	1:00	S
+Rule	Italy	1973	1974	-	Sep	lastSun	0:00	0	-
+Rule	Italy	1974	only	-	May	26	0:00	1:00	S
+Rule	Italy	1975	only	-	Jun	 1	0:00s	1:00	S
+Rule	Italy	1975	1977	-	Sep	lastSun	0:00s	0	-
+Rule	Italy	1976	only	-	May	30	0:00s	1:00	S
+Rule	Italy	1977	1979	-	May	Sun>=22	0:00s	1:00	S
+Rule	Italy	1978	only	-	Oct	 1	0:00s	0	-
+Rule	Italy	1979	only	-	Sep	30	0:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Rome	0:49:56 -	LMT	1866 Sep 22
+			0:49:56	-	RMT	1893 Nov  1 0:00s # Rome Mean
+			1:00	Italy	CE%sT	1942 Nov  2 2:00s
+			1:00	C-Eur	CE%sT	1944 Jul
+			1:00	Italy	CE%sT	1980
+			1:00	EU	CE%sT
+
+Link	Europe/Rome	Europe/Vatican
+Link	Europe/Rome	Europe/San_Marino
+
+# Latvia
+
+# From Liene Kanepe (1998-09-17):
+
+# I asked about this matter Scientific Secretary of the Institute of Astronomy
+# of The University of Latvia Dr. paed Mr. Ilgonis Vilks. I also searched the
+# correct data in juridical acts and I found some juridical documents about
+# changes in the counting of time in Latvia from 1981....
+#
+# Act No.35 of the Council of Ministers of Latvian SSR of 1981-01-22 ...
+# according to the Act No.925 of the Council of Ministers of USSR of 1980-10-24
+# ...: all year round the time of 2nd time zone + 1 hour, in addition turning
+# the hands of the clock 1 hour forward on 1 April at 00:00 (GMT 31 March 21:00)
+# and 1 hour backward on the 1 October at 00:00 (GMT 30 September 20:00).
+#
+# Act No.592 of the Council of Ministers of Latvian SSR of 1984-09-24 ...
+# according to the Act No.967 of the Council of Ministers of USSR of 1984-09-13
+# ...: all year round the time of 2nd time zone + 1 hour, in addition turning
+# the hands of the clock 1 hour forward on the last Sunday of March at 02:00
+# (GMT 23:00 on the previous day) and 1 hour backward on the last Sunday of
+# September at 03:00 (GMT 23:00 on the previous day).
+#
+# Act No.81 of the Council of Ministers of Latvian SSR of 1989-03-22 ...
+# according to the Act No.227 of the Council of Ministers of USSR of 1989-03-14
+# ...: since the last Sunday of March 1989 in Lithuanian SSR, Latvian SSR,
+# Estonian SSR and Kaliningrad region of Russian Federation all year round the
+# time of 2nd time zone (Moscow time minus one hour). On the territory of Latvia
+# transition to summer time is performed on the last Sunday of March at 02:00
+# (GMT 00:00), turning the hands of the clock 1 hour forward.  The end of
+# daylight saving time is performed on the last Sunday of September at 03:00
+# (GMT 00:00), turning the hands of the clock 1 hour backward. Exception is
+# 1989-03-26, when we must not turn the hands of the clock....
+#
+# The Regulations of the Cabinet of Ministers of the Republic of Latvia of
+# 1997-01-21 on transition to Summer time ... established the same order of
+# daylight savings time settings as in the States of the European Union.
+
+# From Andrei Ivanov (2000-03-06):
+# This year Latvia will not switch to Daylight Savings Time (as specified in
+# <a href="http://www.lv-laiks.lv/wwwraksti/2000/071072/vd4.htm">
+# The Regulations of the Cabinet of Ministers of the Rep. of Latvia of
+# 29-Feb-2000 (#79)</a>, in Latvian for subscribers only).
+
+# <a href="http://www.rferl.org/newsline/2001/01/3-CEE/cee-030101.html">
+# From RFE/RL Newsline (2001-01-03), noted after a heads-up by Rives McDow:
+# </a>
+# The Latvian government on 2 January decided that the country will
+# institute daylight-saving time this spring, LETA reported.
+# Last February the three Baltic states decided not to turn back their
+# clocks one hour in the spring....
+# Minister of Economy Aigars Kalvitis noted that Latvia had too few
+# daylight hours and thus decided to comply with a draft European
+# Commission directive that provides for instituting daylight-saving
+# time in EU countries between 2002 and 2006. The Latvian government
+# urged Lithuania and Estonia to adopt a similar time policy, but it
+# appears that they will not do so....
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Latvia	1989	1996	-	Mar	lastSun	 2:00s	1:00	S
+Rule	Latvia	1989	1996	-	Sep	lastSun	 2:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Riga	1:36:24	-	LMT	1880
+			1:36:24	-	RMT	1918 Apr 15 2:00 #Riga Mean Time
+			1:36:24	1:00	LST	1918 Sep 16 3:00 #Latvian Summer
+			1:36:24	-	RMT	1919 Apr  1 2:00
+			1:36:24	1:00	LST	1919 May 22 3:00
+			1:36:24	-	RMT	1926 May 11
+			2:00	-	EET	1940 Aug  5
+			3:00	-	MSK	1941 Jul
+			1:00	C-Eur	CE%sT	1944 Oct 13
+			3:00	Russia	MSK/MSD	1989 Mar lastSun 2:00s
+			2:00	1:00	EEST	1989 Sep lastSun 2:00s
+			2:00	Latvia	EE%sT	1997 Jan 21
+			2:00	EU	EE%sT	2000 Feb 29
+			2:00	-	EET	2001 Jan  2
+			2:00	EU	EE%sT
+
+# Liechtenstein
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Vaduz	0:38:04 -	LMT	1894 Jun
+			1:00	-	CET	1981
+			1:00	EU	CE%sT
+
+# Lithuania
+
+# From Paul Eggert (1996-11-22):
+# IATA SSIM (1992/1996) says Lithuania uses W-Eur rules, but since it is
+# known to be wrong about Estonia and Latvia, assume it's wrong here too.
+
+# From Marius Gedminas (1998-08-07):
+# I would like to inform that in this year Lithuanian time zone
+# (Europe/Vilnius) was changed.
+
+# From <a href="http://www.elta.lt/">ELTA</a> No. 972 (2582) (1999-09-29),
+# via Steffen Thorsen:
+# Lithuania has shifted back to the second time zone (GMT plus two hours)
+# to be valid here starting from October 31,
+# as decided by the national government on Wednesday....
+# The Lithuanian government also announced plans to consider a
+# motion to give up shifting to summer time in spring, as it was
+# already done by Estonia.
+
+# From the <a href="http://www.tourism.lt/informa/ff.htm">
+# Fact File, Lithuanian State Department of Tourism
+# </a> (2000-03-27): Local time is GMT+2 hours ..., no daylight saving.
+
+# From a user via Klaus Marten (2003-02-07):
+# As a candidate for membership of the European Union, Lithuania will
+# observe Summer Time in 2003, changing its clocks at the times laid
+# down in EU Directive 2000/84 of 19.I.01 (i.e. at the same times as its
+# neighbour Latvia). The text of the Lithuanian government Order of
+# 7.XI.02 to this effect can be found at
+# http://www.lrvk.lt/nut/11/n1749.htm
+
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Vilnius	1:41:16	-	LMT	1880
+			1:24:00	-	WMT	1917	    # Warsaw Mean Time
+			1:35:36	-	KMT	1919 Oct 10 # Kaunas Mean Time
+			1:00	-	CET	1920 Jul 12
+			2:00	-	EET	1920 Oct  9
+			1:00	-	CET	1940 Aug  3
+			3:00	-	MSK	1941 Jun 24
+			1:00	C-Eur	CE%sT	1944 Aug
+			3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
+			2:00	1:00	EEST	1991 Sep 29 2:00s
+			2:00	C-Eur	EE%sT	1998
+			2:00	-	EET	1998 Mar 29 1:00u
+			1:00	EU	CE%sT	1999 Oct 31 1:00u
+			2:00	-	EET	2003 Jan  1
+			2:00	EU	EE%sT
+
+# Luxembourg
+# Whitman disagrees with most of these dates in minor ways;
+# go with Shanks & Pottenger.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Lux	1916	only	-	May	14	23:00	1:00	S
+Rule	Lux	1916	only	-	Oct	 1	 1:00	0	-
+Rule	Lux	1917	only	-	Apr	28	23:00	1:00	S
+Rule	Lux	1917	only	-	Sep	17	 1:00	0	-
+Rule	Lux	1918	only	-	Apr	Mon>=15	 2:00s	1:00	S
+Rule	Lux	1918	only	-	Sep	Mon>=15	 2:00s	0	-
+Rule	Lux	1919	only	-	Mar	 1	23:00	1:00	S
+Rule	Lux	1919	only	-	Oct	 5	 3:00	0	-
+Rule	Lux	1920	only	-	Feb	14	23:00	1:00	S
+Rule	Lux	1920	only	-	Oct	24	 2:00	0	-
+Rule	Lux	1921	only	-	Mar	14	23:00	1:00	S
+Rule	Lux	1921	only	-	Oct	26	 2:00	0	-
+Rule	Lux	1922	only	-	Mar	25	23:00	1:00	S
+Rule	Lux	1922	only	-	Oct	Sun>=2	 1:00	0	-
+Rule	Lux	1923	only	-	Apr	21	23:00	1:00	S
+Rule	Lux	1923	only	-	Oct	Sun>=2	 2:00	0	-
+Rule	Lux	1924	only	-	Mar	29	23:00	1:00	S
+Rule	Lux	1924	1928	-	Oct	Sun>=2	 1:00	0	-
+Rule	Lux	1925	only	-	Apr	 5	23:00	1:00	S
+Rule	Lux	1926	only	-	Apr	17	23:00	1:00	S
+Rule	Lux	1927	only	-	Apr	 9	23:00	1:00	S
+Rule	Lux	1928	only	-	Apr	14	23:00	1:00	S
+Rule	Lux	1929	only	-	Apr	20	23:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Europe/Luxembourg	0:24:36 -	LMT	1904 Jun
+			1:00	Lux	CE%sT	1918 Nov 25
+			0:00	Lux	WE%sT	1929 Oct  6 2:00s
+			0:00	Belgium	WE%sT	1940 May 14 3:00
+			1:00	C-Eur	WE%sT	1944 Sep 18 3:00
+			1:00	Belgium	CE%sT	1977
+			1:00	EU	CE%sT
+
+# Macedonia
+# see Serbia
+
+# Malta
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Malta	1973	only	-	Mar	31	0:00s	1:00	S
+Rule	Malta	1973	only	-	Sep	29	0:00s	0	-
+Rule	Malta	1974	only	-	Apr	21	0:00s	1:00	S
+Rule	Malta	1974	only	-	Sep	16	0:00s	0	-
+Rule	Malta	1975	1979	-	Apr	Sun>=15	2:00	1:00	S
+Rule	Malta	1975	1980	-	Sep	Sun>=15	2:00	0	-
+Rule	Malta	1980	only	-	Mar	31	2:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Malta	0:58:04 -	LMT	1893 Nov  2 0:00s # Valletta
+			1:00	Italy	CE%sT	1942 Nov  2 2:00s
+			1:00	C-Eur	CE%sT	1945 Apr  2 2:00s
+			1:00	Italy	CE%sT	1973 Mar 31
+			1:00	Malta	CE%sT	1981
+			1:00	EU	CE%sT
+
+# Moldova
+
+# From Paul Eggert (2006-03-22):
+# A previous version of this database followed Shanks & Pottenger, who write
+# that Tiraspol switched to Moscow time on 1992-01-19 at 02:00.
+# However, this is most likely an error, as Moldova declared independence
+# on 1991-08-27 (the 1992-01-19 date is that of a Russian decree).
+# In early 1992 there was large-scale interethnic violence in the area
+# and it's possible that some Russophones continued to observe Moscow time.
+# But [two people] separately reported via
+# Jesper Norgaard that as of 2001-01-24 Tiraspol was like Chisinau.
+# The Tiraspol entry has therefore been removed for now.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Chisinau	1:55:20 -	LMT	1880
+			1:55	-	CMT	1918 Feb 15 # Chisinau MT
+			1:44:24	-	BMT	1931 Jul 24 # Bucharest MT
+			2:00	Romania	EE%sT	1940 Aug 15
+			2:00	1:00	EEST	1941 Jul 17
+			1:00	C-Eur	CE%sT	1944 Aug 24
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1990 May 6
+			2:00	-	EET	1991
+			2:00	Russia	EE%sT	1992
+			2:00	E-Eur	EE%sT	1997
+# See Romania commentary for the guessed 1997 transition to EU rules.
+			2:00	EU	EE%sT
+
+# Monaco
+# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
+# more precise 0:09:21.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Monaco	0:29:32 -	LMT	1891 Mar 15
+			0:09:21	-	PMT	1911 Mar 11    # Paris Mean Time
+			0:00	France	WE%sT	1945 Sep 16 3:00
+			1:00	France	CE%sT	1977
+			1:00	EU	CE%sT
+
+# Montenegro
+# see Serbia
+
+# Netherlands
+
+# Howse writes that the Netherlands' railways used GMT between 1892 and 1940,
+# but for other purposes the Netherlands used Amsterdam mean time.
+
+# However, Robert H. van Gent writes (2001-04-01):
+# Howse's statement is only correct up to 1909. From 1909-05-01 (00:00:00
+# Amsterdam mean time) onwards, the whole of the Netherlands (including
+# the Dutch railways) was required by law to observe Amsterdam mean time
+# (19 minutes 32.13 seconds ahead of GMT). This had already been the
+# common practice (except for the railways) for many decades but it was
+# not until 1909 when the Dutch government finally defined this by law.
+# On 1937-07-01 this was changed to 20 minutes (exactly) ahead of GMT and
+# was generally known as Dutch Time ("Nederlandse Tijd").
+#
+# (2001-04-08):
+# 1892-05-01 was the date when the Dutch railways were by law required to
+# observe GMT while the remainder of the Netherlands adhered to the common
+# practice of following Amsterdam mean time.
+#
+# (2001-04-09):
+# In 1835 the authorities of the province of North Holland requested the
+# municipal authorities of the towns and cities in the province to observe
+# Amsterdam mean time but I do not know in how many cases this request was
+# actually followed.
+#
+# From 1852 onwards the Dutch telegraph offices were by law required to
+# observe Amsterdam mean time. As the time signals from the observatory of
+# Leiden were also distributed by the telegraph system, I assume that most
+# places linked up with the telegraph (and railway) system automatically
+# adopted Amsterdam mean time.
+#
+# Although the early Dutch railway companies initially observed a variety
+# of times, most of them had adopted Amsterdam mean time by 1858 but it
+# was not until 1866 when they were all required by law to observe
+# Amsterdam mean time.
+
+# The data before 1945 are taken from
+# <http://www.phys.uu.nl/~vgent/wettijd/wettijd.htm>.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Neth	1916	only	-	May	 1	0:00	1:00	NST	# Netherlands Summer Time
+Rule	Neth	1916	only	-	Oct	 1	0:00	0	AMT	# Amsterdam Mean Time
+Rule	Neth	1917	only	-	Apr	16	2:00s	1:00	NST
+Rule	Neth	1917	only	-	Sep	17	2:00s	0	AMT
+Rule	Neth	1918	1921	-	Apr	Mon>=1	2:00s	1:00	NST
+Rule	Neth	1918	1921	-	Sep	lastMon	2:00s	0	AMT
+Rule	Neth	1922	only	-	Mar	lastSun	2:00s	1:00	NST
+Rule	Neth	1922	1936	-	Oct	Sun>=2	2:00s	0	AMT
+Rule	Neth	1923	only	-	Jun	Fri>=1	2:00s	1:00	NST
+Rule	Neth	1924	only	-	Mar	lastSun	2:00s	1:00	NST
+Rule	Neth	1925	only	-	Jun	Fri>=1	2:00s	1:00	NST
+# From 1926 through 1939 DST began 05-15, except that it was delayed by a week
+# in years when 05-15 fell in the Pentecost weekend.
+Rule	Neth	1926	1931	-	May	15	2:00s	1:00	NST
+Rule	Neth	1932	only	-	May	22	2:00s	1:00	NST
+Rule	Neth	1933	1936	-	May	15	2:00s	1:00	NST
+Rule	Neth	1937	only	-	May	22	2:00s	1:00	NST
+Rule	Neth	1937	only	-	Jul	 1	0:00	1:00	S
+Rule	Neth	1937	1939	-	Oct	Sun>=2	2:00s	0	-
+Rule	Neth	1938	1939	-	May	15	2:00s	1:00	S
+Rule	Neth	1945	only	-	Apr	 2	2:00s	1:00	S
+Rule	Neth	1945	only	-	Sep	16	2:00s	0	-
+#
+# Amsterdam Mean Time was +00:19:32.13 exactly, but the .13 is omitted
+# below because the current format requires GMTOFF to be an integer.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Europe/Amsterdam	0:19:32 -	LMT	1835
+			0:19:32	Neth	%s	1937 Jul  1
+			0:20	Neth	NE%sT	1940 May 16 0:00 # Dutch Time
+			1:00	C-Eur	CE%sT	1945 Apr  2 2:00
+			1:00	Neth	CE%sT	1977
+			1:00	EU	CE%sT
+
+# Norway
+# http://met.no/met/met_lex/q_u/sommertid.html (2004-01) agrees with Shanks &
+# Pottenger.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Norway	1916	only	-	May	22	1:00	1:00	S
+Rule	Norway	1916	only	-	Sep	30	0:00	0	-
+Rule	Norway	1945	only	-	Apr	 2	2:00s	1:00	S
+Rule	Norway	1945	only	-	Oct	 1	2:00s	0	-
+Rule	Norway	1959	1964	-	Mar	Sun>=15	2:00s	1:00	S
+Rule	Norway	1959	1965	-	Sep	Sun>=15	2:00s	0	-
+Rule	Norway	1965	only	-	Apr	25	2:00s	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Oslo	0:43:00 -	LMT	1895 Jan  1
+			1:00	Norway	CE%sT	1940 Aug 10 23:00
+			1:00	C-Eur	CE%sT	1945 Apr  2  2:00
+			1:00	Norway	CE%sT	1980
+			1:00	EU	CE%sT
+
+# Svalbard & Jan Mayen
+
+# From Steffen Thorsen (2001-05-01):
+# Although I could not find it explicitly, it seems that Jan Mayen and
+# Svalbard have been using the same time as Norway at least since the
+# time they were declared as parts of Norway.  Svalbard was declared
+# as a part of Norway by law of 1925-07-17 no 11, section 4 and Jan
+# Mayen by law of 1930-02-27 no 2, section 2. (From
+# http://www.lovdata.no/all/nl-19250717-011.html and
+# http://www.lovdata.no/all/nl-19300227-002.html).  The law/regulation
+# for normal/standard time in Norway is from 1894-06-29 no 1 (came
+# into operation on 1895-01-01) and Svalbard/Jan Mayen seem to be a
+# part of this law since 1925/1930. (From
+# http://www.lovdata.no/all/nl-18940629-001.html ) I have not been
+# able to find if Jan Mayen used a different time zone (e.g. -0100)
+# before 1930. Jan Mayen has only been "inhabitated" since 1921 by
+# Norwegian meteorologists and maybe used the same time as Norway ever
+# since 1921.  Svalbard (Arctic/Longyearbyen) has been inhabited since
+# before 1895, and therefore probably changed the local time somewhere
+# between 1895 and 1925 (inclusive).
+
+# From Paul Eggert (2001-05-01):
+#
+# Actually, Jan Mayen was never occupied by Germany during World War II,
+# so it must have diverged from Oslo time during the war, as Oslo was
+# keeping Berlin time.
+#
+# <http://home.no.net/janmayen/history.htm> says that the meteorologists
+# burned down their station in 1940 and left the island, but returned in
+# 1941 with a small Norwegian garrison and continued operations despite
+# frequent air ttacks from Germans.  In 1943 the Americans established a
+# radiolocating station on the island, called "Atlantic City".  Possibly
+# the UTC offset changed during the war, but I think it unlikely that
+# Jan Mayen used German daylight-saving rules.
+#
+# Svalbard is more complicated, as it was raided in August 1941 by an
+# Allied party that evacuated the civilian population to England (says
+# <http://www.bartleby.com/65/sv/Svalbard.html>).  The Svalbard FAQ
+# <http://www.svalbard.com/SvalbardFAQ.html> says that the Germans were
+# expelled on 1942-05-14.  However, small parties of Germans did return,
+# and according to Wilhelm Dege's book "War North of 80" (1954)
+# <http://www.ucalgary.ca/UofC/departments/UP/1-55238/1-55238-110-2.html>
+# the German armed forces at the Svalbard weather station code-named
+# Haudegen did not surrender to the Allies until September 1945.
+#
+# All these events predate our cutoff date of 1970.  Unless we can
+# come up with more definitive info about the timekeeping during the
+# war years it's probably best just do do the following for now:
+Link	Europe/Oslo	Arctic/Longyearbyen
+
+# Poland
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Poland	1918	1919	-	Sep	16	2:00s	0	-
+Rule	Poland	1919	only	-	Apr	15	2:00s	1:00	S
+Rule	Poland	1944	only	-	Apr	 3	2:00s	1:00	S
+# Whitman gives 1944 Nov 30; go with Shanks & Pottenger.
+Rule	Poland	1944	only	-	Oct	 4	2:00	0	-
+# For 1944-1948 Whitman gives the previous day; go with Shanks & Pottenger.
+Rule	Poland	1945	only	-	Apr	29	0:00	1:00	S
+Rule	Poland	1945	only	-	Nov	 1	0:00	0	-
+# For 1946 on the source is Kazimierz Borkowski,
+# Torun Center for Astronomy, Dept. of Radio Astronomy, Nicolaus Copernicus U.,
+# <http://www.astro.uni.torun.pl/~kb/Artykuly/U-PA/Czas2.htm#tth_tAb1>
+# Thanks to Przemyslaw Augustyniak (2005-05-28) for this reference.
+# He also gives these further references:
+# Mon Pol nr 13, poz 162 (1995) <http://www.abc.com.pl/serwis/mp/1995/0162.htm>
+# Druk nr 2180 (2003) <http://www.senat.gov.pl/k5/dok/sejm/053/2180.pdf>
+Rule	Poland	1946	only	-	Apr	14	0:00s	1:00	S
+Rule	Poland	1946	only	-	Oct	 7	2:00s	0	-
+Rule	Poland	1947	only	-	May	 4	2:00s	1:00	S
+Rule	Poland	1947	1949	-	Oct	Sun>=1	2:00s	0	-
+Rule	Poland	1948	only	-	Apr	18	2:00s	1:00	S
+Rule	Poland	1949	only	-	Apr	10	2:00s	1:00	S
+Rule	Poland	1957	only	-	Jun	 2	1:00s	1:00	S
+Rule	Poland	1957	1958	-	Sep	lastSun	1:00s	0	-
+Rule	Poland	1958	only	-	Mar	30	1:00s	1:00	S
+Rule	Poland	1959	only	-	May	31	1:00s	1:00	S
+Rule	Poland	1959	1961	-	Oct	Sun>=1	1:00s	0	-
+Rule	Poland	1960	only	-	Apr	 3	1:00s	1:00	S
+Rule	Poland	1961	1964	-	May	lastSun	1:00s	1:00	S
+Rule	Poland	1962	1964	-	Sep	lastSun	1:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Warsaw	1:24:00 -	LMT	1880
+			1:24:00	-	WMT	1915 Aug  5   # Warsaw Mean Time
+			1:00	C-Eur	CE%sT	1918 Sep 16 3:00
+			2:00	Poland	EE%sT	1922 Jun
+			1:00	Poland	CE%sT	1940 Jun 23 2:00
+			1:00	C-Eur	CE%sT	1944 Oct
+			1:00	Poland	CE%sT	1977
+			1:00	W-Eur	CE%sT	1988
+			1:00	EU	CE%sT
+
+# Portugal
+#
+# From Rui Pedro Salgueiro (1992-11-12):
+# Portugal has recently (September, 27) changed timezone
+# (from WET to MET or CET) to harmonize with EEC.
+#
+# Martin Bruckmann (1996-02-29) reports via Peter Ilieve
+# that Portugal is reverting to 0:00 by not moving its clocks this spring.
+# The new Prime Minister was fed up with getting up in the dark in the winter.
+#
+# From Paul Eggert (1996-11-12):
+# IATA SSIM (1991-09) reports several 1991-09 and 1992-09 transitions
+# at 02:00u, not 01:00u.  Assume that these are typos.
+# IATA SSIM (1991/1992) reports that the Azores were at -1:00.
+# IATA SSIM (1993-02) says +0:00; later issues (through 1996-09) say -1:00.
+# Guess that the Azores changed to EU rules in 1992 (since that's when Portugal
+# harmonized with the EU), and that they stayed +0:00 that winter.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# DSH writes that despite Decree 1,469 (1915), the change to the clocks was not
+# done every year, depending on what Spain did, because of railroad schedules.
+# Go with Shanks & Pottenger.
+Rule	Port	1916	only	-	Jun	17	23:00	1:00	S
+# Whitman gives 1916 Oct 31; go with Shanks & Pottenger.
+Rule	Port	1916	only	-	Nov	 1	 1:00	0	-
+Rule	Port	1917	only	-	Feb	28	23:00s	1:00	S
+Rule	Port	1917	1921	-	Oct	14	23:00s	0	-
+Rule	Port	1918	only	-	Mar	 1	23:00s	1:00	S
+Rule	Port	1919	only	-	Feb	28	23:00s	1:00	S
+Rule	Port	1920	only	-	Feb	29	23:00s	1:00	S
+Rule	Port	1921	only	-	Feb	28	23:00s	1:00	S
+Rule	Port	1924	only	-	Apr	16	23:00s	1:00	S
+Rule	Port	1924	only	-	Oct	14	23:00s	0	-
+Rule	Port	1926	only	-	Apr	17	23:00s	1:00	S
+Rule	Port	1926	1929	-	Oct	Sat>=1	23:00s	0	-
+Rule	Port	1927	only	-	Apr	 9	23:00s	1:00	S
+Rule	Port	1928	only	-	Apr	14	23:00s	1:00	S
+Rule	Port	1929	only	-	Apr	20	23:00s	1:00	S
+Rule	Port	1931	only	-	Apr	18	23:00s	1:00	S
+# Whitman gives 1931 Oct 8; go with Shanks & Pottenger.
+Rule	Port	1931	1932	-	Oct	Sat>=1	23:00s	0	-
+Rule	Port	1932	only	-	Apr	 2	23:00s	1:00	S
+Rule	Port	1934	only	-	Apr	 7	23:00s	1:00	S
+# Whitman gives 1934 Oct 5; go with Shanks & Pottenger.
+Rule	Port	1934	1938	-	Oct	Sat>=1	23:00s	0	-
+# Shanks & Pottenger give 1935 Apr 30; go with Whitman.
+Rule	Port	1935	only	-	Mar	30	23:00s	1:00	S
+Rule	Port	1936	only	-	Apr	18	23:00s	1:00	S
+# Whitman gives 1937 Apr 2; go with Shanks & Pottenger.
+Rule	Port	1937	only	-	Apr	 3	23:00s	1:00	S
+Rule	Port	1938	only	-	Mar	26	23:00s	1:00	S
+Rule	Port	1939	only	-	Apr	15	23:00s	1:00	S
+# Whitman gives 1939 Oct 7; go with Shanks & Pottenger.
+Rule	Port	1939	only	-	Nov	18	23:00s	0	-
+Rule	Port	1940	only	-	Feb	24	23:00s	1:00	S
+# Shanks & Pottenger give 1940 Oct 7; go with Whitman.
+Rule	Port	1940	1941	-	Oct	 5	23:00s	0	-
+Rule	Port	1941	only	-	Apr	 5	23:00s	1:00	S
+Rule	Port	1942	1945	-	Mar	Sat>=8	23:00s	1:00	S
+Rule	Port	1942	only	-	Apr	25	22:00s	2:00	M # Midsummer
+Rule	Port	1942	only	-	Aug	15	22:00s	1:00	S
+Rule	Port	1942	1945	-	Oct	Sat>=24	23:00s	0	-
+Rule	Port	1943	only	-	Apr	17	22:00s	2:00	M
+Rule	Port	1943	1945	-	Aug	Sat>=25	22:00s	1:00	S
+Rule	Port	1944	1945	-	Apr	Sat>=21	22:00s	2:00	M
+Rule	Port	1946	only	-	Apr	Sat>=1	23:00s	1:00	S
+Rule	Port	1946	only	-	Oct	Sat>=1	23:00s	0	-
+Rule	Port	1947	1949	-	Apr	Sun>=1	 2:00s	1:00	S
+Rule	Port	1947	1949	-	Oct	Sun>=1	 2:00s	0	-
+# Shanks & Pottenger say DST was observed in 1950; go with Whitman.
+# Whitman gives Oct lastSun for 1952 on; go with Shanks & Pottenger.
+Rule	Port	1951	1965	-	Apr	Sun>=1	 2:00s	1:00	S
+Rule	Port	1951	1965	-	Oct	Sun>=1	 2:00s	0	-
+Rule	Port	1977	only	-	Mar	27	 0:00s	1:00	S
+Rule	Port	1977	only	-	Sep	25	 0:00s	0	-
+Rule	Port	1978	1979	-	Apr	Sun>=1	 0:00s	1:00	S
+Rule	Port	1978	only	-	Oct	 1	 0:00s	0	-
+Rule	Port	1979	1982	-	Sep	lastSun	 1:00s	0	-
+Rule	Port	1980	only	-	Mar	lastSun	 0:00s	1:00	S
+Rule	Port	1981	1982	-	Mar	lastSun	 1:00s	1:00	S
+Rule	Port	1983	only	-	Mar	lastSun	 2:00s	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# Shanks & Pottenger say the transition from LMT to WET occurred 1911-05-24;
+# Willett says 1912-01-01.  Go with Willett.
+Zone	Europe/Lisbon	-0:36:32 -	LMT	1884
+			-0:36:32 -	LMT	1912 Jan  1  # Lisbon Mean Time
+			 0:00	Port	WE%sT	1966 Apr  3 2:00
+			 1:00	-	CET	1976 Sep 26 1:00
+			 0:00	Port	WE%sT	1983 Sep 25 1:00s
+			 0:00	W-Eur	WE%sT	1992 Sep 27 1:00s
+			 1:00	EU	CE%sT	1996 Mar 31 1:00u
+			 0:00	EU	WE%sT
+Zone Atlantic/Azores	-1:42:40 -	LMT	1884		# Ponta Delgada
+			-1:54:32 -	HMT	1911 May 24  # Horta Mean Time
+			-2:00	Port	AZO%sT	1966 Apr  3 2:00 # Azores Time
+			-1:00	Port	AZO%sT	1983 Sep 25 1:00s
+			-1:00	W-Eur	AZO%sT	1992 Sep 27 1:00s
+			 0:00	EU	WE%sT	1993 Mar 28 1:00u
+			-1:00	EU	AZO%sT
+Zone Atlantic/Madeira	-1:07:36 -	LMT	1884		# Funchal
+			-1:07:36 -	FMT	1911 May 24  # Funchal Mean Time
+			-1:00	Port	MAD%sT	1966 Apr  3 2:00 # Madeira Time
+			 0:00	Port	WE%sT	1983 Sep 25 1:00s
+			 0:00	EU	WE%sT
+
+# Romania
+#
+# From Paul Eggert (1999-10-07):
+# <a href="http://www.nineoclock.ro/POL/1778pol.html">
+# Nine O'clock</a> (1998-10-23) reports that the switch occurred at
+# 04:00 local time in fall 1998.  For lack of better info,
+# assume that Romania and Moldova switched to EU rules in 1997,
+# the same year as Bulgaria.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Romania	1932	only	-	May	21	 0:00s	1:00	S
+Rule	Romania	1932	1939	-	Oct	Sun>=1	 0:00s	0	-
+Rule	Romania	1933	1939	-	Apr	Sun>=2	 0:00s	1:00	S
+Rule	Romania	1979	only	-	May	27	 0:00	1:00	S
+Rule	Romania	1979	only	-	Sep	lastSun	 0:00	0	-
+Rule	Romania	1980	only	-	Apr	 5	23:00	1:00	S
+Rule	Romania	1980	only	-	Sep	lastSun	 1:00	0	-
+Rule	Romania	1991	1993	-	Mar	lastSun	 0:00s	1:00	S
+Rule	Romania	1991	1993	-	Sep	lastSun	 0:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Europe/Bucharest	1:44:24 -	LMT	1891 Oct
+			1:44:24	-	BMT	1931 Jul 24	# Bucharest MT
+			2:00	Romania	EE%sT	1981 Mar 29 2:00s
+			2:00	C-Eur	EE%sT	1991
+			2:00	Romania	EE%sT	1994
+			2:00	E-Eur	EE%sT	1997
+			2:00	EU	EE%sT
+
+# Russia
+
+# From Paul Eggert (2006-03-22):
+# Except for Moscow after 1919-07-01, I invented the time zone abbreviations.
+# Moscow time zone abbreviations after 1919-07-01, and Moscow rules after 1991,
+# are from Andrey A. Chernov.  The rest is from Shanks & Pottenger,
+# except we follow Chernov's report that 1992 DST transitions were Sat
+# 23:00, not Sun 02:00s.
+#
+# From Stanislaw A. Kuzikowski (1994-06-29):
+# But now it is some months since Novosibirsk is 3 hours ahead of Moscow!
+# I do not know why they have decided to make this change;
+# as far as I remember it was done exactly during winter->summer switching
+# so we (Novosibirsk) simply did not switch.
+#
+# From Andrey A. Chernov (1996-10-04):
+# `MSK' and `MSD' were born and used initially on Moscow computers with
+# UNIX-like OSes by several developer groups (e.g. Demos group, Kiae group)....
+# The next step was the UUCP network, the Relcom predecessor
+# (used mainly for mail), and MSK/MSD was actively used there.
+#
+# From Chris Carrier (1996-10-30):
+# According to a friend of mine who rode the Trans-Siberian Railroad from
+# Moscow to Irkutsk in 1995, public air and rail transport in Russia ...
+# still follows Moscow time, no matter where in Russia it is located.
+#
+# For Grozny, Chechnya, we have the following story from
+# John Daniszewski, "Scavengers in the Rubble", Los Angeles Times (2001-02-07):
+# News--often false--is spread by word of mouth.  A rumor that it was
+# time to move the clocks back put this whole city out of sync with
+# the rest of Russia for two weeks--even soldiers stationed here began
+# enforcing curfew at the wrong time.
+#
+# From Gwillim Law (2001-06-05):
+# There's considerable evidence that Sakhalin Island used to be in
+# UTC+11, and has changed to UTC+10, in this decade.  I start with the
+# SSIM, which listed Yuzhno-Sakhalinsk in zone RU10 along with Magadan
+# until February 1997, and then in RU9 with Khabarovsk and Vladivostok
+# since September 1997....  Although the Kuril Islands are
+# administratively part of Sakhalin oblast', they appear to have
+# remained on UTC+11 along with Magadan.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+#
+# Kaliningradskaya oblast'.
+Zone Europe/Kaliningrad	 1:22:00 -	LMT	1893 Apr
+			 1:00	C-Eur	CE%sT	1945
+			 2:00	Poland	CE%sT	1946
+			 3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
+			 2:00	Russia	EE%sT
+#
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
+# Respublika Adygeya, Arkhangel'skaya oblast',
+# Belgorodskaya oblast', Bryanskaya oblast', Vladimirskaya oblast',
+# Vologodskaya oblast', Voronezhskaya oblast',
+# Respublika Dagestan, Ivanovskaya oblast', Respublika Ingushetiya,
+# Kabarbino-Balkarskaya Respublika, Respublika Kalmykiya,
+# Kalyzhskaya oblast', Respublika Karachaevo-Cherkessiya,
+# Respublika Kareliya, Respublika Komi,
+# Kostromskaya oblast', Krasnodarskij kraj, Kurskaya oblast',
+# Leningradskaya oblast', Lipetskaya oblast', Respublika Marij El,
+# Respublika Mordoviya, Moskva, Moskovskaya oblast',
+# Murmanskaya oblast', Nenetskij avtonomnyj okrug,
+# Nizhegorodskaya oblast', Novgorodskaya oblast', Orlovskaya oblast',
+# Penzenskaya oblast', Pskovskaya oblast', Rostovskaya oblast',
+# Ryazanskaya oblast', Sankt-Peterburg,
+# Respublika Severnaya Osetiya, Smolenskaya oblast',
+# Stavropol'skij kraj, Tambovskaya oblast', Respublika Tatarstan,
+# Tverskaya oblast', Tyl'skaya oblast', Ul'yanovskaya oblast',
+# Chechenskaya Respublika, Chuvashskaya oblast',
+# Yaroslavskaya oblast'
+Zone Europe/Moscow	 2:30:20 -	LMT	1880
+			 2:30	-	MMT	1916 Jul  3 # Moscow Mean Time
+			 2:30:48 Russia	%s	1919 Jul  1 2:00
+			 3:00	Russia	MSK/MSD	1922 Oct
+			 2:00	-	EET	1930 Jun 21
+			 3:00	Russia	MSK/MSD	1991 Mar 31 2:00s
+			 2:00	Russia	EE%sT	1992 Jan 19 2:00s
+			 3:00	Russia	MSK/MSD
+#
+# Astrakhanskaya oblast', Kirovskaya oblast', Saratovskaya oblast',
+# Volgogradskaya oblast'.  Shanks & Pottenger say Kirov is still at +0400
+# but Wikipedia (2006-05-09) says +0300.  Perhaps it switched after the
+# others?  But we have no data.
+Zone Europe/Volgograd	 2:57:40 -	LMT	1920 Jan  3
+			 3:00	-	TSAT	1925 Apr  6 # Tsaritsyn Time
+			 3:00	-	STAT	1930 Jun 21 # Stalingrad Time
+			 4:00	-	STAT	1961 Nov 11
+			 4:00	Russia	VOL%sT	1989 Mar 26 2:00s # Volgograd T
+			 3:00	Russia	VOL%sT	1991 Mar 31 2:00s
+			 4:00	-	VOLT	1992 Mar 29 2:00s
+			 3:00	Russia	VOL%sT
+#
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
+# Samarskaya oblast', Udmyrtskaya respublika
+Zone Europe/Samara	 3:20:36 -	LMT	1919 Jul  1 2:00
+			 3:00	-	SAMT	1930 Jun 21
+			 4:00	-	SAMT	1935 Jan 27
+			 4:00	Russia	KUY%sT	1989 Mar 26 2:00s # Kuybyshev
+			 3:00	Russia	KUY%sT	1991 Mar 31 2:00s
+			 2:00	Russia	KUY%sT	1991 Sep 29 2:00s
+			 3:00	-	KUYT	1991 Oct 20 3:00
+			 4:00	Russia	SAM%sT	# Samara Time
+#
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
+# Respublika Bashkortostan, Komi-Permyatskij avtonomnyj okrug,
+# Kurganskaya oblast', Orenburgskaya oblast', Permskaya oblast',
+# Sverdlovskaya oblast', Tyumenskaya oblast',
+# Khanty-Manskijskij avtonomnyj okrug, Chelyabinskaya oblast',
+# Yamalo-Nenetskij avtonomnyj okrug.
+Zone Asia/Yekaterinburg	 4:02:24 -	LMT	1919 Jul 15 4:00
+			 4:00	-	SVET	1930 Jun 21 # Sverdlovsk Time
+			 5:00	Russia	SVE%sT	1991 Mar 31 2:00s
+			 4:00	Russia	SVE%sT	1992 Jan 19 2:00s
+			 5:00	Russia	YEK%sT	# Yekaterinburg Time
+#
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
+# Respublika Altaj, Altajskij kraj, Omskaya oblast'.
+Zone Asia/Omsk		 4:53:36 -	LMT	1919 Nov 14
+			 5:00	-	OMST	1930 Jun 21 # Omsk TIme
+			 6:00	Russia	OMS%sT	1991 Mar 31 2:00s
+			 5:00	Russia	OMS%sT	1992 Jan 19 2:00s
+			 6:00	Russia	OMS%sT
+#
+# From Paul Eggert (2006-08-19): I'm guessing about Tomsk here; it's
+# not clear when it switched from +7 to +6.
+# Novosibirskaya oblast', Tomskaya oblast'.
+Zone Asia/Novosibirsk	 5:31:40 -	LMT	1919 Dec 14 6:00
+			 6:00	-	NOVT	1930 Jun 21 # Novosibirsk Time
+			 7:00	Russia	NOV%sT	1991 Mar 31 2:00s
+			 6:00	Russia	NOV%sT	1992 Jan 19 2:00s
+			 7:00	Russia	NOV%sT	1993 May 23 # say Shanks & P.
+			 6:00	Russia	NOV%sT
+#
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
+# Kemerovskaya oblast', Krasnoyarskij kraj,
+# Tajmyrskij (Dolgano-Nenetskij) avtonomnyj okrug,
+# Respublika Tuva, Respublika Khakasiya, Evenkijskij avtonomnyj okrug.
+Zone Asia/Krasnoyarsk	 6:11:20 -	LMT	1920 Jan  6
+			 6:00	-	KRAT	1930 Jun 21 # Krasnoyarsk Time
+			 7:00	Russia	KRA%sT	1991 Mar 31 2:00s
+			 6:00	Russia	KRA%sT	1992 Jan 19 2:00s
+			 7:00	Russia	KRA%sT
+#
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
+# Respublika Buryatiya, Irkutskaya oblast',
+# Ust'-Ordynskij Buryatskij avtonomnyj okrug.
+Zone Asia/Irkutsk	 6:57:20 -	LMT	1880
+			 6:57:20 -	IMT	1920 Jan 25 # Irkutsk Mean Time
+			 7:00	-	IRKT	1930 Jun 21 # Irkutsk Time
+			 8:00	Russia	IRK%sT	1991 Mar 31 2:00s
+			 7:00	Russia	IRK%sT	1992 Jan 19 2:00s
+			 8:00	Russia	IRK%sT
+#
+# From Oscar van Vlijmen (2003-10-18): [This region consists of]
+# Aginskij Buryatskij avtonomnyj okrug, Amurskaya oblast',
+# [parts of] Respublika Sakha (Yakutiya), Chitinskaya oblast'.
+# The Sakha districts are: Aldanskij, Amginskij, Anabarskij,
+# Bulunskij, Verkhnekolymskij, Verkhnevilyujskij, Vilyujskij, Gornyj,
+# Zhiganskij, Kobyajskij, Lenskij, Megino-Kangalasskij, Mirninskij,
+# Namskij, Nyurbinskij, Olenekskij, Olekminskij, Srednekolymskij,
+# Suntarskij, Tattinskij, Ust'-Aldanskij, Khangalasskij,
+# Churapchinskij, Eveno-Bytantajskij.
+Zone Asia/Yakutsk	 8:38:40 -	LMT	1919 Dec 15
+			 8:00	-	YAKT	1930 Jun 21 # Yakutsk Time
+			 9:00	Russia	YAK%sT	1991 Mar 31 2:00s
+			 8:00	Russia	YAK%sT	1992 Jan 19 2:00s
+			 9:00	Russia	YAK%sT
+#
+# From Oscar van Vlijmen (2003-10-18): [This region consists of]
+# Evrejskaya avtonomnaya oblast', Khabarovskij kraj, Primorskij kraj,
+# [parts of] Respublika Sakha (Yakutiya).
+# The Sakha districts are: Verkhoyanskij, Tomponskij, Ust'-Majskij,
+# Ust'-Yanskij.
+Zone Asia/Vladivostok	 8:47:44 -	LMT	1922 Nov 15
+			 9:00	-	VLAT	1930 Jun 21 # Vladivostok Time
+			10:00	Russia	VLA%sT	1991 Mar 31 2:00s
+			 9:00	Russia	VLA%sST	1992 Jan 19 2:00s
+			10:00	Russia	VLA%sT
+#
+# Sakhalinskaya oblast'.
+# The Zone name should be Yuzhno-Sakhalinsk, but that's too long.
+Zone Asia/Sakhalin	 9:30:48 -	LMT	1905 Aug 23
+			 9:00	-	CJT	1938
+			 9:00	-	JST	1945 Aug 25
+			11:00	Russia	SAK%sT	1991 Mar 31 2:00s # Sakhalin T.
+			10:00	Russia	SAK%sT	1992 Jan 19 2:00s
+			11:00	Russia	SAK%sT	1997 Mar lastSun 2:00s
+			10:00	Russia	SAK%sT
+#
+# From Oscar van Vlijmen (2003-10-18): [This region consists of]
+# Magadanskaya oblast', Respublika Sakha (Yakutiya).
+# Probably also: Kuril Islands.
+# The Sakha districts are: Abyjskij, Allaikhovskij, Momskij,
+# Nizhnekolymskij, Ojmyakonskij.
+Zone Asia/Magadan	10:03:12 -	LMT	1924 May  2
+			10:00	-	MAGT	1930 Jun 21 # Magadan Time
+			11:00	Russia	MAG%sT	1991 Mar 31 2:00s
+			10:00	Russia	MAG%sT	1992 Jan 19 2:00s
+			11:00	Russia	MAG%sT
+#
+# From Oscar van Vlijmen (2001-08-25): [This region consists of]
+# Kamchatskaya oblast', Koryakskij avtonomnyj okrug.
+#
+# The Zone name should be Asia/Petropavlovsk-Kamchatski, but that's too long.
+Zone Asia/Kamchatka	10:34:36 -	LMT	1922 Nov 10
+			11:00	-	PETT	1930 Jun 21 # P-K Time
+			12:00	Russia	PET%sT	1991 Mar 31 2:00s
+			11:00	Russia	PET%sT	1992 Jan 19 2:00s
+			12:00	Russia	PET%sT
+#
+# Chukotskij avtonomnyj okrug
+Zone Asia/Anadyr	11:49:56 -	LMT	1924 May  2
+			12:00	-	ANAT	1930 Jun 21 # Anadyr Time
+			13:00	Russia	ANA%sT	1982 Apr  1 0:00s
+			12:00	Russia	ANA%sT	1991 Mar 31 2:00s
+			11:00	Russia	ANA%sT	1992 Jan 19 2:00s
+			12:00	Russia	ANA%sT
+
+# Serbia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Belgrade	1:22:00	-	LMT	1884
+			1:00	-	CET	1941 Apr 18 23:00
+			1:00	C-Eur	CE%sT	1945
+			1:00	-	CET	1945 May 8 2:00s
+			1:00	1:00	CEST	1945 Sep 16  2:00s
+# Metod Kozelj reports that the legal date of
+# transition to EU rules was 1982-11-27, for all of Yugoslavia at the time.
+# Shanks & Pottenger don't give as much detail, so go with Kozelj.
+			1:00	-	CET	1982 Nov 27
+			1:00	EU	CE%sT
+Link Europe/Belgrade Europe/Ljubljana	# Slovenia
+Link Europe/Belgrade Europe/Podgorica	# Montenegro
+Link Europe/Belgrade Europe/Sarajevo	# Bosnia and Herzegovina
+Link Europe/Belgrade Europe/Skopje	# Macedonia
+Link Europe/Belgrade Europe/Zagreb	# Croatia
+
+# Slovakia
+Link Europe/Prague Europe/Bratislava
+
+# Slovenia
+# see Serbia
+
+# Spain
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# For 1917-1919 Whitman gives Apr Sat>=1 - Oct Sat>=1;
+# go with Shanks & Pottenger.
+Rule	Spain	1917	only	-	May	 5	23:00s	1:00	S
+Rule	Spain	1917	1919	-	Oct	 6	23:00s	0	-
+Rule	Spain	1918	only	-	Apr	15	23:00s	1:00	S
+Rule	Spain	1919	only	-	Apr	 5	23:00s	1:00	S
+# Whitman gives 1921 Feb 28 - Oct 14; go with Shanks & Pottenger.
+Rule	Spain	1924	only	-	Apr	16	23:00s	1:00	S
+# Whitman gives 1924 Oct 14; go with Shanks & Pottenger.
+Rule	Spain	1924	only	-	Oct	 4	23:00s	0	-
+Rule	Spain	1926	only	-	Apr	17	23:00s	1:00	S
+# Whitman says no DST in 1929; go with Shanks & Pottenger.
+Rule	Spain	1926	1929	-	Oct	Sat>=1	23:00s	0	-
+Rule	Spain	1927	only	-	Apr	 9	23:00s	1:00	S
+Rule	Spain	1928	only	-	Apr	14	23:00s	1:00	S
+Rule	Spain	1929	only	-	Apr	20	23:00s	1:00	S
+# Whitman gives 1937 Jun 16, 1938 Apr 16, 1940 Apr 13;
+# go with Shanks & Pottenger.
+Rule	Spain	1937	only	-	May	22	23:00s	1:00	S
+Rule	Spain	1937	1939	-	Oct	Sat>=1	23:00s	0	-
+Rule	Spain	1938	only	-	Mar	22	23:00s	1:00	S
+Rule	Spain	1939	only	-	Apr	15	23:00s	1:00	S
+Rule	Spain	1940	only	-	Mar	16	23:00s	1:00	S
+# Whitman says no DST 1942-1945; go with Shanks & Pottenger.
+Rule	Spain	1942	only	-	May	 2	22:00s	2:00	M # Midsummer
+Rule	Spain	1942	only	-	Sep	 1	22:00s	1:00	S
+Rule	Spain	1943	1946	-	Apr	Sat>=13	22:00s	2:00	M
+Rule	Spain	1943	only	-	Oct	 3	22:00s	1:00	S
+Rule	Spain	1944	only	-	Oct	10	22:00s	1:00	S
+Rule	Spain	1945	only	-	Sep	30	 1:00	1:00	S
+Rule	Spain	1946	only	-	Sep	30	 0:00	0	-
+Rule	Spain	1949	only	-	Apr	30	23:00	1:00	S
+Rule	Spain	1949	only	-	Sep	30	 1:00	0	-
+Rule	Spain	1974	1975	-	Apr	Sat>=13	23:00	1:00	S
+Rule	Spain	1974	1975	-	Oct	Sun>=1	 1:00	0	-
+Rule	Spain	1976	only	-	Mar	27	23:00	1:00	S
+Rule	Spain	1976	1977	-	Sep	lastSun	 1:00	0	-
+Rule	Spain	1977	1978	-	Apr	 2	23:00	1:00	S
+Rule	Spain	1978	only	-	Oct	 1	 1:00	0	-
+# The following rules are copied from Morocco from 1967 through 1978.
+Rule SpainAfrica 1967	only	-	Jun	 3	12:00	1:00	S
+Rule SpainAfrica 1967	only	-	Oct	 1	 0:00	0	-
+Rule SpainAfrica 1974	only	-	Jun	24	 0:00	1:00	S
+Rule SpainAfrica 1974	only	-	Sep	 1	 0:00	0	-
+Rule SpainAfrica 1976	1977	-	May	 1	 0:00	1:00	S
+Rule SpainAfrica 1976	only	-	Aug	 1	 0:00	0	-
+Rule SpainAfrica 1977	only	-	Sep	28	 0:00	0	-
+Rule SpainAfrica 1978	only	-	Jun	 1	 0:00	1:00	S
+Rule SpainAfrica 1978	only	-	Aug	 4	 0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Madrid	-0:14:44 -	LMT	1901 Jan  1  0:00s
+			 0:00	Spain	WE%sT	1946 Sep 30
+			 1:00	Spain	CE%sT	1979
+			 1:00	EU	CE%sT
+Zone	Africa/Ceuta	-0:21:16 -	LMT	1901
+			 0:00	-	WET	1918 May  6 23:00
+			 0:00	1:00	WEST	1918 Oct  7 23:00
+			 0:00	-	WET	1924
+			 0:00	Spain	WE%sT	1929
+			 0:00 SpainAfrica WE%sT 1984 Mar 16
+			 1:00	-	CET	1986
+			 1:00	EU	CE%sT
+Zone	Atlantic/Canary	-1:01:36 -	LMT	1922 Mar # Las Palmas de Gran C.
+			-1:00	-	CANT	1946 Sep 30 1:00 # Canaries Time
+			 0:00	-	WET	1980 Apr  6 0:00s
+			 0:00	1:00	WEST	1980 Sep 28 0:00s
+			 0:00	EU	WE%sT
+# IATA SSIM (1996-09) says the Canaries switch at 2:00u, not 1:00u.
+# Ignore this for now, as the Canaries are part of the EU.
+
+# Sweden
+
+# From Ivan Nilsson (2001-04-13), superseding Shanks & Pottenger:
+#
+# The law "Svensk forfattningssamling 1878, no 14" about standard time in 1879:
+# From the beginning of 1879 (that is 01-01 00:00) the time for all
+# places in the country is "the mean solar time for the meridian at
+# three degrees, or twelve minutes of time, to the west of the
+# meridian of the Observatory of Stockholm".  The law is dated 1878-05-31.
+#
+# The observatory at that time had the meridian 18 degrees 03' 30"
+# eastern longitude = 01:12:14 in time.  Less 12 minutes gives the
+# national standard time as 01:00:14 ahead of GMT....
+#
+# About the beginning of CET in Sweden. The lawtext ("Svensk
+# forfattningssamling 1899, no 44") states, that "from the beginning
+# of 1900... ... the same as the mean solar time for the meridian at
+# the distance of one hour of time from the meridian of the English
+# observatory at Greenwich, or at 12 minutes 14 seconds to the west
+# from the meridian of the Observatory of Stockholm". The law is dated
+# 1899-06-16.  In short: At 1900-01-01 00:00:00 the new standard time
+# in Sweden is 01:00:00 ahead of GMT.
+#
+# 1916: The lawtext ("Svensk forfattningssamling 1916, no 124") states
+# that "1916-05-15 is considered to begin one hour earlier". It is
+# pretty obvious that at 05-14 23:00 the clocks are set to 05-15 00:00....
+# Further the law says, that "1916-09-30 is considered to end one hour later".
+#
+# The laws regulating [DST] are available on the site of the Swedish
+# Parliament beginning with 1985 - the laws regulating 1980/1984 are
+# not available on the site (to my knowledge they are only available
+# in Swedish): <http://www.riksdagen.se/english/work/sfst.asp> (type
+# "sommartid" without the quotes in the field "Fritext" and then click
+# the Sok-button).
+#
+# (2001-05-13):
+#
+# I have now found a newspaper stating that at 1916-10-01 01:00
+# summertime the church-clocks etc were set back one hour to show
+# 1916-10-01 00:00 standard time.  The article also reports that some
+# people thought the switch to standard time would take place already
+# at 1916-10-01 00:00 summer time, but they had to wait for another
+# hour before the event took place.
+#
+# Source: The newspaper "Dagens Nyheter", 1916-10-01, page 7 upper left.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Europe/Stockholm	1:12:12 -	LMT	1879 Jan  1
+			1:00:14	-	SET	1900 Jan  1	# Swedish Time
+			1:00	-	CET	1916 May 14 23:00
+			1:00	1:00	CEST	1916 Oct  1 01:00
+			1:00	-	CET	1980
+			1:00	EU	CE%sT
+
+# Switzerland
+# From Howse:
+# By the end of the 18th century clocks and watches became commonplace
+# and their performance improved enormously.  Communities began to keep
+# mean time in preference to apparent time -- Geneva from 1780 ....
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# From Whitman (who writes ``Midnight?''):
+Rule	Swiss	1940	only	-	Nov	 2	0:00	1:00	S
+Rule	Swiss	1940	only	-	Dec	31	0:00	0	-
+# From Shanks & Pottenger:
+Rule	Swiss	1941	1942	-	May	Sun>=1	2:00	1:00	S
+Rule	Swiss	1941	1942	-	Oct	Sun>=1	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Zurich	0:34:08 -	LMT	1848 Sep 12
+			0:29:44	-	BMT	1894 Jun # Bern Mean Time
+			1:00	Swiss	CE%sT	1981
+			1:00	EU	CE%sT
+
+# Turkey
+
+# From Amar Devegowda (2007-01-03):
+# The time zone rules for Istanbul, Turkey have not been changed for years now.
+# ... The latest rules are available at -
+# http://www.timeanddate.com/worldclock/timezone.html?n=107
+# From Steffen Thorsen (2007-01-03):
+# I have been able to find press records back to 1996 which all say that
+# DST started 01:00 local time and end at 02:00 local time.  I am not sure
+# what happened before that.  One example for each year from 1996 to 2001:
+# http://newspot.byegm.gov.tr/arsiv/1996/21/N4.htm
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING97/03/97X03X25.TXT
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING98/03/98X03X02.HTM
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING99/10/99X10X26.HTM#%2016
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2000/03/00X03X06.HTM#%2021
+# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2001/03/23x03x01.HTM#%2027
+# From Paul Eggert (2007-01-03):
+# Prefer the above source to Shanks & Pottenger for time stamps after 1990.
+
+# From Steffen Thorsen (2007-03-09):
+# Starting 2007 though, it seems that they are adopting EU's 1:00 UTC
+# start/end time, according to the following page (2007-03-07):
+# http://www.ntvmsnbc.com/news/402029.asp
+# The official document is located here - it is in Turkish...:
+# http://rega.basbakanlik.gov.tr/eskiler/2007/03/20070307-7.htm
+# I was able to locate the following seemingly official document
+# (on a non-government server though) describing dates between 2002 and 2006:
+# http://www.alomaliye.com/bkk_2002_3769.htm
+
+# From Sue Williams (2008-08-11):
+# I spotted this news article about a potential change in Turkey.
+#
+# <a href="http://www.hurriyet.com.tr/english/domestic/9626174.asp?scr=1">
+# http://www.hurriyet.com.tr/english/domestic/9626174.asp?scr=1
+# </a>
+
+# From Sue Williams (2008-08-20):
+# This article says that around the end of March 2011, Turkey wants to
+# adjust the clocks forward by 1/2 hour and stay that way permanently.
+# The article indicates that this is a change in timezone offset in addition
+# to stopping observance of DST.
+# This proposal has not yet been approved.
+#
+# Read more here...
+#
+# Turkey to abandon daylight saving time in 2011
+# <a href="http://www.turkishdailynews.com.tr/article.php?enewsid=112989">
+# http://www.turkishdailynews.com.tr/article.php?enewsid=112989
+# </a>
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Turkey	1916	only	-	May	 1	0:00	1:00	S
+Rule	Turkey	1916	only	-	Oct	 1	0:00	0	-
+Rule	Turkey	1920	only	-	Mar	28	0:00	1:00	S
+Rule	Turkey	1920	only	-	Oct	25	0:00	0	-
+Rule	Turkey	1921	only	-	Apr	 3	0:00	1:00	S
+Rule	Turkey	1921	only	-	Oct	 3	0:00	0	-
+Rule	Turkey	1922	only	-	Mar	26	0:00	1:00	S
+Rule	Turkey	1922	only	-	Oct	 8	0:00	0	-
+# Whitman gives 1923 Apr 28 - Sep 16 and no DST in 1924-1925;
+# go with Shanks & Pottenger.
+Rule	Turkey	1924	only	-	May	13	0:00	1:00	S
+Rule	Turkey	1924	1925	-	Oct	 1	0:00	0	-
+Rule	Turkey	1925	only	-	May	 1	0:00	1:00	S
+Rule	Turkey	1940	only	-	Jun	30	0:00	1:00	S
+Rule	Turkey	1940	only	-	Oct	 5	0:00	0	-
+Rule	Turkey	1940	only	-	Dec	 1	0:00	1:00	S
+Rule	Turkey	1941	only	-	Sep	21	0:00	0	-
+Rule	Turkey	1942	only	-	Apr	 1	0:00	1:00	S
+# Whitman omits the next two transition and gives 1945 Oct 1;
+# go with Shanks & Pottenger.
+Rule	Turkey	1942	only	-	Nov	 1	0:00	0	-
+Rule	Turkey	1945	only	-	Apr	 2	0:00	1:00	S
+Rule	Turkey	1945	only	-	Oct	 8	0:00	0	-
+Rule	Turkey	1946	only	-	Jun	 1	0:00	1:00	S
+Rule	Turkey	1946	only	-	Oct	 1	0:00	0	-
+Rule	Turkey	1947	1948	-	Apr	Sun>=16	0:00	1:00	S
+Rule	Turkey	1947	1950	-	Oct	Sun>=2	0:00	0	-
+Rule	Turkey	1949	only	-	Apr	10	0:00	1:00	S
+Rule	Turkey	1950	only	-	Apr	19	0:00	1:00	S
+Rule	Turkey	1951	only	-	Apr	22	0:00	1:00	S
+Rule	Turkey	1951	only	-	Oct	 8	0:00	0	-
+Rule	Turkey	1962	only	-	Jul	15	0:00	1:00	S
+Rule	Turkey	1962	only	-	Oct	 8	0:00	0	-
+Rule	Turkey	1964	only	-	May	15	0:00	1:00	S
+Rule	Turkey	1964	only	-	Oct	 1	0:00	0	-
+Rule	Turkey	1970	1972	-	May	Sun>=2	0:00	1:00	S
+Rule	Turkey	1970	1972	-	Oct	Sun>=2	0:00	0	-
+Rule	Turkey	1973	only	-	Jun	 3	1:00	1:00	S
+Rule	Turkey	1973	only	-	Nov	 4	3:00	0	-
+Rule	Turkey	1974	only	-	Mar	31	2:00	1:00	S
+Rule	Turkey	1974	only	-	Nov	 3	5:00	0	-
+Rule	Turkey	1975	only	-	Mar	30	0:00	1:00	S
+Rule	Turkey	1975	1976	-	Oct	lastSun	0:00	0	-
+Rule	Turkey	1976	only	-	Jun	 1	0:00	1:00	S
+Rule	Turkey	1977	1978	-	Apr	Sun>=1	0:00	1:00	S
+Rule	Turkey	1977	only	-	Oct	16	0:00	0	-
+Rule	Turkey	1979	1980	-	Apr	Sun>=1	3:00	1:00	S
+Rule	Turkey	1979	1982	-	Oct	Mon>=11	0:00	0	-
+Rule	Turkey	1981	1982	-	Mar	lastSun	3:00	1:00	S
+Rule	Turkey	1983	only	-	Jul	31	0:00	1:00	S
+Rule	Turkey	1983	only	-	Oct	 2	0:00	0	-
+Rule	Turkey	1985	only	-	Apr	20	0:00	1:00	S
+Rule	Turkey	1985	only	-	Sep	28	0:00	0	-
+Rule	Turkey	1986	1990	-	Mar	lastSun	2:00s	1:00	S
+Rule	Turkey	1986	1990	-	Sep	lastSun	2:00s	0	-
+Rule	Turkey	1991	2006	-	Mar	lastSun	1:00s	1:00	S
+Rule	Turkey	1991	1995	-	Sep	lastSun	1:00s	0	-
+Rule	Turkey	1996	2006	-	Oct	lastSun	1:00s	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	Europe/Istanbul	1:55:52 -	LMT	1880
+			1:56:56	-	IMT	1910 Oct # Istanbul Mean Time?
+			2:00	Turkey	EE%sT	1978 Oct 15
+			3:00	Turkey	TR%sT	1985 Apr 20 # Turkey Time
+			2:00	Turkey	EE%sT	2007
+			2:00	EU	EE%sT
+Link	Europe/Istanbul	Asia/Istanbul	# Istanbul is in both continents.
+
+# Ukraine
+#
+# From Igor Karpov, who works for the Ukranian Ministry of Justice,
+# via Garrett Wollman (2003-01-27):
+# BTW, I've found the official document on this matter. It's goverment
+# regulations number 509, May 13, 1996. In my poor translation it says:
+# "Time in Ukraine is set to second timezone (Kiev time). Each last Sunday
+# of March at 3am the time is changing to 4am and each last Sunday of
+# October the time at 4am is changing to 3am"
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# Most of Ukraine since 1970 has been like Kiev.
+# "Kyiv" is the transliteration of the Ukrainian name, but
+# "Kiev" is more common in English.
+Zone Europe/Kiev	2:02:04 -	LMT	1880
+			2:02:04	-	KMT	1924 May  2 # Kiev Mean Time
+			2:00	-	EET	1930 Jun 21
+			3:00	-	MSK	1941 Sep 20
+			1:00	C-Eur	CE%sT	1943 Nov  6
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1990 Jul  1 2:00
+			2:00	-	EET	1992
+			2:00	E-Eur	EE%sT	1995
+			2:00	EU	EE%sT
+# Ruthenia used CET 1990/1991.
+# "Uzhhorod" is the transliteration of the Ukrainian name, but
+# "Uzhgorod" is more common in English.
+Zone Europe/Uzhgorod	1:29:12 -	LMT	1890 Oct
+			1:00	-	CET	1940
+			1:00	C-Eur	CE%sT	1944 Oct
+			1:00	1:00	CEST	1944 Oct 26
+			1:00	-	CET	1945 Jun 29
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1990 Jul  1 2:00
+			1:00	-	CET	1991 Mar 31 3:00
+			2:00	-	EET	1992
+			2:00	E-Eur	EE%sT	1995
+			2:00	EU	EE%sT
+# Zaporozh'ye and eastern Lugansk oblasts observed DST 1990/1991.
+# "Zaporizhia" is the transliteration of the Ukrainian name, but
+# "Zaporozh'ye" is more common in English.  Use the common English
+# spelling, except omit the apostrophe as it is not allowed in
+# portable Posix file names.
+Zone Europe/Zaporozhye	2:20:40 -	LMT	1880
+			2:20	-	CUT	1924 May  2 # Central Ukraine T
+			2:00	-	EET	1930 Jun 21
+			3:00	-	MSK	1941 Aug 25
+			1:00	C-Eur	CE%sT	1943 Oct 25
+			3:00	Russia	MSK/MSD	1991 Mar 31 2:00
+			2:00	E-Eur	EE%sT	1995
+			2:00	EU	EE%sT
+# Central Crimea used Moscow time 1994/1997.
+Zone Europe/Simferopol	2:16:24 -	LMT	1880
+			2:16	-	SMT	1924 May  2 # Simferopol Mean T
+			2:00	-	EET	1930 Jun 21
+			3:00	-	MSK	1941 Nov
+			1:00	C-Eur	CE%sT	1944 Apr 13
+			3:00	Russia	MSK/MSD	1990
+			3:00	-	MSK	1990 Jul  1 2:00
+			2:00	-	EET	1992
+# From Paul Eggert (2006-03-22):
+# The _Economist_ (1994-05-28, p 45) reports that central Crimea switched
+# from Kiev to Moscow time sometime after the January 1994 elections.
+# Shanks (1999) says ``date of change uncertain'', but implies that it happened
+# sometime between the 1994 DST switches.  Shanks & Pottenger simply say
+# 1994-09-25 03:00, but that can't be right.  For now, guess it
+# changed in May.
+			2:00	E-Eur	EE%sT	1994 May
+# From IATA SSIM (1994/1997), which also says that Kerch is still like Kiev.
+			3:00	E-Eur	MSK/MSD	1996 Mar 31 3:00s
+			3:00	1:00	MSD	1996 Oct 27 3:00s
+# IATA SSIM (1997-09) says Crimea switched to EET/EEST.
+# Assume it happened in March by not changing the clocks.
+			3:00	Russia	MSK/MSD	1997
+			3:00	-	MSK	1997 Mar lastSun 1:00u
+			2:00	EU	EE%sT
+
+###############################################################################
+
+# One source shows that Bulgaria, Cyprus, Finland, and Greece observe DST from
+# the last Sunday in March to the last Sunday in September in 1986.
+# The source shows Romania changing a day later than everybody else.
+#
+# According to Bernard Sieloff's source, Poland is in the MET time zone but
+# uses the WE DST rules.  The Western USSR uses EET+1 and ME DST rules.
+# Bernard Sieloff's source claims Romania switches on the same day, but at
+# 00:00 standard time (i.e., 01:00 DST).  It also claims that Turkey
+# switches on the same day, but switches on at 01:00 standard time
+# and off at 00:00 standard time (i.e., 01:00 DST)
+
+# ...
+# Date: Wed, 28 Jan 87 16:56:27 -0100
+# From: Tom Hofmann
+# ...
+#
+# ...the European time rules are...standardized since 1981, when
+# most European coun[tr]ies started DST.  Before that year, only
+# a few countries (UK, France, Italy) had DST, each according
+# to own national rules.  In 1981, however, DST started on
+# 'Apr firstSun', and not on 'Mar lastSun' as in the following
+# years...
+# But also since 1981 there are some more national exceptions
+# than listed in 'europe': Switzerland, for example, joined DST
+# one year later, Denmark ended DST on 'Oct 1' instead of 'Sep
+# lastSun' in 1981---I don't know how they handle now.
+#
+# Finally, DST ist always from 'Apr 1' to 'Oct 1' in the
+# Soviet Union (as far as I know).
+#
+# Tom Hofmann, Scientific Computer Center, CIBA-GEIGY AG,
+# 4002 Basle, Switzerland
+# ...
+
+# ...
+# Date: Wed, 4 Feb 87 22:35:22 +0100
+# From: Dik T. Winter
+# ...
+#
+# The information from Tom Hofmann is (as far as I know) not entirely correct.
+# After a request from chongo at amdahl I tried to retrieve all information
+# about DST in Europe.  I was able to find all from about 1969.
+#
+# ...standardization on DST in Europe started in about 1977 with switches on
+# first Sunday in April and last Sunday in September...
+# In 1981 UK joined Europe insofar that
+# the starting day for both shifted to last Sunday in March.  And from 1982
+# the whole of Europe used DST, with switch dates April 1 and October 1 in
+# the Sov[i]et Union.  In 1985 the SU reverted to standard Europe[a]n switch
+# dates...
+#
+# It should also be remembered that time-zones are not constants; e.g.
+# Portugal switched in 1976 from MET (or CET) to WET with DST...
+# Note also that though there were rules for switch dates not
+# all countries abided to these dates, and many individual deviations
+# occurred, though not since 1982 I believe.  Another note: it is always
+# assumed that DST is 1 hour ahead of normal time, this need not be the
+# case; at least in the Netherlands there have been times when DST was 2 hours
+# in advance of normal time.
+#
+# ...
+# dik t. winter, cwi, amsterdam, nederland
+# ...
+
+# From Bob Devine (1988-01-28):
+# ...
+# Greece: Last Sunday in April to last Sunday in September (iffy on dates).
+# Since 1978.  Change at midnight.
+# ...
+# Monaco: has same DST as France.
+# ...
diff --git a/tools/zoneinfo/tzdata2008h/factory b/tools/zoneinfo/tzdata2008h/factory
new file mode 100644
index 0000000..946063c
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/factory
@@ -0,0 +1,8 @@
+# @(#)factory	8.1
+
+# For companies who don't want to put time zone specification in
+# their installation procedures.  When users run date, they'll get the message.
+# Also useful for the "comp.sources" version.
+
+# Zone	NAME	GMTOFF	RULES	FORMAT
+Zone	Factory	0	- "Local time zone must be set--see zic manual page"
diff --git a/tools/zoneinfo/tzdata2008h/iso3166.tab b/tools/zoneinfo/tzdata2008h/iso3166.tab
new file mode 100644
index 0000000..8d62399
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/iso3166.tab
@@ -0,0 +1,269 @@
+# ISO 3166 alpha-2 country codes
+#
+# @(#)iso3166.tab	8.5
+#
+# From Paul Eggert (2006-09-27):
+#
+# This file contains a table with the following columns:
+# 1.  ISO 3166-1 alpha-2 country code, current as of
+#     ISO 3166-1 Newsletter VI-1 (2007-09-21).  See:
+#     <a href="http://www.iso.org/iso/en/prods-services/iso3166ma/index.html">
+#     ISO 3166 Maintenance agency (ISO 3166/MA)
+#     </a>.
+# 2.  The usual English name for the country,
+#     chosen so that alphabetic sorting of subsets produces helpful lists.
+#     This is not the same as the English name in the ISO 3166 tables.
+#
+# Columns are separated by a single tab.
+# The table is sorted by country code.
+#
+# Lines beginning with `#' are comments.
+#
+#country-
+#code	country name
+AD	Andorra
+AE	United Arab Emirates
+AF	Afghanistan
+AG	Antigua & Barbuda
+AI	Anguilla
+AL	Albania
+AM	Armenia
+AN	Netherlands Antilles
+AO	Angola
+AQ	Antarctica
+AR	Argentina
+AS	Samoa (American)
+AT	Austria
+AU	Australia
+AW	Aruba
+AX	Aaland Islands
+AZ	Azerbaijan
+BA	Bosnia & Herzegovina
+BB	Barbados
+BD	Bangladesh
+BE	Belgium
+BF	Burkina Faso
+BG	Bulgaria
+BH	Bahrain
+BI	Burundi
+BJ	Benin
+BL	St Barthelemy
+BM	Bermuda
+BN	Brunei
+BO	Bolivia
+BR	Brazil
+BS	Bahamas
+BT	Bhutan
+BV	Bouvet Island
+BW	Botswana
+BY	Belarus
+BZ	Belize
+CA	Canada
+CC	Cocos (Keeling) Islands
+CD	Congo (Dem. Rep.)
+CF	Central African Rep.
+CG	Congo (Rep.)
+CH	Switzerland
+CI	Cote d'Ivoire
+CK	Cook Islands
+CL	Chile
+CM	Cameroon
+CN	China
+CO	Colombia
+CR	Costa Rica
+CU	Cuba
+CV	Cape Verde
+CX	Christmas Island
+CY	Cyprus
+CZ	Czech Republic
+DE	Germany
+DJ	Djibouti
+DK	Denmark
+DM	Dominica
+DO	Dominican Republic
+DZ	Algeria
+EC	Ecuador
+EE	Estonia
+EG	Egypt
+EH	Western Sahara
+ER	Eritrea
+ES	Spain
+ET	Ethiopia
+FI	Finland
+FJ	Fiji
+FK	Falkland Islands
+FM	Micronesia
+FO	Faroe Islands
+FR	France
+GA	Gabon
+GB	Britain (UK)
+GD	Grenada
+GE	Georgia
+GF	French Guiana
+GG	Guernsey
+GH	Ghana
+GI	Gibraltar
+GL	Greenland
+GM	Gambia
+GN	Guinea
+GP	Guadeloupe
+GQ	Equatorial Guinea
+GR	Greece
+GS	South Georgia & the South Sandwich Islands
+GT	Guatemala
+GU	Guam
+GW	Guinea-Bissau
+GY	Guyana
+HK	Hong Kong
+HM	Heard Island & McDonald Islands
+HN	Honduras
+HR	Croatia
+HT	Haiti
+HU	Hungary
+ID	Indonesia
+IE	Ireland
+IL	Israel
+IM	Isle of Man
+IN	India
+IO	British Indian Ocean Territory
+IQ	Iraq
+IR	Iran
+IS	Iceland
+IT	Italy
+JE	Jersey
+JM	Jamaica
+JO	Jordan
+JP	Japan
+KE	Kenya
+KG	Kyrgyzstan
+KH	Cambodia
+KI	Kiribati
+KM	Comoros
+KN	St Kitts & Nevis
+KP	Korea (North)
+KR	Korea (South)
+KW	Kuwait
+KY	Cayman Islands
+KZ	Kazakhstan
+LA	Laos
+LB	Lebanon
+LC	St Lucia
+LI	Liechtenstein
+LK	Sri Lanka
+LR	Liberia
+LS	Lesotho
+LT	Lithuania
+LU	Luxembourg
+LV	Latvia
+LY	Libya
+MA	Morocco
+MC	Monaco
+MD	Moldova
+ME	Montenegro
+MF	St Martin (French part)
+MG	Madagascar
+MH	Marshall Islands
+MK	Macedonia
+ML	Mali
+MM	Myanmar (Burma)
+MN	Mongolia
+MO	Macau
+MP	Northern Mariana Islands
+MQ	Martinique
+MR	Mauritania
+MS	Montserrat
+MT	Malta
+MU	Mauritius
+MV	Maldives
+MW	Malawi
+MX	Mexico
+MY	Malaysia
+MZ	Mozambique
+NA	Namibia
+NC	New Caledonia
+NE	Niger
+NF	Norfolk Island
+NG	Nigeria
+NI	Nicaragua
+NL	Netherlands
+NO	Norway
+NP	Nepal
+NR	Nauru
+NU	Niue
+NZ	New Zealand
+OM	Oman
+PA	Panama
+PE	Peru
+PF	French Polynesia
+PG	Papua New Guinea
+PH	Philippines
+PK	Pakistan
+PL	Poland
+PM	St Pierre & Miquelon
+PN	Pitcairn
+PR	Puerto Rico
+PS	Palestine
+PT	Portugal
+PW	Palau
+PY	Paraguay
+QA	Qatar
+RE	Reunion
+RO	Romania
+RS	Serbia
+RU	Russia
+RW	Rwanda
+SA	Saudi Arabia
+SB	Solomon Islands
+SC	Seychelles
+SD	Sudan
+SE	Sweden
+SG	Singapore
+SH	St Helena
+SI	Slovenia
+SJ	Svalbard & Jan Mayen
+SK	Slovakia
+SL	Sierra Leone
+SM	San Marino
+SN	Senegal
+SO	Somalia
+SR	Suriname
+ST	Sao Tome & Principe
+SV	El Salvador
+SY	Syria
+SZ	Swaziland
+TC	Turks & Caicos Is
+TD	Chad
+TF	French Southern & Antarctic Lands
+TG	Togo
+TH	Thailand
+TJ	Tajikistan
+TK	Tokelau
+TL	East Timor
+TM	Turkmenistan
+TN	Tunisia
+TO	Tonga
+TR	Turkey
+TT	Trinidad & Tobago
+TV	Tuvalu
+TW	Taiwan
+TZ	Tanzania
+UA	Ukraine
+UG	Uganda
+UM	US minor outlying islands
+US	United States
+UY	Uruguay
+UZ	Uzbekistan
+VA	Vatican City
+VC	St Vincent
+VE	Venezuela
+VG	Virgin Islands (UK)
+VI	Virgin Islands (US)
+VN	Vietnam
+VU	Vanuatu
+WF	Wallis & Futuna
+WS	Samoa (western)
+YE	Yemen
+YT	Mayotte
+ZA	South Africa
+ZM	Zambia
+ZW	Zimbabwe
diff --git a/tools/zoneinfo/tzdata2008h/leapseconds b/tools/zoneinfo/tzdata2008h/leapseconds
new file mode 100644
index 0000000..a2f4f0b
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/leapseconds
@@ -0,0 +1,92 @@
+# @(#)leapseconds	8.6
+
+# Allowance for leapseconds added to each timezone file.
+
+# The International Earth Rotation Service periodically uses leap seconds
+# to keep UTC to within 0.9 s of UT1
+# (which measures the true angular orientation of the earth in space); see
+# Terry J Quinn, The BIPM and the accurate measure of time,
+# Proc IEEE 79, 7 (July 1991), 894-905.
+# There were no leap seconds before 1972, because the official mechanism
+# accounting for the discrepancy between atomic time and the earth's rotation
+# did not exist until the early 1970s.
+
+# The correction (+ or -) is made at the given time, so lines
+# will typically look like:
+#	Leap	YEAR	MON	DAY	23:59:60	+	R/S
+# or
+#	Leap	YEAR	MON	DAY	23:59:59	-	R/S
+
+# If the leapsecond is Rolling (R) the given time is local time
+# If the leapsecond is Stationary (S) the given time is UTC
+
+# Leap	YEAR	MONTH	DAY	HH:MM:SS	CORR	R/S
+Leap	1972	Jun	30	23:59:60	+	S
+Leap	1972	Dec	31	23:59:60	+	S
+Leap	1973	Dec	31	23:59:60	+	S
+Leap	1974	Dec	31	23:59:60	+	S
+Leap	1975	Dec	31	23:59:60	+	S
+Leap	1976	Dec	31	23:59:60	+	S
+Leap	1977	Dec	31	23:59:60	+	S
+Leap	1978	Dec	31	23:59:60	+	S
+Leap	1979	Dec	31	23:59:60	+	S
+Leap	1981	Jun	30	23:59:60	+	S
+Leap	1982	Jun	30	23:59:60	+	S
+Leap	1983	Jun	30	23:59:60	+	S
+Leap	1985	Jun	30	23:59:60	+	S
+Leap	1987	Dec	31	23:59:60	+	S
+Leap	1989	Dec	31	23:59:60	+	S
+Leap	1990	Dec	31	23:59:60	+	S
+Leap	1992	Jun	30	23:59:60	+	S
+Leap	1993	Jun	30	23:59:60	+	S
+Leap	1994	Jun	30	23:59:60	+	S
+Leap	1995	Dec	31	23:59:60	+	S
+Leap	1997	Jun	30	23:59:60	+	S
+Leap	1998	Dec	31	23:59:60	+	S
+Leap	2005	Dec	31	23:59:60	+	S
+Leap	2008	Dec	31	23:59:60	+	S
+
+# INTERNATIONAL EARTH ROTATION AND REFERENCE SYSTEMS SERVICE (IERS)
+#
+# SERVICE INTERNATIONAL DE LA ROTATION TERRESTRE ET DES SYSTEMES DE REFERENCE
+#
+# SERVICE DE LA ROTATION TERRESTRE
+# OBSERVATOIRE DE PARIS
+# 61, Av. de l'Observatoire 75014 PARIS (France)
+# Tel.      : 33 (0) 1 40 51 22 26
+# FAX       : 33 (0) 1 40 51 22 91
+# e-mail    : services.iers@obspm.fr
+# http://hpiers.obspm.fr/eop-pc
+#
+# Paris, 4 July 2008
+#
+# Bulletin C 36
+#
+# To authorities responsible
+# for the measurement and
+# distribution of time
+#
+# UTC TIME STEP
+# on the 1st of January 2009
+#
+# A positive leap second will be introduced at the end of December 2008.
+# The sequence of dates of the UTC second markers will be:		
+#
+# 2008 December 31,     23h 59m 59s
+# 2008 December 31,     23h 59m 60s
+# 2009 January   1,      0h  0m  0s
+#
+# The difference between UTC and the International Atomic Time TAI is:
+#
+# from 2006 January 1, 0h UTC, to 2009 January 1  0h UTC  : UTC-TAI = - 33s
+# from 2009 January 1, 0h UTC, until further notice       : UTC-TAI = - 34s
+#
+# Leap seconds can be introduced in UTC at the end of the months of December
+# or June, depending on the evolution of UT1-TAI. Bulletin C is mailed every
+# six months, either to announce a time step in UTC or to confirm that there
+# will be no time step at the next possible date.
+#
+# Daniel GAMBIS
+# Head		
+# Earth Orientation Center of IERS
+# Observatoire de Paris, France
diff --git a/tools/zoneinfo/tzdata2008h/northamerica b/tools/zoneinfo/tzdata2008h/northamerica
new file mode 100644
index 0000000..b8b333c
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/northamerica
@@ -0,0 +1,2651 @@
+# @(#)northamerica	8.24
+# <pre>
+
+# also includes Central America and the Caribbean
+
+# This data is by no means authoritative; if you think you know better,
+# go ahead and edit the file (and please send any changes to
+# tz@elsie.nci.nih.gov for general use in the future).
+
+# From Paul Eggert (1999-03-22):
+# A reliable and entertaining source about time zones is
+# Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
+
+###############################################################################
+
+# United States
+
+# From Paul Eggert (1999-03-31):
+# Howse writes (pp 121-125) that time zones were invented by
+# Professor Charles Ferdinand Dowd (1825-1904),
+# Principal of Temple Grove Ladies' Seminary (Saratoga Springs, NY).
+# His pamphlet ``A System of National Time for Railroads'' (1870)
+# was the result of his proposals at the Convention of Railroad Trunk Lines
+# in New York City (1869-10).  His 1870 proposal was based on Washington, DC,
+# but in 1872-05 he moved the proposed origin to Greenwich.
+# His proposal was adopted by the railroads on 1883-11-18 at 12:00,
+# and the most of the country soon followed suit.
+
+# From Paul Eggert (2005-04-16):
+# That 1883 transition occurred at 12:00 new time, not at 12:00 old time.
+# See p 46 of David Prerau, Seize the daylight, Thunder's Mouth Press (2005).
+
+# From Paul Eggert (2006-03-22):
+# A good source for time zone historical data in the US is
+# Thomas G. Shanks, The American Atlas (5th edition),
+# San Diego: ACS Publications, Inc. (1991).
+# Make sure you have the errata sheet; the book is somewhat useless without it.
+# It is the source for most of the pre-1991 US entries below.
+
+# From Paul Eggert (2001-03-06):
+# Daylight Saving Time was first suggested as a joke by Benjamin Franklin
+# in his whimsical essay ``An Economical Project for Diminishing the Cost
+# of Light'' published in the Journal de Paris (1784-04-26).
+# Not everyone is happy with the results:
+#
+#	I don't really care how time is reckoned so long as there is some
+#	agreement about it, but I object to being told that I am saving
+#	daylight when my reason tells me that I am doing nothing of the kind.
+#	I even object to the implication that I am wasting something
+#	valuable if I stay in bed after the sun has risen.  As an admirer
+#	of moonlight I resent the bossy insistence of those who want to
+#	reduce my time for enjoying it.  At the back of the Daylight Saving
+#	scheme I detect the bony, blue-fingered hand of Puritanism, eager
+#	to push people into bed earlier, and get them up earlier, to make
+#	them healthy, wealthy and wise in spite of themselves.
+#
+#	-- Robertson Davies, The diary of Samuel Marchbanks,
+#	   Clarke, Irwin (1947), XIX, Sunday
+#
+# For more about the first ten years of DST in the United States, see
+# Robert Garland's <a href="http://www.clpgh.org/exhibit/dst.html">
+# Ten years of daylight saving from the Pittsburgh standpoint
+# (Carnegie Library of Pittsburgh, 1927)</a>.
+#
+# Shanks says that DST was called "War Time" in the US in 1918 and 1919.
+# However, DST was imposed by the Standard Time Act of 1918, which
+# was the first nationwide legal time standard, and apparently
+# time was just called "Standard Time" or "Daylight Saving Time".
+
+# From Arthur David Olson:
+# US Daylight Saving Time ended on the last Sunday of *October* in 1974.
+# See, for example, the front page of the Saturday, 1974-10-26
+# and Sunday, 1974-10-27 editions of the Washington Post.
+
+# From Arthur David Olson:
+# Before the Uniform Time Act of 1966 took effect in 1967, observance of
+# Daylight Saving Time in the US was by local option, except during wartime.
+
+# From Arthur David Olson (2000-09-25):
+# Last night I heard part of a rebroadcast of a 1945 Arch Oboler radio drama.
+# In the introduction, Oboler spoke of "Eastern Peace Time."
+# An AltaVista search turned up
+# <a href="http://rowayton.org/rhs/hstaug45.html">:
+# "When the time is announced over the radio now, it is 'Eastern Peace
+# Time' instead of the old familiar 'Eastern War Time.'  Peace is wonderful."
+# </a> (August 1945) by way of confirmation.
+
+# From Joseph Gallant citing
+# George H. Douglas, _The Early Days of Radio Broadcasting_ (1987):
+# At 7 P.M. (Eastern War Time) [on 1945-08-14], the networks were set
+# to switch to London for Attlee's address, but the American people
+# never got to hear his speech live. According to one press account,
+# CBS' Bob Trout was first to announce the word of Japan's surrender,
+# but a few seconds later, NBC, ABC and Mutual also flashed the word
+# of surrender, all of whom interrupting the bells of Big Ben in
+# London which were to precede Mr. Attlee's speech.
+
+# From Paul Eggert (2003-02-09): It was Robert St John, not Bob Trout.  From
+# Myrna Oliver's obituary of St John on page B16 of today's Los Angeles Times:
+#
+# ... a war-weary U.S. clung to radios, awaiting word of Japan's surrender.
+# Any announcement from Asia would reach St. John's New York newsroom on a
+# wire service teletype machine, which had prescribed signals for major news.
+# Associated Press, for example, would ring five bells before spewing out
+# typed copy of an important story, and 10 bells for news "of transcendental
+# importance."
+#
+# On Aug. 14, stalling while talking steadily into the NBC networks' open
+# microphone, St. John heard five bells and waited only to hear a sixth bell,
+# before announcing confidently: "Ladies and gentlemen, World War II is over.
+# The Japanese have agreed to our surrender terms."
+#
+# He had scored a 20-second scoop on other broadcasters.
+
+# From Arthur David Olson (2005-08-22):
+# Paul has been careful to use the "US" rules only in those locations
+# that are part of the United States; this reflects the real scope of
+# U.S. government action.  So even though the "US" rules have changed
+# in the latest release, other countries won't be affected.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	US	1918	1919	-	Mar	lastSun	2:00	1:00	D
+Rule	US	1918	1919	-	Oct	lastSun	2:00	0	S
+Rule	US	1942	only	-	Feb	9	2:00	1:00	W # War
+Rule	US	1945	only	-	Aug	14	23:00u	1:00	P # Peace
+Rule	US	1945	only	-	Sep	30	2:00	0	S
+Rule	US	1967	2006	-	Oct	lastSun	2:00	0	S
+Rule	US	1967	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	US	1974	only	-	Jan	6	2:00	1:00	D
+Rule	US	1975	only	-	Feb	23	2:00	1:00	D
+Rule	US	1976	1986	-	Apr	lastSun	2:00	1:00	D
+Rule	US	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
+Rule	US	2007	max	-	Mar	Sun>=8	2:00	1:00	D
+Rule	US	2007	max	-	Nov	Sun>=1	2:00	0	S
+
+# From Arthur David Olson, 2005-12-19
+# We generate the files specified below to guard against old files with
+# obsolete information being left in the time zone binary directory.
+# We limit the list to names that have appeared in previous versions of
+# this time zone package.
+# We do these as separate Zones rather than as Links to avoid problems if
+# a particular place changes whether it observes DST.
+# We put these specifications here in the northamerica file both to
+# increase the chances that they'll actually get compiled and to
+# avoid the need to duplicate the US rules in another file.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	EST		 -5:00	-	EST
+Zone	MST		 -7:00	-	MST
+Zone	HST		-10:00	-	HST
+Zone	EST5EDT		 -5:00	US	E%sT
+Zone	CST6CDT		 -6:00	US	C%sT
+Zone	MST7MDT		 -7:00	US	M%sT
+Zone	PST8PDT		 -8:00	US	P%sT
+
+# From Bob Devine (1988-01-28):
+# ...Alaska (and Hawaii) had the timezone names changed in 1967.
+#    old			 new
+#    Pacific Standard Time(PST)  -same-
+#    Yukon Standard Time(YST)    -same-
+#    Central Alaska S.T. (CAT)   Alaska-Hawaii St[an]dard Time (AHST)
+#    Nome Standard Time (NT)     Bering Standard Time (BST)
+#
+# ...Alaska's timezone lines were redrawn in 1983 to give only 2 tz.
+#    The YST zone now covers nearly all of the state, AHST just part
+#    of the Aleutian islands.   No DST.
+
+# From Paul Eggert (1995-12-19):
+# The tables below use `NST', not `NT', for Nome Standard Time.
+# I invented `CAWT' for Central Alaska War Time.
+
+# From U. S. Naval Observatory (1989-01-19):
+# USA  EASTERN       5 H  BEHIND UTC    NEW YORK, WASHINGTON
+# USA  EASTERN       4 H  BEHIND UTC    APR 3 - OCT 30
+# USA  CENTRAL       6 H  BEHIND UTC    CHICAGO, HOUSTON
+# USA  CENTRAL       5 H  BEHIND UTC    APR 3 - OCT 30
+# USA  MOUNTAIN      7 H  BEHIND UTC    DENVER
+# USA  MOUNTAIN      6 H  BEHIND UTC    APR 3 - OCT 30
+# USA  PACIFIC       8 H  BEHIND UTC    L.A., SAN FRANCISCO
+# USA  PACIFIC       7 H  BEHIND UTC    APR 3 - OCT 30
+# USA  ALASKA STD    9 H  BEHIND UTC    MOST OF ALASKA     (AKST)
+# USA  ALASKA STD    8 H  BEHIND UTC    APR 3 - OCT 30 (AKDT)
+# USA  ALEUTIAN     10 H  BEHIND UTC    ISLANDS WEST OF 170W
+# USA  - " -         9 H  BEHIND UTC    APR 3 - OCT 30
+# USA  HAWAII       10 H  BEHIND UTC
+# USA  BERING       11 H  BEHIND UTC    SAMOA, MIDWAY
+
+# From Arthur David Olson (1989-01-21):
+# The above dates are for 1988.
+# Note the "AKST" and "AKDT" abbreviations, the claim that there's
+# no DST in Samoa, and the claim that there is DST in Alaska and the
+# Aleutians.
+
+# From Arthur David Olson (1988-02-13):
+# Legal standard time zone names, from United States Code (1982 Edition and
+# Supplement III), Title 15, Chapter 6, Section 260 and forward.  First, names
+# up to 1967-04-01 (when most provisions of the Uniform Time Act of 1966
+# took effect), as explained in sections 263 and 261:
+#	(none)
+#	United States standard eastern time
+#	United States standard mountain time
+#	United States standard central time
+#	United States standard Pacific time
+#	(none)
+#	United States standard Alaska time
+#	(none)
+# Next, names from 1967-04-01 until 1983-11-30 (the date for
+# public law 98-181):
+#	Atlantic standard time
+#	eastern standard time
+#	central standard time
+#	mountain standard time
+#	Pacific standard time
+#	Yukon standard time
+#	Alaska-Hawaii standard time
+#	Bering standard time
+# And after 1983-11-30:
+#	Atlantic standard time
+#	eastern standard time
+#	central standard time
+#	mountain standard time
+#	Pacific standard time
+#	Alaska standard time
+#	Hawaii-Aleutian standard time
+#	Samoa standard time
+# The law doesn't give abbreviations.
+#
+# From Paul Eggert (2000-01-08), following a heads-up from Rives McDow:
+# Public law 106-564 (2000-12-23) introduced the abbreviation
+# "Chamorro Standard Time" for time in Guam and the Northern Marianas.
+# See the file "australasia".
+
+# From Arthur David Olson, 2005-08-09
+# The following was signed into law on 2005-08-08.
+#
+# H.R. 6, Energy Policy Act of 2005, SEC. 110. DAYLIGHT SAVINGS.
+#   (a) Amendment- Section 3(a) of the Uniform Time Act of 1966 (15
+#   U.S.C. 260a(a)) is amended--
+#     (1) by striking `first Sunday of April' and inserting `second
+#     Sunday of March'; and
+#     (2) by striking `last Sunday of October' and inserting `first
+#     Sunday of November'.
+#   (b) Effective Date- Subsection (a) shall take effect 1 year after the
+#   date of enactment of this Act or March 1, 2007, whichever is later.
+#   (c) Report to Congress- Not later than 9 months after the effective
+#   date stated in subsection (b), the Secretary shall report to Congress
+#   on the impact of this section on energy consumption in the United
+#   States.
+#   (d) Right to Revert- Congress retains the right to revert the
+#   Daylight Saving Time back to the 2005 time schedules once the
+#   Department study is complete.
+
+# US eastern time, represented by New York
+
+# Connecticut, Delaware, District of Columbia, most of Florida,
+# Georgia, southeast Indiana (Dearborn and Ohio counties), eastern Kentucky
+# (except America/Kentucky/Louisville below), Maine, Maryland, Massachusetts,
+# New Hampshire, New Jersey, New York, North Carolina, Ohio,
+# Pennsylvania, Rhode Island, South Carolina, eastern Tennessee,
+# Vermont, Virginia, West Virginia
+
+# From Dave Cantor (2004-11-02):
+# Early this summer I had the occasion to visit the Mount Washington
+# Observatory weather station atop (of course!) Mount Washington [, NH]....
+# One of the staff members said that the station was on Eastern Standard Time
+# and didn't change their clocks for Daylight Saving ... so that their
+# reports will always have times which are 5 hours behind UTC.
+
+# From Paul Eggert (2005-08-26):
+# According to today's Huntsville Times
+# <http://www.al.com/news/huntsvilletimes/index.ssf?/base/news/1125047783228320.xml&coll=1>
+# a few towns on Alabama's "eastern border with Georgia, such as Phenix City
+# in Russell County, Lanett in Chambers County and some towns in Lee County,
+# set their watches and clocks on Eastern time."  It quotes H.H. "Bubba"
+# Roberts, city administrator in Phenix City. as saying "We are in the Central
+# time zone, but we do go by the Eastern time zone because so many people work
+# in Columbus."
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	NYC	1920	only	-	Mar	lastSun	2:00	1:00	D
+Rule	NYC	1920	only	-	Oct	lastSun	2:00	0	S
+Rule	NYC	1921	1966	-	Apr	lastSun	2:00	1:00	D
+Rule	NYC	1921	1954	-	Sep	lastSun	2:00	0	S
+Rule	NYC	1955	1966	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/New_York	-4:56:02 -	LMT	1883 Nov 18 12:03:58
+			-5:00	US	E%sT	1920
+			-5:00	NYC	E%sT	1942
+			-5:00	US	E%sT	1946
+			-5:00	NYC	E%sT	1967
+			-5:00	US	E%sT
+
+# US central time, represented by Chicago
+
+# Alabama, Arkansas, Florida panhandle (Bay, Calhoun, Escambia,
+# Gulf, Holmes, Jackson, Okaloosa, Santa Rosa, Walton, and
+# Washington counties), Illinois, western Indiana
+# (Gibson, Jasper, Lake, LaPorte, Newton, Porter, Posey, Spencer,
+# Vanderburgh, and Warrick counties), Iowa, most of Kansas, western
+# Kentucky, Louisiana, Minnesota, Mississippi, Missouri, eastern
+# Nebraska, eastern North Dakota, Oklahoma, eastern South Dakota,
+# western Tennessee, most of Texas, Wisconsin
+
+# From Larry M. Smith (2006-04-26) re Wisconsin:
+# http://www.legis.state.wi.us/statutes/Stat0175.pdf ...
+# is currently enforced at the 01:00 time of change.  Because the local
+# "bar time" in the state corresponds to 02:00, a number of citations
+# are issued for the "sale of class 'B' alcohol after prohibited
+# hours" within the deviated hour of this change every year....
+#
+# From Douglas R. Bomberg (2007-03-12):
+# Wisconsin has enacted (nearly eleventh-hour) legislation to get WI
+# Statue 175 closer in synch with the US Congress' intent....
+# http://www.legis.state.wi.us/2007/data/acts/07Act3.pdf
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	Chicago	1920	only	-	Jun	13	2:00	1:00	D
+Rule	Chicago	1920	1921	-	Oct	lastSun	2:00	0	S
+Rule	Chicago	1921	only	-	Mar	lastSun	2:00	1:00	D
+Rule	Chicago	1922	1966	-	Apr	lastSun	2:00	1:00	D
+Rule	Chicago	1922	1954	-	Sep	lastSun	2:00	0	S
+Rule	Chicago	1955	1966	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Chicago	-5:50:36 -	LMT	1883 Nov 18 12:09:24
+			-6:00	US	C%sT	1920
+			-6:00	Chicago	C%sT	1936 Mar  1 2:00
+			-5:00	-	EST	1936 Nov 15 2:00
+			-6:00	Chicago	C%sT	1942
+			-6:00	US	C%sT	1946
+			-6:00	Chicago	C%sT	1967
+			-6:00	US	C%sT
+# Oliver County, ND switched from mountain to central time on 1992-10-25.
+Zone America/North_Dakota/Center -6:45:12 - LMT	1883 Nov 18 12:14:48
+			-7:00	US	M%sT	1992 Oct 25 02:00
+			-6:00	US	C%sT
+# Morton County, ND, switched from mountain to central time on
+# 2003-10-26, except for the area around Mandan which was already central time.
+# See <http://dmses.dot.gov/docimages/p63/135818.pdf>.
+# Officially this switch also included part of Sioux County, and
+# Jones, Mellette, and Todd Counties in South Dakota;
+# but in practice these other counties were already observing central time.
+# See <http://www.epa.gov/fedrgstr/EPA-IMPACT/2003/October/Day-28/i27056.htm>.
+Zone America/North_Dakota/New_Salem -6:45:39 - LMT 1883 Nov 18 12:14:21
+			-7:00	US	M%sT	2003 Oct 26 02:00
+			-6:00	US	C%sT
+
+# US mountain time, represented by Denver
+#
+# Colorado, far western Kansas, Montana, western
+# Nebraska, Nevada border (Jackpot, Owyhee, and Mountain City),
+# New Mexico, southwestern North Dakota,
+# western South Dakota, far western Texas (El Paso County, Hudspeth County,
+# and Pine Springs and Nickel Creek in Culberson County), Utah, Wyoming
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	Denver	1920	1921	-	Mar	lastSun	2:00	1:00	D
+Rule	Denver	1920	only	-	Oct	lastSun	2:00	0	S
+Rule	Denver	1921	only	-	May	22	2:00	0	S
+Rule	Denver	1965	1966	-	Apr	lastSun	2:00	1:00	D
+Rule	Denver	1965	1966	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Denver	-6:59:56 -	LMT	1883 Nov 18 12:00:04
+			-7:00	US	M%sT	1920
+			-7:00	Denver	M%sT	1942
+			-7:00	US	M%sT	1946
+			-7:00	Denver	M%sT	1967
+			-7:00	US	M%sT
+
+# US Pacific time, represented by Los Angeles
+#
+# California, northern Idaho (Benewah, Bonner, Boundary, Clearwater,
+# Idaho, Kootenai, Latah, Lewis, Nez Perce, and Shoshone counties,
+# and the northern three-quarters of Idaho county),
+# most of Nevada, most of Oregon, and Washington
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	CA	1948	only	-	Mar	14	2:00	1:00	D
+Rule	CA	1949	only	-	Jan	 1	2:00	0	S
+Rule	CA	1950	1966	-	Apr	lastSun	2:00	1:00	D
+Rule	CA	1950	1961	-	Sep	lastSun	2:00	0	S
+Rule	CA	1962	1966	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Los_Angeles -7:52:58 -	LMT	1883 Nov 18 12:07:02
+			-8:00	US	P%sT	1946
+			-8:00	CA	P%sT	1967
+			-8:00	US	P%sT
+
+# Alaska
+# AK%sT is the modern abbreviation for -9:00 per USNO.
+#
+# From Paul Eggert (2001-05-30):
+# Howse writes that Alaska switched from the Julian to the Gregorian calendar,
+# and from east-of-GMT to west-of-GMT days, when the US bought it from Russia.
+# This was on 1867-10-18, a Friday; the previous day was 1867-10-06 Julian,
+# also a Friday.  Include only the time zone part of this transition,
+# ignoring the switch from Julian to Gregorian, since we can't represent
+# the Julian calendar.
+#
+# As far as we know, none of the exact locations mentioned below were
+# permanently inhabited in 1867 by anyone using either calendar.
+# (Yakutat was colonized by the Russians in 1799, but the settlement
+# was destroyed in 1805 by a Yakutat-kon war party.)  However, there
+# were nearby inhabitants in some cases and for our purposes perhaps
+# it's best to simply use the official transition.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Juneau	 15:02:19 -	LMT	1867 Oct 18
+			 -8:57:41 -	LMT	1900 Aug 20 12:00
+			 -8:00	-	PST	1942
+			 -8:00	US	P%sT	1946
+			 -8:00	-	PST	1969
+			 -8:00	US	P%sT	1983 Oct 30 2:00
+			 -9:00	US	Y%sT	1983 Nov 30
+			 -9:00	US	AK%sT
+Zone America/Yakutat	 14:41:05 -	LMT	1867 Oct 18
+			 -9:18:55 -	LMT	1900 Aug 20 12:00
+			 -9:00	-	YST	1942
+			 -9:00	US	Y%sT	1946
+			 -9:00	-	YST	1969
+			 -9:00	US	Y%sT	1983 Nov 30
+			 -9:00	US	AK%sT
+Zone America/Anchorage	 14:00:24 -	LMT	1867 Oct 18
+			 -9:59:36 -	LMT	1900 Aug 20 12:00
+			-10:00	-	CAT	1942
+			-10:00	US	CAT/CAWT 1945 Aug 14 23:00u
+			-10:00	US	CAT/CAPT 1946 # Peace
+			-10:00	-	CAT	1967 Apr
+			-10:00	-	AHST	1969
+			-10:00	US	AH%sT	1983 Oct 30 2:00
+			 -9:00	US	Y%sT	1983 Nov 30
+			 -9:00	US	AK%sT
+Zone America/Nome	 12:58:21 -	LMT	1867 Oct 18
+			-11:01:38 -	LMT	1900 Aug 20 12:00
+			-11:00	-	NST	1942
+			-11:00	US	N%sT	1946
+			-11:00	-	NST	1967 Apr
+			-11:00	-	BST	1969
+			-11:00	US	B%sT	1983 Oct 30 2:00
+			 -9:00	US	Y%sT	1983 Nov 30
+			 -9:00	US	AK%sT
+Zone America/Adak	 12:13:21 -	LMT	1867 Oct 18
+			-11:46:38 -	LMT	1900 Aug 20 12:00
+			-11:00	-	NST	1942
+			-11:00	US	N%sT	1946
+			-11:00	-	NST	1967 Apr
+			-11:00	-	BST	1969
+			-11:00	US	B%sT	1983 Oct 30 2:00
+			-10:00	US	AH%sT	1983 Nov 30
+			-10:00	US	HA%sT
+# The following switches don't quite make our 1970 cutoff.
+#
+# Shanks writes that part of southwest Alaska (e.g. Aniak)
+# switched from -11:00 to -10:00 on 1968-09-22 at 02:00,
+# and another part (e.g. Akiak) made the same switch five weeks later.
+#
+# From David Flater (2004-11-09):
+# In e-mail, 2004-11-02, Ray Hudson, historian/liaison to the Unalaska
+# Historic Preservation Commission, provided this information, which
+# suggests that Unalaska deviated from statutory time from early 1967
+# possibly until 1983:
+#
+#  Minutes of the Unalaska City Council Meeting, January 10, 1967:
+#  "Except for St. Paul and Akutan, Unalaska is the only important
+#  location not on Alaska Standard Time.  The following resolution was
+#  made by William Robinson and seconded by Henry Swanson:  Be it
+#  resolved that the City of Unalaska hereby goes to Alaska Standard
+#  Time as of midnight Friday, January 13, 1967 (1 A.M. Saturday,
+#  January 14, Alaska Standard Time.)  This resolution was passed with
+#  three votes for and one against."
+
+# Hawaii
+#
+# From Arthur David Olson:
+# And then there's Hawaii.
+# DST was observed for one day in 1933;
+# standard time was changed by half an hour in 1947;
+# it's always standard as of 1986.
+#
+# From Paul Eggert:
+# Shanks says the 1933 experiment lasted for three weeks.  Go with Shanks.
+#
+Zone Pacific/Honolulu	-10:31:26 -	LMT	1900 Jan  1 12:00
+			-10:30	-	HST	1933 Apr 30 2:00
+			-10:30	1:00	HDT	1933 May 21 2:00
+			-10:30	US	H%sT	1947 Jun  8 2:00
+			-10:00	-	HST
+
+# Now we turn to US areas that have diverged from the consensus since 1970.
+
+# Arizona mostly uses MST.
+
+# From Paul Eggert (2002-10-20):
+#
+# The information in the rest of this paragraph is derived from the
+# <a href="http://www.dlapr.lib.az.us/links/daylight.htm">
+# Daylight Saving Time web page (2002-01-23)</a> maintained by the
+# Arizona State Library, Archives and Public Records.
+# Between 1944-01-01 and 1944-04-01 the State of Arizona used standard
+# time, but by federal law railroads, airlines, bus lines, military
+# personnel, and some engaged in interstate commerce continued to
+# observe war (i.e., daylight saving) time.  The 1944-03-17 Phoenix
+# Gazette says that was the date the law changed, and that 04-01 was
+# the date the state's clocks would change.  In 1945 the State of
+# Arizona used standard time all year, again with exceptions only as
+# mandated by federal law.  Arizona observed DST in 1967, but Arizona
+# Laws 1968, ch. 183 (effective 1968-03-21) repealed DST.
+#
+# Shanks says the 1944 experiment came to an end on 1944-03-17.
+# Go with the Arizona State Library instead.
+
+Zone America/Phoenix	-7:28:18 -	LMT	1883 Nov 18 11:31:42
+			-7:00	US	M%sT	1944 Jan  1 00:01
+			-7:00	-	MST	1944 Apr  1 00:01
+			-7:00	US	M%sT	1944 Oct  1 00:01
+			-7:00	-	MST	1967
+			-7:00	US	M%sT	1968 Mar 21
+			-7:00	-	MST
+# From Arthur David Olson (1988-02-13):
+# A writer from the Inter Tribal Council of Arizona, Inc.,
+# notes in private correspondence dated 1987-12-28 that "Presently, only the
+# Navajo Nation participates in the Daylight Saving Time policy, due to its
+# large size and location in three states."  (The "only" means that other
+# tribal nations don't use DST.)
+
+Link America/Denver America/Shiprock
+
+# Southern Idaho (Ada, Adams, Bannock, Bear Lake, Bingham, Blaine,
+# Boise, Bonneville, Butte, Camas, Canyon, Caribou, Cassia, Clark,
+# Custer, Elmore, Franklin, Fremont, Gem, Gooding, Jefferson, Jerome,
+# Lemhi, Lincoln, Madison, Minidoka, Oneida, Owyhee, Payette, Power,
+# Teton, Twin Falls, Valley, Washington counties, and the southern
+# quarter of Idaho county) and eastern Oregon (most of Malheur County)
+# switched four weeks late in 1974.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Boise	-7:44:49 -	LMT	1883 Nov 18 12:15:11
+			-8:00	US	P%sT	1923 May 13 2:00
+			-7:00	US	M%sT	1974
+			-7:00	-	MST	1974 Feb  3 2:00
+			-7:00	US	M%sT
+
+# Indiana
+#
+# For a map of Indiana's time zone regions, see:
+# <a href="http://www.mccsc.edu/time.html">
+# What time is it in Indiana?
+# </a> (2006-03-01)
+#
+# From Paul Eggert (2007-08-17):
+# Since 1970, most of Indiana has been like America/Indiana/Indianapolis,
+# with the following exceptions:
+#
+# - Gibson, Jasper, Lake, LaPorte, Newton, Porter, Posey, Spencer,
+#   Vandenburgh, and Warrick counties have been like America/Chicago.
+#
+# - Dearborn and Ohio counties have been like America/New_York.
+#
+# - Clark, Floyd, and Harrison counties have been like
+#   America/Kentucky/Louisville.
+#
+# - Crawford, Daviess, Dubois, Knox, Martin, Perry, Pike, Pulaski, Starke,
+#   and Switzerland counties have their own time zone histories as noted below.
+#
+# Shanks partitioned Indiana into 345 regions, each with its own time history,
+# and wrote ``Even newspaper reports present contradictory information.''
+# Those Hoosiers!  Such a flighty and changeable people!
+# Fortunately, most of the complexity occurred before our cutoff date of 1970.
+#
+# Other than Indianapolis, the Indiana place names are so nondescript
+# that they would be ambiguous if we left them at the `America' level.
+# So we reluctantly put them all in a subdirectory `America/Indiana'.
+
+# From Paul Eggert (2005-08-16):
+# http://www.mccsc.edu/time.html says that Indiana will use DST starting 2006.
+
+# From Nathan Stratton Treadway (2006-03-30):
+# http://www.dot.gov/affairs/dot0406.htm [3705 B]
+# From Deborah Goldsmith (2006-01-18):
+# http://dmses.dot.gov/docimages/pdf95/382329_web.pdf [2.9 MB]
+# From Paul Eggert (2006-01-20):
+# It says "DOT is relocating the time zone boundary in Indiana to move Starke,
+# Pulaski, Knox, Daviess, Martin, Pike, Dubois, and Perry Counties from the
+# Eastern Time Zone to the Central Time Zone.... The effective date of
+# this rule is 2:OO a.m. EST Sunday, April 2, 2006, which is the
+# changeover date from standard time to Daylight Saving Time."
+# Strictly speaking, this means the affected counties will change their
+# clocks twice that night, but this obviously is in error.  The intent
+# is that 01:59:59 EST be followed by 02:00:00 CDT.
+
+# From Gwillim Law (2007-02-10):
+# The Associated Press has been reporting that Pulaski County, Indiana is
+# going to switch from Central to Eastern Time on March 11, 2007....
+# http://www.indystar.com/apps/pbcs.dll/article?AID=/20070207/LOCAL190108/702070524/0/LOCAL
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule Indianapolis 1941	only	-	Jun	22	2:00	1:00	D
+Rule Indianapolis 1941	1954	-	Sep	lastSun	2:00	0	S
+Rule Indianapolis 1946	1954	-	Apr	lastSun	2:00	1:00	D
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Indianapolis -5:44:38 - LMT 1883 Nov 18 12:15:22
+			-6:00	US	C%sT	1920
+			-6:00 Indianapolis C%sT	1942
+			-6:00	US	C%sT	1946
+			-6:00 Indianapolis C%sT	1955 Apr 24 2:00
+			-5:00	-	EST	1957 Sep 29 2:00
+			-6:00	-	CST	1958 Apr 27 2:00
+			-5:00	-	EST	1969
+			-5:00	US	E%sT	1971
+			-5:00	-	EST	2006
+			-5:00	US	E%sT
+#
+# Eastern Crawford County, Indiana, left its clocks alone in 1974,
+# as well as from 1976 through 2005.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	Marengo	1951	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Marengo	1951	only	-	Sep	lastSun	2:00	0	S
+Rule	Marengo	1954	1960	-	Apr	lastSun	2:00	1:00	D
+Rule	Marengo	1954	1960	-	Sep	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Marengo -5:45:23 -	LMT	1883 Nov 18 12:14:37
+			-6:00	US	C%sT	1951
+			-6:00	Marengo	C%sT	1961 Apr 30 2:00
+			-5:00	-	EST	1969
+			-5:00	US	E%sT	1974 Jan  6 2:00
+			-6:00	1:00	CDT	1974 Oct 27 2:00
+			-5:00	US	E%sT	1976
+			-5:00	-	EST	2006
+			-5:00	US	E%sT
+#
+# Daviess, Dubois, Knox, and Martin Counties, Indiana,
+# switched from eastern to central time in April 2006, then switched back
+# in November 2007.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule Vincennes	1946	only	-	Apr	lastSun	2:00	1:00	D
+Rule Vincennes	1946	only	-	Sep	lastSun	2:00	0	S
+Rule Vincennes	1953	1954	-	Apr	lastSun	2:00	1:00	D
+Rule Vincennes	1953	1959	-	Sep	lastSun	2:00	0	S
+Rule Vincennes	1955	only	-	May	 1	0:00	1:00	D
+Rule Vincennes	1956	1963	-	Apr	lastSun	2:00	1:00	D
+Rule Vincennes	1960	only	-	Oct	lastSun	2:00	0	S
+Rule Vincennes	1961	only	-	Sep	lastSun	2:00	0	S
+Rule Vincennes	1962	1963	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Vincennes -5:50:07 - LMT	1883 Nov 18 12:09:53
+			-6:00	US	C%sT	1946
+			-6:00 Vincennes	C%sT	1964 Apr 26 2:00
+			-5:00	-	EST	1969
+			-5:00	US	E%sT	1971
+			-5:00	-	EST	2006 Apr  2 2:00
+			-6:00	US	C%sT	2007 Nov  4 2:00
+			-5:00	US	E%sT
+#
+# Perry County, Indiana, switched from eastern to central time in April 2006.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule Perry	1946	only	-	Apr	lastSun	2:00	1:00	D
+Rule Perry	1946	only	-	Sep	lastSun	2:00	0	S
+Rule Perry	1953	1954	-	Apr	lastSun	2:00	1:00	D
+Rule Perry	1953	1959	-	Sep	lastSun	2:00	0	S
+Rule Perry	1955	only	-	May	 1	0:00	1:00	D
+Rule Perry	1956	1963	-	Apr	lastSun	2:00	1:00	D
+Rule Perry	1960	only	-	Oct	lastSun	2:00	0	S
+Rule Perry	1961	only	-	Sep	lastSun	2:00	0	S
+Rule Perry	1962	1963	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Tell_City -5:47:03 - LMT	1883 Nov 18 12:12:57
+			-6:00	US	C%sT	1946
+			-6:00 Perry	C%sT	1964 Apr 26 2:00
+			-5:00	-	EST	1969
+			-5:00	US	E%sT	1971
+			-5:00	-	EST	2006 Apr  2 2:00
+			-6:00	US	C%sT
+#
+# Pike County, Indiana moved from central to eastern time in 1977,
+# then switched back in 2006, then switched back again in 2007.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	Pike	1955	only	-	May	 1	0:00	1:00	D
+Rule	Pike	1955	1960	-	Sep	lastSun	2:00	0	S
+Rule	Pike	1956	1964	-	Apr	lastSun	2:00	1:00	D
+Rule	Pike	1961	1964	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Petersburg -5:49:07 - LMT	1883 Nov 18 12:10:53
+			-6:00	US	C%sT	1955
+			-6:00	Pike	C%sT	1965 Apr 25 2:00
+			-5:00	-	EST	1966 Oct 30 2:00
+			-6:00	US	C%sT	1977 Oct 30 2:00
+			-5:00	-	EST	2006 Apr  2 2:00
+			-6:00	US	C%sT	2007 Nov  4 2:00
+			-5:00	US	E%sT
+#
+# Starke County, Indiana moved from central to eastern time in 1991,
+# then switched back in 2006.
+# From Arthur David Olson (1991-10-28):
+# An article on page A3 of the Sunday, 1991-10-27 Washington Post
+# notes that Starke County switched from Central time to Eastern time as of
+# 1991-10-27.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	Starke	1947	1961	-	Apr	lastSun	2:00	1:00	D
+Rule	Starke	1947	1954	-	Sep	lastSun	2:00	0	S
+Rule	Starke	1955	1956	-	Oct	lastSun	2:00	0	S
+Rule	Starke	1957	1958	-	Sep	lastSun	2:00	0	S
+Rule	Starke	1959	1961	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Knox -5:46:30 -	LMT	1883 Nov 18 12:13:30
+			-6:00	US	C%sT	1947
+			-6:00	Starke	C%sT	1962 Apr 29 2:00
+			-5:00	-	EST	1963 Oct 27 2:00
+			-6:00	US	C%sT	1991 Oct 27 2:00
+			-5:00	-	EST	2006 Apr  2 2:00
+			-6:00	US	C%sT
+#
+# Pulaski County, Indiana, switched from eastern to central time in
+# April 2006 and then switched back in March 2007.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	Pulaski	1946	1960	-	Apr	lastSun	2:00	1:00	D
+Rule	Pulaski	1946	1954	-	Sep	lastSun	2:00	0	S
+Rule	Pulaski	1955	1956	-	Oct	lastSun	2:00	0	S
+Rule	Pulaski	1957	1960	-	Sep	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Winamac -5:46:25 - LMT	1883 Nov 18 12:13:35
+			-6:00	US	C%sT	1946
+			-6:00	Pulaski	C%sT	1961 Apr 30 2:00
+			-5:00	-	EST	1969
+			-5:00	US	E%sT	1971
+			-5:00	-	EST	2006 Apr  2 2:00
+			-6:00	US	C%sT	2007 Mar 11 2:00
+			-5:00	US	E%sT
+#
+# Switzerland County, Indiana, did not observe DST from 1973 through 2005.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Indiana/Vevay -5:40:16 -	LMT	1883 Nov 18 12:19:44
+			-6:00	US	C%sT	1954 Apr 25 2:00
+			-5:00	-	EST	1969
+			-5:00	US	E%sT	1973
+			-5:00	-	EST	2006
+			-5:00	US	E%sT
+
+# Part of Kentucky left its clocks alone in 1974.
+# This also includes Clark, Floyd, and Harrison counties in Indiana.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule Louisville	1921	only	-	May	1	2:00	1:00	D
+Rule Louisville	1921	only	-	Sep	1	2:00	0	S
+Rule Louisville	1941	1961	-	Apr	lastSun	2:00	1:00	D
+Rule Louisville	1941	only	-	Sep	lastSun	2:00	0	S
+Rule Louisville	1946	only	-	Jun	2	2:00	0	S
+Rule Louisville	1950	1955	-	Sep	lastSun	2:00	0	S
+Rule Louisville	1956	1960	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Kentucky/Louisville -5:43:02 -	LMT	1883 Nov 18 12:16:58
+			-6:00	US	C%sT	1921
+			-6:00 Louisville C%sT	1942
+			-6:00	US	C%sT	1946
+			-6:00 Louisville C%sT	1961 Jul 23 2:00
+			-5:00	-	EST	1968
+			-5:00	US	E%sT	1974 Jan  6 2:00
+			-6:00	1:00	CDT	1974 Oct 27 2:00
+			-5:00	US	E%sT
+#
+# Wayne County, Kentucky
+#
+# From
+# <a href="http://www.lake-cumberland.com/life/archive/news990129time.shtml">
+# Lake Cumberland LIFE
+# </a> (1999-01-29) via WKYM-101.7:
+# Clinton County has joined Wayne County in asking the DoT to change from
+# the Central to the Eastern time zone....  The Wayne County government made
+# the same request in December.  And while Russell County officials have not
+# taken action, the majority of respondents to a poll conducted there in
+# August indicated they would like to change to "fast time" also.
+# The three Lake Cumberland counties are the farthest east of any U.S.
+# location in the Central time zone.
+#
+# From Rich Wales (2000-08-29):
+# After prolonged debate, and despite continuing deep differences of opinion,
+# Wayne County (central Kentucky) is switching from Central (-0600) to Eastern
+# (-0500) time.  They won't "fall back" this year.  See Sara Shipley,
+# The difference an hour makes, Nando Times (2000-08-29 15:33 -0400).
+#
+# From Paul Eggert (2001-07-16):
+# The final rule was published in the
+# <a href="http://frwebgate.access.gpo.gov/cgi-bin/getdoc.cgi?dbname=2000_register&docid=fr17au00-22">
+# Federal Register 65, 160 (2000-08-17), page 50154-50158.
+# </a>
+#
+Zone America/Kentucky/Monticello -5:39:24 - LMT	1883 Nov 18 12:20:36
+			-6:00	US	C%sT	1946
+			-6:00	-	CST	1968
+			-6:00	US	C%sT	2000 Oct 29  2:00
+			-5:00	US	E%sT
+
+
+# From Rives McDow (2000-08-30):
+# Here ... are all the changes in the US since 1985.
+# Kearny County, KS (put all of county on central;
+#	previously split between MST and CST) ... 1990-10
+# Starke County, IN (from CST to EST) ... 1991-10
+# Oliver County, ND (from MST to CST) ... 1992-10
+# West Wendover, NV (from PST TO MST) ... 1999-10
+# Wayne County, KY (from CST to EST) ... 2000-10
+#
+# From Paul Eggert (2001-07-17):
+# We don't know where the line used to be within Kearny County, KS,
+# so omit that change for now.
+# See America/Indiana/Knox for the Starke County, IN change.
+# See America/North_Dakota/Center for the Oliver County, ND change.
+# West Wendover, NV officially switched from Pacific to mountain time on
+# 1999-10-31.  See the
+# <a href="http://frwebgate.access.gpo.gov/cgi-bin/getdoc.cgi?dbname=1999_register&docid=fr21oc99-15">
+# Federal Register 64, 203 (1999-10-21), page 56705-56707.
+# </a>
+# However, the Federal Register says that West Wendover already operated
+# on mountain time, and the rule merely made this official;
+# hence a separate tz entry is not needed.
+
+# Michigan
+#
+# From Bob Devine (1988-01-28):
+# Michigan didn't observe DST from 1968 to 1973.
+#
+# From Paul Eggert (1999-03-31):
+# Shanks writes that Michigan started using standard time on 1885-09-18,
+# but Howse writes (pp 124-125, referring to Popular Astronomy, 1901-01)
+# that Detroit kept
+#
+#	local time until 1900 when the City Council decreed that clocks should
+#	be put back twenty-eight minutes to Central Standard Time.  Half the
+#	city obeyed, half refused.  After considerable debate, the decision
+#	was rescinded and the city reverted to Sun time.  A derisive offer to
+#	erect a sundial in front of the city hall was referred to the
+#	Committee on Sewers.  Then, in 1905, Central time was adopted
+#	by city vote.
+#
+# This story is too entertaining to be false, so go with Howse over Shanks.
+#
+# From Paul Eggert (2001-03-06):
+# Garland (1927) writes ``Cleveland and Detroit advanced their clocks
+# one hour in 1914.''  This change is not in Shanks.  We have no more
+# info, so omit this for now.
+#
+# Most of Michigan observed DST from 1973 on, but was a bit late in 1975.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule	Detroit	1948	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Detroit	1948	only	-	Sep	lastSun	2:00	0	S
+Rule	Detroit	1967	only	-	Jun	14	2:00	1:00	D
+Rule	Detroit	1967	only	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Detroit	-5:32:11 -	LMT	1905
+			-6:00	-	CST	1915 May 15 2:00
+			-5:00	-	EST	1942
+			-5:00	US	E%sT	1946
+			-5:00	Detroit	E%sT	1973
+			-5:00	US	E%sT	1975
+			-5:00	-	EST	1975 Apr 27 2:00
+			-5:00	US	E%sT
+#
+# Dickinson, Gogebic, Iron, and Menominee Counties, Michigan,
+# switched from EST to CST/CDT in 1973.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER
+Rule Menominee	1946	only	-	Apr	lastSun	2:00	1:00	D
+Rule Menominee	1946	only	-	Sep	lastSun	2:00	0	S
+Rule Menominee	1966	only	-	Apr	lastSun	2:00	1:00	D
+Rule Menominee	1966	only	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Menominee	-5:50:27 -	LMT	1885 Sep 18 12:00
+			-6:00	US	C%sT	1946
+			-6:00 Menominee	C%sT	1969 Apr 27 2:00
+			-5:00	-	EST	1973 Apr 29 2:00
+			-6:00	US	C%sT
+
+# Navassa
+# administered by the US Fish and Wildlife Service
+# claimed by US under the provisions of the 1856 Guano Islands Act
+# also claimed by Haiti
+# occupied 1857/1900 by the Navassa Phosphate Co
+# US lighthouse 1917/1996-09
+# currently uninhabited
+# see Mark Fineman, ``An Isle Rich in Guano and Discord'',
+# _Los Angeles Times_ (1998-11-10), A1, A10; it cites
+# Jimmy Skaggs, _The Great Guano Rush_ (1994).
+
+################################################################################
+
+
+# From Paul Eggert (2006-03-22):
+# A good source for time zone historical data outside the U.S. is
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
+# San Diego: ACS Publications, Inc. (2003).
+#
+# Gwillim Law writes that a good source
+# for recent time zone data is the International Air Transport
+# Association's Standard Schedules Information Manual (IATA SSIM),
+# published semiannually.  Law sent in several helpful summaries
+# of the IATA's data after 1990.
+#
+# Except where otherwise noted, Shanks & Pottenger is the source for
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
+#
+# Other sources occasionally used include:
+#
+#	Edward W. Whitman, World Time Differences,
+#	Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated),
+#	which I found in the UCLA library.
+#
+#	<a href="http://www.pettswoodvillage.co.uk/Daylight_Savings_William_Willett.pdf">
+#	William Willett, The Waste of Daylight, 19th edition
+#	</a> (1914-03)
+#
+# See the `europe' file for Greenland.
+
+# Canada
+
+# From Alain LaBont<e'> (1994-11-14):
+# I post here the time zone abbreviations standardized in Canada
+# for both English and French in the CAN/CSA-Z234.4-89 standard....
+#
+#	UTC	Standard time	Daylight savings time
+#	offset	French	English	French	English
+#	-2:30	-	-	HAT	NDT
+#	-3	-	-	HAA	ADT
+#	-3:30	HNT	NST	-	-
+#	-4	HNA	AST	HAE	EDT
+#	-5	HNE	EST	HAC	CDT
+#	-6	HNC	CST	HAR	MDT
+#	-7	HNR	MST	HAP	PDT
+#	-8	HNP	PST	HAY	YDT
+#	-9	HNY	YST	-	-
+#
+#	HN: Heure Normale	ST: Standard Time
+#	HA: Heure Avanc<e'>e	DT: Daylight saving Time
+#
+#	A: de l'Atlantique	Atlantic
+#	C: du Centre		Central
+#	E: de l'Est		Eastern
+#	M:			Mountain
+#	N:			Newfoundland
+#	P: du Pacifique		Pacific
+#	R: des Rocheuses
+#	T: de Terre-Neuve
+#	Y: du Yukon		Yukon
+#
+# From Paul Eggert (1994-11-22):
+# Alas, this sort of thing must be handled by localization software.
+
+# Unless otherwise specified, the data for Canada are all from Shanks
+# & Pottenger.
+
+# From Chris Walton (2006-04-01, 2006-04-25, 2006-06-26, 2007-01-31,
+# 2007-03-01):
+# The British Columbia government announced yesterday that it will
+# adjust daylight savings next year to align with changes in the
+# U.S. and the rest of Canada....
+# http://www2.news.gov.bc.ca/news_releases_2005-2009/2006AG0014-000330.htm
+# ...
+# Nova Scotia
+# Daylight saving time will be extended by four weeks starting in 2007....
+# http://www.gov.ns.ca/just/regulations/rg2/2006/ma1206.pdf
+#
+# [For New Brunswick] the new legislation dictates that the time change is to
+# be done at 02:00 instead of 00:01.
+# http://www.gnb.ca/0062/acts/BBA-2006/Chap-19.pdf
+# ...
+# Manitoba has traditionally changed the clock every fall at 03:00.
+# As of 2006, the transition is to take place one hour earlier at 02:00.
+# http://web2.gov.mb.ca/laws/statutes/ccsm/o030e.php
+# ...
+# [Alberta, Ontario, Quebec] will follow US rules.
+# http://www.qp.gov.ab.ca/documents/spring/CH03_06.CFM
+# http://www.e-laws.gov.on.ca/DBLaws/Source/Regs/English/2006/R06111_e.htm
+# http://www2.publicationsduquebec.gouv.qc.ca/dynamicSearch/telecharge.php?type=5&file=2006C39A.PDF
+# ...
+# P.E.I. will follow US rules....
+# http://www.assembly.pe.ca/bills/pdf_chapter/62/3/chapter-41.pdf
+# ...
+# Province of Newfoundland and Labrador....
+# http://www.hoa.gov.nl.ca/hoa/bills/Bill0634.htm
+# ...
+# Yukon
+# http://www.gov.yk.ca/legislation/regs/oic2006_127.pdf
+# ...
+# N.W.T. will follow US rules.  Whoever maintains the government web site
+# does not seem to believe in bookmarks.  To see the news release, click the
+# following link and search for "Daylight Savings Time Change".  Press the
+# "Daylight Savings Time Change" link; it will fire off a popup using
+# JavaScript.
+# http://www.exec.gov.nt.ca/currentnews/currentPR.asp?mode=archive
+# ...
+# Nunavut
+# An amendment to the Interpretation Act was registered on February 19/2007....
+# http://action.attavik.ca/home/justice-gn/attach/2007/gaz02part2.pdf
+
+# From Paul Eggert (2006-04-25):
+# H. David Matthews and Mary Vincent's map
+# <a href="http://www.canadiangeographic.ca/Magazine/SO98/geomap.asp">
+# "It's about TIME", _Canadian Geographic_ (September-October 1998)
+# </a> contains detailed boundaries for regions observing nonstandard
+# time and daylight saving time arrangements in Canada circa 1998.
+#
+# INMS, the Institute for National Measurement Standards in Ottawa, has <a
+# href="http://inms-ienm.nrc-cnrc.gc.ca/en/time_services/daylight_saving_e.php">
+# information about standard and daylight saving time zones in Canada.
+# </a> (updated periodically).
+# Its unofficial information is often taken from Matthews and Vincent.
+
+# From Paul Eggert (2006-06-27):
+# For now, assume all of DST-observing Canada will fall into line with the
+# new US DST rules,
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Canada	1918	only	-	Apr	14	2:00	1:00	D
+Rule	Canada	1918	only	-	Oct	31	2:00	0	S
+Rule	Canada	1942	only	-	Feb	 9	2:00	1:00	W # War
+Rule	Canada	1945	only	-	Aug	14	23:00u	1:00	P # Peace
+Rule	Canada	1945	only	-	Sep	30	2:00	0	S
+Rule	Canada	1974	1986	-	Apr	lastSun	2:00	1:00	D
+Rule	Canada	1974	2006	-	Oct	lastSun	2:00	0	S
+Rule	Canada	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
+Rule	Canada	2007	max	-	Mar	Sun>=8	2:00	1:00	D
+Rule	Canada	2007	max	-	Nov	Sun>=1	2:00	0	S
+
+
+# Newfoundland and Labrador
+
+# From Paul Eggert (2000-10-02):
+# Matthews and Vincent (1998) write that Labrador should use NST/NDT,
+# but the only part of Labrador that follows the rules is the
+# southeast corner, including Port Hope Simpson and Mary's Harbour,
+# but excluding, say, Black Tickle.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	StJohns	1917	only	-	Apr	 8	2:00	1:00	D
+Rule	StJohns	1917	only	-	Sep	17	2:00	0	S
+# Whitman gives 1919 Apr 5 and 1920 Apr 5; go with Shanks & Pottenger.
+Rule	StJohns	1919	only	-	May	 5	23:00	1:00	D
+Rule	StJohns	1919	only	-	Aug	12	23:00	0	S
+# For 1931-1935 Whitman gives Apr same date; go with Shanks & Pottenger.
+Rule	StJohns	1920	1935	-	May	Sun>=1	23:00	1:00	D
+Rule	StJohns	1920	1935	-	Oct	lastSun	23:00	0	S
+# For 1936-1941 Whitman gives May Sun>=8 and Oct Sun>=1; go with Shanks &
+# Pottenger.
+Rule	StJohns	1936	1941	-	May	Mon>=9	0:00	1:00	D
+Rule	StJohns	1936	1941	-	Oct	Mon>=2	0:00	0	S
+# Whitman gives the following transitions:
+# 1942 03-01/12-31, 1943 05-30/09-05, 1944 07-10/09-02, 1945 01-01/10-07
+# but go with Shanks & Pottenger and assume they used Canadian rules.
+# For 1946-9 Whitman gives May 5,4,9,1 - Oct 1,5,3,2, and for 1950 he gives
+# Apr 30 - Sep 24; go with Shanks & Pottenger.
+Rule	StJohns	1946	1950	-	May	Sun>=8	2:00	1:00	D
+Rule	StJohns	1946	1950	-	Oct	Sun>=2	2:00	0	S
+Rule	StJohns	1951	1986	-	Apr	lastSun	2:00	1:00	D
+Rule	StJohns	1951	1959	-	Sep	lastSun	2:00	0	S
+Rule	StJohns	1960	1986	-	Oct	lastSun	2:00	0	S
+# From Paul Eggert (2000-10-02):
+# INMS (2000-09-12) says that, since 1988 at least, Newfoundland switches
+# at 00:01 local time.  For now, assume it started in 1987.
+Rule	StJohns	1987	only	-	Apr	Sun>=1	0:01	1:00	D
+Rule	StJohns	1987	2006	-	Oct	lastSun	0:01	0	S
+Rule	StJohns	1988	only	-	Apr	Sun>=1	0:01	2:00	DD
+Rule	StJohns	1989	2006	-	Apr	Sun>=1	0:01	1:00	D
+Rule	StJohns	2007	max	-	Mar	Sun>=8	0:01	1:00	D
+Rule	StJohns	2007	max	-	Nov	Sun>=1	0:01	0	S
+#
+# St John's has an apostrophe, but Posix file names can't have apostrophes.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/St_Johns	-3:30:52 -	LMT	1884
+			-3:30:52 StJohns N%sT	1918
+			-3:30:52 Canada	N%sT	1919
+			-3:30:52 StJohns N%sT	1935 Mar 30
+			-3:30	StJohns	N%sT	1942 May 11
+			-3:30	Canada	N%sT	1946
+			-3:30	StJohns	N%sT
+
+# most of east Labrador
+
+# The name `Happy Valley-Goose Bay' is too long; use `Goose Bay'.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Goose_Bay	-4:01:40 -	LMT	1884 # Happy Valley-Goose Bay
+			-3:30:52 -	NST	1918
+			-3:30:52 Canada N%sT	1919
+			-3:30:52 -	NST	1935 Mar 30
+			-3:30	-	NST	1936
+			-3:30	StJohns	N%sT	1942 May 11
+			-3:30	Canada	N%sT	1946
+			-3:30	StJohns	N%sT	1966 Mar 15 2:00
+			-4:00	StJohns	A%sT
+
+
+# west Labrador, Nova Scotia, Prince Edward I
+
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger write that since 1970 most of this region has been like
+# Halifax.  Many locales did not observe peacetime DST until 1972;
+# Glace Bay, NS is the largest that we know of.
+# Shanks & Pottenger also write that Liverpool, NS was the only town
+# in Canada to observe DST in 1971 but not 1970; for now we'll assume
+# this is a typo.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Halifax	1916	only	-	Apr	 1	0:00	1:00	D
+Rule	Halifax	1916	only	-	Oct	 1	0:00	0	S
+Rule	Halifax	1920	only	-	May	 9	0:00	1:00	D
+Rule	Halifax	1920	only	-	Aug	29	0:00	0	S
+Rule	Halifax	1921	only	-	May	 6	0:00	1:00	D
+Rule	Halifax	1921	1922	-	Sep	 5	0:00	0	S
+Rule	Halifax	1922	only	-	Apr	30	0:00	1:00	D
+Rule	Halifax	1923	1925	-	May	Sun>=1	0:00	1:00	D
+Rule	Halifax	1923	only	-	Sep	 4	0:00	0	S
+Rule	Halifax	1924	only	-	Sep	15	0:00	0	S
+Rule	Halifax	1925	only	-	Sep	28	0:00	0	S
+Rule	Halifax	1926	only	-	May	16	0:00	1:00	D
+Rule	Halifax	1926	only	-	Sep	13	0:00	0	S
+Rule	Halifax	1927	only	-	May	 1	0:00	1:00	D
+Rule	Halifax	1927	only	-	Sep	26	0:00	0	S
+Rule	Halifax	1928	1931	-	May	Sun>=8	0:00	1:00	D
+Rule	Halifax	1928	only	-	Sep	 9	0:00	0	S
+Rule	Halifax	1929	only	-	Sep	 3	0:00	0	S
+Rule	Halifax	1930	only	-	Sep	15	0:00	0	S
+Rule	Halifax	1931	1932	-	Sep	Mon>=24	0:00	0	S
+Rule	Halifax	1932	only	-	May	 1	0:00	1:00	D
+Rule	Halifax	1933	only	-	Apr	30	0:00	1:00	D
+Rule	Halifax	1933	only	-	Oct	 2	0:00	0	S
+Rule	Halifax	1934	only	-	May	20	0:00	1:00	D
+Rule	Halifax	1934	only	-	Sep	16	0:00	0	S
+Rule	Halifax	1935	only	-	Jun	 2	0:00	1:00	D
+Rule	Halifax	1935	only	-	Sep	30	0:00	0	S
+Rule	Halifax	1936	only	-	Jun	 1	0:00	1:00	D
+Rule	Halifax	1936	only	-	Sep	14	0:00	0	S
+Rule	Halifax	1937	1938	-	May	Sun>=1	0:00	1:00	D
+Rule	Halifax	1937	1941	-	Sep	Mon>=24	0:00	0	S
+Rule	Halifax	1939	only	-	May	28	0:00	1:00	D
+Rule	Halifax	1940	1941	-	May	Sun>=1	0:00	1:00	D
+Rule	Halifax	1946	1949	-	Apr	lastSun	2:00	1:00	D
+Rule	Halifax	1946	1949	-	Sep	lastSun	2:00	0	S
+Rule	Halifax	1951	1954	-	Apr	lastSun	2:00	1:00	D
+Rule	Halifax	1951	1954	-	Sep	lastSun	2:00	0	S
+Rule	Halifax	1956	1959	-	Apr	lastSun	2:00	1:00	D
+Rule	Halifax	1956	1959	-	Sep	lastSun	2:00	0	S
+Rule	Halifax	1962	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	Halifax	1962	1973	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Halifax	-4:14:24 -	LMT	1902 Jun 15
+			-4:00	Halifax	A%sT	1918
+			-4:00	Canada	A%sT	1919
+			-4:00	Halifax	A%sT	1942 Feb  9 2:00s
+			-4:00	Canada	A%sT	1946
+			-4:00	Halifax	A%sT	1974
+			-4:00	Canada	A%sT
+Zone America/Glace_Bay	-3:59:48 -	LMT	1902 Jun 15
+			-4:00	Canada	A%sT	1953
+			-4:00	Halifax	A%sT	1954
+			-4:00	-	AST	1972
+			-4:00	Halifax	A%sT	1974
+			-4:00	Canada	A%sT
+
+# New Brunswick
+
+# From Paul Eggert (2007-01-31):
+# The Time Definition Act <http://www.gnb.ca/0062/PDF-acts/t-06.pdf>
+# says they changed at 00:01 through 2006, and
+# <http://www.canlii.org/nb/laws/sta/t-6/20030127/whole.html> makes it
+# clear that this was the case since at least 1993.
+# For now, assume it started in 1993.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Moncton	1933	1935	-	Jun	Sun>=8	1:00	1:00	D
+Rule	Moncton	1933	1935	-	Sep	Sun>=8	1:00	0	S
+Rule	Moncton	1936	1938	-	Jun	Sun>=1	1:00	1:00	D
+Rule	Moncton	1936	1938	-	Sep	Sun>=1	1:00	0	S
+Rule	Moncton	1939	only	-	May	27	1:00	1:00	D
+Rule	Moncton	1939	1941	-	Sep	Sat>=21	1:00	0	S
+Rule	Moncton	1940	only	-	May	19	1:00	1:00	D
+Rule	Moncton	1941	only	-	May	 4	1:00	1:00	D
+Rule	Moncton	1946	1972	-	Apr	lastSun	2:00	1:00	D
+Rule	Moncton	1946	1956	-	Sep	lastSun	2:00	0	S
+Rule	Moncton	1957	1972	-	Oct	lastSun	2:00	0	S
+Rule	Moncton	1993	2006	-	Apr	Sun>=1	0:01	1:00	D
+Rule	Moncton	1993	2006	-	Oct	lastSun	0:01	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Moncton	-4:19:08 -	LMT	1883 Dec  9
+			-5:00	-	EST	1902 Jun 15
+			-4:00	Canada	A%sT	1933
+			-4:00	Moncton	A%sT	1942
+			-4:00	Canada	A%sT	1946
+			-4:00	Moncton	A%sT	1973
+			-4:00	Canada	A%sT	1993
+			-4:00	Moncton	A%sT	2007
+			-4:00	Canada	A%sT
+
+# Quebec
+
+# From Paul Eggert (2006-07-09):
+# Shanks & Pottenger write that since 1970 most of Quebec has been
+# like Montreal.
+
+# From Paul Eggert (2006-06-27):
+# Matthews and Vincent (1998) also write that Quebec east of the -63
+# meridian is supposed to observe AST, but residents as far east as
+# Natashquan use EST/EDT, and residents east of Natashquan use AST.
+# In "Official time in Quebec" the Quebec department of justice writes in
+# http://www.justice.gouv.qc.ca/english/publications/generale/temps-regl-1-a.htm
+# that "The residents of the Municipality of the
+# Cote-Nord-du-Golfe-Saint-Laurent and the municipalities of Saint-Augustin,
+# Bonne-Esperance and Blanc-Sablon apply the Official Time Act as it is
+# written and use Atlantic standard time all year round. The same applies to
+# the residents of the Native facilities along the lower North Shore."
+# <http://www.assnat.qc.ca/eng/37legislature2/Projets-loi/Publics/06-a002.htm>
+# says this common practice was codified into law as of 2007.
+# For lack of better info, guess this practice began around 1970, contra to
+# Shanks & Pottenger who have this region observing AST/ADT.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Mont	1917	only	-	Mar	25	2:00	1:00	D
+Rule	Mont	1917	only	-	Apr	24	0:00	0	S
+Rule	Mont	1919	only	-	Mar	31	2:30	1:00	D
+Rule	Mont	1919	only	-	Oct	25	2:30	0	S
+Rule	Mont	1920	only	-	May	 2	2:30	1:00	D
+Rule	Mont	1920	1922	-	Oct	Sun>=1	2:30	0	S
+Rule	Mont	1921	only	-	May	 1	2:00	1:00	D
+Rule	Mont	1922	only	-	Apr	30	2:00	1:00	D
+Rule	Mont	1924	only	-	May	17	2:00	1:00	D
+Rule	Mont	1924	1926	-	Sep	lastSun	2:30	0	S
+Rule	Mont	1925	1926	-	May	Sun>=1	2:00	1:00	D
+# The 1927-to-1937 rules can be expressed more simply as
+# Rule	Mont	1927	1937	-	Apr	lastSat	24:00	1:00	D
+# Rule	Mont	1927	1937	-	Sep	lastSat	24:00	0	S
+# The rules below avoid use of 24:00
+# (which pre-1998 versions of zic cannot handle).
+Rule	Mont	1927	only	-	May	1	0:00	1:00	D
+Rule	Mont	1927	1932	-	Sep	lastSun	0:00	0	S
+Rule	Mont	1928	1931	-	Apr	lastSun	0:00	1:00	D
+Rule	Mont	1932	only	-	May	1	0:00	1:00	D
+Rule	Mont	1933	1940	-	Apr	lastSun	0:00	1:00	D
+Rule	Mont	1933	only	-	Oct	1	0:00	0	S
+Rule	Mont	1934	1939	-	Sep	lastSun	0:00	0	S
+Rule	Mont	1946	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	Mont	1945	1948	-	Sep	lastSun	2:00	0	S
+Rule	Mont	1949	1950	-	Oct	lastSun	2:00	0	S
+Rule	Mont	1951	1956	-	Sep	lastSun	2:00	0	S
+Rule	Mont	1957	1973	-	Oct	lastSun	2:00	0	S
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Blanc-Sablon -3:48:28 -	LMT	1884
+			-4:00	Canada	A%sT	1970
+			-4:00	-	AST
+Zone America/Montreal	-4:54:16 -	LMT	1884
+			-5:00	Mont	E%sT	1918
+			-5:00	Canada	E%sT	1919
+			-5:00	Mont	E%sT	1942 Feb  9 2:00s
+			-5:00	Canada	E%sT	1946
+			-5:00	Mont	E%sT	1974
+			-5:00	Canada	E%sT
+
+
+# Ontario
+
+# From Paul Eggert (2006-07-09):
+# Shanks & Pottenger write that since 1970 most of Ontario has been like
+# Toronto.
+# Thunder Bay skipped DST in 1973.
+# Many smaller locales did not observe peacetime DST until 1974;
+# Nipigon (EST) and Rainy River (CST) are the largest that we know of.
+# Far west Ontario is like Winnipeg; far east Quebec is like Halifax.
+
+# From Mark Brader (2003-07-26):
+# [According to the Toronto Star] Orillia, Ontario, adopted DST
+# effective Saturday, 1912-06-22, 22:00; the article mentions that
+# Port Arthur (now part of Thunder Bay, Ontario) as well as Moose Jaw
+# have already done so.  In Orillia DST was to run until Saturday,
+# 1912-08-31 (no time mentioned), but it was met with considerable
+# hostility from certain segments of the public, and was revoked after
+# only two weeks -- I copied it as Saturday, 1912-07-07, 22:00, but
+# presumably that should be -07-06.  (1912-06-19, -07-12; also letters
+# earlier in June).
+#
+# Kenora, Ontario, was to abandon DST on 1914-06-01 (-05-21).
+
+# From Paul Eggert (1997-10-17):
+# Mark Brader writes that an article in the 1997-10-14 Toronto Star
+# says that Atikokan, Ontario currently does not observe DST,
+# but will vote on 11-10 whether to use EST/EDT.
+# He also writes that the
+# <a href="http://www.gov.on.ca/MBS/english/publications/statregs/conttext.html">
+# Ontario Time Act (1990, Chapter T.9)
+# </a>
+# says that Ontario east of 90W uses EST/EDT, and west of 90W uses CST/CDT.
+# Officially Atikokan is therefore on CST/CDT, and most likely this report
+# concerns a non-official time observed as a matter of local practice.
+#
+# From Paul Eggert (2000-10-02):
+# Matthews and Vincent (1998) write that Atikokan, Pickle Lake, and
+# New Osnaburgh observe CST all year, that Big Trout Lake observes
+# CST/CDT, and that Upsala and Shebandowan observe EST/EDT, all in
+# violation of the official Ontario rules.
+#
+# From Paul Eggert (2006-07-09):
+# Chris Walton (2006-07-06) mentioned an article by Stephanie MacLellan in the
+# 2005-07-21 Chronicle-Journal, which said:
+#
+#	The clocks in Atikokan stay set on standard time year-round.
+#	This means they spend about half the time on central time and
+#	the other half on eastern time.
+#
+#	For the most part, the system works, Mayor Dennis Brown said.
+#
+#	"The majority of businesses in Atikokan deal more with Eastern
+#	Canada, but there are some that deal with Western Canada," he
+#	said.  "I don't see any changes happening here."
+#
+# Walton also writes "Supposedly Pickle Lake and Mishkeegogamang
+# [New Osnaburgh] follow the same practice."
+
+# From Garry McKinnon (2006-07-14) via Chris Walton:
+# I chatted with a member of my board who has an outstanding memory
+# and a long history in Atikokan (and in the telecom industry) and he
+# can say for certain that Atikokan has been practicing the current
+# time keeping since 1952, at least.
+
+# From Paul Eggert (2006-07-17):
+# Shanks & Pottenger say that Atikokan has agreed with Rainy River
+# ever since standard time was introduced, but the information from
+# McKinnon sounds more authoritative.  For now, assume that Atikokan
+# switched to EST immediately after WWII era daylight saving time
+# ended.  This matches the old (less-populous) America/Coral_Harbour
+# entry since our cutoff date of 1970, so we can move
+# America/Coral_Harbour to the 'backward' file.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Toronto	1919	only	-	Mar	30	23:30	1:00	D
+Rule	Toronto	1919	only	-	Oct	26	0:00	0	S
+Rule	Toronto	1920	only	-	May	 2	2:00	1:00	D
+Rule	Toronto	1920	only	-	Sep	26	0:00	0	S
+Rule	Toronto	1921	only	-	May	15	2:00	1:00	D
+Rule	Toronto	1921	only	-	Sep	15	2:00	0	S
+Rule	Toronto	1922	1923	-	May	Sun>=8	2:00	1:00	D
+# Shanks & Pottenger say 1923-09-19; assume it's a typo and that "-16"
+# was meant.
+Rule	Toronto	1922	1926	-	Sep	Sun>=15	2:00	0	S
+Rule	Toronto	1924	1927	-	May	Sun>=1	2:00	1:00	D
+# The 1927-to-1939 rules can be expressed more simply as
+# Rule	Toronto	1927	1937	-	Sep	Sun>=25	2:00	0	S
+# Rule	Toronto	1928	1937	-	Apr	Sun>=25	2:00	1:00	D
+# Rule	Toronto	1938	1940	-	Apr	lastSun	2:00	1:00	D
+# Rule	Toronto	1938	1939	-	Sep	lastSun	2:00	0	S
+# The rules below avoid use of Sun>=25
+# (which pre-2004 versions of zic cannot handle).
+Rule	Toronto	1927	1932	-	Sep	lastSun	2:00	0	S
+Rule	Toronto	1928	1931	-	Apr	lastSun	2:00	1:00	D
+Rule	Toronto	1932	only	-	May	1	2:00	1:00	D
+Rule	Toronto	1933	1940	-	Apr	lastSun	2:00	1:00	D
+Rule	Toronto	1933	only	-	Oct	1	2:00	0	S
+Rule	Toronto	1934	1939	-	Sep	lastSun	2:00	0	S
+Rule	Toronto	1945	1946	-	Sep	lastSun	2:00	0	S
+Rule	Toronto	1946	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Toronto	1947	1949	-	Apr	lastSun	0:00	1:00	D
+Rule	Toronto	1947	1948	-	Sep	lastSun	0:00	0	S
+Rule	Toronto	1949	only	-	Nov	lastSun	0:00	0	S
+Rule	Toronto	1950	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	Toronto	1950	only	-	Nov	lastSun	2:00	0	S
+Rule	Toronto	1951	1956	-	Sep	lastSun	2:00	0	S
+# Shanks & Pottenger say Toronto ended DST a week early in 1971,
+# namely on 1971-10-24, but Mark Brader wrote (2003-05-31) that this
+# is wrong, and that he had confirmed it by checking the 1971-10-30
+# Toronto Star, which said that DST was ending 1971-10-31 as usual.
+Rule	Toronto	1957	1973	-	Oct	lastSun	2:00	0	S
+
+# From Paul Eggert (2003-07-27):
+# Willett (1914-03) writes (p. 17) "In the Cities of Fort William, and
+# Port Arthur, Ontario, the principle of the Bill has been in
+# operation for the past three years, and in the City of Moose Jaw,
+# Saskatchewan, for one year."
+
+# From David Bryan via Tory Tronrud, Director/Curator,
+# Thunder Bay Museum (2003-11-12):
+# There is some suggestion, however, that, by-law or not, daylight
+# savings time was being practiced in Fort William and Port Arthur
+# before 1909.... [I]n 1910, the line between the Eastern and Central
+# Time Zones was permanently moved about two hundred miles west to
+# include the Thunder Bay area....  When Canada adopted daylight
+# savings time in 1916, Fort William and Port Arthur, having done so
+# already, did not change their clocks....  During the Second World
+# War,... [t]he cities agreed to implement DST during the summer
+# months for the remainder of the war years.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Toronto	-5:17:32 -	LMT	1895
+			-5:00	Canada	E%sT	1919
+			-5:00	Toronto	E%sT	1942 Feb  9 2:00s
+			-5:00	Canada	E%sT	1946
+			-5:00	Toronto	E%sT	1974
+			-5:00	Canada	E%sT
+Zone America/Thunder_Bay -5:57:00 -	LMT	1895
+			-6:00	-	CST	1910
+			-5:00	-	EST	1942
+			-5:00	Canada	E%sT	1970
+			-5:00	Mont	E%sT	1973
+			-5:00	-	EST	1974
+			-5:00	Canada	E%sT
+Zone America/Nipigon	-5:53:04 -	LMT	1895
+			-5:00	Canada	E%sT	1940 Sep 29
+			-5:00	1:00	EDT	1942 Feb  9 2:00s
+			-5:00	Canada	E%sT
+Zone America/Rainy_River -6:18:16 -	LMT	1895
+			-6:00	Canada	C%sT	1940 Sep 29
+			-6:00	1:00	CDT	1942 Feb  9 2:00s
+			-6:00	Canada	C%sT
+Zone America/Atikokan	-6:06:28 -	LMT	1895
+			-6:00	Canada	C%sT	1940 Sep 29
+			-6:00	1:00	CDT	1942 Feb  9 2:00s
+			-6:00	Canada	C%sT	1945 Sep 30 2:00
+			-5:00	-	EST
+
+
+# Manitoba
+
+# From Rob Douglas (2006-04-06):
+# the old Manitoba Time Act - as amended by Bill 2, assented to
+# March 27, 1987 ... said ...
+# "between two o'clock Central Standard Time in the morning of
+# the first Sunday of April of each year and two o'clock Central
+# Standard Time in the morning of the last Sunday of October next
+# following, one hour in advance of Central Standard Time."...
+# I believe that the English legislation [of the old time act] had =
+# been assented to (March 22, 1967)....
+# Also, as far as I can tell, there was no order-in-council varying
+# the time of Daylight Saving Time for 2005 and so the provisions of
+# the 1987 version would apply - the changeover was at 2:00 Central
+# Standard Time (i.e. not until 3:00 Central Daylight Time).
+
+# From Paul Eggert (2006-04-10):
+# Shanks & Pottenger say Manitoba switched at 02:00 (not 02:00s)
+# starting 1966.  Since 02:00s is clearly correct for 1967 on, assume
+# it was also 02:00s in 1966.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Winn	1916	only	-	Apr	23	0:00	1:00	D
+Rule	Winn	1916	only	-	Sep	17	0:00	0	S
+Rule	Winn	1918	only	-	Apr	14	2:00	1:00	D
+Rule	Winn	1918	only	-	Oct	31	2:00	0	S
+Rule	Winn	1937	only	-	May	16	2:00	1:00	D
+Rule	Winn	1937	only	-	Sep	26	2:00	0	S
+Rule	Winn	1942	only	-	Feb	 9	2:00	1:00	W # War
+Rule	Winn	1945	only	-	Aug	14	23:00u	1:00	P # Peace
+Rule	Winn	1945	only	-	Sep	lastSun	2:00	0	S
+Rule	Winn	1946	only	-	May	12	2:00	1:00	D
+Rule	Winn	1946	only	-	Oct	13	2:00	0	S
+Rule	Winn	1947	1949	-	Apr	lastSun	2:00	1:00	D
+Rule	Winn	1947	1949	-	Sep	lastSun	2:00	0	S
+Rule	Winn	1950	only	-	May	 1	2:00	1:00	D
+Rule	Winn	1950	only	-	Sep	30	2:00	0	S
+Rule	Winn	1951	1960	-	Apr	lastSun	2:00	1:00	D
+Rule	Winn	1951	1958	-	Sep	lastSun	2:00	0	S
+Rule	Winn	1959	only	-	Oct	lastSun	2:00	0	S
+Rule	Winn	1960	only	-	Sep	lastSun	2:00	0	S
+Rule	Winn	1963	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Winn	1963	only	-	Sep	22	2:00	0	S
+Rule	Winn	1966	1986	-	Apr	lastSun	2:00s	1:00	D
+Rule	Winn	1966	2005	-	Oct	lastSun	2:00s	0	S
+Rule	Winn	1987	2005	-	Apr	Sun>=1	2:00s	1:00	D
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Winnipeg	-6:28:36 -	LMT	1887 Jul 16
+			-6:00	Winn	C%sT	2006
+			-6:00	Canada	C%sT
+
+
+# Saskatchewan
+
+# From Mark Brader (2003-07-26):
+# The first actual adoption of DST in Canada was at the municipal
+# level.  As the [Toronto] Star put it (1912-06-07), "While people
+# elsewhere have long been talking of legislation to save daylight,
+# the city of Moose Jaw [Saskatchewan] has acted on its own hook."
+# DST in Moose Jaw began on Saturday, 1912-06-01 (no time mentioned:
+# presumably late evening, as below), and would run until "the end of
+# the summer".  The discrepancy between municipal time and railroad
+# time was noted.
+
+# From Paul Eggert (2003-07-27):
+# Willett (1914-03) notes that DST "has been in operation ... in the
+# City of Moose Jaw, Saskatchewan, for one year."
+
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger say that since 1970 this region has mostly been as Regina.
+# Some western towns (e.g. Swift Current) switched from MST/MDT to CST in 1972.
+# Other western towns (e.g. Lloydminster) are like Edmonton.
+# Matthews and Vincent (1998) write that Denare Beach and Creighton
+# are like Winnipeg, in violation of Saskatchewan law.
+
+# From W. Jones (1992-11-06):
+# The. . .below is based on information I got from our law library, the
+# provincial archives, and the provincial Community Services department.
+# A precise history would require digging through newspaper archives, and
+# since you didn't say what you wanted, I didn't bother.
+#
+# Saskatchewan is split by a time zone meridian (105W) and over the years
+# the boundary became pretty ragged as communities near it reevaluated
+# their affiliations in one direction or the other.  In 1965 a provincial
+# referendum favoured legislating common time practices.
+#
+# On 15 April 1966 the Time Act (c. T-14, Revised Statutes of
+# Saskatchewan 1978) was proclaimed, and established that the eastern
+# part of Saskatchewan would use CST year round, that districts in
+# northwest Saskatchewan would by default follow CST but could opt to
+# follow Mountain Time rules (thus 1 hour difference in the winter and
+# zero in the summer), and that districts in southwest Saskatchewan would
+# by default follow MT but could opt to follow CST.
+#
+# It took a few years for the dust to settle (I know one story of a town
+# on one time zone having its school in another, such that a mom had to
+# serve her family lunch in two shifts), but presently it seems that only
+# a few towns on the border with Alberta (e.g. Lloydminster) follow MT
+# rules any more; all other districts appear to have used CST year round
+# since sometime in the 1960s.
+
+# From Chris Walton (2006-06-26):
+# The Saskatchewan time act which was last updated in 1996 is about 30 pages
+# long and rather painful to read.
+# http://www.qp.gov.sk.ca/documents/English/Statutes/Statutes/T14.pdf
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Regina	1918	only	-	Apr	14	2:00	1:00	D
+Rule	Regina	1918	only	-	Oct	31	2:00	0	S
+Rule	Regina	1930	1934	-	May	Sun>=1	0:00	1:00	D
+Rule	Regina	1930	1934	-	Oct	Sun>=1	0:00	0	S
+Rule	Regina	1937	1941	-	Apr	Sun>=8	0:00	1:00	D
+Rule	Regina	1937	only	-	Oct	Sun>=8	0:00	0	S
+Rule	Regina	1938	only	-	Oct	Sun>=1	0:00	0	S
+Rule	Regina	1939	1941	-	Oct	Sun>=8	0:00	0	S
+Rule	Regina	1942	only	-	Feb	 9	2:00	1:00	W # War
+Rule	Regina	1945	only	-	Aug	14	23:00u	1:00	P # Peace
+Rule	Regina	1945	only	-	Sep	lastSun	2:00	0	S
+Rule	Regina	1946	only	-	Apr	Sun>=8	2:00	1:00	D
+Rule	Regina	1946	only	-	Oct	Sun>=8	2:00	0	S
+Rule	Regina	1947	1957	-	Apr	lastSun	2:00	1:00	D
+Rule	Regina	1947	1957	-	Sep	lastSun	2:00	0	S
+Rule	Regina	1959	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Regina	1959	only	-	Oct	lastSun	2:00	0	S
+#
+Rule	Swift	1957	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Swift	1957	only	-	Oct	lastSun	2:00	0	S
+Rule	Swift	1959	1961	-	Apr	lastSun	2:00	1:00	D
+Rule	Swift	1959	only	-	Oct	lastSun	2:00	0	S
+Rule	Swift	1960	1961	-	Sep	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Regina	-6:58:36 -	LMT	1905 Sep
+			-7:00	Regina	M%sT	1960 Apr lastSun 2:00
+			-6:00	-	CST
+Zone America/Swift_Current -7:11:20 -	LMT	1905 Sep
+			-7:00	Canada	M%sT	1946 Apr lastSun 2:00
+			-7:00	Regina	M%sT	1950
+			-7:00	Swift	M%sT	1972 Apr lastSun 2:00
+			-6:00	-	CST
+
+
+# Alberta
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Edm	1918	1919	-	Apr	Sun>=8	2:00	1:00	D
+Rule	Edm	1918	only	-	Oct	31	2:00	0	S
+Rule	Edm	1919	only	-	May	27	2:00	0	S
+Rule	Edm	1920	1923	-	Apr	lastSun	2:00	1:00	D
+Rule	Edm	1920	only	-	Oct	lastSun	2:00	0	S
+Rule	Edm	1921	1923	-	Sep	lastSun	2:00	0	S
+Rule	Edm	1942	only	-	Feb	 9	2:00	1:00	W # War
+Rule	Edm	1945	only	-	Aug	14	23:00u	1:00	P # Peace
+Rule	Edm	1945	only	-	Sep	lastSun	2:00	0	S
+Rule	Edm	1947	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Edm	1947	only	-	Sep	lastSun	2:00	0	S
+Rule	Edm	1967	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Edm	1967	only	-	Oct	lastSun	2:00	0	S
+Rule	Edm	1969	only	-	Apr	lastSun	2:00	1:00	D
+Rule	Edm	1969	only	-	Oct	lastSun	2:00	0	S
+Rule	Edm	1972	1986	-	Apr	lastSun	2:00	1:00	D
+Rule	Edm	1972	2006	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Edmonton	-7:33:52 -	LMT	1906 Sep
+			-7:00	Edm	M%sT	1987
+			-7:00	Canada	M%sT
+
+
+# British Columbia
+
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger write that since 1970 most of this region has
+# been like Vancouver.
+# Dawson Creek uses MST.  Much of east BC is like Edmonton.
+# Matthews and Vincent (1998) write that Creston is like Dawson Creek.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Vanc	1918	only	-	Apr	14	2:00	1:00	D
+Rule	Vanc	1918	only	-	Oct	31	2:00	0	S
+Rule	Vanc	1942	only	-	Feb	 9	2:00	1:00	W # War
+Rule	Vanc	1945	only	-	Aug	14	23:00u	1:00	P # Peace
+Rule	Vanc	1945	only	-	Sep	30	2:00	0	S
+Rule	Vanc	1946	1986	-	Apr	lastSun	2:00	1:00	D
+Rule	Vanc	1946	only	-	Oct	13	2:00	0	S
+Rule	Vanc	1947	1961	-	Sep	lastSun	2:00	0	S
+Rule	Vanc	1962	2006	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Vancouver	-8:12:28 -	LMT	1884
+			-8:00	Vanc	P%sT	1987
+			-8:00	Canada	P%sT
+Zone America/Dawson_Creek -8:00:56 -	LMT	1884
+			-8:00	Canada	P%sT	1947
+			-8:00	Vanc	P%sT	1972 Aug 30 2:00
+			-7:00	-	MST
+
+
+# Northwest Territories, Nunavut, Yukon
+
+# From Paul Eggert (2006-03-22):
+# Dawson switched to PST in 1973.  Inuvik switched to MST in 1979.
+# Mathew Englander (1996-10-07) gives the following refs:
+#	* 1967. Paragraph 28(34)(g) of the Interpretation Act, S.C. 1967-68,
+#	c. 7 defines Yukon standard time as UTC-9.  This is still valid;
+#	see Interpretation Act, R.S.C. 1985, c. I-21, s. 35(1).
+#	* C.O. 1973/214 switched Yukon to PST on 1973-10-28 00:00.
+#	* O.I.C. 1980/02 established DST.
+#	* O.I.C. 1987/056 changed DST to Apr firstSun 2:00 to Oct lastSun 2:00.
+# Shanks & Pottenger say Yukon's 1973-10-28 switch was at 2:00; go
+# with Englander.
+# From Chris Walton (2006-06-26):
+# Here is a link to the old daylight saving portion of the interpretation
+# act which was last updated in 1987:
+# http://www.gov.yk.ca/legislation/regs/oic1987_056.pdf
+
+# From Rives McDow (1999-09-04):
+# Nunavut ... moved ... to incorporate the whole territory into one time zone.
+# <a href="http://www.nunatsiaq.com/nunavut/nvt90903_13.html">
+# Nunavut moves to single time zone Oct. 31
+# </a>
+#
+# From Antoine Leca (1999-09-06):
+# We then need to create a new timezone for the Kitikmeot region of Nunavut
+# to differentiate it from the Yellowknife region.
+
+# From Paul Eggert (1999-09-20):
+# <a href="http://www.nunavut.com/basicfacts/english/basicfacts_1territory.html">
+# Basic Facts: The New Territory
+# </a> (1999) reports that Pangnirtung operates on eastern time,
+# and that Coral Harbour does not observe DST.  We don't know when
+# Pangnirtung switched to eastern time; we'll guess 1995.
+
+# From Rives McDow (1999-11-08):
+# On October 31, when the rest of Nunavut went to Central time,
+# Pangnirtung wobbled.  Here is the result of their wobble:
+#
+# The following businesses and organizations in Pangnirtung use Central Time:
+#
+#	First Air, Power Corp, Nunavut Construction, Health Center, RCMP,
+#	Eastern Arctic National Parks, A & D Specialist
+#
+# The following businesses and organizations in Pangnirtung use Eastern Time:
+#
+#	Hamlet office, All other businesses, Both schools, Airport operator
+#
+# This has made for an interesting situation there, which warranted the news.
+# No one there that I spoke with seems concerned, or has plans to
+# change the local methods of keeping time, as it evidently does not
+# really interfere with any activities or make things difficult locally.
+# They plan to celebrate New Year's turn-over twice, one hour apart,
+# so it appears that the situation will last at least that long.
+# The Nunavut Intergovernmental Affairs hopes that they will "come to
+# their senses", but the locals evidently don't see any problem with
+# the current state of affairs.
+
+# From Michaela Rodrigue, writing in the
+# <a href="http://www.nunatsiaq.com/archives/nunavut991130/nvt91119_17.html">
+# Nunatsiaq News (1999-11-19)</a>:
+# Clyde River, Pangnirtung and Sanikiluaq now operate with two time zones,
+# central - or Nunavut time - for government offices, and eastern time
+# for municipal offices and schools....  Igloolik [was similar but then]
+# made the switch to central time on Saturday, Nov. 6.
+
+# From Paul Eggert (2000-10-02):
+# Matthews and Vincent (1998) say the following, but we lack histories
+# for these potential new Zones.
+#
+# The Canadian Forces station at Alert uses Eastern Time while the
+# handful of residents at the Eureka weather station [in the Central
+# zone] skip daylight savings.  Baffin Island, which is crossed by the
+# Central, Eastern and Atlantic Time zones only uses Eastern Time.
+# Gjoa Haven, Taloyoak and Pelly Bay all use Mountain instead of
+# Central Time and Southampton Island [in the Central zone] is not
+# required to use daylight savings.
+
+# From
+# <a href="http://www.nunatsiaq.com/archives/nunavut001130/nvt21110_02.html">
+# Nunavut now has two time zones
+# </a> (2000-11-10):
+# The Nunavut government would allow its employees in Kugluktuk and
+# Cambridge Bay to operate on central time year-round, putting them
+# one hour behind the rest of Nunavut for six months during the winter.
+# At the end of October the two communities had rebelled against
+# Nunavut's unified time zone, refusing to shift to eastern time with
+# the rest of the territory for the winter.  Cambridge Bay remained on
+# central time, while Kugluktuk, even farther west, reverted to
+# mountain time, which they had used before the advent of Nunavut's
+# unified time zone in 1999.
+#
+# From Rives McDow (2001-01-20), quoting the Nunavut government:
+# The preceding decision came into effect at midnight, Saturday Nov 4, 2000.
+
+# From Paul Eggert (2000-12-04):
+# Let's just keep track of the official times for now.
+
+# From Rives McDow (2001-03-07):
+# The premier of Nunavut has issued a ministerial statement advising
+# that effective 2001-04-01, the territory of Nunavut will revert
+# back to three time zones (mountain, central, and eastern).  Of the
+# cities in Nunavut, Coral Harbor is the only one that I know of that
+# has said it will not observe dst, staying on EST year round.  I'm
+# checking for more info, and will get back to you if I come up with
+# more.
+# [Also see <http://www.nunatsiaq.com/nunavut/nvt10309_06.html> (2001-03-09).]
+
+# From Gwillim Law (2005-05-21):
+# According to maps at
+# http://inms-ienm.nrc-cnrc.gc.ca/images/time_services/TZ01SWE.jpg
+# http://inms-ienm.nrc-cnrc.gc.ca/images/time_services/TZ01SSE.jpg
+# (both dated 2003), and
+# http://www.canadiangeographic.ca/Magazine/SO98/geomap.asp
+# (from a 1998 Canadian Geographic article), the de facto and de jure time
+# for Southampton Island (at the north end of Hudson Bay) is UTC-5 all year
+# round.  Using Google, it's easy to find other websites that confirm this.
+# I wasn't able to find how far back this time regimen goes, but since it
+# predates the creation of Nunavut, it probably goes back many years....
+# The Inuktitut name of Coral Harbour is Sallit, but it's rarely used.
+#
+# From Paul Eggert (2005-07-26):
+# For lack of better information, assume that Southampton Island observed
+# daylight saving only during wartime.
+
+# From Chris Walton (2007-03-01):
+# ... the community of Resolute (located on Cornwallis Island in
+# Nunavut) moved from Central Time to Eastern Time last November.
+# Basically the community did not change its clocks at the end of
+# daylight saving....
+# http://www.nnsl.com/frames/newspapers/2006-11/nov13_06none.html
+
+# From Chris Walton (2007-03-14):
+# Today I phoned the "hamlet office" to find out what Resolute was doing with
+# its clocks.
+#
+# The individual that answered the phone confirmed that the clocks did not
+# move at the end of daylight saving on October 29/2006.  He also told me that
+# the clocks did not move this past weekend (March 11/2007)....
+#
+# America/Resolute should use the "Canada" Rule up to October 29/2006.
+# After that it should be fixed on Eastern Standard Time until further notice.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	NT_YK	1918	only	-	Apr	14	2:00	1:00	D
+Rule	NT_YK	1918	only	-	Oct	27	2:00	0	S
+Rule	NT_YK	1919	only	-	May	25	2:00	1:00	D
+Rule	NT_YK	1919	only	-	Nov	 1	0:00	0	S
+Rule	NT_YK	1942	only	-	Feb	 9	2:00	1:00	W # War
+Rule	NT_YK	1945	only	-	Aug	14	23:00u	1:00	P # Peace
+Rule	NT_YK	1945	only	-	Sep	30	2:00	0	S
+Rule	NT_YK	1965	only	-	Apr	lastSun	0:00	2:00	DD
+Rule	NT_YK	1965	only	-	Oct	lastSun	2:00	0	S
+Rule	NT_YK	1980	1986	-	Apr	lastSun	2:00	1:00	D
+Rule	NT_YK	1980	2006	-	Oct	lastSun	2:00	0	S
+Rule	NT_YK	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# aka Panniqtuuq
+Zone America/Pangnirtung 0	-	zzz	1921 # trading post est.
+			-4:00	NT_YK	A%sT	1995 Apr Sun>=1 2:00
+			-5:00	Canada	E%sT	1999 Oct 31 2:00
+			-6:00	Canada	C%sT	2000 Oct 29 2:00
+			-5:00	Canada	E%sT
+# formerly Frobisher Bay
+Zone America/Iqaluit	0	-	zzz	1942 Aug # Frobisher Bay est.
+			-5:00	NT_YK	E%sT	1999 Oct 31 2:00
+			-6:00	Canada	C%sT	2000 Oct 29 2:00
+			-5:00	Canada	E%sT
+# aka Qausuittuq
+Zone America/Resolute	0	-	zzz	1947 Aug 31 # Resolute founded
+			-6:00	NT_YK	C%sT	2000 Oct 29 2:00
+			-5:00	-	EST	2001 Apr  1 3:00
+			-6:00	Canada	C%sT	2006 Oct 29 2:00
+			-5:00	-	EST
+# aka Kangiqiniq
+Zone America/Rankin_Inlet 0	-	zzz	1957 # Rankin Inlet founded
+			-6:00	NT_YK	C%sT	2000 Oct 29 2:00
+			-5:00	-	EST	2001 Apr  1 3:00
+			-6:00	Canada	C%sT
+# aka Iqaluktuuttiaq
+Zone America/Cambridge_Bay 0	-	zzz	1920 # trading post est.?
+			-7:00	NT_YK	M%sT	1999 Oct 31 2:00
+			-6:00	Canada	C%sT	2000 Oct 29 2:00
+			-5:00	-	EST	2000 Nov  5 0:00
+			-6:00	-	CST	2001 Apr  1 3:00
+			-7:00	Canada	M%sT
+Zone America/Yellowknife 0	-	zzz	1935 # Yellowknife founded?
+			-7:00	NT_YK	M%sT	1980
+			-7:00	Canada	M%sT
+Zone America/Inuvik	0	-	zzz	1953 # Inuvik founded
+			-8:00	NT_YK	P%sT	1979 Apr lastSun 2:00
+			-7:00	NT_YK	M%sT	1980
+			-7:00	Canada	M%sT
+Zone America/Whitehorse	-9:00:12 -	LMT	1900 Aug 20
+			-9:00	NT_YK	Y%sT	1966 Jul 1 2:00
+			-8:00	NT_YK	P%sT	1980
+			-8:00	Canada	P%sT
+Zone America/Dawson	-9:17:40 -	LMT	1900 Aug 20
+			-9:00	NT_YK	Y%sT	1973 Oct 28 0:00
+			-8:00	NT_YK	P%sT	1980
+			-8:00	Canada	P%sT
+
+
+###############################################################################
+
+# Mexico
+
+# From Paul Eggert (2001-03-05):
+# The Investigation and Analysis Service of the
+# Mexican Library of Congress (MLoC) has published a
+# <a href="http://www.cddhcu.gob.mx/bibliot/publica/inveyana/polisoc/horver/">
+# history of Mexican local time (in Spanish)
+# </a>.
+#
+# Here are the discrepancies between Shanks & Pottenger (S&P) and the MLoC.
+# (In all cases we go with the MLoC.)
+# S&P report that Baja was at -8:00 in 1922/1923.
+# S&P say the 1930 transition in Baja was 1930-11-16.
+# S&P report no DST during summer 1931.
+# S&P report a transition at 1932-03-30 23:00, not 1932-04-01.
+
+# From Gwillim Law (2001-02-20):
+# There are some other discrepancies between the Decrees page and the
+# tz database.  I think they can best be explained by supposing that
+# the researchers who prepared the Decrees page failed to find some of
+# the relevant documents.
+
+# From Alan Perry (1996-02-15):
+# A guy from our Mexico subsidiary finally found the Presidential Decree
+# outlining the timezone changes in Mexico.
+#
+# ------------- Begin Forwarded Message -------------
+#
+# I finally got my hands on the Official Presidential Decree that sets up the
+# rules for the DST changes. The rules are:
+#
+# 1. The country is divided in 3 timezones:
+#    - Baja California Norte (the Mexico/BajaNorte TZ)
+#    - Baja California Sur, Nayarit, Sinaloa and Sonora (the Mexico/BajaSur TZ)
+#    - The rest of the country (the Mexico/General TZ)
+#
+# 2. From the first Sunday in April at 2:00 AM to the last Sunday in October
+#    at 2:00 AM, the times in each zone are as follows:
+#    BajaNorte: GMT+7
+#    BajaSur:   GMT+6
+#    General:   GMT+5
+#
+# 3. The rest of the year, the times are as follows:
+#    BajaNorte: GMT+8
+#    BajaSur:   GMT+7
+#    General:   GMT+6
+#
+# The Decree was published in Mexico's Official Newspaper on January 4th.
+#
+# -------------- End Forwarded Message --------------
+# From Paul Eggert (1996-06-12):
+# For an English translation of the decree, see
+# <a href="http://mexico-travel.com/extra/timezone_eng.html">
+# ``Diario Oficial: Time Zone Changeover'' (1996-01-04).
+# </a>
+
+# From Rives McDow (1998-10-08):
+# The State of Quintana Roo has reverted back to central STD and DST times
+# (i.e. UTC -0600 and -0500 as of 1998-08-02).
+
+# From Rives McDow (2000-01-10):
+# Effective April 4, 1999 at 2:00 AM local time, Sonora changed to the time
+# zone 5 hours from the International Date Line, and will not observe daylight
+# savings time so as to stay on the same time zone as the southern part of
+# Arizona year round.
+
+# From Jesper Norgaard, translating
+# <http://www.reforma.com/nacional/articulo/064327/> (2001-01-17):
+# In Oaxaca, the 55.000 teachers from the Section 22 of the National
+# Syndicate of Education Workers, refuse to apply daylight saving each
+# year, so that the more than 10,000 schools work at normal hour the
+# whole year.
+
+# From Gwillim Law (2001-01-19):
+# <http://www.reforma.com/negocios_y_dinero/articulo/064481/> ... says
+# (translated):...
+# January 17, 2000 - The Energy Secretary, Ernesto Martens, announced
+# that Summer Time will be reduced from seven to five months, starting
+# this year....
+# <http://www.publico.com.mx/scripts/texto3.asp?action=pagina&pag=21&pos=p&secc=naci&date=01/17/2001>
+# [translated], says "summer time will ... take effect on the first Sunday
+# in May, and end on the last Sunday of September.
+
+# From Arthur David Olson (2001-01-25):
+# The 2001-01-24 traditional Washington Post contained the page one
+# story "Timely Issue Divides Mexicans."...
+# http://www.washingtonpost.com/wp-dyn/articles/A37383-2001Jan23.html
+# ... Mexico City Mayor Lopez Obrador "...is threatening to keep
+# Mexico City and its 20 million residents on a different time than
+# the rest of the country..." In particular, Lopez Obrador would abolish
+# observation of Daylight Saving Time.
+
+# <a href="http://www.conae.gob.mx/ahorro/decretohorver2001.html#decre">
+# Official statute published by the Energy Department
+# </a> (2001-02-01) shows Baja and Chihauhua as still using US DST rules,
+# and Sonora with no DST.  This was reported by Jesper Norgaard (2001-02-03).
+
+# From Paul Eggert (2001-03-03):
+#
+# <a href="http://www.latimes.com/news/nation/20010303/t000018766.html">
+# James F. Smith writes in today's LA Times
+# </a>
+# * Sonora will continue to observe standard time.
+# * Last week Mexico City's mayor Andres Manuel Lopez Obrador decreed that
+#   the Federal District will not adopt DST.
+# * 4 of 16 district leaders announced they'll ignore the decree.
+# * The decree does not affect federal-controlled facilities including
+#   the airport, banks, hospitals, and schools.
+#
+# For now we'll assume that the Federal District will bow to federal rules.
+
+# From Jesper Norgaard (2001-04-01):
+# I found some references to the Mexican application of daylight
+# saving, which modifies what I had already sent you, stating earlier
+# that a number of northern Mexican states would go on daylight
+# saving. The modification reverts this to only cover Baja California
+# (Norte), while all other states (except Sonora, who has no daylight
+# saving all year) will follow the original decree of president
+# Vicente Fox, starting daylight saving May 6, 2001 and ending
+# September 30, 2001.
+# References: "Diario de Monterrey" <www.diariodemonterrey.com/index.asp>
+# Palabra <http://palabra.infosel.com/010331/primera/ppri3101.pdf> (2001-03-31)
+
+# From Reuters (2001-09-04):
+# Mexico's Supreme Court on Tuesday declared that daylight savings was
+# unconstitutional in Mexico City, creating the possibility the
+# capital will be in a different time zone from the rest of the nation
+# next year....  The Supreme Court's ruling takes effect at 2:00
+# a.m. (0800 GMT) on Sept. 30, when Mexico is scheduled to revert to
+# standard time. "This is so residents of the Federal District are not
+# subject to unexpected time changes," a statement from the court said.
+
+# From Jesper Norgaard Welen (2002-03-12):
+# ... consulting my local grocery store(!) and my coworkers, they all insisted
+# that a new decision had been made to reinstate US style DST in Mexico....
+# http://www.conae.gob.mx/ahorro/horaver2001_m1_2002.html (2002-02-20)
+# confirms this.  Sonora as usual is the only state where DST is not applied.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Mexico	1939	only	-	Feb	5	0:00	1:00	D
+Rule	Mexico	1939	only	-	Jun	25	0:00	0	S
+Rule	Mexico	1940	only	-	Dec	9	0:00	1:00	D
+Rule	Mexico	1941	only	-	Apr	1	0:00	0	S
+Rule	Mexico	1943	only	-	Dec	16	0:00	1:00	W # War
+Rule	Mexico	1944	only	-	May	1	0:00	0	S
+Rule	Mexico	1950	only	-	Feb	12	0:00	1:00	D
+Rule	Mexico	1950	only	-	Jul	30	0:00	0	S
+Rule	Mexico	1996	2000	-	Apr	Sun>=1	2:00	1:00	D
+Rule	Mexico	1996	2000	-	Oct	lastSun	2:00	0	S
+Rule	Mexico	2001	only	-	May	Sun>=1	2:00	1:00	D
+Rule	Mexico	2001	only	-	Sep	lastSun	2:00	0	S
+Rule	Mexico	2002	max	-	Apr	Sun>=1	2:00	1:00	D
+Rule	Mexico	2002	max	-	Oct	lastSun	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+# Quintana Roo
+Zone America/Cancun	-5:47:04 -	LMT	1922 Jan  1  0:12:56
+			-6:00	-	CST	1981 Dec 23
+			-5:00	Mexico	E%sT	1998 Aug  2  2:00
+			-6:00	Mexico	C%sT
+# Campeche, Yucatan
+Zone America/Merida	-5:58:28 -	LMT	1922 Jan  1  0:01:32
+			-6:00	-	CST	1981 Dec 23
+			-5:00	-	EST	1982 Dec  2
+			-6:00	Mexico	C%sT
+# Coahuila, Durango, Nuevo Leon, Tamaulipas
+Zone America/Monterrey	-6:41:16 -	LMT	1921 Dec 31 23:18:44
+			-6:00	-	CST	1988
+			-6:00	US	C%sT	1989
+			-6:00	Mexico	C%sT
+# Central Mexico
+Zone America/Mexico_City -6:36:36 -	LMT	1922 Jan  1  0:23:24
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	Mexico	C%sT	2001 Sep 30 02:00
+			-6:00	-	CST	2002 Feb 20
+			-6:00	Mexico	C%sT
+# Chihuahua
+Zone America/Chihuahua	-7:04:20 -	LMT	1921 Dec 31 23:55:40
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	-	CST	1996
+			-6:00	Mexico	C%sT	1998
+			-6:00	-	CST	1998 Apr Sun>=1 3:00
+			-7:00	Mexico	M%sT
+# Sonora
+Zone America/Hermosillo	-7:23:52 -	LMT	1921 Dec 31 23:36:08
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	-	CST	1942 Apr 24
+			-7:00	-	MST	1949 Jan 14
+			-8:00	-	PST	1970
+			-7:00	Mexico	M%sT	1999
+			-7:00	-	MST
+# Baja California Sur, Nayarit, Sinaloa
+Zone America/Mazatlan	-7:05:40 -	LMT	1921 Dec 31 23:54:20
+			-7:00	-	MST	1927 Jun 10 23:00
+			-6:00	-	CST	1930 Nov 15
+			-7:00	-	MST	1931 May  1 23:00
+			-6:00	-	CST	1931 Oct
+			-7:00	-	MST	1932 Apr  1
+			-6:00	-	CST	1942 Apr 24
+			-7:00	-	MST	1949 Jan 14
+			-8:00	-	PST	1970
+			-7:00	Mexico	M%sT
+# Baja California
+Zone America/Tijuana	-7:48:04 -	LMT	1922 Jan  1  0:11:56
+			-7:00	-	MST	1924
+			-8:00	-	PST	1927 Jun 10 23:00
+			-7:00	-	MST	1930 Nov 15
+			-8:00	-	PST	1931 Apr  1
+			-8:00	1:00	PDT	1931 Sep 30
+			-8:00	-	PST	1942 Apr 24
+			-8:00	1:00	PWT	1945 Aug 14 23:00u
+			-8:00	1:00	PPT	1945 Nov 12 # Peace
+			-8:00	-	PST	1948 Apr  5
+			-8:00	1:00	PDT	1949 Jan 14
+			-8:00	-	PST	1954
+			-8:00	CA	P%sT	1961
+			-8:00	-	PST	1976
+			-8:00	US	P%sT	1996
+			-8:00	Mexico	P%sT	2001
+			-8:00	US	P%sT	2002 Feb 20
+			-8:00	Mexico	P%sT
+# From Paul Eggert (2006-03-22):
+# Formerly there was an America/Ensenada zone, which differed from
+# America/Tijuana only in that it did not observe DST from 1976
+# through 1995.  This was as per Shanks (1999).  But Shanks & Pottenger say
+# Ensenada did not observe DST from 1948 through 1975.  Guy Harris reports
+# that the 1987 OAG says "Only Ensenada, Mexicale, San Felipe and
+# Tijuana observe DST," which agrees with Shanks & Pottenger but implies that
+# DST-observance was a town-by-town matter back then.  This concerns
+# data after 1970 so most likely there should be at least one Zone
+# other than America/Tijuana for Baja, but it's not clear yet what its
+# name or contents should be.
+#
+# Revillagigedo Is
+# no information
+
+###############################################################################
+
+# Anguilla
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Anguilla	-4:12:16 -	LMT	1912 Mar 2
+			-4:00	-	AST
+
+# Antigua and Barbuda
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Antigua	-4:07:12 -	LMT	1912 Mar 2
+			-5:00	-	EST	1951
+			-4:00	-	AST
+
+# Bahamas
+#
+# From Sue Williams (2006-12-07):
+# The Bahamas announced about a month ago that they plan to change their DST
+# rules to sync with the U.S. starting in 2007....
+# http://www.jonesbahamas.com/?c=45&a=10412
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Bahamas	1964	1975	-	Oct	lastSun	2:00	0	S
+Rule	Bahamas	1964	1975	-	Apr	lastSun	2:00	1:00	D
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Nassau	-5:09:24 -	LMT	1912 Mar 2
+			-5:00	Bahamas	E%sT	1976
+			-5:00	US	E%sT
+
+# Barbados
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Barb	1977	only	-	Jun	12	2:00	1:00	D
+Rule	Barb	1977	1978	-	Oct	Sun>=1	2:00	0	S
+Rule	Barb	1978	1980	-	Apr	Sun>=15	2:00	1:00	D
+Rule	Barb	1979	only	-	Sep	30	2:00	0	S
+Rule	Barb	1980	only	-	Sep	25	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Barbados	-3:58:28 -	LMT	1924		# Bridgetown
+			-3:58:28 -	BMT	1932	  # Bridgetown Mean Time
+			-4:00	Barb	A%sT
+
+# Belize
+# Whitman entirely disagrees with Shanks; go with Shanks & Pottenger.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Belize	1918	1942	-	Oct	Sun>=2	0:00	0:30	HD
+Rule	Belize	1919	1943	-	Feb	Sun>=9	0:00	0	S
+Rule	Belize	1973	only	-	Dec	 5	0:00	1:00	D
+Rule	Belize	1974	only	-	Feb	 9	0:00	0	S
+Rule	Belize	1982	only	-	Dec	18	0:00	1:00	D
+Rule	Belize	1983	only	-	Feb	12	0:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Belize	-5:52:48 -	LMT	1912 Apr
+			-6:00	Belize	C%sT
+
+# Bermuda
+
+# From Dan Jones, reporting in The Royal Gazette (2006-06-26):
+
+# Next year, however, clocks in the US will go forward on the second Sunday
+# in March, until the first Sunday in November.  And, after the Time Zone
+# (Seasonal Variation) Bill 2006 was passed in the House of Assembly on
+# Friday, the same thing will happen in Bermuda.
+# http://www.theroyalgazette.com/apps/pbcs.dll/article?AID=/20060529/NEWS/105290135
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Atlantic/Bermuda	-4:19:04 -	LMT	1930 Jan  1 2:00    # Hamilton
+			-4:00	-	AST	1974 Apr 28 2:00
+			-4:00	Bahamas	A%sT	1976
+			-4:00	US	A%sT
+
+# Cayman Is
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Cayman	-5:25:32 -	LMT	1890		# Georgetown
+			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
+			-5:00	-	EST
+
+# Costa Rica
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	CR	1979	1980	-	Feb	lastSun	0:00	1:00	D
+Rule	CR	1979	1980	-	Jun	Sun>=1	0:00	0	S
+Rule	CR	1991	1992	-	Jan	Sat>=15	0:00	1:00	D
+# IATA SSIM (1991-09) says the following was at 1:00;
+# go with Shanks & Pottenger.
+Rule	CR	1991	only	-	Jul	 1	0:00	0	S
+Rule	CR	1992	only	-	Mar	15	0:00	0	S
+# There are too many San Joses elsewhere, so we'll use `Costa Rica'.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Costa_Rica	-5:36:20 -	LMT	1890		# San Jose
+			-5:36:20 -	SJMT	1921 Jan 15 # San Jose Mean Time
+			-6:00	CR	C%sT
+# Coco
+# no information; probably like America/Costa_Rica
+
+# Cuba
+
+# From Arthur David Olson (1999-03-29):
+# The 1999-03-28 exhibition baseball game held in Havana, Cuba, between
+# the Cuban National Team and the Baltimore Orioles was carried live on
+# the Orioles Radio Network, including affiliate WTOP in Washington, DC.
+# During the game, play-by-play announcer Jim Hunter noted that
+# "We'll be losing two hours of sleep...Cuba switched to Daylight Saving
+# Time today."  (The "two hour" remark referred to losing one hour of
+# sleep on 1999-03-28--when the announcers were in Cuba as it switched
+# to DST--and one more hour on 1999-04-04--when the announcers will have
+# returned to Baltimore, which switches on that date.)
+
+# From Evert van der Veer via Steffen Thorsen (2004-10-28):
+# Cuba is not going back to standard time this year.
+# From Paul Eggert (2006-03-22):
+# http://www.granma.cu/ingles/2004/septiembre/juev30/41medid-i.html
+# says that it's due to a problem at the Antonio Guiteras
+# thermoelectric plant, and says "This October there will be no return
+# to normal hours (after daylight saving time)".
+# For now, let's assume that it's a temporary measure.
+
+# From Carlos A. Carnero Delgado (2005-11-12):
+# This year (just like in 2004-2005) there's no change in time zone
+# adjustment in Cuba.  We will stay in daylight saving time:
+# http://www.granma.cu/espanol/2005/noviembre/mier9/horario.html
+
+# From Jesper Norgaard Welen (2006-10-21):
+# An article in GRANMA INTERNACIONAL claims that Cuba will end
+# the 3 years of permanent DST next weekend, see
+# http://www.granma.cu/ingles/2006/octubre/lun16/43horario.html
+# "On Saturday night, October 28 going into Sunday, October 29, at 01:00,
+# watches should be set back one hour -- going back to 00:00 hours -- returning
+# to the normal schedule....
+
+# From Paul Eggert (2007-03-02):
+# http://www.granma.cubaweb.cu/english/news/art89.html, dated yesterday,
+# says Cuban clocks will advance at midnight on March 10.
+# For lack of better information, assume Cuba will use US rules,
+# except that it switches at midnight standard time as usual.
+#
+# From Steffen Thorsen (2007-10-25):
+# Carlos Alberto Fonseca Arauz informed me that Cuba will end DST one week 
+# earlier - on the last Sunday of October, just like in 2006.
+# 
+# He supplied these references:
+# 
+# http://www.prensalatina.com.mx/article.asp?ID=%7B4CC32C1B-A9F7-42FB-8A07-8631AFC923AF%7D&language=ES
+# http://actualidad.terra.es/sociedad/articulo/cuba_llama_ahorrar_energia_cambio_1957044.htm
+# 
+# From Alex Kryvenishev (2007-10-25):
+# Here is also article from Granma (Cuba):
+# 
+# [Regira] el Horario Normal desde el [proximo] domingo 28 de octubre
+# http://www.granma.cubaweb.cu/2007/10/24/nacional/artic07.html
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_cuba03.html
+
+# From Arthur David Olson (2008-03-09):
+# I'm in Maryland which is now observing United States Eastern Daylight
+# Time. At 9:44 local time I used RealPlayer to listen to
+# <a href="http://media.enet.cu/radioreloj">
+# http://media.enet.cu/radioreloj
+# </a>, a Cuban information station, and heard
+# the time announced as "ocho cuarenta y cuatro" ("eight forty-four"),
+# indicating that Cuba is still on standard time.
+
+# From Steffen Thorsen (2008-03-12):
+# It seems that Cuba will start DST on Sunday, 2007-03-16...
+# It was announced yesterday, according to this source (in Spanish):
+# <a href="http://www.nnc.cubaweb.cu/marzo-2008/cien-1-11-3-08.htm">
+# http://www.nnc.cubaweb.cu/marzo-2008/cien-1-11-3-08.htm
+# </a>
+#
+# Some more background information is posted here:
+# <a href="http://www.timeanddate.com/news/time/cuba-starts-dst-march-16.html">
+# http://www.timeanddate.com/news/time/cuba-starts-dst-march-16.html
+# </a>
+#
+# The article also says that Cuba has been observing DST since 1963,
+# while Shanks (and tzdata) has 1965 as the first date (except in the
+# 1940's). Many other web pages in Cuba also claim that it has been
+# observed since 1963, but with the exception of 1970 - an exception
+# which is not present in tzdata/Shanks. So there is a chance we need to
+# change some historic records as well.
+#
+# One example:
+# <a href="http://www.radiohc.cu/espanol/noticias/mar07/11mar/hor.htm">
+# http://www.radiohc.cu/espanol/noticias/mar07/11mar/hor.htm
+# </a>
+
+# From Jesper Norgaard Welen (2008-03-13):
+# The Cuban time change has just been confirmed on the most authoritative
+# web site, the Granma.  Please check out
+# <a href="http://www.granma.cubaweb.cu/2008/03/13/nacional/artic10.html">
+# http://www.granma.cubaweb.cu/2008/03/13/nacional/artic10.html
+# </a>
+#
+# Basically as expected after Steffen Thorsens information, the change
+# will take place midnight between Saturday and Sunday.
+
+# From Arthur David Olson (2008-03-12):
+# Assume Sun>=15 (third Sunday) going forward.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Cuba	1928	only	-	Jun	10	0:00	1:00	D
+Rule	Cuba	1928	only	-	Oct	10	0:00	0	S
+Rule	Cuba	1940	1942	-	Jun	Sun>=1	0:00	1:00	D
+Rule	Cuba	1940	1942	-	Sep	Sun>=1	0:00	0	S
+Rule	Cuba	1945	1946	-	Jun	Sun>=1	0:00	1:00	D
+Rule	Cuba	1945	1946	-	Sep	Sun>=1	0:00	0	S
+Rule	Cuba	1965	only	-	Jun	1	0:00	1:00	D
+Rule	Cuba	1965	only	-	Sep	30	0:00	0	S
+Rule	Cuba	1966	only	-	May	29	0:00	1:00	D
+Rule	Cuba	1966	only	-	Oct	2	0:00	0	S
+Rule	Cuba	1967	only	-	Apr	8	0:00	1:00	D
+Rule	Cuba	1967	1968	-	Sep	Sun>=8	0:00	0	S
+Rule	Cuba	1968	only	-	Apr	14	0:00	1:00	D
+Rule	Cuba	1969	1977	-	Apr	lastSun	0:00	1:00	D
+Rule	Cuba	1969	1971	-	Oct	lastSun	0:00	0	S
+Rule	Cuba	1972	1974	-	Oct	8	0:00	0	S
+Rule	Cuba	1975	1977	-	Oct	lastSun	0:00	0	S
+Rule	Cuba	1978	only	-	May	7	0:00	1:00	D
+Rule	Cuba	1978	1990	-	Oct	Sun>=8	0:00	0	S
+Rule	Cuba	1979	1980	-	Mar	Sun>=15	0:00	1:00	D
+Rule	Cuba	1981	1985	-	May	Sun>=5	0:00	1:00	D
+Rule	Cuba	1986	1989	-	Mar	Sun>=14	0:00	1:00	D
+Rule	Cuba	1990	1997	-	Apr	Sun>=1	0:00	1:00	D
+Rule	Cuba	1991	1995	-	Oct	Sun>=8	0:00s	0	S
+Rule	Cuba	1996	only	-	Oct	 6	0:00s	0	S
+Rule	Cuba	1997	only	-	Oct	12	0:00s	0	S
+Rule	Cuba	1998	1999	-	Mar	lastSun	0:00s	1:00	D
+Rule	Cuba	1998	2003	-	Oct	lastSun	0:00s	0	S
+Rule	Cuba	2000	2006	-	Apr	Sun>=1	0:00s	1:00	D
+Rule	Cuba	2006	max	-	Oct	lastSun	0:00s	0	S
+Rule	Cuba	2007	only	-	Mar	Sun>=8	0:00s	1:00	D
+Rule	Cuba	2008	max	-	Mar	Sun>=15	0:00s	1:00	D
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Havana	-5:29:28 -	LMT	1890
+			-5:29:36 -	HMT	1925 Jul 19 12:00 # Havana MT
+			-5:00	Cuba	C%sT
+
+# Dominica
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Dominica	-4:05:36 -	LMT	1911 Jul 1 0:01		# Roseau
+			-4:00	-	AST
+
+# Dominican Republic
+
+# From Steffen Thorsen (2000-10-30):
+# Enrique Morales reported to me that the Dominican Republic has changed the
+# time zone to Eastern Standard Time as of Sunday 29 at 2 am....
+# http://www.listin.com.do/antes/261000/republica/princi.html
+
+# From Paul Eggert (2000-12-04):
+# That URL (2000-10-26, in Spanish) says they planned to use US-style DST.
+
+# From Rives McDow (2000-12-01):
+# Dominican Republic changed its mind and presidential decree on Tuesday,
+# November 28, 2000, with a new decree.  On Sunday, December 3 at 1:00 AM the
+# Dominican Republic will be reverting to 8 hours from the International Date
+# Line, and will not be using DST in the foreseeable future.  The reason they
+# decided to use DST was to be in synch with Puerto Rico, who was also going
+# to implement DST.  When Puerto Rico didn't implement DST, the president
+# decided to revert.
+
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	DR	1966	only	-	Oct	30	0:00	1:00	D
+Rule	DR	1967	only	-	Feb	28	0:00	0	S
+Rule	DR	1969	1973	-	Oct	lastSun	0:00	0:30	HD
+Rule	DR	1970	only	-	Feb	21	0:00	0	S
+Rule	DR	1971	only	-	Jan	20	0:00	0	S
+Rule	DR	1972	1974	-	Jan	21	0:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Santo_Domingo -4:39:36 -	LMT	1890
+			-4:40	-	SDMT	1933 Apr  1 12:00 # S. Dom. MT
+			-5:00	DR	E%sT	1974 Oct 27
+			-4:00	-	AST	2000 Oct 29 02:00
+			-5:00	US	E%sT	2000 Dec  3 01:00
+			-4:00	-	AST
+
+# El Salvador
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Salv	1987	1988	-	May	Sun>=1	0:00	1:00	D
+Rule	Salv	1987	1988	-	Sep	lastSun	0:00	0	S
+# There are too many San Salvadors elsewhere, so use America/El_Salvador
+# instead of America/San_Salvador.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/El_Salvador -5:56:48 -	LMT	1921		# San Salvador
+			-6:00	Salv	C%sT
+
+# Grenada
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Grenada	-4:07:00 -	LMT	1911 Jul	# St George's
+			-4:00	-	AST
+
+# Guadeloupe
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Guadeloupe	-4:06:08 -	LMT	1911 Jun 8	# Pointe a Pitre
+			-4:00	-	AST
+# St Barthelemy
+Link America/Guadeloupe	America/St_Barthelemy
+# St Martin (French part)
+Link America/Guadeloupe	America/Marigot
+
+# Guatemala
+#
+# From Gwillim Law (2006-04-22), after a heads-up from Oscar van Vlijmen:
+# Diario Co Latino, at
+# http://www.diariocolatino.com/internacionales/detalles.asp?NewsID=8079,
+# says in an article dated 2006-04-19 that the Guatemalan government had
+# decided on that date to advance official time by 60 minutes, to lessen the
+# impact of the elevated cost of oil....  Daylight saving time will last from
+# 2006-04-29 24:00 (Guatemalan standard time) to 2006-09-30 (time unspecified).
+# From Paul Eggert (2006-06-22):
+# The Ministry of Energy and Mines, press release CP-15/2006
+# (2006-04-19), says DST ends at 24:00.  See
+# <http://www.sieca.org.gt/Sitio_publico/Energeticos/Doc/Medidas/Cambio_Horario_Nac_190406.pdf>.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Guat	1973	only	-	Nov	25	0:00	1:00	D
+Rule	Guat	1974	only	-	Feb	24	0:00	0	S
+Rule	Guat	1983	only	-	May	21	0:00	1:00	D
+Rule	Guat	1983	only	-	Sep	22	0:00	0	S
+Rule	Guat	1991	only	-	Mar	23	0:00	1:00	D
+Rule	Guat	1991	only	-	Sep	 7	0:00	0	S
+Rule	Guat	2006	only	-	Apr	30	0:00	1:00	D
+Rule	Guat	2006	only	-	Oct	 1	0:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Guatemala	-6:02:04 -	LMT	1918 Oct 5
+			-6:00	Guat	C%sT
+
+# Haiti
+# From Gwillim Law (2005-04-15):
+# Risto O. Nykanen wrote me that Haiti is now on DST.
+# I searched for confirmation, and I found a
+# <a href="http://www.haitianconsulate.org/time.doc"> press release
+# on the Web page of the Haitian Consulate in Chicago (2005-03-31),
+# </a>.  Translated from French, it says:
+#
+#  "The Prime Minister's Communication Office notifies the public in general
+#   and the press in particular that, following a decision of the Interior
+#   Ministry and the Territorial Collectivities [I suppose that means the
+#   provinces], Haiti will move to Eastern Daylight Time in the night from next
+#   Saturday the 2nd to Sunday the 3rd.
+#
+#  "Consequently, the Prime Minister's Communication Office wishes to inform
+#   the population that the country's clocks will be set forward one hour
+#   starting at midnight.  This provision will hold until the last Saturday in
+#   October 2005.
+#
+#  "Port-au-Prince, March 31, 2005"
+#
+# From Steffen Thorsen (2006-04-04):
+# I have been informed by users that Haiti observes DST this year like
+# last year, so the current "only" rule for 2005 might be changed to a
+# "max" rule or to last until 2006. (Who knows if they will observe DST
+# next year or if they will extend their DST like US/Canada next year).
+#
+# I have found this article about it (in French):
+# http://www.haitipressnetwork.com/news.cfm?articleID=7612
+#
+# The reason seems to be an energy crisis.
+
+# From Stephen Colebourne (2007-02-22):
+# Some IATA info: Haiti won't be having DST in 2007.
+
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Haiti	1983	only	-	May	8	0:00	1:00	D
+Rule	Haiti	1984	1987	-	Apr	lastSun	0:00	1:00	D
+Rule	Haiti	1983	1987	-	Oct	lastSun	0:00	0	S
+# Shanks & Pottenger say AT is 2:00, but IATA SSIM (1991/1997) says 1:00s.
+# Go with IATA.
+Rule	Haiti	1988	1997	-	Apr	Sun>=1	1:00s	1:00	D
+Rule	Haiti	1988	1997	-	Oct	lastSun	1:00s	0	S
+Rule	Haiti	2005	2006	-	Apr	Sun>=1	0:00	1:00	D
+Rule	Haiti	2005	2006	-	Oct	lastSun	0:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Port-au-Prince -4:49:20 -	LMT	1890
+			-4:49	-	PPMT	1917 Jan 24 12:00 # P-a-P MT
+			-5:00	Haiti	E%sT
+
+# Honduras
+# Shanks & Pottenger say 1921 Jan 1; go with Whitman's more precise Apr 1.
+
+# From Paul Eggert (2006-05-05):
+# worldtimezone.com reports a 2006-05-02 Spanish-language AP article
+# saying Honduras will start using DST midnight Saturday, effective 4
+# months until September.  La Tribuna reported today
+# <http://www.latribuna.hn/99299.html> that Manuel Zelaya, the president
+# of Honduras, refused to back down on this.
+
+# From Jesper Norgaard Welen (2006-08-08):
+# It seems that Honduras has returned from DST to standard time this Monday at
+# 00:00 hours (prolonging Sunday to 25 hours duration).
+# http://www.worldtimezone.com/dst_news/dst_news_honduras04.html
+
+# From Paul Eggert (2006-08-08):
+# Also see Diario El Heraldo, The country returns to standard time (2006-08-08)
+# <http://www.elheraldo.hn/nota.php?nid=54941&sec=12>.
+# It mentions executive decree 18-2006.
+
+# From Steffen Thorsen (2006-08-17):
+# Honduras will observe DST from 2007 to 2009, exact dates are not
+# published, I have located this authoritative source:
+# http://www.presidencia.gob.hn/noticia.aspx?nId=47
+
+# From Steffen Thorsen (2007-03-30):
+# http://www.laprensahn.com/pais_nota.php?id04962=7386
+# So it seems that Honduras will not enter DST this year....
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Hond	1987	1988	-	May	Sun>=1	0:00	1:00	D
+Rule	Hond	1987	1988	-	Sep	lastSun	0:00	0	S
+Rule	Hond	2006	only	-	May	Sun>=1	0:00	1:00	D
+Rule	Hond	2006	only	-	Aug	Mon>=1	0:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Tegucigalpa -5:48:52 -	LMT	1921 Apr
+			-6:00	Hond	C%sT
+#
+# Great Swan I ceded by US to Honduras in 1972
+
+# Jamaica
+
+# From Bob Devine (1988-01-28):
+# Follows US rules.
+
+# From U. S. Naval Observatory (1989-01-19):
+# JAMAICA             5 H  BEHIND UTC
+
+# From Shanks & Pottenger:
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Jamaica	-5:07:12 -	LMT	1890		# Kingston
+			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
+			-5:00	-	EST	1974 Apr 28 2:00
+			-5:00	US	E%sT	1984
+			-5:00	-	EST
+
+# Martinique
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Martinique	-4:04:20 -      LMT	1890		# Fort-de-France
+			-4:04:20 -	FFMT	1911 May     # Fort-de-France MT
+			-4:00	-	AST	1980 Apr  6
+			-4:00	1:00	ADT	1980 Sep 28
+			-4:00	-	AST
+
+# Montserrat
+# From Paul Eggert (2006-03-22):
+# In 1995 volcanic eruptions forced evacuation of Plymouth, the capital.
+# world.gazetteer.com says Cork Hill is the most populous location now.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Montserrat	-4:08:52 -	LMT	1911 Jul 1 0:01   # Cork Hill
+			-4:00	-	AST
+
+# Nicaragua
+#
+# This uses Shanks & Pottenger for times before 2005.
+#
+# From Steffen Thorsen (2005-04-12):
+# I've got reports from 8 different people that Nicaragua just started
+# DST on Sunday 2005-04-10, in order to save energy because of
+# expensive petroleum.  The exact end date for DST is not yet
+# announced, only "September" but some sites also say "mid-September".
+# Some background information is available on the President's official site:
+# http://www.presidencia.gob.ni/Presidencia/Files_index/Secretaria/Notas%20de%20Prensa/Presidente/2005/ABRIL/Gobierno-de-nicaragua-adelanta-hora-oficial-06abril.htm
+# The Decree, no 23-2005 is available here:
+# http://www.presidencia.gob.ni/buscador_gaceta/BD/DECRETOS/2005/Decreto%2023-2005%20Se%20adelanta%20en%20una%20hora%20en%20todo%20el%20territorio%20nacional%20apartir%20de%20las%2024horas%20del%2009%20de%20Abril.pdf
+#
+# From Paul Eggert (2005-05-01):
+# The decree doesn't say anything about daylight saving, but for now let's
+# assume that it is daylight saving....
+#
+# From Gwillim Law (2005-04-21):
+# The Associated Press story on the time change, which can be found at
+# http://www.lapalmainteractivo.com/guias/content/gen/ap/America_Latina/AMC_GEN_NICARAGUA_HORA.html
+# and elsewhere, says (fifth paragraph, translated from Spanish):  "The last
+# time that a change of clocks was applied to save energy was in the year 2000
+# during the Arnoldo Aleman administration."...
+# The northamerica file says that Nicaragua has been on UTC-6 continuously
+# since December 1998.  I wasn't able to find any details of Nicaraguan time
+# changes in 2000.  Perhaps a note could be added to the northamerica file, to
+# the effect that we have indirect evidence that DST was observed in 2000.
+#
+# From Jesper Norgaard Welen (2005-11-02):
+# Nicaragua left DST the 2005-10-02 at 00:00 (local time).
+# http://www.presidencia.gob.ni/presidencia/files_index/secretaria/comunicados/2005/septiembre/26septiembre-cambio-hora.htm
+# (2005-09-26)
+#
+# From Jesper Norgaard Welen (2006-05-05):
+# http://www.elnuevodiario.com.ni/2006/05/01/nacionales/18410
+# (my informal translation)
+# By order of the president of the republic, Enrique Bolanos, Nicaragua
+# advanced by sixty minutes their official time, yesterday at 2 in the
+# morning, and will stay that way until 30.th. of september.
+#
+# From Jesper Norgaard Welen (2006-09-30):
+# http://www.presidencia.gob.ni/buscador_gaceta/BD/DECRETOS/2006/D-063-2006P-PRN-Cambio-Hora.pdf
+# My informal translation runs:
+# The natural sun time is restored in all the national territory, in that the
+# time is returned one hour at 01:00 am of October 1 of 2006.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Nic	1979	1980	-	Mar	Sun>=16	0:00	1:00	D
+Rule	Nic	1979	1980	-	Jun	Mon>=23	0:00	0	S
+Rule	Nic	2005	only	-	Apr	10	0:00	1:00	D
+Rule	Nic	2005	only	-	Oct	Sun>=1	0:00	0	S
+Rule	Nic	2006	only	-	Apr	30	2:00	1:00	D
+Rule	Nic	2006	only	-	Oct	Sun>=1	1:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Managua	-5:45:08 -	LMT	1890
+			-5:45:12 -	MMT	1934 Jun 23 # Managua Mean Time?
+			-6:00	-	CST	1973 May
+			-5:00	-	EST	1975 Feb 16
+			-6:00	Nic	C%sT	1992 Jan  1 4:00
+			-5:00	-	EST	1992 Sep 24
+			-6:00	-	CST	1993
+			-5:00	-	EST	1997
+			-6:00	Nic	C%sT
+
+# Panama
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Panama	-5:18:08 -	LMT	1890
+			-5:19:36 -	CMT	1908 Apr 22   # Colon Mean Time
+			-5:00	-	EST
+
+# Puerto Rico
+# There are too many San Juans elsewhere, so we'll use `Puerto_Rico'.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Puerto_Rico -4:24:25 -	LMT	1899 Mar 28 12:00    # San Juan
+			-4:00	-	AST	1942 May  3
+			-4:00	US	A%sT	1946
+			-4:00	-	AST
+
+# St Kitts-Nevis
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/St_Kitts	-4:10:52 -	LMT	1912 Mar 2	# Basseterre
+			-4:00	-	AST
+
+# St Lucia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/St_Lucia	-4:04:00 -	LMT	1890		# Castries
+			-4:04:00 -	CMT	1912	    # Castries Mean Time
+			-4:00	-	AST
+
+# St Pierre and Miquelon
+# There are too many St Pierres elsewhere, so we'll use `Miquelon'.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Miquelon	-3:44:40 -	LMT	1911 May 15	# St Pierre
+			-4:00	-	AST	1980 May
+			-3:00	-	PMST	1987 # Pierre & Miquelon Time
+			-3:00	Canada	PM%sT
+
+# St Vincent and the Grenadines
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/St_Vincent	-4:04:56 -	LMT	1890		# Kingstown
+			-4:04:56 -	KMT	1912	   # Kingstown Mean Time
+			-4:00	-	AST
+
+# Turks and Caicos
+#
+# From Chris Dunn in
+# <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=415007>
+# (2007-03-15): In the Turks & Caicos Islands (America/Grand_Turk) the
+# daylight saving dates for time changes have been adjusted to match
+# the recent U.S. change of dates.
+#
+# From Brian Inglis (2007-04-28):
+# http://www.turksandcaicos.tc/calendar/index.htm [2007-04-26]
+# there is an entry for Nov 4 "Daylight Savings Time Ends 2007" and three
+# rows before that there is an out of date entry for Oct:
+# "Eastern Standard Times Begins 2007
+# Clocks are set back one hour at 2:00 a.m. local Daylight Saving Time"
+# indicating that the normal ET rules are followed.
+#
+# From Paul Eggert (2006-05-01):
+# Shanks & Pottenger say they use US DST rules, but IATA SSIM (1991/1998)
+# says they switch at midnight.  Go with Shanks & Pottenger.
+#
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	TC	1979	1986	-	Apr	lastSun	2:00	1:00	D
+Rule	TC	1979	2006	-	Oct	lastSun	2:00	0	S
+Rule	TC	1987	2006	-	Apr	Sun>=1	2:00	1:00	D
+Rule	TC	2007	max	-	Mar	Sun>=8	2:00	1:00	D
+Rule	TC	2007	max	-	Nov	Sun>=1	2:00	0	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Grand_Turk	-4:44:32 -	LMT	1890
+			-5:07:12 -	KMT	1912 Feb    # Kingston Mean Time
+			-5:00	TC	E%sT
+
+# British Virgin Is
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Tortola	-4:18:28 -	LMT	1911 Jul    # Road Town
+			-4:00	-	AST
+
+# Virgin Is
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/St_Thomas	-4:19:44 -	LMT	1911 Jul    # Charlotte Amalie
+			-4:00	-	AST
diff --git a/tools/zoneinfo/tzdata2008h/pacificnew b/tools/zoneinfo/tzdata2008h/pacificnew
new file mode 100644
index 0000000..667940b
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/pacificnew
@@ -0,0 +1,26 @@
+# @(#)pacificnew	8.1
+
+# From Arthur David Olson (1989-04-05):
+# On 1989-04-05, the U. S. House of Representatives passed (238-154) a bill
+# establishing "Pacific Presidential Election Time"; it was not acted on
+# by the Senate or signed into law by the President.
+# You might want to change the "PE" (Presidential Election) below to
+# "Q" (Quadrennial) to maintain three-character zone abbreviations.
+# If you're really conservative, you might want to change it to "D".
+# Avoid "L" (Leap Year), which won't be true in 2100.
+
+# If Presidential Election Time is ever established, replace "XXXX" below
+# with the year the law takes effect and uncomment the "##" lines.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+## Rule	Twilite	XXXX	max	-	Apr	Sun>=1	2:00	1:00	D
+## Rule	Twilite	XXXX	max	uspres	Oct	lastSun	2:00	1:00	PE
+## Rule	Twilite	XXXX	max	uspres	Nov	Sun>=7	2:00	0	S
+## Rule	Twilite	XXXX	max	nonpres	Oct	lastSun	2:00	0	S
+
+# Zone	NAME			GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
+## Zone	America/Los_Angeles-PET	-8:00	US		P%sT	XXXX
+##				-8:00	Twilite		P%sT
+
+# For now...
+Link	America/Los_Angeles	US/Pacific-New	##
diff --git a/tools/zoneinfo/tzdata2008h/solar87 b/tools/zoneinfo/tzdata2008h/solar87
new file mode 100644
index 0000000..7183932
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/solar87
@@ -0,0 +1,388 @@
+# @(#)solar87	8.1
+
+# So much for footnotes about Saudi Arabia.
+# Apparent noon times below are for Riyadh; your mileage will vary.
+# Times were computed using formulas in the U.S. Naval Observatory's
+# Almanac for Computers 1987; the formulas "will give EqT to an accuracy of
+# [plus or minus two] seconds during the current year."
+#
+# Rounding to the nearest five seconds results in fewer than
+# 256 different "time types"--a limit that's faced because time types are
+# stored on disk as unsigned chars.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	sol87	1987	only	-	Jan	1	12:03:20s -0:03:20 -
+Rule	sol87	1987	only	-	Jan	2	12:03:50s -0:03:50 -
+Rule	sol87	1987	only	-	Jan	3	12:04:15s -0:04:15 -
+Rule	sol87	1987	only	-	Jan	4	12:04:45s -0:04:45 -
+Rule	sol87	1987	only	-	Jan	5	12:05:10s -0:05:10 -
+Rule	sol87	1987	only	-	Jan	6	12:05:40s -0:05:40 -
+Rule	sol87	1987	only	-	Jan	7	12:06:05s -0:06:05 -
+Rule	sol87	1987	only	-	Jan	8	12:06:30s -0:06:30 -
+Rule	sol87	1987	only	-	Jan	9	12:06:55s -0:06:55 -
+Rule	sol87	1987	only	-	Jan	10	12:07:20s -0:07:20 -
+Rule	sol87	1987	only	-	Jan	11	12:07:45s -0:07:45 -
+Rule	sol87	1987	only	-	Jan	12	12:08:10s -0:08:10 -
+Rule	sol87	1987	only	-	Jan	13	12:08:30s -0:08:30 -
+Rule	sol87	1987	only	-	Jan	14	12:08:55s -0:08:55 -
+Rule	sol87	1987	only	-	Jan	15	12:09:15s -0:09:15 -
+Rule	sol87	1987	only	-	Jan	16	12:09:35s -0:09:35 -
+Rule	sol87	1987	only	-	Jan	17	12:09:55s -0:09:55 -
+Rule	sol87	1987	only	-	Jan	18	12:10:15s -0:10:15 -
+Rule	sol87	1987	only	-	Jan	19	12:10:35s -0:10:35 -
+Rule	sol87	1987	only	-	Jan	20	12:10:55s -0:10:55 -
+Rule	sol87	1987	only	-	Jan	21	12:11:10s -0:11:10 -
+Rule	sol87	1987	only	-	Jan	22	12:11:30s -0:11:30 -
+Rule	sol87	1987	only	-	Jan	23	12:11:45s -0:11:45 -
+Rule	sol87	1987	only	-	Jan	24	12:12:00s -0:12:00 -
+Rule	sol87	1987	only	-	Jan	25	12:12:15s -0:12:15 -
+Rule	sol87	1987	only	-	Jan	26	12:12:30s -0:12:30 -
+Rule	sol87	1987	only	-	Jan	27	12:12:40s -0:12:40 -
+Rule	sol87	1987	only	-	Jan	28	12:12:55s -0:12:55 -
+Rule	sol87	1987	only	-	Jan	29	12:13:05s -0:13:05 -
+Rule	sol87	1987	only	-	Jan	30	12:13:15s -0:13:15 -
+Rule	sol87	1987	only	-	Jan	31	12:13:25s -0:13:25 -
+Rule	sol87	1987	only	-	Feb	1	12:13:35s -0:13:35 -
+Rule	sol87	1987	only	-	Feb	2	12:13:40s -0:13:40 -
+Rule	sol87	1987	only	-	Feb	3	12:13:50s -0:13:50 -
+Rule	sol87	1987	only	-	Feb	4	12:13:55s -0:13:55 -
+Rule	sol87	1987	only	-	Feb	5	12:14:00s -0:14:00 -
+Rule	sol87	1987	only	-	Feb	6	12:14:05s -0:14:05 -
+Rule	sol87	1987	only	-	Feb	7	12:14:10s -0:14:10 -
+Rule	sol87	1987	only	-	Feb	8	12:14:10s -0:14:10 -
+Rule	sol87	1987	only	-	Feb	9	12:14:15s -0:14:15 -
+Rule	sol87	1987	only	-	Feb	10	12:14:15s -0:14:15 -
+Rule	sol87	1987	only	-	Feb	11	12:14:15s -0:14:15 -
+Rule	sol87	1987	only	-	Feb	12	12:14:15s -0:14:15 -
+Rule	sol87	1987	only	-	Feb	13	12:14:15s -0:14:15 -
+Rule	sol87	1987	only	-	Feb	14	12:14:15s -0:14:15 -
+Rule	sol87	1987	only	-	Feb	15	12:14:10s -0:14:10 -
+Rule	sol87	1987	only	-	Feb	16	12:14:10s -0:14:10 -
+Rule	sol87	1987	only	-	Feb	17	12:14:05s -0:14:05 -
+Rule	sol87	1987	only	-	Feb	18	12:14:00s -0:14:00 -
+Rule	sol87	1987	only	-	Feb	19	12:13:55s -0:13:55 -
+Rule	sol87	1987	only	-	Feb	20	12:13:50s -0:13:50 -
+Rule	sol87	1987	only	-	Feb	21	12:13:45s -0:13:45 -
+Rule	sol87	1987	only	-	Feb	22	12:13:35s -0:13:35 -
+Rule	sol87	1987	only	-	Feb	23	12:13:30s -0:13:30 -
+Rule	sol87	1987	only	-	Feb	24	12:13:20s -0:13:20 -
+Rule	sol87	1987	only	-	Feb	25	12:13:10s -0:13:10 -
+Rule	sol87	1987	only	-	Feb	26	12:13:00s -0:13:00 -
+Rule	sol87	1987	only	-	Feb	27	12:12:50s -0:12:50 -
+Rule	sol87	1987	only	-	Feb	28	12:12:40s -0:12:40 -
+Rule	sol87	1987	only	-	Mar	1	12:12:30s -0:12:30 -
+Rule	sol87	1987	only	-	Mar	2	12:12:20s -0:12:20 -
+Rule	sol87	1987	only	-	Mar	3	12:12:05s -0:12:05 -
+Rule	sol87	1987	only	-	Mar	4	12:11:55s -0:11:55 -
+Rule	sol87	1987	only	-	Mar	5	12:11:40s -0:11:40 -
+Rule	sol87	1987	only	-	Mar	6	12:11:25s -0:11:25 -
+Rule	sol87	1987	only	-	Mar	7	12:11:15s -0:11:15 -
+Rule	sol87	1987	only	-	Mar	8	12:11:00s -0:11:00 -
+Rule	sol87	1987	only	-	Mar	9	12:10:45s -0:10:45 -
+Rule	sol87	1987	only	-	Mar	10	12:10:30s -0:10:30 -
+Rule	sol87	1987	only	-	Mar	11	12:10:15s -0:10:15 -
+Rule	sol87	1987	only	-	Mar	12	12:09:55s -0:09:55 -
+Rule	sol87	1987	only	-	Mar	13	12:09:40s -0:09:40 -
+Rule	sol87	1987	only	-	Mar	14	12:09:25s -0:09:25 -
+Rule	sol87	1987	only	-	Mar	15	12:09:10s -0:09:10 -
+Rule	sol87	1987	only	-	Mar	16	12:08:50s -0:08:50 -
+Rule	sol87	1987	only	-	Mar	17	12:08:35s -0:08:35 -
+Rule	sol87	1987	only	-	Mar	18	12:08:15s -0:08:15 -
+Rule	sol87	1987	only	-	Mar	19	12:08:00s -0:08:00 -
+Rule	sol87	1987	only	-	Mar	20	12:07:40s -0:07:40 -
+Rule	sol87	1987	only	-	Mar	21	12:07:25s -0:07:25 -
+Rule	sol87	1987	only	-	Mar	22	12:07:05s -0:07:05 -
+Rule	sol87	1987	only	-	Mar	23	12:06:50s -0:06:50 -
+Rule	sol87	1987	only	-	Mar	24	12:06:30s -0:06:30 -
+Rule	sol87	1987	only	-	Mar	25	12:06:10s -0:06:10 -
+Rule	sol87	1987	only	-	Mar	26	12:05:55s -0:05:55 -
+Rule	sol87	1987	only	-	Mar	27	12:05:35s -0:05:35 -
+Rule	sol87	1987	only	-	Mar	28	12:05:15s -0:05:15 -
+Rule	sol87	1987	only	-	Mar	29	12:05:00s -0:05:00 -
+Rule	sol87	1987	only	-	Mar	30	12:04:40s -0:04:40 -
+Rule	sol87	1987	only	-	Mar	31	12:04:25s -0:04:25 -
+Rule	sol87	1987	only	-	Apr	1	12:04:05s -0:04:05 -
+Rule	sol87	1987	only	-	Apr	2	12:03:45s -0:03:45 -
+Rule	sol87	1987	only	-	Apr	3	12:03:30s -0:03:30 -
+Rule	sol87	1987	only	-	Apr	4	12:03:10s -0:03:10 -
+Rule	sol87	1987	only	-	Apr	5	12:02:55s -0:02:55 -
+Rule	sol87	1987	only	-	Apr	6	12:02:35s -0:02:35 -
+Rule	sol87	1987	only	-	Apr	7	12:02:20s -0:02:20 -
+Rule	sol87	1987	only	-	Apr	8	12:02:05s -0:02:05 -
+Rule	sol87	1987	only	-	Apr	9	12:01:45s -0:01:45 -
+Rule	sol87	1987	only	-	Apr	10	12:01:30s -0:01:30 -
+Rule	sol87	1987	only	-	Apr	11	12:01:15s -0:01:15 -
+Rule	sol87	1987	only	-	Apr	12	12:00:55s -0:00:55 -
+Rule	sol87	1987	only	-	Apr	13	12:00:40s -0:00:40 -
+Rule	sol87	1987	only	-	Apr	14	12:00:25s -0:00:25 -
+Rule	sol87	1987	only	-	Apr	15	12:00:10s -0:00:10 -
+Rule	sol87	1987	only	-	Apr	16	11:59:55s 0:00:05 -
+Rule	sol87	1987	only	-	Apr	17	11:59:45s 0:00:15 -
+Rule	sol87	1987	only	-	Apr	18	11:59:30s 0:00:30 -
+Rule	sol87	1987	only	-	Apr	19	11:59:15s 0:00:45 -
+Rule	sol87	1987	only	-	Apr	20	11:59:05s 0:00:55 -
+Rule	sol87	1987	only	-	Apr	21	11:58:50s 0:01:10 -
+Rule	sol87	1987	only	-	Apr	22	11:58:40s 0:01:20 -
+Rule	sol87	1987	only	-	Apr	23	11:58:25s 0:01:35 -
+Rule	sol87	1987	only	-	Apr	24	11:58:15s 0:01:45 -
+Rule	sol87	1987	only	-	Apr	25	11:58:05s 0:01:55 -
+Rule	sol87	1987	only	-	Apr	26	11:57:55s 0:02:05 -
+Rule	sol87	1987	only	-	Apr	27	11:57:45s 0:02:15 -
+Rule	sol87	1987	only	-	Apr	28	11:57:35s 0:02:25 -
+Rule	sol87	1987	only	-	Apr	29	11:57:25s 0:02:35 -
+Rule	sol87	1987	only	-	Apr	30	11:57:15s 0:02:45 -
+Rule	sol87	1987	only	-	May	1	11:57:10s 0:02:50 -
+Rule	sol87	1987	only	-	May	2	11:57:00s 0:03:00 -
+Rule	sol87	1987	only	-	May	3	11:56:55s 0:03:05 -
+Rule	sol87	1987	only	-	May	4	11:56:50s 0:03:10 -
+Rule	sol87	1987	only	-	May	5	11:56:45s 0:03:15 -
+Rule	sol87	1987	only	-	May	6	11:56:40s 0:03:20 -
+Rule	sol87	1987	only	-	May	7	11:56:35s 0:03:25 -
+Rule	sol87	1987	only	-	May	8	11:56:30s 0:03:30 -
+Rule	sol87	1987	only	-	May	9	11:56:25s 0:03:35 -
+Rule	sol87	1987	only	-	May	10	11:56:25s 0:03:35 -
+Rule	sol87	1987	only	-	May	11	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	12	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	13	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	14	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	15	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	16	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	17	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	18	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	May	19	11:56:25s 0:03:35 -
+Rule	sol87	1987	only	-	May	20	11:56:25s 0:03:35 -
+Rule	sol87	1987	only	-	May	21	11:56:30s 0:03:30 -
+Rule	sol87	1987	only	-	May	22	11:56:35s 0:03:25 -
+Rule	sol87	1987	only	-	May	23	11:56:40s 0:03:20 -
+Rule	sol87	1987	only	-	May	24	11:56:45s 0:03:15 -
+Rule	sol87	1987	only	-	May	25	11:56:50s 0:03:10 -
+Rule	sol87	1987	only	-	May	26	11:56:55s 0:03:05 -
+Rule	sol87	1987	only	-	May	27	11:57:00s 0:03:00 -
+Rule	sol87	1987	only	-	May	28	11:57:10s 0:02:50 -
+Rule	sol87	1987	only	-	May	29	11:57:15s 0:02:45 -
+Rule	sol87	1987	only	-	May	30	11:57:25s 0:02:35 -
+Rule	sol87	1987	only	-	May	31	11:57:30s 0:02:30 -
+Rule	sol87	1987	only	-	Jun	1	11:57:40s 0:02:20 -
+Rule	sol87	1987	only	-	Jun	2	11:57:50s 0:02:10 -
+Rule	sol87	1987	only	-	Jun	3	11:58:00s 0:02:00 -
+Rule	sol87	1987	only	-	Jun	4	11:58:10s 0:01:50 -
+Rule	sol87	1987	only	-	Jun	5	11:58:20s 0:01:40 -
+Rule	sol87	1987	only	-	Jun	6	11:58:30s 0:01:30 -
+Rule	sol87	1987	only	-	Jun	7	11:58:40s 0:01:20 -
+Rule	sol87	1987	only	-	Jun	8	11:58:50s 0:01:10 -
+Rule	sol87	1987	only	-	Jun	9	11:59:05s 0:00:55 -
+Rule	sol87	1987	only	-	Jun	10	11:59:15s 0:00:45 -
+Rule	sol87	1987	only	-	Jun	11	11:59:30s 0:00:30 -
+Rule	sol87	1987	only	-	Jun	12	11:59:40s 0:00:20 -
+Rule	sol87	1987	only	-	Jun	13	11:59:50s 0:00:10 -
+Rule	sol87	1987	only	-	Jun	14	12:00:05s -0:00:05 -
+Rule	sol87	1987	only	-	Jun	15	12:00:15s -0:00:15 -
+Rule	sol87	1987	only	-	Jun	16	12:00:30s -0:00:30 -
+Rule	sol87	1987	only	-	Jun	17	12:00:45s -0:00:45 -
+Rule	sol87	1987	only	-	Jun	18	12:00:55s -0:00:55 -
+Rule	sol87	1987	only	-	Jun	19	12:01:10s -0:01:10 -
+Rule	sol87	1987	only	-	Jun	20	12:01:20s -0:01:20 -
+Rule	sol87	1987	only	-	Jun	21	12:01:35s -0:01:35 -
+Rule	sol87	1987	only	-	Jun	22	12:01:50s -0:01:50 -
+Rule	sol87	1987	only	-	Jun	23	12:02:00s -0:02:00 -
+Rule	sol87	1987	only	-	Jun	24	12:02:15s -0:02:15 -
+Rule	sol87	1987	only	-	Jun	25	12:02:25s -0:02:25 -
+Rule	sol87	1987	only	-	Jun	26	12:02:40s -0:02:40 -
+Rule	sol87	1987	only	-	Jun	27	12:02:50s -0:02:50 -
+Rule	sol87	1987	only	-	Jun	28	12:03:05s -0:03:05 -
+Rule	sol87	1987	only	-	Jun	29	12:03:15s -0:03:15 -
+Rule	sol87	1987	only	-	Jun	30	12:03:30s -0:03:30 -
+Rule	sol87	1987	only	-	Jul	1	12:03:40s -0:03:40 -
+Rule	sol87	1987	only	-	Jul	2	12:03:50s -0:03:50 -
+Rule	sol87	1987	only	-	Jul	3	12:04:05s -0:04:05 -
+Rule	sol87	1987	only	-	Jul	4	12:04:15s -0:04:15 -
+Rule	sol87	1987	only	-	Jul	5	12:04:25s -0:04:25 -
+Rule	sol87	1987	only	-	Jul	6	12:04:35s -0:04:35 -
+Rule	sol87	1987	only	-	Jul	7	12:04:45s -0:04:45 -
+Rule	sol87	1987	only	-	Jul	8	12:04:55s -0:04:55 -
+Rule	sol87	1987	only	-	Jul	9	12:05:05s -0:05:05 -
+Rule	sol87	1987	only	-	Jul	10	12:05:15s -0:05:15 -
+Rule	sol87	1987	only	-	Jul	11	12:05:20s -0:05:20 -
+Rule	sol87	1987	only	-	Jul	12	12:05:30s -0:05:30 -
+Rule	sol87	1987	only	-	Jul	13	12:05:40s -0:05:40 -
+Rule	sol87	1987	only	-	Jul	14	12:05:45s -0:05:45 -
+Rule	sol87	1987	only	-	Jul	15	12:05:50s -0:05:50 -
+Rule	sol87	1987	only	-	Jul	16	12:06:00s -0:06:00 -
+Rule	sol87	1987	only	-	Jul	17	12:06:05s -0:06:05 -
+Rule	sol87	1987	only	-	Jul	18	12:06:10s -0:06:10 -
+Rule	sol87	1987	only	-	Jul	19	12:06:15s -0:06:15 -
+Rule	sol87	1987	only	-	Jul	20	12:06:15s -0:06:15 -
+Rule	sol87	1987	only	-	Jul	21	12:06:20s -0:06:20 -
+Rule	sol87	1987	only	-	Jul	22	12:06:25s -0:06:25 -
+Rule	sol87	1987	only	-	Jul	23	12:06:25s -0:06:25 -
+Rule	sol87	1987	only	-	Jul	24	12:06:25s -0:06:25 -
+Rule	sol87	1987	only	-	Jul	25	12:06:30s -0:06:30 -
+Rule	sol87	1987	only	-	Jul	26	12:06:30s -0:06:30 -
+Rule	sol87	1987	only	-	Jul	27	12:06:30s -0:06:30 -
+Rule	sol87	1987	only	-	Jul	28	12:06:30s -0:06:30 -
+Rule	sol87	1987	only	-	Jul	29	12:06:25s -0:06:25 -
+Rule	sol87	1987	only	-	Jul	30	12:06:25s -0:06:25 -
+Rule	sol87	1987	only	-	Jul	31	12:06:25s -0:06:25 -
+Rule	sol87	1987	only	-	Aug	1	12:06:20s -0:06:20 -
+Rule	sol87	1987	only	-	Aug	2	12:06:15s -0:06:15 -
+Rule	sol87	1987	only	-	Aug	3	12:06:10s -0:06:10 -
+Rule	sol87	1987	only	-	Aug	4	12:06:05s -0:06:05 -
+Rule	sol87	1987	only	-	Aug	5	12:06:00s -0:06:00 -
+Rule	sol87	1987	only	-	Aug	6	12:05:55s -0:05:55 -
+Rule	sol87	1987	only	-	Aug	7	12:05:50s -0:05:50 -
+Rule	sol87	1987	only	-	Aug	8	12:05:40s -0:05:40 -
+Rule	sol87	1987	only	-	Aug	9	12:05:35s -0:05:35 -
+Rule	sol87	1987	only	-	Aug	10	12:05:25s -0:05:25 -
+Rule	sol87	1987	only	-	Aug	11	12:05:15s -0:05:15 -
+Rule	sol87	1987	only	-	Aug	12	12:05:05s -0:05:05 -
+Rule	sol87	1987	only	-	Aug	13	12:04:55s -0:04:55 -
+Rule	sol87	1987	only	-	Aug	14	12:04:45s -0:04:45 -
+Rule	sol87	1987	only	-	Aug	15	12:04:35s -0:04:35 -
+Rule	sol87	1987	only	-	Aug	16	12:04:25s -0:04:25 -
+Rule	sol87	1987	only	-	Aug	17	12:04:10s -0:04:10 -
+Rule	sol87	1987	only	-	Aug	18	12:04:00s -0:04:00 -
+Rule	sol87	1987	only	-	Aug	19	12:03:45s -0:03:45 -
+Rule	sol87	1987	only	-	Aug	20	12:03:30s -0:03:30 -
+Rule	sol87	1987	only	-	Aug	21	12:03:15s -0:03:15 -
+Rule	sol87	1987	only	-	Aug	22	12:03:00s -0:03:00 -
+Rule	sol87	1987	only	-	Aug	23	12:02:45s -0:02:45 -
+Rule	sol87	1987	only	-	Aug	24	12:02:30s -0:02:30 -
+Rule	sol87	1987	only	-	Aug	25	12:02:15s -0:02:15 -
+Rule	sol87	1987	only	-	Aug	26	12:02:00s -0:02:00 -
+Rule	sol87	1987	only	-	Aug	27	12:01:40s -0:01:40 -
+Rule	sol87	1987	only	-	Aug	28	12:01:25s -0:01:25 -
+Rule	sol87	1987	only	-	Aug	29	12:01:05s -0:01:05 -
+Rule	sol87	1987	only	-	Aug	30	12:00:50s -0:00:50 -
+Rule	sol87	1987	only	-	Aug	31	12:00:30s -0:00:30 -
+Rule	sol87	1987	only	-	Sep	1	12:00:10s -0:00:10 -
+Rule	sol87	1987	only	-	Sep	2	11:59:50s 0:00:10 -
+Rule	sol87	1987	only	-	Sep	3	11:59:35s 0:00:25 -
+Rule	sol87	1987	only	-	Sep	4	11:59:15s 0:00:45 -
+Rule	sol87	1987	only	-	Sep	5	11:58:55s 0:01:05 -
+Rule	sol87	1987	only	-	Sep	6	11:58:35s 0:01:25 -
+Rule	sol87	1987	only	-	Sep	7	11:58:15s 0:01:45 -
+Rule	sol87	1987	only	-	Sep	8	11:57:55s 0:02:05 -
+Rule	sol87	1987	only	-	Sep	9	11:57:30s 0:02:30 -
+Rule	sol87	1987	only	-	Sep	10	11:57:10s 0:02:50 -
+Rule	sol87	1987	only	-	Sep	11	11:56:50s 0:03:10 -
+Rule	sol87	1987	only	-	Sep	12	11:56:30s 0:03:30 -
+Rule	sol87	1987	only	-	Sep	13	11:56:10s 0:03:50 -
+Rule	sol87	1987	only	-	Sep	14	11:55:45s 0:04:15 -
+Rule	sol87	1987	only	-	Sep	15	11:55:25s 0:04:35 -
+Rule	sol87	1987	only	-	Sep	16	11:55:05s 0:04:55 -
+Rule	sol87	1987	only	-	Sep	17	11:54:45s 0:05:15 -
+Rule	sol87	1987	only	-	Sep	18	11:54:20s 0:05:40 -
+Rule	sol87	1987	only	-	Sep	19	11:54:00s 0:06:00 -
+Rule	sol87	1987	only	-	Sep	20	11:53:40s 0:06:20 -
+Rule	sol87	1987	only	-	Sep	21	11:53:15s 0:06:45 -
+Rule	sol87	1987	only	-	Sep	22	11:52:55s 0:07:05 -
+Rule	sol87	1987	only	-	Sep	23	11:52:35s 0:07:25 -
+Rule	sol87	1987	only	-	Sep	24	11:52:15s 0:07:45 -
+Rule	sol87	1987	only	-	Sep	25	11:51:55s 0:08:05 -
+Rule	sol87	1987	only	-	Sep	26	11:51:35s 0:08:25 -
+Rule	sol87	1987	only	-	Sep	27	11:51:10s 0:08:50 -
+Rule	sol87	1987	only	-	Sep	28	11:50:50s 0:09:10 -
+Rule	sol87	1987	only	-	Sep	29	11:50:30s 0:09:30 -
+Rule	sol87	1987	only	-	Sep	30	11:50:10s 0:09:50 -
+Rule	sol87	1987	only	-	Oct	1	11:49:50s 0:10:10 -
+Rule	sol87	1987	only	-	Oct	2	11:49:35s 0:10:25 -
+Rule	sol87	1987	only	-	Oct	3	11:49:15s 0:10:45 -
+Rule	sol87	1987	only	-	Oct	4	11:48:55s 0:11:05 -
+Rule	sol87	1987	only	-	Oct	5	11:48:35s 0:11:25 -
+Rule	sol87	1987	only	-	Oct	6	11:48:20s 0:11:40 -
+Rule	sol87	1987	only	-	Oct	7	11:48:00s 0:12:00 -
+Rule	sol87	1987	only	-	Oct	8	11:47:45s 0:12:15 -
+Rule	sol87	1987	only	-	Oct	9	11:47:25s 0:12:35 -
+Rule	sol87	1987	only	-	Oct	10	11:47:10s 0:12:50 -
+Rule	sol87	1987	only	-	Oct	11	11:46:55s 0:13:05 -
+Rule	sol87	1987	only	-	Oct	12	11:46:40s 0:13:20 -
+Rule	sol87	1987	only	-	Oct	13	11:46:25s 0:13:35 -
+Rule	sol87	1987	only	-	Oct	14	11:46:10s 0:13:50 -
+Rule	sol87	1987	only	-	Oct	15	11:45:55s 0:14:05 -
+Rule	sol87	1987	only	-	Oct	16	11:45:45s 0:14:15 -
+Rule	sol87	1987	only	-	Oct	17	11:45:30s 0:14:30 -
+Rule	sol87	1987	only	-	Oct	18	11:45:20s 0:14:40 -
+Rule	sol87	1987	only	-	Oct	19	11:45:05s 0:14:55 -
+Rule	sol87	1987	only	-	Oct	20	11:44:55s 0:15:05 -
+Rule	sol87	1987	only	-	Oct	21	11:44:45s 0:15:15 -
+Rule	sol87	1987	only	-	Oct	22	11:44:35s 0:15:25 -
+Rule	sol87	1987	only	-	Oct	23	11:44:25s 0:15:35 -
+Rule	sol87	1987	only	-	Oct	24	11:44:20s 0:15:40 -
+Rule	sol87	1987	only	-	Oct	25	11:44:10s 0:15:50 -
+Rule	sol87	1987	only	-	Oct	26	11:44:05s 0:15:55 -
+Rule	sol87	1987	only	-	Oct	27	11:43:55s 0:16:05 -
+Rule	sol87	1987	only	-	Oct	28	11:43:50s 0:16:10 -
+Rule	sol87	1987	only	-	Oct	29	11:43:45s 0:16:15 -
+Rule	sol87	1987	only	-	Oct	30	11:43:45s 0:16:15 -
+Rule	sol87	1987	only	-	Oct	31	11:43:40s 0:16:20 -
+Rule	sol87	1987	only	-	Nov	1	11:43:40s 0:16:20 -
+Rule	sol87	1987	only	-	Nov	2	11:43:35s 0:16:25 -
+Rule	sol87	1987	only	-	Nov	3	11:43:35s 0:16:25 -
+Rule	sol87	1987	only	-	Nov	4	11:43:35s 0:16:25 -
+Rule	sol87	1987	only	-	Nov	5	11:43:35s 0:16:25 -
+Rule	sol87	1987	only	-	Nov	6	11:43:40s 0:16:20 -
+Rule	sol87	1987	only	-	Nov	7	11:43:40s 0:16:20 -
+Rule	sol87	1987	only	-	Nov	8	11:43:45s 0:16:15 -
+Rule	sol87	1987	only	-	Nov	9	11:43:50s 0:16:10 -
+Rule	sol87	1987	only	-	Nov	10	11:43:55s 0:16:05 -
+Rule	sol87	1987	only	-	Nov	11	11:44:00s 0:16:00 -
+Rule	sol87	1987	only	-	Nov	12	11:44:05s 0:15:55 -
+Rule	sol87	1987	only	-	Nov	13	11:44:15s 0:15:45 -
+Rule	sol87	1987	only	-	Nov	14	11:44:20s 0:15:40 -
+Rule	sol87	1987	only	-	Nov	15	11:44:30s 0:15:30 -
+Rule	sol87	1987	only	-	Nov	16	11:44:40s 0:15:20 -
+Rule	sol87	1987	only	-	Nov	17	11:44:50s 0:15:10 -
+Rule	sol87	1987	only	-	Nov	18	11:45:05s 0:14:55 -
+Rule	sol87	1987	only	-	Nov	19	11:45:15s 0:14:45 -
+Rule	sol87	1987	only	-	Nov	20	11:45:30s 0:14:30 -
+Rule	sol87	1987	only	-	Nov	21	11:45:45s 0:14:15 -
+Rule	sol87	1987	only	-	Nov	22	11:46:00s 0:14:00 -
+Rule	sol87	1987	only	-	Nov	23	11:46:15s 0:13:45 -
+Rule	sol87	1987	only	-	Nov	24	11:46:30s 0:13:30 -
+Rule	sol87	1987	only	-	Nov	25	11:46:50s 0:13:10 -
+Rule	sol87	1987	only	-	Nov	26	11:47:10s 0:12:50 -
+Rule	sol87	1987	only	-	Nov	27	11:47:25s 0:12:35 -
+Rule	sol87	1987	only	-	Nov	28	11:47:45s 0:12:15 -
+Rule	sol87	1987	only	-	Nov	29	11:48:05s 0:11:55 -
+Rule	sol87	1987	only	-	Nov	30	11:48:30s 0:11:30 -
+Rule	sol87	1987	only	-	Dec	1	11:48:50s 0:11:10 -
+Rule	sol87	1987	only	-	Dec	2	11:49:10s 0:10:50 -
+Rule	sol87	1987	only	-	Dec	3	11:49:35s 0:10:25 -
+Rule	sol87	1987	only	-	Dec	4	11:50:00s 0:10:00 -
+Rule	sol87	1987	only	-	Dec	5	11:50:25s 0:09:35 -
+Rule	sol87	1987	only	-	Dec	6	11:50:50s 0:09:10 -
+Rule	sol87	1987	only	-	Dec	7	11:51:15s 0:08:45 -
+Rule	sol87	1987	only	-	Dec	8	11:51:40s 0:08:20 -
+Rule	sol87	1987	only	-	Dec	9	11:52:05s 0:07:55 -
+Rule	sol87	1987	only	-	Dec	10	11:52:30s 0:07:30 -
+Rule	sol87	1987	only	-	Dec	11	11:53:00s 0:07:00 -
+Rule	sol87	1987	only	-	Dec	12	11:53:25s 0:06:35 -
+Rule	sol87	1987	only	-	Dec	13	11:53:55s 0:06:05 -
+Rule	sol87	1987	only	-	Dec	14	11:54:25s 0:05:35 -
+Rule	sol87	1987	only	-	Dec	15	11:54:50s 0:05:10 -
+Rule	sol87	1987	only	-	Dec	16	11:55:20s 0:04:40 -
+Rule	sol87	1987	only	-	Dec	17	11:55:50s 0:04:10 -
+Rule	sol87	1987	only	-	Dec	18	11:56:20s 0:03:40 -
+Rule	sol87	1987	only	-	Dec	19	11:56:50s 0:03:10 -
+Rule	sol87	1987	only	-	Dec	20	11:57:20s 0:02:40 -
+Rule	sol87	1987	only	-	Dec	21	11:57:50s 0:02:10 -
+Rule	sol87	1987	only	-	Dec	22	11:58:20s 0:01:40 -
+Rule	sol87	1987	only	-	Dec	23	11:58:50s 0:01:10 -
+Rule	sol87	1987	only	-	Dec	24	11:59:20s 0:00:40 -
+Rule	sol87	1987	only	-	Dec	25	11:59:50s 0:00:10 -
+Rule	sol87	1987	only	-	Dec	26	12:00:20s -0:00:20 -
+Rule	sol87	1987	only	-	Dec	27	12:00:45s -0:00:45 -
+Rule	sol87	1987	only	-	Dec	28	12:01:15s -0:01:15 -
+Rule	sol87	1987	only	-	Dec	29	12:01:45s -0:01:45 -
+Rule	sol87	1987	only	-	Dec	30	12:02:15s -0:02:15 -
+Rule	sol87	1987	only	-	Dec	31	12:02:45s -0:02:45 -
+
+# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
+# Before and after 1987, we'll operate on local mean solar time.
+
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
+Zone	Asia/Riyadh87	3:07:04	-		zzz	1987
+			3:07:04	sol87		zzz	1988
+			3:07:04	-		zzz
+# For backward compatibility...
+Link	Asia/Riyadh87	Mideast/Riyadh87
diff --git a/tools/zoneinfo/tzdata2008h/solar88 b/tools/zoneinfo/tzdata2008h/solar88
new file mode 100644
index 0000000..b4cfe8e
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/solar88
@@ -0,0 +1,388 @@
+# @(#)solar88	8.1
+
+# Apparent noon times below are for Riyadh; they're a bit off for other places.
+# Times were computed using formulas in the U.S. Naval Observatory's
+# Almanac for Computers 1988; the formulas "will give EqT to an accuracy of
+# [plus or minus two] seconds during the current year."
+#
+# Rounding to the nearest five seconds results in fewer than
+# 256 different "time types"--a limit that's faced because time types are
+# stored on disk as unsigned chars.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	sol88	1988	only	-	Jan	1	12:03:15s -0:03:15 -
+Rule	sol88	1988	only	-	Jan	2	12:03:40s -0:03:40 -
+Rule	sol88	1988	only	-	Jan	3	12:04:10s -0:04:10 -
+Rule	sol88	1988	only	-	Jan	4	12:04:40s -0:04:40 -
+Rule	sol88	1988	only	-	Jan	5	12:05:05s -0:05:05 -
+Rule	sol88	1988	only	-	Jan	6	12:05:30s -0:05:30 -
+Rule	sol88	1988	only	-	Jan	7	12:06:00s -0:06:00 -
+Rule	sol88	1988	only	-	Jan	8	12:06:25s -0:06:25 -
+Rule	sol88	1988	only	-	Jan	9	12:06:50s -0:06:50 -
+Rule	sol88	1988	only	-	Jan	10	12:07:15s -0:07:15 -
+Rule	sol88	1988	only	-	Jan	11	12:07:40s -0:07:40 -
+Rule	sol88	1988	only	-	Jan	12	12:08:05s -0:08:05 -
+Rule	sol88	1988	only	-	Jan	13	12:08:25s -0:08:25 -
+Rule	sol88	1988	only	-	Jan	14	12:08:50s -0:08:50 -
+Rule	sol88	1988	only	-	Jan	15	12:09:10s -0:09:10 -
+Rule	sol88	1988	only	-	Jan	16	12:09:30s -0:09:30 -
+Rule	sol88	1988	only	-	Jan	17	12:09:50s -0:09:50 -
+Rule	sol88	1988	only	-	Jan	18	12:10:10s -0:10:10 -
+Rule	sol88	1988	only	-	Jan	19	12:10:30s -0:10:30 -
+Rule	sol88	1988	only	-	Jan	20	12:10:50s -0:10:50 -
+Rule	sol88	1988	only	-	Jan	21	12:11:05s -0:11:05 -
+Rule	sol88	1988	only	-	Jan	22	12:11:25s -0:11:25 -
+Rule	sol88	1988	only	-	Jan	23	12:11:40s -0:11:40 -
+Rule	sol88	1988	only	-	Jan	24	12:11:55s -0:11:55 -
+Rule	sol88	1988	only	-	Jan	25	12:12:10s -0:12:10 -
+Rule	sol88	1988	only	-	Jan	26	12:12:25s -0:12:25 -
+Rule	sol88	1988	only	-	Jan	27	12:12:40s -0:12:40 -
+Rule	sol88	1988	only	-	Jan	28	12:12:50s -0:12:50 -
+Rule	sol88	1988	only	-	Jan	29	12:13:00s -0:13:00 -
+Rule	sol88	1988	only	-	Jan	30	12:13:10s -0:13:10 -
+Rule	sol88	1988	only	-	Jan	31	12:13:20s -0:13:20 -
+Rule	sol88	1988	only	-	Feb	1	12:13:30s -0:13:30 -
+Rule	sol88	1988	only	-	Feb	2	12:13:40s -0:13:40 -
+Rule	sol88	1988	only	-	Feb	3	12:13:45s -0:13:45 -
+Rule	sol88	1988	only	-	Feb	4	12:13:55s -0:13:55 -
+Rule	sol88	1988	only	-	Feb	5	12:14:00s -0:14:00 -
+Rule	sol88	1988	only	-	Feb	6	12:14:05s -0:14:05 -
+Rule	sol88	1988	only	-	Feb	7	12:14:10s -0:14:10 -
+Rule	sol88	1988	only	-	Feb	8	12:14:10s -0:14:10 -
+Rule	sol88	1988	only	-	Feb	9	12:14:15s -0:14:15 -
+Rule	sol88	1988	only	-	Feb	10	12:14:15s -0:14:15 -
+Rule	sol88	1988	only	-	Feb	11	12:14:15s -0:14:15 -
+Rule	sol88	1988	only	-	Feb	12	12:14:15s -0:14:15 -
+Rule	sol88	1988	only	-	Feb	13	12:14:15s -0:14:15 -
+Rule	sol88	1988	only	-	Feb	14	12:14:15s -0:14:15 -
+Rule	sol88	1988	only	-	Feb	15	12:14:10s -0:14:10 -
+Rule	sol88	1988	only	-	Feb	16	12:14:10s -0:14:10 -
+Rule	sol88	1988	only	-	Feb	17	12:14:05s -0:14:05 -
+Rule	sol88	1988	only	-	Feb	18	12:14:00s -0:14:00 -
+Rule	sol88	1988	only	-	Feb	19	12:13:55s -0:13:55 -
+Rule	sol88	1988	only	-	Feb	20	12:13:50s -0:13:50 -
+Rule	sol88	1988	only	-	Feb	21	12:13:45s -0:13:45 -
+Rule	sol88	1988	only	-	Feb	22	12:13:40s -0:13:40 -
+Rule	sol88	1988	only	-	Feb	23	12:13:30s -0:13:30 -
+Rule	sol88	1988	only	-	Feb	24	12:13:20s -0:13:20 -
+Rule	sol88	1988	only	-	Feb	25	12:13:15s -0:13:15 -
+Rule	sol88	1988	only	-	Feb	26	12:13:05s -0:13:05 -
+Rule	sol88	1988	only	-	Feb	27	12:12:55s -0:12:55 -
+Rule	sol88	1988	only	-	Feb	28	12:12:45s -0:12:45 -
+Rule	sol88	1988	only	-	Feb	29	12:12:30s -0:12:30 -
+Rule	sol88	1988	only	-	Mar	1	12:12:20s -0:12:20 -
+Rule	sol88	1988	only	-	Mar	2	12:12:10s -0:12:10 -
+Rule	sol88	1988	only	-	Mar	3	12:11:55s -0:11:55 -
+Rule	sol88	1988	only	-	Mar	4	12:11:45s -0:11:45 -
+Rule	sol88	1988	only	-	Mar	5	12:11:30s -0:11:30 -
+Rule	sol88	1988	only	-	Mar	6	12:11:15s -0:11:15 -
+Rule	sol88	1988	only	-	Mar	7	12:11:00s -0:11:00 -
+Rule	sol88	1988	only	-	Mar	8	12:10:45s -0:10:45 -
+Rule	sol88	1988	only	-	Mar	9	12:10:30s -0:10:30 -
+Rule	sol88	1988	only	-	Mar	10	12:10:15s -0:10:15 -
+Rule	sol88	1988	only	-	Mar	11	12:10:00s -0:10:00 -
+Rule	sol88	1988	only	-	Mar	12	12:09:45s -0:09:45 -
+Rule	sol88	1988	only	-	Mar	13	12:09:30s -0:09:30 -
+Rule	sol88	1988	only	-	Mar	14	12:09:10s -0:09:10 -
+Rule	sol88	1988	only	-	Mar	15	12:08:55s -0:08:55 -
+Rule	sol88	1988	only	-	Mar	16	12:08:40s -0:08:40 -
+Rule	sol88	1988	only	-	Mar	17	12:08:20s -0:08:20 -
+Rule	sol88	1988	only	-	Mar	18	12:08:05s -0:08:05 -
+Rule	sol88	1988	only	-	Mar	19	12:07:45s -0:07:45 -
+Rule	sol88	1988	only	-	Mar	20	12:07:30s -0:07:30 -
+Rule	sol88	1988	only	-	Mar	21	12:07:10s -0:07:10 -
+Rule	sol88	1988	only	-	Mar	22	12:06:50s -0:06:50 -
+Rule	sol88	1988	only	-	Mar	23	12:06:35s -0:06:35 -
+Rule	sol88	1988	only	-	Mar	24	12:06:15s -0:06:15 -
+Rule	sol88	1988	only	-	Mar	25	12:06:00s -0:06:00 -
+Rule	sol88	1988	only	-	Mar	26	12:05:40s -0:05:40 -
+Rule	sol88	1988	only	-	Mar	27	12:05:20s -0:05:20 -
+Rule	sol88	1988	only	-	Mar	28	12:05:05s -0:05:05 -
+Rule	sol88	1988	only	-	Mar	29	12:04:45s -0:04:45 -
+Rule	sol88	1988	only	-	Mar	30	12:04:25s -0:04:25 -
+Rule	sol88	1988	only	-	Mar	31	12:04:10s -0:04:10 -
+Rule	sol88	1988	only	-	Apr	1	12:03:50s -0:03:50 -
+Rule	sol88	1988	only	-	Apr	2	12:03:35s -0:03:35 -
+Rule	sol88	1988	only	-	Apr	3	12:03:15s -0:03:15 -
+Rule	sol88	1988	only	-	Apr	4	12:03:00s -0:03:00 -
+Rule	sol88	1988	only	-	Apr	5	12:02:40s -0:02:40 -
+Rule	sol88	1988	only	-	Apr	6	12:02:25s -0:02:25 -
+Rule	sol88	1988	only	-	Apr	7	12:02:05s -0:02:05 -
+Rule	sol88	1988	only	-	Apr	8	12:01:50s -0:01:50 -
+Rule	sol88	1988	only	-	Apr	9	12:01:35s -0:01:35 -
+Rule	sol88	1988	only	-	Apr	10	12:01:15s -0:01:15 -
+Rule	sol88	1988	only	-	Apr	11	12:01:00s -0:01:00 -
+Rule	sol88	1988	only	-	Apr	12	12:00:45s -0:00:45 -
+Rule	sol88	1988	only	-	Apr	13	12:00:30s -0:00:30 -
+Rule	sol88	1988	only	-	Apr	14	12:00:15s -0:00:15 -
+Rule	sol88	1988	only	-	Apr	15	12:00:00s 0:00:00 -
+Rule	sol88	1988	only	-	Apr	16	11:59:45s 0:00:15 -
+Rule	sol88	1988	only	-	Apr	17	11:59:30s 0:00:30 -
+Rule	sol88	1988	only	-	Apr	18	11:59:20s 0:00:40 -
+Rule	sol88	1988	only	-	Apr	19	11:59:05s 0:00:55 -
+Rule	sol88	1988	only	-	Apr	20	11:58:55s 0:01:05 -
+Rule	sol88	1988	only	-	Apr	21	11:58:40s 0:01:20 -
+Rule	sol88	1988	only	-	Apr	22	11:58:30s 0:01:30 -
+Rule	sol88	1988	only	-	Apr	23	11:58:15s 0:01:45 -
+Rule	sol88	1988	only	-	Apr	24	11:58:05s 0:01:55 -
+Rule	sol88	1988	only	-	Apr	25	11:57:55s 0:02:05 -
+Rule	sol88	1988	only	-	Apr	26	11:57:45s 0:02:15 -
+Rule	sol88	1988	only	-	Apr	27	11:57:35s 0:02:25 -
+Rule	sol88	1988	only	-	Apr	28	11:57:30s 0:02:30 -
+Rule	sol88	1988	only	-	Apr	29	11:57:20s 0:02:40 -
+Rule	sol88	1988	only	-	Apr	30	11:57:10s 0:02:50 -
+Rule	sol88	1988	only	-	May	1	11:57:05s 0:02:55 -
+Rule	sol88	1988	only	-	May	2	11:56:55s 0:03:05 -
+Rule	sol88	1988	only	-	May	3	11:56:50s 0:03:10 -
+Rule	sol88	1988	only	-	May	4	11:56:45s 0:03:15 -
+Rule	sol88	1988	only	-	May	5	11:56:40s 0:03:20 -
+Rule	sol88	1988	only	-	May	6	11:56:35s 0:03:25 -
+Rule	sol88	1988	only	-	May	7	11:56:30s 0:03:30 -
+Rule	sol88	1988	only	-	May	8	11:56:25s 0:03:35 -
+Rule	sol88	1988	only	-	May	9	11:56:25s 0:03:35 -
+Rule	sol88	1988	only	-	May	10	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	11	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	12	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	13	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	14	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	15	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	16	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	17	11:56:20s 0:03:40 -
+Rule	sol88	1988	only	-	May	18	11:56:25s 0:03:35 -
+Rule	sol88	1988	only	-	May	19	11:56:25s 0:03:35 -
+Rule	sol88	1988	only	-	May	20	11:56:30s 0:03:30 -
+Rule	sol88	1988	only	-	May	21	11:56:35s 0:03:25 -
+Rule	sol88	1988	only	-	May	22	11:56:40s 0:03:20 -
+Rule	sol88	1988	only	-	May	23	11:56:45s 0:03:15 -
+Rule	sol88	1988	only	-	May	24	11:56:50s 0:03:10 -
+Rule	sol88	1988	only	-	May	25	11:56:55s 0:03:05 -
+Rule	sol88	1988	only	-	May	26	11:57:00s 0:03:00 -
+Rule	sol88	1988	only	-	May	27	11:57:05s 0:02:55 -
+Rule	sol88	1988	only	-	May	28	11:57:15s 0:02:45 -
+Rule	sol88	1988	only	-	May	29	11:57:20s 0:02:40 -
+Rule	sol88	1988	only	-	May	30	11:57:30s 0:02:30 -
+Rule	sol88	1988	only	-	May	31	11:57:40s 0:02:20 -
+Rule	sol88	1988	only	-	Jun	1	11:57:50s 0:02:10 -
+Rule	sol88	1988	only	-	Jun	2	11:57:55s 0:02:05 -
+Rule	sol88	1988	only	-	Jun	3	11:58:05s 0:01:55 -
+Rule	sol88	1988	only	-	Jun	4	11:58:15s 0:01:45 -
+Rule	sol88	1988	only	-	Jun	5	11:58:30s 0:01:30 -
+Rule	sol88	1988	only	-	Jun	6	11:58:40s 0:01:20 -
+Rule	sol88	1988	only	-	Jun	7	11:58:50s 0:01:10 -
+Rule	sol88	1988	only	-	Jun	8	11:59:00s 0:01:00 -
+Rule	sol88	1988	only	-	Jun	9	11:59:15s 0:00:45 -
+Rule	sol88	1988	only	-	Jun	10	11:59:25s 0:00:35 -
+Rule	sol88	1988	only	-	Jun	11	11:59:35s 0:00:25 -
+Rule	sol88	1988	only	-	Jun	12	11:59:50s 0:00:10 -
+Rule	sol88	1988	only	-	Jun	13	12:00:00s 0:00:00 -
+Rule	sol88	1988	only	-	Jun	14	12:00:15s -0:00:15 -
+Rule	sol88	1988	only	-	Jun	15	12:00:25s -0:00:25 -
+Rule	sol88	1988	only	-	Jun	16	12:00:40s -0:00:40 -
+Rule	sol88	1988	only	-	Jun	17	12:00:55s -0:00:55 -
+Rule	sol88	1988	only	-	Jun	18	12:01:05s -0:01:05 -
+Rule	sol88	1988	only	-	Jun	19	12:01:20s -0:01:20 -
+Rule	sol88	1988	only	-	Jun	20	12:01:30s -0:01:30 -
+Rule	sol88	1988	only	-	Jun	21	12:01:45s -0:01:45 -
+Rule	sol88	1988	only	-	Jun	22	12:02:00s -0:02:00 -
+Rule	sol88	1988	only	-	Jun	23	12:02:10s -0:02:10 -
+Rule	sol88	1988	only	-	Jun	24	12:02:25s -0:02:25 -
+Rule	sol88	1988	only	-	Jun	25	12:02:35s -0:02:35 -
+Rule	sol88	1988	only	-	Jun	26	12:02:50s -0:02:50 -
+Rule	sol88	1988	only	-	Jun	27	12:03:00s -0:03:00 -
+Rule	sol88	1988	only	-	Jun	28	12:03:15s -0:03:15 -
+Rule	sol88	1988	only	-	Jun	29	12:03:25s -0:03:25 -
+Rule	sol88	1988	only	-	Jun	30	12:03:40s -0:03:40 -
+Rule	sol88	1988	only	-	Jul	1	12:03:50s -0:03:50 -
+Rule	sol88	1988	only	-	Jul	2	12:04:00s -0:04:00 -
+Rule	sol88	1988	only	-	Jul	3	12:04:10s -0:04:10 -
+Rule	sol88	1988	only	-	Jul	4	12:04:25s -0:04:25 -
+Rule	sol88	1988	only	-	Jul	5	12:04:35s -0:04:35 -
+Rule	sol88	1988	only	-	Jul	6	12:04:45s -0:04:45 -
+Rule	sol88	1988	only	-	Jul	7	12:04:55s -0:04:55 -
+Rule	sol88	1988	only	-	Jul	8	12:05:05s -0:05:05 -
+Rule	sol88	1988	only	-	Jul	9	12:05:10s -0:05:10 -
+Rule	sol88	1988	only	-	Jul	10	12:05:20s -0:05:20 -
+Rule	sol88	1988	only	-	Jul	11	12:05:30s -0:05:30 -
+Rule	sol88	1988	only	-	Jul	12	12:05:35s -0:05:35 -
+Rule	sol88	1988	only	-	Jul	13	12:05:45s -0:05:45 -
+Rule	sol88	1988	only	-	Jul	14	12:05:50s -0:05:50 -
+Rule	sol88	1988	only	-	Jul	15	12:05:55s -0:05:55 -
+Rule	sol88	1988	only	-	Jul	16	12:06:00s -0:06:00 -
+Rule	sol88	1988	only	-	Jul	17	12:06:05s -0:06:05 -
+Rule	sol88	1988	only	-	Jul	18	12:06:10s -0:06:10 -
+Rule	sol88	1988	only	-	Jul	19	12:06:15s -0:06:15 -
+Rule	sol88	1988	only	-	Jul	20	12:06:20s -0:06:20 -
+Rule	sol88	1988	only	-	Jul	21	12:06:25s -0:06:25 -
+Rule	sol88	1988	only	-	Jul	22	12:06:25s -0:06:25 -
+Rule	sol88	1988	only	-	Jul	23	12:06:25s -0:06:25 -
+Rule	sol88	1988	only	-	Jul	24	12:06:30s -0:06:30 -
+Rule	sol88	1988	only	-	Jul	25	12:06:30s -0:06:30 -
+Rule	sol88	1988	only	-	Jul	26	12:06:30s -0:06:30 -
+Rule	sol88	1988	only	-	Jul	27	12:06:30s -0:06:30 -
+Rule	sol88	1988	only	-	Jul	28	12:06:30s -0:06:30 -
+Rule	sol88	1988	only	-	Jul	29	12:06:25s -0:06:25 -
+Rule	sol88	1988	only	-	Jul	30	12:06:25s -0:06:25 -
+Rule	sol88	1988	only	-	Jul	31	12:06:20s -0:06:20 -
+Rule	sol88	1988	only	-	Aug	1	12:06:15s -0:06:15 -
+Rule	sol88	1988	only	-	Aug	2	12:06:15s -0:06:15 -
+Rule	sol88	1988	only	-	Aug	3	12:06:10s -0:06:10 -
+Rule	sol88	1988	only	-	Aug	4	12:06:05s -0:06:05 -
+Rule	sol88	1988	only	-	Aug	5	12:05:55s -0:05:55 -
+Rule	sol88	1988	only	-	Aug	6	12:05:50s -0:05:50 -
+Rule	sol88	1988	only	-	Aug	7	12:05:45s -0:05:45 -
+Rule	sol88	1988	only	-	Aug	8	12:05:35s -0:05:35 -
+Rule	sol88	1988	only	-	Aug	9	12:05:25s -0:05:25 -
+Rule	sol88	1988	only	-	Aug	10	12:05:20s -0:05:20 -
+Rule	sol88	1988	only	-	Aug	11	12:05:10s -0:05:10 -
+Rule	sol88	1988	only	-	Aug	12	12:05:00s -0:05:00 -
+Rule	sol88	1988	only	-	Aug	13	12:04:50s -0:04:50 -
+Rule	sol88	1988	only	-	Aug	14	12:04:35s -0:04:35 -
+Rule	sol88	1988	only	-	Aug	15	12:04:25s -0:04:25 -
+Rule	sol88	1988	only	-	Aug	16	12:04:15s -0:04:15 -
+Rule	sol88	1988	only	-	Aug	17	12:04:00s -0:04:00 -
+Rule	sol88	1988	only	-	Aug	18	12:03:50s -0:03:50 -
+Rule	sol88	1988	only	-	Aug	19	12:03:35s -0:03:35 -
+Rule	sol88	1988	only	-	Aug	20	12:03:20s -0:03:20 -
+Rule	sol88	1988	only	-	Aug	21	12:03:05s -0:03:05 -
+Rule	sol88	1988	only	-	Aug	22	12:02:50s -0:02:50 -
+Rule	sol88	1988	only	-	Aug	23	12:02:35s -0:02:35 -
+Rule	sol88	1988	only	-	Aug	24	12:02:20s -0:02:20 -
+Rule	sol88	1988	only	-	Aug	25	12:02:00s -0:02:00 -
+Rule	sol88	1988	only	-	Aug	26	12:01:45s -0:01:45 -
+Rule	sol88	1988	only	-	Aug	27	12:01:30s -0:01:30 -
+Rule	sol88	1988	only	-	Aug	28	12:01:10s -0:01:10 -
+Rule	sol88	1988	only	-	Aug	29	12:00:50s -0:00:50 -
+Rule	sol88	1988	only	-	Aug	30	12:00:35s -0:00:35 -
+Rule	sol88	1988	only	-	Aug	31	12:00:15s -0:00:15 -
+Rule	sol88	1988	only	-	Sep	1	11:59:55s 0:00:05 -
+Rule	sol88	1988	only	-	Sep	2	11:59:35s 0:00:25 -
+Rule	sol88	1988	only	-	Sep	3	11:59:20s 0:00:40 -
+Rule	sol88	1988	only	-	Sep	4	11:59:00s 0:01:00 -
+Rule	sol88	1988	only	-	Sep	5	11:58:40s 0:01:20 -
+Rule	sol88	1988	only	-	Sep	6	11:58:20s 0:01:40 -
+Rule	sol88	1988	only	-	Sep	7	11:58:00s 0:02:00 -
+Rule	sol88	1988	only	-	Sep	8	11:57:35s 0:02:25 -
+Rule	sol88	1988	only	-	Sep	9	11:57:15s 0:02:45 -
+Rule	sol88	1988	only	-	Sep	10	11:56:55s 0:03:05 -
+Rule	sol88	1988	only	-	Sep	11	11:56:35s 0:03:25 -
+Rule	sol88	1988	only	-	Sep	12	11:56:15s 0:03:45 -
+Rule	sol88	1988	only	-	Sep	13	11:55:50s 0:04:10 -
+Rule	sol88	1988	only	-	Sep	14	11:55:30s 0:04:30 -
+Rule	sol88	1988	only	-	Sep	15	11:55:10s 0:04:50 -
+Rule	sol88	1988	only	-	Sep	16	11:54:50s 0:05:10 -
+Rule	sol88	1988	only	-	Sep	17	11:54:25s 0:05:35 -
+Rule	sol88	1988	only	-	Sep	18	11:54:05s 0:05:55 -
+Rule	sol88	1988	only	-	Sep	19	11:53:45s 0:06:15 -
+Rule	sol88	1988	only	-	Sep	20	11:53:25s 0:06:35 -
+Rule	sol88	1988	only	-	Sep	21	11:53:00s 0:07:00 -
+Rule	sol88	1988	only	-	Sep	22	11:52:40s 0:07:20 -
+Rule	sol88	1988	only	-	Sep	23	11:52:20s 0:07:40 -
+Rule	sol88	1988	only	-	Sep	24	11:52:00s 0:08:00 -
+Rule	sol88	1988	only	-	Sep	25	11:51:40s 0:08:20 -
+Rule	sol88	1988	only	-	Sep	26	11:51:15s 0:08:45 -
+Rule	sol88	1988	only	-	Sep	27	11:50:55s 0:09:05 -
+Rule	sol88	1988	only	-	Sep	28	11:50:35s 0:09:25 -
+Rule	sol88	1988	only	-	Sep	29	11:50:15s 0:09:45 -
+Rule	sol88	1988	only	-	Sep	30	11:49:55s 0:10:05 -
+Rule	sol88	1988	only	-	Oct	1	11:49:35s 0:10:25 -
+Rule	sol88	1988	only	-	Oct	2	11:49:20s 0:10:40 -
+Rule	sol88	1988	only	-	Oct	3	11:49:00s 0:11:00 -
+Rule	sol88	1988	only	-	Oct	4	11:48:40s 0:11:20 -
+Rule	sol88	1988	only	-	Oct	5	11:48:25s 0:11:35 -
+Rule	sol88	1988	only	-	Oct	6	11:48:05s 0:11:55 -
+Rule	sol88	1988	only	-	Oct	7	11:47:50s 0:12:10 -
+Rule	sol88	1988	only	-	Oct	8	11:47:30s 0:12:30 -
+Rule	sol88	1988	only	-	Oct	9	11:47:15s 0:12:45 -
+Rule	sol88	1988	only	-	Oct	10	11:47:00s 0:13:00 -
+Rule	sol88	1988	only	-	Oct	11	11:46:45s 0:13:15 -
+Rule	sol88	1988	only	-	Oct	12	11:46:30s 0:13:30 -
+Rule	sol88	1988	only	-	Oct	13	11:46:15s 0:13:45 -
+Rule	sol88	1988	only	-	Oct	14	11:46:00s 0:14:00 -
+Rule	sol88	1988	only	-	Oct	15	11:45:45s 0:14:15 -
+Rule	sol88	1988	only	-	Oct	16	11:45:35s 0:14:25 -
+Rule	sol88	1988	only	-	Oct	17	11:45:20s 0:14:40 -
+Rule	sol88	1988	only	-	Oct	18	11:45:10s 0:14:50 -
+Rule	sol88	1988	only	-	Oct	19	11:45:00s 0:15:00 -
+Rule	sol88	1988	only	-	Oct	20	11:44:45s 0:15:15 -
+Rule	sol88	1988	only	-	Oct	21	11:44:40s 0:15:20 -
+Rule	sol88	1988	only	-	Oct	22	11:44:30s 0:15:30 -
+Rule	sol88	1988	only	-	Oct	23	11:44:20s 0:15:40 -
+Rule	sol88	1988	only	-	Oct	24	11:44:10s 0:15:50 -
+Rule	sol88	1988	only	-	Oct	25	11:44:05s 0:15:55 -
+Rule	sol88	1988	only	-	Oct	26	11:44:00s 0:16:00 -
+Rule	sol88	1988	only	-	Oct	27	11:43:55s 0:16:05 -
+Rule	sol88	1988	only	-	Oct	28	11:43:50s 0:16:10 -
+Rule	sol88	1988	only	-	Oct	29	11:43:45s 0:16:15 -
+Rule	sol88	1988	only	-	Oct	30	11:43:40s 0:16:20 -
+Rule	sol88	1988	only	-	Oct	31	11:43:40s 0:16:20 -
+Rule	sol88	1988	only	-	Nov	1	11:43:35s 0:16:25 -
+Rule	sol88	1988	only	-	Nov	2	11:43:35s 0:16:25 -
+Rule	sol88	1988	only	-	Nov	3	11:43:35s 0:16:25 -
+Rule	sol88	1988	only	-	Nov	4	11:43:35s 0:16:25 -
+Rule	sol88	1988	only	-	Nov	5	11:43:40s 0:16:20 -
+Rule	sol88	1988	only	-	Nov	6	11:43:40s 0:16:20 -
+Rule	sol88	1988	only	-	Nov	7	11:43:45s 0:16:15 -
+Rule	sol88	1988	only	-	Nov	8	11:43:45s 0:16:15 -
+Rule	sol88	1988	only	-	Nov	9	11:43:50s 0:16:10 -
+Rule	sol88	1988	only	-	Nov	10	11:44:00s 0:16:00 -
+Rule	sol88	1988	only	-	Nov	11	11:44:05s 0:15:55 -
+Rule	sol88	1988	only	-	Nov	12	11:44:10s 0:15:50 -
+Rule	sol88	1988	only	-	Nov	13	11:44:20s 0:15:40 -
+Rule	sol88	1988	only	-	Nov	14	11:44:30s 0:15:30 -
+Rule	sol88	1988	only	-	Nov	15	11:44:40s 0:15:20 -
+Rule	sol88	1988	only	-	Nov	16	11:44:50s 0:15:10 -
+Rule	sol88	1988	only	-	Nov	17	11:45:00s 0:15:00 -
+Rule	sol88	1988	only	-	Nov	18	11:45:15s 0:14:45 -
+Rule	sol88	1988	only	-	Nov	19	11:45:25s 0:14:35 -
+Rule	sol88	1988	only	-	Nov	20	11:45:40s 0:14:20 -
+Rule	sol88	1988	only	-	Nov	21	11:45:55s 0:14:05 -
+Rule	sol88	1988	only	-	Nov	22	11:46:10s 0:13:50 -
+Rule	sol88	1988	only	-	Nov	23	11:46:30s 0:13:30 -
+Rule	sol88	1988	only	-	Nov	24	11:46:45s 0:13:15 -
+Rule	sol88	1988	only	-	Nov	25	11:47:05s 0:12:55 -
+Rule	sol88	1988	only	-	Nov	26	11:47:20s 0:12:40 -
+Rule	sol88	1988	only	-	Nov	27	11:47:40s 0:12:20 -
+Rule	sol88	1988	only	-	Nov	28	11:48:00s 0:12:00 -
+Rule	sol88	1988	only	-	Nov	29	11:48:25s 0:11:35 -
+Rule	sol88	1988	only	-	Nov	30	11:48:45s 0:11:15 -
+Rule	sol88	1988	only	-	Dec	1	11:49:05s 0:10:55 -
+Rule	sol88	1988	only	-	Dec	2	11:49:30s 0:10:30 -
+Rule	sol88	1988	only	-	Dec	3	11:49:55s 0:10:05 -
+Rule	sol88	1988	only	-	Dec	4	11:50:15s 0:09:45 -
+Rule	sol88	1988	only	-	Dec	5	11:50:40s 0:09:20 -
+Rule	sol88	1988	only	-	Dec	6	11:51:05s 0:08:55 -
+Rule	sol88	1988	only	-	Dec	7	11:51:35s 0:08:25 -
+Rule	sol88	1988	only	-	Dec	8	11:52:00s 0:08:00 -
+Rule	sol88	1988	only	-	Dec	9	11:52:25s 0:07:35 -
+Rule	sol88	1988	only	-	Dec	10	11:52:55s 0:07:05 -
+Rule	sol88	1988	only	-	Dec	11	11:53:20s 0:06:40 -
+Rule	sol88	1988	only	-	Dec	12	11:53:50s 0:06:10 -
+Rule	sol88	1988	only	-	Dec	13	11:54:15s 0:05:45 -
+Rule	sol88	1988	only	-	Dec	14	11:54:45s 0:05:15 -
+Rule	sol88	1988	only	-	Dec	15	11:55:15s 0:04:45 -
+Rule	sol88	1988	only	-	Dec	16	11:55:45s 0:04:15 -
+Rule	sol88	1988	only	-	Dec	17	11:56:15s 0:03:45 -
+Rule	sol88	1988	only	-	Dec	18	11:56:40s 0:03:20 -
+Rule	sol88	1988	only	-	Dec	19	11:57:10s 0:02:50 -
+Rule	sol88	1988	only	-	Dec	20	11:57:40s 0:02:20 -
+Rule	sol88	1988	only	-	Dec	21	11:58:10s 0:01:50 -
+Rule	sol88	1988	only	-	Dec	22	11:58:40s 0:01:20 -
+Rule	sol88	1988	only	-	Dec	23	11:59:10s 0:00:50 -
+Rule	sol88	1988	only	-	Dec	24	11:59:40s 0:00:20 -
+Rule	sol88	1988	only	-	Dec	25	12:00:10s -0:00:10 -
+Rule	sol88	1988	only	-	Dec	26	12:00:40s -0:00:40 -
+Rule	sol88	1988	only	-	Dec	27	12:01:10s -0:01:10 -
+Rule	sol88	1988	only	-	Dec	28	12:01:40s -0:01:40 -
+Rule	sol88	1988	only	-	Dec	29	12:02:10s -0:02:10 -
+Rule	sol88	1988	only	-	Dec	30	12:02:35s -0:02:35 -
+Rule	sol88	1988	only	-	Dec	31	12:03:05s -0:03:05 -
+
+# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
+# Before and after 1988, we'll operate on local mean solar time.
+
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
+Zone	Asia/Riyadh88	3:07:04	-		zzz	1988
+			3:07:04	sol88		zzz	1989
+			3:07:04	-		zzz
+# For backward compatibility...
+Link	Asia/Riyadh88	Mideast/Riyadh88
diff --git a/tools/zoneinfo/tzdata2008h/solar89 b/tools/zoneinfo/tzdata2008h/solar89
new file mode 100644
index 0000000..8c48531
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/solar89
@@ -0,0 +1,393 @@
+# @(#)solar89	8.1
+
+# Apparent noon times below are for Riyadh; they're a bit off for other places.
+# Times were computed using a formula provided by the U. S. Naval Observatory:
+#	eqt = -105.8 * sin(l) + 596.2 * sin(2 * l) + 4.4 * sin(3 * l)
+#		-12.7 * sin(4 * l) - 429.0 * cos(l) - 2.1 * cos (2 * l)
+#		+ 19.3 * cos(3 * l);
+# where l is the "mean longitude of the Sun" given by
+#	l = 279.642 degrees + 0.985647 * d
+# and d is the interval in days from January 0, 0 hours Universal Time
+# (equaling the day of the year plus the fraction of a day from zero hours).
+# The accuracy of the formula is plus or minus three seconds.
+#
+# Rounding to the nearest five seconds results in fewer than
+# 256 different "time types"--a limit that's faced because time types are
+# stored on disk as unsigned chars.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	sol89	1989	only	-	Jan	1	12:03:35s -0:03:35 -
+Rule	sol89	1989	only	-	Jan	2	12:04:05s -0:04:05 -
+Rule	sol89	1989	only	-	Jan	3	12:04:30s -0:04:30 -
+Rule	sol89	1989	only	-	Jan	4	12:05:00s -0:05:00 -
+Rule	sol89	1989	only	-	Jan	5	12:05:25s -0:05:25 -
+Rule	sol89	1989	only	-	Jan	6	12:05:50s -0:05:50 -
+Rule	sol89	1989	only	-	Jan	7	12:06:15s -0:06:15 -
+Rule	sol89	1989	only	-	Jan	8	12:06:45s -0:06:45 -
+Rule	sol89	1989	only	-	Jan	9	12:07:10s -0:07:10 -
+Rule	sol89	1989	only	-	Jan	10	12:07:35s -0:07:35 -
+Rule	sol89	1989	only	-	Jan	11	12:07:55s -0:07:55 -
+Rule	sol89	1989	only	-	Jan	12	12:08:20s -0:08:20 -
+Rule	sol89	1989	only	-	Jan	13	12:08:45s -0:08:45 -
+Rule	sol89	1989	only	-	Jan	14	12:09:05s -0:09:05 -
+Rule	sol89	1989	only	-	Jan	15	12:09:25s -0:09:25 -
+Rule	sol89	1989	only	-	Jan	16	12:09:45s -0:09:45 -
+Rule	sol89	1989	only	-	Jan	17	12:10:05s -0:10:05 -
+Rule	sol89	1989	only	-	Jan	18	12:10:25s -0:10:25 -
+Rule	sol89	1989	only	-	Jan	19	12:10:45s -0:10:45 -
+Rule	sol89	1989	only	-	Jan	20	12:11:05s -0:11:05 -
+Rule	sol89	1989	only	-	Jan	21	12:11:20s -0:11:20 -
+Rule	sol89	1989	only	-	Jan	22	12:11:35s -0:11:35 -
+Rule	sol89	1989	only	-	Jan	23	12:11:55s -0:11:55 -
+Rule	sol89	1989	only	-	Jan	24	12:12:10s -0:12:10 -
+Rule	sol89	1989	only	-	Jan	25	12:12:20s -0:12:20 -
+Rule	sol89	1989	only	-	Jan	26	12:12:35s -0:12:35 -
+Rule	sol89	1989	only	-	Jan	27	12:12:50s -0:12:50 -
+Rule	sol89	1989	only	-	Jan	28	12:13:00s -0:13:00 -
+Rule	sol89	1989	only	-	Jan	29	12:13:10s -0:13:10 -
+Rule	sol89	1989	only	-	Jan	30	12:13:20s -0:13:20 -
+Rule	sol89	1989	only	-	Jan	31	12:13:30s -0:13:30 -
+Rule	sol89	1989	only	-	Feb	1	12:13:40s -0:13:40 -
+Rule	sol89	1989	only	-	Feb	2	12:13:45s -0:13:45 -
+Rule	sol89	1989	only	-	Feb	3	12:13:55s -0:13:55 -
+Rule	sol89	1989	only	-	Feb	4	12:14:00s -0:14:00 -
+Rule	sol89	1989	only	-	Feb	5	12:14:05s -0:14:05 -
+Rule	sol89	1989	only	-	Feb	6	12:14:10s -0:14:10 -
+Rule	sol89	1989	only	-	Feb	7	12:14:10s -0:14:10 -
+Rule	sol89	1989	only	-	Feb	8	12:14:15s -0:14:15 -
+Rule	sol89	1989	only	-	Feb	9	12:14:15s -0:14:15 -
+Rule	sol89	1989	only	-	Feb	10	12:14:20s -0:14:20 -
+Rule	sol89	1989	only	-	Feb	11	12:14:20s -0:14:20 -
+Rule	sol89	1989	only	-	Feb	12	12:14:20s -0:14:20 -
+Rule	sol89	1989	only	-	Feb	13	12:14:15s -0:14:15 -
+Rule	sol89	1989	only	-	Feb	14	12:14:15s -0:14:15 -
+Rule	sol89	1989	only	-	Feb	15	12:14:10s -0:14:10 -
+Rule	sol89	1989	only	-	Feb	16	12:14:10s -0:14:10 -
+Rule	sol89	1989	only	-	Feb	17	12:14:05s -0:14:05 -
+Rule	sol89	1989	only	-	Feb	18	12:14:00s -0:14:00 -
+Rule	sol89	1989	only	-	Feb	19	12:13:55s -0:13:55 -
+Rule	sol89	1989	only	-	Feb	20	12:13:50s -0:13:50 -
+Rule	sol89	1989	only	-	Feb	21	12:13:40s -0:13:40 -
+Rule	sol89	1989	only	-	Feb	22	12:13:35s -0:13:35 -
+Rule	sol89	1989	only	-	Feb	23	12:13:25s -0:13:25 -
+Rule	sol89	1989	only	-	Feb	24	12:13:15s -0:13:15 -
+Rule	sol89	1989	only	-	Feb	25	12:13:05s -0:13:05 -
+Rule	sol89	1989	only	-	Feb	26	12:12:55s -0:12:55 -
+Rule	sol89	1989	only	-	Feb	27	12:12:45s -0:12:45 -
+Rule	sol89	1989	only	-	Feb	28	12:12:35s -0:12:35 -
+Rule	sol89	1989	only	-	Mar	1	12:12:25s -0:12:25 -
+Rule	sol89	1989	only	-	Mar	2	12:12:10s -0:12:10 -
+Rule	sol89	1989	only	-	Mar	3	12:12:00s -0:12:00 -
+Rule	sol89	1989	only	-	Mar	4	12:11:45s -0:11:45 -
+Rule	sol89	1989	only	-	Mar	5	12:11:35s -0:11:35 -
+Rule	sol89	1989	only	-	Mar	6	12:11:20s -0:11:20 -
+Rule	sol89	1989	only	-	Mar	7	12:11:05s -0:11:05 -
+Rule	sol89	1989	only	-	Mar	8	12:10:50s -0:10:50 -
+Rule	sol89	1989	only	-	Mar	9	12:10:35s -0:10:35 -
+Rule	sol89	1989	only	-	Mar	10	12:10:20s -0:10:20 -
+Rule	sol89	1989	only	-	Mar	11	12:10:05s -0:10:05 -
+Rule	sol89	1989	only	-	Mar	12	12:09:50s -0:09:50 -
+Rule	sol89	1989	only	-	Mar	13	12:09:30s -0:09:30 -
+Rule	sol89	1989	only	-	Mar	14	12:09:15s -0:09:15 -
+Rule	sol89	1989	only	-	Mar	15	12:09:00s -0:09:00 -
+Rule	sol89	1989	only	-	Mar	16	12:08:40s -0:08:40 -
+Rule	sol89	1989	only	-	Mar	17	12:08:25s -0:08:25 -
+Rule	sol89	1989	only	-	Mar	18	12:08:05s -0:08:05 -
+Rule	sol89	1989	only	-	Mar	19	12:07:50s -0:07:50 -
+Rule	sol89	1989	only	-	Mar	20	12:07:30s -0:07:30 -
+Rule	sol89	1989	only	-	Mar	21	12:07:15s -0:07:15 -
+Rule	sol89	1989	only	-	Mar	22	12:06:55s -0:06:55 -
+Rule	sol89	1989	only	-	Mar	23	12:06:35s -0:06:35 -
+Rule	sol89	1989	only	-	Mar	24	12:06:20s -0:06:20 -
+Rule	sol89	1989	only	-	Mar	25	12:06:00s -0:06:00 -
+Rule	sol89	1989	only	-	Mar	26	12:05:40s -0:05:40 -
+Rule	sol89	1989	only	-	Mar	27	12:05:25s -0:05:25 -
+Rule	sol89	1989	only	-	Mar	28	12:05:05s -0:05:05 -
+Rule	sol89	1989	only	-	Mar	29	12:04:50s -0:04:50 -
+Rule	sol89	1989	only	-	Mar	30	12:04:30s -0:04:30 -
+Rule	sol89	1989	only	-	Mar	31	12:04:10s -0:04:10 -
+Rule	sol89	1989	only	-	Apr	1	12:03:55s -0:03:55 -
+Rule	sol89	1989	only	-	Apr	2	12:03:35s -0:03:35 -
+Rule	sol89	1989	only	-	Apr	3	12:03:20s -0:03:20 -
+Rule	sol89	1989	only	-	Apr	4	12:03:00s -0:03:00 -
+Rule	sol89	1989	only	-	Apr	5	12:02:45s -0:02:45 -
+Rule	sol89	1989	only	-	Apr	6	12:02:25s -0:02:25 -
+Rule	sol89	1989	only	-	Apr	7	12:02:10s -0:02:10 -
+Rule	sol89	1989	only	-	Apr	8	12:01:50s -0:01:50 -
+Rule	sol89	1989	only	-	Apr	9	12:01:35s -0:01:35 -
+Rule	sol89	1989	only	-	Apr	10	12:01:20s -0:01:20 -
+Rule	sol89	1989	only	-	Apr	11	12:01:05s -0:01:05 -
+Rule	sol89	1989	only	-	Apr	12	12:00:50s -0:00:50 -
+Rule	sol89	1989	only	-	Apr	13	12:00:35s -0:00:35 -
+Rule	sol89	1989	only	-	Apr	14	12:00:20s -0:00:20 -
+Rule	sol89	1989	only	-	Apr	15	12:00:05s -0:00:05 -
+Rule	sol89	1989	only	-	Apr	16	11:59:50s 0:00:10 -
+Rule	sol89	1989	only	-	Apr	17	11:59:35s 0:00:25 -
+Rule	sol89	1989	only	-	Apr	18	11:59:20s 0:00:40 -
+Rule	sol89	1989	only	-	Apr	19	11:59:10s 0:00:50 -
+Rule	sol89	1989	only	-	Apr	20	11:58:55s 0:01:05 -
+Rule	sol89	1989	only	-	Apr	21	11:58:45s 0:01:15 -
+Rule	sol89	1989	only	-	Apr	22	11:58:30s 0:01:30 -
+Rule	sol89	1989	only	-	Apr	23	11:58:20s 0:01:40 -
+Rule	sol89	1989	only	-	Apr	24	11:58:10s 0:01:50 -
+Rule	sol89	1989	only	-	Apr	25	11:58:00s 0:02:00 -
+Rule	sol89	1989	only	-	Apr	26	11:57:50s 0:02:10 -
+Rule	sol89	1989	only	-	Apr	27	11:57:40s 0:02:20 -
+Rule	sol89	1989	only	-	Apr	28	11:57:30s 0:02:30 -
+Rule	sol89	1989	only	-	Apr	29	11:57:20s 0:02:40 -
+Rule	sol89	1989	only	-	Apr	30	11:57:15s 0:02:45 -
+Rule	sol89	1989	only	-	May	1	11:57:05s 0:02:55 -
+Rule	sol89	1989	only	-	May	2	11:57:00s 0:03:00 -
+Rule	sol89	1989	only	-	May	3	11:56:50s 0:03:10 -
+Rule	sol89	1989	only	-	May	4	11:56:45s 0:03:15 -
+Rule	sol89	1989	only	-	May	5	11:56:40s 0:03:20 -
+Rule	sol89	1989	only	-	May	6	11:56:35s 0:03:25 -
+Rule	sol89	1989	only	-	May	7	11:56:30s 0:03:30 -
+Rule	sol89	1989	only	-	May	8	11:56:30s 0:03:30 -
+Rule	sol89	1989	only	-	May	9	11:56:25s 0:03:35 -
+Rule	sol89	1989	only	-	May	10	11:56:25s 0:03:35 -
+Rule	sol89	1989	only	-	May	11	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	May	12	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	May	13	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	May	14	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	May	15	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	May	16	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	May	17	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	May	18	11:56:25s 0:03:35 -
+Rule	sol89	1989	only	-	May	19	11:56:25s 0:03:35 -
+Rule	sol89	1989	only	-	May	20	11:56:30s 0:03:30 -
+Rule	sol89	1989	only	-	May	21	11:56:35s 0:03:25 -
+Rule	sol89	1989	only	-	May	22	11:56:35s 0:03:25 -
+Rule	sol89	1989	only	-	May	23	11:56:40s 0:03:20 -
+Rule	sol89	1989	only	-	May	24	11:56:45s 0:03:15 -
+Rule	sol89	1989	only	-	May	25	11:56:55s 0:03:05 -
+Rule	sol89	1989	only	-	May	26	11:57:00s 0:03:00 -
+Rule	sol89	1989	only	-	May	27	11:57:05s 0:02:55 -
+Rule	sol89	1989	only	-	May	28	11:57:15s 0:02:45 -
+Rule	sol89	1989	only	-	May	29	11:57:20s 0:02:40 -
+Rule	sol89	1989	only	-	May	30	11:57:30s 0:02:30 -
+Rule	sol89	1989	only	-	May	31	11:57:35s 0:02:25 -
+Rule	sol89	1989	only	-	Jun	1	11:57:45s 0:02:15 -
+Rule	sol89	1989	only	-	Jun	2	11:57:55s 0:02:05 -
+Rule	sol89	1989	only	-	Jun	3	11:58:05s 0:01:55 -
+Rule	sol89	1989	only	-	Jun	4	11:58:15s 0:01:45 -
+Rule	sol89	1989	only	-	Jun	5	11:58:25s 0:01:35 -
+Rule	sol89	1989	only	-	Jun	6	11:58:35s 0:01:25 -
+Rule	sol89	1989	only	-	Jun	7	11:58:45s 0:01:15 -
+Rule	sol89	1989	only	-	Jun	8	11:59:00s 0:01:00 -
+Rule	sol89	1989	only	-	Jun	9	11:59:10s 0:00:50 -
+Rule	sol89	1989	only	-	Jun	10	11:59:20s 0:00:40 -
+Rule	sol89	1989	only	-	Jun	11	11:59:35s 0:00:25 -
+Rule	sol89	1989	only	-	Jun	12	11:59:45s 0:00:15 -
+Rule	sol89	1989	only	-	Jun	13	12:00:00s 0:00:00 -
+Rule	sol89	1989	only	-	Jun	14	12:00:10s -0:00:10 -
+Rule	sol89	1989	only	-	Jun	15	12:00:25s -0:00:25 -
+Rule	sol89	1989	only	-	Jun	16	12:00:35s -0:00:35 -
+Rule	sol89	1989	only	-	Jun	17	12:00:50s -0:00:50 -
+Rule	sol89	1989	only	-	Jun	18	12:01:05s -0:01:05 -
+Rule	sol89	1989	only	-	Jun	19	12:01:15s -0:01:15 -
+Rule	sol89	1989	only	-	Jun	20	12:01:30s -0:01:30 -
+Rule	sol89	1989	only	-	Jun	21	12:01:40s -0:01:40 -
+Rule	sol89	1989	only	-	Jun	22	12:01:55s -0:01:55 -
+Rule	sol89	1989	only	-	Jun	23	12:02:10s -0:02:10 -
+Rule	sol89	1989	only	-	Jun	24	12:02:20s -0:02:20 -
+Rule	sol89	1989	only	-	Jun	25	12:02:35s -0:02:35 -
+Rule	sol89	1989	only	-	Jun	26	12:02:45s -0:02:45 -
+Rule	sol89	1989	only	-	Jun	27	12:03:00s -0:03:00 -
+Rule	sol89	1989	only	-	Jun	28	12:03:10s -0:03:10 -
+Rule	sol89	1989	only	-	Jun	29	12:03:25s -0:03:25 -
+Rule	sol89	1989	only	-	Jun	30	12:03:35s -0:03:35 -
+Rule	sol89	1989	only	-	Jul	1	12:03:45s -0:03:45 -
+Rule	sol89	1989	only	-	Jul	2	12:04:00s -0:04:00 -
+Rule	sol89	1989	only	-	Jul	3	12:04:10s -0:04:10 -
+Rule	sol89	1989	only	-	Jul	4	12:04:20s -0:04:20 -
+Rule	sol89	1989	only	-	Jul	5	12:04:30s -0:04:30 -
+Rule	sol89	1989	only	-	Jul	6	12:04:40s -0:04:40 -
+Rule	sol89	1989	only	-	Jul	7	12:04:50s -0:04:50 -
+Rule	sol89	1989	only	-	Jul	8	12:05:00s -0:05:00 -
+Rule	sol89	1989	only	-	Jul	9	12:05:10s -0:05:10 -
+Rule	sol89	1989	only	-	Jul	10	12:05:20s -0:05:20 -
+Rule	sol89	1989	only	-	Jul	11	12:05:25s -0:05:25 -
+Rule	sol89	1989	only	-	Jul	12	12:05:35s -0:05:35 -
+Rule	sol89	1989	only	-	Jul	13	12:05:40s -0:05:40 -
+Rule	sol89	1989	only	-	Jul	14	12:05:50s -0:05:50 -
+Rule	sol89	1989	only	-	Jul	15	12:05:55s -0:05:55 -
+Rule	sol89	1989	only	-	Jul	16	12:06:00s -0:06:00 -
+Rule	sol89	1989	only	-	Jul	17	12:06:05s -0:06:05 -
+Rule	sol89	1989	only	-	Jul	18	12:06:10s -0:06:10 -
+Rule	sol89	1989	only	-	Jul	19	12:06:15s -0:06:15 -
+Rule	sol89	1989	only	-	Jul	20	12:06:20s -0:06:20 -
+Rule	sol89	1989	only	-	Jul	21	12:06:20s -0:06:20 -
+Rule	sol89	1989	only	-	Jul	22	12:06:25s -0:06:25 -
+Rule	sol89	1989	only	-	Jul	23	12:06:25s -0:06:25 -
+Rule	sol89	1989	only	-	Jul	24	12:06:30s -0:06:30 -
+Rule	sol89	1989	only	-	Jul	25	12:06:30s -0:06:30 -
+Rule	sol89	1989	only	-	Jul	26	12:06:30s -0:06:30 -
+Rule	sol89	1989	only	-	Jul	27	12:06:30s -0:06:30 -
+Rule	sol89	1989	only	-	Jul	28	12:06:30s -0:06:30 -
+Rule	sol89	1989	only	-	Jul	29	12:06:25s -0:06:25 -
+Rule	sol89	1989	only	-	Jul	30	12:06:25s -0:06:25 -
+Rule	sol89	1989	only	-	Jul	31	12:06:20s -0:06:20 -
+Rule	sol89	1989	only	-	Aug	1	12:06:20s -0:06:20 -
+Rule	sol89	1989	only	-	Aug	2	12:06:15s -0:06:15 -
+Rule	sol89	1989	only	-	Aug	3	12:06:10s -0:06:10 -
+Rule	sol89	1989	only	-	Aug	4	12:06:05s -0:06:05 -
+Rule	sol89	1989	only	-	Aug	5	12:06:00s -0:06:00 -
+Rule	sol89	1989	only	-	Aug	6	12:05:50s -0:05:50 -
+Rule	sol89	1989	only	-	Aug	7	12:05:45s -0:05:45 -
+Rule	sol89	1989	only	-	Aug	8	12:05:35s -0:05:35 -
+Rule	sol89	1989	only	-	Aug	9	12:05:30s -0:05:30 -
+Rule	sol89	1989	only	-	Aug	10	12:05:20s -0:05:20 -
+Rule	sol89	1989	only	-	Aug	11	12:05:10s -0:05:10 -
+Rule	sol89	1989	only	-	Aug	12	12:05:00s -0:05:00 -
+Rule	sol89	1989	only	-	Aug	13	12:04:50s -0:04:50 -
+Rule	sol89	1989	only	-	Aug	14	12:04:40s -0:04:40 -
+Rule	sol89	1989	only	-	Aug	15	12:04:30s -0:04:30 -
+Rule	sol89	1989	only	-	Aug	16	12:04:15s -0:04:15 -
+Rule	sol89	1989	only	-	Aug	17	12:04:05s -0:04:05 -
+Rule	sol89	1989	only	-	Aug	18	12:03:50s -0:03:50 -
+Rule	sol89	1989	only	-	Aug	19	12:03:35s -0:03:35 -
+Rule	sol89	1989	only	-	Aug	20	12:03:25s -0:03:25 -
+Rule	sol89	1989	only	-	Aug	21	12:03:10s -0:03:10 -
+Rule	sol89	1989	only	-	Aug	22	12:02:55s -0:02:55 -
+Rule	sol89	1989	only	-	Aug	23	12:02:40s -0:02:40 -
+Rule	sol89	1989	only	-	Aug	24	12:02:20s -0:02:20 -
+Rule	sol89	1989	only	-	Aug	25	12:02:05s -0:02:05 -
+Rule	sol89	1989	only	-	Aug	26	12:01:50s -0:01:50 -
+Rule	sol89	1989	only	-	Aug	27	12:01:30s -0:01:30 -
+Rule	sol89	1989	only	-	Aug	28	12:01:15s -0:01:15 -
+Rule	sol89	1989	only	-	Aug	29	12:00:55s -0:00:55 -
+Rule	sol89	1989	only	-	Aug	30	12:00:40s -0:00:40 -
+Rule	sol89	1989	only	-	Aug	31	12:00:20s -0:00:20 -
+Rule	sol89	1989	only	-	Sep	1	12:00:00s 0:00:00 -
+Rule	sol89	1989	only	-	Sep	2	11:59:45s 0:00:15 -
+Rule	sol89	1989	only	-	Sep	3	11:59:25s 0:00:35 -
+Rule	sol89	1989	only	-	Sep	4	11:59:05s 0:00:55 -
+Rule	sol89	1989	only	-	Sep	5	11:58:45s 0:01:15 -
+Rule	sol89	1989	only	-	Sep	6	11:58:25s 0:01:35 -
+Rule	sol89	1989	only	-	Sep	7	11:58:05s 0:01:55 -
+Rule	sol89	1989	only	-	Sep	8	11:57:45s 0:02:15 -
+Rule	sol89	1989	only	-	Sep	9	11:57:20s 0:02:40 -
+Rule	sol89	1989	only	-	Sep	10	11:57:00s 0:03:00 -
+Rule	sol89	1989	only	-	Sep	11	11:56:40s 0:03:20 -
+Rule	sol89	1989	only	-	Sep	12	11:56:20s 0:03:40 -
+Rule	sol89	1989	only	-	Sep	13	11:56:00s 0:04:00 -
+Rule	sol89	1989	only	-	Sep	14	11:55:35s 0:04:25 -
+Rule	sol89	1989	only	-	Sep	15	11:55:15s 0:04:45 -
+Rule	sol89	1989	only	-	Sep	16	11:54:55s 0:05:05 -
+Rule	sol89	1989	only	-	Sep	17	11:54:35s 0:05:25 -
+Rule	sol89	1989	only	-	Sep	18	11:54:10s 0:05:50 -
+Rule	sol89	1989	only	-	Sep	19	11:53:50s 0:06:10 -
+Rule	sol89	1989	only	-	Sep	20	11:53:30s 0:06:30 -
+Rule	sol89	1989	only	-	Sep	21	11:53:10s 0:06:50 -
+Rule	sol89	1989	only	-	Sep	22	11:52:45s 0:07:15 -
+Rule	sol89	1989	only	-	Sep	23	11:52:25s 0:07:35 -
+Rule	sol89	1989	only	-	Sep	24	11:52:05s 0:07:55 -
+Rule	sol89	1989	only	-	Sep	25	11:51:45s 0:08:15 -
+Rule	sol89	1989	only	-	Sep	26	11:51:25s 0:08:35 -
+Rule	sol89	1989	only	-	Sep	27	11:51:05s 0:08:55 -
+Rule	sol89	1989	only	-	Sep	28	11:50:40s 0:09:20 -
+Rule	sol89	1989	only	-	Sep	29	11:50:20s 0:09:40 -
+Rule	sol89	1989	only	-	Sep	30	11:50:00s 0:10:00 -
+Rule	sol89	1989	only	-	Oct	1	11:49:45s 0:10:15 -
+Rule	sol89	1989	only	-	Oct	2	11:49:25s 0:10:35 -
+Rule	sol89	1989	only	-	Oct	3	11:49:05s 0:10:55 -
+Rule	sol89	1989	only	-	Oct	4	11:48:45s 0:11:15 -
+Rule	sol89	1989	only	-	Oct	5	11:48:30s 0:11:30 -
+Rule	sol89	1989	only	-	Oct	6	11:48:10s 0:11:50 -
+Rule	sol89	1989	only	-	Oct	7	11:47:50s 0:12:10 -
+Rule	sol89	1989	only	-	Oct	8	11:47:35s 0:12:25 -
+Rule	sol89	1989	only	-	Oct	9	11:47:20s 0:12:40 -
+Rule	sol89	1989	only	-	Oct	10	11:47:00s 0:13:00 -
+Rule	sol89	1989	only	-	Oct	11	11:46:45s 0:13:15 -
+Rule	sol89	1989	only	-	Oct	12	11:46:30s 0:13:30 -
+Rule	sol89	1989	only	-	Oct	13	11:46:15s 0:13:45 -
+Rule	sol89	1989	only	-	Oct	14	11:46:00s 0:14:00 -
+Rule	sol89	1989	only	-	Oct	15	11:45:50s 0:14:10 -
+Rule	sol89	1989	only	-	Oct	16	11:45:35s 0:14:25 -
+Rule	sol89	1989	only	-	Oct	17	11:45:20s 0:14:40 -
+Rule	sol89	1989	only	-	Oct	18	11:45:10s 0:14:50 -
+Rule	sol89	1989	only	-	Oct	19	11:45:00s 0:15:00 -
+Rule	sol89	1989	only	-	Oct	20	11:44:50s 0:15:10 -
+Rule	sol89	1989	only	-	Oct	21	11:44:40s 0:15:20 -
+Rule	sol89	1989	only	-	Oct	22	11:44:30s 0:15:30 -
+Rule	sol89	1989	only	-	Oct	23	11:44:20s 0:15:40 -
+Rule	sol89	1989	only	-	Oct	24	11:44:10s 0:15:50 -
+Rule	sol89	1989	only	-	Oct	25	11:44:05s 0:15:55 -
+Rule	sol89	1989	only	-	Oct	26	11:44:00s 0:16:00 -
+Rule	sol89	1989	only	-	Oct	27	11:43:50s 0:16:10 -
+Rule	sol89	1989	only	-	Oct	28	11:43:45s 0:16:15 -
+Rule	sol89	1989	only	-	Oct	29	11:43:40s 0:16:20 -
+Rule	sol89	1989	only	-	Oct	30	11:43:40s 0:16:20 -
+Rule	sol89	1989	only	-	Oct	31	11:43:35s 0:16:25 -
+Rule	sol89	1989	only	-	Nov	1	11:43:35s 0:16:25 -
+Rule	sol89	1989	only	-	Nov	2	11:43:35s 0:16:25 -
+Rule	sol89	1989	only	-	Nov	3	11:43:30s 0:16:30 -
+Rule	sol89	1989	only	-	Nov	4	11:43:35s 0:16:25 -
+Rule	sol89	1989	only	-	Nov	5	11:43:35s 0:16:25 -
+Rule	sol89	1989	only	-	Nov	6	11:43:35s 0:16:25 -
+Rule	sol89	1989	only	-	Nov	7	11:43:40s 0:16:20 -
+Rule	sol89	1989	only	-	Nov	8	11:43:45s 0:16:15 -
+Rule	sol89	1989	only	-	Nov	9	11:43:50s 0:16:10 -
+Rule	sol89	1989	only	-	Nov	10	11:43:55s 0:16:05 -
+Rule	sol89	1989	only	-	Nov	11	11:44:00s 0:16:00 -
+Rule	sol89	1989	only	-	Nov	12	11:44:05s 0:15:55 -
+Rule	sol89	1989	only	-	Nov	13	11:44:15s 0:15:45 -
+Rule	sol89	1989	only	-	Nov	14	11:44:25s 0:15:35 -
+Rule	sol89	1989	only	-	Nov	15	11:44:35s 0:15:25 -
+Rule	sol89	1989	only	-	Nov	16	11:44:45s 0:15:15 -
+Rule	sol89	1989	only	-	Nov	17	11:44:55s 0:15:05 -
+Rule	sol89	1989	only	-	Nov	18	11:45:10s 0:14:50 -
+Rule	sol89	1989	only	-	Nov	19	11:45:20s 0:14:40 -
+Rule	sol89	1989	only	-	Nov	20	11:45:35s 0:14:25 -
+Rule	sol89	1989	only	-	Nov	21	11:45:50s 0:14:10 -
+Rule	sol89	1989	only	-	Nov	22	11:46:05s 0:13:55 -
+Rule	sol89	1989	only	-	Nov	23	11:46:25s 0:13:35 -
+Rule	sol89	1989	only	-	Nov	24	11:46:40s 0:13:20 -
+Rule	sol89	1989	only	-	Nov	25	11:47:00s 0:13:00 -
+Rule	sol89	1989	only	-	Nov	26	11:47:20s 0:12:40 -
+Rule	sol89	1989	only	-	Nov	27	11:47:35s 0:12:25 -
+Rule	sol89	1989	only	-	Nov	28	11:47:55s 0:12:05 -
+Rule	sol89	1989	only	-	Nov	29	11:48:20s 0:11:40 -
+Rule	sol89	1989	only	-	Nov	30	11:48:40s 0:11:20 -
+Rule	sol89	1989	only	-	Dec	1	11:49:00s 0:11:00 -
+Rule	sol89	1989	only	-	Dec	2	11:49:25s 0:10:35 -
+Rule	sol89	1989	only	-	Dec	3	11:49:50s 0:10:10 -
+Rule	sol89	1989	only	-	Dec	4	11:50:15s 0:09:45 -
+Rule	sol89	1989	only	-	Dec	5	11:50:35s 0:09:25 -
+Rule	sol89	1989	only	-	Dec	6	11:51:00s 0:09:00 -
+Rule	sol89	1989	only	-	Dec	7	11:51:30s 0:08:30 -
+Rule	sol89	1989	only	-	Dec	8	11:51:55s 0:08:05 -
+Rule	sol89	1989	only	-	Dec	9	11:52:20s 0:07:40 -
+Rule	sol89	1989	only	-	Dec	10	11:52:50s 0:07:10 -
+Rule	sol89	1989	only	-	Dec	11	11:53:15s 0:06:45 -
+Rule	sol89	1989	only	-	Dec	12	11:53:45s 0:06:15 -
+Rule	sol89	1989	only	-	Dec	13	11:54:10s 0:05:50 -
+Rule	sol89	1989	only	-	Dec	14	11:54:40s 0:05:20 -
+Rule	sol89	1989	only	-	Dec	15	11:55:10s 0:04:50 -
+Rule	sol89	1989	only	-	Dec	16	11:55:40s 0:04:20 -
+Rule	sol89	1989	only	-	Dec	17	11:56:05s 0:03:55 -
+Rule	sol89	1989	only	-	Dec	18	11:56:35s 0:03:25 -
+Rule	sol89	1989	only	-	Dec	19	11:57:05s 0:02:55 -
+Rule	sol89	1989	only	-	Dec	20	11:57:35s 0:02:25 -
+Rule	sol89	1989	only	-	Dec	21	11:58:05s 0:01:55 -
+Rule	sol89	1989	only	-	Dec	22	11:58:35s 0:01:25 -
+Rule	sol89	1989	only	-	Dec	23	11:59:05s 0:00:55 -
+Rule	sol89	1989	only	-	Dec	24	11:59:35s 0:00:25 -
+Rule	sol89	1989	only	-	Dec	25	12:00:05s -0:00:05 -
+Rule	sol89	1989	only	-	Dec	26	12:00:35s -0:00:35 -
+Rule	sol89	1989	only	-	Dec	27	12:01:05s -0:01:05 -
+Rule	sol89	1989	only	-	Dec	28	12:01:35s -0:01:35 -
+Rule	sol89	1989	only	-	Dec	29	12:02:00s -0:02:00 -
+Rule	sol89	1989	only	-	Dec	30	12:02:30s -0:02:30 -
+Rule	sol89	1989	only	-	Dec	31	12:03:00s -0:03:00 -
+
+# Riyadh is at about 46 degrees 46 minutes East:  3 hrs, 7 mins, 4 secs
+# Before and after 1989, we'll operate on local mean solar time.
+
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
+Zone	Asia/Riyadh89	3:07:04	-		zzz	1989
+			3:07:04	sol89		zzz	1990
+			3:07:04	-		zzz
+# For backward compatibility...
+Link	Asia/Riyadh89	Mideast/Riyadh89
diff --git a/tools/zoneinfo/tzdata2008h/southamerica b/tools/zoneinfo/tzdata2008h/southamerica
new file mode 100644
index 0000000..5dae61a
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/southamerica
@@ -0,0 +1,1390 @@
+# @(#)southamerica	8.30
+# <pre>
+
+# This data is by no means authoritative; if you think you know better,
+# go ahead and edit the file (and please send any changes to
+# tz@elsie.nci.nih.gov for general use in the future).
+
+# From Paul Eggert (2006-03-22):
+# A good source for time zone historical data outside the U.S. is
+# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
+# San Diego: ACS Publications, Inc. (2003).
+#
+# Gwillim Law writes that a good source
+# for recent time zone data is the International Air Transport
+# Association's Standard Schedules Information Manual (IATA SSIM),
+# published semiannually.  Law sent in several helpful summaries
+# of the IATA's data after 1990.
+#
+# Except where otherwise noted, Shanks & Pottenger is the source for
+# entries through 1990, and IATA SSIM is the source for entries afterwards.
+#
+# Earlier editions of these tables used the North American style (e.g. ARST and
+# ARDT for Argentine Standard and Daylight Time), but the following quote
+# suggests that it's better to use European style (e.g. ART and ARST).
+#	I suggest the use of _Summer time_ instead of the more cumbersome
+#	_daylight-saving time_.  _Summer time_ seems to be in general use
+#	in Europe and South America.
+#	-- E O Cutler, _New York Times_ (1937-02-14), quoted in
+#	H L Mencken, _The American Language: Supplement I_ (1960), p 466
+#
+# Earlier editions of these tables also used the North American style
+# for time zones in Brazil, but this was incorrect, as Brazilians say
+# "summer time".  Reinaldo Goulart, a Sao Paulo businessman active in
+# the railroad sector, writes (1999-07-06):
+#	The subject of time zones is currently a matter of discussion/debate in
+#	Brazil.  Let's say that "the Brasilia time" is considered the
+#	"official time" because Brasilia is the capital city.
+#	The other three time zones are called "Brasilia time "minus one" or
+#	"plus one" or "plus two".  As far as I know there is no such
+#	name/designation as "Eastern Time" or "Central Time".
+# So I invented the following (English-language) abbreviations for now.
+# Corrections are welcome!
+#		std	dst
+#	-2:00	FNT	FNST	Fernando de Noronha
+#	-3:00	BRT	BRST	Brasilia
+#	-4:00	AMT	AMST	Amazon
+#	-5:00	ACT	ACST	Acre
+
+###############################################################################
+
+###############################################################################
+
+# Argentina
+
+# From Bob Devine (1988-01-28):
+# Argentina: first Sunday in October to first Sunday in April since 1976.
+# Double Summer time from 1969 to 1974.  Switches at midnight.
+
+# From U. S. Naval Observatory (1988-01-199):
+# ARGENTINA           3 H BEHIND   UTC
+
+# From Hernan G. Otero (1995-06-26):
+# I am sending modifications to the Argentine time zone table...
+# AR was chosen because they are the ISO letters that represent Argentina.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Arg	1930	only	-	Dec	 1	0:00	1:00	S
+Rule	Arg	1931	only	-	Apr	 1	0:00	0	-
+Rule	Arg	1931	only	-	Oct	15	0:00	1:00	S
+Rule	Arg	1932	1940	-	Mar	 1	0:00	0	-
+Rule	Arg	1932	1939	-	Nov	 1	0:00	1:00	S
+Rule	Arg	1940	only	-	Jul	 1	0:00	1:00	S
+Rule	Arg	1941	only	-	Jun	15	0:00	0	-
+Rule	Arg	1941	only	-	Oct	15	0:00	1:00	S
+Rule	Arg	1943	only	-	Aug	 1	0:00	0	-
+Rule	Arg	1943	only	-	Oct	15	0:00	1:00	S
+Rule	Arg	1946	only	-	Mar	 1	0:00	0	-
+Rule	Arg	1946	only	-	Oct	 1	0:00	1:00	S
+Rule	Arg	1963	only	-	Oct	 1	0:00	0	-
+Rule	Arg	1963	only	-	Dec	15	0:00	1:00	S
+Rule	Arg	1964	1966	-	Mar	 1	0:00	0	-
+Rule	Arg	1964	1966	-	Oct	15	0:00	1:00	S
+Rule	Arg	1967	only	-	Apr	 2	0:00	0	-
+Rule	Arg	1967	1968	-	Oct	Sun>=1	0:00	1:00	S
+Rule	Arg	1968	1969	-	Apr	Sun>=1	0:00	0	-
+Rule	Arg	1974	only	-	Jan	23	0:00	1:00	S
+Rule	Arg	1974	only	-	May	 1	0:00	0	-
+Rule	Arg	1988	only	-	Dec	 1	0:00	1:00	S
+#
+# From Hernan G. Otero (1995-06-26):
+# These corrections were contributed by InterSoft Argentina S.A.,
+# obtaining the data from the:
+# Talleres de Hidrografia Naval Argentina
+# (Argentine Naval Hydrography Institute)
+Rule	Arg	1989	1993	-	Mar	Sun>=1	0:00	0	-
+Rule	Arg	1989	1992	-	Oct	Sun>=15	0:00	1:00	S
+#
+# From Hernan G. Otero (1995-06-26):
+# From this moment on, the law that mandated the daylight saving
+# time corrections was derogated and no more modifications
+# to the time zones (for daylight saving) are now made.
+#
+# From Rives McDow (2000-01-10):
+# On October 3, 1999, 0:00 local, Argentina implemented daylight savings time,
+# which did not result in the switch of a time zone, as they stayed 9 hours
+# from the International Date Line.
+Rule	Arg	1999	only	-	Oct	Sun>=1	0:00	1:00	S
+# From Paul Eggert (2007-12-28):
+# DST was set to expire on March 5, not March 3, but since it was converted
+# to standard time on March 3 it's more convenient for us to pretend that
+# it ended on March 3.
+Rule	Arg	2000	only	-	Mar	3	0:00	0	-
+#
+# From Peter Gradelski via Steffen Thorsen (2000-03-01):
+# We just checked with our Sao Paulo office and they say the government of
+# Argentina decided not to become one of the countries that go on or off DST.
+# So Buenos Aires should be -3 hours from GMT at all times.
+#
+# From Fabian L. Arce Jofre (2000-04-04):
+# The law that claimed DST for Argentina was derogated by President Fernando
+# de la Rua on March 2, 2000, because it would make people spend more energy
+# in the winter time, rather than less.  The change took effect on March 3.
+#
+# From Mariano Absatz (2001-06-06):
+# one of the major newspapers here in Argentina said that the 1999
+# Timezone Law (which never was effectively applied) will (would?) be
+# in effect.... The article is at
+# http://ar.clarin.com/diario/2001-06-06/e-01701.htm
+# ... The Law itself is "Ley No 25155", sanctioned on 1999-08-25, enacted
+# 1999-09-17, and published 1999-09-21.  The official publication is at:
+# http://www.boletin.jus.gov.ar/BON/Primera/1999/09-Septiembre/21/PDF/BO21-09-99LEG.PDF
+# Regretfully, you have to subscribe (and pay) for the on-line version....
+#
+# (2001-06-12):
+# the timezone for Argentina will not change next Sunday.
+# Apparently it will do so on Sunday 24th....
+# http://ar.clarin.com/diario/2001-06-12/s-03501.htm
+#
+# (2001-06-25):
+# Last Friday (yes, the last working day before the date of the change), the
+# Senate annulled the 1999 law that introduced the changes later postponed.
+# http://www.clarin.com.ar/diario/2001-06-22/s-03601.htm
+# It remains the vote of the Deputies..., but it will be the same....
+# This kind of things had always been done this way in Argentina.
+# We are still -03:00 all year round in all of the country.
+#
+# From Steffen Thorsen (2007-12-21):
+# A user (Leonardo Chaim) reported that Argentina will adopt DST....
+# all of the country (all Zone-entries) are affected.  News reports like
+# http://www.lanacion.com.ar/opinion/nota.asp?nota_id=973037 indicate
+# that Argentina will use DST next year as well, from October to
+# March, although exact rules are not given.
+#
+# From Jesper Norgaard Welen (2007-12-26)
+# The last hurdle of Argentina DST is over, the proposal was approved in
+# the lower chamber too (Deputados) with a vote 192 for and 2 against.
+# By the way thanks to Mariano Absatz and Daniel Mario Vega for the link to
+# the original scanned proposal, where the dates and the zero hours are
+# clear and unambiguous...This is the article about final approval:
+# <a href="http://www.lanacion.com.ar/politica/nota.asp?nota_id=973996">
+# http://www.lanacion.com.ar/politica/nota.asp?nota_id=973996
+# </a>
+#
+# From Paul Eggert (2007-12-22):
+# For dates after mid-2008, the following rules are my guesses and
+# are quite possibly wrong, but are more likely than no DST at all.
+
+# From Alexander Krivenyshev (2008-09-05):
+# As per message from Carlos Alberto Fonseca Arauz (Nicaragua),
+# Argentina will start DST on Sunday October 19, 2008.
+#
+# <a href="http://www.worldtimezone.com/dst_news/dst_news_argentina03.html">
+# http://www.worldtimezone.com/dst_news/dst_news_argentina03.html
+# </a>
+# OR
+# <a href="http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish)">
+# http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish)
+# </a>
+
+# From Rodrigo Severo (2008-10-06):
+# Here is some info available at a Gentoo bug related to TZ on Argentina's DST:
+# ...
+# ------- Comment #1 from [jmdocile]  2008-10-06 16:28 0000 -------
+# Hi, there is a problem with timezone-data-2008e and maybe with
+# timezone-data-2008f
+# Argentinian law [Number] 25.155 is no longer valid.
+# <a href="http://www.infoleg.gov.ar/infolegInternet/anexos/60000-64999/60036/norma.htm">
+# http://www.infoleg.gov.ar/infolegInternet/anexos/60000-64999/60036/norma.htm
+# </a>
+# The new one is law [Number] 26.350
+# <a href="http://www.infoleg.gov.ar/infolegInternet/anexos/135000-139999/136191/norma.htm">
+# http://www.infoleg.gov.ar/infolegInternet/anexos/135000-139999/136191/norma.htm
+# </a>
+# So there is no summer time in Argentina for now.
+
+Rule	Arg	2007	only	-	Dec	30	0:00	1:00	S
+Rule	Arg	2008	max	-	Mar	Sun>=15	0:00	0	-
+Rule	Arg	2008	max	-	Oct	Sun>=15	0:00	1:00	S
+ 
+# From Mariano Absatz (2004-05-21):
+# Today it was officially published that the Province of Mendoza is changing
+# its timezone this winter... starting tomorrow night....
+# http://www.gobernac.mendoza.gov.ar/boletin/pdf/20040521-27158-normas.pdf
+# From Paul Eggert (2004-05-24):
+# It's Law No. 7,210.  This change is due to a public power emergency, so for
+# now we'll assume it's for this year only.
+#
+# From Paul Eggert (2006-03-22):
+# <a href="http://www.spicasc.net/horvera.html">
+# Hora de verano para la Republica Argentina (2003-06-08)
+# </a> says that standard time in Argentina from 1894-10-31
+# to 1920-05-01 was -4:16:48.25.  Go with this more-precise value
+# over Shanks & Pottenger.
+#
+# From Mariano Absatz (2004-06-05):
+# These media articles from a major newspaper mostly cover the current state:
+# http://www.lanacion.com.ar/04/05/27/de_604825.asp
+# http://www.lanacion.com.ar/04/05/28/de_605203.asp
+#
+# The following eight (8) provinces pulled clocks back to UTC-04:00 at
+# midnight Monday May 31st. (that is, the night between 05/31 and 06/01).
+# Apparently, all nine provinces would go back to UTC-03:00 at the same
+# time in October 17th.
+#
+# Catamarca, Chubut, La Rioja, San Juan, San Luis, Santa Cruz,
+# Tierra del Fuego, Tucuman.
+#
+# From Mariano Absatz (2004-06-14):
+# ... this weekend, the Province of Tucuman decided it'd go back to UTC-03:00
+# yesterday midnight (that is, at 24:00 Saturday 12th), since the people's
+# annoyance with the change is much higher than the power savings obtained....
+#
+# From Gwillim Law (2004-06-14):
+# http://www.lanacion.com.ar/04/06/10/de_609078.asp ...
+#     "The time change in Tierra del Fuego was a conflicted decision from
+#   the start.  The government had decreed that the measure would take
+#   effect on June 1, but a normative error forced the new time to begin
+#   three days earlier, from a Saturday to a Sunday....
+# Our understanding was that the change was originally scheduled to take place
+# on June 1 at 00:00 in Chubut, Santa Cruz, Tierra del Fuego (and some other
+# provinces).  Sunday was May 30, only two days earlier.  So the article
+# contains a contradiction.  I would give more credence to the Saturday/Sunday
+# date than the "three days earlier" phrase, and conclude that Tierra del
+# Fuego set its clocks back at 2004-05-30 00:00.
+#
+# From Steffen Thorsen (2004-10-05):
+# The previous law 7210 which changed the province of Mendoza's time zone
+# back in May have been modified slightly in a new law 7277, which set the
+# new end date to 2004-09-26 (original date was 2004-10-17).
+# http://www.gobernac.mendoza.gov.ar/boletin/pdf/20040924-27244-normas.pdf
+#
+# From Mariano Absatz (2004-10-05):
+# San Juan changed from UTC-03:00 to UTC-04:00 at midnight between
+# Sunday, May 30th and Monday, May 31st.  It changed back to UTC-03:00
+# at midnight between Saturday, July 24th and Sunday, July 25th....
+# http://www.sanjuan.gov.ar/prensa/archivo/000329.html
+# http://www.sanjuan.gov.ar/prensa/archivo/000426.html
+# http://www.sanjuan.gov.ar/prensa/archivo/000441.html
+
+# From Alex Krivenyshev (2008-01-17):
+# Here are articles that Argentina Province San Luis is planning to end DST
+# as earlier as upcoming Monday January 21, 2008 or February 2008:
+#
+# Provincia argentina retrasa reloj y marca diferencia con resto del pais
+# (Argentine Province delayed clock and mark difference with the rest of the
+# country)
+# <a href="http://cl.invertia.com/noticias/noticia.aspx?idNoticia=200801171849_EFE_ET4373&idtel">
+# http://cl.invertia.com/noticias/noticia.aspx?idNoticia=200801171849_EFE_ET4373&idtel
+# </a>
+#
+# Es inminente que en San Luis atrasen una hora los relojes
+# (It is imminent in San Luis clocks one hour delay)
+# <a href="http://www.lagaceta.com.ar/vernotae.asp?id_nota=253414">
+# http://www.lagaceta.com.ar/vernotae.asp?id_nota=253414
+# </a>
+#
+# <a href="http://www.worldtimezone.net/dst_news/dst_news_argentina02.html">
+# http://www.worldtimezone.net/dst_news/dst_news_argentina02.html
+# </a>
+
+# From Jesper Norgaard Welen (2008-01-18):
+# The page of the San Luis provincial government
+# <a href="http://www.sanluis.gov.ar/notas.asp?idCanal=0&id=22812">
+# http://www.sanluis.gov.ar/notas.asp?idCanal=0&id=22812
+# </a>
+# confirms what Alex Krivenyshev has earlier sent to the tz
+# emailing list about that San Luis plans to return to standard
+# time much earlier than the rest of the country. It also
+# confirms that upon request the provinces San Juan and Mendoza 
+# refused to follow San Luis in this change. 
+# 
+# The change is supposed to take place Monday the 21.st at 0:00
+# hours. As far as I understand it if this goes ahead, we need
+# a new timezone for San Luis (although there are also documented
+# independent changes in the southamerica file of San Luis in
+# 1990 and 1991 which has not been confirmed).
+
+# From Jesper Norgaard Welen (2008-01-25):
+# Unfortunately the below page has become defunct, about the San Luis
+# time change. Perhaps because it now is part of a group of pages "Most
+# important pages of 2008."
+#
+# You can use
+# <a href="http://www.sanluis.gov.ar/notas.asp?idCanal=8141&id=22834">
+# http://www.sanluis.gov.ar/notas.asp?idCanal=8141&id=22834
+# </a>
+# instead it seems. Or use "Buscador" from the main page of the San Luis
+# government, and fill in "huso" and click OK, and you will get 3 pages
+# from which the first one is identical to the above.
+
+# From Mariano Absatz (2008-01-28):
+# I can confirm that the Province of San Luis (and so far only that
+# province) decided to go back to UTC-3 effective midnight Jan 20th 2008
+# (that is, Monday 21st at 0:00 is the time the clocks were delayed back
+# 1 hour), and they intend to keep UTC-3 as their timezone all year round
+# (that is, unless they change their mind any minute now).
+#
+# So we'll have to add yet another city to 'southamerica' (I think San
+# Luis city is the mos populated city in the Province, so it'd be
+# America/Argentina/San_Luis... of course I can't remember if San Luis's
+# history of particular changes goes along with Mendoza or San Juan :-(
+# (I only remember not being able to collect hard facts about San Luis
+# back in 2004, when these provinces changed to UTC-4 for a few days, I
+# mailed them personally and never got an answer).
+
+# From Paul Eggert (2008-06-30):
+# Unless otherwise specified, data are from Shanks & Pottenger through 1992,
+# from the IATA otherwise.  As noted below, Shanks & Pottenger say that
+# America/Cordoba split into 6 subregions during 1991/1992, one of which
+# was America/San_Luis, but we haven't verified this yet so for now we'll
+# keep America/Cordoba a single region rather than splitting it into the
+# other 5 subregions.
+
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+#
+# Buenos Aires (BA), Capital Federal (CF),
+Zone America/Argentina/Buenos_Aires -3:53:48 - LMT 1894 Oct 31
+			-4:16:48 -	CMT	1920 May # Cordoba Mean Time
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	Arg	AR%sT
+#
+# Santa Fe (SF), Entre Rios (ER), Corrientes (CN), Misiones (MN), Chaco (CC),
+# Formosa (FM), Salta (SA), Santiago del Estero (SE), Cordoba (CB),
+# La Pampa (LP), Neuquen (NQ), Rio Negro (RN)
+#
+# Shanks & Pottenger also make the following claims, which we haven't verified:
+# - Formosa switched to -3:00 on 1991-01-07.
+# - Misiones switched to -3:00 on 1990-12-29.
+# - Chaco switched to -3:00 on 1991-01-04.
+# - Santiago del Estero switched to -4:00 on 1991-04-01,
+#   then to -3:00 on 1991-04-26.
+#
+Zone America/Argentina/Cordoba -4:16:48 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1991 Mar  3
+			-4:00	-	WART	1991 Oct 20
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	Arg	AR%sT
+#
+# Tucuman (TM)
+Zone America/Argentina/Tucuman -4:20:52 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1991 Mar  3
+			-4:00	-	WART	1991 Oct 20
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	-	ART	2004 Jun  1
+			-4:00	-	WART	2004 Jun 13
+			-3:00	Arg	AR%sT
+#
+# La Rioja (LR)
+Zone America/Argentina/La_Rioja -4:27:24 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1991 Mar  1
+			-4:00	-	WART	1991 May  7
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	-	ART	2004 Jun  1
+			-4:00	-	WART	2004 Jun 20
+			-3:00	Arg	AR%sT
+#
+# San Juan (SJ)
+Zone America/Argentina/San_Juan -4:34:04 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1991 Mar  1
+			-4:00	-	WART	1991 May  7
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	-	ART	2004 May 31
+			-4:00	-	WART	2004 Jul 25
+			-3:00	Arg	AR%sT
+#
+# Jujuy (JY)
+Zone America/Argentina/Jujuy -4:21:12 -	LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1990 Mar  4
+			-4:00	-	WART	1990 Oct 28
+			-4:00	1:00	WARST	1991 Mar 17
+			-4:00	-	WART	1991 Oct  6
+			-3:00	1:00	ARST	1992
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	Arg	AR%sT
+#
+# Catamarca (CT), Chubut (CH)
+Zone America/Argentina/Catamarca -4:23:08 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1991 Mar  3
+			-4:00	-	WART	1991 Oct 20
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	-	ART	2004 Jun  1
+			-4:00	-	WART	2004 Jun 20
+			-3:00	Arg	AR%sT
+#
+# Mendoza (MZ)
+Zone America/Argentina/Mendoza -4:35:16 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1990 Mar  4
+			-4:00	-	WART	1990 Oct 15
+			-4:00	1:00	WARST	1991 Mar  1
+			-4:00	-	WART	1991 Oct 15
+			-4:00	1:00	WARST	1992 Mar  1
+			-4:00	-	WART	1992 Oct 18
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	-	ART	2004 May 23
+			-4:00	-	WART	2004 Sep 26
+			-3:00	Arg	AR%sT
+#
+# San Luis (SL)
+Zone America/Argentina/San_Luis -4:25:24 - LMT	1894 Oct 31
+			-4:16:48 -	CMT	1920 May
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1990
+			-3:00	1:00	ARST	1990 Mar 14
+			-4:00	-	WART	1990 Oct 15
+			-4:00	1:00	WARST	1991 Mar  1
+			-4:00	-	WART	1991 Jun  1
+			-3:00	-	ART	1999 Oct  3
+			-4:00	1:00	WARST	2000 Mar  3
+			-3:00	-	ART	2004 May 31
+			-4:00	-	WART	2004 Jul 25
+			-3:00	Arg	AR%sT	2008 Jan 21
+			-3:00	-	ART
+#
+# Santa Cruz (SC)
+Zone America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 Oct 31
+			-4:16:48 -	CMT	1920 May # Cordoba Mean Time
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	-	ART	2004 Jun  1
+			-4:00	-	WART	2004 Jun 20
+			-3:00	Arg	AR%sT
+#
+# Tierra del Fuego, Antartida e Islas del Atlantico Sur (TF)
+Zone America/Argentina/Ushuaia -4:33:12 - LMT 1894 Oct 31
+			-4:16:48 -	CMT	1920 May # Cordoba Mean Time
+			-4:00	-	ART	1930 Dec
+			-4:00	Arg	AR%sT	1969 Oct  5
+			-3:00	Arg	AR%sT	1999 Oct  3
+			-4:00	Arg	AR%sT	2000 Mar  3
+			-3:00	-	ART	2004 May 30
+			-4:00	-	WART	2004 Jun 20
+			-3:00	Arg	AR%sT
+
+# Aruba
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Aruba	-4:40:24 -	LMT	1912 Feb 12	# Oranjestad
+			-4:30	-	ANT	1965 # Netherlands Antilles Time
+			-4:00	-	AST
+
+# Bolivia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/La_Paz	-4:32:36 -	LMT	1890
+			-4:32:36 -	CMT	1931 Oct 15 # Calamarca MT
+			-4:32:36 1:00	BOST	1932 Mar 21 # Bolivia ST
+			-4:00	-	BOT	# Bolivia Time
+
+# Brazil
+
+# From Paul Eggert (1993-11-18):
+# The mayor of Rio recently attempted to change the time zone rules
+# just in his city, in order to leave more summer time for the tourist trade.
+# The rule change lasted only part of the day;
+# the federal government refused to follow the city's rules, and business
+# was in a chaos, so the mayor backed down that afternoon.
+
+# From IATA SSIM (1996-02):
+# _Only_ the following states in BR1 observe DST: Rio Grande do Sul (RS),
+# Santa Catarina (SC), Parana (PR), Sao Paulo (SP), Rio de Janeiro (RJ),
+# Espirito Santo (ES), Minas Gerais (MG), Bahia (BA), Goias (GO),
+# Distrito Federal (DF), Tocantins (TO), Sergipe [SE] and Alagoas [AL].
+# [The last three states are new to this issue of the IATA SSIM.]
+
+# From Gwillim Law (1996-10-07):
+# Geography, history (Tocantins was part of Goias until 1989), and other
+# sources of time zone information lead me to believe that AL, SE, and TO were
+# always in BR1, and so the only change was whether or not they observed DST....
+# The earliest issue of the SSIM I have is 2/91.  Each issue from then until
+# 9/95 says that DST is observed only in the ten states I quoted from 9/95,
+# along with Mato Grosso (MT) and Mato Grosso do Sul (MS), which are in BR2
+# (UTC-4)....  The other two time zones given for Brazil are BR3, which is
+# UTC-5, no DST, and applies only in the state of Acre (AC); and BR4, which is
+# UTC-2, and applies to Fernando de Noronha (formerly FN, but I believe it's
+# become part of the state of Pernambuco).  The boundary between BR1 and BR2
+# has never been clearly stated.  They've simply been called East and West.
+# However, some conclusions can be drawn from another IATA manual: the Airline
+# Coding Directory, which lists close to 400 airports in Brazil.  For each
+# airport it gives a time zone which is coded to the SSIM.  From that
+# information, I'm led to conclude that the states of Amapa (AP), Ceara (CE),
+# Maranhao (MA), Paraiba (PR), Pernambuco (PE), Piaui (PI), and Rio Grande do
+# Norte (RN), and the eastern part of Para (PA) are all in BR1 without DST.
+
+# From Marcos Tadeu (1998-09-27):
+# <a href="http://pcdsh01.on.br/verao1.html">
+# Brazilian official page
+# </a>
+
+# From Jesper Norgaard (2000-11-03):
+# [For an official list of which regions in Brazil use which time zones, see:]
+# http://pcdsh01.on.br/Fusbr.htm
+# http://pcdsh01.on.br/Fusbrhv.htm
+
+# From Celso Doria via David Madeo (2002-10-09):
+# The reason for the delay this year has to do with elections in Brazil.
+#
+# Unlike in the United States, elections in Brazil are 100% computerized and
+# the results are known almost immediately.  Yesterday, it was the first
+# round of the elections when 115 million Brazilians voted for President,
+# Governor, Senators, Federal Deputies, and State Deputies.  Nobody is
+# counting (or re-counting) votes anymore and we know there will be a second
+# round for the Presidency and also for some Governors.  The 2nd round will
+# take place on October 27th.
+#
+# The reason why the DST will only begin November 3rd is that the thousands
+# of electoral machines used cannot have their time changed, and since the
+# Constitution says the elections must begin at 8:00 AM and end at 5:00 PM,
+# the Government decided to postpone DST, instead of changing the Constitution
+# (maybe, for the next elections, it will be possible to change the clock)...
+
+# From Rodrigo Severo (2004-10-04):
+# It's just the biannual change made necessary by the much hyped, supposedly
+# modern Brazilian eletronic voting machines which, apparently, can't deal
+# with a time change between the first and the second rounds of the elections.
+
+# From Steffen Thorsen (2007-09-20):
+# Brazil will start DST on 2007-10-14 00:00 and end on 2008-02-17 00:00:
+# http://www.mme.gov.br/site/news/detail.do;jsessionid=BBA06811AFCAAC28F0285210913513DA?newsId=13975
+
+# From Paul Schulze (2008-06-24):
+# ...by law number 11.662 of April 24, 2008 (published in the "Diario
+# Oficial da Uniao"...) in Brazil there are changes in the timezones,
+# effective today (00:00am at June 24, 2008) as follows:
+#
+# a) The timezone UTC+5 is e[x]tinguished, with all the Acre state and the
+# part of the Amazonas state that had this timezone now being put to the
+# timezone UTC+4
+# b) The whole Para state now is put at timezone UTC+3, instead of just
+# part of it, as was before.
+#
+# This change follows a proposal of senator Tiao Viana of Acre state, that
+# proposed it due to concerns about open television channels displaying
+# programs inappropriate to youths in the states that had the timezone
+# UTC+5 too early in the night. In the occasion, some more corrections
+# were proposed, trying to unify the timezones of any given state. This
+# change modifies timezone rules defined in decree 2.784 of 18 June,
+# 1913.
+
+# From Rodrigo Severo (2008-06-24):
+# Just correcting the URL:
+# <a href="https://www.in.gov.br/imprensa/visualiza/index.jsp?jornal=3Ddo&secao=3D1&pagina=3D1&data=3D25/04/2008">
+# https://www.in.gov.br/imprensa/visualiza/index.jsp?jornal=3Ddo&secao=3D1&pagina=3D1&data=3D25/04/2008
+# </a>
+#
+# As a result of the above Decree I believe the America/Rio_Branco
+# timezone shall be modified from UTC-5 to UTC-4 and a new timezone shall
+# be created to represent the the west side of the Para State. I
+# suggest this new timezone be called Santarem as the most
+# important/populated city in the affected area.
+#
+# This new timezone would be the same as the Rio_Branco timezone up to
+# the 2008/06/24 change which would be to UTC-3 instead of UTC-4.
+
+# From Alex Krivenyshev (2008-06-24):
+# This is a quick reference page for New and Old Brazil Time Zones map.
+# <a href="http://www.worldtimezone.com/brazil-time-new-old.php">
+# http://www.worldtimezone.com/brazil-time-new-old.php
+# </a>
+#
+# - 4 time zones replaced by 3 time zones-eliminating time zone UTC- 05
+# (state Acre and the part of the Amazonas will be UTC/GMT- 04) - western
+# part of Par state is moving to one timezone UTC- 03 (from UTC -04).
+
+# From Paul Eggert (2002-10-10):
+# The official decrees referenced below are mostly taken from
+# <a href="http://pcdsh01.on.br/DecHV.html">
+# Decretos sobre o Horario de Verao no Brasil
+# </a>.
+
+# From Steffen Thorsen (2008-08-29):
+# As announced by the government and many newspapers in Brazil late
+# yesterday, Brazil will start DST on 2008-10-19 (need to change rule) and
+# it will end on 2009-02-15 (current rule for Brazil is fine). Based on
+# past years experience with the elections, there was a good chance that
+# the start was postponed to November, but it did not happen this year.
+#
+# It has not yet been posted to http://pcdsh01.on.br/DecHV.html
+#
+# An official page about it:
+# <a href="http://www.mme.gov.br/site/news/detail.do?newsId=16722">
+# http://www.mme.gov.br/site/news/detail.do?newsId=16722
+# </a>
+# Note that this link does not always work directly, but must be accessed
+# by going to
+# <a href="http://www.mme.gov.br/first">
+# http://www.mme.gov.br/first
+# </a>
+#
+# One example link that works directly:
+# <a href="http://jornale.com.br/index.php?option=com_content&task=view&id=13530&Itemid=54">
+# http://jornale.com.br/index.php?option=com_content&task=view&id=13530&Itemid=54
+# (Portuguese)
+# </a>
+#
+# We have a written a short article about it as well:
+# <a href="http://www.timeanddate.com/news/time/brazil-dst-2008-2009.html">
+# http://www.timeanddate.com/news/time/brazil-dst-2008-2009.html
+# </a>
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# Decree <a href="http://pcdsh01.on.br/HV20466.htm">20,466</a> (1931-10-01)
+# Decree <a href="http://pcdsh01.on.br/HV21896.htm">21,896</a> (1932-01-10)
+Rule	Brazil	1931	only	-	Oct	 3	11:00	1:00	S
+Rule	Brazil	1932	1933	-	Apr	 1	 0:00	0	-
+Rule	Brazil	1932	only	-	Oct	 3	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/HV23195.htm">23,195</a> (1933-10-10)
+# revoked DST.
+# Decree <a href="http://pcdsh01.on.br/HV27496.htm">27,496</a> (1949-11-24)
+# Decree <a href="http://pcdsh01.on.br/HV27998.htm">27,998</a> (1950-04-13)
+Rule	Brazil	1949	1952	-	Dec	 1	 0:00	1:00	S
+Rule	Brazil	1950	only	-	Apr	16	 1:00	0	-
+Rule	Brazil	1951	1952	-	Apr	 1	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV32308.htm">32,308</a> (1953-02-24)
+Rule	Brazil	1953	only	-	Mar	 1	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV34724.htm">34,724</a> (1953-11-30)
+# revoked DST.
+# Decree <a href="http://pcdsh01.on.br/HV52700.htm">52,700</a> (1963-10-18)
+# established DST from 1963-10-23 00:00 to 1964-02-29 00:00
+# in SP, RJ, GB, MG, ES, due to the prolongation of the drought.
+# Decree <a href="http://pcdsh01.on.br/HV53071.htm">53,071</a> (1963-12-03)
+# extended the above decree to all of the national territory on 12-09.
+Rule	Brazil	1963	only	-	Dec	 9	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/HV53604.htm">53,604</a> (1964-02-25)
+# extended summer time by one day to 1964-03-01 00:00 (start of school).
+Rule	Brazil	1964	only	-	Mar	 1	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV55639.htm">55,639</a> (1965-01-27)
+Rule	Brazil	1965	only	-	Jan	31	 0:00	1:00	S
+Rule	Brazil	1965	only	-	Mar	31	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV57303.htm">57,303</a> (1965-11-22)
+Rule	Brazil	1965	only	-	Dec	 1	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/HV57843.htm">57,843</a> (1966-02-18)
+Rule	Brazil	1966	1968	-	Mar	 1	 0:00	0	-
+Rule	Brazil	1966	1967	-	Nov	 1	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/HV63429.htm">63,429</a> (1968-10-15)
+# revoked DST.
+# Decree <a href="http://pcdsh01.on.br/HV91698.htm">91,698</a> (1985-09-27)
+Rule	Brazil	1985	only	-	Nov	 2	 0:00	1:00	S
+# Decree 92,310 (1986-01-21)
+# Decree 92,463 (1986-03-13)
+Rule	Brazil	1986	only	-	Mar	15	 0:00	0	-
+# Decree 93,316 (1986-10-01)
+Rule	Brazil	1986	only	-	Oct	25	 0:00	1:00	S
+Rule	Brazil	1987	only	-	Feb	14	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV94922.htm">94,922</a> (1987-09-22)
+Rule	Brazil	1987	only	-	Oct	25	 0:00	1:00	S
+Rule	Brazil	1988	only	-	Feb	 7	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV96676.htm">96,676</a> (1988-09-12)
+# except for the states of AC, AM, PA, RR, RO, and AP (then a territory)
+Rule	Brazil	1988	only	-	Oct	16	 0:00	1:00	S
+Rule	Brazil	1989	only	-	Jan	29	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV98077.htm">98,077</a> (1989-08-21)
+# with the same exceptions
+Rule	Brazil	1989	only	-	Oct	15	 0:00	1:00	S
+Rule	Brazil	1990	only	-	Feb	11	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV99530.htm">99,530</a> (1990-09-17)
+# adopted by RS, SC, PR, SP, RJ, ES, MG, GO, MS, DF.
+# Decree 99,629 (1990-10-19) adds BA, MT.
+Rule	Brazil	1990	only	-	Oct	21	 0:00	1:00	S
+Rule	Brazil	1991	only	-	Feb	17	 0:00	0	-
+# <a href="http://pcdsh01.on.br/HV1991.htm">Unnumbered decree</a> (1991-09-25)
+# adopted by RS, SC, PR, SP, RJ, ES, MG, BA, GO, MT, MS, DF.
+Rule	Brazil	1991	only	-	Oct	20	 0:00	1:00	S
+Rule	Brazil	1992	only	-	Feb	 9	 0:00	0	-
+# <a href="http://pcdsh01.on.br/HV1992.htm">Unnumbered decree</a> (1992-10-16)
+# adopted by same states.
+Rule	Brazil	1992	only	-	Oct	25	 0:00	1:00	S
+Rule	Brazil	1993	only	-	Jan	31	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV942.htm">942</a> (1993-09-28)
+# adopted by same states, plus AM.
+# Decree <a href="http://pcdsh01.on.br/HV1252.htm">1,252</a> (1994-09-22;
+# web page corrected 2004-01-07) adopted by same states, minus AM.
+# Decree <a href="http://pcdsh01.on.br/HV1636.htm">1,636</a> (1995-09-14)
+# adopted by same states, plus MT and TO.
+# Decree <a href="http://pcdsh01.on.br/HV1674.htm">1,674</a> (1995-10-13)
+# adds AL, SE.
+Rule	Brazil	1993	1995	-	Oct	Sun>=11	 0:00	1:00	S
+Rule	Brazil	1994	1995	-	Feb	Sun>=15	 0:00	0	-
+Rule	Brazil	1996	only	-	Feb	11	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/HV2000.htm">2,000</a> (1996-09-04)
+# adopted by same states, minus AL, SE.
+Rule	Brazil	1996	only	-	Oct	 6	 0:00	1:00	S
+Rule	Brazil	1997	only	-	Feb	16	 0:00	0	-
+# From Daniel C. Sobral (1998-02-12):
+# In 1997, the DS began on October 6. The stated reason was that
+# because international television networks ignored Brazil's policy on DS,
+# they bought the wrong times on satellite for coverage of Pope's visit.
+# This year, the ending date of DS was postponed to March 1
+# to help dealing with the shortages of electric power.
+#
+# Decree 2,317 (1997-09-04), adopted by same states.
+Rule	Brazil	1997	only	-	Oct	 6	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/figuras/HV2495.JPG">2,495</a>
+# (1998-02-10)
+Rule	Brazil	1998	only	-	Mar	 1	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/figuras/Hv98.jpg">2,780</a> (1998-09-11)
+# adopted by the same states as before.
+Rule	Brazil	1998	only	-	Oct	11	 0:00	1:00	S
+Rule	Brazil	1999	only	-	Feb	21	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/figuras/HV3150.gif">3,150</a>
+# (1999-08-23) adopted by same states.
+# Decree <a href="http://pcdsh01.on.br/DecHV99.gif">3,188</a> (1999-09-30)
+# adds SE, AL, PB, PE, RN, CE, PI, MA and RR.
+Rule	Brazil	1999	only	-	Oct	 3	 0:00	1:00	S
+Rule	Brazil	2000	only	-	Feb	27	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/DEC3592.htm">3,592</a> (2000-09-06)
+# adopted by the same states as before.
+# Decree <a href="http://pcdsh01.on.br/Dec3630.jpg">3,630</a> (2000-10-13)
+# repeals DST in PE and RR, effective 2000-10-15 00:00.
+# Decree <a href="http://pcdsh01.on.br/Dec3632.jpg">3,632</a> (2000-10-17)
+# repeals DST in SE, AL, PB, RN, CE, PI and MA, effective 2000-10-22 00:00.
+# Decree <a href="http://pcdsh01.on.br/figuras/HV3916.gif">3,916</a>
+# (2001-09-13) reestablishes DST in AL, CE, MA, PB, PE, PI, RN, SE.
+Rule	Brazil	2000	2001	-	Oct	Sun>=8	 0:00	1:00	S
+Rule	Brazil	2001	2006	-	Feb	Sun>=15	 0:00	0	-
+# Decree 4,399 (2002-10-01) repeals DST in AL, CE, MA, PB, PE, PI, RN, SE.
+# <a href="http://www.presidencia.gov.br/CCIVIL/decreto/2002/D4399.htm">4,399</a>
+Rule	Brazil	2002	only	-	Nov	 3	 0:00	1:00	S
+# Decree 4,844 (2003-09-24; corrected 2003-09-26) repeals DST in BA, MT, TO.
+# <a href="http://www.presidencia.gov.br/CCIVIL/decreto/2003/D4844.htm">4,844</a>
+Rule	Brazil	2003	only	-	Oct	19	 0:00	1:00	S
+# Decree 5,223 (2004-10-01) reestablishes DST in MT.
+# <a href="http://www.planalto.gov.br/ccivil_03/_Ato2004-2006/2004/Decreto/D5223.htm">5,223</a>
+Rule	Brazil	2004	only	-	Nov	 2	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/DecHV5539.gif">5,539</a> (2005-09-19),
+# adopted by the same states as before.
+Rule	Brazil	2005	only	-	Oct	16	 0:00	1:00	S
+# Decree <a href="http://pcdsh01.on.br/DecHV5920.gif">5,920</a> (2006-10-03),
+# adopted by the same states as before.
+Rule	Brazil	2006	only	-	Nov	 5	 0:00	1:00	S
+Rule	Brazil	2007	only	-	Feb	25	 0:00	0	-
+# Decree <a href="http://pcdsh01.on.br/DecHV6212.gif">6,212</a> (2007-09-26),
+# adopted by the same states as before.
+Rule	Brazil	2007	only	-	Oct	Sun>=8	 0:00	1:00	S
+# From Frederico A. C. Neves (2008-09-10):
+# Acording to this decree
+# <a href="http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm">
+# http://www.planalto.gov.br/ccivil_03/_Ato2007-2010/2008/Decreto/D6558.htm
+# </a>
+# [t]he DST period in Brazil now on will be from the 3rd Oct Sunday to the
+# 3rd Feb Sunday. There is an exception on the return date when this is
+# the Carnival Sunday then the return date will be the next Sunday...
+Rule	Brazil	2008	max	-	Oct	Sun>=15	0:00	1:00	S
+Rule	Brazil	2008	2011	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2012	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2013	2014	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2015	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2016	2022	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2023	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2024	2025	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2026	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2027	2033	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2034	only	-	Feb	Sun>=22	0:00	0	-
+Rule	Brazil	2035	2036	-	Feb	Sun>=15	0:00	0	-
+Rule	Brazil	2037	only	-	Feb	Sun>=22	0:00	0	-
+# From Arthur David Olson (2008-09-29):
+# The next is wrong in some years but is better than nothing.
+Rule	Brazil	2038	max	-	Feb	Sun>=15	0:00	0	-
+
+# The latest ruleset listed above says that the following states observe DST:
+# DF, ES, GO, MG, MS, MT, PR, RJ, RS, SC, SP.
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+#
+# Fernando de Noronha (administratively part of PE)
+Zone America/Noronha	-2:09:40 -	LMT	1914
+			-2:00	Brazil	FN%sT	1990 Sep 17
+			-2:00	-	FNT	1999 Sep 30
+			-2:00	Brazil	FN%sT	2000 Oct 15
+			-2:00	-	FNT	2001 Sep 13
+			-2:00	Brazil	FN%sT	2002 Oct  1
+			-2:00	-	FNT
+# Other Atlantic islands have no permanent settlement.
+# These include Trindade and Martin Vaz (administratively part of ES),
+# Atol das Rocas (RN), and Penedos de Sao Pedro e Sao Paulo (PE).
+# Fernando de Noronha was a separate territory from 1942-09-02 to 1989-01-01;
+# it also included the Penedos.
+#
+# Amapa (AP), east Para (PA)
+# East Para includes Belem, Maraba, Serra Norte, and Sao Felix do Xingu.
+# The division between east and west Para is the river Xingu.
+# In the north a very small part from the river Javary (now Jari I guess,
+# the border with Amapa) to the Amazon, then to the Xingu.
+Zone America/Belem	-3:13:56 -	LMT	1914
+			-3:00	Brazil	BR%sT	1988 Sep 12
+			-3:00	-	BRT
+#
+# west Para (PA)
+# West Para includes Altamira, Oribidos, Prainha, Oriximina, and Santarem.
+Zone America/Santarem	-3:38:48 -	LMT	1914
+			-4:00	Brazil	AM%sT	1988 Sep 12
+			-4:00	-	AMT	2008 Jun 24 00:00
+			-3:00	-	BRT
+#
+# Maranhao (MA), Piaui (PI), Ceara (CE), Rio Grande do Norte (RN),
+# Paraiba (PB)
+Zone America/Fortaleza	-2:34:00 -	LMT	1914
+			-3:00	Brazil	BR%sT	1990 Sep 17
+			-3:00	-	BRT	1999 Sep 30
+			-3:00	Brazil	BR%sT	2000 Oct 22
+			-3:00	-	BRT	2001 Sep 13
+			-3:00	Brazil	BR%sT	2002 Oct  1
+			-3:00	-	BRT
+#
+# Pernambuco (PE) (except Atlantic islands)
+Zone America/Recife	-2:19:36 -	LMT	1914
+			-3:00	Brazil	BR%sT	1990 Sep 17
+			-3:00	-	BRT	1999 Sep 30
+			-3:00	Brazil	BR%sT	2000 Oct 15
+			-3:00	-	BRT	2001 Sep 13
+			-3:00	Brazil	BR%sT	2002 Oct  1
+			-3:00	-	BRT
+#
+# Tocantins (TO)
+Zone America/Araguaina	-3:12:48 -	LMT	1914
+			-3:00	Brazil	BR%sT	1990 Sep 17
+			-3:00	-	BRT	1995 Sep 14
+			-3:00	Brazil	BR%sT	2003 Sep 24
+			-3:00	-	BRT
+#
+# Alagoas (AL), Sergipe (SE)
+Zone America/Maceio	-2:22:52 -	LMT	1914
+			-3:00	Brazil	BR%sT	1990 Sep 17
+			-3:00	-	BRT	1995 Oct 13
+			-3:00	Brazil	BR%sT	1996 Sep  4
+			-3:00	-	BRT	1999 Sep 30
+			-3:00	Brazil	BR%sT	2000 Oct 22
+			-3:00	-	BRT	2001 Sep 13
+			-3:00	Brazil	BR%sT	2002 Oct  1
+			-3:00	-	BRT
+#
+# Bahia (BA)
+# There are too many Salvadors elsewhere, so use America/Bahia instead
+# of America/Salvador.
+Zone America/Bahia	-2:34:04 -	LMT	1914
+			-3:00	Brazil	BR%sT	2003 Sep 24
+			-3:00	-	BRT
+#
+# Goias (GO), Distrito Federal (DF), Minas Gerais (MG),
+# Espirito Santo (ES), Rio de Janeiro (RJ), Sao Paulo (SP), Parana (PR),
+# Santa Catarina (SC), Rio Grande do Sul (RS)
+Zone America/Sao_Paulo	-3:06:28 -	LMT	1914
+			-3:00	Brazil	BR%sT	1963 Oct 23 00:00
+			-3:00	1:00	BRST	1964
+			-3:00	Brazil	BR%sT
+#
+# Mato Grosso do Sul (MS)
+Zone America/Campo_Grande -3:38:28 -	LMT	1914
+			-4:00	Brazil	AM%sT
+#
+# Mato Grosso (MT)
+Zone America/Cuiaba	-3:44:20 -	LMT	1914
+			-4:00	Brazil	AM%sT	2003 Sep 24
+			-4:00	-	AMT	2004 Oct  1
+			-4:00	Brazil	AM%sT
+#
+# Rondonia (RO)
+Zone America/Porto_Velho -4:15:36 -	LMT	1914
+			-4:00	Brazil	AM%sT	1988 Sep 12
+			-4:00	-	AMT
+#
+# Roraima (RR)
+Zone America/Boa_Vista	-4:02:40 -	LMT	1914
+			-4:00	Brazil	AM%sT	1988 Sep 12
+			-4:00	-	AMT	1999 Sep 30
+			-4:00	Brazil	AM%sT	2000 Oct 15
+			-4:00	-	AMT
+#
+# east Amazonas (AM): Boca do Acre, Jutai, Manaus, Floriano Peixoto
+# The great circle line from Tabatinga to Porto Acre divides
+# east from west Amazonas.
+Zone America/Manaus	-4:00:04 -	LMT	1914
+			-4:00	Brazil	AM%sT	1988 Sep 12
+			-4:00	-	AMT	1993 Sep 28
+			-4:00	Brazil	AM%sT	1994 Sep 22
+			-4:00	-	AMT
+#
+# west Amazonas (AM): Atalaia do Norte, Boca do Maoco, Benjamin Constant,
+#	Eirunepe, Envira, Ipixuna
+Zone America/Eirunepe	-4:39:28 -	LMT	1914
+			-5:00	Brazil	AC%sT	1988 Sep 12
+			-5:00	-	ACT	1993 Sep 28
+			-5:00	Brazil	AC%sT	1994 Sep 22
+			-5:00	-	ACT	2008 Jun 24 00:00
+			-4:00	-	AMT
+#
+# Acre (AC)
+Zone America/Rio_Branco	-4:31:12 -	LMT	1914
+			-5:00	Brazil	AC%sT	1988 Sep 12
+			-5:00	-	ACT	2008 Jun 24 00:00
+			-4:00	-	AMT
+
+# Chile
+
+# From Eduardo Krell (1995-10-19):
+# The law says to switch to DST at midnight [24:00] on the second SATURDAY
+# of October....  The law is the same for March and October.
+# (1998-09-29):
+# Because of the drought this year, the government decided to go into
+# DST earlier (saturday 9/26 at 24:00). This is a one-time change only ...
+# (unless there's another dry season next year, I guess).
+
+# From Julio I. Pacheco Troncoso (1999-03-18):
+# Because of the same drought, the government decided to end DST later,
+# on April 3, (one-time change).
+
+# From Oscar van Vlijmen (2006-10-08):
+# http://www.horaoficial.cl/cambio.htm
+
+# From Jesper Norgaard Welen (2006-10-08):
+# I think that there are some obvious mistakes in the suggested link
+# from Oscar van Vlijmen,... for instance entry 66 says that GMT-4
+# ended 1990-09-12 while entry 67 only begins GMT-3 at 1990-09-15
+# (they should have been 1990-09-15 and 1990-09-16 respectively), but
+# anyhow it clears up some doubts too.
+
+# From Paul Eggert (2006-12-27):
+# The following data for Chile and America/Santiago are from
+# <http://www.horaoficial.cl/horaof.htm> (2006-09-20), transcribed by
+# Jesper Norgaard Welen.  The data for Pacific/Easter are from Shanks
+# & Pottenger, except with DST transitions after 1932 cloned from
+# America/Santiago.  The pre-1980 Pacific/Easter data are dubious,
+# but we have no other source.
+
+# From German Poo-Caaman~o (2008-03-03):
+# Due to drought, Chile extends Daylight Time in three weeks.  This
+# is one-time change (Saturday 3/29 at 24:00 for America/Santiago
+# and Saturday 3/29 at 22:00 for Pacific/Easter)
+# The Supreme Decree is located at 
+# <a href="http://www.shoa.cl/servicios/supremo316.pdf">
+# http://www.shoa.cl/servicios/supremo316.pdf
+# </a>
+# and the instructions for 2008 are located in:
+# <a href="http://www.horaoficial.cl/cambio.htm">
+# http://www.horaoficial.cl/cambio.htm
+# </a>.
+
+# From Jose Miguel Garrido (2008-03-05):
+# ...
+# You could see the announces of the change on 
+# <a href="http://www.shoa.cl/noticias/2008/04hora/hora.htm">
+# http://www.shoa.cl/noticias/2008/04hora/hora.htm
+# </a>.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Chile	1927	1932	-	Sep	 1	0:00	1:00	S
+Rule	Chile	1928	1932	-	Apr	 1	0:00	0	-
+Rule	Chile	1942	only	-	Jun	 1	4:00u	0	-
+Rule	Chile	1942	only	-	Aug	 1	5:00u	1:00	S
+Rule	Chile	1946	only	-	Jul	15	4:00u	1:00	S
+Rule	Chile	1946	only	-	Sep	 1	3:00u	0:00	-
+Rule	Chile	1947	only	-	Apr	 1	4:00u	0	-
+Rule	Chile	1968	only	-	Nov	 3	4:00u	1:00	S
+Rule	Chile	1969	only	-	Mar	30	3:00u	0	-
+Rule	Chile	1969	only	-	Nov	23	4:00u	1:00	S
+Rule	Chile	1970	only	-	Mar	29	3:00u	0	-
+Rule	Chile	1971	only	-	Mar	14	3:00u	0	-
+Rule	Chile	1970	1972	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	Chile	1972	1986	-	Mar	Sun>=9	3:00u	0	-
+Rule	Chile	1973	only	-	Sep	30	4:00u	1:00	S
+Rule	Chile	1974	1987	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	Chile	1987	only	-	Apr	12	3:00u	0	-
+Rule	Chile	1988	1989	-	Mar	Sun>=9	3:00u	0	-
+Rule	Chile	1988	only	-	Oct	Sun>=1	4:00u	1:00	S
+Rule	Chile	1989	only	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	Chile	1990	only	-	Mar	18	3:00u	0	-
+Rule	Chile	1990	only	-	Sep	16	4:00u	1:00	S
+Rule	Chile	1991	1996	-	Mar	Sun>=9	3:00u	0	-
+Rule	Chile	1991	1997	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	Chile	1997	only	-	Mar	30	3:00u	0	-
+Rule	Chile	1998	only	-	Mar	Sun>=9	3:00u	0	-
+Rule	Chile	1998	only	-	Sep	27	4:00u	1:00	S
+Rule	Chile	1999	only	-	Apr	 4	3:00u	0	-
+Rule	Chile	1999	max	-	Oct	Sun>=9	4:00u	1:00	S
+Rule	Chile	2000	2007	-	Mar	Sun>=9	3:00u	0	-
+# N.B.: the end of March 29 in Chile is March 30 in Universal time,
+# which is used below in specifying the transition.
+Rule	Chile	2008	only	-	Mar	30	3:00u	0	-
+Rule	Chile	2009	max	-	Mar	Sun>=9	3:00u	0	-
+# IATA SSIM anomalies: (1992-02) says 1992-03-14;
+# (1996-09) says 1998-03-08.  Ignore these.
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Santiago	-4:42:46 -	LMT	1890
+			-4:42:46 -	SMT	1910 	    # Santiago Mean Time
+			-5:00	-	CLT	1916 Jul  1 # Chile Time
+			-4:42:46 -	SMT	1918 Sep  1 # Santiago Mean Time
+			-4:00	-	CLT	1919 Jul  1 # Chile Time
+			-4:42:46 -	SMT	1927 Sep  1 # Santiago Mean Time
+			-5:00	Chile	CL%sT	1947 May 22 # Chile Time
+			-4:00	Chile	CL%sT
+Zone Pacific/Easter	-7:17:44 -	LMT	1890
+			-7:17:28 -	EMT	1932 Sep    # Easter Mean Time
+			-7:00	Chile	EAS%sT	1982 Mar 13 21:00 # Easter I Time
+			-6:00	Chile	EAS%sT
+#
+# Sala y Gomez Island is like Pacific/Easter.
+# Other Chilean locations, including Juan Fernandez Is, San Ambrosio,
+# San Felix, and Antarctic bases, are like America/Santiago.
+
+# Colombia
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	CO	1992	only	-	May	 3	0:00	1:00	S
+Rule	CO	1993	only	-	Apr	 4	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Bogota	-4:56:20 -	LMT	1884 Mar 13
+			-4:56:20 -	BMT	1914 Nov 23 # Bogota Mean Time
+			-5:00	CO	CO%sT	# Colombia Time
+# Malpelo, Providencia, San Andres
+# no information; probably like America/Bogota
+
+# Curacao
+#
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger say that The Bottom and Philipsburg have been at
+# -4:00 since standard time was introduced on 1912-03-02; and that
+# Kralendijk and Rincon used Kralendijk Mean Time (-4:33:08) from
+# 1912-02-02 to 1965-01-01.  The former is dubious, since S&P also say
+# Saba Island has been like Curacao.
+# This all predates our 1970 cutoff, though.
+#
+# By July 2007 Curacao and St Maarten are planned to become
+# associated states within the Netherlands, much like Aruba;
+# Bonaire, Saba and St Eustatius would become directly part of the
+# Netherlands as Kingdom Islands.  This won't affect their time zones
+# though, as far as we know.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Curacao	-4:35:44 -	LMT	1912 Feb 12	# Willemstad
+			-4:30	-	ANT	1965 # Netherlands Antilles Time
+			-4:00	-	AST
+
+# Ecuador
+#
+# From Paul Eggert (2007-03-04):
+# Apparently Ecuador had a failed experiment with DST in 1992.
+# <http://midena.gov.ec/content/view/1261/208/> (2007-02-27) and
+# <http://www.hoy.com.ec/NoticiaNue.asp?row_id=249856> (2006-11-06) both
+# talk about "hora Sixto".  Leave this alone for now, as we have no data.
+#
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Guayaquil	-5:19:20 -	LMT	1890
+			-5:14:00 -	QMT	1931 # Quito Mean Time
+			-5:00	-	ECT	     # Ecuador Time
+Zone Pacific/Galapagos	-5:58:24 -	LMT	1931 # Puerto Baquerizo Moreno
+			-5:00	-	ECT	1986
+			-6:00	-	GALT	     # Galapagos Time
+
+# Falklands
+
+# From Paul Eggert (2006-03-22):
+# Between 1990 and 2000 inclusive, Shanks & Pottenger and the IATA agree except
+# the IATA gives 1996-09-08.  Go with Shanks & Pottenger.
+
+# From Falkland Islands Government Office, London (2001-01-22)
+# via Jesper Norgaard:
+# ... the clocks revert back to Local Mean Time at 2 am on Sunday 15
+# April 2001 and advance one hour to summer time at 2 am on Sunday 2
+# September.  It is anticipated that the clocks will revert back at 2
+# am on Sunday 21 April 2002 and advance to summer time at 2 am on
+# Sunday 1 September.
+
+# From Rives McDow (2001-02-13):
+#
+# I have communicated several times with people there, and the last
+# time I had communications that was helpful was in 1998.  Here is
+# what was said then:
+#
+# "The general rule was that Stanley used daylight saving and the Camp
+# did not. However for various reasons many people in the Camp have
+# started to use daylight saving (known locally as 'Stanley Time')
+# There is no rule as to who uses daylight saving - it is a matter of
+# personal choice and so it is impossible to draw a map showing who
+# uses it and who does not. Any list would be out of date as soon as
+# it was produced. This year daylight saving ended on April 18/19th
+# and started again on September 12/13th.  I do not know what the rule
+# is, but can find out if you like.  We do not change at the same time
+# as UK or Chile."
+#
+# I did have in my notes that the rule was "Second Saturday in Sep at
+# 0:00 until third Saturday in Apr at 0:00".  I think that this does
+# not agree in some cases with Shanks; is this true?
+#
+# Also, there is no mention in the list that some areas in the
+# Falklands do not use DST.  I have found in my communications there
+# that these areas are on the western half of East Falkland and all of
+# West Falkland.  Stanley is the only place that consistently observes
+# DST.  Again, as in other places in the world, the farmers don't like
+# it.  West Falkland is almost entirely sheep farmers.
+#
+# I know one lady there that keeps a list of which farm keeps DST and
+# which doesn't each year.  She runs a shop in Stanley, and says that
+# the list changes each year.  She uses it to communicate to her
+# customers, catching them when they are home for lunch or dinner.
+
+# From Paul Eggert (2001-03-05):
+# For now, we'll just record the time in Stanley, since we have no
+# better info.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Falk	1937	1938	-	Sep	lastSun	0:00	1:00	S
+Rule	Falk	1938	1942	-	Mar	Sun>=19	0:00	0	-
+Rule	Falk	1939	only	-	Oct	1	0:00	1:00	S
+Rule	Falk	1940	1942	-	Sep	lastSun	0:00	1:00	S
+Rule	Falk	1943	only	-	Jan	1	0:00	0	-
+Rule	Falk	1983	only	-	Sep	lastSun	0:00	1:00	S
+Rule	Falk	1984	1985	-	Apr	lastSun	0:00	0	-
+Rule	Falk	1984	only	-	Sep	16	0:00	1:00	S
+Rule	Falk	1985	2000	-	Sep	Sun>=9	0:00	1:00	S
+Rule	Falk	1986	2000	-	Apr	Sun>=16	0:00	0	-
+Rule	Falk	2001	max	-	Apr	Sun>=15	2:00	0	-
+Rule	Falk	2001	max	-	Sep	Sun>=1	2:00	1:00	S
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Atlantic/Stanley	-3:51:24 -	LMT	1890
+			-3:51:24 -	SMT	1912 Mar 12  # Stanley Mean Time
+			-4:00	Falk	FK%sT	1983 May     # Falkland Is Time
+			-3:00	Falk	FK%sT	1985 Sep 15
+			-4:00	Falk	FK%sT
+
+# French Guiana
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Cayenne	-3:29:20 -	LMT	1911 Jul
+			-4:00	-	GFT	1967 Oct # French Guiana Time
+			-3:00	-	GFT
+
+# Guyana
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Guyana	-3:52:40 -	LMT	1915 Mar	# Georgetown
+			-3:45	-	GBGT	1966 May 26 # Br Guiana Time
+			-3:45	-	GYT	1975 Jul 31 # Guyana Time
+			-3:00	-	GYT	1991
+# IATA SSIM (1996-06) says -4:00.  Assume a 1991 switch.
+			-4:00	-	GYT
+
+# Paraguay
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger say that spring transitions are from 01:00 -> 02:00,
+# and autumn transitions are from 00:00 -> 23:00.  Go with pre-1999
+# editions of Shanks, and with the IATA, who say transitions occur at 00:00.
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Para	1975	1988	-	Oct	 1	0:00	1:00	S
+Rule	Para	1975	1978	-	Mar	 1	0:00	0	-
+Rule	Para	1979	1991	-	Apr	 1	0:00	0	-
+Rule	Para	1989	only	-	Oct	22	0:00	1:00	S
+Rule	Para	1990	only	-	Oct	 1	0:00	1:00	S
+Rule	Para	1991	only	-	Oct	 6	0:00	1:00	S
+Rule	Para	1992	only	-	Mar	 1	0:00	0	-
+Rule	Para	1992	only	-	Oct	 5	0:00	1:00	S
+Rule	Para	1993	only	-	Mar	31	0:00	0	-
+Rule	Para	1993	1995	-	Oct	 1	0:00	1:00	S
+Rule	Para	1994	1995	-	Feb	lastSun	0:00	0	-
+Rule	Para	1996	only	-	Mar	 1	0:00	0	-
+# IATA SSIM (2000-02) says 1999-10-10; ignore this for now.
+# From Steffen Thorsen (2000-10-02):
+# I have three independent reports that Paraguay changed to DST this Sunday
+# (10-01).
+#
+# Translated by Gwillim Law (2001-02-27) from
+# <a href="http://www.diarionoticias.com.py/011000/nacional/naciona1.htm">
+# Noticias, a daily paper in Asuncion, Paraguay (2000-10-01)
+# </a>:
+# Starting at 0:00 today, the clock will be set forward 60 minutes, in
+# fulfillment of Decree No. 7,273 of the Executive Power....  The time change
+# system has been operating for several years.  Formerly there was a separate
+# decree each year; the new law has the same effect, but permanently.  Every
+# year, the time will change on the first Sunday of October; likewise, the
+# clock will be set back on the first Sunday of March.
+#
+Rule	Para	1996	2001	-	Oct	Sun>=1	0:00	1:00	S
+# IATA SSIM (1997-09) says Mar 1; go with Shanks & Pottenger.
+Rule	Para	1997	only	-	Feb	lastSun	0:00	0	-
+# Shanks & Pottenger say 1999-02-28; IATA SSIM (1999-02) says 1999-02-27, but
+# (1999-09) reports no date; go with above sources and Gerd Knops (2001-02-27).
+Rule	Para	1998	2001	-	Mar	Sun>=1	0:00	0	-
+# From Rives McDow (2002-02-28):
+# A decree was issued in Paraguay (no. 16350) on 2002-02-26 that changed the
+# dst method to be from the first Sunday in September to the first Sunday in
+# April.
+Rule	Para	2002	2004	-	Apr	Sun>=1	0:00	0	-
+Rule	Para	2002	2003	-	Sep	Sun>=1	0:00	1:00	S
+#
+# From Jesper Norgaard Welen (2005-01-02):
+# There are several sources that claim that Paraguay made
+# a timezone rule change in autumn 2004.
+# From Steffen Thorsen (2005-01-05):
+# Decree 1,867 (2004-03-05)
+# From Carlos Raul Perasso via Jesper Norgaard Welen (2006-10-13)
+# <http://www.presidencia.gov.py/decretos/D1867.pdf>
+Rule	Para	2004	max	-	Oct	Sun>=15	0:00	1:00	S
+Rule	Para	2005	max	-	Mar	Sun>=8	0:00	0	-
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Asuncion	-3:50:40 -	LMT	1890
+			-3:50:40 -	AMT	1931 Oct 10 # Asuncion Mean Time
+			-4:00	-	PYT	1972 Oct # Paraguay Time
+			-3:00	-	PYT	1974 Apr
+			-4:00	Para	PY%sT
+
+# Peru
+#
+# <a href="news:xrGmb.39935$gA1.13896113@news4.srv.hcvlny.cv.net">
+# From Evelyn C. Leeper via Mark Brader (2003-10-26):</a>
+# When we were in Peru in 1985-1986, they apparently switched over
+# sometime between December 29 and January 3 while we were on the Amazon.
+#
+# From Paul Eggert (2006-03-22):
+# Shanks & Pottenger don't have this transition.  Assume 1986 was like 1987.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	Peru	1938	only	-	Jan	 1	0:00	1:00	S
+Rule	Peru	1938	only	-	Apr	 1	0:00	0	-
+Rule	Peru	1938	1939	-	Sep	lastSun	0:00	1:00	S
+Rule	Peru	1939	1940	-	Mar	Sun>=24	0:00	0	-
+Rule	Peru	1986	1987	-	Jan	 1	0:00	1:00	S
+Rule	Peru	1986	1987	-	Apr	 1	0:00	0	-
+Rule	Peru	1990	only	-	Jan	 1	0:00	1:00	S
+Rule	Peru	1990	only	-	Apr	 1	0:00	0	-
+# IATA is ambiguous for 1993/1995; go with Shanks & Pottenger.
+Rule	Peru	1994	only	-	Jan	 1	0:00	1:00	S
+Rule	Peru	1994	only	-	Apr	 1	0:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Lima	-5:08:12 -	LMT	1890
+			-5:08:36 -	LMT	1908 Jul 28 # Lima Mean Time?
+			-5:00	Peru	PE%sT	# Peru Time
+
+# South Georgia
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone Atlantic/South_Georgia -2:26:08 -	LMT	1890		# Grytviken
+			-2:00	-	GST	# South Georgia Time
+
+# South Sandwich Is
+# uninhabited; scientific personnel have wintered
+
+# Suriname
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Paramaribo	-3:40:40 -	LMT	1911
+			-3:40:52 -	PMT	1935     # Paramaribo Mean Time
+			-3:40:36 -	PMT	1945 Oct # The capital moved?
+			-3:30	-	NEGT	1975 Nov 20 # Dutch Guiana Time
+			-3:30	-	SRT	1984 Oct # Suriname Time
+			-3:00	-	SRT
+
+# Trinidad and Tobago
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Port_of_Spain -4:06:04 -	LMT	1912 Mar 2
+			-4:00	-	AST
+
+# Uruguay
+# From Paul Eggert (1993-11-18):
+# Uruguay wins the prize for the strangest peacetime manipulation of the rules.
+# From Shanks & Pottenger:
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+# Whitman gives 1923 Oct 1; go with Shanks & Pottenger.
+Rule	Uruguay	1923	only	-	Oct	 2	 0:00	0:30	HS
+Rule	Uruguay	1924	1926	-	Apr	 1	 0:00	0	-
+Rule	Uruguay	1924	1925	-	Oct	 1	 0:00	0:30	HS
+Rule	Uruguay	1933	1935	-	Oct	lastSun	 0:00	0:30	HS
+# Shanks & Pottenger give 1935 Apr 1 0:00 & 1936 Mar 30 0:00; go with Whitman.
+Rule	Uruguay	1934	1936	-	Mar	Sat>=25	23:30s	0	-
+Rule	Uruguay	1936	only	-	Nov	 1	 0:00	0:30	HS
+Rule	Uruguay	1937	1941	-	Mar	lastSun	 0:00	0	-
+# Whitman gives 1937 Oct 3; go with Shanks & Pottenger.
+Rule	Uruguay	1937	1940	-	Oct	lastSun	 0:00	0:30	HS
+# Whitman gives 1941 Oct 24 - 1942 Mar 27, 1942 Dec 14 - 1943 Apr 13,
+# and 1943 Apr 13 ``to present time''; go with Shanks & Pottenger.
+Rule	Uruguay	1941	only	-	Aug	 1	 0:00	0:30	HS
+Rule	Uruguay	1942	only	-	Jan	 1	 0:00	0	-
+Rule	Uruguay	1942	only	-	Dec	14	 0:00	1:00	S
+Rule	Uruguay	1943	only	-	Mar	14	 0:00	0	-
+Rule	Uruguay	1959	only	-	May	24	 0:00	1:00	S
+Rule	Uruguay	1959	only	-	Nov	15	 0:00	0	-
+Rule	Uruguay	1960	only	-	Jan	17	 0:00	1:00	S
+Rule	Uruguay	1960	only	-	Mar	 6	 0:00	0	-
+Rule	Uruguay	1965	1967	-	Apr	Sun>=1	 0:00	1:00	S
+Rule	Uruguay	1965	only	-	Sep	26	 0:00	0	-
+Rule	Uruguay	1966	1967	-	Oct	31	 0:00	0	-
+Rule	Uruguay	1968	1970	-	May	27	 0:00	0:30	HS
+Rule	Uruguay	1968	1970	-	Dec	 2	 0:00	0	-
+Rule	Uruguay	1972	only	-	Apr	24	 0:00	1:00	S
+Rule	Uruguay	1972	only	-	Aug	15	 0:00	0	-
+Rule	Uruguay	1974	only	-	Mar	10	 0:00	0:30	HS
+Rule	Uruguay	1974	only	-	Dec	22	 0:00	1:00	S
+Rule	Uruguay	1976	only	-	Oct	 1	 0:00	0	-
+Rule	Uruguay	1977	only	-	Dec	 4	 0:00	1:00	S
+Rule	Uruguay	1978	only	-	Apr	 1	 0:00	0	-
+Rule	Uruguay	1979	only	-	Oct	 1	 0:00	1:00	S
+Rule	Uruguay	1980	only	-	May	 1	 0:00	0	-
+Rule	Uruguay	1987	only	-	Dec	14	 0:00	1:00	S
+Rule	Uruguay	1988	only	-	Mar	14	 0:00	0	-
+Rule	Uruguay	1988	only	-	Dec	11	 0:00	1:00	S
+Rule	Uruguay	1989	only	-	Mar	12	 0:00	0	-
+Rule	Uruguay	1989	only	-	Oct	29	 0:00	1:00	S
+# Shanks & Pottenger say no DST was observed in 1990/1 and 1991/2,
+# and that 1992/3's DST was from 10-25 to 03-01.  Go with IATA.
+Rule	Uruguay	1990	1992	-	Mar	Sun>=1	 0:00	0	-
+Rule	Uruguay	1990	1991	-	Oct	Sun>=21	 0:00	1:00	S
+Rule	Uruguay	1992	only	-	Oct	18	 0:00	1:00	S
+Rule	Uruguay	1993	only	-	Feb	28	 0:00	0	-
+# From Eduardo Cota (2004-09-20):
+# The uruguayan government has decreed a change in the local time....
+# http://www.presidencia.gub.uy/decretos/2004091502.htm
+Rule	Uruguay	2004	only	-	Sep	19	 0:00	1:00	S
+# From Steffen Thorsen (2005-03-11):
+# Uruguay's DST was scheduled to end on Sunday, 2005-03-13, but in order to
+# save energy ... it was postponed two weeks....
+# http://www.presidencia.gub.uy/_Web/noticias/2005/03/2005031005.htm
+Rule	Uruguay	2005	only	-	Mar	27	 2:00	0	-
+# From Eduardo Cota (2005-09-27):
+# http://www.presidencia.gub.uy/_Web/decretos/2005/09/CM%20119_09%2009%202005_00001.PDF
+# This means that from 2005-10-09 at 02:00 local time, until 2006-03-12 at
+# 02:00 local time, official time in Uruguay will be at GMT -2.
+Rule	Uruguay	2005	only	-	Oct	 9	 2:00	1:00	S
+Rule	Uruguay	2006	only	-	Mar	12	 2:00	0	-
+# From Jesper Norgaard Welen (2006-09-06):
+# http://www.presidencia.gub.uy/_web/decretos/2006/09/CM%20210_08%2006%202006_00001.PDF
+Rule	Uruguay	2006	max	-	Oct	Sun>=1	 2:00	1:00	S
+Rule	Uruguay	2007	max	-	Mar	Sun>=8	 2:00	0	-
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone America/Montevideo	-3:44:44 -	LMT	1898 Jun 28
+			-3:44:44 -	MMT	1920 May  1	# Montevideo MT
+			-3:30	Uruguay	UY%sT	1942 Dec 14	# Uruguay Time
+			-3:00	Uruguay	UY%sT
+
+# Venezuela
+#
+# From John Stainforth (2007-11-28):
+# ... the change for Venezuela originally expected for 2007-12-31 has
+# been brought forward to 2007-12-09.  The official announcement was
+# published today in the "Gaceta Oficial de la Republica Bolivariana
+# de Venezuela, numero 38.819" (official document for all laws or
+# resolution publication)
+# http://www.globovision.com/news.php?nid=72208
+
+# Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
+Zone	America/Caracas	-4:27:44 -	LMT	1890
+			-4:27:40 -	CMT	1912 Feb 12 # Caracas Mean Time?
+			-4:30	-	VET	1965	     # Venezuela Time
+			-4:00	-	VET	2007 Dec  9 03:00
+			-4:30	-	VET
diff --git a/tools/zoneinfo/tzdata2008h/systemv b/tools/zoneinfo/tzdata2008h/systemv
new file mode 100644
index 0000000..6cf9645
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/systemv
@@ -0,0 +1,36 @@
+# @(#)systemv	8.1
+
+# Old rules, should the need arise.
+# No attempt is made to handle Newfoundland, since it cannot be expressed
+# using the System V "TZ" scheme (half-hour offset), or anything outside
+# North America (no support for non-standard DST start/end dates), nor
+# the changes in the DST rules in the US after 1976 (which occurred after
+# the old rules were written).
+#
+# If you need the old rules, uncomment ## lines.
+# Compile this *without* leap second correction for true conformance.
+
+# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
+Rule	SystemV	min	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	SystemV	min	1973	-	Oct	lastSun	2:00	0	S
+Rule	SystemV	1974	only	-	Jan	6	2:00	1:00	D
+Rule	SystemV	1974	only	-	Nov	lastSun	2:00	0	S
+Rule	SystemV	1975	only	-	Feb	23	2:00	1:00	D
+Rule	SystemV	1975	only	-	Oct	lastSun	2:00	0	S
+Rule	SystemV	1976	max	-	Apr	lastSun	2:00	1:00	D
+Rule	SystemV	1976	max	-	Oct	lastSun	2:00	0	S
+
+# Zone	NAME		GMTOFF	RULES/SAVE	FORMAT	[UNTIL]
+## Zone	SystemV/AST4ADT	-4:00	SystemV		A%sT
+## Zone	SystemV/EST5EDT	-5:00	SystemV		E%sT
+## Zone	SystemV/CST6CDT	-6:00	SystemV		C%sT
+## Zone	SystemV/MST7MDT	-7:00	SystemV		M%sT
+## Zone	SystemV/PST8PDT	-8:00	SystemV		P%sT
+## Zone	SystemV/YST9YDT	-9:00	SystemV		Y%sT
+## Zone	SystemV/AST4	-4:00	-		AST
+## Zone	SystemV/EST5	-5:00	-		EST
+## Zone	SystemV/CST6	-6:00	-		CST
+## Zone	SystemV/MST7	-7:00	-		MST
+## Zone	SystemV/PST8	-8:00	-		PST
+## Zone	SystemV/YST9	-9:00	-		YST
+## Zone	SystemV/HST10	-10:00	-		HST
diff --git a/tools/zoneinfo/tzdata2008h/yearistype.sh b/tools/zoneinfo/tzdata2008h/yearistype.sh
new file mode 100644
index 0000000..66dbf89
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/yearistype.sh
@@ -0,0 +1,40 @@
+#! /bin/sh
+
+: 'This file is in the public domain, so clarified as of'
+: '2006-07-17 by Arthur David Olson.'
+
+: '@(#)yearistype.sh	8.2'
+
+case $#-$1 in
+	2-|2-0*|2-*[!0-9]*)
+		echo "$0: wild year - $1" >&2
+		exit 1 ;;
+esac
+
+case $#-$2 in
+	2-even)
+		case $1 in
+			*[24680])			exit 0 ;;
+			*)				exit 1 ;;
+		esac ;;
+	2-nonpres|2-nonuspres)
+		case $1 in
+			*[02468][048]|*[13579][26])	exit 1 ;;
+			*)				exit 0 ;;
+		esac ;;
+	2-odd)
+		case $1 in
+			*[13579])			exit 0 ;;
+			*)				exit 1 ;;
+		esac ;;
+	2-uspres)
+		case $1 in
+			*[02468][048]|*[13579][26])	exit 0 ;;
+			*)				exit 1 ;;
+		esac ;;
+	2-*)
+		echo "$0: wild type - $2" >&2 ;;
+esac
+
+echo "$0: usage is $0 year even|odd|uspres|nonpres|nonuspres" >&2
+exit 1
diff --git a/tools/zoneinfo/tzdata2008h/zone.tab b/tools/zoneinfo/tzdata2008h/zone.tab
new file mode 100644
index 0000000..ca9c76b
--- /dev/null
+++ b/tools/zoneinfo/tzdata2008h/zone.tab
@@ -0,0 +1,424 @@
+# @(#)zone.tab	8.19
+#
+# TZ zone descriptions
+#
+# From Paul Eggert (1996-08-05):
+#
+# This file contains a table with the following columns:
+# 1.  ISO 3166 2-character country code.  See the file `iso3166.tab'.
+# 2.  Latitude and longitude of the zone's principal location
+#     in ISO 6709 sign-degrees-minutes-seconds format,
+#     either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS,
+#     first latitude (+ is north), then longitude (+ is east).
+# 3.  Zone name used in value of TZ environment variable.
+# 4.  Comments; present if and only if the country has multiple rows.
+#
+# Columns are separated by a single tab.
+# The table is sorted first by country, then an order within the country that
+# (1) makes some geographical sense, and
+# (2) puts the most populous zones first, where that does not contradict (1).
+#
+# Lines beginning with `#' are comments.
+#
+#country-
+#code	coordinates	TZ			comments
+AD	+4230+00131	Europe/Andorra
+AE	+2518+05518	Asia/Dubai
+AF	+3431+06912	Asia/Kabul
+AG	+1703-06148	America/Antigua
+AI	+1812-06304	America/Anguilla
+AL	+4120+01950	Europe/Tirane
+AM	+4011+04430	Asia/Yerevan
+AN	+1211-06900	America/Curacao
+AO	-0848+01314	Africa/Luanda
+AQ	-7750+16636	Antarctica/McMurdo	McMurdo Station, Ross Island
+AQ	-9000+00000	Antarctica/South_Pole	Amundsen-Scott Station, South Pole
+AQ	-6734-06808	Antarctica/Rothera	Rothera Station, Adelaide Island
+AQ	-6448-06406	Antarctica/Palmer	Palmer Station, Anvers Island
+AQ	-6736+06253	Antarctica/Mawson	Mawson Station, Holme Bay
+AQ	-6835+07758	Antarctica/Davis	Davis Station, Vestfold Hills
+AQ	-6617+11031	Antarctica/Casey	Casey Station, Bailey Peninsula
+AQ	-7824+10654	Antarctica/Vostok	Vostok Station, S Magnetic Pole
+AQ	-6640+14001	Antarctica/DumontDUrville	Dumont-d'Urville Station, Terre Adelie
+AQ	-690022+0393524	Antarctica/Syowa	Syowa Station, E Ongul I
+AR	-3436-05827	America/Argentina/Buenos_Aires	Buenos Aires (BA, CF)
+AR	-3124-06411	America/Argentina/Cordoba	most locations (CB, CC, CN, ER, FM, LP, MN, NQ, RN, SA, SE, SF)
+AR	-3319-06621	America/Argentina/San_Luis	San Luis (SL)
+AR	-2411-06518	America/Argentina/Jujuy	Jujuy (JY)
+AR	-2649-06513	America/Argentina/Tucuman	Tucuman (TM)
+AR	-2828-06547	America/Argentina/Catamarca	Catamarca (CT), Chubut (CH)
+AR	-2926-06651	America/Argentina/La_Rioja	La Rioja (LR)
+AR	-3132-06831	America/Argentina/San_Juan	San Juan (SJ)
+AR	-3253-06849	America/Argentina/Mendoza	Mendoza (MZ)
+AR	-5138-06913	America/Argentina/Rio_Gallegos	Santa Cruz (SC)
+AR	-5448-06818	America/Argentina/Ushuaia	Tierra del Fuego (TF)
+AS	-1416-17042	Pacific/Pago_Pago
+AT	+4813+01620	Europe/Vienna
+AU	-3133+15905	Australia/Lord_Howe	Lord Howe Island
+AU	-4253+14719	Australia/Hobart	Tasmania - most locations
+AU	-3956+14352	Australia/Currie	Tasmania - King Island
+AU	-3749+14458	Australia/Melbourne	Victoria
+AU	-3352+15113	Australia/Sydney	New South Wales - most locations
+AU	-3157+14127	Australia/Broken_Hill	New South Wales - Yancowinna
+AU	-2728+15302	Australia/Brisbane	Queensland - most locations
+AU	-2016+14900	Australia/Lindeman	Queensland - Holiday Islands
+AU	-3455+13835	Australia/Adelaide	South Australia
+AU	-1228+13050	Australia/Darwin	Northern Territory
+AU	-3157+11551	Australia/Perth	Western Australia - most locations
+AU	-3143+12852	Australia/Eucla	Western Australia - Eucla area
+AW	+1230-06958	America/Aruba
+AX	+6006+01957	Europe/Mariehamn
+AZ	+4023+04951	Asia/Baku
+BA	+4352+01825	Europe/Sarajevo
+BB	+1306-05937	America/Barbados
+BD	+2343+09025	Asia/Dhaka
+BE	+5050+00420	Europe/Brussels
+BF	+1222-00131	Africa/Ouagadougou
+BG	+4241+02319	Europe/Sofia
+BH	+2623+05035	Asia/Bahrain
+BI	-0323+02922	Africa/Bujumbura
+BJ	+0629+00237	Africa/Porto-Novo
+BL	+1753-06251	America/St_Barthelemy
+BM	+3217-06446	Atlantic/Bermuda
+BN	+0456+11455	Asia/Brunei
+BO	-1630-06809	America/La_Paz
+BR	-0351-03225	America/Noronha	Atlantic islands
+BR	-0127-04829	America/Belem	Amapa, E Para
+BR	-0343-03830	America/Fortaleza	NE Brazil (MA, PI, CE, RN, PB)
+BR	-0803-03454	America/Recife	Pernambuco
+BR	-0712-04812	America/Araguaina	Tocantins
+BR	-0940-03543	America/Maceio	Alagoas, Sergipe
+BR	-1259-03831	America/Bahia	Bahia
+BR	-2332-04637	America/Sao_Paulo	S & SE Brazil (GO, DF, MG, ES, RJ, SP, PR, SC, RS)
+BR	-2027-05437	America/Campo_Grande	Mato Grosso do Sul
+BR	-1535-05605	America/Cuiaba	Mato Grosso
+BR	-0226-05452	America/Santarem	W Para
+BR	-0846-06354	America/Porto_Velho	Rondonia
+BR	+0249-06040	America/Boa_Vista	Roraima
+BR	-0308-06001	America/Manaus	E Amazonas
+BR	-0640-06952	America/Eirunepe	W Amazonas
+BR	-0958-06748	America/Rio_Branco	Acre
+BS	+2505-07721	America/Nassau
+BT	+2728+08939	Asia/Thimphu
+BW	-2545+02555	Africa/Gaborone
+BY	+5354+02734	Europe/Minsk
+BZ	+1730-08812	America/Belize
+CA	+4734-05243	America/St_Johns	Newfoundland Time, including SE Labrador
+CA	+4439-06336	America/Halifax	Atlantic Time - Nova Scotia (most places), PEI
+CA	+4612-05957	America/Glace_Bay	Atlantic Time - Nova Scotia - places that did not observe DST 1966-1971
+CA	+4606-06447	America/Moncton	Atlantic Time - New Brunswick
+CA	+5320-06025	America/Goose_Bay	Atlantic Time - Labrador - most locations
+CA	+5125-05707	America/Blanc-Sablon	Atlantic Standard Time - Quebec - Lower North Shore
+CA	+4531-07334	America/Montreal	Eastern Time - Quebec - most locations
+CA	+4339-07923	America/Toronto	Eastern Time - Ontario - most locations
+CA	+4901-08816	America/Nipigon	Eastern Time - Ontario & Quebec - places that did not observe DST 1967-1973
+CA	+4823-08915	America/Thunder_Bay	Eastern Time - Thunder Bay, Ontario
+CA	+6344-06828	America/Iqaluit	Eastern Time - east Nunavut - most locations
+CA	+6608-06544	America/Pangnirtung	Eastern Time - Pangnirtung, Nunavut
+CA	+744144-0944945	America/Resolute	Eastern Time - Resolute, Nunavut
+CA	+484531-0913718	America/Atikokan	Eastern Standard Time - Atikokan, Ontario and Southampton I, Nunavut
+CA	+624900-0920459	America/Rankin_Inlet	Central Time - central Nunavut
+CA	+4953-09709	America/Winnipeg	Central Time - Manitoba & west Ontario
+CA	+4843-09434	America/Rainy_River	Central Time - Rainy River & Fort Frances, Ontario
+CA	+5024-10439	America/Regina	Central Standard Time - Saskatchewan - most locations
+CA	+5017-10750	America/Swift_Current	Central Standard Time - Saskatchewan - midwest
+CA	+5333-11328	America/Edmonton	Mountain Time - Alberta, east British Columbia & west Saskatchewan
+CA	+690650-1050310	America/Cambridge_Bay	Mountain Time - west Nunavut
+CA	+6227-11421	America/Yellowknife	Mountain Time - central Northwest Territories
+CA	+682059-1334300	America/Inuvik	Mountain Time - west Northwest Territories
+CA	+5946-12014	America/Dawson_Creek	Mountain Standard Time - Dawson Creek & Fort Saint John, British Columbia
+CA	+4916-12307	America/Vancouver	Pacific Time - west British Columbia
+CA	+6043-13503	America/Whitehorse	Pacific Time - south Yukon
+CA	+6404-13925	America/Dawson	Pacific Time - north Yukon
+CC	-1210+09655	Indian/Cocos
+CD	-0418+01518	Africa/Kinshasa	west Dem. Rep. of Congo
+CD	-1140+02728	Africa/Lubumbashi	east Dem. Rep. of Congo
+CF	+0422+01835	Africa/Bangui
+CG	-0416+01517	Africa/Brazzaville
+CH	+4723+00832	Europe/Zurich
+CI	+0519-00402	Africa/Abidjan
+CK	-2114-15946	Pacific/Rarotonga
+CL	-3327-07040	America/Santiago	most locations
+CL	-2709-10926	Pacific/Easter	Easter Island & Sala y Gomez
+CM	+0403+00942	Africa/Douala
+CN	+3114+12128	Asia/Shanghai	east China - Beijing, Guangdong, Shanghai, etc.
+CN	+4545+12641	Asia/Harbin	Heilongjiang (except Mohe), Jilin
+CN	+2934+10635	Asia/Chongqing	central China - Sichuan, Yunnan, Guangxi, Shaanxi, Guizhou, etc.
+CN	+4348+08735	Asia/Urumqi	most of Tibet & Xinjiang
+CN	+3929+07559	Asia/Kashgar	west Tibet & Xinjiang
+CO	+0436-07405	America/Bogota
+CR	+0956-08405	America/Costa_Rica
+CU	+2308-08222	America/Havana
+CV	+1455-02331	Atlantic/Cape_Verde
+CX	-1025+10543	Indian/Christmas
+CY	+3510+03322	Asia/Nicosia
+CZ	+5005+01426	Europe/Prague
+DE	+5230+01322	Europe/Berlin
+DJ	+1136+04309	Africa/Djibouti
+DK	+5540+01235	Europe/Copenhagen
+DM	+1518-06124	America/Dominica
+DO	+1828-06954	America/Santo_Domingo
+DZ	+3647+00303	Africa/Algiers
+EC	-0210-07950	America/Guayaquil	mainland
+EC	-0054-08936	Pacific/Galapagos	Galapagos Islands
+EE	+5925+02445	Europe/Tallinn
+EG	+3003+03115	Africa/Cairo
+EH	+2709-01312	Africa/El_Aaiun
+ER	+1520+03853	Africa/Asmara
+ES	+4024-00341	Europe/Madrid	mainland
+ES	+3553-00519	Africa/Ceuta	Ceuta & Melilla
+ES	+2806-01524	Atlantic/Canary	Canary Islands
+ET	+0902+03842	Africa/Addis_Ababa
+FI	+6010+02458	Europe/Helsinki
+FJ	-1808+17825	Pacific/Fiji
+FK	-5142-05751	Atlantic/Stanley
+FM	+0725+15147	Pacific/Truk	Truk (Chuuk) and Yap
+FM	+0658+15813	Pacific/Ponape	Ponape (Pohnpei)
+FM	+0519+16259	Pacific/Kosrae	Kosrae
+FO	+6201-00646	Atlantic/Faroe
+FR	+4852+00220	Europe/Paris
+GA	+0023+00927	Africa/Libreville
+GB	+513030-0000731	Europe/London
+GD	+1203-06145	America/Grenada
+GE	+4143+04449	Asia/Tbilisi
+GF	+0456-05220	America/Cayenne
+GG	+4927-00232	Europe/Guernsey
+GH	+0533-00013	Africa/Accra
+GI	+3608-00521	Europe/Gibraltar
+GL	+6411-05144	America/Godthab	most locations
+GL	+7646-01840	America/Danmarkshavn	east coast, north of Scoresbysund
+GL	+7029-02158	America/Scoresbysund	Scoresbysund / Ittoqqortoormiit
+GL	+7634-06847	America/Thule	Thule / Pituffik
+GM	+1328-01639	Africa/Banjul
+GN	+0931-01343	Africa/Conakry
+GP	+1614-06132	America/Guadeloupe
+GQ	+0345+00847	Africa/Malabo
+GR	+3758+02343	Europe/Athens
+GS	-5416-03632	Atlantic/South_Georgia
+GT	+1438-09031	America/Guatemala
+GU	+1328+14445	Pacific/Guam
+GW	+1151-01535	Africa/Bissau
+GY	+0648-05810	America/Guyana
+HK	+2217+11409	Asia/Hong_Kong
+HN	+1406-08713	America/Tegucigalpa
+HR	+4548+01558	Europe/Zagreb
+HT	+1832-07220	America/Port-au-Prince
+HU	+4730+01905	Europe/Budapest
+ID	-0610+10648	Asia/Jakarta	Java & Sumatra
+ID	-0002+10920	Asia/Pontianak	west & central Borneo
+ID	-0507+11924	Asia/Makassar	east & south Borneo, Celebes, Bali, Nusa Tengarra, west Timor
+ID	-0232+14042	Asia/Jayapura	Irian Jaya & the Moluccas
+IE	+5320-00615	Europe/Dublin
+IL	+3146+03514	Asia/Jerusalem
+IM	+5409-00428	Europe/Isle_of_Man
+IN	+2232+08822	Asia/Kolkata
+IO	-0720+07225	Indian/Chagos
+IQ	+3321+04425	Asia/Baghdad
+IR	+3540+05126	Asia/Tehran
+IS	+6409-02151	Atlantic/Reykjavik
+IT	+4154+01229	Europe/Rome
+JE	+4912-00207	Europe/Jersey
+JM	+1800-07648	America/Jamaica
+JO	+3157+03556	Asia/Amman
+JP	+353916+1394441	Asia/Tokyo
+KE	-0117+03649	Africa/Nairobi
+KG	+4254+07436	Asia/Bishkek
+KH	+1133+10455	Asia/Phnom_Penh
+KI	+0125+17300	Pacific/Tarawa	Gilbert Islands
+KI	-0308-17105	Pacific/Enderbury	Phoenix Islands
+KI	+0152-15720	Pacific/Kiritimati	Line Islands
+KM	-1141+04316	Indian/Comoro
+KN	+1718-06243	America/St_Kitts
+KP	+3901+12545	Asia/Pyongyang
+KR	+3733+12658	Asia/Seoul
+KW	+2920+04759	Asia/Kuwait
+KY	+1918-08123	America/Cayman
+KZ	+4315+07657	Asia/Almaty	most locations
+KZ	+4448+06528	Asia/Qyzylorda	Qyzylorda (Kyzylorda, Kzyl-Orda)
+KZ	+5017+05710	Asia/Aqtobe	Aqtobe (Aktobe)
+KZ	+4431+05016	Asia/Aqtau	Atyrau (Atirau, Gur'yev), Mangghystau (Mankistau)
+KZ	+5113+05121	Asia/Oral	West Kazakhstan
+LA	+1758+10236	Asia/Vientiane
+LB	+3353+03530	Asia/Beirut
+LC	+1401-06100	America/St_Lucia
+LI	+4709+00931	Europe/Vaduz
+LK	+0656+07951	Asia/Colombo
+LR	+0618-01047	Africa/Monrovia
+LS	-2928+02730	Africa/Maseru
+LT	+5441+02519	Europe/Vilnius
+LU	+4936+00609	Europe/Luxembourg
+LV	+5657+02406	Europe/Riga
+LY	+3254+01311	Africa/Tripoli
+MA	+3339-00735	Africa/Casablanca
+MC	+4342+00723	Europe/Monaco
+MD	+4700+02850	Europe/Chisinau
+ME	+4226+01916	Europe/Podgorica
+MF	+1804-06305	America/Marigot
+MG	-1855+04731	Indian/Antananarivo
+MH	+0709+17112	Pacific/Majuro	most locations
+MH	+0905+16720	Pacific/Kwajalein	Kwajalein
+MK	+4159+02126	Europe/Skopje
+ML	+1239-00800	Africa/Bamako
+MM	+1647+09610	Asia/Rangoon
+MN	+4755+10653	Asia/Ulaanbaatar	most locations
+MN	+4801+09139	Asia/Hovd	Bayan-Olgiy, Govi-Altai, Hovd, Uvs, Zavkhan
+MN	+4804+11430	Asia/Choibalsan	Dornod, Sukhbaatar
+MO	+2214+11335	Asia/Macau
+MP	+1512+14545	Pacific/Saipan
+MQ	+1436-06105	America/Martinique
+MR	+1806-01557	Africa/Nouakchott
+MS	+1643-06213	America/Montserrat
+MT	+3554+01431	Europe/Malta
+MU	-2010+05730	Indian/Mauritius
+MV	+0410+07330	Indian/Maldives
+MW	-1547+03500	Africa/Blantyre
+MX	+1924-09909	America/Mexico_City	Central Time - most locations
+MX	+2105-08646	America/Cancun	Central Time - Quintana Roo
+MX	+2058-08937	America/Merida	Central Time - Campeche, Yucatan
+MX	+2540-10019	America/Monterrey	Central Time - Coahuila, Durango, Nuevo Leon, Tamaulipas
+MX	+2313-10625	America/Mazatlan	Mountain Time - S Baja, Nayarit, Sinaloa
+MX	+2838-10605	America/Chihuahua	Mountain Time - Chihuahua
+MX	+2904-11058	America/Hermosillo	Mountain Standard Time - Sonora
+MX	+3232-11701	America/Tijuana	Pacific Time
+MY	+0310+10142	Asia/Kuala_Lumpur	peninsular Malaysia
+MY	+0133+11020	Asia/Kuching	Sabah & Sarawak
+MZ	-2558+03235	Africa/Maputo
+NA	-2234+01706	Africa/Windhoek
+NC	-2216+16530	Pacific/Noumea
+NE	+1331+00207	Africa/Niamey
+NF	-2903+16758	Pacific/Norfolk
+NG	+0627+00324	Africa/Lagos
+NI	+1209-08617	America/Managua
+NL	+5222+00454	Europe/Amsterdam
+NO	+5955+01045	Europe/Oslo
+NP	+2743+08519	Asia/Katmandu
+NR	-0031+16655	Pacific/Nauru
+NU	-1901-16955	Pacific/Niue
+NZ	-3652+17446	Pacific/Auckland	most locations
+NZ	-4357-17633	Pacific/Chatham	Chatham Islands
+OM	+2336+05835	Asia/Muscat
+PA	+0858-07932	America/Panama
+PE	-1203-07703	America/Lima
+PF	-1732-14934	Pacific/Tahiti	Society Islands
+PF	-0900-13930	Pacific/Marquesas	Marquesas Islands
+PF	-2308-13457	Pacific/Gambier	Gambier Islands
+PG	-0930+14710	Pacific/Port_Moresby
+PH	+1435+12100	Asia/Manila
+PK	+2452+06703	Asia/Karachi
+PL	+5215+02100	Europe/Warsaw
+PM	+4703-05620	America/Miquelon
+PN	-2504-13005	Pacific/Pitcairn
+PR	+182806-0660622	America/Puerto_Rico
+PS	+3130+03428	Asia/Gaza
+PT	+3843-00908	Europe/Lisbon	mainland
+PT	+3238-01654	Atlantic/Madeira	Madeira Islands
+PT	+3744-02540	Atlantic/Azores	Azores
+PW	+0720+13429	Pacific/Palau
+PY	-2516-05740	America/Asuncion
+QA	+2517+05132	Asia/Qatar
+RE	-2052+05528	Indian/Reunion
+RO	+4426+02606	Europe/Bucharest
+RS	+4450+02030	Europe/Belgrade
+RU	+5443+02030	Europe/Kaliningrad	Moscow-01 - Kaliningrad
+RU	+5545+03735	Europe/Moscow	Moscow+00 - west Russia
+RU	+4844+04425	Europe/Volgograd	Moscow+00 - Caspian Sea
+RU	+5312+05009	Europe/Samara	Moscow+01 - Samara, Udmurtia
+RU	+5651+06036	Asia/Yekaterinburg	Moscow+02 - Urals
+RU	+5500+07324	Asia/Omsk	Moscow+03 - west Siberia
+RU	+5502+08255	Asia/Novosibirsk	Moscow+03 - Novosibirsk
+RU	+5601+09250	Asia/Krasnoyarsk	Moscow+04 - Yenisei River
+RU	+5216+10420	Asia/Irkutsk	Moscow+05 - Lake Baikal
+RU	+6200+12940	Asia/Yakutsk	Moscow+06 - Lena River
+RU	+4310+13156	Asia/Vladivostok	Moscow+07 - Amur River
+RU	+4658+14242	Asia/Sakhalin	Moscow+07 - Sakhalin Island
+RU	+5934+15048	Asia/Magadan	Moscow+08 - Magadan
+RU	+5301+15839	Asia/Kamchatka	Moscow+09 - Kamchatka
+RU	+6445+17729	Asia/Anadyr	Moscow+10 - Bering Sea
+RW	-0157+03004	Africa/Kigali
+SA	+2438+04643	Asia/Riyadh
+SB	-0932+16012	Pacific/Guadalcanal
+SC	-0440+05528	Indian/Mahe
+SD	+1536+03232	Africa/Khartoum
+SE	+5920+01803	Europe/Stockholm
+SG	+0117+10351	Asia/Singapore
+SH	-1555-00542	Atlantic/St_Helena
+SI	+4603+01431	Europe/Ljubljana
+SJ	+7800+01600	Arctic/Longyearbyen
+SK	+4809+01707	Europe/Bratislava
+SL	+0830-01315	Africa/Freetown
+SM	+4355+01228	Europe/San_Marino
+SN	+1440-01726	Africa/Dakar
+SO	+0204+04522	Africa/Mogadishu
+SR	+0550-05510	America/Paramaribo
+ST	+0020+00644	Africa/Sao_Tome
+SV	+1342-08912	America/El_Salvador
+SY	+3330+03618	Asia/Damascus
+SZ	-2618+03106	Africa/Mbabane
+TC	+2128-07108	America/Grand_Turk
+TD	+1207+01503	Africa/Ndjamena
+TF	-492110+0701303	Indian/Kerguelen
+TG	+0608+00113	Africa/Lome
+TH	+1345+10031	Asia/Bangkok
+TJ	+3835+06848	Asia/Dushanbe
+TK	-0922-17114	Pacific/Fakaofo
+TL	-0833+12535	Asia/Dili
+TM	+3757+05823	Asia/Ashgabat
+TN	+3648+01011	Africa/Tunis
+TO	-2110+17510	Pacific/Tongatapu
+TR	+4101+02858	Europe/Istanbul
+TT	+1039-06131	America/Port_of_Spain
+TV	-0831+17913	Pacific/Funafuti
+TW	+2503+12130	Asia/Taipei
+TZ	-0648+03917	Africa/Dar_es_Salaam
+UA	+5026+03031	Europe/Kiev	most locations
+UA	+4837+02218	Europe/Uzhgorod	Ruthenia
+UA	+4750+03510	Europe/Zaporozhye	Zaporozh'ye, E Lugansk / Zaporizhia, E Luhansk
+UA	+4457+03406	Europe/Simferopol	central Crimea
+UG	+0019+03225	Africa/Kampala
+UM	+1645-16931	Pacific/Johnston	Johnston Atoll
+UM	+2813-17722	Pacific/Midway	Midway Islands
+UM	+1917+16637	Pacific/Wake	Wake Island
+US	+404251-0740023	America/New_York	Eastern Time
+US	+421953-0830245	America/Detroit	Eastern Time - Michigan - most locations
+US	+381515-0854534	America/Kentucky/Louisville	Eastern Time - Kentucky - Louisville area
+US	+364947-0845057	America/Kentucky/Monticello	Eastern Time - Kentucky - Wayne County
+US	+394606-0860929	America/Indiana/Indianapolis	Eastern Time - Indiana - most locations
+US	+384038-0873143	America/Indiana/Vincennes	Eastern Time - Indiana - Daviess, Dubois, Knox & Martin Counties
+US	+411745-0863730	America/Indiana/Knox	Eastern Time - Indiana - Starke County
+US	+410305-0863611	America/Indiana/Winamac	Eastern Time - Indiana - Pulaski County
+US	+382232-0862041	America/Indiana/Marengo	Eastern Time - Indiana - Crawford County
+US	+384452-0850402	America/Indiana/Vevay	Eastern Time - Indiana - Switzerland County
+US	+415100-0873900	America/Chicago	Central Time
+US	+375711-0864541	America/Indiana/Tell_City	Central Time - Indiana - Perry County
+US	+382931-0871643	America/Indiana/Petersburg	Central Time - Indiana - Pike County
+US	+450628-0873651	America/Menominee	Central Time - Michigan - Dickinson, Gogebic, Iron & Menominee Counties
+US	+470659-1011757	America/North_Dakota/Center	Central Time - North Dakota - Oliver County
+US	+465042-1012439	America/North_Dakota/New_Salem	Central Time - North Dakota - Morton County (except Mandan area)
+US	+394421-1045903	America/Denver	Mountain Time
+US	+433649-1161209	America/Boise	Mountain Time - south Idaho & east Oregon
+US	+364708-1084111	America/Shiprock	Mountain Time - Navajo
+US	+332654-1120424	America/Phoenix	Mountain Standard Time - Arizona
+US	+340308-1181434	America/Los_Angeles	Pacific Time
+US	+611305-1495401	America/Anchorage	Alaska Time
+US	+581807-1342511	America/Juneau	Alaska Time - Alaska panhandle
+US	+593249-1394338	America/Yakutat	Alaska Time - Alaska panhandle neck
+US	+643004-1652423	America/Nome	Alaska Time - west Alaska
+US	+515248-1763929	America/Adak	Aleutian Islands
+US	+211825-1575130	Pacific/Honolulu	Hawaii
+UY	-3453-05611	America/Montevideo
+UZ	+3940+06648	Asia/Samarkand	west Uzbekistan
+UZ	+4120+06918	Asia/Tashkent	east Uzbekistan
+VA	+4154+01227	Europe/Vatican
+VC	+1309-06114	America/St_Vincent
+VE	+1030-06656	America/Caracas
+VG	+1827-06437	America/Tortola
+VI	+1821-06456	America/St_Thomas
+VN	+1045+10640	Asia/Ho_Chi_Minh
+VU	-1740+16825	Pacific/Efate
+WF	-1318-17610	Pacific/Wallis
+WS	-1350-17144	Pacific/Apia
+YE	+1245+04512	Asia/Aden
+YT	-1247+04514	Indian/Mayotte
+ZA	-2615+02800	Africa/Johannesburg
+ZM	-1525+02817	Africa/Lusaka
+ZW	-1750+03103	Africa/Harare
