This commit was manufactured by cvs2svn to create branch 'STABLE'.

Sprout from master 2001-10-23 04:06:04 UTC Darin Wright <darin> 'IDebugModelPresentation API change'
Cherrypick from master 2002-10-29 23:02:53 UTC Darin Swanson <darins> 'Bug 25397 - AntPage flashes when resized':
    org.eclipse.ui.externaltools/.classpath
    org.eclipse.ui.externaltools/.cvsignore
    org.eclipse.ui.externaltools/.options
    org.eclipse.ui.externaltools/.project
    org.eclipse.ui.externaltools/Ant Builder/org/eclipse/ui/externaltools/internal/ui/ant/AntBuildLogger.java
    org.eclipse.ui.externaltools/Ant Builder/org/eclipse/ui/externaltools/internal/ui/ant/AntInputHandler.java
    org.eclipse.ui.externaltools/Ant Builder/org/eclipse/ui/externaltools/internal/ui/ant/NullBuildLogger.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/AntFileRunner.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/AntTargetList.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/AntUtil.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/DefaultRunnerContext.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalTool.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsBuilder.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsPlugin.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsRegistry.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsRunner.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/IPreferenceConstants.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/IRunnerContext.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ProgramRunner.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ToolMessages.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ToolUtil.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/messages.properties
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AddCustomDialog.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntAction.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntClasspathPage.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntDialogMessages.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntDialogMessages.properties
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntLaunchWizard.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntLaunchWizardPage.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntPage.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntPageLabelProvider.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntPreferencePage.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntRunActionDelegate.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTargetContentProvider.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTargetLabelProvider.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTasksPage.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTypesPage.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/BuilderPropertyPage.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/ConfigurationDialog.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/EditDialog.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/ExternalToolsAction.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/IHelpContextIds.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/IUIConstants.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogConsoleDocument.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogConsolePreferencePage.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogConsoleView.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogTreeContentProvider.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogTreeLabelProvider.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/OutputStructureElement.java
    org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/ToolsPreferencePage.java
    org.eclipse.ui.externaltools/about.html
    org.eclipse.ui.externaltools/build.properties
    org.eclipse.ui.externaltools/buildnotes.html
    org.eclipse.ui.externaltools/icons/full/clcl16/clear.gif
    org.eclipse.ui.externaltools/icons/full/clcl16/hide_show_tree.gif
    org.eclipse.ui.externaltools/icons/full/clcl16/show_selected_text.gif
    org.eclipse.ui.externaltools/icons/full/ctool16/external_tools.gif
    org.eclipse.ui.externaltools/icons/full/cview16/log_console_view.gif
    org.eclipse.ui.externaltools/icons/full/dtool16/external_tools.gif
    org.eclipse.ui.externaltools/icons/full/etool16/external_tools.gif
    org.eclipse.ui.externaltools/icons/full/eview16/log_console_view.gif
    org.eclipse.ui.externaltools/icons/full/obj16/ant_file.gif
    org.eclipse.ui.externaltools/icons/full/obj16/builder.gif
    org.eclipse.ui.externaltools/icons/full/obj16/classpath.gif
    org.eclipse.ui.externaltools/icons/full/obj16/external_tools.gif
    org.eclipse.ui.externaltools/icons/full/obj16/invalid_build_tool.gif
    org.eclipse.ui.externaltools/icons/full/obj16/jar_l_obj.gif
    org.eclipse.ui.externaltools/icons/full/obj16/type.gif
    org.eclipse.ui.externaltools/icons/full/wizban/ant_wiz.gif
    org.eclipse.ui.externaltools/icons/full/wizban/ext_tools_wiz.gif
    org.eclipse.ui.externaltools/lib/.cvsignore
    org.eclipse.ui.externaltools/plugin.properties
    org.eclipse.ui.externaltools/plugin.xml
    org.eclipse.ui.externaltools/scripts/buildExtraJAR.xml
    org.eclipse.ui.externaltools/scripts/buildSelfHostingJARs.xml
    org.eclipse.ui.externaltools/scripts/exportplugin.xml
    org.eclipse.ui.externaltools/scripts/updateTarget.xml
    org.eclipse.ui.externaltools/scripts/updateTargets.xml
Cherrypick from master 2001-05-18 10:25:56 UTC Darin Wright <darin> '*** empty log message ***':
    org.eclipse.debug.core/plugin.jars
    org.eclipse.debug.ui/plugin.jars
Cherrypick from master 2001-10-12 21:03:30 UTC jszursze <jszursze> 'bug #1531':
    org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIResources.properties
    org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIUtils.java
diff --git a/org.eclipse.debug.core/plugin.jars b/org.eclipse.debug.core/plugin.jars
new file mode 100644
index 0000000..e50828d
--- /dev/null
+++ b/org.eclipse.debug.core/plugin.jars
@@ -0,0 +1 @@
+dtcore.jar=Eclipse Debug Core
\ No newline at end of file
diff --git a/org.eclipse.debug.ui/plugin.jars b/org.eclipse.debug.ui/plugin.jars
new file mode 100644
index 0000000..2b4b80c
--- /dev/null
+++ b/org.eclipse.debug.ui/plugin.jars
@@ -0,0 +1 @@
+dtui.jar=Eclipse Debug UI
\ No newline at end of file
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIResources.properties b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIResources.properties
new file mode 100644
index 0000000..b3651fa
--- /dev/null
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIResources.properties
@@ -0,0 +1,126 @@
+##############################################################
+# (c) Copyright IBM Corp. 2000, 2001.
+# All Rights Reserved.
+##############################################################
+
+##############################################################
+# Launcher property page
+##############################################################
+launcher_preferences.description=Select default launcher
+launcher_preferences.run_debug=Run/Debug
+launcher_preferences.none=none
+launcher_preferences.closed_project=Launcher information is not available for a closed project
+##############################################################
+# Launch wizard 
+##############################################################
+launch_wizard.title.debug=Debug

+launch_wizard.title.run=Run
+
+##############################################################
+# Launch wizard project selection page
+##############################################################
+launch_wizard_project_page.title=Select Project
+launch_wizard_project_page.select_element= Select a project for the launch context.
+launch_wizard_project_page.select_error_element=No projects available.
+launch_wizard_project_page.pattern_label=Enter a pattern to select a range of projects
+
+##############################################################
+# Launch wizard page
+##############################################################
+launch_wizard_page.title=Select Launcher
+launch_wizard_page.launcher= Select a launcher:
+launch_wizard_page.select_error_launcher=No launchers registered.
+launch_wizard_page.default_launcher=Set as &default launcher for project \"{0}\"
+launch_wizard_page.unknown=<unknown>
+
+##############################################################
+# Action resources
+##############################################################
+
+add_to_inspector_action.text=&Inspect
+add_to_inspector_action.toolTipText=Adds Selected Variables to Inspector
+
+change_variable_value_action.text=&Change Variable Value
+change_variable_value_action.description=Changes the value of a simple type variable
+change_variable_value_action.dialog.message=Enter the new value for the variable \"{0}\"
+change_variable_value_action.dialog.invalid=Value is not valid for the variable \"{0}\"
+change_variable_value_action.dialog.title=Change Variable Value
+
+clear_output_action.text=Clear &Output
+clear_output_action.toolTipText=Clear Output
+
+copy_action.label=&Copy@Ctrl+C
+copy_action.tooltip=Copy
+copy_action.description=Copy
+
+cut_action.label=Cu&t@Ctrl+X
+cut_action.tooltip=Cut
+cut_action.description=Cut
+
+debug_action.text=&Debug@F9
+debug_action.toolTipText=Debug
+
+find_replace_action.label=&Find/Replace@Ctrl+F
+find_replace_action.tooltip=Find/Replace
+find_replace_action.image=
+find_replace_action.description=Find/Replace
+
+goto_line_action.label=Go to &Line...@Ctrl+L
+goto_line_action.tooltip=Go to Line
+goto_line_action.image=
+goto_line_action.description=Go to Line
+goto_line_action.dialog.title=Go to Line
+goto_line_action.dialog.message=Enter line number:
+goto_line_action.dialog.invalid_input=Not a number
+goto_line_action.dialog.invalid_range=Line number out of range
+
+launch_with_action.text.debug=Debug
+launch_with_action.text.run=Run
+
+open_breakpoint_marker_action.text=&Go to File
+open_breakpoint_marker_action.toolTipText=Go to File for Breakpoint
+
+paste_action.label=&Paste@Ctrl+V
+paste_action.tooltip=Paste
+paste_action.description=Pastes clipboard text
+
+remove_all_breakpoints_action.text=Remove &All
+remove_all_breakpoints_action.toolTipText=Remove All Breakpoints
+
+remove_all_from_inspector_action.text=Remove &All
+remove_all_from_inspector_action.toolTipText=Remove All Variables from Inspector
+
+remove_all_terminated_action.text=Remove &All Terminated
+remove_all_terminated_action.toolTipText=Remove All Terminated Launches
+
+remove_breakpoint_action.text=&Remove
+remove_breakpoint_action.toolTipText=Remove Selected Breakpoints
+
+remove_from_inspector_action.text=&Remove
+remove_from_inspector_action.toolTipText=Remove Selected Variables from Inspector
+
+run_action.text=R&un@Alt+F9
+run_action.toolTipText=Run
+
+select_all_action.label=Select &All@Ctrl+A
+select_all_action.tooltip=Select All
+select_all_action.description=Select All
+
+show_qualified_action.toolTipText.show=Show &Qualified Names
+show_qualified_action.toolTipText.hide=Hide &Qualified Names
+
+show_types_action.toolTipText.show=Show &Type Names
+show_types_action.toolTipText.hide=Hide &Type Names
+
+terminate_all_action.text=Termi&nate All
+terminate_all_action.toolTipText=Terminate All
+
+
+##############################################################
+# Breakpoint Labels
+##############################################################
+breakpoint_label.line_number=Line:
+breakpoint_label.unknown_line_number=<unknown>
+breakpoint_label.unknown_resource=ERROR
+breakpoint_label.expired=<expired>
+breakpoint_label.hit_count=<Hit Count: {0}>
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIUtils.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIUtils.java
new file mode 100644
index 0000000..bc241a3
--- /dev/null
+++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIUtils.java
@@ -0,0 +1,87 @@
+package org.eclipse.debug.internal.ui;

+

+/*

+ * (c) Copyright IBM Corp. 2000, 2001.

+ * All Rights Reserved.

+ */

+

+import java.util.MissingResourceException;

+import java.util.ResourceBundle;

+

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.debug.core.model.IProcess;

+import org.eclipse.jface.dialogs.ErrorDialog;

+import org.eclipse.jface.dialogs.MessageDialog;

+import org.eclipse.jface.text.IDocument;

+import org.eclipse.swt.widgets.Shell;

+

+/**

+ * This class serves as a location for utility methods for the debug UI.

+ */

+public class DebugUIUtils {

+

+	private static ResourceBundle fgResourceBundle;

+

+	/**

+	 * Utility method with conventions

+	 */

+	public static void errorDialog(Shell shell, String title, String message, IStatus s) {

+		// if the 'message' resource string and the IStatus' message are the same,

+		// don't show both in the dialog

+		if (s != null && message.equals(s.getMessage())) {

+			message= null;

+		}

+		ErrorDialog.openError(shell, title, message, s);

+	}

+

+	/**

+	 * Utility method

+	 */

+	public static String getResourceString(String key) {

+		if (fgResourceBundle == null) {

+			fgResourceBundle= getResourceBundle();

+		}

+		if (fgResourceBundle != null) {

+			return fgResourceBundle.getString(key);

+		} else {

+			return "!" + key + "!";

+		}

+	}

+

+	/**

+	 * Returns the resource bundle used by all parts of the debug ui package.

+	 */

+	public static ResourceBundle getResourceBundle() {

+		try {

+			return ResourceBundle.getBundle("org.eclipse.debug.internal.ui.DebugUIResources");

+		} catch (MissingResourceException e) {

+			MessageDialog.openError(DebugUIPlugin.getActiveWorkbenchWindow().getShell(), "Error", e.toString());

+		}

+		return null;

+	}

+

+	/**

+	 * Convenience method to log internal UI errors

+	 */

+	public static void logError(Exception e) {

+		if (DebugUIPlugin.getDefault().isDebugging()) {

+			// this message is intentionally not internationalized, as an exception may

+			// be due to the resource bundle itself

+			System.out.println("Internal error logged from UI: ");

+			e.printStackTrace();

+			System.out.println();

+		}

+	}

+	

+	/**

+	 * Defined here as an API-legal way to get the console document for the 

+	 * current process.

+	 */

+	public static IDocument getCurrentConsoleDocument() {

+		DebugUIPlugin plugin = DebugUIPlugin.getDefault();

+		IProcess currentProcess = plugin.getCurrentProcess();

+		IDocument document = plugin.getConsoleDocument(currentProcess, true);

+		return document;

+	}

+}

+

diff --git a/org.eclipse.ui.externaltools/.classpath b/org.eclipse.ui.externaltools/.classpath
new file mode 100644
index 0000000..adcec91
--- /dev/null
+++ b/org.eclipse.ui.externaltools/.classpath
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<classpath>

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

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

+    <classpathentry kind="src" path="/org.apache.xerces"/>

+    <classpathentry kind="src" path="/org.eclipse.ant.core"/>

+    <classpathentry kind="src" path="/org.eclipse.core.resources"/>

+    <classpathentry kind="src" path="/org.eclipse.ui"/>

+    <classpathentry kind="src" path="/org.eclipse.core.runtime"/>

+    <classpathentry kind="src" path="/org.eclipse.core.boot"/>

+    <classpathentry kind="var" path="JRE_LIB" rootpath="JRE_SRCROOT" sourcepath="JRE_SRC"/>

+    <classpathentry kind="src" path="/org.apache.ant"/>

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

+</classpath>

diff --git a/org.eclipse.ui.externaltools/.cvsignore b/org.eclipse.ui.externaltools/.cvsignore
new file mode 100644
index 0000000..e21de8f
--- /dev/null
+++ b/org.eclipse.ui.externaltools/.cvsignore
@@ -0,0 +1,4 @@
+bin
+externaltools.jar.bin.log
+externaltools.jar
+build.xml
diff --git a/org.eclipse.ui.externaltools/.options b/org.eclipse.ui.externaltools/.options
new file mode 100644
index 0000000..d127194
--- /dev/null
+++ b/org.eclipse.ui.externaltools/.options
@@ -0,0 +1 @@
+# Debugging options for the org.eclipse.ui.externaltools plugin.

diff --git a/org.eclipse.ui.externaltools/.project b/org.eclipse.ui.externaltools/.project
new file mode 100644
index 0000000..6f3deaf
--- /dev/null
+++ b/org.eclipse.ui.externaltools/.project
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<projectDescription>

+	<name>org.eclipse.ui.externaltools</name>

+	<comment></comment>

+	<projects>

+		<project>org.apache.ant</project>

+		<project>org.apache.xerces</project>

+		<project>org.eclipse.ant.core</project>

+		<project>org.eclipse.core.boot</project>

+		<project>org.eclipse.core.resources</project>

+		<project>org.eclipse.core.runtime</project>

+		<project>org.eclipse.ui</project>

+	</projects>

+	<buildSpec>

+		<buildCommand>

+			<name>org.eclipse.jdt.core.javabuilder</name>

+			<arguments>

+			</arguments>

+		</buildCommand>

+	</buildSpec>

+	<natures>

+		<nature>org.eclipse.jdt.core.javanature</nature>

+	</natures>

+</projectDescription>

diff --git a/org.eclipse.ui.externaltools/Ant Builder/org/eclipse/ui/externaltools/internal/ui/ant/AntBuildLogger.java b/org.eclipse.ui.externaltools/Ant Builder/org/eclipse/ui/externaltools/internal/ui/ant/AntBuildLogger.java
new file mode 100644
index 0000000..a0ed27c
--- /dev/null
+++ b/org.eclipse.ui.externaltools/Ant Builder/org/eclipse/ui/externaltools/internal/ui/ant/AntBuildLogger.java
@@ -0,0 +1,111 @@
+package org.eclipse.ui.externaltools.internal.ui.ant;
+
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+**********************************************************************/
+
+import org.apache.tools.ant.BuildEvent;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.externaltools.internal.ui.LogConsoleDocument;
+import org.eclipse.ui.externaltools.internal.ui.OutputStructureElement;
+
+public class AntBuildLogger extends NullBuildLogger {
+
+	private int fLogLength = 0;
+	private int fLastTargetEndIndex = 0;
+	
+	public AntBuildLogger() {
+	}
+
+	/**
+	 * @see BuildListener#targetStarted(BuildEvent)
+	 */
+	public void targetStarted(BuildEvent event) {
+		createNewOutputStructureElement(event.getTarget().getName(), fLogLength);
+	}
+
+	protected void refreshConsoleTrees() {
+		final LogConsoleDocument doc = LogConsoleDocument.getInstance();
+		if (!doc.hasViews()) {
+			return;
+		}
+		// we get the display from the console #0 (that exists for sure because consoles!=null)
+		Display display = doc.getDisplay();
+		// create a new thread for synchronizing all the refresh operations
+		display.asyncExec(new Runnable() {
+			public void run() {
+				doc.refreshTree();
+			}
+		});
+	}
+
+	protected void createNewOutputStructureElement(String name, int index) {
+		LogConsoleDocument doc = LogConsoleDocument.getInstance();
+		OutputStructureElement newElement =
+			new OutputStructureElement(name, doc.getCurrentOutputStructureElement(), index);
+		doc.setCurrentOutputStructureElement(newElement);
+	}
+
+	/**
+	 * @see BuildListener#targetFinished(BuildEvent)
+	 */
+	public void targetFinished(BuildEvent event) {
+		handleException(event);
+		finishCurrentOutputStructureElement();
+		// store the end index of this target's log (so that we can use it later)
+		fLastTargetEndIndex = fLogLength;
+		refreshConsoleTrees();
+	}
+
+	/**
+	 * @see BuildListener#taskStarted(BuildEvent)
+	 */
+	public void taskStarted(BuildEvent event) {
+		createNewOutputStructureElement(event.getTask().getTaskName());
+	}
+
+	/**
+	 * @see BuildListener#taskFinished(BuildEvent)
+	 */
+	public void taskFinished(BuildEvent event) {
+		handleException(event);
+		finishCurrentOutputStructureElement();
+		refreshConsoleTrees();
+	}
+
+	protected void logMessage(String message, int priority) {
+		if (priority > getMessageOutputLevel()) {
+			return;
+		}
+		super.logMessage(message, priority);
+		message += '\n';
+		LogConsoleDocument doc = LogConsoleDocument.getInstance();
+		doc.append(message, priority);
+		fLogLength += message.length();
+	}
+
+	protected void finishCurrentOutputStructureElement() {
+		LogConsoleDocument doc = LogConsoleDocument.getInstance();
+		// sets the index that indicates the end of the log part linked to this element
+		OutputStructureElement output = doc.getCurrentOutputStructureElement();
+		output.setEndIndex(fLogLength);
+		// and sets the current element to the parent of the element
+		doc.setCurrentOutputStructureElement(output.getParent());
+	}
+
+	protected void createNewOutputStructureElement(String name) {
+		createNewOutputStructureElement(name, fLogLength);
+	}
+	
+	private IProgressMonitor monitorFor(IProgressMonitor monitor) {
+		if (monitor == null) {
+			return new NullProgressMonitor();
+		}
+		return monitor;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/Ant Builder/org/eclipse/ui/externaltools/internal/ui/ant/AntInputHandler.java b/org.eclipse.ui.externaltools/Ant Builder/org/eclipse/ui/externaltools/internal/ui/ant/AntInputHandler.java
new file mode 100644
index 0000000..2c53562
--- /dev/null
+++ b/org.eclipse.ui.externaltools/Ant Builder/org/eclipse/ui/externaltools/internal/ui/ant/AntInputHandler.java
@@ -0,0 +1,61 @@
+package org.eclipse.ui.externaltools.internal.ui.ant;
+
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+**********************************************************************/
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.input.DefaultInputHandler;
+import org.apache.tools.ant.input.InputRequest;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.externaltools.internal.core.ToolMessages;
+
+/**
+ * The default input handler when using Ant within Eclipse.
+ * This is the class that will respond to <input> requests from
+ * within an Ant build file.
+ */
+public class AntInputHandler extends DefaultInputHandler {
+	
+	/**
+	 * @see org.apache.tools.ant.input.InputHandler#handleInput(org.apache.tools.ant.input.InputRequest)
+	 */
+	public void handleInput(InputRequest request) throws BuildException {
+		BuildException[] problem= new BuildException[1];
+		Runnable runnable= getHandleInputRunnable(request, problem);
+		Display.getDefault().syncExec(runnable);
+		if (problem[0] != null) {
+			throw problem[0];
+		}
+	}
+	
+	protected Runnable getHandleInputRunnable(final InputRequest request, final BuildException[] problem) {
+		return new Runnable() {
+			public void run() {
+				String prompt = getPrompt(request);
+		       	String title= ToolMessages.getString("AntInputHandler.Ant_Input_Request_1"); //$NON-NLS-1$
+				IInputValidator validator= new IInputValidator() {
+					int hitCount= -1;
+					public String isValid(String value) {
+						request.setInput(value);
+						if (request.isInputValid()) {
+							return null;
+						} else {
+							return ToolMessages.getString("AntInputHandler.Invalid_input_2"); //$NON-NLS-1$
+						}
+					}
+				};
+		
+				InputDialog dialog= new InputDialog(null, title, prompt, "", validator); //$NON-NLS-1$
+				if (dialog.open() != InputDialog.OK) {
+					problem[0]= new BuildException(ToolMessages.getString("AntInputHandler.Unable_able_to_respond_to_<input>_request_4")); //$NON-NLS-1$
+				}
+			}
+		};
+	}
+}
diff --git a/org.eclipse.ui.externaltools/Ant Builder/org/eclipse/ui/externaltools/internal/ui/ant/NullBuildLogger.java b/org.eclipse.ui.externaltools/Ant Builder/org/eclipse/ui/externaltools/internal/ui/ant/NullBuildLogger.java
new file mode 100644
index 0000000..13a2c07
--- /dev/null
+++ b/org.eclipse.ui.externaltools/Ant Builder/org/eclipse/ui/externaltools/internal/ui/ant/NullBuildLogger.java
Binary files differ
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/AntFileRunner.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/AntFileRunner.java
new file mode 100644
index 0000000..c5910ad
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/AntFileRunner.java
@@ -0,0 +1,79 @@
+package org.eclipse.ui.externaltools.internal.core;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import org.eclipse.ant.core.AntRunner;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+
+/**
+ * Responsible for running ant files.
+ */
+public class AntFileRunner extends ExternalToolsRunner {
+	private static final String ANT_LOGGER_CLASS = "org.eclipse.ui.externaltools.internal.ui.ant.AntBuildLogger"; //$NON-NLS-1$
+	private static final String NULL_LOGGER_CLASS = "org.eclipse.ui.externaltools.internal.ui.ant.NullBuildLogger"; //$NON-NLS-1$
+	
+	private static final String INPUT_HANDLER_CLASS = "org.eclipse.ui.externaltools.internal.ui.ant.AntInputHandler"; //$NON-NLS-1$
+	
+	private static final String BASE_DIR_PREFIX = "-Dbasedir="; //$NON-NLS-1$
+
+	/**
+	 * Creates an empty ant file runner
+	 */
+	public AntFileRunner() {
+		super();
+	}
+
+	/* (non-Javadoc)
+	 * Method declared in ExternalToolsRunner.
+	 */
+	public void execute(IProgressMonitor monitor, IRunnerContext runnerContext) throws CoreException, InterruptedException {
+		try {
+			String[] targets = runnerContext.getAntTargets();
+			AntRunner runner = new AntRunner();
+			String args = runnerContext.getExpandedArguments();
+			String baseDir = runnerContext.getExpandedWorkingDirectory();
+			if (baseDir.length() > 0) {
+				String baseDirArg;
+				if (ToolUtil.hasSpace(baseDir)) {
+					baseDirArg = BASE_DIR_PREFIX + "\"" + baseDir + "\""; //$NON-NLS-2$ //$NON-NLS-1$
+				} else {
+					baseDirArg = BASE_DIR_PREFIX + baseDir;
+				}
+				runner.setArguments(args + " " + baseDirArg ); //$NON-NLS-1$
+			} else {
+				runner.setArguments(args);	
+			}
+			runner.setBuildFileLocation(runnerContext.getExpandedLocation());
+			if (targets.length > 0) {
+				runner.setExecutionTargets(targets);
+			}
+			if (runnerContext.getShowLog()) {
+				runner.addBuildLogger(ANT_LOGGER_CLASS);
+			} else {
+				runner.addBuildLogger(NULL_LOGGER_CLASS);
+			}
+			
+			runner.setInputHandler(INPUT_HANDLER_CLASS);
+			
+			runner.run(monitor);
+		} catch (CoreException e) {
+			Throwable carriedException = e.getStatus().getException();
+			if (carriedException instanceof OperationCanceledException) {
+				throw new InterruptedException(carriedException.getMessage());
+			} else {
+				throw e;
+			}
+		} finally {
+			monitor.done();
+		}
+	}
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/AntTargetList.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/AntTargetList.java
new file mode 100644
index 0000000..bf0552f
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/AntTargetList.java
@@ -0,0 +1,87 @@
+package org.eclipse.ui.externaltools.internal.core;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.text.MessageFormat;
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.*;
+
+/**
+ * This class represents a list of targets that an
+ * Ant file can run.
+ */
+public class AntTargetList {
+	// The list of targets.
+	private ArrayList targets = new ArrayList();
+	
+	// The target that will be run if no targets are specified
+	// by the user.
+	private String defaultTarget = null;
+	
+	/**
+	 * Add a target to the list.
+	 */
+	/*package*/ void add(String target) {
+		targets.add(target);	
+	}
+	
+	/**
+	 * Retrieve the default target. This method will return
+	 * <code>null</code> if the default target has not yet
+	 * been specified.
+	 */
+	public String getDefaultTarget() {
+		return defaultTarget;	
+	}
+	
+	/**
+	 * Retrieve all the targets as an array.
+	 */
+	public String[] getTargets() {
+		String[] array = new String[targets.size()];
+		targets.toArray(array);
+		return array;
+	}
+	
+	/**
+	 * Returns the number of targets in the list.
+	 */
+	public int getTargetCount() {
+		return targets.size();
+	}
+	
+	/**
+	 * Set the default target.
+	 */
+	/*package*/ void setDefaultTarget(String target) {
+		defaultTarget = target;
+	}
+	
+	/**
+	 * Validate the default target exists within the
+	 * known target list and if not, remove it.
+	 */
+	/*package*/ void validateDefaultTarget() throws CoreException {
+		if (defaultTarget != null) {
+			if (targets.contains(defaultTarget)) {
+				return;
+			}
+		}
+		String msg;
+		if (defaultTarget != null) {
+			msg= MessageFormat.format("Default target {0}{1}{2} does not exist in this project.", new String[]{"'", defaultTarget, "'"});
+		} else {
+			msg= "A default target must exist in the project";
+		}
+		IStatus status = new Status(IStatus.ERROR, ExternalToolsPlugin.PLUGIN_ID, 0, msg, null);
+		throw new CoreException(status);
+	}
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/AntUtil.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/AntUtil.java
new file mode 100644
index 0000000..db6ffdb
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/AntUtil.java
@@ -0,0 +1,211 @@
+package org.eclipse.ui.externaltools.internal.core;
+
+/**********************************************************************
+Copyright (c) 2000, 2002 IBM Corp.  All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html
+**********************************************************************/
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.text.MessageFormat;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+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.ui.IMemento;
+import org.eclipse.ui.XMLMemento;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+/**
+ * General utility class dealing with Ant files
+ */
+public final class AntUtil {
+	private static final String ATT_DEFAULT = "default"; //NON-NLS-1$
+	private static final String ATT_NAME = "name"; //NON-NLS-1$
+	private static final String TAG_TARGET = "target"; //NON-NLS-1$
+	
+	/**
+	 * No instances allowed
+	 */
+	private AntUtil() {
+		super();
+	}
+
+	/**
+	 * Returns the list of targets for the Ant file specified by the provided
+	 * IPath, or <code>null</code> if no Ant targets found.
+	 * 
+	 * @throws CoreException if file does not exist, IO problems, or invalid format.
+	 */
+	public static AntTargetList getTargetList(IPath path) throws CoreException {
+		IMemento memento = getMemento(path);
+		return getTargetList(memento);	
+	}
+	
+	/**
+	 * Returns an IMemento representing the Ant builder found in
+	 * the supplied IPath.
+	 * 
+	 * @throws CoreException if file does not exist, IO problems, or invalid format.
+	 */
+	private static IMemento getMemento(IPath path) throws CoreException {
+		try {
+			Reader reader = new FileReader(path.toFile());
+			IPath basePath = path.removeLastSegments(1).addTrailingSeparator();
+			return createReadRoot(reader, basePath.toOSString());
+		} catch (FileNotFoundException e) {
+			processException(e, "AntUtil.antFileNotFound", -1); //$NON-NLS-1$
+		}
+		
+		// Will never get here as processException will always throw
+		// a Core exception...but compiler does not know that!
+		return null;
+	}
+
+	/**
+	 * Creates a <code>Document</code> from the <code>Reader</code>
+	 * and returns a root memento for reading the document.
+	 * 
+	 * @param reader the reader used to create the memento's document
+	 * @param baseDir the directory to use to resolve relative file names
+	 * 		in XML document. This directory must exist and include a
+	 * 		trailing separator. The directory format, including the separators,
+	 * 		must be valid for the platform.
+	 * @return the root memento for reading the document
+	 * @throws CoreException if IO problems, or invalid XML format.
+	 */
+	private static XMLMemento createReadRoot(Reader reader, String baseDir) throws CoreException {
+		try {
+			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+			DocumentBuilder parser = factory.newDocumentBuilder();
+			parser.setEntityResolver(new AntEntityResolver(baseDir));
+			InputSource source = new InputSource(reader);
+			source.setSystemId(baseDir);
+			Document document = parser.parse(source);
+			NodeList list = document.getChildNodes();
+			for(int i=0; i < list.getLength(); i++) {
+				Node node = list.item(i);
+				if (node instanceof Element) {
+					return new XMLMemento(document, (Element) node);
+				}
+			}
+		} catch (ParserConfigurationException e) {
+			processException(e, "AntUtil.parserConfigError", -1); //$NON-NLS-1$
+		} catch (IOException e) {
+			processException(e, "AntUtil.ioError", -1); //$NON-NLS-1$
+		} catch (SAXParseException e) {
+			processException(e, "AntUtil.formatError", e.getLineNumber());
+		} catch (SAXException e) {
+			processException(e, "AntUtil.formatError", -1); //$NON-NLS-1$
+		}
+		
+		// Invalid ant file
+		processException(null, "AntUtil.invalidAntBuildFile", -1); //$NON-NLS-1$
+		
+		// Will never get here as processException will always throw
+		// a Core exception...but compiler does not know that!
+		return null;
+	}
+
+	/**
+	 * Returns the list of targets of the Ant file represented by the
+	 * supplied IMemento, or <code>null</code> if the memento is null or
+	 * does not represent a valid Ant file.
+	 */
+	private static AntTargetList getTargetList(IMemento memento) throws CoreException {
+		if (memento == null)
+			return null;
+		AntTargetList targets = new AntTargetList();
+		
+		String defaultTarget = memento.getString(ATT_DEFAULT);
+		targets.setDefaultTarget(defaultTarget);
+		
+		IMemento[] targetMementos = memento.getChildren(TAG_TARGET);
+		for (int i=0; i < targetMementos.length; i++) {
+			IMemento targetMemento = targetMementos[i];
+			String target = targetMemento.getString(ATT_NAME);
+			if (target!= null)
+				targets.add(target);
+		}
+		
+		// If the file has no targets, then it is not a
+		// valid Ant file.
+		if (targets.getTargetCount() == 0) {
+			return null;
+		} else {
+			targets.validateDefaultTarget();
+			return targets;
+		}
+	}
+	
+	/**
+	 * Process the exception by creating a well formatted
+	 * IStatus and throwing a CoreException with it.
+	 */
+	private static void processException(Exception e, String messageKey, int lineNumber) throws CoreException {
+		StringBuffer problem= new StringBuffer();
+		
+		if (lineNumber > 0) {
+			problem.append(MessageFormat.format("At line number: {0}", new String[]{Integer.toString(lineNumber)}));
+			problem.append(System.getProperty("line.separator")); //$NON-NLS-1$;
+		}
+		if (e != null) {
+			problem.append(e.getMessage());
+		}
+		if (problem.length() == 0) {
+			problem.append(ToolMessages.getString(messageKey));
+		}
+		IStatus status = new Status(IStatus.ERROR, ExternalToolsPlugin.PLUGIN_ID, 0, problem.toString(), e);
+		throw new CoreException(status);
+	}
+	
+	/**
+	 * EntityResolver used when parsing Ant files to find targets.
+	 */
+	private static class AntEntityResolver implements EntityResolver {
+		private String baseDir;
+		
+		public AntEntityResolver(String baseDir) {
+			this.baseDir = baseDir;
+		}
+		
+		public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
+			if (systemId == null) {
+				return null;
+			}
+			
+			// remove "file:" prefix
+			if (systemId.startsWith("file:")) { //$NON-NLS-1$
+				// 5 is the length of the string "file:"
+				systemId = systemId.substring(5);
+				File file = new File(systemId);
+				// If the file is not absolute, the systemId is relative
+				// to the baseDir.
+				if (!file.isAbsolute())
+					file = new File(baseDir, systemId);
+				Reader reader = new FileReader(file);
+				return new InputSource(reader);
+			}
+			
+			// use default behaviour if systemId does not have "file:" prefix
+			return null;
+		}
+	}
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/DefaultRunnerContext.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/DefaultRunnerContext.java
new file mode 100644
index 0000000..d04bb04
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/DefaultRunnerContext.java
@@ -0,0 +1,494 @@
+package org.eclipse.ui.externaltools.internal.core;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.io.File;
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+
+/**
+ * Context to run the external tool in.
+ */
+public final class DefaultRunnerContext implements IRunnerContext {
+	private ExternalTool tool;
+	private IProject currentProject;
+	private IResource selectedResource;
+	private IWorkingSetManager workingSetManager;
+	private ArrayList antTargets = new ArrayList();
+	private String expandedLocation;
+	private String expandedArguments;
+	private String expandedDirectory;
+	private String buildType = ToolUtil.BUILD_TYPE_NONE;
+	
+	/**
+	 * Create a new context
+	 * 
+	 * @param tool the external tool for which the context applies to
+	 * @param currentProject the project to run the external tool on, or <code>null</code>
+	 * @param manager the working set manager
+	 */
+	public DefaultRunnerContext(ExternalTool tool, IProject currentProject, IWorkingSetManager manager) {
+		this(tool, currentProject, null, manager);
+	}
+
+	/**
+	 * Create a new context
+	 * 
+	 * @param tool the external tool for which the context applies to
+	 * @param currentProject the project to run the external tool on, or <code>null</code>
+	 * @param selectedResource the selected resource to run the external tool on, or <code>null</code>
+	 * @param manager the working set manager
+	 */
+	public DefaultRunnerContext(ExternalTool tool, IProject currentProject, IResource selectedResource, IWorkingSetManager manager) {
+		super();
+		this.tool = tool;
+		this.currentProject = currentProject;
+		this.selectedResource = selectedResource;
+		this.workingSetManager = manager;
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on IRunnerContext.
+	 */
+	public String getName() {
+		return tool.getName();
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on IRunnerContext.
+	 */
+	public String[] getAntTargets() {
+		// Required because ant target variable tags
+		// are embedded in the tool's arguments and
+		// must be expanded beforehand.
+		getExpandedArguments();
+		
+		String[] results = new String[antTargets.size()];	
+		antTargets.toArray(results);
+		return results;
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on IRunnerContext.
+	 */
+	public String getExpandedLocation() {
+		if (expandedLocation == null)
+			expandedLocation = expandVariables(tool.getLocation(), false);
+		return expandedLocation;
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on IRunnerContext.
+	 */
+	public String getExpandedArguments() {
+		if (expandedArguments == null)
+			expandedArguments = expandVariables(tool.getArguments(), true);
+		return expandedArguments;
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on IRunnerContext.
+	 */
+	public String getExpandedWorkingDirectory() {
+		if (expandedDirectory == null)
+			expandedDirectory = expandVariables(tool.getWorkingDirectory(), false);
+		return expandedDirectory;
+	}
+	
+	/**
+	 * Returns whether or not the execution log should appear
+	 * on the log console.
+	 */
+	public boolean getShowLog() {
+		return tool.getShowLog();	
+	}
+
+	/**
+	 * Expands the variables found in the text.
+	 */
+	private String expandVariables(String text, boolean addQuotes) {
+		StringBuffer buffer = new StringBuffer();
+		
+		int start = 0;
+		while (true) {
+			ToolUtil.VariableDefinition varDef = ToolUtil.extractVariableTag(text, start);
+			
+			if (varDef.start == -1) {
+				if (start == 0)
+					buffer.append(text);
+				else
+					buffer.append(text.substring(start));
+				break;
+			} else if (varDef.start > start) {
+				buffer.append(text.substring(start, varDef.start));
+			}
+
+			if (varDef.end == -1) {
+				buffer.append(text.substring(varDef.start));
+				break;
+			} else {
+				start = varDef.end;
+			}
+
+			if (varDef.name != null)			
+				expandVariable(varDef, buffer, addQuotes);
+		}
+		
+		return buffer.toString();
+	}
+
+	/**
+	 * Expands the variable
+	 */
+	private void expandVariable(ToolUtil.VariableDefinition varDef, StringBuffer buf, boolean addQuotes) {
+		if (ExternalTool.VAR_BUILD_TYPE.equals(varDef.name)) {
+			appendVariable(buildType, buf, addQuotes);	
+		}
+
+		if (ExternalTool.VAR_ANT_TARGET.equals(varDef.name)) {
+			if (varDef.argument != null && varDef.argument.length() > 0)
+				antTargets.add(varDef.argument);
+			return;
+		}
+		
+		if (ExternalTool.VAR_WORKSPACE_LOC.equals(varDef.name)) {
+			String location = null;
+			if (varDef.argument != null && varDef.argument.length() > 0)
+				location = ToolUtil.getLocationFromFullPath(varDef.argument);
+			else
+				location = Platform.getLocation().toOSString();
+			appendVariable(location, buf, addQuotes);
+			return;
+		}
+		
+		if (ExternalTool.VAR_PROJECT_LOC.equals(varDef.name)) {
+			String location = null;
+			if (varDef.argument != null && varDef.argument.length() > 0) {
+				IResource member = ResourcesPlugin.getWorkspace().getRoot().findMember(varDef.argument);
+				if (member != null)
+					location = member.getProject().getLocation().toOSString();
+			} else {
+				if (currentProject != null)
+					location = currentProject.getLocation().toOSString();
+			}
+			appendVariable(location, buf, addQuotes);
+			return;
+		}
+		
+		if (ExternalTool.VAR_RESOURCE_LOC.equals(varDef.name)) {
+			String location = null;
+			if (varDef.argument != null && varDef.argument.length() > 0) {
+				location = ToolUtil.getLocationFromFullPath(varDef.argument);
+			} else {
+				if (selectedResource != null)
+					location = selectedResource.getLocation().toOSString();
+			}
+			appendVariable(location, buf, addQuotes);
+			return;			
+		}
+		
+		if (ExternalTool.VAR_CONTAINER_LOC.equals(varDef.name)) {
+			String location = null;
+			if (varDef.argument != null && varDef.argument.length() > 0) {
+				IResource member = ResourcesPlugin.getWorkspace().getRoot().findMember(varDef.argument);
+				if (member != null)
+					location = member.getParent().getLocation().toOSString();
+			} else {
+				if (selectedResource != null)
+					location = selectedResource.getParent().getLocation().toOSString();
+			}
+			appendVariable(location, buf, addQuotes);
+			return;			
+		}
+		
+		if (ExternalTool.VAR_PROJECT_PATH.equals(varDef.name)) {
+			String fullPath = null;
+			if (varDef.argument != null && varDef.argument.length() > 0) {
+				IResource member = ResourcesPlugin.getWorkspace().getRoot().findMember(varDef.argument);
+				if (member != null)
+					fullPath = member.getProject().getFullPath().toString();
+			} else {
+				if (currentProject != null)
+					fullPath = currentProject.getFullPath().toString();
+			}
+			appendVariable(fullPath, buf, addQuotes);
+			return;
+		}
+		
+		if (ExternalTool.VAR_RESOURCE_PATH.equals(varDef.name)) {
+			String fullPath = null;
+			if (varDef.argument != null && varDef.argument.length() > 0) {
+				IResource member = ResourcesPlugin.getWorkspace().getRoot().findMember(varDef.argument);
+				if (member != null)
+					fullPath = member.getFullPath().toString();
+			} else {
+				if (selectedResource != null)
+					fullPath = selectedResource.getFullPath().toString();
+			}
+			appendVariable(fullPath, buf, addQuotes);
+			return;			
+		}
+		
+		if (ExternalTool.VAR_CONTAINER_PATH.equals(varDef.name)) {
+			String fullPath = null;
+			if (varDef.argument != null && varDef.argument.length() > 0) {
+				IResource member = ResourcesPlugin.getWorkspace().getRoot().findMember(varDef.argument);
+				if (member != null)
+					fullPath = member.getParent().getFullPath().toString();
+			} else {
+				if (selectedResource != null)
+					fullPath = selectedResource.getParent().getFullPath().toString();
+			}
+			appendVariable(fullPath, buf, addQuotes);
+			return;			
+		}
+		
+		if (ExternalTool.VAR_PROJECT_NAME.equals(varDef.name)) {
+			String name = null;
+			if (varDef.argument != null && varDef.argument.length() > 0) {
+				IResource member = ResourcesPlugin.getWorkspace().getRoot().findMember(varDef.argument);
+				if (member != null)
+					name = member.getProject().getName();
+			} else {
+				if (currentProject != null)
+					name = currentProject.getName();
+			}
+			appendVariable(name, buf, addQuotes);
+			return;
+		}
+		
+		if (ExternalTool.VAR_RESOURCE_NAME.equals(varDef.name)) {
+			String name = null;
+			if (varDef.argument != null && varDef.argument.length() > 0) {
+				IResource member = ResourcesPlugin.getWorkspace().getRoot().findMember(varDef.argument);
+				if (member != null)
+					name = member.getName();
+			} else {
+				if (selectedResource != null)
+					name = selectedResource.getName();
+			}
+			appendVariable(name, buf, addQuotes);
+			return;			
+		}
+		
+		if (ExternalTool.VAR_CONTAINER_NAME.equals(varDef.name)) {
+			String name = null;
+			if (varDef.argument != null && varDef.argument.length() > 0) {
+				IResource member = ResourcesPlugin.getWorkspace().getRoot().findMember(varDef.argument);
+				if (member != null)
+					name = member.getParent().getName();
+			} else {
+				if (selectedResource != null)
+					name = selectedResource.getParent().getName();
+			}
+			appendVariable(name, buf, addQuotes);
+			return;			
+		}
+	}
+
+	/**
+	 * Helper method to add the given variable string to the given
+	 * string buffer if the string is not null. Adds enclosing quotation
+	 * marks if addQuotes is true.
+	 * 
+	 * @param var the variable string to be added
+	 * @param buf the string buffer to which the string will be added
+	 * @parman addQuotes whether or not to add enclosing quotation marks
+	 */
+	private void appendVariable(String var, StringBuffer buf, boolean addQuotes) {
+		if (var != null) {
+			if (addQuotes && ToolUtil.hasSpace(var))
+				buf.append("\""); //$NON-NLS-1$
+			buf.append(var);
+			if (addQuotes && ToolUtil.hasSpace(var))
+				buf.append("\""); //$NON-NLS-1$			
+		}
+	}
+	
+	/**
+	 * Executes the runner to launch the external tool. A resource refresh
+	 * is done if specified.
+	 * 
+	 * @param monitor the monitor to report progress to, or <code>null</code>.
+	 */
+	private void executeRunner(IProgressMonitor monitor) throws CoreException, InterruptedException {
+		if (monitor == null)
+			monitor = new NullProgressMonitor();
+		try {
+			ToolUtil.VariableDefinition scope = ToolUtil.extractVariableTag(tool.getRefreshScope(), 0);
+			ExternalToolsRunner runner = ToolUtil.getRunner(tool.getType());
+			if (runner != null) {
+				if (scope.name == null || ExternalTool.REFRESH_SCOPE_NONE.equals(scope.name)) {
+					runner.execute(monitor, this);
+				} else {
+					monitor.beginTask(ToolMessages.getString("DefaultRunnerContext.runningExternalTool"), 100); //$NON-NLS-1$
+					runner.execute(new SubProgressMonitor(monitor, 70), this);
+					refreshResources(new SubProgressMonitor(monitor, 30), scope.name, scope.argument);
+				}
+			}
+		} finally {
+			monitor.done();
+		}
+	}
+	
+	/**
+	 * Runs the external tool and does a resource refresh if specified.
+	 * The tool is validated within this context before being
+	 * runned. Any problems will cause an exception to be thrown.
+	 * 
+	 * @param monitor the monitor to report progress to, or <code>null</code>.
+	 */
+	public void run(IProgressMonitor monitor) throws CoreException, InterruptedException {
+		String problem = validateInContext();
+		if (problem != null) {
+			IStatus status = new Status(IStatus.WARNING, ExternalToolsPlugin.PLUGIN_ID, 0, problem, null);
+			throw new CoreException(status);
+		}
+		
+		executeRunner(monitor);
+	}
+
+	/**
+	 * Runs the external tool and does a resource refresh if specified.
+	 * The tool is validated within this context before being
+	 * runned. Any problems are displayed to the user in a dialog box.
+	 * 
+	 * @param monitor the monitor to report progress to, or <code>null</code>.
+	 * @param shell the shell to parent the error message dialog
+	 */
+	public void run(IProgressMonitor monitor, final Shell shell) throws InterruptedException {
+		try {
+			final String problem = validateInContext();
+			if (problem != null) {
+				shell.getDisplay().syncExec(new Runnable() { 
+					public void run() {
+						MessageDialog.openError(
+							shell, 
+							ToolMessages.getString("DefaultRunnerContext.errorShellTitle"), //$NON-NLS-1$
+							problem);
+					}
+				});
+			} else {
+				executeRunner(monitor);
+			}
+		} catch (final CoreException e) {
+			shell.getDisplay().syncExec(new Runnable() { 
+				public void run() {
+					ErrorDialog.openError(
+						shell,
+						ToolMessages.getString("DefaultRunnerContext.errorShellTitle"), //$NON-NLS-1$
+						ToolMessages.getString("DefaultRunnerContext.errorMessage"), //$NON-NLS-1$
+						e.getStatus());
+				}
+			});
+		}
+	}
+
+	/**
+	 * Causes the specified resources to be refreshed.
+	 */
+	private void refreshResources(IProgressMonitor monitor, String scope, String argument) throws CoreException {
+		if (ExternalTool.REFRESH_SCOPE_WORKSPACE.equals(scope)) {
+			ResourcesPlugin.getWorkspace().getRoot().refreshLocal(IResource.DEPTH_INFINITE, monitor);
+			return;
+		}
+		
+		if (ExternalTool.REFRESH_SCOPE_PROJECT.equals(scope)) {
+			IProject container = null;
+			if (argument == null) {
+				container = currentProject;
+			} else {
+				container = ResourcesPlugin.getWorkspace().getRoot().getProject(argument);
+			}
+			if (container != null && container.isAccessible())
+				container.refreshLocal(IResource.DEPTH_INFINITE, monitor);
+			return;
+		}
+		
+		if (ExternalTool.REFRESH_SCOPE_WORKING_SET.equals(scope)) {
+			if (argument == null)
+				return;
+			IWorkingSet set = workingSetManager.getWorkingSet(argument);
+			if (set == null)
+				return;
+			try {
+				IAdaptable[] elements = set.getElements();
+				monitor.beginTask(
+					ToolMessages.getString("DefaultRunnerContext.refreshWorkingSet"), //$NON-NLS-1$
+					elements.length);
+				for (int i = 0; i < elements.length; i++) {
+					IAdaptable adaptable = elements[i];
+					IResource resource;
+					
+					if (adaptable instanceof IResource)
+						resource = (IResource) adaptable;
+					else
+						resource = (IResource) adaptable.getAdapter(IResource.class);
+					if (resource != null)
+						resource.refreshLocal(IResource.DEPTH_INFINITE, null);
+
+					monitor.worked(1);
+				}
+			}
+			finally {
+				monitor.done();
+			}
+			
+			return;
+		}
+	}
+	
+	/**
+	 * Validates the external tool to ensure the external tool location and
+	 * working directory exist in the file system.
+	 * 
+	 * @return the problem text is validate fails, or <code>null</code>
+	 * 		if all seems valid.
+	 */
+	private String validateInContext() {
+		String loc = getExpandedLocation();
+		if (loc == null || loc.length() == 0)
+			return ToolMessages.format("DefaultRunnerContext.invalidLocation", new Object[] {tool.getName()}); //$NON-NLS-1$
+		File file = new File(loc);
+		if (!file.isFile())
+			return  ToolMessages.format("DefaultRunnerContext.invalidLocation", new Object[] {tool.getName()}); //$NON-NLS-1$
+		
+		String dir = getExpandedWorkingDirectory();
+		if (dir != null && dir.length() > 0) {
+			File path = new File(dir);
+			if (!path.isDirectory())
+				return ToolMessages.format("DefaultRunnerContext.invalidDirectory", new Object[] {tool.getName()}); //$NON-NLS-1$
+		}
+		
+		return null;
+	}
+	
+	/**
+	 * Set the build type for this runner context. The build type is the type 
+	 * of build (one of ToolUtil.BUILD_TYPE_INCREMENTAL, ToolUtil.BUILD_TYPE_AUTO,
+	 * or ToolUtil.BUILD_TYPE_FULL) if the tool being run is running as a project
+	 * builder, or ToolUtil.BUILD_TYPE_NONE otherwise.
+	 */
+	/*package*/ void setBuildType(int kind) {
+		if (kind == IncrementalProjectBuilder.INCREMENTAL_BUILD)
+			buildType = ToolUtil.BUILD_TYPE_INCREMENTAL;
+		else if (kind == IncrementalProjectBuilder.FULL_BUILD)
+			buildType = ToolUtil.BUILD_TYPE_FULL;
+		else if (kind == IncrementalProjectBuilder.AUTO_BUILD)
+			buildType = ToolUtil.BUILD_TYPE_AUTO;
+		else 
+			buildType = ToolUtil.BUILD_TYPE_NONE;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalTool.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalTool.java
new file mode 100644
index 0000000..ddc315a
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalTool.java
@@ -0,0 +1,298 @@
+package org.eclipse.ui.externaltools.internal.core;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.ICommand;
+
+/**
+ * This class represents an external tool that can be run. The tool
+ * can be inside or outside the workspace.
+ * <p>
+ * An external tool consist of a user defined name, a path to the location
+ * of the file, optional arguments for the file, and the working
+ * directory.
+ * </p><p>
+ * After the tool has run, part or all of the workspace can be
+ * refreshed to pickup changes made by the tool. This is optional
+ * and does nothing by default
+ * </p>
+ */
+public class ExternalTool {
+	// Internal tags for storing tool related information
+	private static final String TAG_TOOL_TYPE = "!{tool_type}"; //$NON-NLS-1$
+	private static final String TAG_TOOL_NAME = "!{tool_name}"; //$NON-NLS-1$
+	private static final String TAG_TOOL_LOCATION = "!{tool_loc}"; //$NON-NLS-1$
+	private static final String TAG_TOOL_ARGUMENTS = "!{tool_args}"; //$NON-NLS-1$
+	private static final String TAG_TOOL_DIRECTORY = "!{tool_dir}"; //$NON-NLS-1$
+	private static final String TAG_TOOL_REFRESH = "!{tool_refresh}"; //$NON-NLS-1$
+	private static final String TAG_TOOL_SHOW_LOG = "!{tool_show_log}"; //$NON-NLS-1$
+	
+	// Known kind of tools
+	public static final String TOOL_TYPE_PROGRAM = "org.eclipse.ui.externaltools.type.program"; //$NON-NLS-1$
+	public static final String TOOL_TYPE_ANT = "org.eclipse.ui.externaltools.type.ant"; //$NON-NLS-1$
+	
+	// Variable names the tool will expand
+	public static final String VAR_WORKSPACE_LOC = "workspace_loc"; //$NON-NLS-1$
+
+	public static final String VAR_PROJECT_LOC = "project_loc"; //$NON-NLS-1$
+	public static final String VAR_PROJECT_PATH = "project_path"; //$NON-NLS-1$
+	public static final String VAR_PROJECT_NAME = "project_name"; //$NON-NLS-1$
+
+	public static final String VAR_RESOURCE_LOC = "resource_loc"; //$NON-NLS-1$
+	public static final String VAR_RESOURCE_PATH = "resource_path"; //$NON-NLS-1$
+	public static final String VAR_RESOURCE_NAME = "resource_name"; //$NON-NLS-1$
+
+	public static final String VAR_CONTAINER_LOC = "container_loc"; //$NON-NLS-1$
+	public static final String VAR_CONTAINER_PATH = "container_path"; //$NON-NLS-1$
+	public static final String VAR_CONTAINER_NAME = "container_name"; //$NON-NLS-1$
+
+	public static final String VAR_EDITOR_CUR_COL = "editor_cur_col"; //$NON-NLS-1$
+	public static final String VAR_EDITOR_CUR_LINE = "editor_cur_line"; //$NON-NLS-1$
+	public static final String VAR_EDITOR_SEL_TEXT = "editor_sel_text"; //$NON-NLS-1$
+
+	public static final String VAR_ANT_TARGET = "ant_target"; //$NON-NLS-1$
+	public static final String VAR_BUILD_TYPE = "build_type"; //$NON-NLS-1$
+
+	// Known refresh scopes
+	public static final String REFRESH_SCOPE_NONE = "none"; //$NON-NLS-1$;
+	public static final String REFRESH_SCOPE_WORKSPACE = "workspace"; //$NON-NLS-1$;
+	public static final String REFRESH_SCOPE_PROJECT = "project"; //$NON-NLS-1$;
+	public static final String REFRESH_SCOPE_WORKING_SET = "working_set"; //$NON-NLS-1$;
+	
+	private static final String EMPTY_VALUE = ""; //$NON-NLS-1$;
+	private static final String TRUE = "true"; //$NON-NLS-1$
+	private static final String FALSE = "false"; //$NON-NLS-1$
+	
+	private String type = TOOL_TYPE_PROGRAM;
+	private String name = EMPTY_VALUE;
+	private String location = EMPTY_VALUE;
+	private String arguments = EMPTY_VALUE;
+	private String directory = EMPTY_VALUE;
+	private String refreshScope = EMPTY_VALUE;
+	private boolean showLog = true;
+	
+	/**
+	 * Creates an empty initialized external tool.
+	 */
+	public ExternalTool() {
+		super();
+		this.refreshScope = ToolUtil.buildVariableTag(REFRESH_SCOPE_NONE, null);
+	}
+
+	/**
+	 * Creates a fully initialized external tool.
+	 */
+	public ExternalTool(String type, String name, String location, String arguments, String directory, String refreshScope, boolean showLog) {
+		this();
+		if (type != null)
+			this.type = type;
+		if (name != null)
+			this.name = name;
+		if (location != null)
+			this.location = location;
+		if (arguments != null)
+			this.arguments = arguments;
+		if (directory != null)
+			this.directory = directory;
+		if (refreshScope != null)
+			this.refreshScope = refreshScope;
+		this.showLog = showLog;
+	}
+	
+	/**
+	 * Creates an external tool based on specified arguments.
+	 * Returns null if no corresponding external tool could be created.
+	 */
+	public static ExternalTool fromArgumentMap(Map args) {
+		// Validate the critical information.
+		String type = (String)args.get(TAG_TOOL_TYPE);
+		String name = (String)args.get(TAG_TOOL_NAME);
+		String location = (String)args.get(TAG_TOOL_LOCATION);
+		if (type == null || name == null || location == null)
+			return null;
+		if (type.length() == 0 || name.length() == 0 || location.length() == 0)
+			return null;
+		String sShowLog = (String)args.get(TAG_TOOL_SHOW_LOG);
+		boolean showLog;
+		if (FALSE.equals(sShowLog))
+			showLog = false;
+		else
+			showLog = true;
+			
+		return new ExternalTool(
+			type,
+			name,
+			location,
+			(String)args.get(TAG_TOOL_ARGUMENTS),
+			(String)args.get(TAG_TOOL_DIRECTORY),
+			(String)args.get(TAG_TOOL_REFRESH),
+			showLog);
+	}
+
+	/**
+	 * Returns the type of external tool.
+	 */
+	public String getType() {
+		return type;
+	}
+	
+	/**
+	 * Returns the name of the external tool.
+	 */
+	public String getName() {
+		return name;
+	}
+	
+	/**
+	 * Returns the path where the external tool is located.
+	 */
+	public String getLocation() {
+		return location;
+	}
+	
+	/**
+	 * Returns the arguments for the external tool.
+	 */
+	public String getArguments() {
+		return arguments;
+	}
+	
+	/**
+	 * Returns the working directory to run the external tool in.
+	 */
+	public String getWorkingDirectory() {
+		return directory;
+	}
+	
+	/**
+	 * Returns the scope of resources to refresh after
+	 * the external tool is run
+	 */
+	public String getRefreshScope() {
+		return refreshScope;
+	}
+	
+	/**
+	 * Returns whether or not the execution log of the external tool
+	 * will be shown on the log console.
+	 */
+	public boolean getShowLog() {
+		return showLog;	
+	}
+	
+	/**
+	 * Sets the type of external tool.
+	 */
+	public void setType(String type) {
+		if (type == null)
+			this.type = EMPTY_VALUE;
+		else
+			this.type = type;
+	}
+	
+	/**
+	 * Sets the name of the external tool.
+	 */
+	public void setName(String name) {
+		if (name == null)
+			this.name = EMPTY_VALUE;
+		else
+			this.name = name;
+	}
+	
+	/**
+	 * Sets the path where the external tool is located.
+	 */
+	public void setLocation(String location) {
+		if (location == null)
+			this.location = EMPTY_VALUE;
+		else
+			this.location = location;
+	}
+	
+	/**
+	 * Sets the arguments for the external tool.
+	 */
+	public void setArguments(String arguments) {
+		if (arguments == null)
+			this.arguments = EMPTY_VALUE;
+		else
+			this.arguments = arguments;
+	}
+	
+	/**
+	 * Sets the working directory to run the external tool in.
+	 */
+	public void setWorkingDirectory(String directory) {
+		if (directory == null)
+			this.directory = EMPTY_VALUE;
+		else
+			this.directory = directory;
+	}
+	
+	/**
+	 * Sets the scope of resources to refresh after
+	 * the external tool is run
+	 */
+	public void setRefreshScope(String refreshScope) {
+		if (refreshScope == null || refreshScope.length() < 1)
+			this.refreshScope = ToolUtil.buildVariableTag(REFRESH_SCOPE_NONE, null);
+		else
+			this.refreshScope = refreshScope;
+	}
+	
+	/**
+	 * Sets whether or not the execution log of the external tool should
+	 * be shown on the log console.
+	 */
+	public void setShowLog(boolean showLog) {
+		this.showLog = showLog;	
+	}
+	
+	/**
+	 * Stores the external tool as an argument map that can be
+	 * used later on to recreate this external tool.
+	 * 
+	 * @return the argument map
+	 */
+	public Map toArgumentMap() {
+		HashMap args = new HashMap();
+		args.put(TAG_TOOL_TYPE, type);
+		args.put(TAG_TOOL_NAME, name);
+		args.put(TAG_TOOL_LOCATION, location);
+		args.put(TAG_TOOL_ARGUMENTS, arguments);
+		args.put(TAG_TOOL_DIRECTORY, directory);
+		args.put(TAG_TOOL_REFRESH, refreshScope);
+		if (showLog)
+			args.put(TAG_TOOL_SHOW_LOG, TRUE);
+		else
+			args.put(TAG_TOOL_SHOW_LOG, FALSE);
+		
+		return args;
+	}
+
+	/**
+	 * Configures the given build command to invoke this
+	 * external tool.
+	 * 
+	 * @param command the build command to configure
+	 * @return the configured command.
+	 */
+	public ICommand toBuildCommand(ICommand command) {
+		Map args = toArgumentMap();
+		command.setBuilderName(ExternalToolsBuilder.ID);
+		command.setArguments(args);
+		
+		return command;
+	}
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsBuilder.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsBuilder.java
new file mode 100644
index 0000000..a02950d
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsBuilder.java
@@ -0,0 +1,57 @@
+package org.eclipse.ui.externaltools.internal.core;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * The external tool builder can be added to the build spec of a project to run 
+ * external tools inside the incremental build process.
+ * <p>
+ * Note that there is only ever one instance of ExternalToolsBuilder per project,
+ * and the external tool to run is specified in the builder's arguments.
+ * </p>
+ */
+public final class ExternalToolsBuilder extends IncrementalProjectBuilder {
+	public static final String ID = "org.eclipse.ui.externaltools.ExternalToolBuilder";
+
+	/**
+	 * Creates an uninitialized external tool builder.
+	 */
+	public ExternalToolsBuilder() {
+		super();
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on IncrementalProjectBuilder.
+	 */
+	protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
+		ExternalTool tool = ExternalTool.fromArgumentMap(args);
+		if (tool != null) {
+			DefaultRunnerContext context = new DefaultRunnerContext(tool, getProject(), PlatformUI.getWorkbench().getWorkingSetManager());
+			context.setBuildType(kind);
+			try {
+				context.run(monitor);
+			} catch (InterruptedException e) {
+				// Do nothing, the operation was cancelled by the user
+			} finally {
+				forgetLastBuiltState();
+			}
+		}
+		
+		return null;
+	}
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsPlugin.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsPlugin.java
new file mode 100644
index 0000000..b07d72f
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsPlugin.java
@@ -0,0 +1,107 @@
+package org.eclipse.ui.externaltools.internal.core;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.net.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.preference.*;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+/**
+ * External tools plug-in class
+ */
+public final class ExternalToolsPlugin extends AbstractUIPlugin {
+	public static final String PLUGIN_ID = "org.eclipse.ui.externaltools"; //$NON-NLS-1$;
+	/*package*/ static final String LOG_CONSOLE_ID = PLUGIN_ID + ".LogConsoleView"; //$NON-NLS-1$;
+	
+	public static final String IMG_ANT_TOOL= "icons/full/obj16/ant_file.gif"; //$NON-NLS-1$;
+	public static final String IMG_BUILDER= "icons/full/obj16/builder.gif"; //$NON-NLS-1$;
+	public static final String IMG_JAR_FILE = "icons/full/obj16/jar_l_obj.gif"; //$NON-NLS-1$;
+	public static final String IMG_CLASSPATH = "icons/full/obj16/classpath.gif"; //$NON-NLS-1$;
+	public static final String IMG_TYPE = "icons/full/obj16/type.gif"; //$NON-NLS-1$;
+	public static final String IMG_EXTERNAL_TOOL = "icons/full/obj16/external_tools.gif"; //$NON-NLS-1$
+	public static final String IMG_INVALID_BUILD_TOOL = "icons/full/obj16/invalid_build_tool.gif"; //$NON-NLS-1$
+	public static final String IMG_WIZBAN_EXTERNAL_TOOLS = "icons/full/wizban/ext_tools_wiz.gif"; //$NON-NLS-1$
+	
+	private static ExternalToolsPlugin plugin;
+	private ExternalToolsRegistry registry;
+	
+	/**
+	 * Create an instance of the External Tools plug-in.
+	 */
+	public ExternalToolsPlugin(IPluginDescriptor descriptor) {
+		super(descriptor);
+		plugin = this;
+	}
+	
+	/**
+	 * Returns the default instance of the receiver.
+	 * This represents the runtime plugin.
+	 */
+	public static ExternalToolsPlugin getDefault() {
+		return plugin;
+	}
+
+	/**
+	 * Returns the registry of external tools that the
+	 * user can run using the external tools menu. Does
+	 * not include external tools part of the build process.
+	 */
+	public ExternalToolsRegistry getRegistry() {
+		if (registry == null)
+			registry = new ExternalToolsRegistry();
+		return registry;
+	}
+
+	/**
+	 * Writes the message to the plug-in's log
+	 * 
+	 * @param message the text to write to the log
+	 */
+	public void log(String message, Throwable exception) {
+		Status status = new Status(Status.ERROR, PLUGIN_ID, 0, message, exception);
+		getLog().log(status);
+		System.err.println(message);
+	}
+
+	/**
+	 * Returns the ImageDescriptor for the icon with the given path
+	 * 
+	 * @return the ImageDescriptor object
+	 */
+	public ImageDescriptor getImageDescriptor(String path) {
+		try {
+			URL installURL = getDescriptor().getInstallURL();
+			URL url = new URL(installURL,path);
+			return ImageDescriptor.createFromURL(url);
+		} catch (MalformedURLException e) {
+			return null;
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared in AbstractUIPlugin.
+	 */
+	protected void initializeDefaultPreferences(IPreferenceStore prefs) {
+		prefs.setDefault(IPreferenceConstants.AUTO_SAVE, false);
+		prefs.setDefault(IPreferenceConstants.INFO_LEVEL, true);
+		prefs.setDefault(IPreferenceConstants.VERBOSE_LEVEL, false);
+		prefs.setDefault(IPreferenceConstants.DEBUG_LEVEL, false);
+	
+		PreferenceConverter.setDefault(prefs, IPreferenceConstants.CONSOLE_ERROR_RGB, new RGB(255, 0, 0)); 		// red - exactly the same as debug Consol
+		PreferenceConverter.setDefault(prefs, IPreferenceConstants.CONSOLE_WARNING_RGB, new RGB(255, 100, 0)); 	// orange
+		PreferenceConverter.setDefault(prefs, IPreferenceConstants.CONSOLE_INFO_RGB, new RGB(0, 0, 255)); 		// blue
+		PreferenceConverter.setDefault(prefs, IPreferenceConstants.CONSOLE_VERBOSE_RGB, new RGB(0, 200, 125));	// green
+		PreferenceConverter.setDefault(prefs, IPreferenceConstants.CONSOLE_DEBUG_RGB, new RGB(0, 0, 0));			// black
+	}	
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsRegistry.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsRegistry.java
new file mode 100644
index 0000000..b5acded
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsRegistry.java
@@ -0,0 +1,183 @@
+package org.eclipse.ui.externaltools.internal.core;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.XMLMemento;
+
+/**
+ * The registry of user defined external tools that can
+ * be run using the external tool menu. It does not include
+ * any external tools that are assigned as builders on a
+ * project.
+ */
+public final class ExternalToolsRegistry {
+	private static final String STATE_FILE_NAME = "externaltools.xml"; //$NON-NLS-1$
+	private static final String TAG_EXTERNALTOOLS = "externaltools"; //$NON-NLS-1$
+	private static final String TAG_TOOL = "tool"; //$NON-NLS-1$
+	private static final String TAG_ENTRY = "entry"; //$NON-NLS-1$
+	private static final String TAG_KEY = "key"; //$NON-NLS-1$
+	private static final String TAG_VALUE = "value"; //$NON-NLS-1$
+	
+	private ArrayList externalTools;
+
+	/**
+	 * Creates the registry and loads the saved
+	 * external tools.
+	 */
+	/*package*/ ExternalToolsRegistry() {
+		super();
+		loadExternalTools();
+	}
+
+	/**
+	 * Returns the named external tool or <code>null</code>
+	 * if not found.
+	 */
+	public ExternalTool getExternalTool(String name) {
+		Iterator enum = externalTools.iterator();
+		while (enum.hasNext()) {
+			ExternalTool tool = (ExternalTool)enum.next();
+			if (tool.getName().equals(name))
+				return tool;
+		}
+		return null;
+	}
+	
+	/**
+	 * Returns the external tools of the registry
+	 */
+	public ArrayList getExternalTools() {
+		return externalTools;
+	}
+	
+	/**
+	 * Sets the external tools for the registry.
+	 * Causes them to be saved to disk.
+	 */
+	public boolean setExternalTools(ArrayList tools) {
+		this.externalTools = tools;
+		return saveExternalTools();
+	}
+	
+	/**
+	 * Loads the external tools from storage and
+	 * adds them to the registry.
+	 */
+	private void loadExternalTools() {
+		IPath path = ExternalToolsPlugin.getDefault().getStateLocation();
+		path = path.append(STATE_FILE_NAME);
+		InputStreamReader reader = null;
+		try {
+			FileInputStream input = new FileInputStream(path.toFile());
+			reader = new InputStreamReader(input, "utf-8"); //$NON-NLS-1$
+			XMLMemento memento = XMLMemento.createReadRoot(reader);
+			
+			// Get the external tool children element
+			IMemento[] tools = memento.getChildren(TAG_TOOL);
+			externalTools = new ArrayList(tools.length);
+			for (int i = 0; i < tools.length; i++) {
+				HashMap args = new HashMap();
+				IMemento[] entries = tools[i].getChildren(TAG_ENTRY);
+				for (int j = 0; j < entries.length; j++) {
+					String key = entries[j].getString(TAG_KEY);
+					if (key != null) {
+						String value = entries[j].getTextData();
+						args.put(key, value);
+					}
+				}
+				ExternalTool tool = ExternalTool.fromArgumentMap(args);
+				if (tool != null)
+					externalTools.add(tool);
+			}
+		}
+		catch (FileNotFoundException e) {
+			// Silently ignore this...
+		}
+		catch (IOException e) {
+			ExternalToolsPlugin.getDefault().log("File I/O error with external tool state reader.", e); //$NON-NLS-1$
+		}
+		catch (WorkbenchException e) {
+			ExternalToolsPlugin.getDefault().getLog().log(e.getStatus());
+			System.err.println("Error with external tool state reader. See .log file for more details"); //$NON-NLS-1$
+		}
+		finally {
+			if (reader != null) {
+				try {
+					reader.close();
+				} catch(IOException e) {
+					ExternalToolsPlugin.getDefault().log("Unable to close external tool state reader.", e); //$NON-NLS-1$
+				}
+			}
+			if (externalTools == null)
+				externalTools = new ArrayList(0);
+		}
+	}
+	
+	/**
+	 * Saves the external tool to storage.
+	 * 
+	 * @return true if save is successful, false otherwise.
+	 */
+	/*package*/ boolean saveExternalTools() {
+		boolean successful = true;
+		
+		// Populate the memento
+		XMLMemento memento = XMLMemento.createWriteRoot(TAG_EXTERNALTOOLS);
+		Iterator enum = externalTools.iterator();
+		while (enum.hasNext()) {
+			IMemento toolMemento = memento.createChild(TAG_TOOL);
+			ExternalTool tool = (ExternalTool)enum.next();
+			Map args = tool.toArgumentMap();
+			Iterator entries = args.entrySet().iterator();
+			while (entries.hasNext()) {
+				Map.Entry entry = (Map.Entry)entries.next();
+				IMemento entryMemento = toolMemento.createChild(TAG_ENTRY);
+				entryMemento.putString(TAG_KEY, (String)entry.getKey());
+				entryMemento.putTextData((String)entry.getValue());
+			}
+		}
+
+		// Write the memento to the state file		
+		IPath path = ExternalToolsPlugin.getDefault().getStateLocation();
+		path = path.append(STATE_FILE_NAME);
+		File stateFile = path.toFile();
+		try {
+			FileOutputStream stream = new FileOutputStream(stateFile);
+			OutputStreamWriter writer = new OutputStreamWriter(stream, "utf-8"); //$NON-NLS-1$
+			memento.save(writer);
+			writer.close();
+		} catch (IOException e) {
+			stateFile.delete();
+			MessageDialog.openError(
+				null,
+				ToolMessages.getString("ExternalToolsRegistry.saveStateErrorTitle"), //$NON-NLS-1$
+				ToolMessages.getString("ExternalToolsRegistry.saveStateError")); //$NON-NLS-1$
+			successful = false;
+		}
+		
+		return successful;
+	}
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsRunner.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsRunner.java
new file mode 100644
index 0000000..e882b74
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ExternalToolsRunner.java
@@ -0,0 +1,54 @@
+package org.eclipse.ui.externaltools.internal.core;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * Responsible for executing the external tool. Clients
+ * must provide a public no-argument constructor
+ */
+public abstract class ExternalToolsRunner {
+
+	/**
+	 * Creates an empty external tool runner
+	 */
+	public ExternalToolsRunner() {
+		super();
+	}
+
+	/**
+	 * Execute the external tool within the given context. Subclasses
+	 * are responsible for showing the execution log if
+	 * specified in the context.
+	 */
+	public abstract void execute(IProgressMonitor monitor, IRunnerContext runnerContext) throws CoreException, InterruptedException;
+	
+	/**
+	 * Handles exceptions that may occur while running.
+	 */
+	protected final void handleException(Exception e) throws CoreException {
+		String msg = e.getMessage();
+		if (msg == null)
+			msg = ToolMessages.getString("ExternalToolsRunner.internalErrorMessage"); //$NON-NLS-1$;
+		throw new CoreException(new Status(IStatus.ERROR, ExternalToolsPlugin.PLUGIN_ID, 0, msg, e));
+	}
+
+	/**
+	 * Starts the monitor to show progress while running.
+	 */
+	protected final void startMonitor(IProgressMonitor monitor, IRunnerContext runnerContext, int workAmount) {
+		String label = ToolMessages.format("ExternalToolsRunner.runningToolLabel", new Object[] {runnerContext.getName()}); //$NON-NLS-1$;
+		monitor.beginTask(label, workAmount);
+	}
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/IPreferenceConstants.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/IPreferenceConstants.java
new file mode 100644
index 0000000..11e7de4
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/IPreferenceConstants.java
@@ -0,0 +1,30 @@
+package org.eclipse.ui.externaltools.internal.core;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+
+/**
+ * Constants used to identify user preferences.
+ */
+public interface IPreferenceConstants {
+	public static final String AUTO_SAVE = "externaltools.auto_save"; // $NON-NLS-1$
+
+	public static final String OUPUT_LEVEL = "externaltools.outputLevel"; // $NON-NLS-1$
+ 	public static final String INFO_LEVEL = "externaltools.infoLevel"; // $NON-NLS-1$
+ 	public static final String VERBOSE_LEVEL = "externaltools.verboseLevel"; // $NON-NLS-1$
+ 	public static final String DEBUG_LEVEL = "externaltools.levelLevel"; // $NON-NLS-1$
+	
+	public static final String CONSOLE_ERROR_RGB = "externaltools.console.errorColor"; // $NON-NLS-1$
+	public static final String CONSOLE_WARNING_RGB = "externaltools.console.warningColor"; // $NON-NLS-1$
+ 	public static final String CONSOLE_INFO_RGB = "externaltools.console.infoColor"; // $NON-NLS-1$
+ 	public static final String CONSOLE_VERBOSE_RGB = "externaltools.console.verboseColor"; // $NON-NLS-1$
+ 	public static final String CONSOLE_DEBUG_RGB = "externaltools.console.debugColor"; // $NON-NLS-1$
+ 	public static final String CONSOLE_FONT = "externaltools.console.font"; // $NON-NLS-1$
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/IRunnerContext.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/IRunnerContext.java
new file mode 100644
index 0000000..1ebd197
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/IRunnerContext.java
@@ -0,0 +1,56 @@
+package org.eclipse.ui.externaltools.internal.core;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+
+/**
+ * Represents the context in which to run the
+ * external tools.
+ */
+public interface IRunnerContext {
+	/**
+	 * Returns the name of the external tool.
+	 */
+	public String getName();
+	
+	/**
+	 * Returns the path where the external tool is located. All
+	 * variables embedded in the path have been fully
+	 * expanded.
+	 */
+	public String getExpandedLocation();
+	
+	/**
+	 * Returns the targets for an Ant file. The
+	 * targets are collected from the corresponding
+	 * variable tags in the external tool's arguments.
+	 */
+	public String[] getAntTargets();
+	
+	/**
+	 * Returns the arguments for the external tool. All
+	 * variables embedded in the arguments have been fully
+	 * expanded.
+	 */
+	public String getExpandedArguments();
+	
+	/**
+	 * Returns the working directory to run the external tool in.
+	 * All variables embedded in the path have been fully
+	 * expanded.
+	 */
+	public String getExpandedWorkingDirectory();
+	
+	/**
+	 * Returns whether or not the execution log for the
+	 * external tool should appear on the log console.
+	 */
+	public boolean getShowLog();
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ProgramRunner.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ProgramRunner.java
new file mode 100644
index 0000000..fe4dee1
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ProgramRunner.java
@@ -0,0 +1,105 @@
+package org.eclipse.ui.externaltools.internal.core;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.ui.externaltools.internal.ui.LogConsoleDocument;
+
+/**
+ * Execute external tools that represent programs in the file
+ * system.
+ */
+public class ProgramRunner extends ExternalToolsRunner {
+
+	/**
+	 * Creates an empty program runner
+	 */
+	public ProgramRunner() {
+		super();
+	}
+
+	/* (non-Javadoc)
+	 * Method declared in ExternalToolsRunner.
+	 */
+	public void execute(IProgressMonitor monitor, IRunnerContext runnerContext) throws CoreException, InterruptedException {
+		String commandLine = runnerContext.getExpandedLocation() + " " + runnerContext.getExpandedArguments(); //$NON-NLS-1$;
+		try {
+			File workingDir = null;
+			if (runnerContext.getExpandedWorkingDirectory().length() > 0)
+				workingDir = new File(runnerContext.getExpandedWorkingDirectory());
+			startMonitor(monitor, runnerContext, IProgressMonitor.UNKNOWN);
+			boolean[] finished = new boolean[1];
+			
+			finished[0] = false;
+			Process p;
+			if (workingDir != null)
+				p = Runtime.getRuntime().exec(commandLine, null, workingDir);
+			else
+				p = Runtime.getRuntime().exec(commandLine);		
+			new Thread(getRunnable(p.getInputStream(), LogConsoleDocument.getInstance(), LogConsoleDocument.MSG_INFO, finished, runnerContext.getShowLog())).start();
+			new Thread(getRunnable(p.getErrorStream(), LogConsoleDocument.getInstance(), LogConsoleDocument.MSG_ERR, finished, runnerContext.getShowLog())).start();
+	
+			p.waitFor();
+				
+			// Sleep to allow the two new threads to begin reading
+			// the program-running process's input and error streams
+			// before finished[0] is set to true. This is especially
+			// necessary with short programs that execute quickly. If
+			// finished[0] is set to true before the threads run,
+			// nothing will be read from the input and error streams.
+			Thread.sleep(200);
+				
+			finished[0] = true;
+		} catch (IOException e) {
+			handleException(e);
+		} catch (InterruptedException e) {
+			handleException(e);
+		} finally {
+			monitor.done();
+		}
+	}
+
+	/**
+	 * Returns a runnable that is used to capture and print out a stream
+	 * from another process.
+	 */
+	private Runnable getRunnable(final InputStream input, final LogConsoleDocument document, final int severity, final boolean[] finished, final boolean showLog) {
+		return new Runnable() {
+			public void run() {
+				try {
+					StringBuffer sb;
+					while (!finished[0]) {
+						sb = new StringBuffer();
+						int c = input.read();
+						while (c != -1) {
+							sb.append((char)c);
+							c = input.read();
+						}
+						if (showLog)
+							document.append(sb.toString(), severity);
+						try {
+							Thread.sleep(100);
+						} catch (InterruptedException e) {
+						}
+					}
+					input.close();
+				} catch (IOException e) {
+					e.printStackTrace(System.out);
+				}
+			}
+		};
+	}
+
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ToolMessages.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ToolMessages.java
new file mode 100644
index 0000000..28d2383
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ToolMessages.java
@@ -0,0 +1,61 @@
+package org.eclipse.ui.externaltools.internal.core;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Utility class which helps managing messages
+ */
+public class ToolMessages {
+	private static final String RESOURCE_BUNDLE= "org.eclipse.ui.externaltools.internal.core.messages"; //$NON-NLS-1$
+	private static ResourceBundle bundle = ResourceBundle.getBundle(RESOURCE_BUNDLE);
+	
+	private ToolMessages(){
+		// prevent instantiation of class
+	}
+	
+	/**
+	 * Returns the formatted message for the given key in
+	 * the resource bundle. 
+	 *
+	 * @param key the message name
+	 * @param args the message arguments
+	 * @return the formatted message
+	 */	
+	public static String format(String key, Object[] args) {
+		return MessageFormat.format(getString(key), args);
+	}
+	
+	/**
+	 * Returns the message with the given key in
+	 * the resource bundle. If there isn't any value under
+	 * the given key, the key is returned.
+	 *
+	 * @param key the message name
+	 * @return the message
+	 */	
+	public static String getString(String key) {
+		try {
+			return bundle.getString(key);
+		} catch (MissingResourceException e) {
+			return key;
+		}
+	}
+	
+	/**
+	 * Returns the resource bundle for the plug-in
+	 */
+	public static ResourceBundle getResourceBundle() {
+		return bundle;
+	}
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ToolUtil.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ToolUtil.java
new file mode 100644
index 0000000..cbd66ab
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/ToolUtil.java
@@ -0,0 +1,336 @@
+package org.eclipse.ui.externaltools.internal.core;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.ui.*;
+import org.eclipse.ui.externaltools.internal.ui.*;
+
+/**
+ * General utility class dealing with external tools
+ */
+public final class ToolUtil {
+	/**
+	 * Variable tag indentifiers
+	 */
+	/*package*/ static final String VAR_TAG_START = "${"; //$NON-NLS-1$
+	/*package*/ static final String VAR_TAG_END = "}"; //$NON-NLS-1$
+	/*package*/ static final String VAR_TAG_SEP = ":"; //$NON-NLS-1$
+
+	/**
+	 * Build types (what type of build is occuring when a tool is run)
+	 */
+	public static final String BUILD_TYPE_INCREMENTAL = "incremental"; //$NON-NLS-1$
+	public static final String BUILD_TYPE_FULL = "full"; //$NON-NLS-1$
+	public static final String BUILD_TYPE_AUTO = "auto"; //$NON-NLS-1$
+	public static final String BUILD_TYPE_NONE = "none"; //$NON-NLS-1$
+	
+	private static final ToolUtil instance = new ToolUtil();
+	
+	/**
+	 * No instances allowed
+	 */
+	private ToolUtil() {
+		super();
+	}
+
+	/**
+	 * Builds a variable tag that will be auto-expanded before
+	 * the tool is run.
+	 * 
+	 * @param varName the name of a known variable (one of the VAR_* constants)
+	 * @param varArgument an optional argument for the variable, <code>null</code> if none
+	 */
+	public static String buildVariableTag(String varName, String varArgument) {
+		StringBuffer buf = new StringBuffer();
+		buildVariableTag(varName,varArgument, buf);
+		return buf.toString();
+	}
+	
+	/**
+	 * Builds a variable tag that will be auto-expanded before
+	 * the tool is run.
+	 * 
+	 * @param varName the name of a known variable (one of the VAR_* constants)
+	 * @param varArgument an optional argument for the variable, <code>null</code> if none
+	 * @param buffer the buffer to write the constructed variable tag
+	 */
+	public static void buildVariableTag(String varName, String varArgument, StringBuffer buffer) {
+		buffer.append(VAR_TAG_START);
+		buffer.append(varName);
+		if (varArgument != null && varArgument.length() > 0) {
+			buffer.append(VAR_TAG_SEP);
+			buffer.append(varArgument);
+		}
+		buffer.append(VAR_TAG_END);
+	}
+	
+	/**
+	 * Builds a variable tag for each argument that will be auto-expanded before
+	 * the tool is run.
+	 * 
+	 * @param varName the name of a known variable (one of the VAR_* constants)
+	 * @param varArguments a list of arguments for each variable
+	 * @param buffer the buffer to write the constructed variable tags
+	 */
+	public static void buildVariableTags(String varName, String[] varArguments, StringBuffer buffer) {
+		for (int i = 0; i < varArguments.length; i++) {
+			buffer.append(" "); // $NON-NLS-1$
+			buildVariableTag(varName, varArguments[i], buffer);
+		}
+	}
+	
+	/**
+	 * Extracts from the source text the variable tag's name
+	 * and argument.
+	 * 
+	 * @param text the source text to parse for a variable tag
+	 * @param start the index in the string to start the search
+	 * @return the variable definition
+	 */
+	public static VariableDefinition extractVariableTag(String text, int start) {
+		VariableDefinition varDef = instance.new VariableDefinition();
+		
+		varDef.start = text.indexOf(VAR_TAG_START, start);
+		if (varDef.start < 0)
+			return varDef;
+		start = varDef.start + VAR_TAG_START.length();
+		
+		int end = text.indexOf(VAR_TAG_END, start);
+		if (end < 0)
+			return varDef;
+		varDef.end = end + VAR_TAG_END.length();
+		if (end == start)
+			return varDef;
+	
+		int mid = text.indexOf(VAR_TAG_SEP, start);
+		if (mid < 0 || mid > end) {
+			varDef.name = text.substring(start, end);
+		} else {
+			if (mid > start)
+				varDef.name = text.substring(start, mid);
+			mid = mid + VAR_TAG_SEP.length();
+			if (mid < end)
+				varDef.argument = text.substring(mid, end);
+		}
+		
+		return varDef;
+	}
+	
+	/**
+	 * Extracts all arguments of the specified variable tag name.
+	 * Places the remaining text on the buffer.
+	 * 
+	 * @param text the text to parse for variable tags of the specified name
+	 * @param varName the name of the variable tag to extract its argument
+	 * @param buffer the buffer to write the rest of the text
+	 * @return an array of arguments for the variable tag name specified
+	 */
+	public static String[] extractVariableArguments(String text, String varName, StringBuffer buffer) {
+		ArrayList results = new ArrayList();
+
+		int start = 0;
+		while (true) {
+			VariableDefinition varDef = extractVariableTag(text, start);
+			
+			if (varDef.start == -1) {
+				if (start == 0)
+					buffer.append(text);
+				else
+					buffer.append(text.substring(start));
+				break;
+			} else if (varDef.start > start) {
+				buffer.append(text.substring(start, varDef.start));
+			}
+
+			if (varDef.end == -1) {
+				buffer.append(text.substring(varDef.start));
+				break;
+			}
+
+			if (varName.equals(varDef.name)) {
+				if (varDef.argument != null)
+					results.add(varDef.argument);
+			} else {
+				buffer.append(text.substring(varDef.start, varDef.end));
+			}
+			
+			start = varDef.end;
+		}
+		
+		String[] args = new String[results.size()];
+		results.toArray(args);
+		return args;
+	}
+	
+	/**
+	 * Clears the log messages recorded so far.
+	 */
+	public static void clearLogDocument() {
+		LogConsoleDocument.getInstance().clearOutput();
+	}
+
+	/**
+	 * Returns the physical location of a resource, given a string of the form
+	 * VAR_TAG_START + ExternalTool.VAR_WORKSPACE_LOC + VAR_TAG_SEP + 
+	 * full path of a resource + VAR_TAG_END, or a string that is already
+	 * a resource location.
+	 * 
+	 * @param contents the contents of a EditDialog location field.
+	 * @return the location of the resource, or null if the resource
+	 * is not found.
+	 */
+	public static String getLocationFromText(String contents) {
+		VariableDefinition varDef = extractVariableTag(contents, 0);
+		if (varDef.start >= 0 && ExternalTool.VAR_WORKSPACE_LOC.equals(varDef.name))
+			if (varDef.argument != null && varDef.argument.length() > 0) {
+				return getLocationFromFullPath(varDef.argument);			
+			} else {
+				return Platform.getLocation().toOSString() + contents.substring(varDef.end);
+			}
+		else
+			return contents;
+	}
+	
+	/**
+	 * Returns the physical location of a resource, given the full path of the
+	 * resource (with respect to the workspace).
+	 * 
+	 * @param fullPath the full path of the resource.
+	 * @return the location of the resource, or null if the resource is not found.
+	 */
+	public static String getLocationFromFullPath(String fullPath) {
+		IResource member = ResourcesPlugin.getWorkspace().getRoot().findMember(fullPath);
+		if (member != null)
+			return member.getLocation().toOSString();
+		else
+			return null;
+	}
+	
+	/**
+	 * Returns the tool runner for the specified
+	 * type, or <code>null</code> if none registered.
+	 */
+	public static ExternalToolsRunner getRunner(String type) {
+		if (ExternalTool.TOOL_TYPE_PROGRAM.equals(type))
+			return new ProgramRunner();
+		if (ExternalTool.TOOL_TYPE_ANT.equals(type))
+			return new AntFileRunner();
+		return null;
+	}
+	
+	/**
+	 * Saves any dirty editors if user preference
+	 */
+	public static void saveDirtyEditors(IWorkbenchWindow window) {
+		IPreferenceStore store = ExternalToolsPlugin.getDefault().getPreferenceStore();
+		boolean autoSave = store.getBoolean(IPreferenceConstants.AUTO_SAVE);
+		if (autoSave) {
+			IWorkbenchWindow[] windows = window.getWorkbench().getWorkbenchWindows();
+			for (int i=0; i < windows.length; i++) {
+				IWorkbenchPage[] pages = windows[i].getPages();
+				for (int j = 0; j < pages.length; j++) {
+					pages[j].saveAllEditors(false);
+				}
+			}
+		}
+	}
+	
+	/**
+	 * Forces the log console view to open. Returns the view
+	 * part if successful, otherwise <code>null</code>.
+	 */
+	public static LogConsoleView showLogConsole(IWorkbenchWindow window) {
+		IWorkbenchPage page = window.getActivePage();
+		LogConsoleView console = null;
+		try {
+			if (page != null) {
+				console= (LogConsoleView)page.findView(ExternalToolsPlugin.LOG_CONSOLE_ID);
+				if(console == null) {
+					IWorkbenchPart activePart= page.getActivePart();
+					page.showView(ExternalToolsPlugin.LOG_CONSOLE_ID);
+					//restore focus stolen by the creation of the console
+					page.activate(activePart);
+				} else {
+					page.bringToTop(console);
+				}
+			}
+		} catch (PartInitException e) {
+			ExternalToolsPlugin.getDefault().getLog().log(e.getStatus());
+		}
+		return console;
+	}
+	
+	/**
+	 * Returns whether or not the given string contains at least one space.
+	 * 
+	 * @return true if the given string contains at least one space, false otherwise
+	 */
+	public static boolean hasSpace(String var) {
+		int index = var.indexOf(' ');
+		if (index >= 0)
+			return true;
+		else
+			return false;
+	}
+	
+	/**
+	 * Structure to represent a variable definition within a
+	 * source string.
+	 */
+	public final class VariableDefinition {
+		/**
+		 * Index in the source text where the variable started
+		 * or <code>-1</code> if no valid variable start tag 
+		 * identifier found.
+		 */
+		public int start = -1;
+		
+		/**
+		 * Index in the source text of the character following
+		 * the end of the variable or <code>-1</code> if no 
+		 * valid variable end tag found.
+		 */
+		public int end = -1;
+		
+		/**
+		 * The variable's name found in the source text, or
+		 * <code>null</code> if no valid variable found.
+		 */
+		public String name = null;
+		
+		/**
+		 * The variable's argument found in the source text, or
+		 * <code>null</code> if no valid variable found or if
+		 * the variable did not specify an argument
+		 */
+		public String argument = null;
+		
+		/**
+		 * Create an initialized variable definition.
+		 */
+		private VariableDefinition() {
+			super();
+		}
+		
+		/**
+		 * Create an initialized variable definition.
+		 */
+		private VariableDefinition(int start, int end) {
+			super();
+			this.start = start;
+			this.end = end;
+		}
+	}
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/messages.properties b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/messages.properties
new file mode 100644
index 0000000..4ab4202
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/core/messages.properties
@@ -0,0 +1,215 @@
+# ======================================================================
+# Copyright (c) 2002 IBM Corp. and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Common Public License v0.5
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v05.html
+#
+# Contributors:
+# ======================================================================
+
+AntClasspathPage.addFolderButtonTitle = Add &Folder...
+AntClasspathPage.addJarButtonTitle = Add &JARs...
+AntClasspathPage.upButtonTitle = &Up
+AntClasspathPage.downButtonTitle = Do&wn
+AntClasspathPage.removeButtonTitle = &Remove
+AntClasspathPage.title = C&lasspath
+
+ConfigurationDialog.shellTitle = External Tools Configuration
+ConfigurationDialog.dialogTitle = External Tools
+ConfigurationDialog.dialogMessage = Configure an external tool to run a program, batch file, or Ant build file.
+ConfigurationDialog.toolList = &Tools:
+ConfigurationDialog.newButton = &New...
+ConfigurationDialog.editButton = &Edit...
+ConfigurationDialog.removeButton = &Remove
+ConfigurationDialog.upButton = &Up
+ConfigurationDialog.downButton = &Down
+ConfigurationDialog.details = Det&ails:
+ConfigurationDialog.detailMessage = Location: {0}\nArguments: {1}\nDirectory: {2}
+
+EditDialog.newShellTitle = New External Tool
+EditDialog.editShellTitle = Edit External Tool
+EditDialog.dialogTitle = External Tool
+EditDialog.newDialogMessage = Create an external tool to run a program, batch file, or Ant build file.
+EditDialog.editDialogMessage = Edit an external tool to run a program, batch file, or Ant build file.
+EditDialog.howToSelectAntTargets = To choose Ant targets, press the ''Browse Variables'' button and select ''Ant targets''.
+EditDialog.nameLabel = &Name:
+EditDialog.locationLabel = Tool &Location:
+EditDialog.argumentLabel = Tool &Arguments:
+EditDialog.dirLabel = Working &Directory:
+EditDialog.refreshOption = After running, &refresh:
+EditDialog.browseWkspButton1 = Browse &Workspace...
+EditDialog.browseFileSysButton1 = Browse &File System...
+EditDialog.browseVarsButton = Browse &Variables...
+EditDialog.directoryBrowseButton = Browse &Options...
+EditDialog.refreshOptionButton = Browse O&ptions...
+EditDialog.browseWorkspaceTitle = Browse Workspace
+EditDialog.selectTool = &Select the external tool to use:
+EditDialog.selectResource = &Select the resource to use:
+EditDialog.selectContainer = &Select the container to use:
+EditDialog.selectDirectory = &Select the working directory to use:
+EditDialog.selectTargets = &Select the Ant targets to use:
+EditDialog.selectFolder = &Select the folder to use:
+EditDialog.browseVarTitle = Browse Variables
+EditDialog.browseDirTitle = Browse Working Directory Options
+EditDialog.selectVar = &Select a variable to use:
+EditDialog.selectDir = &Select a working directory option:
+EditDialog.dirBrowseWorkspace = Browse workspace
+EditDialog.dirBrowseFileSystem = Browse file system
+EditDialog.varWorkspaceLocLabel = Workspace location
+EditDialog.varProjectLocLabel = Selected resource's project location
+EditDialog.varContainerLocLabel = Selected resource's container location
+EditDialog.varResourceLocLabel = Selected resource location
+EditDialog.varProjectPathLabel = Selected resource's project full path
+EditDialog.varContainerPathLabel = Selected resource's container full path
+EditDialog.varResourcePathLabel = Selected resource full path
+EditDialog.varProjectNameLabel = Selected resource's project name
+EditDialog.varContainerNameLabel = Selected resource's container name
+EditDialog.varResourceNameLabel = Selected resource name
+EditDialog.varProjectXLocLabel = Specific resource's project location
+EditDialog.varContainerXLocLabel = Specific resource's container location
+EditDialog.varResourceXLocLabel = Specific resource location
+EditDialog.varProjectXPathLabel = Specific resource's project full path
+EditDialog.varContainerXPathLabel = Specific resource's container full path
+EditDialog.varResourceXPathLabel = Specific resource full path
+EditDialog.varProjectXNameLabel = Specific resource's project name
+EditDialog.varContainerXNameLabel = Specific resource's container name
+EditDialog.varResourceXNameLabel = Specific resource name
+EditDialog.varBuildTypeNameLabel = Build type
+EditDialog.varAntTargetLabel = Ant targets
+EditDialog.browseProjectTitle = Browse Projects
+EditDialog.selectProject = &Select a project to use:
+EditDialog.noToolName = Enter a name for the tool
+EditDialog.noToolLocation = Enter a location for the tool
+EditDialog.missingToolLocation = Tool location does not exist or is invalid
+EditDialog.missingToolDirectory = Tool working directory does not exist or is invalid
+EditDialog.refreshScopeNone = Nothing
+EditDialog.refreshScopeWorkspace = Workspace
+EditDialog.refreshScopeProject = Current project
+EditDialog.refreshScopeProjectX = Project named {0}
+EditDialog.refreshScopeWorkingSet = Working set named {0}
+EditDialog.browseRefreshTitle = Browse Refresh Scopes
+EditDialog.selectRefresh = &Select the refresh scope to use:
+EditDialog.refreshNothingLabel = Nothing
+EditDialog.refreshWorkspaceLabel = Current workspace
+EditDialog.refreshProjectLabel = Current project
+EditDialog.refreshProjectXLabel = Specific project
+EditDialog.refreshWorkingSetLabel = Specific working set
+EditDialog.showLogLabel = S&how execution log on console
+EditDialog.errorTitle = Edit External Tool Problem
+EditDialog.errorReadAntFile = Problems reading Ant build file: {0}
+EditDialog.noAntTargets = Could not find any targets in Ant build file: {0}
+
+ExternalToolsRegistry.saveStateErrorTitle = Problem Saving External Tool
+ExternalToolsRegistry.saveStateError = Could not write external tool configurations to disk.\n\nPlease try again.
+
+BuilderPropertyPage.description = Add external tools to the build order.
+BuilderPropertyPage.newButton = &New...
+BuilderPropertyPage.editButton = &Edit...
+BuilderPropertyPage.removeButton = &Remove
+BuilderPropertyPage.upButton = &Up
+BuilderPropertyPage.downButton = &Down
+BuilderPropertyPage.statusMessage = Internal error
+BuilderPropertyPage.errorTitle = External Tool Builder Problem
+BuilderPropertyPage.errorMessage = Internal error
+BuilderPropertyPage.invalidBuildTool = Invalid External Tool Builder
+BuilderPropertyPage.missingBuilder = Missing builder ({0})
+
+DefaultRunnerContext.runningExternalTool = Running external tool...
+DefaultRunnerContext.invalidLocation = The tool''s file does not exist for the external tool named {0}.
+DefaultRunnerContext.invalidDirectory = The tool''s working directory does not exist for the external tool named {0}.
+DefaultRunnerContext.refreshWorkingSet = Refreshing...
+DefaultRunnerContext.errorShellTitle = Problem Running External Tool
+DefaultRunnerContext.errorMessage = External tool failed to run.
+
+ExternalToolsRunner.runningToolLabel = Running external tool: {0}
+ExternalToolsRunner.internalErrorMessage = Internal error
+
+ExternalToolsAction.runProblem = A problem occurred running the external tool. See the log console for details.
+ExternalToolsAction.runErrorTitle = Run Tool Problem
+ExternalToolsAction.internalError = External tool runner internal error
+ExternalToolsAction.configure = &Configure...
+
+LogConsoleDocument.externalTool = External Tool
+
+LogConsoleView.copy = &Copy@Ctrl+C
+LogConsoleView.expandAll = &Expand All
+LogConsoleView.selectAll = Select &All@Ctrl+A
+LogConsoleView.clearOutput = Clear Output
+LogConsoleView.hideOutputStructureTree = Hide Output Structure Tree
+LogConsoleView.showOutputStructureTree = Show Output Structure Tree
+LogConsoleView.showTree = &Show Tree
+LogConsoleView.showSelectedElementOnly = Show Output of Selected Element Only
+LogConsoleView.showCompleteOutput = Show Complete Output
+LogConsoleView.findAction.label = Find/Replace
+
+LogTreeLabelProvider.invalidItemName = Invalid item name
+
+ToolsPreferencePage.errorColor = &Error:
+ToolsPreferencePage.warningColor = &Warning:
+ToolsPreferencePage.infoColor = I&nformation:
+ToolsPreferencePage.verboseColor = Ve&rbose:
+ToolsPreferencePage.debugColor = Deb&ug:
+ToolsPreferencePage.font = Console font setting:
+ToolsPreferencePage.description = Console text color settings.
+ToolsPreferencePage.savePriorToBuilding = &Save all modified resources before running an external tool
+ToolsPreferencePage.preferedOutputLevel = Preferred output level
+ToolsPreferencePage.info = &Information (normal)
+ToolsPreferencePage.verbose = &Verbose
+ToolsPreferencePage.debug = De&bug
+
+BuildCanceledException.canceled = Canceled
+
+AntUtil.antFileNotFound = Could not open Ant build file.
+AntUtil.parserConfigError = Internal parser configuration error.
+AntUtil.ioError = Could not read content of Ant build file.
+AntUtil.formatError = Could not parse content of Ant build file.
+AntUtil.invalidAntBuildFile = Invalid content format of Ant build file.
+
+AntAction.runErrorTitle = Run Ant Problem
+AntAction.errorReadAntFile = Problems reading Ant build file: {0}
+AntAction.noAntTargets = Could not find any targets in Ant build file: {0}
+
+AntLaunchWizard.shellTitle = Run Ant
+AntLaunchWizard.dialogTitle = Run
+AntLaunchWizard.dialogDescription = Run an Ant build file
+AntLaunchWizard.runningAnt = Running Ant
+AntLaunchWizard.runAntProblem = A problem occurred executing the Ant file. See the log console for details.
+AntLaunchWizard.runErrorTitle = Run Ant Problem
+AntLaunchWizard.internalAntError = Ant runner internal error
+
+AntLaunchWizardPage.targetLabel = Available &targets:
+AntLaunchWizardPage.argsLabel = &Arguments:
+AntLaunchWizardPage.showLogLabel = S&how execution log in console
+
+AntTargetLabelProvider.defaultTarget = Default
+
+NullBuildLogger.buildException = BUILD FAILED: {0}
+
+AddCustomDialog.name = &Name:
+AddCustomDialog.class = &Class:
+AddCustomDialog.library = &Library:
+
+AntTasksPage.addTaskButtonTitle = Add &Task...
+AntTasksPage.editTaskButtonTitle = &Edit Task...
+AntTasksPage.removeButtonTitle = &Remove
+AntTasksPage.addTaskDialogDescription = Enter a name, Java class, and library for your custom task:
+AntTasksPage.addTaskDialogTitle = Add Task
+AntTasksPage.title = Ta&sks
+AntTasksPage.editTaskDialogDescription = Modify the name, Java class, and library of your custom task
+AntTasksPage.editTaskDialogTitle = Edit Task
+
+AntTypesPage.removeButtonTitle = &Remove
+AntTypesPage.addTypeButtonTitle = Add &Type...
+AntTypesPage.editTypeButtonTitle = &Edit Type...
+AntTypesPage.typesPageTitle = T&ypes
+AntTypesPage.addTypeDialogDescription = Enter a name, Java class, and library for your custom type:
+AntTypesPage.addTypeDialogTitle = Add Type
+AntTypesPage.editTypeDialogDescription = Modify the name, Java class, and library of your custom type
+AntTypesPage.editTypeDialogTitle = Edit Type
+
+AntPreferencePage.description = &Customize the classpath, tasks and types used when running Ant files from Eclipse.
+
+AntInputHandler.Ant_Input_Request_1=Ant Input Request
+AntInputHandler.Invalid_input_2=Invalid input
+AntInputHandler.Unable_able_to_respond_to_<input>_request_4=Unable able to respond to <input> request
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AddCustomDialog.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AddCustomDialog.java
new file mode 100644
index 0000000..798ee59
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AddCustomDialog.java
@@ -0,0 +1,213 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others. All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html

+Contributors:
+**********************************************************************/
+
+import java.net.URL;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.ant.core.AntCorePlugin;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.externaltools.internal.core.ToolMessages;
+import org.eclipse.ui.help.WorkbenchHelp;
+
+/**
+ * Dialog to prompt the user to add a custom Ant task or type.
+ */
+public class AddCustomDialog extends Dialog {
+	private String title;
+	private String description;
+
+	//task/type attributes
+	private String taskName;
+	private String className;
+	private URL library;
+
+	//widgets
+	private Button okButton;
+	private Text nameField;
+	private Text classField;
+	private org.eclipse.swt.widgets.List libraryField;
+
+	private List libraryUrls;
+
+	/**
+	 * Creates a new dialog with the given shell and title.
+	 */
+	protected AddCustomDialog(Shell parent, List libraryUrls, String title, String description) {
+		super(parent);
+		this.title = title;
+		this.description = description;
+		this.libraryUrls= libraryUrls;
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on Window.
+	 */
+	protected void configureShell(Shell newShell) {
+		super.configureShell(newShell);
+		newShell.setText(title);
+		WorkbenchHelp.setHelp(newShell, IHelpContextIds.ADD_TASK_DIALOG);
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on Dialog.
+	 */
+	protected void createButtonsForButtonBar(Composite parent) {
+		okButton = createButton(
+			parent,
+			IDialogConstants.OK_ID,
+			IDialogConstants.OK_LABEL,
+			true);
+		createButton(
+			parent,
+			IDialogConstants.CANCEL_ID,
+			IDialogConstants.CANCEL_LABEL,
+			false);
+		updateEnablement();
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on Dialog.
+	 */
+	protected Control createDialogArea(Composite parent) {
+		Composite dialogArea = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginHeight = 10;
+		layout.marginWidth = 10;
+		dialogArea.setLayout(layout);
+
+		Label label = new Label(dialogArea, SWT.NONE);
+		label.setText(description);
+		GridData data = new GridData(GridData.FILL_HORIZONTAL);
+		data.horizontalSpan = 2;
+		label.setLayoutData(data);
+
+		label = new Label(dialogArea, SWT.NONE);
+		label.setText(ToolMessages.getString("AddCustomDialog.name")); //$NON-NLS-1$;
+		nameField = new Text(dialogArea, SWT.BORDER);
+		data = new GridData(GridData.FILL_HORIZONTAL);
+		data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
+		nameField.setLayoutData(data);
+		nameField.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				updateEnablement();
+			}
+		});
+
+		label = new Label(dialogArea, SWT.NONE);
+		label.setText(ToolMessages.getString("AddCustomDialog.class")); //$NON-NLS-1$;
+		classField = new Text(dialogArea, SWT.BORDER);
+		data = new GridData(GridData.FILL_HORIZONTAL);
+		data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
+		classField.setLayoutData(data);
+		classField.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				updateEnablement();
+			}
+		});
+
+		label = new Label(dialogArea, SWT.NONE);
+		label.setText(ToolMessages.getString("AddCustomDialog.library")); //$NON-NLS-1$;
+		libraryField = new org.eclipse.swt.widgets.List(dialogArea, SWT.READ_ONLY | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
+		data = new GridData(GridData.FILL_HORIZONTAL);
+		data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
+		libraryField.setLayoutData(data);
+		libraryField.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				updateEnablement();
+			}
+		});
+
+		//populate library combo and select input library
+		if (libraryUrls == null) {
+			libraryUrls = Arrays.asList(AntCorePlugin.getPlugin().getPreferences().getCustomURLs());
+		}
+		int selection = 0;
+		Iterator itr= libraryUrls.iterator();
+		int i= 0;
+		while (itr.hasNext()) {
+			URL lib = (URL) itr.next();
+			libraryField.add(lib.getFile());
+			if (lib.equals(library)) {
+				selection = i;
+			}
+			i++;
+		}
+			
+		//intialize fields
+		if (taskName != null) {
+			nameField.setText(taskName);
+		}
+		if (className != null) {
+			classField.setText(className);
+		}
+		if (libraryUrls.size() >= 0) {
+			libraryField.select(selection);
+		}
+
+		return dialogArea;
+	}
+
+	public String getClassName() {
+		return className;
+	}
+	
+	public URL getLibrary() {
+		return library;
+	}
+	
+	public String getTaskName() {
+		return taskName;
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on Dialog.
+	 */
+	protected void okPressed() {
+		className = classField.getText();
+		taskName = nameField.getText();
+		int selection = libraryField.getSelectionIndex();
+		if (selection >= 0) {
+			library = (URL)libraryUrls.get(selection);
+		}
+		super.okPressed();
+	}
+
+	public void setClassName(String className) {
+		this.className = className;
+	}
+	
+	public void setLibrary(URL library) {
+		this.library = library;
+	}
+
+	public void setTaskName(String taskName) {
+		this.taskName = taskName;
+	}
+
+	private void updateEnablement() {
+		if (okButton != null) {
+			okButton.setEnabled(
+				nameField.getText().length() > 0
+					&& classField.getText().length() > 0
+					&& libraryField.getSelectionIndex() >= 0);
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntAction.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntAction.java
new file mode 100644
index 0000000..c4df54b
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntAction.java
@@ -0,0 +1,78 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.externaltools.internal.core.*;
+import org.eclipse.ui.help.WorkbenchHelp;
+
+/**
+ * Action to run an ant build file.
+ */
+public class AntAction extends Action {
+	private IFile file;
+	private IWorkbenchWindow window;
+
+	/**
+	 * Creates an initialize action to run an
+	 * Ant build file
+	 * 
+	 * @param file the ant build file to run
+	 */
+	public AntAction(IFile file, IWorkbenchWindow window) {
+		super();
+		this.file = file;
+		this.window = window;
+		setText(file.getName());
+		setToolTipText(file.getFullPath().toOSString());
+		WorkbenchHelp.setHelp(this, IHelpContextIds.ANT_ACTION);
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on IAction.
+	 */
+	public void run() {
+		if (file == null)
+			return;
+
+		AntTargetList targetList = null;
+		try {
+			targetList = AntUtil.getTargetList(file.getLocation());
+		} catch (CoreException e) {
+			ErrorDialog.openError(
+				window.getShell(),
+				ToolMessages.getString("AntAction.runErrorTitle"), //$NON-NLS-1$
+				ToolMessages.format("AntAction.errorReadAntFile", new Object[] {file.getFullPath().toString()}), //$NON-NLS-1$;
+				e.getStatus());
+			return;
+		}
+		
+		if (targetList == null) {
+			MessageDialog.openError(
+				window.getShell(),
+				ToolMessages.getString("AntAction.runErrorTitle"), //$NON-NLS-1$;
+				ToolMessages.format("AntAction.noAntTargets", new Object[] {file.getFullPath().toString()})); //$NON-NLS-1$;
+			return;
+		}
+
+		AntLaunchWizard wizard = new AntLaunchWizard(targetList, file, window);
+		wizard.setNeedsProgressMonitor(true);
+		WizardDialog dialog = new WizardDialog(window.getShell(), wizard);
+		dialog.create();
+		WorkbenchHelp.setHelp(dialog.getShell(), IHelpContextIds.ANT_LAUNCH_WIZARD);		
+		dialog.open();
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntClasspathPage.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntClasspathPage.java
new file mode 100644
index 0000000..95c1799
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntClasspathPage.java
@@ -0,0 +1,284 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others. All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html

+Contributors:
+**********************************************************************/
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.externaltools.internal.core.ExternalToolsPlugin;
+import org.eclipse.ui.externaltools.internal.core.ToolMessages;
+
+/**
+ * Sub-page that allows the user to enter custom classpaths
+ * to be used when running Ant build files.
+ */
+public class AntClasspathPage extends AntPage {
+	private static final int ADD_JARS_BUTTON = IDialogConstants.CLIENT_ID + 1;
+	private static final int ADD_FOLDER_BUTTON = IDialogConstants.CLIENT_ID + 2;
+	private static final int REMOVE_BUTTON = IDialogConstants.CLIENT_ID + 3;
+	private static final int UP_BUTTON = IDialogConstants.CLIENT_ID + 4;
+	private static final int DOWN_BUTTON = IDialogConstants.CLIENT_ID + 5;
+
+	private Button upButton;
+	private Button downButton;
+	
+	private IDialogSettings fDialogSettings;
+	
+	private final AntClasspathLabelProvider labelProvider = new AntClasspathLabelProvider();
+
+	/**
+	 * Creates an instance.
+	 */
+	public AntClasspathPage(AntPreferencePage preferencePage) {
+		super(preferencePage);
+		fDialogSettings= ExternalToolsPlugin.getDefault().getDialogSettings();
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on AntPage.
+	 */
+	protected void addButtonsToButtonGroup(Composite parent) {
+		createButton(parent, "AntClasspathPage.addJarButtonTitle", ADD_JARS_BUTTON); //$NON-NLS-1$;
+		createButton(parent, "AntClasspathPage.addFolderButtonTitle", ADD_FOLDER_BUTTON); //$NON-NLS-1$;
+		createSeparator(parent);
+		upButton= createButton(parent, "AntClasspathPage.upButtonTitle", UP_BUTTON); //$NON-NLS-1$;
+		downButton= createButton(parent, "AntClasspathPage.downButtonTitle", DOWN_BUTTON); //$NON-NLS-1$;
+		removeButton= createButton(parent, "AntClasspathPage.removeButtonTitle", REMOVE_BUTTON); //$NON-NLS-1$;
+	}
+	
+	/**
+	 * Allows the user to enter a folder as a classpath.
+	 */
+	private void addFolderButtonPressed() {
+		DirectoryDialog dialog = new DirectoryDialog(getShell());
+		dialog.setMessage(AntDialogMessages.getString("AntClasspathPage.&Choose_a_folder_to_add_to_the_classpath__1")); //$NON-NLS-1$
+		
+		String result = dialog.open();
+		if (result != null) {
+			try {
+				URL url = new URL("file:" + result + "/"); //$NON-NLS-2$;//$NON-NLS-1$;
+				addContent(url);
+			} catch (MalformedURLException e) {
+			}
+		}
+	}
+	
+	/**
+	 * Allows the user to enter add JARs to the classpath.
+	 */
+	private void addJarsButtonPressed() {
+		String lastUsedPath;
+		lastUsedPath= fDialogSettings.get(IUIConstants.DIALOGSTORE_LASTEXTJAR);
+		if (lastUsedPath == null) {
+			lastUsedPath= ""; //$NON-NLS-1$
+		}
+		FileDialog dialog = new FileDialog(getShell(), SWT.MULTI);
+		dialog.setFilterExtensions(new String[] { "*.jar" }); //$NON-NLS-1$;
+		dialog.setFilterPath(lastUsedPath);
+		String result = dialog.open();
+		if (result == null) {
+			return;
+		}
+		IPath filterPath= new Path(dialog.getFilterPath());
+		String[] results= dialog.getFileNames();
+		for (int i = 0; i < results.length; i++) {
+			String jarName = results[i];
+			try {
+				IPath path= filterPath.append(jarName).makeAbsolute();	
+				URL url = new URL("file:" + path.toOSString()); //$NON-NLS-1$;
+				addContent(url);
+			} catch (MalformedURLException e) {
+			}
+		}
+		
+		fDialogSettings.put(IUIConstants.DIALOGSTORE_LASTEXTJAR, filterPath.toOSString());
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on AntPage.
+	 */
+	protected void buttonPressed(int buttonId) {
+		switch (buttonId) {
+			case ADD_JARS_BUTTON :
+				addJarsButtonPressed();
+				break;
+			case ADD_FOLDER_BUTTON :
+				addFolderButtonPressed();
+				break;
+			case UP_BUTTON :
+				handleMove(-1);
+				break;
+			case DOWN_BUTTON :
+				handleMove(1);
+				break;
+			case REMOVE_BUTTON :
+				removeButtonPressed();
+				break;
+		}
+	}
+	
+	/**
+	 * Creates the tab item that contains this sub-page.
+	 */
+	public TabItem createTabItem(TabFolder folder) {
+		TabItem item = new TabItem(folder, SWT.NONE);
+		item.setText(ToolMessages.getString("AntClasspathPage.title")); //$NON-NLS-1$;
+		item.setImage(labelProvider.getClasspathImage());
+		item.setData(this);
+		item.setControl(createControl(folder));
+		return item;
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on AntPage.
+	 */
+	protected ITableLabelProvider getLabelProvider() {
+		return labelProvider;
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on AntPage.
+	 */
+	protected void tableSelectionChanged(IStructuredSelection newSelection) {
+	
+		IStructuredSelection selection = (IStructuredSelection)getTableViewer().getSelection();
+		List urls = getContents();
+		boolean notEmpty = !selection.isEmpty();
+		Iterator elements= selection.iterator();
+		boolean first= false;
+		boolean last= false;
+		int lastUrl= urls.size() - 1;
+		while (elements.hasNext()) {
+			Object element = (Object) elements.next();
+			if(!first && urls.indexOf(element) == 0) {
+				first= true;
+			}
+			if (!last && urls.indexOf(element) == lastUrl) {
+				last= true;
+			}
+		}
+		
+		removeButton.setEnabled(notEmpty);
+		upButton.setEnabled(notEmpty && !first);
+		downButton.setEnabled(notEmpty && !last);
+	}
+	
+	protected void handleMove(int direction) {
+		IStructuredSelection sel = (IStructuredSelection)getTableViewer().getSelection();
+		List selList= sel.toList();
+		List contents= getContents();
+		Object[] movedURL= new Object[contents.size()];
+		int i;
+		for (Iterator urls = selList.iterator(); urls.hasNext();) {
+			Object config = urls.next();
+			i= contents.indexOf(config);
+			movedURL[i + direction]= config;
+		}
+		
+		contents.removeAll(selList);
+			
+		for (int j = 0; j < movedURL.length; j++) {
+			Object config = movedURL[j];
+			if (config != null) {
+				contents.add(j, config);		
+			}
+		}
+		setInput(contents);
+		getTableViewer().refresh();	
+	}
+
+
+	/**
+	 * Label provider for classpath elements
+	 */
+	private static final class AntClasspathLabelProvider extends LabelProvider implements ITableLabelProvider {
+		private static final String IMG_JAR_FILE = "icons/full/obj16/jar_l_obj.gif"; //$NON-NLS-1$;
+		private static final String IMG_CLASSPATH = "icons/full/obj16/classpath.gif"; //$NON-NLS-1$;
+
+		private Image classpathImage;
+		private Image folderImage;
+		private Image jarImage;
+	
+		/**
+		 * Creates an instance.
+		 */
+		public AntClasspathLabelProvider() {
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on IBaseLabelProvider.
+		 */
+		public void dispose() {
+			// Folder image is shared, do not dispose.
+			folderImage = null;
+			if (jarImage != null) {
+				jarImage.dispose();
+				jarImage = null;
+			}
+			if (classpathImage != null) {
+				classpathImage.dispose();
+				classpathImage = null;
+			}
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on ITableLabelProvider.
+		 */
+		public Image getColumnImage(Object element, int columnIndex) {
+			URL url = (URL) element;
+			if (url.getFile().endsWith("/")) //$NON-NLS-1$
+				return getFolderImage();
+			else
+				return getJarImage();
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on ITableLabelProvider.
+		 */
+		public String getColumnText(Object element, int columnIndex) {
+			return ((URL) element).getFile();
+		}
+
+		private Image getFolderImage() {
+			if (folderImage == null)
+				folderImage = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
+			return folderImage;
+		}
+		
+		private Image getJarImage() {
+			if (jarImage == null) {
+				ImageDescriptor desc = ExternalToolsPlugin.getDefault().getImageDescriptor(IMG_JAR_FILE);
+				jarImage = desc.createImage();
+			}
+			return jarImage;
+		}
+		
+		private Image getClasspathImage() {
+			if (classpathImage == null) {
+				ImageDescriptor desc = ExternalToolsPlugin.getDefault().getImageDescriptor(IMG_CLASSPATH);
+				classpathImage = desc.createImage();
+			}
+			return classpathImage;
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntDialogMessages.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntDialogMessages.java
new file mode 100644
index 0000000..d9d6e79
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntDialogMessages.java
@@ -0,0 +1,31 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others. All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html

+Contributors:
+**********************************************************************/
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class AntDialogMessages {
+
+	private static final String BUNDLE_NAME = "org.eclipse.ui.externaltools.internal.ui.AntDialogMessages"; //$NON-NLS-1$
+
+	private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
+
+	private AntDialogMessages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return RESOURCE_BUNDLE.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntDialogMessages.properties b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntDialogMessages.properties
new file mode 100644
index 0000000..2e312db
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntDialogMessages.properties
@@ -0,0 +1,13 @@
+######################################################################
+# Copyright (c) 2002 IBM Corp. and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+#
+# Contributors:
+#    IBM Corporation - Initial implementation
+######################################################################
+
+
+AntClasspathPage.&Choose_a_folder_to_add_to_the_classpath__1=&Choose a folder to add to the classpath:
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntLaunchWizard.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntLaunchWizard.java
new file mode 100644
index 0000000..14b1f9e
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntLaunchWizard.java
@@ -0,0 +1,159 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.externaltools.internal.core.*;
+
+/**
+ * The wizard to run an Ant file when the Run Ant...
+ * context menu action is choosen by the user.
+ * <p>
+ * Note: Currently there is only one page in this wizard.
+ * </p>
+ */
+public class AntLaunchWizard extends Wizard {
+	/**
+	 * The file that contains the Ant file.
+	 */
+	private IFile antFile = null;
+
+	/**
+	 * The Ant project described in the xml file.
+	 */
+	private AntTargetList targetList = null;
+
+	/**
+	 * The external tool representing the Ant file
+	 */
+	private ExternalTool antTool = null;
+
+	/**
+	 * Whether the external tool is new for this wizard
+	 */
+	private boolean isNewTool = false;
+	
+	/**
+	 * The workbench window that the action launch
+	 * this wizard.
+	 */
+	private IWorkbenchWindow window = null;
+
+	/**
+	 * The first page of the wizard.
+	 */
+	private AntLaunchWizardPage page1 = null;
+
+	/**
+	 * Creates a new wizard, given the project described in the
+	 * file and the file itself.
+	 * 
+	 * @param antProject
+	 * @param antFile
+	 */
+	public AntLaunchWizard(AntTargetList targetList, IFile antFile, IWorkbenchWindow window) {
+		super();
+		this.targetList = targetList;
+		this.antFile = antFile;
+		this.window = window;
+		String antPath = antFile.getFullPath().toString();
+		this.antTool = ExternalToolsPlugin.getDefault().getRegistry().getExternalTool(antPath);
+		if (this.antTool == null) {
+			this.antTool = new ExternalTool();
+			this.antTool.setName(antPath);
+			this.antTool.setType(ExternalTool.TOOL_TYPE_ANT);
+			this.antTool.setLocation(ToolUtil.buildVariableTag(ExternalTool.VAR_WORKSPACE_LOC, antPath));
+			this.isNewTool = true;
+		}
+		setWindowTitle(ToolMessages.getString("AntLaunchWizard.shellTitle")); //$NON-NLS-1$;
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on IWizard.
+	 */
+	public void addPages() {
+		page1 = new AntLaunchWizardPage(targetList);
+		addPage(page1);
+		
+		String args = antTool.getArguments();
+		StringBuffer buf = new StringBuffer();
+		String[] targets = ToolUtil.extractVariableArguments(args, ExternalTool.VAR_ANT_TARGET, buf);
+		
+		page1.setInitialTargets(targets);
+		page1.setInitialArguments(buf.toString());
+		page1.setInitialDisplayLog(antTool.getShowLog());
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on IWizard.
+	 */
+	public boolean performFinish() {
+		updateTool();
+		ToolUtil.saveDirtyEditors(window);
+		if (antTool.getShowLog()) {
+			ToolUtil.showLogConsole(window);
+			ToolUtil.clearLogDocument();
+		}
+		
+		IRunnableWithProgress runnable = new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+				DefaultRunnerContext context = new DefaultRunnerContext(antTool, antFile.getProject(), window.getWorkbench().getWorkingSetManager());
+				context.run(monitor, window.getShell());
+			};
+		};
+
+		try {
+			getContainer().run(true, true, runnable);
+		} catch (InterruptedException e) {
+			return false;
+		} catch (InvocationTargetException e) {
+			IStatus status = null;
+			if (e.getTargetException() instanceof CoreException)
+				status = ((CoreException)e.getTargetException()).getStatus();
+			else
+				status = new Status(IStatus.ERROR, ExternalToolsPlugin.PLUGIN_ID, 0, ToolMessages.getString("AntLaunchWizard.internalAntError"), e.getTargetException()); //$NON-NLS-1$;
+			ErrorDialog.openError(
+				getShell(), 
+				ToolMessages.getString("AntLaunchWizard.runErrorTitle"), //$NON-NLS-1$;
+				ToolMessages.getString("AntLaunchWizard.runAntProblem"), //$NON-NLS-1$;
+				status);
+			return false;
+		}
+
+		return true;
+	}
+
+	/**
+	 * Method updateTool.
+	 */
+	private void updateTool() {
+		StringBuffer buf = new StringBuffer(page1.getArguments());
+		String[] targets = page1.getSelectedTargets();
+		ToolUtil.buildVariableTags(ExternalTool.VAR_ANT_TARGET, targets, buf);
+		
+		antTool.setArguments(buf.toString());
+		antTool.setShowLog(page1.getShowLog());
+
+		ArrayList tools = ExternalToolsPlugin.getDefault().getRegistry().getExternalTools();
+		if (isNewTool) {
+			tools.add(antTool);
+			isNewTool = false;
+		}
+		ExternalToolsPlugin.getDefault().getRegistry().setExternalTools(tools);
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntLaunchWizardPage.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntLaunchWizardPage.java
new file mode 100644
index 0000000..1101f0c
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntLaunchWizardPage.java
@@ -0,0 +1,229 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.net.*;
+import java.util.ArrayList;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.externaltools.internal.core.*;
+import org.eclipse.ui.help.WorkbenchHelp;
+
+/**
+ * First page of the run Ant wizard. Allows the user to pick
+ * the targets, supply extra arguments, and decide to show
+ * output to the console.
+ */
+public class AntLaunchWizardPage extends WizardPage {
+	private static final int SIZING_SELECTION_WIDGET_HEIGHT = 200;
+	private static final int SIZING_SELECTION_WIDGET_WIDTH = 200;
+
+	private AntTargetList targetList;
+	private String initialTargets[];
+	private String initialArguments;
+	private boolean initialDisplayLog = true;
+	private ArrayList selectedTargets = new ArrayList();
+	
+	private CheckboxTableViewer listViewer;
+	private AntTargetLabelProvider labelProvider = new AntTargetLabelProvider();
+	private Button showLog;
+	private Text argumentsField;
+
+	public AntLaunchWizardPage(AntTargetList targetList) {
+		super("AntScriptPage"); //$NON-NLS-1$;
+		this.targetList = targetList;
+		setTitle(ToolMessages.getString("AntLaunchWizard.dialogTitle")); //$NON-NLS-1$;
+		setDescription(ToolMessages.getString("AntLaunchWizard.dialogDescription")); //$NON-NLS-1$;
+		setImageDescriptor(getImageDescriptor("icons/full/wizban/ant_wiz.gif")); //$NON-NLS-1$;
+	}
+	
+	/**
+	 * Returns the image descriptor for the banner
+	 */
+	private ImageDescriptor getImageDescriptor(String relativePath) {
+		try {
+			URL installURL = ExternalToolsPlugin.getDefault().getDescriptor().getInstallURL();
+			URL url = new URL(installURL, relativePath);
+			return ImageDescriptor.createFromURL(url);
+		} catch (MalformedURLException e) {
+			return null;
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on IWizardPage.
+	 */
+	public void createControl(Composite parent) {
+		Composite composite = new Composite(parent, SWT.NULL);
+		composite.setLayout(new GridLayout());
+		composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL));
+
+		// The list of targets
+		Label label = new Label(composite, SWT.NONE);
+		label.setText(ToolMessages.getString("AntLaunchWizardPage.targetLabel")); //$NON-NLS-1$;
+
+		listViewer = CheckboxTableViewer.newCheckList(composite, SWT.BORDER);
+		GridData data = new GridData(GridData.FILL_BOTH);
+		data.heightHint = SIZING_SELECTION_WIDGET_HEIGHT;
+		data.widthHint = SIZING_SELECTION_WIDGET_WIDTH;
+		listViewer.getTable().setLayoutData(data);
+		listViewer.setSorter(new ViewerSorter() {
+			public int compare(Viewer viewer, Object o1, Object o2) {
+				return ((String)o1).compareTo((String) o2);
+			}
+		});
+		if (targetList.getDefaultTarget() != null)
+			labelProvider.setDefaultTargetName(targetList.getDefaultTarget());
+		listViewer.setLabelProvider(labelProvider);
+		listViewer.setContentProvider(new AntTargetContentProvider());
+		listViewer.setInput(targetList);
+
+		// The arguments field
+		label = new Label(composite, SWT.NONE);
+		label.setText(ToolMessages.getString("AntLaunchWizardPage.argsLabel")); //$NON-NLS-1$;
+		
+		argumentsField = new Text(composite, SWT.BORDER);
+		argumentsField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		argumentsField.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				validatePageComplete();
+			}
+		});
+
+		// The show log option
+		showLog = new Button(composite, SWT.CHECK);
+		showLog.setText(ToolMessages.getString("AntLaunchWizardPage.showLogLabel")); //$NON-NLS-1$;
+		
+		// Setup initial field values
+		if (initialArguments != null)
+			argumentsField.setText(initialArguments);
+		showLog.setSelection(initialDisplayLog);
+		selectInitialTargets();
+		
+		validatePageComplete();
+
+		listViewer.addCheckStateListener(new TargetCheckListener());
+		listViewer.refresh();
+		argumentsField.setFocus();
+		
+		setControl(composite);
+
+		WorkbenchHelp.setHelp(composite, IHelpContextIds.ANT_LAUNCH_WIZARD_PAGE);
+	}
+	
+	/**
+	 * Returns the arguments that the user has entered
+	 * to run the ant file.
+	 * 
+	 * @return String the arguments
+	 */
+	public String getArguments() {
+		return argumentsField.getText().trim();
+	}
+	
+	/**
+	 * Returns the targets selected by the user
+	 */
+	public String[] getSelectedTargets() {
+		String[] names = new String[selectedTargets.size()];
+		selectedTargets.toArray(names);
+		return names;
+	}
+	
+	/**
+	 * Returns whether the users wants messages from running
+	 * the tool displayed in the console
+	 */
+	public boolean getShowLog() {
+		return showLog.getSelection();
+	}
+
+	/**
+	 * Setup the initial selected targets in the viewer
+	 */	
+	private void selectInitialTargets() {
+		if (initialTargets != null && initialTargets.length > 0) {
+			String[] targets = targetList.getTargets();
+			for (int i = 0; i < initialTargets.length; i++) {
+				for (int j = 0; j < targets.length; j++) {
+					if (targets[j].equals(initialTargets[i])) {
+						String target = targets[j];
+						listViewer.setChecked(target, true);
+						selectedTargets.add(target);
+						break;
+					}
+				}
+			}
+		} else {
+			String target = targetList.getDefaultTarget();
+			if (target != null) {
+				listViewer.setChecked(target, true);
+				selectedTargets.add(target);
+			}
+		}
+		
+		labelProvider.setSelectedTargets(selectedTargets);
+	}
+	
+	/**
+	 * Sets the initial contents of the target list field.
+	 * Ignored if controls already created.
+	 */
+	public void setInitialTargets(String value[]) {
+		initialTargets = value;
+	}
+	
+	/**
+	 * Sets the initial contents of the arguments text field.
+	 * Ignored if controls already created.
+	 */
+	public void setInitialArguments(String value) {
+		initialArguments = value;
+	}
+	
+	/**
+	 * Sets the initial contents of the display to log option field.
+	 * Ignored if controls already created.
+	 */
+	public void setInitialDisplayLog(boolean value) {
+		initialDisplayLog = value;
+	}
+	
+	/**
+	 * Validates the page is complete
+	 */
+	private void validatePageComplete() {
+		setPageComplete(selectedTargets.size() > 0 || getArguments().length() > 0);
+	}
+	
+	
+	/**
+	 * Inner class for checkbox listener
+	 */
+	private class TargetCheckListener implements ICheckStateListener {
+		public void checkStateChanged(CheckStateChangedEvent e) {
+			String checkedTarget = (String) e.getElement();
+			if (e.getChecked())
+				selectedTargets.add(checkedTarget);
+			else
+				selectedTargets.remove(checkedTarget);
+	
+			labelProvider.setSelectedTargets(selectedTargets);
+			listViewer.refresh();
+			validatePageComplete();
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntPage.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntPage.java
new file mode 100644
index 0000000..1b3b5c2
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntPage.java
@@ -0,0 +1,278 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others. All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html

+Contributors:
+**********************************************************************/
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+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.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.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.ui.externaltools.internal.core.ToolMessages;
+
+/**
+ * Provides the generic implementation for a sub-page in the
+ * Ant preference page.
+ */
+public abstract class AntPage {
+	private SelectionAdapter selectionAdapter = new SelectionAdapter() {
+		public void widgetSelected(SelectionEvent e) {
+			buttonPressed(((Integer) e.widget.getData()).intValue());
+		}
+	};
+	private AntPreferencePage preferencePage;
+	private TableViewer tableViewer;
+	private AntPageContentProvider contentProvider;
+	
+	protected Button editButton;
+	protected Button removeButton;
+
+	/**
+	 * Creates an instance of this page.
+	 */
+	public AntPage(AntPreferencePage preferencePage) {
+		super();
+		this.preferencePage = preferencePage;
+	}
+	
+	/**
+	 * Adds buttons specific to the page.
+	 */
+	protected abstract void addButtonsToButtonGroup(Composite parent);
+	
+	/**
+	 * Adds an object to the contents
+	 */
+	protected final void addContent(Object o) {
+		if (contentProvider != null)
+			contentProvider.add(o);
+	}
+	
+	/**
+	 * Handles a button pressed event.
+	 */
+	protected void buttonPressed(int buttonId) {
+	}
+
+	/**
+	 * Creates and returns a button with appropriate size and layout.
+	 * 
+	 * @param parent the control to create the button on
+	 * @param labelKey the key to lookup the button's label
+	 * @param buttonId the id to assign to this button
+	 * @return a new and initialized button
+	 */
+	protected Button createButton(Composite parent, String labelKey, int buttonId) {
+		Button button = new Button(parent, SWT.PUSH);
+		button.setText(ToolMessages.getString(labelKey));
+		button.setData(new Integer(buttonId));
+		button.addSelectionListener(selectionAdapter);
+		preferencePage.setButtonGridData(button);
+		return button;
+	}
+	
+	/**
+	 * Creates the group which will contain the buttons.
+	 */
+	private void createButtonGroup(Composite top) {
+		Composite buttonGroup = new Composite(top, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		buttonGroup.setLayout(layout);
+		buttonGroup.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+
+		addButtonsToButtonGroup(buttonGroup);
+	}
+
+	/**
+	 * Creates a space between controls
+	 */
+	protected final Label createSeparator(Composite parent) {
+		Label separator = new Label(parent, SWT.NONE);
+		GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING);
+		gd.heightHint = 4;
+		separator.setLayoutData(gd);
+		return separator;
+	}
+	
+	/**
+	 * Creates the table viewer.
+	 */
+	private void createTable(Composite parent) {
+		Table table = new Table(parent, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER);
+		GridData data= new GridData(GridData.FILL_BOTH);
+		data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
+		table.setLayoutData(data);
+		contentProvider = new AntPageContentProvider();
+		tableViewer = new TableViewer(table);
+		tableViewer.setContentProvider(contentProvider);
+		tableViewer.setLabelProvider(getLabelProvider());
+		tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				tableSelectionChanged((IStructuredSelection) event.getSelection());
+			}
+		});
+	}
+
+	/**
+	 * Returns the currently listed objects in the table.  Returns null
+	 * if this widget has not yet been created or has been disposed.
+	 */
+	public List getContents() {
+		if (tableViewer == null || tableViewer.getControl().isDisposed())
+			return null;
+		Object[] elements = contentProvider.getElements(tableViewer.getInput());
+		List contents= new ArrayList(elements.length);
+		for (int i = 0; i < elements.length; i++) {
+			contents.add(elements[i]);
+		}
+		return contents;
+	}
+	
+	/**
+	 * Returns the label provider the sub-page wants to use
+	 * to display its content with.
+	 */
+	protected abstract ITableLabelProvider getLabelProvider();
+	
+	/**
+	 * Returns the first selected element in the viewer, or
+	 * <code>null</code> if none.
+	 */
+	protected final Object getSelectedElement() {
+		if (tableViewer == null || tableViewer.getControl().isDisposed())
+			return null;
+		return ((IStructuredSelection) tableViewer.getSelection()).getFirstElement();
+	}
+	
+	/**
+	 * Returns the shell of the sub-page.
+	 */
+	protected final Shell getShell() {
+		if (tableViewer == null || tableViewer.getControl().isDisposed())
+			return null;
+		return tableViewer.getControl().getShell();
+	}
+	
+	/**
+	 * Handles the remove button pressed event
+	 */
+	protected void removeButtonPressed() {
+		IStructuredSelection sel = (IStructuredSelection) tableViewer.getSelection();
+		Iterator enum = sel.iterator();
+		while (enum.hasNext())
+			contentProvider.remove(enum.next());
+	}
+	
+	/**
+	 * Sets the contents of the table on this page.  Has no effect
+	 * if this widget has not yet been created or has been disposed.
+	 */
+	public void setInput(List inputs) {
+		if (tableViewer == null || tableViewer.getControl().isDisposed())
+			return;
+		tableViewer.setInput(inputs);
+		tableSelectionChanged((IStructuredSelection) tableViewer.getSelection());
+	}
+	/**
+	 * Handles selection changes in the table viewer.
+	 */
+	protected void tableSelectionChanged(IStructuredSelection newSelection) {
+	}
+
+	/**
+	 * Updates the content element in the table viewer.
+	 */
+	protected final void updateContent(Object element) {
+		if (tableViewer == null || tableViewer.getControl().isDisposed())
+			return;
+		tableViewer.update(element, null);
+	}
+	
+	/**
+	 * Creates this page's controls
+	 */
+	public Control createControl(Composite parent) {
+		Composite top = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginHeight = 2;
+		layout.marginWidth = 2;
+		top.setLayout(layout);
+
+		createTable(top);
+		createButtonGroup(top);
+		
+		return top;
+	}
+
+
+	/**
+	 * Content provider that maintains a generic list of objects which
+	 * are shown in a table viewer.
+	 */
+	private static final class AntPageContentProvider implements IStructuredContentProvider {
+		private ArrayList elements = new ArrayList();
+		private TableViewer viewer;
+	
+		public void add(Object o) {
+			if (elements.contains(o)) {
+				return;
+			}
+			elements.add(o);
+			viewer.add(o);
+		}
+		
+		public void dispose() {
+		}
+		
+		public Object[] getElements(Object inputElement) {
+			return (Object[]) elements.toArray(new Object[elements.size()]);
+		}
+		
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+			this.viewer = (TableViewer) viewer;
+			elements.clear();
+			if (newInput != null)
+				elements.addAll((List) newInput);
+		}
+		
+		public void remove(Object o) {
+			elements.remove(o);
+			viewer.remove(o);
+		}
+	}
+	
+	protected AntPreferencePage getPreferencePage() {
+		return preferencePage;
+	}
+	
+	protected TableViewer getTableViewer() {
+		return tableViewer;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntPageLabelProvider.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntPageLabelProvider.java
new file mode 100644
index 0000000..b10e620
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntPageLabelProvider.java
@@ -0,0 +1,115 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.net.URL;
+
+import org.eclipse.ant.core.*;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.*;
+import org.eclipse.ui.externaltools.internal.core.ExternalToolsPlugin;
+
+/**
+ * Label provider for the items in the custmomize ant preference page: 
+ * URLs, Tasks, and Types.
+ */
+public class AntPageLabelProvider
+	extends LabelProvider
+	implements ITableLabelProvider {
+		
+	private Image folderImage;
+	private Image jarImage;
+	private Image taskImage;
+	private Image typeImage;
+
+	public AntPageLabelProvider() {
+	}
+	public void dispose() {
+		//note: folder and task are shared images
+		folderImage = null;
+		taskImage = null;
+		if (jarImage != null) {
+			jarImage.dispose();
+			jarImage = null;
+		}
+		if (typeImage != null) {
+			typeImage.dispose();
+			typeImage = null;
+		}
+	}
+	public Image getColumnImage(Object element, int columnIndex) {
+		if (element instanceof URL) {
+			URL url = (URL) element;
+			if (url.getFile().endsWith("/")) { //$NON-NLS-1$
+				return folderImage();
+			} else {
+				return jarImage();
+			}
+		}
+		if (element instanceof Task) {
+			return taskImage();
+		}
+		if (element instanceof Type) {
+			return typeImage();
+		}
+		return null;
+	}
+	public String getColumnText(Object element, int columnIndex) {
+		if (element instanceof URL) {
+			return ((URL) element).getFile();
+		}
+		if (element instanceof Task) {
+			Task task = (Task) element;
+			return task.getTaskName() + " (" + task.getLibrary().getFile() + ": " + task.getClassName() + ")"; //$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
+		}
+		if (element instanceof Type) {
+			Type type = (Type) element;
+			return type.getTypeName() + " (" + type.getLibrary().getFile() + ": " + type.getClassName() + ")"; //$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
+		}
+		return element.toString();
+	}
+	private Image folderImage() {
+		if (folderImage != null)
+			return folderImage;
+		folderImage =
+			PlatformUI.getWorkbench().getSharedImages().getImage(
+				ISharedImages.IMG_OBJ_FOLDER);
+		return folderImage;
+	}
+	private Image jarImage() {
+		if (jarImage != null)
+			return jarImage;
+		jarImage =
+			ExternalToolsPlugin
+				.getDefault()
+				.getImageDescriptor(ExternalToolsPlugin.IMG_JAR_FILE)
+				.createImage();
+		return jarImage;
+	}
+	private Image taskImage() {
+		if (taskImage != null)
+			return taskImage;
+		taskImage =
+			PlatformUI.getWorkbench().getSharedImages().getImage(
+				ISharedImages.IMG_OBJS_TASK_TSK);
+		return taskImage;
+	}
+	private Image typeImage() {
+		if (typeImage != null)
+			return typeImage;
+		typeImage =
+			ExternalToolsPlugin
+				.getDefault()
+				.getImageDescriptor(ExternalToolsPlugin.IMG_TYPE)
+				.createImage();
+		return typeImage;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntPreferencePage.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntPreferencePage.java
new file mode 100644
index 0000000..87528a7
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntPreferencePage.java
@@ -0,0 +1,128 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others. All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html

+Contributors:
+**********************************************************************/
+
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.ant.core.*;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.externaltools.internal.core.ExternalToolsPlugin;
+import org.eclipse.ui.externaltools.internal.core.ToolMessages;
+import org.eclipse.ui.help.WorkbenchHelp;
+
+/**
+ * Ant preference page to set the classpath, tasks, and types.
+ */
+public class AntPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+	
+	private AntClasspathPage classpathPage;
+	private AntTasksPage tasksPage;
+	private AntTypesPage typesPage;
+	
+	/**
+	 * Creates the preference page
+	 */
+	public AntPreferencePage() {
+		setDescription(ToolMessages.getString("AntPreferencePage.description")); //$NON-NLS-1$
+		setPreferenceStore(ExternalToolsPlugin.getDefault().getPreferenceStore());
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on IWorkbenchPreferencePage.
+	 */
+	public void init(IWorkbench workbench) {
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on PreferencePage.
+	 */
+	protected Control createContents(Composite parent) {
+		WorkbenchHelp.setHelp(parent, IHelpContextIds.ANT_PREFERENCE_PAGE);
+
+		TabFolder folder = new TabFolder(parent, SWT.NONE);
+		folder.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+		classpathPage = new AntClasspathPage(this);
+		classpathPage.createTabItem(folder);
+		tasksPage = new AntTasksPage(this);
+		tasksPage.createTabItem(folder);
+		typesPage = new AntTypesPage(this);
+		typesPage.createTabItem(folder);
+
+		AntCorePreferences prefs = AntCorePlugin.getPlugin().getPreferences();
+		classpathPage.setInput(Arrays.asList(prefs.getCustomURLs()));
+		tasksPage.setInput(Arrays.asList(prefs.getCustomTasks()));
+		typesPage.setInput(Arrays.asList(prefs.getCustomTypes()));
+
+		return folder;
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on PreferencePage.
+	 */
+	protected void performDefaults() {
+		super.performDefaults();
+		
+		AntCorePreferences prefs = AntCorePlugin.getPlugin().getPreferences();
+		classpathPage.setInput(Arrays.asList(prefs.getDefaultCustomURLs()));
+		tasksPage.setInput(Arrays.asList(prefs.getCustomTasks()));
+		typesPage.setInput(Arrays.asList(prefs.getCustomTypes()));
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on PreferencePage.
+	 */
+	public boolean performOk() {
+		AntCorePreferences prefs = AntCorePlugin.getPlugin().getPreferences();
+		
+		List contents = classpathPage.getContents();
+		if (contents != null) {
+			URL[] urls = (URL[]) contents.toArray(new URL[contents.size()]);
+			prefs.setCustomURLs(urls);
+		}
+		
+		contents = tasksPage.getContents();
+		if (contents != null) {
+			Task[] tasks = (Task[]) contents.toArray(new Task[contents.size()]);
+			prefs.setCustomTasks(tasks);
+		}
+		
+		contents = typesPage.getContents();
+		if (contents != null) {
+			Type[] types = (Type[]) contents.toArray(new Type[contents.size()]);
+			prefs.setCustomTypes(types);
+		}
+		
+		prefs.updatePluginPreferences();
+		return super.performOk();
+	}
+	
+	/**
+	 * Sets the <code>GridData</code> on the specified button to
+	 * be one that is spaced for the current dialog page units.
+	 * 
+	 * @param button the button to set the <code>GridData</code>
+	 * @return the <code>GridData</code> set on the specified button
+	 */
+	/*package*/ GridData setButtonGridData(Button button) {
+		return setButtonLayoutData(button);
+	}
+	
+	protected List getLibraryURLs() {
+		return classpathPage.getContents();
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntRunActionDelegate.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntRunActionDelegate.java
new file mode 100644
index 0000000..4a48b46
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntRunActionDelegate.java
@@ -0,0 +1,57 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import org.eclipse.core.resources.IFile;
+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.actions.ActionDelegate;
+
+/**
+ * Action delegate to launch Ant on a build file.
+ */
+public class AntRunActionDelegate extends ActionDelegate implements IObjectActionDelegate {
+	private IFile selectedFile;
+	private IWorkbenchPart part;
+
+	/* (non-Javadoc)
+	 * Method declared on IActionDelegate.
+	 */
+	public void run(IAction action) {
+		if (part != null && selectedFile != null) {
+			new AntAction(selectedFile, part.getSite().getWorkbenchWindow()).run();
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on IActionDelegate.
+	 */
+	public void selectionChanged(IAction action, ISelection selection) {
+		selectedFile = null;
+		if (selection instanceof IStructuredSelection) {
+			IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+			if (structuredSelection.size() == 1) {
+				Object selectedResource = structuredSelection.getFirstElement();
+				if (selectedResource instanceof IFile)
+					selectedFile = (IFile) selectedResource;
+			}
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on IObjectActionDelegate.
+	 */
+	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
+		this.part = targetPart;
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTargetContentProvider.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTargetContentProvider.java
new file mode 100644
index 0000000..4334b68
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTargetContentProvider.java
@@ -0,0 +1,45 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import org.eclipse.jface.viewers.*;
+import org.eclipse.ui.externaltools.internal.core.AntTargetList;
+
+/**
+ * Content provider for targets within an Ant file
+ */
+public class AntTargetContentProvider implements IStructuredContentProvider {
+	/**
+	 * Creates a default instance of the content provider.
+	 */
+	public AntTargetContentProvider() {
+		super();
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on IStructuredContentProvider.
+	 */
+	public Object[] getElements(Object input) {
+		AntTargetList targetList = (AntTargetList) input;
+		return targetList.getTargets();
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on IContentProvider.
+	 */
+	public void dispose() {
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on IContentProvider.
+	 */
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTargetLabelProvider.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTargetLabelProvider.java
new file mode 100644
index 0000000..4bfdc44
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTargetLabelProvider.java
@@ -0,0 +1,64 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.util.ArrayList;
+
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.ui.externaltools.internal.core.ToolMessages;
+
+/**
+ * Ant target label provider
+ */
+public class AntTargetLabelProvider extends LabelProvider {
+	private ArrayList selectedTargets = null;
+	private String defaultTargetName = null;
+
+	/* (non-Javadoc)
+	 * Method declared on ILabelProvider.
+	 */
+	public String getText(Object model) {
+		String targetToDisplay = (String) model;
+		if (targetToDisplay != null) {
+			StringBuffer result = new StringBuffer(targetToDisplay);
+			if (targetToDisplay.equals(defaultTargetName)) {
+				result.append(" ("); //$NON-NLS-1$;
+				result.append(ToolMessages.getString("AntTargetLabelProvider.defaultTarget")); //$NON-NLS-1$;
+				result.append(")"); //$NON-NLS-1$;
+			}
+			if (selectedTargets != null) {
+				int targetIndex = selectedTargets.indexOf(targetToDisplay);
+				if (targetIndex >= 0) {
+					result.append(" ["); //$NON-NLS-1$;
+					result.append(targetIndex + 1);
+					result.append("]"); //$NON-NLS-1$;
+				}
+			}
+			return result.toString();
+		} else {
+			return "";
+		}
+	}
+
+	/**
+	 * Sets the targets selected in the viewer.
+	 */
+	public void setSelectedTargets(ArrayList value) {
+		selectedTargets = value;
+	}
+
+	/**
+	 * Sets the name of the default target
+	 */
+	public void setDefaultTargetName(String name) {
+		defaultTargetName = name;
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTasksPage.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTasksPage.java
new file mode 100644
index 0000000..9b34242
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTasksPage.java
@@ -0,0 +1,180 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others. All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html

+Contributors:
+**********************************************************************/
+
+import org.eclipse.ant.core.Task;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.externaltools.internal.core.ToolMessages;
+
+/**
+ * Sub-page that allows the user to enter custom tasks
+ * to be used when running Ant build files.
+ */
+public class AntTasksPage extends AntPage {
+	private static final int ADD_TASK_BUTTON = IDialogConstants.CLIENT_ID + 1;
+	private static final int EDIT_TASK_BUTTON = IDialogConstants.CLIENT_ID + 2;
+	private static final int REMOVE_BUTTON = IDialogConstants.CLIENT_ID + 3;
+
+	private final AntTasksLabelProvider labelProvider = new AntTasksLabelProvider();
+	/**
+	 * Creates an instance.
+	 */
+	public AntTasksPage(AntPreferencePage preferencePage) {
+		super(preferencePage);
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on AntPage.
+	 */
+	protected void addButtonsToButtonGroup(Composite parent) {
+		createButton(parent, "AntTasksPage.addTaskButtonTitle", ADD_TASK_BUTTON); //$NON-NLS-1$
+		editButton = createButton(parent, "AntTasksPage.editTaskButtonTitle", EDIT_TASK_BUTTON); //$NON-NLS-1$
+		createSeparator(parent);
+		removeButton = createButton(parent, "AntTasksPage.removeButtonTitle", REMOVE_BUTTON); //$NON-NLS-1$
+	}
+	
+	/**
+	 * Allows the user to enter a custom task.
+	 */
+	private void addTaskButtonPressed() {
+		String title = ToolMessages.getString("AntTasksPage.addTaskDialogTitle"); //$NON-NLS-1$
+		String msg = ToolMessages.getString("AntTasksPage.addTaskDialogDescription"); //$NON-NLS-1$
+		AddCustomDialog dialog = new AddCustomDialog(getShell(), getPreferencePage().getLibraryURLs(), title, msg);
+		if (dialog.open() == Dialog.CANCEL)
+			return;
+
+		Task task = new Task();
+		task.setTaskName(dialog.getTaskName());
+		task.setClassName(dialog.getClassName());
+		task.setLibrary(dialog.getLibrary());
+		addContent(task);
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on AntPage.
+	 */
+	protected void buttonPressed(int buttonId) {
+		switch (buttonId) {
+			case ADD_TASK_BUTTON :
+				addTaskButtonPressed();
+				break;
+			case EDIT_TASK_BUTTON :
+				editTaskButtonPressed();
+				break;
+			case REMOVE_BUTTON :
+				removeButtonPressed();
+				break;
+		}
+	}
+	
+	/**
+	 * Creates the tab item that contains this sub-page.
+	 */
+	public TabItem createTabItem(TabFolder folder) {
+		TabItem item = new TabItem(folder, SWT.NONE);
+		item.setText(ToolMessages.getString("AntTasksPage.title")); //$NON-NLS-1$
+		item.setImage(labelProvider.getTaskImage());
+		item.setData(this);
+		item.setControl(createControl(folder));
+		return item;
+	}
+
+	/**
+	 * Allows the user to edit a custom Ant task.
+	 */	
+	private void editTaskButtonPressed() {
+		String title = ToolMessages.getString("AntTasksPage.editTaskDialogTitle"); //$NON-NLS-1$
+		String msg = ToolMessages.getString("AntTasksPage.editTaskDialogDescription"); //$NON-NLS-1$
+		AddCustomDialog dialog = new AddCustomDialog(getShell(), getPreferencePage().getLibraryURLs(), title, msg);
+		Task task = (Task) getSelectedElement();
+		if (task == null)
+			return;
+		dialog.setClassName(task.getClassName());
+		dialog.setTaskName(task.getTaskName());
+		dialog.setLibrary(task.getLibrary());
+		if (dialog.open() == Dialog.CANCEL)
+			return;
+
+		task.setTaskName(dialog.getTaskName());
+		task.setClassName(dialog.getClassName());
+		task.setLibrary(dialog.getLibrary());
+		updateContent(task);
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on AntPage.
+	 */
+	protected ITableLabelProvider getLabelProvider() {
+		return labelProvider;
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on AntPage.
+	 */
+	protected void tableSelectionChanged(IStructuredSelection newSelection) {
+		int size = newSelection.size();
+		editButton.setEnabled(size == 1);
+		removeButton.setEnabled(size > 0);
+	}
+	
+	
+	/**
+	 * Label provider for task elements
+	 */
+	private static final class AntTasksLabelProvider extends LabelProvider implements ITableLabelProvider {
+		private Image taskImage;
+	
+		/**
+		 * Creates an instance.
+		 */
+		public AntTasksLabelProvider() {
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on IBaseLabelProvider.
+		 */
+		public void dispose() {
+			// Task image is shared, do not dispose.
+			taskImage = null;
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on ITableLabelProvider.
+		 */
+		public Image getColumnImage(Object element, int columnIndex) {
+			return getTaskImage();
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on ITableLabelProvider.
+		 */
+		public String getColumnText(Object element, int columnIndex) {
+			Task task = (Task) element;
+			return task.getTaskName() + " (" + task.getLibrary().getFile() + ": " + task.getClassName() + ")"; //$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
+		}
+		
+		public Image getTaskImage() {
+			if (taskImage == null)
+				taskImage = PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJS_TASK_TSK);
+			return taskImage;
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTypesPage.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTypesPage.java
new file mode 100644
index 0000000..dadefac
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/AntTypesPage.java
@@ -0,0 +1,187 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others. All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html

+Contributors:
+**********************************************************************/
+
+import org.eclipse.ant.core.Type;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.TabFolder;
+import org.eclipse.swt.widgets.TabItem;
+import org.eclipse.ui.externaltools.internal.core.ExternalToolsPlugin;
+import org.eclipse.ui.externaltools.internal.core.ToolMessages;
+
+/**
+ * Sub-page that allows the user to enter custom types
+ * to be used when running Ant build files.
+ */
+public class AntTypesPage extends AntPage {
+	private static final int ADD_TYPE_BUTTON = IDialogConstants.CLIENT_ID + 1;
+	private static final int EDIT_TYPE_BUTTON = IDialogConstants.CLIENT_ID + 2;
+	private static final int REMOVE_BUTTON = IDialogConstants.CLIENT_ID + 3;
+
+	private final AntTypesLabelProvider labelProvider = new AntTypesLabelProvider();
+	/**
+	 * Creates an instance.
+	 */
+	public AntTypesPage(AntPreferencePage preferencePage) {
+		super(preferencePage);
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on AntPage.
+	 */
+	protected void addButtonsToButtonGroup(Composite parent) {
+		createButton(parent, "AntTypesPage.addTypeButtonTitle", ADD_TYPE_BUTTON); //$NON-NLS-1$
+		editButton = createButton(parent, "AntTypesPage.editTypeButtonTitle", EDIT_TYPE_BUTTON); //$NON-NLS-1$
+		createSeparator(parent);
+		removeButton = createButton(parent, "AntTypesPage.removeButtonTitle", REMOVE_BUTTON); //$NON-NLS-1$
+	}
+	
+	/**
+	 * Allows the user to enter a custom type.
+	 */
+	private void addTypeButtonPressed() {
+		String title = ToolMessages.getString("AntTypesPage.addTypeDialogTitle"); //$NON-NLS-1$
+		String msg = ToolMessages.getString("AntTypesPage.addTypeDialogDescription"); //$NON-NLS-1$
+		AddCustomDialog dialog = new AddCustomDialog(getShell(), getPreferencePage().getLibraryURLs(), title, msg);
+		if (dialog.open() == Dialog.CANCEL) {
+			return;
+		}
+
+		Type type = new Type();
+		type.setTypeName(dialog.getTaskName());
+		type.setClassName(dialog.getClassName());
+		type.setLibrary(dialog.getLibrary());
+		addContent(type);
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on AntPage.
+	 */
+	protected void buttonPressed(int buttonId) {
+		switch (buttonId) {
+			case ADD_TYPE_BUTTON :
+				addTypeButtonPressed();
+				break;
+			case EDIT_TYPE_BUTTON :
+				editTypeButtonPressed();
+				break;
+			case REMOVE_BUTTON :
+				removeButtonPressed();
+				break;
+		}
+	}
+	
+	/**
+	 * Creates the tab item that contains this sub-page.
+	 */
+	public TabItem createTabItem(TabFolder folder) {
+		TabItem item = new TabItem(folder, SWT.NONE);
+		item.setText(ToolMessages.getString("AntTypesPage.typesPageTitle")); //$NON-NLS-1$
+		item.setImage(labelProvider.getTypeImage());
+		item.setData(this);
+		item.setControl(createControl(folder));
+		return item;
+	}
+	
+	/**
+	 * Allows the user to edit a custom Ant type.
+	 */	
+	private void editTypeButtonPressed() {
+		String title = ToolMessages.getString("AntTypesPage.editTypeDialogTitle"); //$NON-NLS-1$
+		String msg = ToolMessages.getString("AntTypesPage.editTypeDialogDescription"); //$NON-NLS-1$
+		AddCustomDialog dialog = new AddCustomDialog(getShell(), getPreferencePage().getLibraryURLs(), title, msg);
+		Type type = (Type) getSelectedElement();
+		if (type == null)
+			return;
+		dialog.setClassName(type.getClassName());
+		dialog.setTaskName(type.getTypeName());
+		dialog.setLibrary(type.getLibrary());
+		if (dialog.open() == Dialog.CANCEL) {
+			return;
+		}
+
+		type.setTypeName(dialog.getTaskName());
+		type.setClassName(dialog.getClassName());
+		type.setLibrary(dialog.getLibrary());
+		updateContent(type);
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on AntPage.
+	 */
+	protected ITableLabelProvider getLabelProvider() {
+		return labelProvider;
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on AntPage.
+	 */
+	protected void tableSelectionChanged(IStructuredSelection newSelection) {
+		int size = newSelection.size();
+		editButton.setEnabled(size == 1);
+		removeButton.setEnabled(size > 0);
+	}
+
+
+	/**
+	 * Label provider for type elements
+	 */
+	private static final class AntTypesLabelProvider extends LabelProvider implements ITableLabelProvider {
+		private static final String IMG_TYPE = "icons/full/obj16/type.gif"; //$NON-NLS-1$;
+		private Image typeImage;
+	
+		/**
+		 * Creates an instance.
+		 */
+		public AntTypesLabelProvider() {
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on IBaseLabelProvider.
+		 */
+		public void dispose() {
+			if (typeImage != null) {
+				typeImage.dispose();
+				typeImage = null;
+			}
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on ITableLabelProvider.
+		 */
+		public Image getColumnImage(Object element, int columnIndex) {
+			return getTypeImage();
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on ITableLabelProvider.
+		 */
+		public String getColumnText(Object element, int columnIndex) {
+			Type type = (Type) element;
+			return type.getTypeName() + " (" + type.getLibrary().getFile() + ": " + type.getClassName() + ")"; //$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
+		}
+		
+		public Image getTypeImage() {
+			if (typeImage == null) {
+				ImageDescriptor desc = ExternalToolsPlugin.getDefault().getImageDescriptor(IMG_TYPE);
+				typeImage = desc.createImage();
+			}
+			return typeImage;
+		}
+	}
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/BuilderPropertyPage.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/BuilderPropertyPage.java
new file mode 100644
index 0000000..b7bf255
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/BuilderPropertyPage.java
@@ -0,0 +1,401 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.util.*;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.dialogs.PropertyPage;
+import org.eclipse.ui.externaltools.internal.core.*;
+
+/**
+ * Property page to add external tools in between builders.
+ */
+public final class BuilderPropertyPage extends PropertyPage {
+	private static final int BUILDER_TABLE_WIDTH = 250;
+
+	private Table builderTable;
+	private Button upButton, downButton, newButton, editButton, removeButton;
+	private ArrayList imagesToDispose = new ArrayList();
+	private Image antImage, builderImage, externalToolImage, invalidBuildToolImage;
+
+	/**
+	 * Creates an initialized property page
+	 */
+	public BuilderPropertyPage() {
+		super();
+		noDefaultAndApplyButton();
+	}
+
+	/**
+	 * Add the project's build to the table viewer.
+	 */
+	private void addBuildersToTable() {
+		IProject project = getInputProject();
+		if (project == null) {
+			return;
+		}
+		//add build spec entries to the table
+		try {
+			ICommand[] commands = project.getDescription().getBuildSpec();
+			for (int i = 0; i < commands.length; i++) {
+				addCommand(commands[i], -1, false);
+			}
+		} catch (CoreException e) {
+			handleException(e);
+		}
+	}
+	
+	/**
+	 * Adds a build command to the table viewer.
+	 * 
+	 * @param command the command to be added
+	 * @param position the insertion position, or -1 to add at the end
+	 * @param select whether to select the newly created item.
+	 */
+	private void addCommand(ICommand command, int position, boolean select) {
+		TableItem newItem;
+		if (position < 0) {
+			newItem = new TableItem(builderTable, SWT.NONE);
+		} else {
+			newItem = new TableItem(builderTable, SWT.NONE, position);
+		}
+		newItem.setData(command);
+		updateCommandItem(newItem, command);
+		if (select) builderTable.setSelection(position);
+	}
+	
+	/**
+	 * Configures and creates a new build command
+	 * that invokes an external tool.  Returns the new command,
+	 * or <code>null</code> if no command was created.
+	 */
+	private ICommand createTool() {
+		try {
+			EditDialog dialog;
+			dialog = new EditDialog(getShell(), null);
+			if (dialog.open() == Window.OK) {
+				ExternalTool tool = dialog.getExternalTool();
+				ICommand command = getInputProject().getDescription().newCommand();
+				return tool.toBuildCommand(command);
+			} else {
+				return null;	
+			}
+		} catch(CoreException e) {
+			handleException(e);
+			return null;
+		}		
+	}
+	
+	/**
+	 * Edits an exisiting build command that invokes an external tool.
+	 */
+	private void editTool(ICommand command) {
+		ExternalTool tool = ExternalTool.fromArgumentMap(command.getArguments());
+		if (tool == null)
+			return;
+		EditDialog dialog;
+		dialog = new EditDialog(getShell(), tool);
+		if (dialog.open() == Window.OK) {
+			tool = dialog.getExternalTool();
+			tool.toBuildCommand(command);
+		}
+	}
+	
+	/**
+	 * Creates and returns a button with the given label, id, and enablement.
+	 */
+	private Button createButton(Composite parent, String label) {
+		Button button = new Button(parent, SWT.PUSH);
+		GridData data = new GridData();
+		data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+		data.heightHint = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
+		button.setLayoutData(data); 
+		button.setText(label);
+		button.setEnabled(false);
+		button.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleButtonPressed((Button)e.widget);
+			}
+		});
+		return button;
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on PreferencePage.
+	 */
+	protected Control createContents(Composite parent) {
+		externalToolImage = ExternalToolsPlugin.getDefault().getImageDescriptor(ExternalToolsPlugin.IMG_EXTERNAL_TOOL).createImage();
+		antImage = ExternalToolsPlugin.getDefault().getImageDescriptor(ExternalToolsPlugin.IMG_ANT_TOOL).createImage();
+		builderImage = ExternalToolsPlugin.getDefault().getImageDescriptor(ExternalToolsPlugin.IMG_BUILDER).createImage();
+		invalidBuildToolImage = ExternalToolsPlugin.getDefault().getImageDescriptor(ExternalToolsPlugin.IMG_INVALID_BUILD_TOOL).createImage();
+
+		imagesToDispose.add(externalToolImage);
+		imagesToDispose.add(antImage);
+		imagesToDispose.add(builderImage);
+		imagesToDispose.add(invalidBuildToolImage);
+		
+		Composite topLevel = new Composite(parent, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		topLevel.setLayout(layout);
+		topLevel.setLayoutData(new GridData(GridData.FILL_BOTH));
+		
+		Label description = new Label(topLevel, SWT.WRAP);
+		description.setText(ToolMessages.getString("BuilderPropertyPage.description")); //$NON-NLS-1$
+		description.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+	
+		Composite tableAndButtons = new Composite(topLevel, SWT.NONE);
+		tableAndButtons.setLayoutData(new GridData(GridData.FILL_BOTH));
+		layout = new GridLayout();
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		layout.numColumns = 2;
+		tableAndButtons.setLayout(layout);
+	
+		// table of builders and tools		
+		builderTable = new Table(tableAndButtons, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
+		GridData data = new GridData(GridData.FILL_BOTH);
+		data.widthHint = BUILDER_TABLE_WIDTH;
+		builderTable.setLayoutData(data);
+		builderTable.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleTableSelectionChanged();
+			}
+		});
+		
+		//button area
+		Composite buttonArea = new Composite(tableAndButtons, SWT.NONE);
+		layout = new GridLayout();
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		buttonArea.setLayout(layout);
+		buttonArea.setLayoutData(new GridData(GridData.FILL_VERTICAL));
+		newButton = createButton(buttonArea, ToolMessages.getString("BuilderPropertyPage.newButton")); //$NON-NLS-1$
+		editButton = createButton(buttonArea, ToolMessages.getString("BuilderPropertyPage.editButton")); //$NON-NLS-1$
+		removeButton = createButton(buttonArea, ToolMessages.getString("BuilderPropertyPage.removeButton")); //$NON-NLS-1$
+		new Label(buttonArea, SWT.LEFT);
+		upButton = createButton(buttonArea, ToolMessages.getString("BuilderPropertyPage.upButton")); //$NON-NLS-1$
+		downButton = createButton(buttonArea, ToolMessages.getString("BuilderPropertyPage.downButton")); //$NON-NLS-1$
+	
+		newButton.setEnabled(true);
+		
+		//populate widget contents	
+		addBuildersToTable();
+		
+		return topLevel;
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on DialogPage.
+	 */
+	public void dispose() {
+		super.dispose();
+		for (Iterator i = imagesToDispose.iterator(); i.hasNext();) {
+			Image image = (Image) i.next();
+			image.dispose();
+		}
+		imagesToDispose.clear();
+	}
+	
+	/**
+	 * Returns the project that is the input for this property page,
+	 * or <code>null</code>.
+	 */
+	private IProject getInputProject() {
+		IAdaptable element = getElement();
+		if (element instanceof IProject) {
+			return (IProject)element;
+		}
+		Object resource = element.getAdapter(IResource.class);
+		if (resource instanceof IProject) {
+			return (IProject)resource;
+		}
+		return null;
+	}
+	
+	/**
+	 * One of the buttons has been pressed, act accordingly.
+	 */
+	private void handleButtonPressed(Button button) {
+		if (button == newButton) {
+			ICommand newCommand = createTool();
+			if (newCommand != null) {
+				int insertPosition = builderTable.getSelectionIndex() + 1;
+				addCommand(newCommand, insertPosition, true);
+			}
+		} else if (button == editButton) {
+			TableItem[] selection = builderTable.getSelection();
+			if (selection != null) {
+				editTool((ICommand)selection[0].getData());
+				updateCommandItem(selection[0],(ICommand)selection[0].getData());
+			}
+		} else if (button == removeButton) {
+			TableItem[] selection = builderTable.getSelection();
+			if (selection != null) {
+				for (int i = 0; i < selection.length; i++) {
+					selection[i].dispose();
+				}
+			}
+		} else if (button == upButton) {
+			moveSelectionUp();
+		} else if (button == downButton) {
+			moveSelectionDown();
+		}
+		handleTableSelectionChanged();
+		builderTable.setFocus();
+	}
+	
+	/**
+	 * Handles unexpected internal exceptions
+	 */
+	private void handleException(Exception e) {
+		IStatus status;
+		if (e instanceof CoreException) {
+			status = ((CoreException)e).getStatus();
+		} else {
+			status = new Status(IStatus.ERROR, ExternalToolsPlugin.PLUGIN_ID, 0, ToolMessages.getString("BuilderPropertyPage.statusMessage"), e); //$NON-NLS-1$
+		}
+		ErrorDialog.openError(
+			getShell(),
+			ToolMessages.getString("BuilderPropertyPage.errorTitle"), //$NON-NLS-1$
+			ToolMessages.getString("BuilderPropertyPage.errorMessage"), //$NON-NLS-1$
+			status);
+	}
+	
+	/**
+	 * The user has selected a different builder in table.
+	 * Update button enablement.
+	 */
+	private void handleTableSelectionChanged() {
+		newButton.setEnabled(true);
+		TableItem[] items = builderTable.getSelection();
+		if (items != null && items.length == 1) {
+			TableItem item = items[0];
+			ICommand buildCommand = (ICommand)item.getData();
+			if (buildCommand.getBuilderName().equals(ExternalToolsBuilder.ID)) {
+				editButton.setEnabled(true);
+				removeButton.setEnabled(true);
+				int selection = builderTable.getSelectionIndex();
+				int max = builderTable.getItemCount();
+				upButton.setEnabled(selection != 0);
+				downButton.setEnabled(selection < max-1);
+				return;
+			}
+		}
+		//in all other cases we can't do any of these.
+		editButton.setEnabled(false);
+		removeButton.setEnabled(false);
+		upButton.setEnabled(false);
+		downButton.setEnabled(false);
+	}
+	
+	/**
+	 * Moves an entry in the builder table to the given index.
+	 */
+	private void move(TableItem item, int index) {
+		Object data = item.getData();
+		String text = item.getText();
+		Image image= item.getImage();
+		item.dispose();
+		TableItem newItem = new TableItem(builderTable, SWT.NONE, index);
+		newItem.setData(data);
+		newItem.setText(text);
+		newItem.setImage(image);
+	}
+	
+	/**
+	 * Move the current selection in the build list down.
+	 */
+	private void moveSelectionDown() {
+		// Only do this operation on a single selection
+		if (builderTable.getSelectionCount() == 1) {
+			int currentIndex = builderTable.getSelectionIndex();
+			if (currentIndex < builderTable.getItemCount() - 1) {
+				move(builderTable.getItem(currentIndex), currentIndex+1);
+				builderTable.setSelection(currentIndex+1);
+			}
+		}
+	}
+	
+	/**
+	 * Move the current selection in the build list up.
+	 */
+	private void moveSelectionUp() {
+		int currentIndex = builderTable.getSelectionIndex();
+		// Only do this operation on a single selection
+		if (currentIndex > 0 && builderTable.getSelectionCount() == 1) {
+			move(builderTable.getItem(currentIndex), currentIndex-1);
+			builderTable.setSelection(currentIndex-1);
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on IPreferencePage.
+	 */
+	public boolean performOk() {
+		//get all the build commands
+		int numCommands = builderTable.getItemCount();
+		ICommand[] commands = new ICommand[numCommands];
+		for (int i = 0; i < numCommands; i++) {
+			commands[i] = (ICommand)builderTable.getItem(i).getData();
+		}
+		//set the build spec
+		IProject project = getInputProject();
+		try {
+			IProjectDescription desc = project.getDescription();
+			desc.setBuildSpec(commands);
+			project.setDescription(desc, null);
+		} catch(CoreException e) {
+			handleException(e);
+		}
+		return super.performOk();
+	}
+	
+	/**
+	 * Update the table item with the given build command
+	 */
+	private void updateCommandItem(TableItem item, ICommand command) {
+		String builderID = command.getBuilderName();
+		if (builderID.equals(ExternalToolsBuilder.ID)) {
+			ExternalTool tool = ExternalTool.fromArgumentMap(command.getArguments());
+			if (tool == null) {
+				item.setText(ToolMessages.getString("BuilderPropertyPage.invalidBuildTool")); //$NON-NLS-1$
+				item.setImage(invalidBuildToolImage);
+				return;
+			}
+			item.setText(tool.getName());
+			if (ExternalTool.TOOL_TYPE_ANT.equals(tool.getType())) {
+				item.setImage(antImage);
+			} else {
+				item.setImage(externalToolImage);
+			}
+		} else {
+			// Get the human-readable name of the builder
+			IExtension extension = Platform.getPluginRegistry().getExtension(ResourcesPlugin.PI_RESOURCES, 	ResourcesPlugin.PT_BUILDERS, builderID);
+			String builderName;
+			if (extension != null)
+				builderName = extension.getLabel();
+			else
+				builderName = ToolMessages.format("BuilderPropertyPage.missingBuilder", new Object[] {builderID}); //$NON-NLS-1$
+			item.setText(builderName);
+			item.setImage(builderImage);
+		}
+	}
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/ConfigurationDialog.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/ConfigurationDialog.java
new file mode 100644
index 0000000..64b9ed7
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/ConfigurationDialog.java
@@ -0,0 +1,328 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.util.ArrayList;
+
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.externaltools.internal.core.*;
+import org.eclipse.ui.help.WorkbenchHelp;
+
+/**
+ * Dialog box to add, remove, and edit external tools.
+ */
+public class ConfigurationDialog extends TitleAreaDialog {
+	// Minimum height in chars of the details text box.
+	private static final int DETAILS_HEIGHT = 5;
+	
+	private ListViewer listViewer;
+	private Button newButton;
+	private Button editButton;
+	private Button removeButton;
+	private Button upButton;
+	private Button downButton;
+	private Text detailText;
+	private ExternalTool currentSelection;
+	private ArrayList tools;
+
+	/**
+	 * Instantiate a new external tool configuration dialog.
+	 *
+	 * @param parentShell the parent SWT shell
+	 */
+	public ConfigurationDialog(Shell parentShell) {
+		super(parentShell);
+	}
+
+	/* (non-Javadoc)
+	 * Method declared in Window.
+	 */
+	protected void configureShell(Shell shell) {
+		super.configureShell(shell);
+		shell.setText(ToolMessages.getString("ConfigurationDialog.shellTitle")); //$NON-NLS-1$
+		WorkbenchHelp.setHelp(
+			shell,
+			IHelpContextIds.CONFIGURE_DIALOG);
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on Dialog.
+	 */
+	protected void createButtonsForButtonBar(Composite parent) {
+		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+		createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on Dialog.
+	 */
+	protected Control createDialogArea(Composite parent) {
+		tools = new ArrayList(ExternalToolsPlugin.getDefault().getRegistry().getExternalTools());
+		
+		Composite dialogComp = (Composite)super.createDialogArea(parent);
+				
+		// Set title and message now that the controls exist
+		setTitle(ToolMessages.getString("ConfigurationDialog.dialogTitle")); //$NON-NLS-1$
+		setMessage(ToolMessages.getString("ConfigurationDialog.dialogMessage")); //$NON-NLS-1$
+		setTitleImage(ExternalToolsPlugin.getDefault().getImageDescriptor(ExternalToolsPlugin.IMG_WIZBAN_EXTERNAL_TOOLS).createImage());
+			
+		// Build the top container
+		Composite topComp = new Composite(dialogComp, SWT.NONE);
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = 5;
+		layout.marginWidth = 5;
+		topComp.setLayout(layout);
+		GridData data = new GridData(GridData.FILL_BOTH);
+		topComp.setLayoutData(data);
+
+		// Build middle container with 2 columns
+		Composite midComp = new Composite(topComp, SWT.NONE);
+		layout = new GridLayout();
+		layout.numColumns = 2;
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		midComp.setLayout(layout);
+		data = new GridData(GridData.FILL_BOTH);
+		midComp.setLayoutData(data);
+
+		// Build the tools list
+		Composite listComp = new Composite(midComp, SWT.NONE);
+		layout = new GridLayout();
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		listComp.setLayout(layout);
+		data = new GridData(GridData.FILL_BOTH);
+		listComp.setLayoutData(data);
+
+		Label label = new Label(listComp, SWT.LEFT);
+		label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		label.setText(ToolMessages.getString("ConfigurationDialog.toolList")); //$NON-NLS-1$
+		
+		listViewer = new ListViewer(listComp, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+		listViewer.getList().setLayoutData(new GridData(GridData.FILL_BOTH));
+		listViewer.setContentProvider(new ToolContentProvider());
+		listViewer.setLabelProvider(new ToolLabelProvider());
+		listViewer.setInput(tools);
+		listViewer.addDoubleClickListener(new IDoubleClickListener() {
+			public void doubleClick(DoubleClickEvent event) {
+				openEditToolDialog();
+			}
+		});
+
+		// Build the button list
+		Composite buttonComp = new Composite(midComp, SWT.NONE);
+		layout = new GridLayout();
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		buttonComp.setLayout(layout);
+		data = new GridData(GridData.FILL_VERTICAL);
+		buttonComp.setLayoutData(data);
+
+		label = new Label(buttonComp, SWT.LEFT); // spacer
+		label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+		newButton = createPushButton(buttonComp, "ConfigurationDialog.newButton", true); //$NON-NLS-1$
+		editButton = createPushButton(buttonComp, "ConfigurationDialog.editButton", false); //$NON-NLS-1$
+		removeButton = createPushButton(buttonComp, "ConfigurationDialog.removeButton", false); //$NON-NLS-1$
+		label = new Label(buttonComp, SWT.LEFT); // spacer
+		label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
+		upButton = createPushButton(buttonComp, "ConfigurationDialog.upButton", false); //$NON-NLS-1$
+		downButton = createPushButton(buttonComp, "ConfigurationDialog.downButton", false); //$NON-NLS-1$
+		
+		// Build the details field
+		label = new Label(topComp, SWT.LEFT);
+		label.setText(ToolMessages.getString("ConfigurationDialog.details")); //$NON-NLS-1$
+		label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+		detailText = new Text(topComp, SWT.WRAP | SWT.MULTI | SWT.V_SCROLL | SWT.BORDER);
+		detailText.setEditable(false);
+		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+		gridData.heightHint = convertHeightInCharsToPixels(DETAILS_HEIGHT);
+		detailText.setLayoutData(gridData);
+		
+		// Build the separator line
+		Label separator = new Label(topComp, SWT.HORIZONTAL | SWT.SEPARATOR);
+		separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		
+		// Finish setup
+		hookButtonActions();
+		hookStateUpdates();
+		
+		return dialogComp;
+	}
+	
+	private Button createPushButton(Composite parent, String labelKey, boolean enabled) {
+		Button button = new Button(parent, SWT.PUSH);
+		button.setText(ToolMessages.getString(labelKey));
+		button.setEnabled(enabled);
+		
+		GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
+		data.heightHint = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
+		int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+		data.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
+		button.setLayoutData(data);
+		
+		return button;
+	}
+	
+	/**
+	 * Adds the listeners required to handle the button
+	 * actions
+	 */
+	private void hookButtonActions() {
+		newButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				EditDialog dialog;
+				dialog = new EditDialog(getShell(), null);
+				if (dialog.open() == Window.OK) {
+					ExternalTool tool = dialog.getExternalTool();
+					tools.add(tool);
+					listViewer.add(tool);
+					listViewer.setSelection(new StructuredSelection(tool), true);
+				}
+			}
+		});
+
+		editButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				openEditToolDialog();
+			}
+		});
+
+		removeButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				tools.remove(currentSelection);
+				listViewer.remove(currentSelection);
+			}
+		});
+
+		upButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				int index = tools.indexOf(currentSelection);
+				if (index < 1)
+					return;
+				Object tool = tools.get(index - 1);
+				tools.set(index - 1, currentSelection);
+				tools.set(index, tool);
+				listViewer.refresh(false);
+				updateUpDownButtons();
+			}
+		});
+
+		downButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				int index = tools.indexOf(currentSelection);
+				if (index < 0 || index >= tools.size() - 1)
+					return;
+				Object tool = tools.get(index + 1);
+				tools.set(index + 1, currentSelection);
+				tools.set(index, tool);
+				listViewer.refresh(false);
+				updateUpDownButtons();
+			}
+		});
+	}
+
+	/**
+	 * Adds a listener to control button enablement based on
+	 * the current selection.
+	 */
+	private void hookStateUpdates() {
+		listViewer.addSelectionChangedListener(new ISelectionChangedListener() {
+			public void selectionChanged(SelectionChangedEvent event) {
+				currentSelection = null;
+				if (event.getSelection() instanceof IStructuredSelection) {
+					IStructuredSelection sel = (IStructuredSelection) event.getSelection() ;
+					currentSelection = (ExternalTool)sel.getFirstElement();
+				}
+
+				editButton.setEnabled(currentSelection != null);
+				removeButton.setEnabled(currentSelection != null);
+				updateUpDownButtons();
+				updateDetails();
+			}
+		});
+	}
+
+	/**
+	 * Update the enable state of the up/down buttons
+	 */
+	private void updateUpDownButtons() {
+		int selIndex = listViewer.getList().getSelectionIndex();
+		int itemCount = listViewer.getList().getItemCount();
+		upButton.setEnabled(currentSelection != null && selIndex > 0);
+		downButton.setEnabled(currentSelection != null && selIndex < itemCount - 1);
+	}
+
+	/**
+	 * Opens the edit external tool dialog on
+	 * the currently selected external tool.
+	 */
+	private void openEditToolDialog() {
+		if (currentSelection == null)
+			return;
+		EditDialog dialog;
+		dialog = new EditDialog(getShell(), currentSelection);
+		dialog.open();
+		listViewer.update(currentSelection, null);
+		updateDetails();
+	}
+	
+	/**
+	 * Update the detail field
+	 */
+	private void updateDetails() {
+		if (currentSelection == null)
+			detailText.setText(""); //$NON-NLS-1$
+		else
+			detailText.setText(ToolMessages.format("ConfigurationDialog.detailMessage", new Object[] {currentSelection.getLocation(), currentSelection.getArguments(), currentSelection.getWorkingDirectory()})); //$NON-NLS-1$
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on Dialog.
+	 */
+	protected void okPressed() {
+		ExternalToolsPlugin.getDefault().getRegistry().setExternalTools(tools);
+		super.okPressed();
+	}
+
+	
+	/**
+	 * Internal content provider of existing tool tools
+	 */
+	private class ToolContentProvider implements IStructuredContentProvider {
+		public Object[] getElements(Object inputElement) {
+			return tools.toArray();
+		}
+
+		public void dispose() {
+		}
+
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		}
+	}
+	
+	/**
+	 * Internal label provider of existing tool tools
+	 */
+	private class ToolLabelProvider extends LabelProvider {
+		public String getText(Object element) {
+			if (element instanceof ExternalTool)
+				return ((ExternalTool)element).getName();
+			else
+				return "";//$NON-NLS-1$
+		}
+	}
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/EditDialog.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/EditDialog.java
new file mode 100644
index 0000000..3e1fa65
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/EditDialog.java
@@ -0,0 +1,1116 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.io.File;
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.*;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.help.WorkbenchHelp;
+import org.eclipse.ui.model.*;
+import org.eclipse.ui.dialogs.*;
+import org.eclipse.ui.externaltools.internal.core.*;
+
+/**
+ * Dialog box to enter the required information for running
+ * an external tool.
+ */
+public class EditDialog extends TitleAreaDialog {
+	// The width of most text fields in the dialog.
+	// Fields that have labels on the same line are shorter.
+	// As such, all fields end in the same vertical position.
+	private static final int FIELD_WIDTH = 300;
+	// The spacing used to seperate groups in the dialog.
+	private static final int GROUP_SPACE = 20;
+	// The spacing used to seperate widgets in a group
+	private static final int WIDGET_SPACE = 5;
+	// The spacing of margins in the dialog
+	private static final int MARGIN_SPACE = 5;
+	
+	// dialog sizing constants
+	private static final int SIZING_SELECTION_PANE_HEIGHT = 300;
+	private static final int SIZING_SELECTION_PANE_WIDTH = 300;	
+	
+	private static final boolean INITIAL_SHOW_LOG = true;
+	
+	private Text nameField;
+	private Text locationField;
+	private Text argumentsField;
+	private Text directoryField;
+	private Text refreshField;
+	private Button locationBrowseWorkspace;
+	private Button locationBrowseFileSystem;
+	private Button argumentsBrowseVariable;
+//	private Button directoryBrowseWorkspace;
+	private Button directoryBrowseButton;
+	private Button refreshOptionButton;
+	private Button showLog;
+	
+	private boolean editMode = false;
+	private ExternalTool tool;
+	private String refreshScope;
+
+	private int maxButtonWidth = 0;
+	// The difference between the height of a button and
+	// the height of a label.
+	private int buttonLabelHeightDiff;
+	
+	/**
+	 * Instantiate a new tool tool edit dialog.
+	 *
+	 * @param parentShell the parent SWT shell
+	 * @param tool the tool tool to edit, <code>null</code> if new
+	 */
+	public EditDialog(Shell parentShell, ExternalTool tool) {
+		super(parentShell);
+		if (tool == null) {
+			this.tool = new ExternalTool();
+			this.editMode = false;
+		} else {
+			this.tool = tool;
+			this.editMode = true;
+		}
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared in Window.
+	 */
+	protected void configureShell(Shell shell) {
+		super.configureShell(shell);
+		if (editMode)
+			shell.setText(ToolMessages.getString("EditDialog.editShellTitle")); //$NON-NLS-1$
+		else
+			shell.setText(ToolMessages.getString("EditDialog.newShellTitle")); //$NON-NLS-1$
+		WorkbenchHelp.setHelp(
+			shell,
+			IHelpContextIds.EDIT_DIALOG);
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on Dialog.
+	 */
+	protected void createButtonsForButtonBar(Composite parent) {
+		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+		createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+		
+		if (!editMode)
+			getButton(IDialogConstants.OK_ID).setEnabled(false);
+			
+		// Now that both the dialog area and buttons have been
+		// created, update the message description.
+		validateFields();
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on Dialog.
+	 */
+	protected Control createDialogArea(Composite parent) {
+		Composite dialogComp = (Composite)super.createDialogArea(parent);
+				
+		// Set title and message now that the controls exist
+		setTitle(ToolMessages.getString("EditDialog.dialogTitle")); //$NON-NLS-1$
+		if (editMode)
+			setMessage(ToolMessages.getString("EditDialog.editDialogMessage")); //$NON-NLS-1$
+		else
+			setMessage(ToolMessages.getString("EditDialog.newDialogMessage")); //$NON-NLS-1$
+		setTitleImage(ExternalToolsPlugin.getDefault().getImageDescriptor(ExternalToolsPlugin.IMG_WIZBAN_EXTERNAL_TOOLS).createImage());
+		
+		// Build the top container
+		Composite topComp = new Composite(dialogComp, SWT.NONE);
+		FormLayout layout = new FormLayout();
+		topComp.setLayout(layout);
+		layout.marginHeight = MARGIN_SPACE;
+		layout.marginWidth = MARGIN_SPACE;
+		
+		// Need to keep track of the FormData's for the buttons to set
+		// the width of all the buttons to be the same as the largest
+		// button width
+		FormData[] buttonData = new FormData[5];
+		
+		// Create name label
+		Label nameLabel = new Label(topComp, SWT.NONE);
+		nameLabel.setText(ToolMessages.getString("EditDialog.nameLabel")); //$NON-NLS-1$
+		FormData data = new FormData();
+		data.top = new FormAttachment(0, MARGIN_SPACE);
+		nameLabel.setLayoutData(data);
+
+		// Create name text field
+		nameField = new Text(topComp, SWT.BORDER);
+		data = new FormData();
+		data.left = new FormAttachment(nameLabel, MARGIN_SPACE, SWT.RIGHT);
+		data.top = new FormAttachment(nameLabel, 0, SWT.CENTER);
+		data.width = FIELD_WIDTH - MARGIN_SPACE - nameLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT, false).x;
+		nameField.setLayoutData(data);
+
+		// Create location browse workspace button
+		locationBrowseWorkspace = new Button(topComp, SWT.PUSH);
+		locationBrowseWorkspace.setText(ToolMessages.getString("EditDialog.browseWkspButton1")); //$NON-NLS-1$
+		buttonData[0] = new FormData();
+		buttonData[0].left = new FormAttachment(nameField, MARGIN_SPACE, SWT.RIGHT);
+		buttonData[0].top = new FormAttachment(nameField, GROUP_SPACE, SWT.BOTTOM);
+		locationBrowseWorkspace.setLayoutData(buttonData[0]);
+		checkForMaxWidth(locationBrowseWorkspace);
+		
+		// Calculate the difference in height between a label and a button.
+		// This variable will be used to ensure equal spacing between groups.
+		buttonLabelHeightDiff = locationBrowseWorkspace.computeSize(SWT.DEFAULT, SWT.DEFAULT, false).y - nameLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT, false).y;
+
+		// Create label for location text field.
+		Label locationLabel = new Label(topComp, SWT.NONE);
+		locationLabel.setText(ToolMessages.getString("EditDialog.locationLabel")); //$NON-NLS-1$
+		data = new FormData();
+		data.bottom = new FormAttachment(locationBrowseWorkspace, 0, SWT.BOTTOM);
+		locationLabel.setLayoutData(data);
+
+		// Create location text field.
+		locationField = new Text(topComp, SWT.BORDER);
+		data = new FormData();
+		data.left = new FormAttachment(0, 0);
+		data.right = new FormAttachment(locationBrowseWorkspace, -MARGIN_SPACE, SWT.LEFT);
+		data.top = new FormAttachment(locationBrowseWorkspace, WIDGET_SPACE, SWT.BOTTOM);
+		data.width = FIELD_WIDTH;
+		locationField.setLayoutData(data);
+
+		// Create location browse file system button.
+		locationBrowseFileSystem = new Button(topComp, SWT.PUSH);
+		locationBrowseFileSystem.setText(ToolMessages.getString("EditDialog.browseFileSysButton1")); //$NON-NLS-1$
+		buttonData[1] = new FormData();
+		buttonData[1].left = new FormAttachment(locationBrowseWorkspace, 0, SWT.LEFT);
+		buttonData[1].top = new FormAttachment(locationBrowseWorkspace, WIDGET_SPACE, SWT.BOTTOM);
+		locationBrowseFileSystem.setLayoutData(buttonData[1]);
+		checkForMaxWidth(locationBrowseFileSystem);
+
+		// Create label for arguments text field.
+		Label argumentsLabel = new Label(topComp, SWT.NONE);
+		argumentsLabel.setText(ToolMessages.getString("EditDialog.argumentLabel")); //$NON-NLS-1$
+		data = new FormData();
+		data.top = new FormAttachment(locationField, GROUP_SPACE+buttonLabelHeightDiff, SWT.BOTTOM);
+		argumentsLabel.setLayoutData(data);
+
+		// Create arguments text field.
+		argumentsField = new Text(topComp, SWT.BORDER);
+		data = new FormData ();
+		data.left = new FormAttachment(0, 0);
+		data.right = new FormAttachment(locationBrowseFileSystem, -MARGIN_SPACE, SWT.LEFT);
+		data.top = new FormAttachment(argumentsLabel, WIDGET_SPACE, SWT.BOTTOM);
+		data.width = FIELD_WIDTH;
+		argumentsField.setLayoutData(data);
+
+		// Create argument browse variable button.
+		argumentsBrowseVariable = new Button(topComp, SWT.PUSH);
+		argumentsBrowseVariable.setText(ToolMessages.getString("EditDialog.browseVarsButton")); //$NON-NLS-1$
+		buttonData[2] = new FormData();
+		buttonData[2].left = new FormAttachment(locationBrowseFileSystem, 0, SWT.LEFT);
+		buttonData[2].bottom = new FormAttachment(argumentsField, 0, SWT.BOTTOM);
+		argumentsBrowseVariable.setLayoutData(buttonData[2]);
+		checkForMaxWidth(argumentsBrowseVariable);
+
+		// Create label for directory text field.
+		Label dirLabel = new Label(topComp, SWT.NONE);
+		dirLabel.setText(ToolMessages.getString("EditDialog.dirLabel")); //$NON-NLS-1$
+		data = new FormData();
+		data.top = new FormAttachment(argumentsField, GROUP_SPACE+buttonLabelHeightDiff, SWT.BOTTOM);
+		dirLabel.setLayoutData(data);
+
+		// Create directory text field.
+		directoryField = new Text(topComp, SWT.BORDER);
+		data = new FormData();
+		data.left = new FormAttachment(0, 0);
+		data.right = new FormAttachment(argumentsBrowseVariable, -MARGIN_SPACE, SWT.LEFT);
+		data.top = new FormAttachment(dirLabel, WIDGET_SPACE, SWT.BOTTOM);
+		data.width = FIELD_WIDTH;
+		directoryField.setLayoutData(data);
+
+		// Create directory browse file system button.
+		directoryBrowseButton = new Button(topComp, SWT.PUSH);
+		directoryBrowseButton.setText(ToolMessages.getString("EditDialog.directoryBrowseButton")); //$NON-NLS-1$
+		buttonData[3] = new FormData();
+		buttonData[3].left = new FormAttachment(argumentsField, MARGIN_SPACE, SWT.RIGHT);
+		buttonData[3].bottom = new FormAttachment(directoryField, 0, SWT.BOTTOM);
+		directoryBrowseButton.setLayoutData(buttonData[3]);
+		checkForMaxWidth(directoryBrowseButton);
+		
+		// Create refresh check box and label.
+		Label refreshLabel = new Label(topComp, SWT.NONE);
+		refreshLabel.setText(ToolMessages.getString("EditDialog.refreshOption")); //$NON-NLS-1$
+		data = new FormData();
+		data.left = new FormAttachment(0,0);
+		data.top = new FormAttachment(directoryField, GROUP_SPACE+buttonLabelHeightDiff, SWT.BOTTOM);
+		refreshLabel.setLayoutData(data);
+		
+		// Create refresh text field.
+		refreshField = new Text(topComp, SWT.SINGLE | SWT.H_SCROLL | SWT.BORDER);
+		refreshField.setEditable(false);
+		data = new FormData();
+		data.left = new FormAttachment(refreshLabel, MARGIN_SPACE, SWT.RIGHT);
+		data.top = new FormAttachment(refreshLabel, 0, SWT.CENTER);
+		data.width = FIELD_WIDTH - MARGIN_SPACE - refreshLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT, false).x;
+		refreshField.setLayoutData(data);
+
+		// Create refresh scope.
+		refreshOptionButton = new Button(topComp, SWT.PUSH);
+		refreshOptionButton.setText(ToolMessages.getString("EditDialog.refreshOptionButton")); //$NON-NLS-1$
+		buttonData[4] = new FormData();
+		buttonData[4].left = new FormAttachment(directoryBrowseButton, 0, SWT.LEFT);
+		buttonData[4].top = new FormAttachment(refreshField, 0, SWT.TOP);
+		refreshOptionButton.setLayoutData(buttonData[4]);
+		checkForMaxWidth(refreshOptionButton);
+		
+		// Create show log checkbox
+		showLog = new Button(topComp, SWT.CHECK);
+		showLog.setText(ToolMessages.getString("EditDialog.showLogLabel")); //$NON-NLS-1$
+		showLog.setSelection(INITIAL_SHOW_LOG);
+		data = new FormData();
+		data.left = new FormAttachment(0,0);
+		data.top = new FormAttachment(refreshField, GROUP_SPACE, SWT.BOTTOM);
+		showLog.setLayoutData(data);
+		
+		// give all the buttons the same width
+		for (int i=0; i<buttonData.length; i++) {
+			buttonData[i].width = maxButtonWidth;	
+		}	
+		
+		// Build the separator line
+		Label separator = new Label(dialogComp, SWT.HORIZONTAL | SWT.SEPARATOR);
+		separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		
+		// Init field values
+		if (editMode) {
+			nameField.setText(tool.getName());
+			locationField.setText(tool.getLocation());
+			argumentsField.setText(tool.getArguments());
+			directoryField.setText(tool.getWorkingDirectory());
+			showLog.setSelection(tool.getShowLog());
+		}
+		refreshScope = tool.getRefreshScope();
+		updateRefreshField();
+
+		// Set the proper tab order
+		Control[] tabList = new Control[] {
+			nameField, 
+			locationField, 
+			locationBrowseWorkspace,
+			locationBrowseFileSystem,
+			argumentsField,
+			argumentsBrowseVariable,
+			directoryField,
+			directoryBrowseButton,
+			refreshField,
+			refreshOptionButton};
+		topComp.setTabList(tabList);
+		
+		// Finish setup
+		hookButtonActions();
+		hookFieldValidation();
+		nameField.setFocus();
+
+		return dialogComp;
+	}
+	
+	/**
+	 * Check to see if the supplied button has the maximum width of
+	 * all the buttons so far. If it is, store the width in
+	 * the integer variable <code>maxButtonWidth</code>.
+	 */
+	private void checkForMaxWidth(Button button) {
+		Point size = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
+		if (size.x > maxButtonWidth)
+			maxButtonWidth = size.x;		
+	}
+	
+	/**
+	 * Returns the tool tool applicable to this dialog.
+	 */
+	public ExternalTool getExternalTool() {
+		return tool;
+	}
+	
+	/**
+	 * Hooks the action handler for when a button is pressed
+	 */
+	private void hookButtonActions() {
+		locationBrowseWorkspace.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				ResourceSelectionDialog dialog;
+				dialog = new ResourceSelectionDialog(
+					getShell(), 
+					ResourcesPlugin.getWorkspace().getRoot(),
+					ToolMessages.getString("EditDialog.selectTool")); //$NON-NLS-1$
+				dialog.open();
+				Object[] results = dialog.getResult();
+				if (results == null || results.length < 1)
+					return;
+				IResource resource = (IResource)results[0];
+				StringBuffer buf = new StringBuffer();
+				ToolUtil.buildVariableTag(ExternalTool.VAR_WORKSPACE_LOC, resource.getFullPath().toString(), buf);
+				locationField.setText(buf.toString());
+			}
+		});
+		
+		locationBrowseFileSystem.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				FileDialog dialog = new FileDialog(getShell(), SWT.NONE);
+				dialog.setFileName(locationField.getText());
+				String filename = dialog.open();
+				if (filename != null) {
+					locationField.setText(filename);
+				}
+			}
+		});
+
+		argumentsBrowseVariable.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				VariableSelectionDialog dialog;
+				dialog = new VariableSelectionDialog(getShell());
+				dialog.open();
+				Object[] results = dialog.getResult();
+				if (results == null || results.length < 1)
+					return;
+				String args = argumentsField.getText();
+				args = args + (String)results[0];
+				argumentsField.setText(args);
+			}
+		});
+		
+		directoryBrowseButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				DirectorySelectionDialog dialog = new DirectorySelectionDialog(getShell());
+				dialog.open();
+				Object[] results = dialog.getResult();
+				String selectedDirectory = null;
+				if (results != null && results.length > 0)
+					selectedDirectory = (String)results[0];
+				if (selectedDirectory != null) {
+					directoryField.setText(selectedDirectory);
+				}
+			}
+		});
+
+		refreshOptionButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				RefreshSelectionDialog dialog;
+				dialog = new RefreshSelectionDialog(getShell());
+				dialog.open();
+				Object[] results = dialog.getResult();
+				if (results == null || results.length < 1)
+					return;
+				refreshScope = (String)results[0];
+				updateRefreshField();
+			}
+		});
+	}
+	
+	/**
+	 * Hooks the necessary field validation
+	 */
+	private void hookFieldValidation() {
+		nameField.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				validateFields();
+			}
+		});
+		
+		locationField.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				validateFields();
+			}
+		});
+		
+		directoryField.addModifyListener(new ModifyListener() {
+			public void modifyText(ModifyEvent e) {
+				validateFields();
+			}
+		});
+	}
+
+	/**
+	 * Validate the fields for acceptable values
+	 */
+	private void validateFields() {
+		String value = nameField.getText().trim();
+		if (value.length() < 1) {
+			setMessage(ToolMessages.getString("EditDialog.noToolName"), IMessageProvider.NONE); //$NON-NLS-1$
+			getButton(IDialogConstants.OK_ID).setEnabled(false);
+			return;
+		}
+		
+		value = locationField.getText().trim();
+		if (value.length() < 1) {
+			setMessage(ToolMessages.getString("EditDialog.noToolLocation"), IMessageProvider.NONE); //$NON-NLS-1$
+			getButton(IDialogConstants.OK_ID).setEnabled(false);
+			return;
+		}
+
+		getButton(IDialogConstants.OK_ID).setEnabled(true);
+		
+		// Translate field contents to the actual file location so we
+		// can check to ensure the file actually exists.
+		value = ToolUtil.getLocationFromText(value);
+		
+		if (value == null) { // The resource could not be found.
+			setMessage(ToolMessages.getString("EditDialog.missingToolLocation"), IMessageProvider.WARNING); //$NON-NLS-1$
+			return;			
+		}
+		File file = new File(value);
+		if (!file.exists()) { // The file does not exist.
+			setMessage(ToolMessages.getString("EditDialog.missingToolLocation"), IMessageProvider.WARNING); //$NON-NLS-1$
+			return;
+		}
+		String fileName = value;
+		
+		value = directoryField.getText().trim();
+		if (value.length() > 0) {
+			// Translate field contents to the actual directory location so we
+			// can check to ensure the directory actually exists.
+			value = ToolUtil.getLocationFromText(value);
+			
+			if (value == null) { // The resource could not be found.
+				setMessage(ToolMessages.getString("EditDialog.missingToolDirectory"), IMessageProvider.WARNING); //$NON-NLS-1$
+				return;			
+			}			
+			file = new File(value);
+			if (!file.exists()) { // The directory does not exist.
+				setMessage(ToolMessages.getString("EditDialog.missingToolDirectory"), IMessageProvider.WARNING); //$NON-NLS-1$
+				return;
+			}
+		}
+		
+		if (fileName.endsWith(".xml")) { //$NON-NLS-1$
+			setMessage(ToolMessages.getString("EditDialog.howToSelectAntTargets"), IMessageProvider.INFORMATION); //$NON-NLS-1$
+			return;
+		}
+		
+		if (editMode)
+			setMessage(ToolMessages.getString("EditDialog.editDialogMessage")); //$NON-NLS-1$
+		else
+			setMessage(ToolMessages.getString("EditDialog.newDialogMessage")); //$NON-NLS-1$
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on Dialog.
+	 */
+	protected void okPressed() {
+		String command = locationField.getText().trim();
+		String value = ToolUtil.getLocationFromText(command);
+		if (value != null && value.endsWith(".xml")) //$NON-NLS-1$
+			tool.setType(ExternalTool.TOOL_TYPE_ANT);
+		else
+			tool.setType(ExternalTool.TOOL_TYPE_PROGRAM);
+		tool.setName(nameField.getText().trim());
+		tool.setLocation(command);
+		tool.setArguments(argumentsField.getText().trim());
+		tool.setWorkingDirectory(directoryField.getText().trim());
+		tool.setRefreshScope(refreshScope);
+		tool.setShowLog(showLog.getSelection());
+		
+		super.okPressed();
+	}
+	
+	/**
+	 * Update the refresh scope field
+	 */
+	private void updateRefreshField() {
+		ToolUtil.VariableDefinition result = ToolUtil.extractVariableTag(refreshScope, 0);
+		if (result.name == null) {
+			refreshScope = ToolUtil.buildVariableTag(ExternalTool.REFRESH_SCOPE_NONE, null);
+			result.name = ExternalTool.REFRESH_SCOPE_NONE;
+		}
+		
+		if (ExternalTool.REFRESH_SCOPE_NONE.equals(result.name)) {
+			refreshField.setText(ToolMessages.getString("EditDialog.refreshScopeNone")); //$NON-NLS-1$
+			return;
+		}
+		if (ExternalTool.REFRESH_SCOPE_WORKSPACE.equals(result.name)) {
+			refreshField.setText(ToolMessages.getString("EditDialog.refreshScopeWorkspace")); //$NON-NLS-1$
+			return;
+		}
+		if (ExternalTool.REFRESH_SCOPE_PROJECT.equals(result.name)) {
+			if (result.argument == null)
+				refreshField.setText(ToolMessages.getString("EditDialog.refreshScopeProject")); //$NON-NLS-1$
+			else
+				refreshField.setText(ToolMessages.format("EditDialog.refreshScopeProjectX", new Object[] {result.argument})); //$NON-NLS-1$
+			return;
+		}
+		if (ExternalTool.REFRESH_SCOPE_WORKING_SET.equals(result.name)) {
+			if (result.argument == null) {
+				refreshScope = ToolUtil.buildVariableTag(ExternalTool.REFRESH_SCOPE_NONE, null);
+				refreshField.setText(ToolMessages.getString("EditDialog.refreshScopeNone")); //$NON-NLS-1$
+			}
+			else
+				refreshField.setText(ToolMessages.format("EditDialog.refreshScopeWorkingSet", new Object[] {result.argument})); //$NON-NLS-1$
+			return;
+		}
+	}
+	
+	/**
+	 * Internal dialog to show available resources from which
+	 * the user can select one
+	 */
+	private class ResourceSelectionDialog extends SelectionDialog {
+		String labelText;
+		IContainer root;
+		TreeViewer wsTree;
+		
+		public ResourceSelectionDialog(Shell parent, IContainer root, String labelText) {
+			super(parent);
+			this.root = root;
+			this.labelText = labelText;
+			setShellStyle(getShellStyle() | SWT.RESIZE);
+			setTitle(ToolMessages.getString("EditDialog.browseWorkspaceTitle")); //$NON-NLS-1$
+			WorkbenchHelp.setHelp(parent, IHelpContextIds.RESOURCE_SELECTION_DIALOG);
+		}
+
+		/* (non-Javadoc)
+		 * Method declared on Dialog.
+		 */
+		protected Control createDialogArea(Composite parent) {
+			// create composite 
+			Composite dialogArea = (Composite)super.createDialogArea(parent);
+			
+			Label label = new Label(dialogArea, SWT.LEFT);
+			label.setText(labelText);
+			
+			Tree tree = new Tree(dialogArea, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.BORDER);
+			GridData data = new GridData(GridData.FILL_BOTH);
+			data.heightHint = SIZING_SELECTION_PANE_HEIGHT;
+			data.widthHint = SIZING_SELECTION_PANE_WIDTH;
+			tree.setLayoutData(data);
+			wsTree = new TreeViewer(tree);
+			wsTree.setContentProvider(new WorkbenchContentProvider());
+			wsTree.setLabelProvider(new WorkbenchLabelProvider());
+			wsTree.setInput(root);
+			
+			return dialogArea;
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on Dialog.
+		 */
+		protected void okPressed() {
+			IStructuredSelection sel = (IStructuredSelection)wsTree.getSelection();
+			if (sel != null)
+				setSelectionResult(sel.toArray());
+			super.okPressed();
+		}
+	}
+
+
+	/**
+	 * Internal dialog to show available variables from which
+	 * the user can select one.
+	 */
+	private class VariableSelectionDialog extends SelectionDialog {
+		String location;
+		List list;
+		
+		public VariableSelectionDialog(Shell parent) {
+			super(parent);
+			setTitle(ToolMessages.getString("EditDialog.browseVarTitle")); //$NON-NLS-1$
+			WorkbenchHelp.setHelp(parent, IHelpContextIds.VARIABLE_SELECTION_DIALOG);
+		}
+
+		/* (non-Javadoc)
+		 * Method declared on Dialog.
+		 */
+		protected Control createDialogArea(Composite parent) {
+			// create composite 
+			Composite dialogArea = (Composite)super.createDialogArea(parent);
+			
+			Label label = new Label(dialogArea, SWT.LEFT);
+			label.setText(ToolMessages.getString("EditDialog.selectVar")); //$NON-NLS-1$
+			
+			list = new List(dialogArea, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.BORDER);
+			GridData data = new GridData(GridData.FILL_BOTH);
+			data.heightHint = SIZING_SELECTION_PANE_HEIGHT;
+			data.widthHint = SIZING_SELECTION_PANE_WIDTH;
+			list.setLayoutData(data);
+
+			list.add(ToolMessages.getString("EditDialog.varWorkspaceLocLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varProjectLocLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varContainerLocLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varResourceLocLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varProjectPathLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varContainerPathLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varResourcePathLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varProjectNameLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varContainerNameLabel")); //$NON-NLS-1$	
+			list.add(ToolMessages.getString("EditDialog.varResourceNameLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varProjectXLocLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varContainerXLocLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varResourceXLocLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varProjectXPathLabel")); //$NON-NLS-1$	
+			list.add(ToolMessages.getString("EditDialog.varContainerXPathLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varResourceXPathLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varProjectXNameLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varContainerXNameLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varResourceXNameLabel")); //$NON-NLS-1$	
+			list.add(ToolMessages.getString("EditDialog.varBuildTypeNameLabel")); //$NON-NLS-1$	
+
+			location = ToolUtil.getLocationFromText(locationField.getText().trim());
+			if (location != null && location.endsWith(".xml")) { //$NON-NLS-1$
+				list.add(ToolMessages.getString("EditDialog.varAntTargetLabel")); //$NON-NLS-1$
+			}		
+			
+			return dialogArea;
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on Dialog.
+		 */
+		protected void okPressed() {
+			int sel = list.getSelectionIndex();
+			String result = null;
+			
+			switch (sel) {
+				case 0 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_WORKSPACE_LOC, null);
+					break;
+
+				case 1 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_PROJECT_LOC, null);
+					break;
+
+				case 2 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_CONTAINER_LOC, null);
+					break;
+
+				case 3 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_RESOURCE_LOC, null);
+					break;
+
+				case 4 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_PROJECT_PATH, null);
+					break;
+
+				case 5 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_CONTAINER_PATH, null);
+					break;
+
+				case 6 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_RESOURCE_PATH, null);
+					break;
+
+				case 7 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_PROJECT_NAME, null);
+					break;
+
+				case 8 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_CONTAINER_NAME, null);
+					break;
+
+				case 9 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_RESOURCE_NAME, null);
+					break;
+
+				case 10 :
+					result = showResourceDialog(ExternalTool.VAR_PROJECT_LOC);
+					break;
+
+				case 11 :
+					result = showResourceDialog(ExternalTool.VAR_CONTAINER_LOC);
+					break;
+
+				case 12 :
+					result = showResourceDialog(ExternalTool.VAR_RESOURCE_LOC);
+					break;
+
+				case 13 :
+					result = showResourceDialog(ExternalTool.VAR_PROJECT_PATH);
+					break;
+
+				case 14 :
+					result = showResourceDialog(ExternalTool.VAR_CONTAINER_PATH);
+					break;
+
+				case 15 :
+					result = showResourceDialog(ExternalTool.VAR_RESOURCE_PATH);
+					break;
+
+				case 16 :
+					result = showResourceDialog(ExternalTool.VAR_PROJECT_NAME);
+					break;
+
+				case 17 :
+					result = showResourceDialog(ExternalTool.VAR_CONTAINER_NAME);
+					break;
+
+				case 18 :
+					result = showResourceDialog(ExternalTool.VAR_RESOURCE_NAME);
+					break;
+					
+				case 19 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_BUILD_TYPE, null);
+					break;
+					
+				case 20 :
+					AntTargetList targetList = null;
+					try {
+						targetList = AntUtil.getTargetList(new Path(location));
+					} catch (CoreException e) {
+						ErrorDialog.openError(
+							getShell(),
+							ToolMessages.getString("EditDialog.errorTitle"), //$NON-NLS-1$
+							ToolMessages.format("EditDialog.errorReadAntFile", new Object[] {location}), //$NON-NLS-1$;
+							e.getStatus());
+						break;
+					}
+					
+					if (targetList == null) {
+						MessageDialog.openError(
+							getShell(),
+							ToolMessages.getString("EditDialog.errorTitle"), //$NON-NLS-1$;
+							ToolMessages.format("EditDialog.noAntTargets", new Object[] {location})); //$NON-NLS-1$;
+						break;
+					}
+
+					TargetSelectionDialog targetDialog;
+					targetDialog = new TargetSelectionDialog(getShell(), targetList);
+					targetDialog.open();
+					Object[] targets = targetDialog.getResult();
+					if (targets != null && targets.length > 0) {
+						StringBuffer buf = new StringBuffer();
+						ToolUtil.buildVariableTags(ExternalTool.VAR_ANT_TARGET, (String[])targets, buf);
+						result = buf.toString().trim();
+					}
+					break;
+			}
+			
+			if (result != null)
+				setSelectionResult(new Object[] {result});
+			super.okPressed();
+		}
+		
+		private String showResourceDialog(String varName) {
+			ResourceSelectionDialog resDialog;
+			resDialog = new ResourceSelectionDialog(
+				getShell(), 
+				ResourcesPlugin.getWorkspace().getRoot(),
+				ToolMessages.getString("EditDialog.selectResource")); //$NON-NLS-1$
+			resDialog.open();
+			Object[] resource = resDialog.getResult();
+			if (resource != null && resource.length > 0)
+				return ToolUtil.buildVariableTag(varName, ((IResource)resource[0]).getFullPath().toString());
+			else
+				return null;
+		}
+	}
+	
+		/**
+	 * Internal dialog to show available variables from which
+	 * the user can select one.
+	 */
+	private class DirectorySelectionDialog extends SelectionDialog {
+		String location;
+		List list;
+		
+		public DirectorySelectionDialog(Shell parent) {
+			super(parent);
+			setTitle(ToolMessages.getString("EditDialog.browseDirTitle")); //$NON-NLS-1$
+			WorkbenchHelp.setHelp(parent, IHelpContextIds.VARIABLE_SELECTION_DIALOG);
+		}
+
+		/* (non-Javadoc)
+		 * Method declared on Dialog.
+		 */
+		protected Control createDialogArea(Composite parent) {
+			// create composite 
+			Composite dialogArea = (Composite)super.createDialogArea(parent);
+			
+			Label label = new Label(dialogArea, SWT.LEFT);
+			label.setText(ToolMessages.getString("EditDialog.selectDir")); //$NON-NLS-1$
+			
+			list = new List(dialogArea, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.BORDER);
+			GridData data = new GridData(GridData.FILL_BOTH);
+			data.heightHint = SIZING_SELECTION_PANE_HEIGHT;
+			data.widthHint = SIZING_SELECTION_PANE_WIDTH;
+			list.setLayoutData(data);
+
+			list.add(ToolMessages.getString("EditDialog.varWorkspaceLocLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varProjectLocLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varContainerLocLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.varResourceLocLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.dirBrowseWorkspace")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.dirBrowseFileSystem")); //NON-NLS-1$)
+			
+			return dialogArea;
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on Dialog.
+		 */
+		protected void okPressed() {
+			int sel = list.getSelectionIndex();
+			String result = null;
+			
+			switch (sel) {
+				case 0 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_WORKSPACE_LOC, null);
+					break;
+
+				case 1 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_PROJECT_LOC, null);
+					break;
+
+				case 2 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_CONTAINER_LOC, null);
+					break;
+
+				case 3 :
+					result = ToolUtil.buildVariableTag(ExternalTool.VAR_RESOURCE_LOC, null);
+					break;
+
+				case 4 :
+					result = showContainerDialog();
+					break;
+
+				case 5 :
+					result = showDirectoryDialog();
+					break;
+				
+			}
+			
+			if (result != null)
+				setSelectionResult(new Object[] {result});
+			super.okPressed();
+		}
+		
+		private String showContainerDialog() {
+			String varName = ExternalTool.VAR_WORKSPACE_LOC;
+			ContainerSelectionDialog containerDialog;
+			containerDialog = new ContainerSelectionDialog(
+				getShell(), 
+				ResourcesPlugin.getWorkspace().getRoot(),
+				false,
+				ToolMessages.getString("EditDialog.selectContainer")); //$NON-NLS-1$
+			containerDialog.open();
+			Object[] resource = containerDialog.getResult();
+			if (resource != null && resource.length > 0)
+				return ToolUtil.buildVariableTag(varName, ((IPath)resource[0]).toString());
+			else
+				return null;
+		}
+		
+		private String showDirectoryDialog() {
+				DirectoryDialog dialog = new DirectoryDialog(getShell(), SWT.SAVE);
+				dialog.setMessage(ToolMessages.getString("EditDialog.selectDirectory")); //$NON-NLS-1$
+				dialog.setFilterPath(directoryField.getText());
+				return dialog.open();	
+		}
+	}
+	
+	/**
+	 * Internal dialog to show available refresh scope from which
+	 * the user can select one.
+	 */
+	private class RefreshSelectionDialog extends SelectionDialog {
+		List list;
+		
+		public RefreshSelectionDialog(Shell parent) {
+			super(parent);
+			setTitle(ToolMessages.getString("EditDialog.browseRefreshTitle")); //$NON-NLS-1$
+			WorkbenchHelp.setHelp(parent, IHelpContextIds.REFRESH_SELECTION_DIALOG);
+
+		}
+
+		/* (non-Javadoc)
+		 * Method declared on Dialog.
+		 */
+		protected Control createDialogArea(Composite parent) {
+			// create composite 
+			Composite dialogArea = (Composite)super.createDialogArea(parent);
+			
+			Label label = new Label(dialogArea, SWT.LEFT);
+			label.setText(ToolMessages.getString("EditDialog.selectRefresh")); //$NON-NLS-1$
+			
+			list = new List(dialogArea, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.BORDER);
+			GridData data = new GridData(GridData.FILL_BOTH);
+			data.heightHint = SIZING_SELECTION_PANE_HEIGHT;
+			data.widthHint = SIZING_SELECTION_PANE_WIDTH;
+			list.setLayoutData(data);
+			
+			list.add(ToolMessages.getString("EditDialog.refreshNothingLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.refreshWorkspaceLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.refreshProjectLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.refreshProjectXLabel")); //$NON-NLS-1$
+			list.add(ToolMessages.getString("EditDialog.refreshWorkingSetLabel")); //$NON-NLS-1$
+
+			return dialogArea;
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on Dialog.
+		 */
+		protected void okPressed() {
+			int sel = list.getSelectionIndex();
+			String result = null;
+			
+			switch (sel) {
+				case 0 :
+					result = ToolUtil.buildVariableTag(ExternalTool.REFRESH_SCOPE_NONE, null);
+					break;
+					
+				case 1 :
+					result = ToolUtil.buildVariableTag(ExternalTool.REFRESH_SCOPE_WORKSPACE, null);
+					break;
+
+				case 2 :
+					result = ToolUtil.buildVariableTag(ExternalTool.REFRESH_SCOPE_PROJECT, null);
+					break;
+
+				case 3 :
+					ProjectSelectionDialog prjDialog;
+					prjDialog = new ProjectSelectionDialog(getShell());
+					prjDialog.open();
+					Object[] name = prjDialog.getResult();
+					if (name != null && name.length > 0)
+						result = ToolUtil.buildVariableTag(ExternalTool.REFRESH_SCOPE_PROJECT, (String)name[0]);
+					break;
+
+				case 4 :
+					IWorkingSetSelectionDialog setDialog;
+					setDialog = PlatformUI.getWorkbench().getWorkingSetManager().createWorkingSetSelectionDialog(getShell(), false);
+					setDialog.open();
+					IWorkingSet[] sets = setDialog.getSelection();
+					if (sets != null && sets.length > 0)
+						result = ToolUtil.buildVariableTag(ExternalTool.REFRESH_SCOPE_WORKING_SET, sets[0].getName());
+					break;
+			}
+			
+			if (result != null)
+				setSelectionResult(new Object[] {result});
+			super.okPressed();
+		}
+	}
+	
+	/**
+	 * Internal dialog to show available projects from which
+	 * the user can select one.
+	 */
+	private class ProjectSelectionDialog extends SelectionDialog {
+		List list;
+		
+		public ProjectSelectionDialog(Shell parent) {
+			super(parent);
+			setTitle(ToolMessages.getString("EditDialog.browseProjectTitle")); //$NON-NLS-1$
+			WorkbenchHelp.setHelp(parent, IHelpContextIds.PROJECT_SELECTION_DIALOG);
+		}
+
+		/* (non-Javadoc)
+		 * Method declared on Dialog.
+		 */
+		protected Control createDialogArea(Composite parent) {
+			// create composite 
+			Composite dialogArea = (Composite)super.createDialogArea(parent);
+			
+			Label label = new Label(dialogArea, SWT.LEFT);
+			label.setText(ToolMessages.getString("EditDialog.selectProject")); //$NON-NLS-1$
+			
+			list = new List(dialogArea, SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.BORDER);
+			GridData data = new GridData(GridData.FILL_BOTH);
+			data.heightHint = SIZING_SELECTION_PANE_HEIGHT;
+			data.widthHint = SIZING_SELECTION_PANE_WIDTH;
+			list.setLayoutData(data);
+			
+			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+			IProject[] projects = root.getProjects();
+			for (int i = 0; i < projects.length; i++) {
+				list.add(projects[i].getName());
+			}
+			
+			return dialogArea;
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on Dialog.
+		 */
+		protected void okPressed() {
+			setSelectionResult(list.getSelection());
+			super.okPressed();
+		}
+	}
+	
+	private class TargetSelectionDialog extends SelectionDialog implements ICheckStateListener {
+		private ArrayList selectedTargets = new ArrayList();
+		private CheckboxTableViewer listViewer;
+		private AntTargetList targetList;
+		private AntTargetLabelProvider labelProvider = new AntTargetLabelProvider();	
+		
+		public TargetSelectionDialog(Shell parent, AntTargetList targetList) {
+			super(parent);
+			this.targetList = targetList;
+			setTitle(ToolMessages.getString("EditDialog.varAntTargetLabel")); //$NON-NLS-1$
+			WorkbenchHelp.setHelp(parent, IHelpContextIds.TARGET_SELECTION_DIALOG);
+		}
+		
+		public void checkStateChanged(CheckStateChangedEvent e) {
+			String checkedTarget = (String)e.getElement();
+			if (e.getChecked())
+				selectedTargets.add(checkedTarget);
+			else
+				selectedTargets.remove(checkedTarget);
+				
+			labelProvider.setSelectedTargets(selectedTargets);
+			listViewer.refresh();
+		}
+		
+		protected Control createDialogArea(Composite parent) {
+			Composite dialogArea = (Composite)super.createDialogArea(parent);
+			
+			Label label = new Label(dialogArea, SWT.LEFT);
+			label.setText(ToolMessages.getString("EditDialog.selectTargets")); //$NON-NLS-1$
+			
+			listViewer = CheckboxTableViewer.newCheckList(dialogArea, SWT.BORDER);
+			GridData data = new GridData(GridData.FILL_BOTH);
+			data.heightHint = SIZING_SELECTION_PANE_HEIGHT;
+			data.widthHint = SIZING_SELECTION_PANE_WIDTH;
+			listViewer.getTable().setLayoutData(data);
+			listViewer.setSorter(new ViewerSorter() {
+				public int compare(Viewer viewer,Object o1,Object o2) {
+					return ((String)o1).compareTo((String)o2);
+				}
+			});
+			
+			if (targetList != null && targetList.getDefaultTarget() != null)
+				labelProvider.setDefaultTargetName(targetList.getDefaultTarget());
+			listViewer.setLabelProvider(labelProvider);
+			listViewer.setContentProvider(new AntTargetContentProvider());
+			listViewer.setInput(targetList);
+			
+			listViewer.addCheckStateListener(this);
+			listViewer.refresh();
+			
+			return dialogArea;
+		}
+		
+		/* (non-Javadoc)
+		 * Method declared on Dialog.
+		 */
+		protected void okPressed() {
+			setSelectionResult(getTargetNames());
+			super.okPressed();
+		}
+		
+		protected String[] getTargetNames() {
+			String[] result = new String[selectedTargets.size()];
+			selectedTargets.toArray(result);
+			return result;
+		}
+	}
+	
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/ExternalToolsAction.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/ExternalToolsAction.java
new file mode 100644
index 0000000..2b96f89
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/ExternalToolsAction.java
@@ -0,0 +1,233 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuCreator;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.actions.ActionDelegate;
+import org.eclipse.ui.externaltools.internal.core.*;
+
+/**
+ * This action will display the external tool configuration dialog.
+ * In addition, as a tool bar item, it's drop down list will include
+ * tools to run directly.
+ */
+public class ExternalToolsAction extends ActionDelegate implements IWorkbenchWindowPulldownDelegate2, IMenuCreator {
+	private IWorkbenchWindow window;
+	private IAction realAction;
+	
+	/**
+	 * Creates the external tool configure action
+	 */
+	public ExternalToolsAction() {
+		super();
+	}
+	
+	/* (non-Javadoc)
+	 * Method declared on IActionDelegate.
+	 */
+	public void run(IAction action) {
+		if (action.isEnabled())
+			showConfigurationDialog();
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on IActionDelegate.
+	 */
+	public void selectionChanged(IAction action, ISelection selection) {
+		if (realAction == null) {
+			realAction = action;
+			realAction.setMenuCreator(this);
+		}
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on IWorkbenchWindowPulldownDelegate.
+	 */
+	public Menu getMenu(Control parent) {
+		Menu menu= new Menu(parent);
+		return createMenu(menu, false);
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on IWorkbenchWindowPulldownDelegate2.
+	 */
+	public Menu getMenu(Menu parent) {
+		Menu menu= new Menu(parent);
+		return createMenu(menu, true);
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on IWorkbenchWindowActionDelegate.
+	 */
+	public void dispose() {
+	}
+
+	/* (non-Javadoc)
+	 * Method declared on IWorkbenchWindowActionDelegate.
+	 */
+	public void init(IWorkbenchWindow window) {
+		this.window = window;
+	}
+	
+	/**
+	 * Creates the menu for the action
+	 */
+	private Menu createMenu(Menu menu, final boolean wantFastAccess) {
+		// Add listener to repopulate the menu each time
+		// it is shown because of dynamic history list
+		menu.addMenuListener(new MenuAdapter() {
+			public void menuShown(MenuEvent e) {
+				Menu m = (Menu)e.widget;
+				MenuItem[] items = m.getItems();
+				for (int i=0; i < items.length; i++)
+					items[i].dispose();
+				populateMenu(m, wantFastAccess);
+			}
+		});
+		
+		return menu;
+	}
+
+	/**
+	 * Populates the menu with its items
+	 */
+	private void populateMenu(Menu menu, boolean wantFastAccess) {
+		// Add a menu item for each tool in the history
+		ArrayList tools = ExternalToolsPlugin.getDefault().getRegistry().getExternalTools();
+		if (tools.size() > 0) {
+			for (int i = 0; i < tools.size(); i++) {
+				ExternalTool tool = (ExternalTool)tools.get(i);
+				StringBuffer label = new StringBuffer();
+				if (i < 9 && wantFastAccess) {
+					//add the numerical accelerator
+					label.append('&');
+					label.append(i+1);
+					label.append(' ');
+				}
+				label.append(tool.getName());
+				MenuItem item = new MenuItem(menu, SWT.NONE);
+				item.setText(label.toString());
+				item.setData(tool);
+				item.addSelectionListener(new SelectionAdapter() {
+					public void widgetSelected(SelectionEvent e) {
+						runTool((ExternalTool)e.widget.getData());
+					}
+				});
+			}
+			
+			// Add a separator
+			new MenuItem(menu, SWT.SEPARATOR);
+		}
+
+		// Add a menu to edit the configurations
+		MenuItem item = new MenuItem(menu, SWT.NONE);
+		item.setText(ToolMessages.getString("ExternalToolsAction.configure")); //$NON-NLS-1$
+		item.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				showConfigurationDialog();
+			}
+		});
+	}
+
+	/**
+	 * Runs the specified tool
+	 */
+	private void runTool(final ExternalTool tool) {
+		if (tool == null)
+			return;
+			
+		ToolUtil.saveDirtyEditors(window);
+			
+		// Selection is assigned BEFORE Log Console is given focus.
+		// Otherwise incorrect selection is used. Selection is assigned outside
+		// runnable.run(IProgressMonitor) to avoid invalid thread access.
+		final ISelection sel = window.getSelectionService().getSelection();
+		final IWorkbenchPart activePart = window.getPartService().getActivePart();
+									
+		if (tool.getShowLog()) {
+			ToolUtil.showLogConsole(window);
+			ToolUtil.clearLogDocument();
+		}
+		
+		IRunnableWithProgress runnable = new IRunnableWithProgress() {
+			public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+				IResource resource = null;
+
+				// Get the focused resource.
+				if (sel instanceof IStructuredSelection) {
+					Object result = ((IStructuredSelection)sel).getFirstElement();
+					if (result instanceof IResource) {
+						resource = (IResource) result;
+					} else if (result instanceof IAdaptable) {
+						resource = (IResource)((IAdaptable) result).getAdapter(IResource.class);
+					}
+				}
+				
+				if (resource == null) {
+					// If the active part is an editor, get the file resource used as input.
+					if (activePart instanceof IEditorPart) {
+						IEditorPart editorPart = (IEditorPart) activePart;
+						IEditorInput input = editorPart.getEditorInput();
+						resource = (IResource) input.getAdapter(IResource.class);
+					} 
+				}
+
+				DefaultRunnerContext context;
+				if (resource != null)
+					context = new DefaultRunnerContext(tool, resource.getProject(), resource, window.getWorkbench().getWorkingSetManager());
+				else
+					context = new DefaultRunnerContext(tool, null, window.getWorkbench().getWorkingSetManager());
+				context.run(monitor, window.getShell());
+			};
+		};
+		
+		try {
+			new ProgressMonitorDialog(window.getShell()).run(true, true, runnable);		
+		} catch (InterruptedException e) {
+			return;
+		} catch (InvocationTargetException e) {
+			IStatus status = null;
+			if (e.getTargetException() instanceof CoreException)
+				status = ((CoreException)e.getTargetException()).getStatus();
+			else
+				status = new Status(IStatus.ERROR, ExternalToolsPlugin.PLUGIN_ID, 0, ToolMessages.getString("ExternalToolsAction.internalError"), e.getTargetException()); //$NON-NLS-1$;
+			ErrorDialog.openError(
+				window.getShell(), 
+				ToolMessages.getString("ExternalToolsAction.runErrorTitle"), //$NON-NLS-1$;
+				ToolMessages.getString("ExternalToolsAction.runProblem"), //$NON-NLS-1$;
+				status);
+			return;
+		}
+	}
+	
+	/**
+	 * Shows the tool configuration dialog
+	 */
+	private void showConfigurationDialog() {
+		ConfigurationDialog dialog;
+		dialog = new ConfigurationDialog(window.getShell());
+		dialog.open();
+	}
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/IHelpContextIds.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/IHelpContextIds.java
new file mode 100644
index 0000000..1418ed1
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/IHelpContextIds.java
@@ -0,0 +1,49 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+
+/**
+ * Help context ids for the external tools.
+ * <p>
+ * This interface contains constants only; it is not intended to be implemented
+ * or extended.
+ * </p>
+ */
+public interface IHelpContextIds {
+	public static final String PREFIX = "org.eclipse.ui.externaltools."; //$NON-NLS-1$
+
+	// Actions
+	public static final String ANT_ACTION = PREFIX + "ant_action_context"; //$NON-NLS-1$
+	
+	// Dialogs
+	public static final String CONFIGURE_DIALOG = PREFIX + "configure_dialog_context"; //$NON-NLS-1$
+	public static final String EDIT_DIALOG = PREFIX + "edit_dialog_context"; //$NON-NLS-1$
+	public static final String ADD_TASK_DIALOG = PREFIX + "add_task_dialog_context"; //$NON-NLS-1$
+	public static final String PROJECT_SELECTION_DIALOG = PREFIX + "project_selection_dialog_context"; //$NON-NLS-1$
+	public static final String REFRESH_SELECTION_DIALOG = PREFIX + "refresh_selection_dialog_context"; //$NON-NLS-1$
+	public static final String TARGET_SELECTION_DIALOG = PREFIX + "target_selection_dialog_context"; //$NON-NLS-1$
+	public static final String VARIABLE_SELECTION_DIALOG = PREFIX + "variable_selection_dialog_context"; //$NON-NLS-1$
+	public static final String RESOURCE_SELECTION_DIALOG = PREFIX + "resource_selection_dialog_context"; //$NON-NLS-1$
+
+	// Preference Pages
+	public static final String ANT_PREFERENCE_PAGE = PREFIX + "ant_preference_page_context"; //$NON-NLS-1$
+	public static final String LOG_CONSOLE_PREFERENCE_PAGE = PREFIX + "log_console_preference_page_context"; //$NON-NLS-1$
+	
+	// Views
+	public static final String LOG_CONSOLE_VIEW = PREFIX + "log_console_view_context"; //$NON-NLS-1$
+
+	// Wizards
+	public static final String ANT_LAUNCH_WIZARD = PREFIX + "ant_launch_wizard_context"; //$NON-NLS-1$
+	
+	// Wizard Pages
+	public static final String ANT_LAUNCH_WIZARD_PAGE = PREFIX + "ant_launch_wizard_page_context"; //$NON-NLS-1$
+	
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/IUIConstants.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/IUIConstants.java
new file mode 100644
index 0000000..d649201
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/IUIConstants.java
@@ -0,0 +1,17 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others. All rights reserved.
+This file is made available under the terms of the Common Public License v1.0
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v10.html

+Contributors:
+**********************************************************************/
+
+import org.eclipse.ui.externaltools.internal.core.ExternalToolsPlugin;
+
+public interface IUIConstants {
+	
+	public static final String DIALOGSTORE_LASTEXTJAR= ExternalToolsPlugin.PLUGIN_ID + ".lastextjar"; //$NON-NLS-1$
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogConsoleDocument.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogConsoleDocument.java
new file mode 100644
index 0000000..f62c479
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogConsoleDocument.java
@@ -0,0 +1,329 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import java.util.*;
+
+import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.*;
+import org.eclipse.jface.util.*;
+import org.eclipse.swt.custom.StyleRange;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.externaltools.internal.core.*;
+
+/**
+ * Holds onto messages generated by the execution on an
+ * external tool.
+ */
+public class LogConsoleDocument {
+	// class variables that handle the colors and the font
+	private static Color ERROR_COLOR;
+	private static Color WARN_COLOR;
+	private static Color INFO_COLOR;
+	private static Color VERBOSE_COLOR;
+	private static Color DEBUG_COLOR;
+	/*package*/ static Font ANT_FONT;
+	
+	public static final int MSG_ERR = 0;
+	public static final int MSG_WARN = 10;
+	public static final int MSG_INFO = 20;
+	public static final int MSG_VERBOSE = 30;
+	public static final int MSG_DEBUG = 40;
+	
+	private static final LogConsoleDocument instance = new LogConsoleDocument();
+	
+	private LogPropertyChangeListener changeListener;
+
+	/*package*/ ArrayList views = new ArrayList();
+	private Document document;
+	private ArrayList styleRanges;
+	
+	// Structure to store the textwidget index information
+	private OutputStructureElement root = null;	
+	private OutputStructureElement currentElement = null;
+
+	private LogConsoleDocument() {
+		changeListener = new LogPropertyChangeListener();
+		document = new Document();
+		styleRanges = new ArrayList(5);
+		initializeOutputStructure();		
+	}
+
+	public void append(final String message, final int priority) {
+		if (views.size() == 0)
+			return;
+		((LogConsoleView)views.get(0)).getViewSite().getShell().getDisplay().asyncExec(new Runnable() {
+			public void run() {
+				int start = getDocument().getLength();
+				try {
+					// Append new message to the end of the document. This
+					// avoids console flicker when messages are appended.
+					getDocument().replace(start, 0, message);
+				} catch (BadLocationException e) {
+				}
+				setOutputLevelColor(priority, start, message.length());
+			}
+		});		
+		for (int i=0; i < views.size(); i++) {
+			((LogConsoleView)views.get(i)).append(message, priority);	
+		}
+	}
+	
+	private void addRangeStyle(int start, int length, Color color) {
+		// Don't add a StyleRange if the length is 0.
+		if (length == 0)
+			return;	
+		if (styleRanges.size() != 0) {
+			StyleRange lastStyle = (StyleRange) styleRanges.get(styleRanges.size()-1);
+			if (color.equals(lastStyle.foreground))
+				lastStyle.length += length;
+			else
+				styleRanges.add(new StyleRange(start, length, color, null));
+		} else
+			styleRanges.add(new StyleRange(start, length, color, null));
+		StyleRange[] styleArray = (StyleRange[]) styleRanges.toArray(new StyleRange[styleRanges.size()]);			
+		for (int i = 0; i < views.size(); i++) {
+			TextViewer tv = ((LogConsoleView)views.get(i)).getTextViewer();
+			if (tv != null)
+				tv.getTextWidget().setStyleRanges(styleArray);
+		}
+	}
+	
+	public void clearOutput() {
+		document.set("");
+		styleRanges.clear();
+		// the tree can be null if #createPartControl has not called yet, 
+		// i.e. if the console exists but has never been shown so far
+		initializeOutputStructure();
+		refreshTree();
+	}	
+
+	public void refreshTree() {
+		for(int i=0; i<views.size(); i++) {
+			((LogConsoleView)views.get(i)).refreshTree();
+		}
+	}	
+	
+	/**
+	 * Returns the color used for error messages on the log console.
+	 */
+	private static Color getErrorColor() {
+		if (ERROR_COLOR == null || ERROR_COLOR.isDisposed())
+			ERROR_COLOR = new Color(null, PreferenceConverter.getColor(ExternalToolsPlugin.getDefault().getPreferenceStore(),IPreferenceConstants.CONSOLE_ERROR_RGB));
+		return ERROR_COLOR;
+	}
+	/**
+	 * Returns the color used for warning messages on the log console.
+	 */
+	private static Color getWarnColor() {
+		if (WARN_COLOR == null || WARN_COLOR.isDisposed())
+			WARN_COLOR = new Color(null, PreferenceConverter.getColor(ExternalToolsPlugin.getDefault().getPreferenceStore(),IPreferenceConstants.CONSOLE_WARNING_RGB));	
+		return WARN_COLOR;
+	}
+	/**
+	 * Returns the color used for info (normal) messages on the log console.
+	 */
+	private static Color getInfoColor() {
+		if (INFO_COLOR == null || INFO_COLOR.isDisposed())
+			INFO_COLOR = new Color(null, PreferenceConverter.getColor(ExternalToolsPlugin.getDefault().getPreferenceStore(),IPreferenceConstants.CONSOLE_INFO_RGB));		
+		return INFO_COLOR;
+	}
+	/**
+	 * Returns the color used for verbose messages on the log console.
+	 */
+	private static Color getVerboseColor() {
+		if (VERBOSE_COLOR == null || VERBOSE_COLOR.isDisposed())
+			VERBOSE_COLOR = new Color(null, PreferenceConverter.getColor(ExternalToolsPlugin.getDefault().getPreferenceStore(),IPreferenceConstants.CONSOLE_VERBOSE_RGB));		
+		return VERBOSE_COLOR;
+	}
+	/**
+	 * Returns the color used for debug messages on the log console.
+	 */
+	private static Color getDebugColor() {
+		if (DEBUG_COLOR == null || DEBUG_COLOR.isDisposed())
+			DEBUG_COLOR = new Color(null, PreferenceConverter.getColor(ExternalToolsPlugin.getDefault().getPreferenceStore(),IPreferenceConstants.CONSOLE_DEBUG_RGB));	
+		return DEBUG_COLOR;
+	}
+	
+	public Display getDisplay() {
+		if (!hasViews()) 
+			return null;
+		return ((LogConsoleView)views.get(0)).getSite().getShell().getDisplay();	
+	}
+	
+	/*package*/ Document getDocument() {
+		return document;	
+	}
+	
+	/*package*/  ArrayList getStyleRanges() {
+		return styleRanges;	
+	}
+	
+	public ArrayList getViews() {
+		return views;
+	}
+	
+	/*package*/ OutputStructureElement getRoot() {
+		return root;	
+	}
+	
+	public boolean hasViews() {
+		return (views.size() > 0);	
+	}
+	
+	public void initializeOutputStructure() {
+		// root is the first element of the structure: it is a fake so it doesn't need a real name
+		root = new OutputStructureElement("-- root --"); // $NON-NLS-1$
+		currentElement = new OutputStructureElement(ToolMessages.getString("LogConsoleDocument.externalTool"), root, 0); // $NON-NLS-1$
+		
+		for (int i=0; i < views.size(); i++) {
+			LogConsoleView view = (LogConsoleView)views.get(i);
+			if (view.getTreeViewer() != null)
+				view.initializeTreeInput();
+		}
+	}
+	
+	public void registerView(LogConsoleView view) {
+		if (!hasViews()) {
+			// first time there is an instance of this class: intantiate the font and register the listener
+			ANT_FONT = new Font(null, PreferenceConverter.getFontData(ExternalToolsPlugin.getDefault().getPreferenceStore(),IPreferenceConstants.CONSOLE_FONT));
+			ExternalToolsPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(changeListener);
+		}
+		views.add(view);	
+	}
+	
+	public void unregisterView(LogConsoleView view) {
+		views.remove(view);	
+		if (! hasViews()) {
+			// all the consoles are diposed: we can dispose the font and remove the property listener
+			ANT_FONT.dispose();
+			ExternalToolsPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(changeListener);
+		}
+	}
+	
+	public static LogConsoleDocument getInstance() {
+		return instance;	
+	}
+	
+	public OutputStructureElement getCurrentOutputStructureElement() {
+		return currentElement;
+	}
+	public void setCurrentOutputStructureElement(OutputStructureElement output) {
+		this.currentElement = output;
+	}
+	/*package*/ void setOutputLevelColor(int level, int start, int end) {
+		switch (level) {
+			case LogConsoleDocument.MSG_ERR: 
+				addRangeStyle(start, end, getErrorColor()); 
+				break;
+			case LogConsoleDocument.MSG_WARN: 
+				addRangeStyle(start, end, getWarnColor()); 
+				break;
+			case LogConsoleDocument.MSG_INFO: 
+				addRangeStyle(start, end, getInfoColor()); 
+				break;
+			case LogConsoleDocument.MSG_VERBOSE: 
+				addRangeStyle(start, end, getVerboseColor()); 
+				break;
+			case LogConsoleDocument.MSG_DEBUG: 
+				addRangeStyle(start, end, getDebugColor()); 
+				break;
+			default: 
+				addRangeStyle(start, end, getInfoColor());
+		}
+	}
+	
+	/**
+	 * Replaces the old color with the new one in all style ranges,
+	 */
+	private void updateStyleRanges(Color oldColor, Color newColor) {
+		for (int i=0; i<styleRanges.size(); i++) {
+			StyleRange range = (StyleRange)styleRanges.get(i);
+			if (range.foreground == oldColor)
+				range.foreground = newColor;
+		}
+	}
+
+	private class LogPropertyChangeListener implements IPropertyChangeListener {
+	
+		// private constructor to ensure the singleton
+		private LogPropertyChangeListener() {
+		}
+		
+		/**
+		 * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
+		 */
+		public void propertyChange(PropertyChangeEvent event) {
+				String propertyName= event.getProperty();
+			
+				if (propertyName.equals(IPreferenceConstants.CONSOLE_ERROR_RGB)) {
+					if (LogConsoleDocument.ERROR_COLOR == null)
+						return;
+					Color temp = getErrorColor();
+					LogConsoleDocument.ERROR_COLOR = ToolsPreferencePage.getPreferenceColor(IPreferenceConstants.CONSOLE_ERROR_RGB);
+					updateStyleRanges(temp, getErrorColor());
+					temp.dispose();
+				} else if (propertyName.equals(IPreferenceConstants.CONSOLE_WARNING_RGB)) {
+					if (LogConsoleDocument.WARN_COLOR == null)
+						return;
+					Color temp = getWarnColor();
+					LogConsoleDocument.WARN_COLOR = ToolsPreferencePage.getPreferenceColor(IPreferenceConstants.CONSOLE_WARNING_RGB);
+					updateStyleRanges(temp, getWarnColor());
+					temp.dispose();
+				} else if (propertyName.equals(IPreferenceConstants.CONSOLE_INFO_RGB)) {
+					if (LogConsoleDocument.INFO_COLOR == null)
+						return;
+					Color temp = getInfoColor();
+					LogConsoleDocument.INFO_COLOR = ToolsPreferencePage.getPreferenceColor(IPreferenceConstants.CONSOLE_INFO_RGB);
+					updateStyleRanges(temp, getInfoColor());
+					temp.dispose();
+				} else if (propertyName.equals(IPreferenceConstants.CONSOLE_VERBOSE_RGB)) {
+					if (LogConsoleDocument.VERBOSE_COLOR == null)
+						return;
+					Color temp = getVerboseColor();
+					LogConsoleDocument.VERBOSE_COLOR = ToolsPreferencePage.getPreferenceColor(IPreferenceConstants.CONSOLE_VERBOSE_RGB);
+					updateStyleRanges(temp, getVerboseColor());
+					temp.dispose();
+				} else if (propertyName.equals(IPreferenceConstants.CONSOLE_DEBUG_RGB)) {
+					if (LogConsoleDocument.DEBUG_COLOR == null)
+						return;
+					Color temp = getDebugColor();
+					LogConsoleDocument.DEBUG_COLOR = ToolsPreferencePage.getPreferenceColor(IPreferenceConstants.CONSOLE_DEBUG_RGB);
+					updateStyleRanges(temp, getDebugColor());
+					temp.dispose();
+				} else if (propertyName.equals(IPreferenceConstants.CONSOLE_FONT)) {
+					FontData data= ToolsPreferencePage.getConsoleFontData();
+					Font temp= LogConsoleDocument.ANT_FONT;
+					LogConsoleDocument.ANT_FONT = new Font(Display.getCurrent(), data);
+					temp.dispose();
+					updateFont();	
+				} else
+					return;
+		}
+	
+		/**
+		 * Clears the output of all the consoles
+		 */
+		private void clearOutput() {
+			LogConsoleDocument.getInstance().clearOutput();
+		}
+		
+		/**
+		 * Updates teh font in all the consoles
+		 */
+		private void updateFont() {
+			for (Iterator iterator = LogConsoleDocument.getInstance().getViews().iterator(); iterator.hasNext();)
+				 ((LogConsoleView) iterator.next()).updateFont();
+		}
+	}
+
+
+}
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogConsolePreferencePage.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogConsolePreferencePage.java
new file mode 100644
index 0000000..f7bf957
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogConsolePreferencePage.java
@@ -0,0 +1,115 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import org.eclipse.jface.preference.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.*;
+import org.eclipse.ui.externaltools.internal.core.*;
+import org.eclipse.ui.help.WorkbenchHelp;
+
+/**
+ * A page to set the preferences for the console
+ * 
+ * @deprecated This preference page should not be used. To be removed by next release.
+ */
+public class LogConsolePreferencePage
+	extends FieldEditorPreferencePage
+	implements IWorkbenchPreferencePage {
+
+	/**
+	 * Create the console page.
+	 */
+	public LogConsolePreferencePage() {
+		super(GRID);
+
+		setDescription(ToolMessages.getString("LogConsolePreferencePage.description")); //$NON-NLS-1$
+
+		IPreferenceStore store =
+			ExternalToolsPlugin.getDefault().getPreferenceStore();
+		setPreferenceStore(store);
+	}
+	public void createControl(Composite parent) {
+		super.createControl(parent);
+		WorkbenchHelp.setHelp(getControl(), IHelpContextIds.LOG_CONSOLE_PREFERENCE_PAGE);
+	}
+	/**
+	 * Create all field editors for this page
+	 */
+	public void createFieldEditors() {
+
+		ColorFieldEditor errOut =
+			new ColorFieldEditor(
+				IPreferenceConstants.CONSOLE_ERROR_RGB,
+				ToolMessages.getString("LogConsolePreferencePage.errorColor"), //$NON-NLS-1$
+				getFieldEditorParent());
+		ColorFieldEditor warnOut =
+			new ColorFieldEditor(
+				IPreferenceConstants.CONSOLE_WARNING_RGB,
+				ToolMessages.getString("LogConsolePreferencePage.warningColor"), //$NON-NLS-1$
+				getFieldEditorParent());
+		ColorFieldEditor infoOut =
+			new ColorFieldEditor(
+				IPreferenceConstants.CONSOLE_INFO_RGB,
+				ToolMessages.getString("LogConsolePreferencePage.infoColor"), //$NON-NLS-1$
+				getFieldEditorParent());
+		ColorFieldEditor verbOut =
+			new ColorFieldEditor(
+				IPreferenceConstants.CONSOLE_VERBOSE_RGB,
+				ToolMessages.getString("LogConsolePreferencePage.verboseColor"), //$NON-NLS-1$
+				getFieldEditorParent());
+		ColorFieldEditor debugOut =
+			new ColorFieldEditor(
+				IPreferenceConstants.CONSOLE_DEBUG_RGB,
+				ToolMessages.getString("LogConsolePreferencePage.debugColor"), //$NON-NLS-1$
+				getFieldEditorParent());
+
+		FontFieldEditor font =
+			new FontFieldEditor(
+				IPreferenceConstants.CONSOLE_FONT,
+				ToolMessages.getString("LogConsolePreferencePage.font"), //$NON-NLS-1$
+				getFieldEditorParent());
+
+		addField(errOut);
+		addField(warnOut);
+		addField(infoOut);
+		addField(verbOut);
+		addField(debugOut);
+		addField(font);
+	}
+	/**
+	 * Returns the font data that describes the font to use for the console
+	 */
+	protected static FontData getConsoleFontData() {
+		IPreferenceStore pstore =
+			ExternalToolsPlugin.getDefault().getPreferenceStore();
+		FontData fontData =
+			PreferenceConverter.getFontData(
+				pstore,
+				IPreferenceConstants.CONSOLE_FONT);
+		return fontData;
+	}
+	/**
+	 * Returns the a color based on the type.
+	 */
+	protected static Color getPreferenceColor(String type) {
+		IPreferenceStore pstore =
+			ExternalToolsPlugin.getDefault().getPreferenceStore();
+		RGB outRGB = PreferenceConverter.getColor(pstore, type);
+		return new Color(Display.getCurrent(), outRGB);
+	}
+	/**
+	 * @see IWorkbenchPreferencePage#init
+	 */
+	public void init(IWorkbench workbench) {
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogConsoleView.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogConsoleView.java
new file mode 100644
index 0000000..e62462a
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogConsoleView.java
Binary files differ
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogTreeContentProvider.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogTreeContentProvider.java
new file mode 100644
index 0000000..5d3a51b
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogTreeContentProvider.java
@@ -0,0 +1,67 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+/**
+ * Content provider for the tree viewer of the Ant Console.
+ */
+
+public class LogTreeContentProvider implements ITreeContentProvider {
+
+	private LogConsoleView console;
+
+	public LogTreeContentProvider(LogConsoleView console) {
+		this.console = console;
+	}
+
+	/**
+	 * @see ITreeContentProvider#getChildren(Object)
+	 */
+	public Object[] getChildren(Object parent) {
+		return ((OutputStructureElement) parent).getChildren();
+	}
+
+	/**
+	 * @see ITreeContentProvider#getParent(Object)
+	 */
+	public Object getParent(Object element) {
+		return ((OutputStructureElement) element).getParent();
+	}
+
+	/**
+	 * @see ITreeContentProvider#hasChildren(Object)
+	 */
+	public boolean hasChildren(Object element) {
+		return ((OutputStructureElement) element).hasChildren();
+	}
+
+	/**
+	 * @see IStructuredContentProvider#getElements(Object)
+	 */
+	public Object[] getElements(Object parent) {
+		return ((OutputStructureElement) parent).getChildren();
+	}
+
+	/**
+	 * @see IContentProvider#dispose()
+	 */
+	public void dispose() {
+	}
+
+	/**
+	 * @see IContentProvider#inputChanged(Viewer, Object, Object)
+	 */
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogTreeLabelProvider.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogTreeLabelProvider.java
new file mode 100644
index 0000000..66c8743
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/LogTreeLabelProvider.java
@@ -0,0 +1,72 @@
+package org.eclipse.ui.externaltools.internal.ui;
+
+/**********************************************************************
+Copyright (c) 2002 IBM Corp. and others.
+All rights reserved.   This program and the accompanying materials
+are made available under the terms of the Common Public License v0.5
+which accompanies this distribution, and is available at
+http://www.eclipse.org/legal/cpl-v05.html

+Contributors:
+**********************************************************************/
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.externaltools.internal.core.ToolMessages;
+
+/**
+ * Label provider for the tree viewer of the Log Console.
+ */
+public class LogTreeLabelProvider implements ILabelProvider {
+
+	private LogConsoleView console;
+
+	public LogTreeLabelProvider(LogConsoleView console) {
+		this.console = console;
+	}
+
+	/**
+	 * @see ILabelProvider#getImage(Object)
+	 */
+	public Image getImage(Object element) {
+		return null;
+	}
+
+	/**
+	 * @see ILabelProvider#getText(Object)
+	 */
+	public String getText(Object element) {
+		String text = ((OutputStructureElement) element).getName();
+		if (text == null)
+			// this can happen if the user writes a task name that doesn't exist => the #taskStarted will be triggered
+			// but null will be given as a name to the current task, and then only, the exception will be raised
+			return ToolMessages.getString("LogTreeLabelProvider.invalidItemName"); // $NON-NLS-1$
+		return text;
+	}
+
+	/**
+	 * @see IBaseLabelProvider#addListener(ILabelProviderListener)
+	 */
+	public void addListener(ILabelProviderListener listener) {
+	}
+
+	/**
+	 * @see IBaseLabelProvider#dispose()
+	 */
+	public void dispose() {
+	}
+
+	/**
+	 * @see IBaseLabelProvider#isLabelProperty(Object, String)
+	 */
+	public boolean isLabelProperty(Object arg0, String arg1) {
+		return false;
+	}
+
+	/**
+	 * @see IBaseLabelProvider#removeListener(ILabelProviderListener)
+	 */
+	public void removeListener(ILabelProviderListener listener) {
+	}
+
+}
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/OutputStructureElement.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/OutputStructureElement.java
new file mode 100644
index 0000000..76b5397
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/OutputStructureElement.java
@@ -0,0 +1,102 @@
+/**********************************************************************
+ * Copyright (c) 2002 IBM Corporation and others.
+ * All rights reserved.   This program and the accompanying materials
+ * are made available under the terms of the Common Public License v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ * 
+ * Contributors: 
+ * IBM - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.ui.externaltools.internal.ui;
+
+import java.util.ArrayList;
+
+/**
+ * Object which stores the index and the length of the output for a given
+ * target or task (represented by a string)
+ */
+
+public class OutputStructureElement {
+
+	private OutputStructureElement parent = null;
+	private ArrayList children;
+	private String name;
+	private int startIndex = 0;
+	private int length = 0;
+
+
+/**
+ * This constructor is intended to be used only by the first element of the structure (the root element)
+ */
+public OutputStructureElement(String name) {
+	// there's at least one target as it is the root which may be instantiated via this constructor
+	children = new ArrayList(1);
+	this.name = name;
+}
+
+/**
+ * This constructor is used for any element but the first element of the structure (the root element)
+ */	
+public OutputStructureElement(String name, OutputStructureElement parent, int startIndex) {
+	children = new ArrayList(0);
+	this.name = name;
+	this.startIndex = startIndex;
+	parent.addChild(this);
+}
+
+public void addChild(OutputStructureElement child) {
+	children.add(child);
+	child.setParent(this);
+}
+
+public boolean hasChildren() {
+	return !children.isEmpty();
+}
+
+public String getName() {
+	return name;
+}
+
+public void setName(String name) {
+	this.name = name;
+}
+
+public void setParent(OutputStructureElement parent) {
+	this.parent = parent;
+}
+
+public OutputStructureElement getParent() {
+	return parent;
+}
+
+public OutputStructureElement[] getChildren() {
+	return (OutputStructureElement[]) children.toArray(new OutputStructureElement[children.size()]);
+}
+
+public void setStartIndex(int index) {
+	startIndex = index;
+}
+
+public void setEndIndex(int index) {
+	length = index - startIndex;
+}
+
+public int getStartIndex() {
+	return startIndex;
+}
+
+public int getEndIndex() {
+	return startIndex + length;
+}
+
+public int getLength() {
+	return length;
+}
+
+public String toString() {
+	return name;
+}
+
+}
+
diff --git a/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/ToolsPreferencePage.java b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/ToolsPreferencePage.java
new file mode 100644
index 0000000..271d9d8
--- /dev/null
+++ b/org.eclipse.ui.externaltools/External Tools/org/eclipse/ui/externaltools/internal/ui/ToolsPreferencePage.java
Binary files differ
diff --git a/org.eclipse.ui.externaltools/about.html b/org.eclipse.ui.externaltools/about.html
new file mode 100644
index 0000000..9db411a
--- /dev/null
+++ b/org.eclipse.ui.externaltools/about.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>20th June, 2002</p>	
+<h3>License</h3>
+<p>Eclipse.org makes available all content in this plug-in (&quot;Content&quot;).  Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Common Public License Version 1.0 (&quot;CPL&quot;).  A copy of the CPL is available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+For purposes of the CPL, &quot;Program&quot; will mean the Content.</p>
+
+<h3>Contributions</h3>
+
+<p>If this Content is licensed to you under the terms and conditions of the CPL, any Contributions, as defined in the CPL, uploaded, submitted, or otherwise
+made available to Eclipse.org, members of Eclipse.org and/or the host of Eclipse.org web site, by you that relate to such
+Content are provided under the terms and conditions of the CPL and can be made available to others under the terms of the CPL.</p>
+
+<p>If this Content is licensed to you under license terms and conditions other than the CPL (&quot;Other License&quot;), any modifications, enhancements and/or
+other code and/or documentation (&quot;Modifications&quot;) uploaded, submitted, or otherwise made available to Eclipse.org, members of Eclipse.org and/or the
+host of Eclipse.org, by you that relate to such Content are provided under terms and conditions of the Other License and can be made available
+to others under the terms of the Other License.  In addition, with regard to Modifications for which you are the copyright holder, you are also
+providing the Modifications under the terms and conditions of the CPL and such Modifications can be made available to others under the terms of
+the CPL.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/build.properties b/org.eclipse.ui.externaltools/build.properties
new file mode 100644
index 0000000..a7e53a5
--- /dev/null
+++ b/org.eclipse.ui.externaltools/build.properties
@@ -0,0 +1,16 @@
+source.externaltools.jar = External Tools/
+
+source.lib/antbuilder.jar = Ant Builder
+
+src.includes=about.html
+
+bin.includes = icons/,\
+		.options,\
+		plugin.properties,\
+		plugin.xml,\
+		about.html,\
+		*.jar,\
+		lib/*.jar
+				
+jars.compile.order=externaltools.jar,lib/antbuilder.jar
+jars.extra.classpath=../org.apache.ant/ant.jar
diff --git a/org.eclipse.ui.externaltools/buildnotes.html b/org.eclipse.ui.externaltools/buildnotes.html
new file mode 100644
index 0000000..545a618
--- /dev/null
+++ b/org.eclipse.ui.externaltools/buildnotes.html
@@ -0,0 +1,39 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="Build">
+   <meta name="GENERATOR" content="Mozilla/4.75 [en] (Windows NT 5.0; U) [Netscape]">
+   <title>Eclipse Platform Release Notes - Workbench</title>
+</head>
+<body>
+
+<h1>
+Eclipse Platform Build Notes<br>
+External Tools</h1>
+Eclipse Integration Build 20020507
+<h2>
+What's new in this drop</h2>
+
+<h3>
+API changes</h3>
+
+<h3>
+API additions</h3>
+
+<h3>
+Other highlights</h3>
+
+<h2>
+Known deficiencies</h2>
+
+<h2>
+Problem reports fixed</h2>
+<a href="http://dev.eclipse.org/bugs/buglist.cgi?bug_status=RESOLVED&bug_status=VERIFIED&bug_status=CLOSED&chfield=bug_status&chfieldfrom=2002%2F04%2F30&chfieldto=2002%2F05%2F07&product=Platform&component=UI&cmdtype=doit&&order=Bug+Number">Click
+here</a> to see PRs which have been marked as RESOLVED, VERIFIED or CLOSED
+between 2002/04/30 and 2002/05/07.
+<p>
+<hr SIZE=0 WIDTH="100%">
+<br>&nbsp;
+</body>
+</html>
diff --git a/org.eclipse.ui.externaltools/icons/full/clcl16/clear.gif b/org.eclipse.ui.externaltools/icons/full/clcl16/clear.gif
new file mode 100644
index 0000000..2558326
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/clcl16/clear.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/clcl16/hide_show_tree.gif b/org.eclipse.ui.externaltools/icons/full/clcl16/hide_show_tree.gif
new file mode 100644
index 0000000..5a8c7ea
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/clcl16/hide_show_tree.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/clcl16/show_selected_text.gif b/org.eclipse.ui.externaltools/icons/full/clcl16/show_selected_text.gif
new file mode 100644
index 0000000..be9eb92
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/clcl16/show_selected_text.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/ctool16/external_tools.gif b/org.eclipse.ui.externaltools/icons/full/ctool16/external_tools.gif
new file mode 100644
index 0000000..2133b45
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/ctool16/external_tools.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/cview16/log_console_view.gif b/org.eclipse.ui.externaltools/icons/full/cview16/log_console_view.gif
new file mode 100644
index 0000000..3200ac3
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/cview16/log_console_view.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/dtool16/external_tools.gif b/org.eclipse.ui.externaltools/icons/full/dtool16/external_tools.gif
new file mode 100644
index 0000000..fae592d
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/dtool16/external_tools.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/etool16/external_tools.gif b/org.eclipse.ui.externaltools/icons/full/etool16/external_tools.gif
new file mode 100644
index 0000000..f7472c9
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/etool16/external_tools.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/eview16/log_console_view.gif b/org.eclipse.ui.externaltools/icons/full/eview16/log_console_view.gif
new file mode 100644
index 0000000..3f6fff3
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/eview16/log_console_view.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/obj16/ant_file.gif b/org.eclipse.ui.externaltools/icons/full/obj16/ant_file.gif
new file mode 100644
index 0000000..f3e45a4
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/obj16/ant_file.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/obj16/builder.gif b/org.eclipse.ui.externaltools/icons/full/obj16/builder.gif
new file mode 100644
index 0000000..20e7bae
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/obj16/builder.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/obj16/classpath.gif b/org.eclipse.ui.externaltools/icons/full/obj16/classpath.gif
new file mode 100644
index 0000000..f966fc3
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/obj16/classpath.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/obj16/external_tools.gif b/org.eclipse.ui.externaltools/icons/full/obj16/external_tools.gif
new file mode 100644
index 0000000..2133b45
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/obj16/external_tools.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/obj16/invalid_build_tool.gif b/org.eclipse.ui.externaltools/icons/full/obj16/invalid_build_tool.gif
new file mode 100644
index 0000000..b04020b
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/obj16/invalid_build_tool.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/obj16/jar_l_obj.gif b/org.eclipse.ui.externaltools/icons/full/obj16/jar_l_obj.gif
new file mode 100644
index 0000000..11e04e2
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/obj16/jar_l_obj.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/obj16/type.gif b/org.eclipse.ui.externaltools/icons/full/obj16/type.gif
new file mode 100644
index 0000000..2db7604
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/obj16/type.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/wizban/ant_wiz.gif b/org.eclipse.ui.externaltools/icons/full/wizban/ant_wiz.gif
new file mode 100644
index 0000000..e40998a
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/wizban/ant_wiz.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/icons/full/wizban/ext_tools_wiz.gif b/org.eclipse.ui.externaltools/icons/full/wizban/ext_tools_wiz.gif
new file mode 100644
index 0000000..1a863bf
--- /dev/null
+++ b/org.eclipse.ui.externaltools/icons/full/wizban/ext_tools_wiz.gif
Binary files differ
diff --git a/org.eclipse.ui.externaltools/lib/.cvsignore b/org.eclipse.ui.externaltools/lib/.cvsignore
new file mode 100644
index 0000000..5bdda7d
--- /dev/null
+++ b/org.eclipse.ui.externaltools/lib/.cvsignore
@@ -0,0 +1,2 @@
+antbuilder.jar
+antbuilder.jar.bin.log
diff --git a/org.eclipse.ui.externaltools/plugin.properties b/org.eclipse.ui.externaltools/plugin.properties
new file mode 100644
index 0000000..07bc79b
--- /dev/null
+++ b/org.eclipse.ui.externaltools/plugin.properties
@@ -0,0 +1,14 @@
+Plugin.name = External Tools
+Plugin.providerName = Eclipse.org
+PopupMenu.runAnt = Run &Ant...
+PopupMenu.runAntTip = Run Ant With The Selected File
+ActionSet.externalTools = External Tools
+Action.externalTools = &External Tools
+Action.externalToolsTip = Run or Configure External Tools
+PropertyPage.externalToolsBuilders = External Tools Builders
+Category.externalTools = External Tools
+View.logConsole = Log Console
+PreferencePage.toolsPreferences = External Tools
+PreferencePage.antPreferences = Ant
+Menu.run = &Run
+Builder.externalTools = Integrated External Tools Builder
\ No newline at end of file
diff --git a/org.eclipse.ui.externaltools/plugin.xml b/org.eclipse.ui.externaltools/plugin.xml
new file mode 100644
index 0000000..f2cd673
--- /dev/null
+++ b/org.eclipse.ui.externaltools/plugin.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin
+   id="org.eclipse.ui.externaltools"
+   name="%Plugin.name"
+   version="2.1.0"
+   provider-name="%Plugin.providerName"
+   class="org.eclipse.ui.externaltools.internal.core.ExternalToolsPlugin">
+
+   <runtime>
+      <library name="externaltools.jar">
+         <export name="*"/>
+      </library>
+   </runtime>
+   <requires>
+      <import plugin="org.apache.xerces"/>
+      <import plugin="org.eclipse.ant.core"/>
+      <import plugin="org.eclipse.core.resources"/>
+      <import plugin="org.eclipse.ui"/>
+   </requires>
+
+
+<!-- extension point definitions -->
+
+<!-- Extensions -->
+	<extension point="org.eclipse.core.resources.builders"
+		id="ExternalToolBuilder"
+		name="%Builder.externalTools">
+		<builder> 
+			<run class="org.eclipse.ui.externaltools.internal.core.ExternalToolsBuilder"/> 
+		</builder> 
+	</extension>
+
+	<extension point="org.eclipse.ui.popupMenus">
+		<objectContribution
+			id="org.eclipse.ui.externaltools.RunAnt"
+			objectClass="org.eclipse.core.resources.IFile"
+			adaptable="true"
+			nameFilter="*.xml">
+			<action
+				id="org.eclipse.ui.externaltools.RunAntAction"
+				label="%PopupMenu.runAnt"
+				tooltip="%PopupMenu.runAntTip"
+				menubarPath="additions"
+				enablesFor="1"
+				class="org.eclipse.ui.externaltools.internal.ui.AntRunActionDelegate">
+			</action>
+		</objectContribution>			
+	</extension>
+
+	<extension point="org.eclipse.ui.actionSets">
+		<actionSet
+			id="org.eclipse.ui.externaltools.ExternalToolsSet"
+			label="%ActionSet.externalTools"
+			visible="true">
+			<menu id="org.eclipse.ui.run" 
+				label="%Menu.run" 
+				path="additions"> 
+				<separator name="ExternalToolsGroup"/> 
+			</menu> 
+			<action
+				id="org.eclipse.ui.externaltools.ExternalToolAction"
+				label="%Action.externalTools"
+				menubarPath="org.eclipse.ui.run/ExternalToolsGroup"
+				toolbarPath="Normal/additions"
+				disabledIcon="icons/full/dtool16/external_tools.gif"
+				icon="icons/full/etool16/external_tools.gif"
+				hoverIcon="icons/full/ctool16/external_tools.gif"
+				tooltip="%Action.externalToolsTip"
+				pulldown="true"
+				class="org.eclipse.ui.externaltools.internal.ui.ExternalToolsAction">
+			</action>
+		</actionSet>
+	</extension>
+
+	<extension point="org.eclipse.ui.propertyPages">
+		<page
+			id="org.eclipse.ui.externaltools.propertypages.BuilderPropertyPage"
+			objectClass="org.eclipse.core.resources.IProject"
+			adaptable="true"
+			name="%PropertyPage.externalToolsBuilders"
+			class="org.eclipse.ui.externaltools.internal.ui.BuilderPropertyPage">
+			<filter name="open" value="true"/> 
+		</page>
+	</extension>
+
+	<extension point="org.eclipse.ui.preferencePages">
+		<page 
+			id="org.eclipse.ui.externaltools.ToolsPreferencePage" 
+			name="%PreferencePage.toolsPreferences"
+			class="org.eclipse.ui.externaltools.internal.ui.ToolsPreferencePage">
+		</page>
+		<page 
+			id="org.eclipse.ui.externaltools.AntPreferencePage" 
+			name="%PreferencePage.antPreferences"
+			class="org.eclipse.ui.externaltools.internal.ui.AntPreferencePage"
+			category="org.eclipse.ui.externaltools.ToolsPreferencePage">
+		</page>
+	</extension>
+
+	<extension point="org.eclipse.ui.views">
+		<category 
+			id="org.eclipse.ui.externaltools.views"
+			name="%Category.externalTools">
+		</category>
+		<view
+			id="org.eclipse.ui.externaltools.LogConsoleView"
+	  		name="%View.logConsole"
+			icon="icons/full/cview16/log_console_view.gif"
+			fastViewWidthRatio="0.75"
+			category="org.eclipse.ui.externaltools.views"
+			class="org.eclipse.ui.externaltools.internal.ui.LogConsoleView">
+		</view>
+	</extension>
+
+    <extension point="org.eclipse.ant.core.extraClasspathEntries">
+     	<extraClasspathEntry
+         	library="lib/antbuilder.jar">
+      	</extraClasspathEntry>
+    </extension>
+
+
+</plugin>
diff --git a/org.eclipse.ui.externaltools/scripts/buildExtraJAR.xml b/org.eclipse.ui.externaltools/scripts/buildExtraJAR.xml
new file mode 100644
index 0000000..fb32fdc
--- /dev/null
+++ b/org.eclipse.ui.externaltools/scripts/buildExtraJAR.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="org.eclipse.ui.externaltools" default="build" basedir="..">
+
+	<property name="bootclasspath" value=""/>
+
+	<target name="build">
+		<antcall target="clean"/>
+		<antcall target="lib/antbuilderlib.jar"/>
+		<antcall target="refresh"/>
+	</target>
+
+	<target name="init" depends="properties">
+		<property name="plugin" value="org.eclipse.ui.externaltools"/>
+		<property name="version.suffix" value="_2.1.0"/>
+		<property name="full.name" value="${plugin}${version.suffix}"/>
+		<property name="temp.folder" value="${basedir}/temp.folder"/>
+		<property name="plugin.destination" value="${basedir}"/>
+		<property name="build.result.folder" value="${basedir}"/>
+		<property name="win32.jar" value="${basedir}/../org.eclipse.swt.win32/ws/win32/swt.jar"/>
+		<property name="gtk.jar" value="${basedir}/../org.eclipse.swt.gtk/ws/gtk/swt.jar"/>
+		<property name="motif.jar" value="${basedir}/../org.eclipse.swt.motif/ws/motif/swt.jar"/>
+		<available file="${win32.jar}" property="swt.jar" value="${win32.jar}"/>
+		<available file="${gtk.jar}" property="swt.jar" value="${gtk.jar}"/>
+		<available file="${motif.jar}" property="swt.jar" value="${motif.jar}"/>
+	</target>
+
+	<target name="properties" if="eclipse.running">
+		<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+	</target>
+
+	<target name="lib/antbuilderlib.jar" depends="init">
+		<property name="destdir" value="${temp.folder}/lib/antbuilderlib.jar.bin"/>
+		<delete dir="${temp.folder}/lib/antbuilderlib.jar.bin"/>
+		<mkdir dir="${temp.folder}/lib/antbuilderlib.jar.bin"/>
+		<!-- compile the source code -->
+		<javac target="1.3" source="1.3" destdir="${temp.folder}/lib/antbuilderlib.jar.bin" failonerror="false" verbose="false" debug="on" includeAntRuntime="no" bootclasspath="${bootclasspath}" classpath="${basedir}/../org.eclipse.core.runtime/runtime.jar;${basedir}/../org.apache.ant/ant.jar;${basedir}/../org.apache.xerces/xercesImpl.jar;${basedir}/../org.apache.xerces/xmlParserAPIs.jar;${basedir}/bin;${basedir}/../org.eclipse.core.boot/boot.jar;${swt.jar};${basedir}/../org.eclipse.jface/jface.jar;${basedir}/../org.eclipse.ui.workbench/workbench.jar;${basedir}/../org.eclipse.ant.core/bin">
+			<src path="Ant Builder/"/>
+		</javac>
+		<!-- copy necessary resources -->
+		<copy todir="${temp.folder}/lib/antbuilderlib.jar.bin">
+			<fileset dir="Ant Builder/" excludes="**/*.java"/>
+		</copy>
+		<mkdir dir="${build.result.folder}/lib"/>
+		<jar jarfile="${build.result.folder}/lib/antbuilder.jar" basedir="${temp.folder}/lib/antbuilderlib.jar.bin"/>
+		<delete dir="${temp.folder}"/>
+	</target>
+
+	<target name="clean" depends="init">
+		<delete file="${build.result.folder}/lib/antbuilder.jar"/>
+		<delete dir="${temp.folder}"/>
+	</target>
+
+	<target name="refresh" depends="init" if="eclipse.running">
+		<eclipse.refreshLocal resource="${plugin}" depth="infinite"/>
+	</target>
+
+</project>
diff --git a/org.eclipse.ui.externaltools/scripts/buildSelfHostingJARs.xml b/org.eclipse.ui.externaltools/scripts/buildSelfHostingJARs.xml
new file mode 100644
index 0000000..4fb2342
--- /dev/null
+++ b/org.eclipse.ui.externaltools/scripts/buildSelfHostingJARs.xml
@@ -0,0 +1,14 @@
+<project name="exportplugins" default="Create extra JARs" basedir=".">
+	<target name="init">
+		<tstamp/>
+	</target>
+
+	<target name="Create extra JARs" depends="init">
+		<ant antfile="scripts/buildExtraJAR.xml" dir="../../org.eclipse.ant.core" target="clean"/>
+		<ant antfile="scripts/buildExtraJAR.xml" dir="../../org.eclipse.ant.core" target="lib/antsupportlib.jar"/>
+		<ant antfile="scripts/buildExtraJAR.xml" dir="../../org.eclipse.ant.core" target="refresh"/>
+		<ant antfile="scripts/buildExtraJAR.xml" dir="../../org.eclipse.ui.externaltools" target="clean"/>
+		<ant antfile="scripts/buildExtraJAR.xml" dir="../../org.eclipse.ui.externaltools" target="lib/antbuilderlib.jar"/>
+		<ant antfile="scripts/buildExtraJAR.xml" dir="../../org.eclipse.ui.externaltools" target="refresh"/>
+	</target>
+</project>
diff --git a/org.eclipse.ui.externaltools/scripts/exportplugin.xml b/org.eclipse.ui.externaltools/scripts/exportplugin.xml
new file mode 100644
index 0000000..5437425
--- /dev/null
+++ b/org.eclipse.ui.externaltools/scripts/exportplugin.xml
@@ -0,0 +1,40 @@
+<!-- Export a jar of .class files for the org.eclipse.ui.externaltools Eclipse plug-in
+     along with other important plugin files to the "plugin-export" subdirectory
+     of the target Eclipse installation -->
+<project name="org.eclipse.ui.externaltools" default="export" basedir="..">
+
+	<!-- Set the timestamp and important properties -->
+	<target name="init">
+		<tstamp/>
+		<property name="destdir" value="../../plugin-export" />
+		<property name="dest"  value="${destdir}/org.eclipse.ui.externaltools_2.1.0" />
+	</target>
+
+	<!-- Create the jar of .class files, and copy other important files to export dir -->
+	<target name="export" depends="init">
+		<mkdir dir="${destdir}" />
+		<delete dir="${dest}" />
+		<mkdir dir="${dest}" />
+		<delete dir="${dest}/lib"/>
+		<mkdir dir="${dest}/lib"/>
+		<jar 
+			jarfile="${dest}/externaltools.jar"
+			basedir="bin"
+		/>
+		<!-- Create the source zip -->
+		<zip zipfile="${dest}/externaltoolssrc.zip">
+			<fileset dir="Ant Builder"/>
+			<fileset dir="External Tools"/>
+		</zip>
+		<copy file="plugin.xml" todir="${dest}"/>
+		<copy file="plugin.properties" todir="${dest}"/>
+		<copy file=".classpath" todir="${dest}"/>
+		<copy file=".options" todir="${dest}"/>
+		<ant antfile="scripts/buildExtraJAR.xml" target="build"/>
+		<copy file="lib/antbuilder.jar" todir="${dest}/lib"/>
+		<copy todir="${dest}/icons">
+			<fileset dir="icons" />
+		</copy>		
+	</target>
+	
+</project>
diff --git a/org.eclipse.ui.externaltools/scripts/updateTarget.xml b/org.eclipse.ui.externaltools/scripts/updateTarget.xml
new file mode 100644
index 0000000..afb0830
--- /dev/null
+++ b/org.eclipse.ui.externaltools/scripts/updateTarget.xml
@@ -0,0 +1,72 @@
+<!-- 
+
+	For use in development of the External tools plugin 
+	This script can be used to update a target for testing/debugging
+	Export a jar of .class files for the org.eclipse.ant.core Eclipse plugin
+    along with other important plugin files to the "plugin-export" subdirectory
+    of the target Eclipse installation
+	As well the export of the plugin is copied to a target installation.
+ -->
+<project name="org.eclipse.ui.externaltools" default="export" basedir="..">
+
+	<!-- Set the timestamp and important properties -->
+	<target name="init">
+		<tstamp/>
+		<property name="bootclasspath" value=""/>
+		<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>
+		<property name="destdir" value="../../plugin-export" />
+		<property name="pluginName" value= "org.eclipse.ui.externaltools_2.1.0"/>
+		<property name="destBin"  value="${destdir}/${pluginName}" />
+		<property name="destSrc"  value="${destdir}/org.eclipse.platform.source/src/org.eclipse.ui.externaltools_2.1.0" />
+		<property name="temp.folder" value="${destdir}/temp.folder"/>
+
+		<property name="currentBuild" value="../../Debugger/Ant/eclipse"/>
+		<property name="currentBuildPlugins" value="${currentBuild}/plugins/${pluginName}"/>
+	</target>
+
+	<!-- Create the jar of .class files, and copy other important files to export dir -->
+	<target name="export" depends="init">
+		<mkdir dir="${destdir}" />
+		<delete dir="${destBin}" />
+		<mkdir dir="${destBin}" />
+		<delete dir="${destSrc}" />
+		<mkdir dir="${destSrc}" />
+		<delete dir="${destBin}/lib" />
+		<jar 
+			jarfile="${destBin}/externaltools.jar"
+			basedir="bin"
+			excludes="bin/org/eclipse/ui/externaltools/internal/ui/ant"
+		/>
+		<!-- Create the source zip -->
+		<zip zipfile="${destSrc}/externaltoolssrc.zip">
+			<fileset dir="External Tools"/>
+		</zip>
+		<copy file="plugin.xml" todir="${destBin}"/>
+		<copy file="plugin.properties" todir="${destBin}"/>
+		<copy file="about.html" todir="${destBin}"/>
+		<copy file=".classpath" todir="${destBin}"/>
+		<copy file=".options" todir="${destBin}"/>
+		
+		<delete dir="${temp.folder}/lib/antbuilder.jar.bin"/>
+		<mkdir dir="${temp.folder}/lib/antbuilder.jar.bin"/>
+		<!-- compile the source code -->
+		<javac destdir="${temp.folder}/lib/antbuilder.jar.bin" failonerror="false" verbose="false" debug="on" includeAntRuntime="no" bootclasspath="${bootclasspath}" classpath="${basedir}/../org.eclipse.core.runtime/runtime.jar;${basedir}/../org.apache.ant/ant.jar;${basedir}/../org.apache.xerces/xercesImpl.jar;${basedir}/../org.apache.xerces/xmlParserAPIs.jar;${basedir}/bin;${basedir}/../org.eclipse.core.boot/boot.jar;${basedir}/../org.eclipse.swt.win32/ws/win32/swt.jar;${basedir}/../org.eclipse.ant.core/bin">
+			<src path="Ant Builder/"/>
+		</javac>
+		<!-- copy any necessary resources -->
+		<copy todir="${temp.folder}/lib/antbuilder.jar.bin">
+			<fileset dir="Ant Builder/" excludes="**/*.java"/>
+		</copy>
+		<mkdir dir="${destBin}/lib"/>
+		<jar jarfile="${destBin}/lib/antbuilder.jar" basedir="${temp.folder}/lib/antbuilder.jar.bin"/>
+		<delete dir="${temp.folder}"/>
+		
+	</target>
+	
+	<target name="copy" depends="init">
+		<copy todir="${currentBuildPlugins}">
+			<fileset dir="${destBin}"/>
+		</copy>
+	</target>
+	
+</project>
diff --git a/org.eclipse.ui.externaltools/scripts/updateTargets.xml b/org.eclipse.ui.externaltools/scripts/updateTargets.xml
new file mode 100644
index 0000000..b0da825
--- /dev/null
+++ b/org.eclipse.ui.externaltools/scripts/updateTargets.xml
@@ -0,0 +1,12 @@
+<project name="exportplugins" default="export to remote targets" basedir=".">
+	<target name="init">
+		<tstamp/>
+	</target>
+
+	<target name="export to remote targets" depends="init">
+		<ant antfile="scripts/updateTarget.xml" dir="../../org.eclipse.ant.core" target="export"/>
+		<ant antfile="scripts/updateTarget.xml" dir="../../org.eclipse.ant.core" target="copy"/>
+		<ant antfile="scripts/updateTarget.xml" dir="../../org.eclipse.ui.externalTools" target="export"/>
+		<ant antfile="scripts/updateTarget.xml" dir="../../org.eclipse.ui.externalTools" target="copy"/>
+	</target>
+</project>