diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/Auditor.java b/command-line-debugger/src/main/org/apache/ant/debugger/Auditor.java
new file mode 100644
index 0000000..3c9487b
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/Auditor.java
@@ -0,0 +1,49 @@
+package org.apache.ant.debugger;
+
+import java.util.List;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * Audits all calls to change property values
+ * 
+ * Right now only properties are audited: We can try to figure a way to audit
+ * other data-types if it adds any value.
+ */
+public interface Auditor {
+
+	/**
+	 * Marks a property to be tracked for attempted changes.
+	 * 
+	 * @param property
+	 */
+	public void addPropertyForAudits(String property, Project project);
+
+	/**
+	 * Audits change to a property by name <code>property</code>.
+	 * 
+	 * @param property
+	 * @param value
+	 * @param project
+	 */
+	public void auditPropertyChange(String property, Object value,
+			Project project);
+
+	/**
+	 * Returns all records for the key.
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public List getAuditsForProperty(String key);
+
+	/**
+	 * Provide a hook for debuggers to attach to this auditor so that it may be
+	 * able to pass back the control to the Debugger in case of a Property
+	 * Breakpoint.
+	 * 
+	 * @param debugger
+	 */
+	public void setPrompt(DebugPrompt debugger);
+
+}
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/DebugCommandSet.java b/command-line-debugger/src/main/org/apache/ant/debugger/DebugCommandSet.java
new file mode 100644
index 0000000..e9f60b0
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/DebugCommandSet.java
@@ -0,0 +1,100 @@
+package org.apache.ant.debugger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * Handles all debug support functionality.
+ */
+public class DebugCommandSet {
+
+	protected Project project;
+
+	protected Map commandSupport = new HashMap();
+
+	public void setProject(Project project) {
+		this.project = project;
+	}
+
+	/**
+	 * Initialize all debug commands here - preferrably read from a properties
+	 * file.
+	 */
+	public void init(Map commands) {
+		if (commands != null)
+			commandSupport.putAll(commands);
+		Properties props = new Properties();
+		try {
+			InputStream is = DebugCommandSet.class.getClassLoader()
+					.getResourceAsStream(
+							"org/apache/ant/debugger/debug-support.properties");
+			props.load(is);
+			Enumeration en = props.keys();
+			while (en.hasMoreElements()) {
+				String key = (String) en.nextElement();
+				String className = props.getProperty(key);
+				Class commandClass;
+				try {
+					commandClass = Class.forName(className);
+					Object command = commandClass.newInstance();
+					if (command instanceof DebugSupport)
+						commandSupport.put(key, command);
+					else
+						project
+								.log(
+										"Command Class: "
+												+ className
+												+ " does not implement DebugSupport. Ignoring.",
+										Project.MSG_WARN);
+				} catch (ClassNotFoundException e) {
+					project.log("Could not find class: " + className,
+							Project.MSG_WARN);
+				} catch (InstantiationException e) {
+					project.log("Could not instantiate class: " + className,
+							Project.MSG_WARN);
+				} catch (IllegalAccessException e) {
+					project.log("Illegal Access while instantiating class: "
+							+ className, Project.MSG_WARN);
+				}
+			}
+		} catch (IOException ioe) {
+			// if the resource could not be located, then initialize with what
+			// is known
+			throw new RuntimeException(ioe);
+		}
+	}
+
+	public void handleCommand(String command) {
+		if (command == null || command.trim().length() == 0) {
+			project.log("Invalid command. Use /? for more information.");
+		}
+		command = command.trim();
+		if (command.equals("/?")) {
+			printUsage();
+			return;
+		}
+
+		String[] tokens = command.split(" ");
+		DebugSupport selected = (DebugSupport) commandSupport.get(tokens[0]);
+		if (selected != null) {
+			selected.execute(project, tokens);
+		} else {
+			printUsage();
+		}
+	}
+
+	protected void printUsage() {
+		// log all help stuff here
+		project
+				.log("You may use one of the following commands: locate, inspect, return");
+		project
+				.log("Type the command followed by /? for more information. Eg. inspect /?");
+	}
+
+}
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/DebugPrompt.java b/command-line-debugger/src/main/org/apache/ant/debugger/DebugPrompt.java
new file mode 100644
index 0000000..046af54
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/DebugPrompt.java
@@ -0,0 +1,46 @@
+package org.apache.ant.debugger;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.input.DefaultInputHandler;
+import org.apache.tools.ant.input.InputHandler;
+import org.apache.tools.ant.input.InputRequest;
+import org.apache.tools.ant.util.StringUtils;
+
+public class DebugPrompt {
+
+	protected Project project = null;
+
+	protected DebugCommandSet commandHandler;
+
+	public DebugPrompt(Project project, DebugCommandSet commandHandler) {
+		this.project = project;
+		this.commandHandler = commandHandler;
+	}
+
+	public void prompt(String message) {
+		InputRequest ir = new InputRequest("Debugger> ");
+		InputHandler ih = new DefaultInputHandler();
+		String command = null;
+		project.log(StringUtils.LINE_SEP
+				+ "-------- Ant Command Line Debugger --------"
+				+ StringUtils.LINE_SEP + StringUtils.LINE_SEP);
+
+		// print a friendly message to allow the user to understand why this
+		// breakpoint occurred
+		project.log(message);
+		project.log("");
+		// keep accepting inputs, until the user enters the return command
+		do {
+			ih.handleInput(ir);
+			command = ir.getInput();
+			commandHandler.handleCommand(command);
+			project.log(""); // log a new line
+		} while (!"return".equals(command));
+
+		// resume build execution on this
+		project.log(StringUtils.LINE_SEP
+				+ "--------- Resuming Ant Execution ----------"
+				+ StringUtils.LINE_SEP);
+	}
+
+}
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/DebugSupport.java b/command-line-debugger/src/main/org/apache/ant/debugger/DebugSupport.java
new file mode 100644
index 0000000..1e26146
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/DebugSupport.java
@@ -0,0 +1,33 @@
+package org.apache.ant.debugger;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * An interface for supporting debug commands.
+ */
+public interface DebugSupport {
+
+	/**
+	 * Check if this command is supported.
+	 * 
+	 * @param command
+	 * @return
+	 */
+	public boolean commandSupported(String command);
+
+	/**
+	 * Main execution body of the class. Pass all command parameters.
+	 * 
+	 * @param project
+	 * @param params
+	 */
+	public void execute(Project project, String[] params);
+
+	/**
+	 * Prints usage of the command.
+	 * 
+	 * @param project
+	 */
+	public void printUsage(Project project);
+
+}
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/DebugUtils.java b/command-line-debugger/src/main/org/apache/ant/debugger/DebugUtils.java
new file mode 100644
index 0000000..db1e052
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/DebugUtils.java
@@ -0,0 +1,34 @@
+package org.apache.ant.debugger;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.ComponentHelper;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.Task;
+
+public class DebugUtils {
+	
+	public static List searchTask(Class expectedTaskClass, Project project) {
+		List result = new ArrayList();
+		for (Iterator iterator = project.getTargets().values().iterator(); iterator
+				.hasNext();) {
+			Target t = (Target) iterator.next();
+			for (int i = 0; i < t.getTasks().length; i++) {
+				Task task = t.getTasks()[i];
+				Class taskClass = ComponentHelper.getComponentHelper(project)
+						.getComponentClass(task.getTaskType());
+				// will need to see in what cases it could return a null type
+				// perhaps failing when the task is using a custom antlib
+				// defined task
+				if (taskClass != null && taskClass.equals(expectedTaskClass)) {
+					result.add(task);
+				}
+			}
+		}
+		return result;
+	}
+
+}
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/DefaultAuditor.java b/command-line-debugger/src/main/org/apache/ant/debugger/DefaultAuditor.java
new file mode 100644
index 0000000..0438a33
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/DefaultAuditor.java
@@ -0,0 +1,98 @@
+package org.apache.ant.debugger;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+
+/**
+ * Default implementation of {@link Auditor}. At the same time, this class also
+ * acts as a Debug command permitting the recorded audits to be available on
+ * user commands.
+ * <p />
+ * Optionally, this class allows a {@link DebugPrompt} instance to attach itself to
+ * this auditor, so that if change to a certain property is attempted, then the
+ * debugger may be chosen to be transferred the control to.
+ */
+public class DefaultAuditor implements Auditor, DebugSupport {
+
+	protected Map propertyaudits = new HashMap();
+
+	protected DebugPrompt prompt = null;
+
+	public void setPrompt(DebugPrompt prompt) {
+		this.prompt = prompt;
+	}
+
+	public void addPropertyForAudits(String property, Project project) {
+		// the list in the value will keep track of all attempted changes to
+		// this property
+		project.log("Adding Property: " + property + " to be audited.",
+				Project.MSG_DEBUG);
+		propertyaudits.put(property, new LinkedList());
+	}
+
+	public void auditPropertyChange(String property, Object value,
+			Project project) {
+		List audits = (List) propertyaudits.get(property);
+		if (audits != null) {
+			project.log("Adding Attempted Change record for Property: "
+					+ property, Project.MSG_DEBUG);
+			// if any target executes while currentTarget = null, it indicates
+			// the property
+			// transition happened outside the scope of any target, directly
+			// inside the build file
+			PropertyHelper helper = PropertyHelper.getPropertyHelper(project);
+			StringBuffer sb = new StringBuffer();
+			sb.append("Property [").append(property).append(
+					"] change attempted from [");
+			sb.append(helper.getProperty(property)).append("] to [");
+			sb.append(value).append("]");
+			String message = sb.toString();
+			audits.add(message);
+
+			// if there is a debugger attached to this instance, pass the
+			// control to the debugger
+			if (prompt != null)
+				prompt.prompt(message);
+		}
+
+	}
+
+	public List getAuditsForProperty(String key) {
+		return (List) propertyaudits.get(key);
+	}
+
+	public boolean commandSupported(String command) {
+		return "trace".equals(command);
+	}
+
+	public void execute(Project project, String[] params) {
+		if (params.length != 2) {
+			printUsage(project);
+		}
+
+		String property = params[1];
+
+		List changes = getAuditsForProperty(property);
+		if (changes != null) {
+			project.log("Found " + changes.size()
+					+ " Attempted Changes to Property: " + property);
+			Iterator it = changes.iterator();
+			while (it.hasNext()) {
+				project.log("  - " + (String) it.next());
+			}
+		} else {
+			project.log("  - No records found for Property: " + property);
+		}
+	}
+
+	public void printUsage(Project project) {
+		project.log("Some HelpFul Message here");
+	}
+
+}
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/Inspector.java b/command-line-debugger/src/main/org/apache/ant/debugger/Inspector.java
new file mode 100644
index 0000000..319ec1e
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/Inspector.java
@@ -0,0 +1,60 @@
+package org.apache.ant.debugger;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.taskdefs.PathConvert;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Inspects the current value of a property, path or some reference.
+ */
+public class Inspector implements DebugSupport {
+
+	public boolean commandSupported(String command) {
+		return "inspect".equalsIgnoreCase(command);
+	}
+
+	public void execute(Project project, String[] params) {
+		if (params.length < 3 || "/?".equals(params[1])) {
+			printUsage(project);
+		}
+
+		if ("property".equalsIgnoreCase(params[1])) {
+			// show all matches for a property
+			Object value = PropertyHelper.getProperty(project, params[2]);
+			if (value != null) {
+				project.log("Detected a property by name [" + params[1]
+						+ "]. Current value: " + value);
+			} else {
+				project.log("Found no such property.");
+			}
+		} else if ("path".equalsIgnoreCase(params[1])) {
+			// look optional component
+			// the remaining part of the string could be:
+			// id=<someid> or refid=<somerefid>
+			Object ref = project.getReference(params[2]);
+			if (ref instanceof ResourceCollection) {
+				if (ref != null) {
+					PathConvert path = (PathConvert) project
+							.createTask("pathconvert");
+					path.setProject(project);
+					path.setPathSep(StringUtils.LINE_SEP + "    - ");
+					path.add((ResourceCollection) ref);
+					path.execute();
+				} else {
+					project.log("No path-reference found for " + params[2]);
+				}
+			} else {
+				project.log("No path found for reference id: " + params[2]);
+			}
+		}
+
+	}
+
+	public void printUsage(Project project) {
+		project.log("Incorrect Parameters");
+		project.log("Usage: inspect property some.property");
+		project.log("       inspect path path.id");
+	}
+}
\ No newline at end of file
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/NoOp.java b/command-line-debugger/src/main/org/apache/ant/debugger/NoOp.java
new file mode 100644
index 0000000..9bfeced
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/NoOp.java
@@ -0,0 +1,21 @@
+package org.apache.ant.debugger;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * Used to implement commands that should not be handled by {@link DebugSupport}
+ * at all. Example, the 'return' command
+ */
+public final class NoOp implements DebugSupport {
+
+	public boolean commandSupported(String command) {
+		return "return".equalsIgnoreCase(command);
+	}
+
+	public void execute(Project project, String[] params) {
+		// do nothing
+	}
+
+	public void printUsage(Project project) {
+	};
+}
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/debug-support.properties b/command-line-debugger/src/main/org/apache/ant/debugger/debug-support.properties
new file mode 100644
index 0000000..e388e71
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/debug-support.properties
@@ -0,0 +1,3 @@
+inspect=org.apache.ant.debugger.Inspector
+locate=org.apache.tools.ant.Locator
+return=org.apache.ant.debugger.NoOp
\ No newline at end of file
diff --git a/command-line-debugger/src/main/org/apache/tools/ant/DebugTask.java b/command-line-debugger/src/main/org/apache/tools/ant/DebugTask.java
deleted file mode 100644
index 6049b1b..0000000
--- a/command-line-debugger/src/main/org/apache/tools/ant/DebugTask.java
+++ /dev/null
@@ -1,329 +0,0 @@
-package org.apache.tools.ant;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.ComponentHelper;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.Target;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.input.DefaultInputHandler;
-import org.apache.tools.ant.input.InputHandler;
-import org.apache.tools.ant.input.InputRequest;
-import org.apache.tools.ant.taskdefs.PathConvert;
-import org.apache.tools.ant.taskdefs.Property;
-import org.apache.tools.ant.types.Path;
-import org.apache.tools.ant.types.Reference;
-import org.apache.tools.ant.types.ResourceCollection;
-import org.apache.tools.ant.util.StringUtils;
-
-/**
- * A stand alone debug task that plugs into the build through projecthelper
- * class by injecting a dependency at the end of a target. This is a POC and
- * does not yet work for Extension-Points.
- */
-public class DebugTask extends Task {
-	/**
-	 * Debugger prompt
-	 */
-	public static final String PROMPT = "DEBUGGER> ";
-
-	/**
-	 * Standard target name for the internal debugger
-	 */
-	public static final String DEBUG_TARGET_NAME = "-internal-debugger";
-
-	/*
-	 * A static final debug target that is injected as a dependency. We may need
-	 * to have more than one such target if we are to allow multiple
-	 * break-points in the build.
-	 */
-	private static final Target debugTarget = new Target();
-
-	/*
-	 * Set of all commands that can be interpreted at runtime.
-	 */
-	private static Set supportedCommands = new HashSet();
-
-	static {
-		// add any more commands to be supported here
-		// if need be, this can be considered to be
-		// moved to a separate properties file
-		supportedCommands.add("locate");
-		supportedCommands.add("inspect");
-		supportedCommands.add("return");
-	}
-
-	public void execute() throws BuildException {
-		// expect input here
-		InputRequest ir = new InputRequest(PROMPT);
-		InputHandler ih = new DefaultInputHandler();
-		String command = null;
-		getProject().log(
-				StringUtils.LINE_SEP
-						+ "-------- Ant Command Line Debugger --------"
-						+ StringUtils.LINE_SEP + StringUtils.LINE_SEP);
-
-		// keep accepting inputs, until the user enters the return command
-		do {
-			ih.handleInput(ir);
-			command = ir.getInput();
-			handleCommand(command);
-			getProject().log(""); // log a new line
-		} while (!"return".equals(command));
-
-		// resume build execution on this
-		getProject().log(
-				StringUtils.LINE_SEP
-						+ "--------- Resuming Ant Execution ----------"
-						+ StringUtils.LINE_SEP);
-	}
-
-	/**
-	 * Static method to create a runtime-debug target. For purposes of Command
-	 * Line Debugger (CLD), the target returned by this method, and identified
-	 * by DEBUG_TARGET_NAME must be added at the end of the dependency list of
-	 * the target where the break point exists.
-	 * 
-	 * @param project
-	 * @return
-	 */
-	public static Target createDebugTarget(Project project) {
-		// see what is the best value for the Location to assume?
-		// Location loc = new Location(??);
-
-		debugTarget.setProject(project);
-		debugTarget.setName(DEBUG_TARGET_NAME);
-		project.addTarget(debugTarget);
-		// create an instance of debug task and attach it to this project
-		Task debugtask = project.createTask("debug");
-		debugtask.setProject(project);
-		debugtask.setTaskName("Debugger");
-		debugTarget.addTask(debugtask);
-		return debugTarget;
-	}
-
-	/*
-	 * Interprets user input and decides if the command is supported or should
-	 * be rejected.
-	 */
-	protected void handleCommand(String command) {
-		if (command == null || command.trim().length() == 0) {
-			getProject().log("Invalid command. Use /? for more information.");
-		}
-		command = command.trim();
-		if (command.equals("/?")) {
-			printUsage();
-			return;
-		}
-
-		String[] tokens = command.split(" ");
-		if (!supportedCommands.contains(tokens[0])) {
-			printUsage();
-			return;
-		}
-
-		DebugSupport[] debuggers = new DebugSupport[] { new NoOp(),
-				new Inspector(), new Locator() };
-		DebugSupport selected = null;
-		for (int j = 0; j < debuggers.length; j++) {
-			if (debuggers[j].commandSupported(tokens[0]))
-				selected = debuggers[j];
-		}
-		selected.execute(getProject(), tokens);
-	}
-
-	protected void printUsage() {
-		// log all help stuff here
-		getProject()
-				.log(
-						"You may use one of the following commands: locate, inspect, return");
-		getProject()
-				.log(
-						"Type the command followed by /? for more information. Eg. inspect /?");
-	}
-
-	protected static List searchTask(Class expectedTaskClass, Project project) {
-		List result = new ArrayList();
-		for (Iterator iterator = project.getTargets().values().iterator(); iterator
-				.hasNext();) {
-			Target t = (Target) iterator.next();
-			for (int i = 0; i < t.getTasks().length; i++) {
-				Task task = t.getTasks()[i];
-				Class taskClass = ComponentHelper.getComponentHelper(project)
-						.getComponentClass(task.getTaskType());
-				// will need to see in what cases it could return a null type
-				// perhaps failing when the task is using a custom antlib
-				// defined task
-				if (taskClass != null && taskClass.equals(expectedTaskClass)) {
-					result.add(task);
-				}
-			}
-		}
-		return result;
-	}
-
-	/**
-	 * An interface for supporting debug commands.
-	 */
-	public static interface DebugSupport {
-
-		/**
-		 * Check if this command is supported.
-		 * 
-		 * @param command
-		 * @return
-		 */
-		public boolean commandSupported(String command);
-
-		/**
-		 * Main execution body of the class. Pass all command parameters.
-		 * 
-		 * @param project
-		 * @param params
-		 */
-		public void execute(Project project, String[] params);
-
-		/**
-		 * Prints usage of the command.
-		 * 
-		 * @param project
-		 */
-		public void printUsage(Project project);
-
-	}
-
-	/**
-	 * Used to implement commands that should not be handled by
-	 * {@link DebugSupport} at all. Example, the 'return' command
-	 */
-	public static final class NoOp implements DebugSupport {
-
-		public boolean commandSupported(String command) {
-			return "return".equalsIgnoreCase(command);
-		}
-
-		public void execute(Project project, String[] params) {
-			// do nothing
-		}
-
-		public void printUsage(Project project) {
-		};
-	}
-
-	/**
-	 * Locates properties / paths in static build sources
-	 */
-	public static final class Locator implements DebugSupport {
-
-		public boolean commandSupported(String command) {
-			return "locate".equalsIgnoreCase(command);
-		}
-
-		public void execute(Project project, String[] params) {
-			// the command syntax is 'locate property some.property'
-			// or 'locate path some.path
-			if (params.length != 3 || "/?".equals(params[1])) {
-				printUsage(project);
-				return;
-			}
-
-			List matches = null;
-			String key = null;
-			if ("property".equalsIgnoreCase(params[1])) {
-				// locate and publish the property
-				matches = DebugTask.searchTask(Property.class, project);
-				key = "name";
-			} else if ("path".equalsIgnoreCase(params[1])) {
-				// locate and publish the path
-				matches = DebugTask.searchTask(Path.class, project);
-				key = "id";
-			} else {
-				// see if any other component may be supported
-				project.log("Unexpected component: " + params[1]);
-				project.log("Supported components are property, path.");
-				return;
-			}
-
-			// probably accept some kind of a query from end user and select the
-			// target object based on the query
-			for (Iterator iterator = matches.iterator(); iterator.hasNext();) {
-				Task task = (Task) iterator.next();
-				// display attributes
-				Map attributeMap = task.getWrapper().getAttributeMap();
-				if (!params[2].equals(attributeMap.get(key))) {
-					continue;
-				}
-				String value = (String) attributeMap.get("value");
-				project.log("Detected a property by name [" + params[2]
-						+ "]. Build file value: " + value);
-				// and their respected location
-				project.log("Located at: " + task.getLocation().toString());
-			}
-		}
-
-		public void printUsage(Project project) {
-			project.log("Incorrect Parameters");
-			project.log("Usage: locate property/path propertyname/pathname");
-		}
-	}
-
-	/**
-	 * Inspects the current value of a property, path or some reference.
-	 */
-	public static final class Inspector implements DebugSupport {
-
-		public boolean commandSupported(String command) {
-			return "inspect".equalsIgnoreCase(command);
-		}
-
-		public void execute(Project project, String[] params) {
-			if (params.length < 3 || "/?".equals(params[1])) {
-				printUsage(project);
-			}
-
-			if ("property".equalsIgnoreCase(params[1])) {
-				// show all matches for a property
-				Object value = PropertyHelper.getProperty(project, params[2]);
-				if (value != null) {
-					project.log("Detected a property by name [" + params[1]
-							+ "]. Current value: " + value);
-				} else {
-					project.log("Found no such property.");
-				}
-			} else if ("path".equalsIgnoreCase(params[1])) {
-				// look optional component
-				// the remaining part of the string could be:
-				// id=<someid> or refid=<somerefid>
-				Object ref = project.getReference(params[2]);
-				if (ref instanceof ResourceCollection) {
-					if (ref != null) {
-						PathConvert path = (PathConvert) project
-								.createTask("pathconvert");
-						path.setProject(project);
-						path.setPathSep(StringUtils.LINE_SEP + "    - ");
-						path.add((ResourceCollection) ref);
-						path.execute();
-					} else {
-						project.log("No path-reference found for " + params[2]);
-					}
-				} else {
-					project.log("No path found for reference id: " + params[2]);
-				}
-			}
-
-		}
-
-		public void printUsage(Project project) {
-			project.log("Incorrect Parameters");
-			project.log("Usage: inspect property some.property");
-			project.log("       inspect path path.id");
-		}
-	}
-}
diff --git a/command-line-debugger/src/main/org/apache/tools/ant/Locator.java b/command-line-debugger/src/main/org/apache/tools/ant/Locator.java
new file mode 100644
index 0000000..98202e7
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/tools/ant/Locator.java
@@ -0,0 +1,75 @@
+package org.apache.tools.ant;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ant.debugger.DebugSupport;
+import org.apache.ant.debugger.DebugUtils;
+
+import org.apache.tools.ant.taskdefs.Property;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Locates properties / paths in static build sources
+ */
+public class Locator implements DebugSupport {
+
+	public boolean commandSupported(String command) {
+		return "locate".equalsIgnoreCase(command);
+	}
+
+	public void execute(Project project, String[] params) {
+		// the command syntax is 'locate property some.property'
+		// or 'locate path some.path
+		if (params.length != 3 || "/?".equals(params[1])) {
+			printUsage(project);
+			return;
+		}
+
+		List matches = null;
+		String key = null;
+		if ("property".equalsIgnoreCase(params[1])) {
+			// locate and publish the property
+			matches = DebugUtils.searchTask(Property.class, project);
+			key = "name";
+		} else if ("path".equalsIgnoreCase(params[1])) {
+			// locate and publish the path
+			matches = DebugUtils.searchTask(Path.class, project);
+			key = "id";
+		} else {
+			// see if any other component may be supported
+			project.log("Unexpected component: " + params[1]);
+			project.log("Supported components are property, path.");
+			return;
+		}
+
+		boolean found = false;
+
+		// probably accept some kind of a query from end user and select the
+		// target object based on the query
+		for (Iterator iterator = matches.iterator(); iterator.hasNext();) {
+			Task task = (Task) iterator.next();
+			// display attributes
+			Map attributeMap = task.getWrapper().getAttributeMap();
+			if (!params[2].equals(attributeMap.get(key))) {
+				continue;
+			}
+			found = true;
+			String value = (String) attributeMap.get("value");
+			project.log("Detected a property by name [" + params[2]
+					+ "]. Build file value: " + value);
+			// and their respected location
+			project.log("Located at: " + task.getLocation().toString());
+		}
+
+		if (!found) {
+			project.log("No property by name [" + params[2] + "] found.");
+		}
+	}
+
+	public void printUsage(Project project) {
+		project.log("Incorrect Parameters");
+		project.log("Usage: locate property/path propertyname/pathname");
+	}
+}
\ No newline at end of file
diff --git a/command-line-debugger/src/main/org/apache/tools/ant/Main.java b/command-line-debugger/src/main/org/apache/tools/ant/Main.java
deleted file mode 100644
index d85ddf9..0000000
--- a/command-line-debugger/src/main/org/apache/tools/ant/Main.java
+++ /dev/null
@@ -1,1235 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-
-package org.apache.tools.ant;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.Vector;
-
-import org.apache.tools.ant.input.DefaultInputHandler;
-import org.apache.tools.ant.input.InputHandler;
-import org.apache.tools.ant.launch.AntMain;
-import org.apache.tools.ant.property.ResolvePropertyMap;
-import org.apache.tools.ant.util.ClasspathUtils;
-import org.apache.tools.ant.util.FileUtils;
-import org.apache.tools.ant.util.ProxySetup;
-
-
-/**
- * Command line entry point into Ant. This class is entered via the
- * canonical `public static void main` entry point and reads the
- * command line arguments. It then assembles and executes an Ant
- * project.
- * <p>
- * If you integrating Ant into some other tool, this is not the class
- * to use as an entry point. Please see the source code of this
- * class to see how it manipulates the Ant project classes.
- *
- */
-public class Main implements AntMain {
-
-    /**
-     * A Set of args are are handled by the launcher and should
-     * not be seen by Main.
-     */
-    private static final Set LAUNCH_COMMANDS = new HashSet();
-    static {
-        LAUNCH_COMMANDS.add("-lib");
-        LAUNCH_COMMANDS.add("-cp");
-        LAUNCH_COMMANDS.add("-noclasspath");
-        LAUNCH_COMMANDS.add("--noclasspath");
-        LAUNCH_COMMANDS.add("-nouserlib");
-        LAUNCH_COMMANDS.add("-main");
-    }
-
-    /** The default build file name. {@value} */
-    public static final String DEFAULT_BUILD_FILENAME = "build.xml";
-
-    /** Our current message output status. Follows Project.MSG_XXX. */
-    private int msgOutputLevel = Project.MSG_INFO;
-
-    /** File that we are using for configuration. */
-    private File buildFile; /* null */
-
-    /** Stream to use for logging. */
-    private static PrintStream out = System.out;
-
-    /** Stream that we are using for logging error messages. */
-    private static PrintStream err = System.err;
-
-    /** The build targets. */
-    private Vector targets = new Vector();
-
-    /** Set of properties that can be used by tasks. */
-    private Properties definedProps = new Properties();
-
-    /** Names of classes to add as listeners to project. */
-    private Vector listeners = new Vector(1);
-
-    /** File names of property files to load on startup. */
-    private Vector propertyFiles = new Vector(1);
-
-    /** Indicates whether this build is to support interactive input */
-    private boolean allowInput = true;
-
-    /** keep going mode */
-    private boolean keepGoingMode = false;
-
-    /**
-     * The Ant logger class. There may be only one logger. It will have
-     * the right to use the 'out' PrintStream. The class must implements the
-     * BuildLogger interface.
-     */
-    private String loggerClassname = null;
-
-    /**
-     * The Ant InputHandler class.  There may be only one input
-     * handler.
-     */
-    private String inputHandlerClassname = null;
-
-    /**
-     * Whether or not output to the log is to be unadorned.
-     */
-    private boolean emacsMode = false;
-
-    /**
-     * Whether or not this instance has successfully been
-     * constructed and is ready to run.
-     */
-    private boolean readyToRun = false;
-
-    /**
-     * Whether or not we should only parse and display the project help
-     * information.
-     */
-    private boolean projectHelp = false;
-
-    /**
-     * Whether or not a logfile is being used. This is used to
-     * check if the output streams must be closed.
-     */
-    private static boolean isLogFileUsed = false;
-
-    /**
-     * optional thread priority
-     */
-    private Integer threadPriority = null;
-
-    /**
-     * proxy flag: default is false
-     */
-    private boolean proxy = false;
-
-    /**
-     * Target at which to break execution sequence
-     */
-    private String breakAt = null;
-    
-    /**
-     * Prints the message of the Throwable if it (the message) is not
-     * <code>null</code>.
-     *
-     * @param t Throwable to print the message of.
-     *          Must not be <code>null</code>.
-     */
-    private static void printMessage(Throwable t) {
-        String message = t.getMessage();
-        if (message != null) {
-            System.err.println(message);
-        }
-    }
-
-    /**
-     * Creates a new instance of this class using the
-     * arguments specified, gives it any extra user properties which have been
-     * specified, and then runs the build using the classloader provided.
-     *
-     * @param args Command line arguments. Must not be <code>null</code>.
-     * @param additionalUserProperties Any extra properties to use in this
-     *        build. May be <code>null</code>, which is the equivalent to
-     *        passing in an empty set of properties.
-     * @param coreLoader Classloader used for core classes. May be
-     *        <code>null</code> in which case the system classloader is used.
-     */
-    public static void start(String[] args, Properties additionalUserProperties,
-                             ClassLoader coreLoader) {
-        Main m = new Main();
-        m.startAnt(args, additionalUserProperties, coreLoader);
-    }
-
-    /**
-     * Start Ant
-     * @param args command line args
-     * @param additionalUserProperties properties to set beyond those that
-     *        may be specified on the args list
-     * @param coreLoader - not used
-     *
-     * @since Ant 1.6
-     */
-    public void startAnt(String[] args, Properties additionalUserProperties,
-                         ClassLoader coreLoader) {
-
-        try {
-            processArgs(args);
-        } catch (Throwable exc) {
-            handleLogfile();
-            printMessage(exc);
-            exit(1);
-            return;
-        }
-
-        if (additionalUserProperties != null) {
-            for (Enumeration e = additionalUserProperties.keys();
-                    e.hasMoreElements();) {
-                String key = (String) e.nextElement();
-                String property = additionalUserProperties.getProperty(key);
-                definedProps.put(key, property);
-            }
-        }
-
-        // expect the worst
-        int exitCode = 1;
-        try {
-            try {
-                runBuild(coreLoader);
-                exitCode = 0;
-            } catch (ExitStatusException ese) {
-                exitCode = ese.getStatus();
-                if (exitCode != 0) {
-                    throw ese;
-                }
-            }
-        } catch (BuildException be) {
-            if (err != System.err) {
-                printMessage(be);
-            }
-        } catch (Throwable exc) {
-            exc.printStackTrace();
-            printMessage(exc);
-        } finally {
-            handleLogfile();
-        }
-        exit(exitCode);
-    }
-
-    /**
-     * This operation is expected to call {@link System#exit(int)}, which
-     * is what the base version does.
-     * However, it is possible to do something else.
-     * @param exitCode code to exit with
-     */
-    protected void exit(int exitCode) {
-        System.exit(exitCode);
-    }
-
-    /**
-     * Close logfiles, if we have been writing to them.
-     *
-     * @since Ant 1.6
-     */
-    private static void handleLogfile() {
-        if (isLogFileUsed) {
-            FileUtils.close(out);
-            FileUtils.close(err);
-        }
-    }
-
-    /**
-     * Command line entry point. This method kicks off the building
-     * of a project object and executes a build using either a given
-     * target or the default target.
-     *
-     * @param args Command line arguments. Must not be <code>null</code>.
-     */
-    public static void main(String[] args) {
-        start(args, null, null);
-    }
-
-    /**
-     * Constructor used when creating Main for later arg processing
-     * and startup
-     */
-    public Main() {
-    }
-
-    /**
-     * Sole constructor, which parses and deals with command line
-     * arguments.
-     *
-     * @param args Command line arguments. Must not be <code>null</code>.
-     *
-     * @exception BuildException if the specified build file doesn't exist
-     *                           or is a directory.
-     *
-     * @deprecated since 1.6.x
-     */
-    protected Main(String[] args) throws BuildException {
-        processArgs(args);
-    }
-
-    /**
-     * Process command line arguments.
-     * When ant is started from Launcher, launcher-only arguments do not get
-     * passed through to this routine.
-     *
-     * @param args the command line arguments.
-     *
-     * @since Ant 1.6
-     */
-    private void processArgs(String[] args) {
-        String searchForThis = null;
-        boolean searchForFile = false;
-        PrintStream logTo = null;
-
-        // cycle through given args
-
-        boolean justPrintUsage = false;
-        boolean justPrintVersion = false;
-        boolean justPrintDiagnostics = false;
-
-        for (int i = 0; i < args.length; i++) {
-            String arg = args[i];
-
-            if (arg.equals("-help") || arg.equals("-h")) {
-                justPrintUsage = true;
-            } else if (arg.equals("-version")) {
-                justPrintVersion = true;
-            } else if (arg.equals("-diagnostics")) {
-                justPrintDiagnostics = true;
-            } else if (arg.equals("-quiet") || arg.equals("-q")) {
-                msgOutputLevel = Project.MSG_WARN;
-            } else if (arg.equals("-verbose") || arg.equals("-v")) {
-                msgOutputLevel = Project.MSG_VERBOSE;
-            } else if (arg.equals("-debug") || arg.equals("-d")) {
-                msgOutputLevel = Project.MSG_DEBUG;
-            } else if (arg.equals("-noinput")) {
-                allowInput = false;
-            } else if (arg.equals("-logfile") || arg.equals("-l")) {
-                try {
-                    File logFile = new File(args[i + 1]);
-                    i++;
-                    logTo = new PrintStream(new FileOutputStream(logFile));
-                    isLogFileUsed = true;
-                } catch (IOException ioe) {
-                    String msg = "Cannot write on the specified log file. "
-                        + "Make sure the path exists and you have write "
-                        + "permissions.";
-                    throw new BuildException(msg);
-                } catch (ArrayIndexOutOfBoundsException aioobe) {
-                    String msg = "You must specify a log file when "
-                        + "using the -log argument";
-                    throw new BuildException(msg);
-                }
-            } else if (arg.equals("-buildfile") || arg.equals("-file")
-                       || arg.equals("-f")) {
-                i = handleArgBuildFile(args, i);
-            } else if (arg.equals("-listener")) {
-                i = handleArgListener(args, i);
-            } else if (arg.startsWith("-D")) {
-                i = handleArgDefine(args, i);
-            } else if (arg.equals("-logger")) {
-                i = handleArgLogger(args, i);
-            } else if (arg.equals("-inputhandler")) {
-                i = handleArgInputHandler(args, i);
-            } else if (arg.equals("-emacs") || arg.equals("-e")) {
-                emacsMode = true;
-            } else if (arg.equals("-projecthelp") || arg.equals("-p")) {
-                // set the flag to display the targets and quit
-                projectHelp = true;
-            } else if (arg.equals("-find") || arg.equals("-s")) {
-                searchForFile = true;
-                // eat up next arg if present, default to build.xml
-                if (i < args.length - 1) {
-                    searchForThis = args[++i];
-                }
-            } else if (arg.startsWith("-propertyfile")) {
-                i = handleArgPropertyFile(args, i);
-            } else if (arg.equals("-k") || arg.equals("-keep-going")) {
-                keepGoingMode = true;
-            } else if (arg.equals("-nice")) {
-                i = handleArgNice(args, i);
-            } else if (LAUNCH_COMMANDS.contains(arg)) {
-                //catch script/ant mismatch with a meaningful message
-                //we could ignore it, but there are likely to be other
-                //version problems, so we stamp down on the configuration now
-                String msg = "Ant's Main method is being handed "
-                        + "an option " + arg + " that is only for the launcher class."
-                        + "\nThis can be caused by a version mismatch between "
-                        + "the ant script/.bat file and Ant itself.";
-                throw new BuildException(msg);
-            } else if (arg.equals("-autoproxy")) {
-                proxy = true;
-            } else if (arg.equals("-breakAt")) {
-            	breakAt = args[++i];
-            } else if (arg.startsWith("-")) {
-                // we don't have any more args to recognize!
-                String msg = "Unknown argument: " + arg;
-                System.err.println(msg);
-                printUsage();
-                throw new BuildException("");
-            } else {
-                // if it's no other arg, it may be the target
-                targets.addElement(arg);
-            }
-        }
-
-        if (msgOutputLevel >= Project.MSG_VERBOSE || justPrintVersion) {
-            printVersion(msgOutputLevel);
-        }
-
-        if (justPrintUsage || justPrintVersion || justPrintDiagnostics) {
-            if (justPrintUsage) {
-                printUsage();
-            }
-            if (justPrintDiagnostics) {
-                Diagnostics.doReport(System.out, msgOutputLevel);
-            }
-            return;
-        }
-
-        // if buildFile was not specified on the command line,
-        if (buildFile == null) {
-            // but -find then search for it
-            if (searchForFile) {
-                if (searchForThis != null) {
-                    buildFile = findBuildFile(System.getProperty("user.dir"), searchForThis);
-                    if (buildFile == null) {
-                        throw new BuildException("Could not locate a build file!");
-                    }
-                } else {
-                    // no search file specified: so search an existing default file
-                    Iterator it = ProjectHelperRepository.getInstance().getHelpers();
-                    do {
-                        ProjectHelper helper = (ProjectHelper) it.next();
-                        searchForThis = helper.getDefaultBuildFile();
-                        if (msgOutputLevel >= Project.MSG_VERBOSE) {
-                            System.out.println("Searching the default build file: " + searchForThis);
-                        }
-                        buildFile = findBuildFile(System.getProperty("user.dir"), searchForThis);
-                    } while (buildFile == null && it.hasNext());
-                    if (buildFile == null) {
-                        throw new BuildException("Could not locate a build file!");
-                    }
-                }
-            } else {
-                // no build file specified: so search an existing default file
-                Iterator it = ProjectHelperRepository.getInstance().getHelpers();
-                do {
-                    ProjectHelper helper = (ProjectHelper) it.next();
-                    buildFile = new File(helper.getDefaultBuildFile());
-                    if (msgOutputLevel >= Project.MSG_VERBOSE) {
-                        System.out.println("Trying the default build file: " + buildFile);
-                    }
-                } while (!buildFile.exists() && it.hasNext());
-            }
-        }
-
-        // make sure buildfile exists
-        if (!buildFile.exists()) {
-            System.out.println("Buildfile: " + buildFile + " does not exist!");
-            throw new BuildException("Build failed");
-        }
-
-        // make sure it's not a directory (this falls into the ultra
-        // paranoid lets check everything category
-
-        if (buildFile.isDirectory()) {
-            System.out.println("What? Buildfile: " + buildFile + " is a dir!");
-            throw new BuildException("Build failed");
-        }
-
-        // Normalize buildFile for re-import detection
-        buildFile =
-            FileUtils.getFileUtils().normalize(buildFile.getAbsolutePath());
-
-        // Load the property files specified by -propertyfile
-        loadPropertyFiles();
-
-        if (msgOutputLevel >= Project.MSG_INFO) {
-            System.out.println("Buildfile: " + buildFile);
-        }
-
-        if (logTo != null) {
-            out = logTo;
-            err = logTo;
-            System.setOut(out);
-            System.setErr(err);
-        }
-        readyToRun = true;
-    }
-
-    // --------------------------------------------------------
-    //    Methods for handling the command line arguments
-    // --------------------------------------------------------
-
-    /** Handle the -buildfile, -file, -f argument */
-    private int handleArgBuildFile(String[] args, int pos) {
-        try {
-            buildFile = new File(
-                args[++pos].replace('/', File.separatorChar));
-        } catch (ArrayIndexOutOfBoundsException aioobe) {
-            throw new BuildException(
-                "You must specify a buildfile when using the -buildfile argument");
-        }
-        return pos;
-    }
-
-    /** Handle -listener argument */
-    private int handleArgListener(String[] args, int pos) {
-        try {
-            listeners.addElement(args[pos + 1]);
-            pos++;
-        } catch (ArrayIndexOutOfBoundsException aioobe) {
-            String msg = "You must specify a classname when "
-                + "using the -listener argument";
-            throw new BuildException(msg);
-        }
-        return pos;
-    }
-
-    /** Handler -D argument */
-    private int handleArgDefine(String[] args, int argPos) {
-        /* Interestingly enough, we get to here when a user
-         * uses -Dname=value. However, in some cases, the OS
-         * goes ahead and parses this out to args
-         *   {"-Dname", "value"}
-         * so instead of parsing on "=", we just make the "-D"
-         * characters go away and skip one argument forward.
-         *
-         * I don't know how to predict when the JDK is going
-         * to help or not, so we simply look for the equals sign.
-         */
-        String arg = args[argPos];
-        String name = arg.substring(2, arg.length());
-        String value = null;
-        int posEq = name.indexOf("=");
-        if (posEq > 0) {
-            value = name.substring(posEq + 1);
-            name = name.substring(0, posEq);
-        } else if (argPos < args.length - 1) {
-            value = args[++argPos];
-        } else {
-            throw new BuildException("Missing value for property "
-                                     + name);
-        }
-        definedProps.put(name, value);
-        return argPos;
-    }
-
-    /** Handle the -logger argument. */
-    private int handleArgLogger(String[] args, int pos) {
-        if (loggerClassname != null) {
-            throw new BuildException(
-                "Only one logger class may be specified.");
-        }
-        try {
-            loggerClassname = args[++pos];
-        } catch (ArrayIndexOutOfBoundsException aioobe) {
-            throw new BuildException(
-                "You must specify a classname when using the -logger argument");
-        }
-        return pos;
-    }
-
-    /** Handle the -inputhandler argument. */
-    private int handleArgInputHandler(String[] args, int pos) {
-        if (inputHandlerClassname != null) {
-            throw new BuildException("Only one input handler class may "
-                                     + "be specified.");
-        }
-        try {
-            inputHandlerClassname = args[++pos];
-        } catch (ArrayIndexOutOfBoundsException aioobe) {
-            throw new BuildException("You must specify a classname when"
-                                     + " using the -inputhandler"
-                                     + " argument");
-        }
-        return pos;
-    }
-
-    /** Handle the -propertyfile argument. */
-    private int handleArgPropertyFile(String[] args, int pos) {
-        try {
-            propertyFiles.addElement(args[++pos]);
-        } catch (ArrayIndexOutOfBoundsException aioobe) {
-            String msg = "You must specify a property filename when "
-                + "using the -propertyfile argument";
-            throw new BuildException(msg);
-        }
-        return pos;
-    }
-
-    /** Handle the -nice argument. */
-    private int handleArgNice(String[] args, int pos) {
-        try {
-            threadPriority = Integer.decode(args[++pos]);
-        } catch (ArrayIndexOutOfBoundsException aioobe) {
-            throw new BuildException(
-                "You must supply a niceness value (1-10)"
-                + " after the -nice option");
-        } catch (NumberFormatException e) {
-            throw new BuildException("Unrecognized niceness value: "
-                                     + args[pos]);
-        }
-
-        if (threadPriority.intValue() < Thread.MIN_PRIORITY
-            || threadPriority.intValue() > Thread.MAX_PRIORITY) {
-            throw new BuildException(
-                "Niceness value is out of the range 1-10");
-        }
-        return pos;
-    }
-
-    // --------------------------------------------------------
-    //    other methods
-    // --------------------------------------------------------
-
-    /** Load the property files specified by -propertyfile */
-    private void loadPropertyFiles() {
-        for (int propertyFileIndex = 0;
-             propertyFileIndex < propertyFiles.size();
-             propertyFileIndex++) {
-            String filename
-                = (String) propertyFiles.elementAt(propertyFileIndex);
-            Properties props = new Properties();
-            FileInputStream fis = null;
-            try {
-                fis = new FileInputStream(filename);
-                props.load(fis);
-            } catch (IOException e) {
-                System.out.println("Could not load property file "
-                                   + filename + ": " + e.getMessage());
-            } finally {
-                FileUtils.close(fis);
-            }
-
-            // ensure that -D properties take precedence
-            Enumeration propertyNames = props.propertyNames();
-            while (propertyNames.hasMoreElements()) {
-                String name = (String) propertyNames.nextElement();
-                if (definedProps.getProperty(name) == null) {
-                    definedProps.put(name, props.getProperty(name));
-                }
-            }
-        }
-    }
-
-    /**
-     * Helper to get the parent file for a given file.
-     * <p>
-     * Added to simulate File.getParentFile() from JDK 1.2.
-     * @deprecated since 1.6.x
-     *
-     * @param file   File to find parent of. Must not be <code>null</code>.
-     * @return       Parent file or null if none
-     */
-    private File getParentFile(File file) {
-        File parent = file.getParentFile();
-
-        if (parent != null && msgOutputLevel >= Project.MSG_VERBOSE) {
-            System.out.println("Searching in " + parent.getAbsolutePath());
-        }
-
-        return parent;
-    }
-
-    /**
-     * Search parent directories for the build file.
-     * <p>
-     * Takes the given target as a suffix to append to each
-     * parent directory in search of a build file.  Once the
-     * root of the file-system has been reached <code>null</code>
-     * is returned.
-     *
-     * @param start  Leaf directory of search.
-     *               Must not be <code>null</code>.
-     * @param suffix  Suffix filename to look for in parents.
-     *                Must not be <code>null</code>.
-     *
-     * @return A handle to the build file if one is found, <code>null</code> if not
-     */
-    private File findBuildFile(String start, String suffix) {
-        if (msgOutputLevel >= Project.MSG_INFO) {
-            System.out.println("Searching for " + suffix + " ...");
-        }
-
-        File parent = new File(new File(start).getAbsolutePath());
-        File file = new File(parent, suffix);
-
-        // check if the target file exists in the current directory
-        while (!file.exists()) {
-            // change to parent directory
-            parent = getParentFile(parent);
-
-            // if parent is null, then we are at the root of the fs,
-            // complain that we can't find the build file.
-            if (parent == null) {
-                return null;
-            }
-
-            // refresh our file handle
-            file = new File(parent, suffix);
-        }
-
-        return file;
-    }
-
-    /**
-     * Executes the build. If the constructor for this instance failed
-     * (e.g. returned after issuing a warning), this method returns
-     * immediately.
-     *
-     * @param coreLoader The classloader to use to find core classes.
-     *                   May be <code>null</code>, in which case the
-     *                   system classloader is used.
-     *
-     * @exception BuildException if the build fails
-     */
-    private void runBuild(ClassLoader coreLoader) throws BuildException {
-
-        if (!readyToRun) {
-            return;
-        }
-
-        final Project project = new Project();
-        project.setCoreLoader(coreLoader);
-
-        Throwable error = null;
-
-        try {
-            addBuildListeners(project);
-            addInputHandler(project);
-
-            PrintStream savedErr = System.err;
-            PrintStream savedOut = System.out;
-            InputStream savedIn = System.in;
-
-            // use a system manager that prevents from System.exit()
-            SecurityManager oldsm = null;
-            oldsm = System.getSecurityManager();
-
-                //SecurityManager can not be installed here for backwards
-                //compatibility reasons (PD). Needs to be loaded prior to
-                //ant class if we are going to implement it.
-                //System.setSecurityManager(new NoExitSecurityManager());
-            try {
-                if (allowInput) {
-                    project.setDefaultInputStream(System.in);
-                }
-                System.setIn(new DemuxInputStream(project));
-                System.setOut(new PrintStream(new DemuxOutputStream(project, false)));
-                System.setErr(new PrintStream(new DemuxOutputStream(project, true)));
-
-
-                if (!projectHelp) {
-                    project.fireBuildStarted();
-                }
-
-                // set the thread priorities
-                if (threadPriority != null) {
-                    try {
-                        project.log("Setting Ant's thread priority to "
-                                + threadPriority, Project.MSG_VERBOSE);
-                        Thread.currentThread().setPriority(threadPriority.intValue());
-                    } catch (SecurityException swallowed) {
-                        //we cannot set the priority here.
-                        project.log("A security manager refused to set the -nice value");
-                    }
-                }
-
-
-
-                project.init();
-                project.setBreakAt(breakAt);
-                // resolve properties
-                PropertyHelper propertyHelper
-                    = (PropertyHelper) PropertyHelper.getPropertyHelper(project);
-                HashMap props = new HashMap(definedProps);
-                new ResolvePropertyMap(project, propertyHelper,
-                                       propertyHelper.getExpanders())
-                    .resolveAllProperties(props, null, false);
-
-                // set user-define properties
-                for (Iterator e = props.entrySet().iterator(); e.hasNext(); ) {
-                    Map.Entry ent = (Map.Entry) e.next();
-                    String arg = (String) ent.getKey();
-                    Object value = ent.getValue();
-                    project.setUserProperty(arg, String.valueOf(value));
-                }
-
-                project.setUserProperty(MagicNames.ANT_FILE,
-                                        buildFile.getAbsolutePath());
-                project.setUserProperty(MagicNames.ANT_FILE_TYPE,
-                                        MagicNames.ANT_FILE_TYPE_FILE);
-
-                project.setKeepGoingMode(keepGoingMode);
-                if (proxy) {
-                    //proxy setup if enabled
-                    ProxySetup proxySetup = new ProxySetup(project);
-                    proxySetup.enableProxies();
-                }
-
-                ProjectHelper.configureProject(project, buildFile);
-
-                if (projectHelp) {
-                    printDescription(project);
-                    printTargets(project, msgOutputLevel > Project.MSG_INFO,
-                            msgOutputLevel > Project.MSG_VERBOSE);
-                    return;
-                }
-
-                // make sure that we have a target to execute
-                if (targets.size() == 0) {
-                    if (project.getDefaultTarget() != null) {
-                        targets.addElement(project.getDefaultTarget());
-                    }
-                }
-
-                project.executeTargets(targets);
-            } finally {
-                // put back the original security manager
-                //The following will never eval to true. (PD)
-                if (oldsm != null) {
-                    System.setSecurityManager(oldsm);
-                }
-
-                System.setOut(savedOut);
-                System.setErr(savedErr);
-                System.setIn(savedIn);
-            }
-        } catch (RuntimeException exc) {
-            error = exc;
-            throw exc;
-        } catch (Error e) {
-            error = e;
-            throw e;
-        } finally {
-            if (!projectHelp) {
-                try {
-                    project.fireBuildFinished(error);
-                } catch (Throwable t) {
-                    // yes, I know it is bad style to catch Throwable,
-                    // but if we don't, we lose valuable information
-                    System.err.println("Caught an exception while logging the"
-                                       + " end of the build.  Exception was:");
-                    t.printStackTrace();
-                    if (error != null) {
-                        System.err.println("There has been an error prior to"
-                                           + " that:");
-                        error.printStackTrace();
-                    }
-                    throw new BuildException(t);
-                }
-            } else if (error != null) {
-                project.log(error.toString(), Project.MSG_ERR);
-            }
-        }
-    }
-
-    /**
-     * Adds the listeners specified in the command line arguments,
-     * along with the default listener, to the specified project.
-     *
-     * @param project The project to add listeners to.
-     *                Must not be <code>null</code>.
-     */
-    protected void addBuildListeners(Project project) {
-
-        // Add the default listener
-        project.addBuildListener(createLogger());
-
-        final int count = listeners.size();
-        for (int i = 0; i < count; i++) {
-            String className = (String) listeners.elementAt(i);
-            BuildListener listener =
-                    (BuildListener) ClasspathUtils.newInstance(className,
-                            Main.class.getClassLoader(), BuildListener.class);
-            project.setProjectReference(listener);
-
-            project.addBuildListener(listener);
-        }
-    }
-
-    /**
-     * Creates the InputHandler and adds it to the project.
-     *
-     * @param project the project instance.
-     *
-     * @exception BuildException if a specified InputHandler
-     *                           implementation could not be loaded.
-     */
-    private void addInputHandler(Project project) throws BuildException {
-        InputHandler handler = null;
-        if (inputHandlerClassname == null) {
-            handler = new DefaultInputHandler();
-        } else {
-            handler = (InputHandler) ClasspathUtils.newInstance(
-                    inputHandlerClassname, Main.class.getClassLoader(),
-                    InputHandler.class);
-            project.setProjectReference(handler);
-        }
-        project.setInputHandler(handler);
-    }
-
-    // XXX: (Jon Skeet) Any reason for writing a message and then using a bare
-    // RuntimeException rather than just using a BuildException here? Is it
-    // in case the message could end up being written to no loggers (as the
-    // loggers could have failed to be created due to this failure)?
-    /**
-     * Creates the default build logger for sending build events to the ant
-     * log.
-     *
-     * @return the logger instance for this build.
-     */
-    private BuildLogger createLogger() {
-        BuildLogger logger = null;
-        if (loggerClassname != null) {
-            try {
-                logger = (BuildLogger) ClasspathUtils.newInstance(
-                        loggerClassname, Main.class.getClassLoader(),
-                        BuildLogger.class);
-            } catch (BuildException e) {
-                System.err.println("The specified logger class "
-                    + loggerClassname
-                    + " could not be used because " + e.getMessage());
-                throw new RuntimeException();
-            }
-        } else {
-            logger = new DefaultLogger();
-        }
-
-        logger.setMessageOutputLevel(msgOutputLevel);
-        logger.setOutputPrintStream(out);
-        logger.setErrorPrintStream(err);
-        logger.setEmacsMode(emacsMode);
-
-        return logger;
-    }
-
-    /**
-     * Prints the usage information for this class to <code>System.out</code>.
-     */
-    private static void printUsage() {
-        String lSep = System.getProperty("line.separator");
-        StringBuffer msg = new StringBuffer();
-        msg.append("ant [options] [target [target2 [target3] ...]]" + lSep);
-        msg.append("Options: " + lSep);
-        msg.append("  -help, -h              print this message" + lSep);
-        msg.append("  -projecthelp, -p       print project help information" + lSep);
-        msg.append("  -version               print the version information and exit" + lSep);
-        msg.append("  -diagnostics           print information that might be helpful to" + lSep);
-        msg.append("                         diagnose or report problems." + lSep);
-        msg.append("  -quiet, -q             be extra quiet" + lSep);
-        msg.append("  -verbose, -v           be extra verbose" + lSep);
-        msg.append("  -debug, -d             print debugging information" + lSep);
-        msg.append("  -emacs, -e             produce logging information without adornments"
-                   + lSep);
-        msg.append("  -lib <path>            specifies a path to search for jars and classes"
-                   + lSep);
-        msg.append("  -logfile <file>        use given file for log" + lSep);
-        msg.append("    -l     <file>                ''" + lSep);
-        msg.append("  -logger <classname>    the class which is to perform logging" + lSep);
-        msg.append("  -listener <classname>  add an instance of class as a project listener"
-                   + lSep);
-        msg.append("  -noinput               do not allow interactive input" + lSep);
-        msg.append("  -buildfile <file>      use given buildfile" + lSep);
-        msg.append("    -file    <file>              ''" + lSep);
-        msg.append("    -f       <file>              ''" + lSep);
-        msg.append("  -D<property>=<value>   use value for given property" + lSep);
-        msg.append("  -keep-going, -k        execute all targets that do not depend" + lSep);
-        msg.append("                         on failed target(s)" + lSep);
-        msg.append("  -propertyfile <name>   load all properties from file with -D" + lSep);
-        msg.append("                         properties taking precedence" + lSep);
-        msg.append("  -inputhandler <class>  the class which will handle input requests" + lSep);
-        msg.append("  -find <file>           (s)earch for buildfile towards the root of" + lSep);
-        msg.append("    -s  <file>           the filesystem and use it" + lSep);
-        msg.append("  -nice  number          A niceness value for the main thread:" + lSep
-                   + "                         1 (lowest) to 10 (highest); 5 is the default"
-                   + lSep);
-        msg.append("  -nouserlib             Run ant without using the jar files from" + lSep
-                   + "                         ${user.home}/.ant/lib" + lSep);
-        msg.append("  -noclasspath           Run ant without using CLASSPATH" + lSep);
-        msg.append("  -autoproxy             Java1.5+: use the OS proxy settings"
-                + lSep);
-        msg.append("  -main <class>          override Ant's normal entry point");
-        System.out.println(msg.toString());
-    }
-
-    /**
-     * Prints the Ant version information to <code>System.out</code>.
-     *
-     * @exception BuildException if the version information is unavailable
-     */
-    private static void printVersion(int logLevel) throws BuildException {
-        System.out.println(getAntVersion());
-    }
-
-    /**
-     * Cache of the Ant version information when it has been loaded.
-     */
-    private static String antVersion = null;
-
-    /**
-     * Returns the Ant version information, if available. Once the information
-     * has been loaded once, it's cached and returned from the cache on future
-     * calls.
-     *
-     * @return the Ant version information as a String
-     *         (always non-<code>null</code>)
-     *
-     * @exception BuildException if the version information is unavailable
-     */
-    public static synchronized String getAntVersion() throws BuildException {
-        if (antVersion == null) {
-            try {
-                Properties props = new Properties();
-                InputStream in =
-                    Main.class.getResourceAsStream("/org/apache/tools/ant/version.txt");
-                props.load(in);
-                in.close();
-
-                StringBuffer msg = new StringBuffer();
-                msg.append("Apache Ant(TM) version ");
-                msg.append(props.getProperty("VERSION"));
-                msg.append(" compiled on ");
-                msg.append(props.getProperty("DATE"));
-                antVersion = msg.toString();
-            } catch (IOException ioe) {
-                throw new BuildException("Could not load the version information:"
-                                         + ioe.getMessage());
-            } catch (NullPointerException npe) {
-                throw new BuildException("Could not load the version information.");
-            }
-        }
-        return antVersion;
-    }
-
-     /**
-      * Prints the description of a project (if there is one) to
-      * <code>System.out</code>.
-      *
-      * @param project The project to display a description of.
-      *                Must not be <code>null</code>.
-      */
-    private static void printDescription(Project project) {
-       if (project.getDescription() != null) {
-          project.log(project.getDescription());
-       }
-    }
-
-    /**
-     * Targets in imported files with a project name
-     * and not overloaded by the main build file will
-     * be in the target map twice. This method
-     * removes the duplicate target.
-     * @param targets the targets to filter.
-     * @return the filtered targets.
-     */
-    private static Map removeDuplicateTargets(Map targets) {
-        Map locationMap = new HashMap();
-        for (Iterator i = targets.entrySet().iterator(); i.hasNext();) {
-            Map.Entry entry = (Map.Entry) i.next();
-            String name = (String) entry.getKey();
-            Target target = (Target) entry.getValue();
-            Target otherTarget =
-                (Target) locationMap.get(target.getLocation());
-            // Place this entry in the location map if
-            //  a) location is not in the map
-            //  b) location is in map, but it's name is longer
-            //     (an imported target will have a name. prefix)
-            if (otherTarget == null
-                || otherTarget.getName().length() > name.length()) {
-                locationMap.put(
-                    target.getLocation(), target); // Smallest name wins
-            }
-        }
-        Map ret = new HashMap();
-        for (Iterator i = locationMap.values().iterator(); i.hasNext();) {
-            Target target = (Target) i.next();
-            ret.put(target.getName(), target);
-        }
-        return ret;
-    }
-
-    /**
-     * Prints a list of all targets in the specified project to
-     * <code>System.out</code>, optionally including subtargets.
-     *
-     * @param project The project to display a description of.
-     *                Must not be <code>null</code>.
-     * @param printSubTargets Whether or not subtarget names should also be
-     *                        printed.
-     */
-    private static void printTargets(Project project, boolean printSubTargets,
-            boolean printDependencies) {
-        // find the target with the longest name
-        int maxLength = 0;
-        Map ptargets = removeDuplicateTargets(project.getTargets());
-        String targetName;
-        String targetDescription;
-        Target currentTarget;
-        // split the targets in top-level and sub-targets depending
-        // on the presence of a description
-        Vector topNames = new Vector();
-        Vector topDescriptions = new Vector();
-        Vector/*<Enumeration<String>>*/ topDependencies = new Vector();
-        Vector subNames = new Vector();
-        Vector/*<Enumeration<String>>*/ subDependencies = new Vector();
-
-        for (Iterator i = ptargets.values().iterator(); i.hasNext();) {
-            currentTarget = (Target) i.next();
-            targetName = currentTarget.getName();
-            if (targetName.equals("")) {
-                continue;
-            }
-            targetDescription = currentTarget.getDescription();
-            // maintain a sorted list of targets
-            if (targetDescription == null) {
-                int pos = findTargetPosition(subNames, targetName);
-                subNames.insertElementAt(targetName, pos);
-                if (printDependencies) {
-                    subDependencies.insertElementAt(currentTarget.getDependencies(), pos);
-                }
-            } else {
-                int pos = findTargetPosition(topNames, targetName);
-                topNames.insertElementAt(targetName, pos);
-                topDescriptions.insertElementAt(targetDescription, pos);
-                if (targetName.length() > maxLength) {
-                    maxLength = targetName.length();
-                }
-                if (printDependencies) {
-                    topDependencies.insertElementAt(currentTarget.getDependencies(), pos);
-                }
-            }
-        }
-
-        printTargets(project, topNames, topDescriptions, topDependencies,
-                "Main targets:", maxLength);
-        //if there were no main targets, we list all subtargets
-        //as it means nothing has a description
-        if (topNames.size() == 0) {
-            printSubTargets = true;
-        }
-        if (printSubTargets) {
-            printTargets(project, subNames, null, subDependencies, "Other targets:", 0);
-        }
-
-        String defaultTarget = project.getDefaultTarget();
-        if (defaultTarget != null && !"".equals(defaultTarget)) {
-            // shouldn't need to check but...
-            project.log("Default target: " + defaultTarget);
-        }
-    }
-
-    /**
-     * Searches for the correct place to insert a name into a list so as
-     * to keep the list sorted alphabetically.
-     *
-     * @param names The current list of names. Must not be <code>null</code>.
-     * @param name  The name to find a place for.
-     *              Must not be <code>null</code>.
-     *
-     * @return the correct place in the list for the given name
-     */
-    private static int findTargetPosition(Vector names, String name) {
-        final int size = names.size();
-        int res = size;
-        for (int i = 0; i < size && res == size; i++) {
-            if (name.compareTo((String) names.elementAt(i)) < 0) {
-                res = i;
-            }
-        }
-        return res;
-    }
-
-    /**
-     * Writes a formatted list of target names to <code>System.out</code>
-     * with an optional description.
-     *
-     *
-     * @param project the project instance.
-     * @param names The names to be printed.
-     *              Must not be <code>null</code>.
-     * @param descriptions The associated target descriptions.
-     *                     May be <code>null</code>, in which case
-     *                     no descriptions are displayed.
-     *                     If non-<code>null</code>, this should have
-     *                     as many elements as <code>names</code>.
-     * @param topDependencies The list of dependencies for each target.
-     *                        The dependencies are listed as a non null
-     *                        enumeration of String.
-     * @param heading The heading to display.
-     *                Should not be <code>null</code>.
-     * @param maxlen The maximum length of the names of the targets.
-     *               If descriptions are given, they are padded to this
-     *               position so they line up (so long as the names really
-     *               <i>are</i> shorter than this).
-     */
-    private static void printTargets(Project project, Vector names,
-                                     Vector descriptions, Vector dependencies,
-                                     String heading,
-                                     int maxlen) {
-        // now, start printing the targets and their descriptions
-        String lSep = System.getProperty("line.separator");
-        // got a bit annoyed that I couldn't find a pad function
-        String spaces = "    ";
-        while (spaces.length() <= maxlen) {
-            spaces += spaces;
-        }
-        StringBuffer msg = new StringBuffer();
-        msg.append(heading + lSep + lSep);
-        final int size = names.size();
-        for (int i = 0; i < size; i++) {
-            msg.append(" ");
-            msg.append(names.elementAt(i));
-            if (descriptions != null) {
-                msg.append(
-                    spaces.substring(0, maxlen - ((String) names.elementAt(i)).length() + 2));
-                msg.append(descriptions.elementAt(i));
-            }
-            msg.append(lSep);
-            if (!dependencies.isEmpty()) {
-                Enumeration deps = (Enumeration) dependencies.elementAt(i);
-                if (deps.hasMoreElements()) {
-                    msg.append("   depends on: ");
-                    while (deps.hasMoreElements()) {
-                        msg.append(deps.nextElement());
-                        if (deps.hasMoreElements()) {
-                            msg.append(", ");
-                        }
-                    }
-                    msg.append(lSep);                
-                }
-            }
-        }
-        project.log(msg.toString(), Project.MSG_WARN);
-    }
-}
diff --git a/command-line-debugger/src/main/org/apache/tools/ant/Project.java b/command-line-debugger/src/main/org/apache/tools/ant/Project.java
deleted file mode 100644
index ddaee39..0000000
--- a/command-line-debugger/src/main/org/apache/tools/ant/Project.java
+++ /dev/null
@@ -1,2489 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-package org.apache.tools.ant;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.EOFException;
-import java.io.InputStream;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Properties;
-import java.util.Stack;
-import java.util.Vector;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.WeakHashMap;
-import org.apache.tools.ant.input.DefaultInputHandler;
-import org.apache.tools.ant.input.InputHandler;
-import org.apache.tools.ant.helper.DefaultExecutor;
-import org.apache.tools.ant.types.FilterSet;
-import org.apache.tools.ant.types.FilterSetCollection;
-import org.apache.tools.ant.types.Description;
-import org.apache.tools.ant.types.Path;
-import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.types.ResourceFactory;
-import org.apache.tools.ant.types.resources.FileResource;
-import org.apache.tools.ant.util.CollectionUtils;
-import org.apache.tools.ant.util.FileUtils;
-import org.apache.tools.ant.util.JavaEnvUtils;
-import org.apache.tools.ant.util.StringUtils;
-import org.apache.tools.ant.util.VectorSet;
-
-/**
- * Central representation of an Ant project. This class defines an
- * Ant project with all of its targets, tasks and various other
- * properties. It also provides the mechanism to kick off a build using
- * a particular target name.
- * <p>
- * This class also encapsulates methods which allow files to be referred
- * to using abstract path names which are translated to native system
- * file paths at runtime.
- *
- */
-public class Project implements ResourceFactory {
-    /** Message priority of &quot;error&quot;. */
-    public static final int MSG_ERR = 0;
-    /** Message priority of &quot;warning&quot;. */
-    public static final int MSG_WARN = 1;
-    /** Message priority of &quot;information&quot;. */
-    public static final int MSG_INFO = 2;
-    /** Message priority of &quot;verbose&quot;. */
-    public static final int MSG_VERBOSE = 3;
-    /** Message priority of &quot;debug&quot;. */
-    public static final int MSG_DEBUG = 4;
-
-    /**
-     * Constant for the &quot;visiting&quot; state, used when
-     * traversing a DFS of target dependencies.
-     */
-    private static final String VISITING = "VISITING";
-    /**
-     * Constant for the &quot;visited&quot; state, used when
-     * traversing a DFS of target dependencies.
-     */
-    private static final String VISITED = "VISITED";
-
-    /**
-     * Version constant for Java 1.0 .
-     *
-     * @deprecated since 1.5.x.
-     *             Use {@link JavaEnvUtils#JAVA_1_0} instead.
-     */
-    public static final String JAVA_1_0 = JavaEnvUtils.JAVA_1_0;
-    /**
-     * Version constant for Java 1.1 .
-     *
-     * @deprecated since 1.5.x.
-     *             Use {@link JavaEnvUtils#JAVA_1_1} instead.
-     */
-    public static final String JAVA_1_1 = JavaEnvUtils.JAVA_1_1;
-    /**
-     * Version constant for Java 1.2 .
-     *
-     * @deprecated since 1.5.x.
-     *             Use {@link JavaEnvUtils#JAVA_1_2} instead.
-     */
-    public static final String JAVA_1_2 = JavaEnvUtils.JAVA_1_2;
-    /**
-     * Version constant for Java 1.3 .
-     *
-     * @deprecated since 1.5.x.
-     *             Use {@link JavaEnvUtils#JAVA_1_3} instead.
-     */
-    public static final String JAVA_1_3 = JavaEnvUtils.JAVA_1_3;
-    /**
-     * Version constant for Java 1.4 .
-     *
-     * @deprecated since 1.5.x.
-     *             Use {@link JavaEnvUtils#JAVA_1_4} instead.
-     */
-    public static final String JAVA_1_4 = JavaEnvUtils.JAVA_1_4;
-
-    /** Default filter start token. */
-    public static final String TOKEN_START = FilterSet.DEFAULT_TOKEN_START;
-    /** Default filter end token. */
-    public static final String TOKEN_END = FilterSet.DEFAULT_TOKEN_END;
-
-    /** Instance of a utility class to use for file operations. */
-    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-
-    /** Name of this project. */
-    private String name;
-    /** Description for this project (if any). */
-    private String description;
-
-
-    /** Map of references within the project (paths etc) (String to Object). */
-    private Hashtable references = new AntRefTable();
-
-    /** Map of id references - used for indicating broken build files */
-    private HashMap idReferences = new HashMap();
-
-    /** the parent project for old id resolution (if inheritreferences is set) */
-    private Project parentIdProject = null;
-
-    /** Name of the project's default target. */
-    private String defaultTarget;
-
-    /** Map from target names to targets (String to Target). */
-    private Hashtable targets = new Hashtable();
-    /** Set of global filters. */
-    private FilterSet globalFilterSet = new FilterSet();
-    {
-        // Initialize the globalFileSet's project
-        globalFilterSet.setProject(this);
-    }
-
-    /**
-     * Wrapper around globalFilterSet. This collection only ever
-     * contains one FilterSet, but the wrapper is needed in order to
-     * make it easier to use the FileUtils interface.
-     */
-    private FilterSetCollection globalFilters
-        = new FilterSetCollection(globalFilterSet);
-
-    /** Project base directory. */
-    private File baseDir;
-
-    /** lock object used when adding/removing listeners */
-    private final Object listenersLock = new Object();
-
-    /** List of listeners to notify of build events. */
-    private volatile BuildListener[] listeners = new BuildListener[0];
-
-    /** for each thread, record whether it is currently executing
-        messageLogged */
-    private final ThreadLocal isLoggingMessage = new ThreadLocal() {
-            protected Object initialValue() {
-                return Boolean.FALSE;
-            }
-        };
-
-    /**
-     * The Ant core classloader--may be <code>null</code> if using
-     * parent classloader.
-     */
-    private ClassLoader coreLoader = null;
-
-    /** Records the latest task to be executed on a thread. */
-    private final Map/*<Thread,Task>*/ threadTasks =
-        Collections.synchronizedMap(new WeakHashMap());
-
-    /** Records the latest task to be executed on a thread group. */
-    private final Map/*<ThreadGroup,Task>*/ threadGroupTasks
-        = Collections.synchronizedMap(new WeakHashMap());
-
-    /**
-     * Called to handle any input requests.
-     */
-    private InputHandler inputHandler = null;
-
-    /**
-     * The default input stream used to read any input.
-     */
-    private InputStream defaultInputStream = null;
-
-    /**
-     * Keep going flag.
-     */
-    private boolean keepGoingMode = false;
-
-    /**
-     * Contains the target to break the execution at.
-     */
-	protected String breakAt;
-	
-	public void setBreakAt(String breakAt) {
-		this.breakAt = breakAt;
-	}
-	
-	public String getBreakAt() {
-		return breakAt;
-	}
-	
-    /**
-     * Set the input handler.
-     *
-     * @param handler the InputHandler instance to use for gathering input.
-     */
-    public void setInputHandler(InputHandler handler) {
-        inputHandler = handler;
-    }
-
-    /**
-     * Set the default System input stream. Normally this stream is set to
-     * System.in. This inputStream is used when no task input redirection is
-     * being performed.
-     *
-     * @param defaultInputStream the default input stream to use when input
-     *        is requested.
-     * @since Ant 1.6
-     */
-    public void setDefaultInputStream(InputStream defaultInputStream) {
-        this.defaultInputStream = defaultInputStream;
-    }
-
-    /**
-     * Get this project's input stream.
-     *
-     * @return the InputStream instance in use by this Project instance to
-     * read input.
-     */
-    public InputStream getDefaultInputStream() {
-        return defaultInputStream;
-    }
-
-    /**
-     * Retrieve the current input handler.
-     *
-     * @return the InputHandler instance currently in place for the project
-     *         instance.
-     */
-    public InputHandler getInputHandler() {
-        return inputHandler;
-    }
-
-    /**
-     * Create a new Ant project.
-     */
-    public Project() {
-        inputHandler = new DefaultInputHandler();
-    }
-
-    /**
-     * Create and initialize a subproject. By default the subproject will be of
-     * the same type as its parent. If a no-arg constructor is unavailable, the
-     * <code>Project</code> class will be used.
-     * @return a Project instance configured as a subproject of this Project.
-     * @since Ant 1.7
-     */
-    public Project createSubProject() {
-        Project subProject = null;
-        try {
-            subProject = (Project) (getClass().newInstance());
-        } catch (Exception e) {
-            subProject = new Project();
-        }
-        initSubProject(subProject);
-        return subProject;
-    }
-
-    /**
-     * Initialize a subproject.
-     * @param subProject the subproject to initialize.
-     */
-    public void initSubProject(Project subProject) {
-        ComponentHelper.getComponentHelper(subProject)
-            .initSubProject(ComponentHelper.getComponentHelper(this));
-        subProject.setDefaultInputStream(getDefaultInputStream());
-        subProject.setKeepGoingMode(this.isKeepGoingMode());
-        subProject.setExecutor(getExecutor().getSubProjectExecutor());
-    }
-
-    /**
-     * Initialise the project.
-     *
-     * This involves setting the default task definitions and loading the
-     * system properties.
-     *
-     * @exception BuildException if the default task list cannot be loaded.
-     */
-    public void init() throws BuildException {
-        initProperties();
-
-        ComponentHelper.getComponentHelper(this).initDefaultDefinitions();
-    }
-
-    /**
-     * Initializes the properties.
-     * @exception BuildException if an vital property could not be set.
-     * @since Ant 1.7
-     */
-    public void initProperties() throws BuildException {
-        setJavaVersionProperty();
-        setSystemProperties();
-        setPropertyInternal(MagicNames.ANT_VERSION, Main.getAntVersion());
-        setAntLib();
-    }
-
-    /**
-     * Set a property to the location of ant.jar.
-     * Use the locator to find the location of the Project.class, and
-     * if this is not null, set the property {@link MagicNames#ANT_LIB}
-     * to the result
-     */
-    private void setAntLib() {
-        File antlib = org.apache.tools.ant.launch.Locator.getClassSource(
-            Project.class);
-        if (antlib != null) {
-            setPropertyInternal(MagicNames.ANT_LIB, antlib.getAbsolutePath());
-        }
-    }
-    /**
-     * Factory method to create a class loader for loading classes from
-     * a given path.
-     *
-     * @param path the path from which classes are to be loaded.
-     *
-     * @return an appropriate classloader.
-     */
-    public AntClassLoader createClassLoader(Path path) {
-        return AntClassLoader
-            .newAntClassLoader(getClass().getClassLoader(), this, path, true);
-    }
-
-    /**
-     * Factory method to create a class loader for loading classes from
-     * a given path.
-     *
-     * @param parent the parent classloader for the new loader.
-     * @param path the path from which classes are to be loaded.
-     *
-     * @return an appropriate classloader.
-     */
-    public AntClassLoader createClassLoader(
-        ClassLoader parent, Path path) {
-        return AntClassLoader.newAntClassLoader(parent, this, path, true);
-    }
-
-    /**
-     * Set the core classloader for the project. If a <code>null</code>
-     * classloader is specified, the parent classloader should be used.
-     *
-     * @param coreLoader The classloader to use for the project.
-     *                   May be <code>null</code>.
-     */
-    public void setCoreLoader(ClassLoader coreLoader) {
-        this.coreLoader = coreLoader;
-    }
-
-    /**
-     * Return the core classloader to use for this project.
-     * This may be <code>null</code>, indicating that
-     * the parent classloader should be used.
-     *
-     * @return the core classloader to use for this project.
-     *
-     */
-    public ClassLoader getCoreLoader() {
-        return coreLoader;
-    }
-
-    /**
-     * Add a build listener to the list. This listener will
-     * be notified of build events for this project.
-     *
-     * @param listener The listener to add to the list.
-     *                 Must not be <code>null</code>.
-     */
-    public void addBuildListener(BuildListener listener) {
-        synchronized (listenersLock) {
-            // If the listeners already has this listener, do nothing
-            for (int i = 0; i < listeners.length; i++) {
-                if (listeners[i] == listener) {
-                    return;
-                }
-            }
-            // copy on write semantics
-            BuildListener[] newListeners =
-                new BuildListener[listeners.length + 1];
-            System.arraycopy(listeners, 0, newListeners, 0, listeners.length);
-            newListeners[listeners.length] = listener;
-            listeners = newListeners;
-        }
-    }
-
-    /**
-     * Remove a build listener from the list. This listener
-     * will no longer be notified of build events for this project.
-     *
-     * @param listener The listener to remove from the list.
-     *                 Should not be <code>null</code>.
-     */
-    public void removeBuildListener(BuildListener listener) {
-        synchronized (listenersLock) {
-            // copy on write semantics
-            for (int i = 0; i < listeners.length; i++) {
-                if (listeners[i] == listener) {
-                    BuildListener[] newListeners =
-                        new BuildListener[listeners.length - 1];
-                    System.arraycopy(listeners, 0, newListeners, 0, i);
-                    System.arraycopy(listeners, i + 1, newListeners, i,
-                                     listeners.length - i - 1);
-                    listeners = newListeners;
-                    break;
-                }
-            }
-        }
-    }
-
-    /**
-     * Return a copy of the list of build listeners for the project.
-     * 
-     * @return a list of build listeners for the project
-     */
-    public Vector getBuildListeners() {
-        synchronized (listenersLock) {
-            Vector r = new Vector(listeners.length);
-            for (int i = 0; i < listeners.length; i++) {
-                r.add(listeners[i]);
-            }
-            return r;
-        }
-    }
-
-    /**
-     * Write a message to the log with the default log level
-     * of MSG_INFO .
-     * @param message The text to log. Should not be <code>null</code>.
-     */
-
-    public void log(String message) {
-        log(message, MSG_INFO);
-    }
-
-    /**
-     * Write a project level message to the log with the given log level.
-     * @param message The text to log. Should not be <code>null</code>.
-     * @param msgLevel The log priority level to use.
-     */
-    public void log(String message, int msgLevel) {
-        log(message, null, msgLevel);
-    }
-
-    /**
-     * Write a project level message to the log with the given log level.
-     * @param message The text to log. Should not be <code>null</code>.
-     * @param throwable The exception causing this log, may be <code>null</code>.
-     * @param msgLevel The log priority level to use.
-     * @since 1.7
-     */
-    public void log(String message, Throwable throwable, int msgLevel) {
-        fireMessageLogged(this, message, throwable, msgLevel);
-    }
-
-    /**
-     * Write a task level message to the log with the given log level.
-     * @param task The task to use in the log. Must not be <code>null</code>.
-     * @param message The text to log. Should not be <code>null</code>.
-     * @param msgLevel The log priority level to use.
-     */
-    public void log(Task task, String message, int msgLevel) {
-        fireMessageLogged(task, message, null, msgLevel);
-    }
-
-    /**
-     * Write a task level message to the log with the given log level.
-     * @param task The task to use in the log. Must not be <code>null</code>.
-     * @param message The text to log. Should not be <code>null</code>.
-     * @param throwable The exception causing this log, may be <code>null</code>.
-     * @param msgLevel The log priority level to use.
-     * @since 1.7
-     */
-    public void log(Task task, String message, Throwable throwable, int msgLevel) {
-        fireMessageLogged(task, message, throwable, msgLevel);
-    }
-
-    /**
-     * Write a target level message to the log with the given log level.
-     * @param target The target to use in the log.
-     *               Must not be <code>null</code>.
-     * @param message The text to log. Should not be <code>null</code>.
-     * @param msgLevel The log priority level to use.
-     */
-    public void log(Target target, String message, int msgLevel) {
-        log(target, message, null, msgLevel);
-    }
-
-    /**
-     * Write a target level message to the log with the given log level.
-     * @param target The target to use in the log.
-     *               Must not be <code>null</code>.
-     * @param message The text to log. Should not be <code>null</code>.
-     * @param throwable The exception causing this log, may be <code>null</code>.
-     * @param msgLevel The log priority level to use.
-     * @since 1.7
-     */
-    public void log(Target target, String message, Throwable throwable,
-            int msgLevel) {
-        fireMessageLogged(target, message, throwable, msgLevel);
-    }
-
-    /**
-     * Return the set of global filters.
-     *
-     * @return the set of global filters.
-     */
-    public FilterSet getGlobalFilterSet() {
-        return globalFilterSet;
-    }
-
-    /**
-     * Set a property. Any existing property of the same name
-     * is overwritten, unless it is a user property.
-     * @param name The name of property to set.
-     *             Must not be <code>null</code>.
-     * @param value The new value of the property.
-     *              Must not be <code>null</code>.
-     */
-    public void setProperty(String name, String value) {
-        PropertyHelper.getPropertyHelper(this).setProperty(name, value, true);
-    }
-
-    /**
-     * Set a property if no value currently exists. If the property
-     * exists already, a message is logged and the method returns with
-     * no other effect.
-     *
-     * @param name The name of property to set.
-     *             Must not be <code>null</code>.
-     * @param value The new value of the property.
-     *              Must not be <code>null</code>.
-     * @since 1.5
-     */
-    public void setNewProperty(String name, String value) {
-        PropertyHelper.getPropertyHelper(this).setNewProperty(name, value);
-    }
-
-    /**
-     * Set a user property, which cannot be overwritten by
-     * set/unset property calls. Any previous value is overwritten.
-     * @param name The name of property to set.
-     *             Must not be <code>null</code>.
-     * @param value The new value of the property.
-     *              Must not be <code>null</code>.
-     * @see #setProperty(String,String)
-     */
-    public void setUserProperty(String name, String value) {
-        PropertyHelper.getPropertyHelper(this).setUserProperty(name, value);
-    }
-
-    /**
-     * Set a user property, which cannot be overwritten by set/unset
-     * property calls. Any previous value is overwritten. Also marks
-     * these properties as properties that have not come from the
-     * command line.
-     *
-     * @param name The name of property to set.
-     *             Must not be <code>null</code>.
-     * @param value The new value of the property.
-     *              Must not be <code>null</code>.
-     * @see #setProperty(String,String)
-     */
-    public void setInheritedProperty(String name, String value) {
-        PropertyHelper.getPropertyHelper(this).setInheritedProperty(name, value);
-    }
-
-    /**
-     * Set a property unless it is already defined as a user property
-     * (in which case the method returns silently).
-     *
-     * @param name The name of the property.
-     *             Must not be <code>null</code>.
-     * @param value The property value. Must not be <code>null</code>.
-     */
-    private void setPropertyInternal(String name, String value) {
-        PropertyHelper.getPropertyHelper(this).setProperty(name, value, false);
-    }
-
-    /**
-     * Return the value of a property, if it is set.
-     *
-     * @param propertyName The name of the property.
-     *             May be <code>null</code>, in which case
-     *             the return value is also <code>null</code>.
-     * @return the property value, or <code>null</code> for no match
-     *         or if a <code>null</code> name is provided.
-     */
-    public String getProperty(String propertyName) {
-        Object value = PropertyHelper.getPropertyHelper(this).getProperty(propertyName);
-        return value == null ? null : String.valueOf(value);
-    }
-
-    /**
-     * Replace ${} style constructions in the given value with the
-     * string value of the corresponding data types.
-     *
-     * @param value The string to be scanned for property references.
-     *              May be <code>null</code>.
-     *
-     * @return the given string with embedded property names replaced
-     *         by values, or <code>null</code> if the given string is
-     *         <code>null</code>.
-     *
-     * @exception BuildException if the given value has an unclosed
-     *                           property name, e.g. <code>${xxx</code>.
-     */
-    public String replaceProperties(String value) throws BuildException {
-        return PropertyHelper.getPropertyHelper(this).replaceProperties(null, value, null);
-    }
-
-    /**
-     * Return the value of a user property, if it is set.
-     *
-     * @param propertyName The name of the property.
-     *             May be <code>null</code>, in which case
-     *             the return value is also <code>null</code>.
-     * @return the property value, or <code>null</code> for no match
-     *         or if a <code>null</code> name is provided.
-     */
-     public String getUserProperty(String propertyName) {
-        return (String) PropertyHelper.getPropertyHelper(this).getUserProperty(propertyName);
-    }
-
-    /**
-     * Return a copy of the properties table.
-     * @return a hashtable containing all properties
-     *         (including user properties).
-     */
-    public Hashtable getProperties() {
-        return PropertyHelper.getPropertyHelper(this).getProperties();
-    }
-
-    /**
-     * Return a copy of the user property hashtable.
-     * @return a hashtable containing just the user properties.
-     */
-    public Hashtable getUserProperties() {
-        return PropertyHelper.getPropertyHelper(this).getUserProperties();
-    }
-
-    /**
-     * Return a copy of the inherited property hashtable.
-     * @return a hashtable containing just the inherited properties.
-     * @since Ant 1.8.0
-     */
-    public Hashtable getInheritedProperties() {
-        return PropertyHelper.getPropertyHelper(this).getInheritedProperties();
-    }
-
-    /**
-     * Copy all user properties that have been set on the command
-     * line or a GUI tool from this instance to the Project instance
-     * given as the argument.
-     *
-     * <p>To copy all &quot;user&quot; properties, you will also have to call
-     * {@link #copyInheritedProperties copyInheritedProperties}.</p>
-     *
-     * @param other the project to copy the properties to.  Must not be null.
-     *
-     * @since Ant 1.5
-     */
-    public void copyUserProperties(Project other) {
-        PropertyHelper.getPropertyHelper(this).copyUserProperties(other);
-    }
-
-    /**
-     * Copy all user properties that have not been set on the
-     * command line or a GUI tool from this instance to the Project
-     * instance given as the argument.
-     *
-     * <p>To copy all &quot;user&quot; properties, you will also have to call
-     * {@link #copyUserProperties copyUserProperties}.</p>
-     *
-     * @param other the project to copy the properties to.  Must not be null.
-     *
-     * @since Ant 1.5
-     */
-    public void copyInheritedProperties(Project other) {
-        PropertyHelper.getPropertyHelper(this).copyInheritedProperties(other);
-    }
-
-    /**
-     * Set the default target of the project.
-     *
-     * @param defaultTarget The name of the default target for this project.
-     *                      May be <code>null</code>, indicating that there is
-     *                      no default target.
-     *
-     * @deprecated since 1.5.x.
-     *             Use setDefault.
-     * @see #setDefault(String)
-     */
-    public void setDefaultTarget(String defaultTarget) {
-        setDefault(defaultTarget);
-    }
-
-    /**
-     * Return the name of the default target of the project.
-     * @return name of the default target or
-     *         <code>null</code> if no default has been set.
-     */
-    public String getDefaultTarget() {
-        return defaultTarget;
-    }
-
-    /**
-     * Set the default target of the project.
-     *
-     * @param defaultTarget The name of the default target for this project.
-     *                      May be <code>null</code>, indicating that there is
-     *                      no default target.
-     */
-    public void setDefault(String defaultTarget) {
-        if (defaultTarget != null) {
-            setUserProperty(MagicNames.PROJECT_DEFAULT_TARGET, defaultTarget);
-        }
-        this.defaultTarget = defaultTarget;
-    }
-
-    /**
-     * Set the name of the project, also setting the user
-     * property <code>ant.project.name</code>.
-     *
-     * @param name The name of the project.
-     *             Must not be <code>null</code>.
-     */
-    public void setName(String name) {
-        setUserProperty(MagicNames.PROJECT_NAME,  name);
-        this.name = name;
-    }
-
-    /**
-     * Return the project name, if one has been set.
-     *
-     * @return the project name, or <code>null</code> if it hasn't been set.
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Set the project description.
-     *
-     * @param description The description of the project.
-     *                    May be <code>null</code>.
-     */
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    /**
-     * Return the project description, if one has been set.
-     *
-     * @return the project description, or <code>null</code> if it hasn't
-     *         been set.
-     */
-    public String getDescription() {
-        if (description == null) {
-            description = Description.getDescription(this);
-        }
-        return description;
-    }
-
-    /**
-     * Add a filter to the set of global filters.
-     *
-     * @param token The token to filter.
-     *              Must not be <code>null</code>.
-     * @param value The replacement value.
-     *              Must not be <code>null</code>.
-     * @deprecated since 1.4.x.
-     *             Use getGlobalFilterSet().addFilter(token,value)
-     *
-     * @see #getGlobalFilterSet()
-     * @see FilterSet#addFilter(String,String)
-     */
-    public void addFilter(String token, String value) {
-        if (token == null) {
-            return;
-        }
-        globalFilterSet.addFilter(new FilterSet.Filter(token, value));
-    }
-
-    /**
-     * Return a hashtable of global filters, mapping tokens to values.
-     *
-     * @return a hashtable of global filters, mapping tokens to values
-     *         (String to String).
-     *
-     * @deprecated since 1.4.x
-     *             Use getGlobalFilterSet().getFilterHash().
-     *
-     * @see #getGlobalFilterSet()
-     * @see FilterSet#getFilterHash()
-     */
-    public Hashtable getFilters() {
-        // we need to build the hashtable dynamically
-        return globalFilterSet.getFilterHash();
-    }
-
-    /**
-     * Set the base directory for the project, checking that
-     * the given filename exists and is a directory.
-     *
-     * @param baseD The project base directory.
-     *              Must not be <code>null</code>.
-     *
-     * @exception BuildException if the directory if invalid.
-     */
-    public void setBasedir(String baseD) throws BuildException {
-        setBaseDir(new File(baseD));
-    }
-
-    /**
-     * Set the base directory for the project, checking that
-     * the given file exists and is a directory.
-     *
-     * @param baseDir The project base directory.
-     *                Must not be <code>null</code>.
-     * @exception BuildException if the specified file doesn't exist or
-     *                           isn't a directory.
-     */
-    public void setBaseDir(File baseDir) throws BuildException {
-        baseDir = FILE_UTILS.normalize(baseDir.getAbsolutePath());
-        if (!baseDir.exists()) {
-            throw new BuildException("Basedir " + baseDir.getAbsolutePath()
-                + " does not exist");
-        }
-        if (!baseDir.isDirectory()) {
-            throw new BuildException("Basedir " + baseDir.getAbsolutePath()
-                + " is not a directory");
-        }
-        this.baseDir = baseDir;
-        setPropertyInternal(MagicNames.PROJECT_BASEDIR, this.baseDir.getPath());
-        String msg = "Project base dir set to: " + this.baseDir;
-        log(msg, MSG_VERBOSE);
-    }
-
-    /**
-     * Return the base directory of the project as a file object.
-     *
-     * @return the project base directory, or <code>null</code> if the
-     *         base directory has not been successfully set to a valid value.
-     */
-    public File getBaseDir() {
-        if (baseDir == null) {
-            try {
-                setBasedir(".");
-            } catch (BuildException ex) {
-                ex.printStackTrace();
-            }
-        }
-        return baseDir;
-    }
-
-    /**
-     * Set &quot;keep-going&quot; mode. In this mode Ant will try to execute
-     * as many targets as possible. All targets that do not depend
-     * on failed target(s) will be executed.  If the keepGoing settor/getter
-     * methods are used in conjunction with the <code>ant.executor.class</code>
-     * property, they will have no effect.
-     * @param keepGoingMode &quot;keep-going&quot; mode
-     * @since Ant 1.6
-     */
-    public void setKeepGoingMode(boolean keepGoingMode) {
-        this.keepGoingMode = keepGoingMode;
-    }
-
-    /**
-     * Return the keep-going mode.  If the keepGoing settor/getter
-     * methods are used in conjunction with the <code>ant.executor.class</code>
-     * property, they will have no effect.
-     * @return &quot;keep-going&quot; mode
-     * @since Ant 1.6
-     */
-    public boolean isKeepGoingMode() {
-        return this.keepGoingMode;
-    }
-
-    /**
-     * Return the version of Java this class is running under.
-     * @return the version of Java as a String, e.g. "1.1" .
-     * @see org.apache.tools.ant.util.JavaEnvUtils#getJavaVersion
-     * @deprecated since 1.5.x.
-     *             Use org.apache.tools.ant.util.JavaEnvUtils instead.
-     */
-    public static String getJavaVersion() {
-        return JavaEnvUtils.getJavaVersion();
-    }
-
-    /**
-     * Set the <code>ant.java.version</code> property and tests for
-     * unsupported JVM versions. If the version is supported,
-     * verbose log messages are generated to record the Java version
-     * and operating system name.
-     *
-     * @exception BuildException if this Java version is not supported.
-     *
-     * @see org.apache.tools.ant.util.JavaEnvUtils#getJavaVersion
-     */
-    public void setJavaVersionProperty() throws BuildException {
-        String javaVersion = JavaEnvUtils.getJavaVersion();
-        setPropertyInternal(MagicNames.ANT_JAVA_VERSION, javaVersion);
-
-        // sanity check
-        if (!JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_1_4))  {
-            throw new BuildException("Ant cannot work on Java prior to 1.4");
-        }
-        log("Detected Java version: " + javaVersion + " in: "
-            + System.getProperty("java.home"), MSG_VERBOSE);
-
-        log("Detected OS: " + System.getProperty("os.name"), MSG_VERBOSE);
-    }
-
-    /**
-     * Add all system properties which aren't already defined as
-     * user properties to the project properties.
-     */
-    public void setSystemProperties() {
-        Properties systemP = System.getProperties();
-        Enumeration e = systemP.propertyNames();
-        while (e.hasMoreElements()) {
-            String propertyName = (String) e.nextElement();
-            String value = systemP.getProperty(propertyName);
-            if (value != null) {
-                this.setPropertyInternal(propertyName, value);
-            }
-        }
-    }
-
-    /**
-     * Add a new task definition to the project.
-     * Attempting to override an existing definition with an
-     * equivalent one (i.e. with the same classname) results in
-     * a verbose log message. Attempting to override an existing definition
-     * with a different one results in a warning log message and
-     * invalidates any tasks which have already been created with the
-     * old definition.
-     *
-     * @param taskName The name of the task to add.
-     *                 Must not be <code>null</code>.
-     * @param taskClass The full name of the class implementing the task.
-     *                  Must not be <code>null</code>.
-     *
-     * @exception BuildException if the class is unsuitable for being an Ant
-     *                           task. An error level message is logged before
-     *                           this exception is thrown.
-     *
-     * @see #checkTaskClass(Class)
-     */
-    public void addTaskDefinition(String taskName, Class taskClass)
-         throws BuildException {
-        ComponentHelper.getComponentHelper(this).addTaskDefinition(taskName,
-                taskClass);
-    }
-
-    /**
-     * Check whether or not a class is suitable for serving as Ant task.
-     * Ant task implementation classes must be public, concrete, and have
-     * a no-arg constructor.
-     *
-     * @param taskClass The class to be checked.
-     *                  Must not be <code>null</code>.
-     *
-     * @exception BuildException if the class is unsuitable for being an Ant
-     *                           task. An error level message is logged before
-     *                           this exception is thrown.
-     */
-    public void checkTaskClass(final Class taskClass) throws BuildException {
-        ComponentHelper.getComponentHelper(this).checkTaskClass(taskClass);
-
-        if (!Modifier.isPublic(taskClass.getModifiers())) {
-            final String message = taskClass + " is not public";
-            log(message, Project.MSG_ERR);
-            throw new BuildException(message);
-        }
-        if (Modifier.isAbstract(taskClass.getModifiers())) {
-            final String message = taskClass + " is abstract";
-            log(message, Project.MSG_ERR);
-            throw new BuildException(message);
-        }
-        try {
-            taskClass.getConstructor((Class[]) null);
-            // don't have to check for public, since
-            // getConstructor finds public constructors only.
-        } catch (NoSuchMethodException e) {
-            final String message = "No public no-arg constructor in "
-                + taskClass;
-            log(message, Project.MSG_ERR);
-            throw new BuildException(message);
-        } catch (LinkageError e) {
-            String message = "Could not load " + taskClass + ": " + e;
-            log(message, Project.MSG_ERR);
-            throw new BuildException(message, e);
-        }
-        if (!Task.class.isAssignableFrom(taskClass)) {
-            TaskAdapter.checkTaskClass(taskClass, this);
-        }
-    }
-
-    /**
-     * Return the current task definition hashtable. The returned hashtable is
-     * &quot;live&quot; and so should not be modified.
-     *
-     * @return a map of from task name to implementing class
-     *         (String to Class).
-     */
-    public Hashtable getTaskDefinitions() {
-        return ComponentHelper.getComponentHelper(this).getTaskDefinitions();
-    }
-
-    /**
-     * Return the current task definition map. The returned map is a
-     * copy of the &quot;live&quot; definitions.
-     *
-     * @return a map of from task name to implementing class
-     *         (String to Class).
-     *
-     * @since Ant 1.8.1
-     */
-    public Map getCopyOfTaskDefinitions() {
-        return new HashMap(getTaskDefinitions());
-    }
-
-    /**
-     * Add a new datatype definition.
-     * Attempting to override an existing definition with an
-     * equivalent one (i.e. with the same classname) results in
-     * a verbose log message. Attempting to override an existing definition
-     * with a different one results in a warning log message, but the
-     * definition is changed.
-     *
-     * @param typeName The name of the datatype.
-     *                 Must not be <code>null</code>.
-     * @param typeClass The full name of the class implementing the datatype.
-     *                  Must not be <code>null</code>.
-     */
-    public void addDataTypeDefinition(String typeName, Class typeClass) {
-        ComponentHelper.getComponentHelper(this).addDataTypeDefinition(typeName,
-                typeClass);
-    }
-
-    /**
-     * Return the current datatype definition hashtable. The returned
-     * hashtable is &quot;live&quot; and so should not be modified.
-     *
-     * @return a map of from datatype name to implementing class
-     *         (String to Class).
-     */
-    public Hashtable getDataTypeDefinitions() {
-        return ComponentHelper.getComponentHelper(this).getDataTypeDefinitions();
-    }
-
-    /**
-     * Return the current datatype definition map. The returned
-     * map is a copy pf the &quot;live&quot; definitions.
-     *
-     * @return a map of from datatype name to implementing class
-     *         (String to Class).
-     *
-     * @since Ant 1.8.1
-     */
-    public Map getCopyOfDataTypeDefinitions() {
-        return new HashMap(getDataTypeDefinitions());
-    }
-
-    /**
-     * Add a <em>new</em> target to the project.
-     *
-     * @param target The target to be added to the project.
-     *               Must not be <code>null</code>.
-     *
-     * @exception BuildException if the target already exists in the project
-     *
-     * @see Project#addOrReplaceTarget(Target)
-     */
-    public void addTarget(Target target) throws BuildException {
-        addTarget(target.getName(), target);
-    }
-
-    /**
-     * Add a <em>new</em> target to the project.
-     *
-     * @param targetName The name to use for the target.
-     *             Must not be <code>null</code>.
-     * @param target The target to be added to the project.
-     *               Must not be <code>null</code>.
-     *
-     * @exception BuildException if the target already exists in the project.
-     *
-     * @see Project#addOrReplaceTarget(String, Target)
-     */
-     public void addTarget(String targetName, Target target)
-         throws BuildException {
-         if (targets.get(targetName) != null) {
-             throw new BuildException("Duplicate target: `" + targetName + "'");
-         }
-         addOrReplaceTarget(targetName, target);
-     }
-
-    /**
-     * Add a target to the project, or replaces one with the same
-     * name.
-     *
-     * @param target The target to be added or replaced in the project.
-     *               Must not be <code>null</code>.
-     */
-    public void addOrReplaceTarget(Target target) {
-        addOrReplaceTarget(target.getName(), target);
-    }
-
-    /**
-     * Add a target to the project, or replaces one with the same
-     * name.
-     *
-     * @param targetName The name to use for the target.
-     *                   Must not be <code>null</code>.
-     * @param target The target to be added or replaced in the project.
-     *               Must not be <code>null</code>.
-     */
-    public void addOrReplaceTarget(String targetName, Target target) {
-        String msg = " +Target: " + targetName;
-        log(msg, MSG_DEBUG);
-        target.setProject(this);
-        targets.put(targetName, target);
-    }
-
-    /**
-     * Return the hashtable of targets. The returned hashtable
-     * is &quot;live&quot; and so should not be modified.
-     * @return a map from name to target (String to Target).
-     */
-    public Hashtable getTargets() {
-        return targets;
-    }
-
-    /**
-     * Return the map of targets. The returned map
-     * is a copy of the &quot;live&quot; targets.
-     * @return a map from name to target (String to Target).
-     * @since Ant 1.8.1
-     */
-    public Map getCopyOfTargets() {
-        return new HashMap(targets);
-    }
-
-    /**
-     * Create a new instance of a task, adding it to a list of
-     * created tasks for later invalidation. This causes all tasks
-     * to be remembered until the containing project is removed
-     * @param taskType The name of the task to create an instance of.
-     *                 Must not be <code>null</code>.
-     *
-     * @return an instance of the specified task, or <code>null</code> if
-     *         the task name is not recognised.
-     *
-     * @exception BuildException if the task name is recognised but task
-     *                           creation fails.
-     */
-    public Task createTask(String taskType) throws BuildException {
-        return ComponentHelper.getComponentHelper(this).createTask(taskType);
-    }
-
-    /**
-     * Create a new instance of a data type.
-     *
-     * @param typeName The name of the data type to create an instance of.
-     *                 Must not be <code>null</code>.
-     *
-     * @return an instance of the specified data type, or <code>null</code> if
-     *         the data type name is not recognised.
-     *
-     * @exception BuildException if the data type name is recognised but
-     *                           instance creation fails.
-     */
-    public Object createDataType(String typeName) throws BuildException {
-        return ComponentHelper.getComponentHelper(this).createDataType(typeName);
-    }
-
-    /**
-     * Set the Executor instance for this Project.
-     * @param e the Executor to use.
-     */
-    public void setExecutor(Executor e) {
-        addReference(MagicNames.ANT_EXECUTOR_REFERENCE, e);
-    }
-
-    /**
-     * Get this Project's Executor (setting it if necessary).
-     * @return an Executor instance.
-     */
-    public Executor getExecutor() {
-        Object o = getReference(MagicNames.ANT_EXECUTOR_REFERENCE);
-        if (o == null) {
-            String classname = getProperty(MagicNames.ANT_EXECUTOR_CLASSNAME);
-            if (classname == null) {
-                classname = DefaultExecutor.class.getName();
-            }
-            log("Attempting to create object of type " + classname, MSG_DEBUG);
-            try {
-                o = Class.forName(classname, true, coreLoader).newInstance();
-            } catch (ClassNotFoundException seaEnEfEx) {
-                //try the current classloader
-                try {
-                    o = Class.forName(classname).newInstance();
-                } catch (Exception ex) {
-                    log(ex.toString(), MSG_ERR);
-                }
-            } catch (Exception ex) {
-                log(ex.toString(), MSG_ERR);
-            }
-            if (o == null) {
-                throw new BuildException(
-                    "Unable to obtain a Target Executor instance.");
-            }
-            setExecutor((Executor) o);
-        }
-        return (Executor) o;
-    }
-
-    /**
-     * Execute the specified sequence of targets, and the targets
-     * they depend on.
-     *
-     * @param names A vector of target name strings to execute.
-     *              Must not be <code>null</code>.
-     *
-     * @exception BuildException if the build failed.
-     */
-    public void executeTargets(Vector names) throws BuildException {
-        setUserProperty(MagicNames.PROJECT_INVOKED_TARGETS,
-                        CollectionUtils.flattenToString(names));
-        getExecutor().executeTargets(this,
-            (String[]) (names.toArray(new String[names.size()])));
-    }
-
-    /**
-     * Demultiplex output so that each task receives the appropriate
-     * messages. If the current thread is not currently executing a task,
-     * the message is logged directly.
-     *
-     * @param output Message to handle. Should not be <code>null</code>.
-     * @param isWarning Whether the text represents an warning (<code>true</code>)
-     *        or information (<code>false</code>).
-     */
-    public void demuxOutput(String output, boolean isWarning) {
-        Task task = getThreadTask(Thread.currentThread());
-        if (task == null) {
-            log(output, isWarning ? MSG_WARN : MSG_INFO);
-        } else {
-            if (isWarning) {
-                task.handleErrorOutput(output);
-            } else {
-                task.handleOutput(output);
-            }
-        }
-    }
-
-    /**
-     * Read data from the default input stream. If no default has been
-     * specified, System.in is used.
-     *
-     * @param buffer the buffer into which data is to be read.
-     * @param offset the offset into the buffer at which data is stored.
-     * @param length the amount of data to read.
-     *
-     * @return the number of bytes read.
-     *
-     * @exception IOException if the data cannot be read.
-     * @since Ant 1.6
-     */
-    public int defaultInput(byte[] buffer, int offset, int length)
-        throws IOException {
-        if (defaultInputStream != null) {
-            System.out.flush();
-            return defaultInputStream.read(buffer, offset, length);
-        } else {
-            throw new EOFException("No input provided for project");
-        }
-    }
-
-    /**
-     * Demux an input request to the correct task.
-     *
-     * @param buffer the buffer into which data is to be read.
-     * @param offset the offset into the buffer at which data is stored.
-     * @param length the amount of data to read.
-     *
-     * @return the number of bytes read.
-     *
-     * @exception IOException if the data cannot be read.
-     * @since Ant 1.6
-     */
-    public int demuxInput(byte[] buffer, int offset, int length)
-        throws IOException {
-        Task task = getThreadTask(Thread.currentThread());
-        if (task == null) {
-            return defaultInput(buffer, offset, length);
-        } else {
-            return task.handleInput(buffer, offset, length);
-        }
-    }
-
-    /**
-     * Demultiplex flush operations so that each task receives the appropriate
-     * messages. If the current thread is not currently executing a task,
-     * the message is logged directly.
-     *
-     * @since Ant 1.5.2
-     *
-     * @param output Message to handle. Should not be <code>null</code>.
-     * @param isError Whether the text represents an error (<code>true</code>)
-     *        or information (<code>false</code>).
-     */
-    public void demuxFlush(String output, boolean isError) {
-        Task task = getThreadTask(Thread.currentThread());
-        if (task == null) {
-            fireMessageLogged(this, output, isError ? MSG_ERR : MSG_INFO);
-        } else {
-            if (isError) {
-                task.handleErrorFlush(output);
-            } else {
-                task.handleFlush(output);
-            }
-        }
-    }
-
-    /**
-     * Execute the specified target and any targets it depends on.
-     *
-     * @param targetName The name of the target to execute.
-     *                   Must not be <code>null</code>.
-     *
-     * @exception BuildException if the build failed.
-     */
-    public void executeTarget(String targetName) throws BuildException {
-
-        // sanity check ourselves, if we've been asked to build nothing
-        // then we should complain
-
-        if (targetName == null) {
-            String msg = "No target specified";
-            throw new BuildException(msg);
-        }
-
-        // Sort and run the dependency tree.
-        // Sorting checks if all the targets (and dependencies)
-        // exist, and if there is any cycle in the dependency
-        // graph.
-        executeSortedTargets(topoSort(targetName, targets, false));
-    }
-
-    /**
-     * Execute a <code>Vector</code> of sorted targets.
-     * @param sortedTargets   the aforementioned <code>Vector</code>.
-     * @throws BuildException on error.
-     */
-    public void executeSortedTargets(Vector sortedTargets)
-        throws BuildException {
-        Set succeededTargets = new HashSet();
-        BuildException buildException = null; // first build exception
-        for (Enumeration iter = sortedTargets.elements();
-             iter.hasMoreElements();) {
-            Target curtarget = (Target) iter.nextElement();
-            boolean canExecute = true;
-            for (Enumeration depIter = curtarget.getDependencies();
-                 depIter.hasMoreElements();) {
-                String dependencyName = ((String) depIter.nextElement());
-                if (!succeededTargets.contains(dependencyName)) {
-                    canExecute = false;
-                    log(curtarget,
-                        "Cannot execute '" + curtarget.getName() + "' - '"
-                        + dependencyName + "' failed or was not executed.",
-                        MSG_ERR);
-                    break;
-                }
-            }
-            if (canExecute) {
-                Throwable thrownException = null;
-                try {
-                    curtarget.performTasks();
-                    succeededTargets.add(curtarget.getName());
-                } catch (RuntimeException ex) {
-                    if (!(keepGoingMode)) {
-                        throw ex; // throw further
-                    }
-                    thrownException = ex;
-                } catch (Throwable ex) {
-                    if (!(keepGoingMode)) {
-                        throw new BuildException(ex);
-                    }
-                    thrownException = ex;
-                }
-                if (thrownException != null) {
-                    if (thrownException instanceof BuildException) {
-                        log(curtarget,
-                            "Target '" + curtarget.getName()
-                            + "' failed with message '"
-                            + thrownException.getMessage() + "'.", MSG_ERR);
-                        // only the first build exception is reported
-                        if (buildException == null) {
-                            buildException = (BuildException) thrownException;
-                        }
-                    } else {
-                        log(curtarget,
-                            "Target '" + curtarget.getName()
-                            + "' failed with message '"
-                            + thrownException.getMessage() + "'.", MSG_ERR);
-                        thrownException.printStackTrace(System.err);
-                        if (buildException == null) {
-                            buildException =
-                                new BuildException(thrownException);
-                        }
-                    }
-                }
-            }
-        }
-        if (buildException != null) {
-            throw buildException;
-        }
-    }
-
-    /**
-     * Return the canonical form of a filename.
-     * <p>
-     * If the specified file name is relative it is resolved
-     * with respect to the given root directory.
-     *
-     * @param fileName The name of the file to resolve.
-     *                 Must not be <code>null</code>.
-     *
-     * @param rootDir  The directory respective to which relative file names
-     *                 are resolved. May be <code>null</code>, in which case
-     *                 the current directory is used.
-     *
-     * @return the resolved File.
-     *
-     * @deprecated since 1.4.x
-     */
-    public File resolveFile(String fileName, File rootDir) {
-        return FILE_UTILS.resolveFile(rootDir, fileName);
-    }
-
-    /**
-     * Return the canonical form of a filename.
-     * <p>
-     * If the specified file name is relative it is resolved
-     * with respect to the project's base directory.
-     *
-     * @param fileName The name of the file to resolve.
-     *                 Must not be <code>null</code>.
-     *
-     * @return the resolved File.
-     *
-     */
-    public File resolveFile(String fileName) {
-        return FILE_UTILS.resolveFile(baseDir, fileName);
-    }
-
-    /**
-     * Translate a path into its native (platform specific) format.
-     * <p>
-     * This method uses PathTokenizer to separate the input path
-     * into its components. This handles DOS style paths in a relatively
-     * sensible way. The file separators are then converted to their platform
-     * specific versions.
-     *
-     * @param toProcess The path to be translated.
-     *                  May be <code>null</code>.
-     *
-     * @return the native version of the specified path or
-     *         an empty string if the path is <code>null</code> or empty.
-     *
-     * @deprecated since 1.7
-     *             Use FileUtils.translatePath instead.
-     *
-     * @see PathTokenizer
-     */
-    public static String translatePath(String toProcess) {
-        return FileUtils.translatePath(toProcess);
-    }
-
-    /**
-     * Convenience method to copy a file from a source to a destination.
-     * No filtering is performed.
-     *
-     * @param sourceFile Name of file to copy from.
-     *                   Must not be <code>null</code>.
-     * @param destFile Name of file to copy to.
-     *                 Must not be <code>null</code>.
-     *
-     * @exception IOException if the copying fails.
-     *
-     * @deprecated since 1.4.x
-     */
-    public void copyFile(String sourceFile, String destFile)
-          throws IOException {
-        FILE_UTILS.copyFile(sourceFile, destFile);
-    }
-
-    /**
-     * Convenience method to copy a file from a source to a destination
-     * specifying if token filtering should be used.
-     *
-     * @param sourceFile Name of file to copy from.
-     *                   Must not be <code>null</code>.
-     * @param destFile Name of file to copy to.
-     *                 Must not be <code>null</code>.
-     * @param filtering Whether or not token filtering should be used during
-     *                  the copy.
-     *
-     * @exception IOException if the copying fails.
-     *
-     * @deprecated since 1.4.x
-     */
-    public void copyFile(String sourceFile, String destFile, boolean filtering)
-        throws IOException {
-        FILE_UTILS.copyFile(sourceFile, destFile,
-            filtering ? globalFilters : null);
-    }
-
-    /**
-     * Convenience method to copy a file from a source to a
-     * destination specifying if token filtering should be used and if
-     * source files may overwrite newer destination files.
-     *
-     * @param sourceFile Name of file to copy from.
-     *                   Must not be <code>null</code>.
-     * @param destFile Name of file to copy to.
-     *                 Must not be <code>null</code>.
-     * @param filtering Whether or not token filtering should be used during
-     *                  the copy.
-     * @param overwrite Whether or not the destination file should be
-     *                  overwritten if it already exists.
-     *
-     * @exception IOException if the copying fails.
-     *
-     * @deprecated since 1.4.x
-     */
-    public void copyFile(String sourceFile, String destFile, boolean filtering,
-                         boolean overwrite) throws IOException {
-        FILE_UTILS.copyFile(sourceFile, destFile,
-            filtering ? globalFilters : null, overwrite);
-    }
-
-    /**
-     * Convenience method to copy a file from a source to a
-     * destination specifying if token filtering should be used, if
-     * source files may overwrite newer destination files, and if the
-     * last modified time of the resulting file should be set to
-     * that of the source file.
-     *
-     * @param sourceFile Name of file to copy from.
-     *                   Must not be <code>null</code>.
-     * @param destFile Name of file to copy to.
-     *                 Must not be <code>null</code>.
-     * @param filtering Whether or not token filtering should be used during
-     *                  the copy.
-     * @param overwrite Whether or not the destination file should be
-     *                  overwritten if it already exists.
-     * @param preserveLastModified Whether or not the last modified time of
-     *                             the resulting file should be set to that
-     *                             of the source file.
-     *
-     * @exception IOException if the copying fails.
-     *
-     * @deprecated since 1.4.x
-     */
-    public void copyFile(String sourceFile, String destFile, boolean filtering,
-                         boolean overwrite, boolean preserveLastModified)
-        throws IOException {
-        FILE_UTILS.copyFile(sourceFile, destFile,
-            filtering ? globalFilters : null, overwrite, preserveLastModified);
-    }
-
-    /**
-     * Convenience method to copy a file from a source to a destination.
-     * No filtering is performed.
-     *
-     * @param sourceFile File to copy from.
-     *                   Must not be <code>null</code>.
-     * @param destFile File to copy to.
-     *                 Must not be <code>null</code>.
-     *
-     * @exception IOException if the copying fails.
-     *
-     * @deprecated since 1.4.x
-     */
-    public void copyFile(File sourceFile, File destFile) throws IOException {
-        FILE_UTILS.copyFile(sourceFile, destFile);
-    }
-
-    /**
-     * Convenience method to copy a file from a source to a destination
-     * specifying if token filtering should be used.
-     *
-     * @param sourceFile File to copy from.
-     *                   Must not be <code>null</code>.
-     * @param destFile File to copy to.
-     *                 Must not be <code>null</code>.
-     * @param filtering Whether or not token filtering should be used during
-     *                  the copy.
-     *
-     * @exception IOException if the copying fails.
-     *
-     * @deprecated since 1.4.x
-     */
-    public void copyFile(File sourceFile, File destFile, boolean filtering)
-        throws IOException {
-        FILE_UTILS.copyFile(sourceFile, destFile,
-            filtering ? globalFilters : null);
-    }
-
-    /**
-     * Convenience method to copy a file from a source to a
-     * destination specifying if token filtering should be used and if
-     * source files may overwrite newer destination files.
-     *
-     * @param sourceFile File to copy from.
-     *                   Must not be <code>null</code>.
-     * @param destFile File to copy to.
-     *                 Must not be <code>null</code>.
-     * @param filtering Whether or not token filtering should be used during
-     *                  the copy.
-     * @param overwrite Whether or not the destination file should be
-     *                  overwritten if it already exists.
-     *
-     * @exception IOException if the file cannot be copied.
-     *
-     * @deprecated since 1.4.x
-     */
-    public void copyFile(File sourceFile, File destFile, boolean filtering,
-                         boolean overwrite) throws IOException {
-        FILE_UTILS.copyFile(sourceFile, destFile,
-            filtering ? globalFilters : null, overwrite);
-    }
-
-    /**
-     * Convenience method to copy a file from a source to a
-     * destination specifying if token filtering should be used, if
-     * source files may overwrite newer destination files, and if the
-     * last modified time of the resulting file should be set to
-     * that of the source file.
-     *
-     * @param sourceFile File to copy from.
-     *                   Must not be <code>null</code>.
-     * @param destFile File to copy to.
-     *                 Must not be <code>null</code>.
-     * @param filtering Whether or not token filtering should be used during
-     *                  the copy.
-     * @param overwrite Whether or not the destination file should be
-     *                  overwritten if it already exists.
-     * @param preserveLastModified Whether or not the last modified time of
-     *                             the resulting file should be set to that
-     *                             of the source file.
-     *
-     * @exception IOException if the file cannot be copied.
-     *
-     * @deprecated since 1.4.x
-     */
-    public void copyFile(File sourceFile, File destFile, boolean filtering,
-                         boolean overwrite, boolean preserveLastModified)
-        throws IOException {
-        FILE_UTILS.copyFile(sourceFile, destFile,
-            filtering ? globalFilters : null, overwrite, preserveLastModified);
-    }
-
-    /**
-     * Call File.setLastModified(long time) on Java above 1.1, and logs
-     * a warning on Java 1.1.
-     *
-     * @param file The file to set the last modified time on.
-     *             Must not be <code>null</code>.
-     *
-     * @param time the required modification time.
-     *
-     * @deprecated since 1.4.x
-     *
-     * @exception BuildException if the last modified time cannot be set
-     *                           despite running on a platform with a version
-     *                           above 1.1.
-     */
-    public void setFileLastModified(File file, long time)
-         throws BuildException {
-        FILE_UTILS.setFileLastModified(file, time);
-        log("Setting modification time for " + file, MSG_VERBOSE);
-    }
-
-    /**
-     * Return the boolean equivalent of a string, which is considered
-     * <code>true</code> if either <code>"on"</code>, <code>"true"</code>,
-     * or <code>"yes"</code> is found, ignoring case.
-     *
-     * @param s The string to convert to a boolean value.
-     *
-     * @return <code>true</code> if the given string is <code>"on"</code>,
-     *         <code>"true"</code> or <code>"yes"</code>, or
-     *         <code>false</code> otherwise.
-     */
-    public static boolean toBoolean(String s) {
-        return ("on".equalsIgnoreCase(s)
-                || "true".equalsIgnoreCase(s)
-                || "yes".equalsIgnoreCase(s));
-    }
-
-    /**
-     * Get the Project instance associated with the specified object.
-     * @param o the object to query.
-     * @return Project instance, if any.
-     * @since Ant 1.7.1
-     */
-    public static Project getProject(Object o) {
-        if (o instanceof ProjectComponent) {
-            return ((ProjectComponent) o).getProject();
-        }
-        try {
-            Method m = o.getClass().getMethod("getProject", (Class[]) null);
-            if (Project.class == m.getReturnType()) {
-                return (Project) m.invoke(o, (Object[]) null);
-            }
-        } catch (Exception e) {
-            //too bad
-        }
-        return null;
-    }
-
-    /**
-     * Topologically sort a set of targets.  Equivalent to calling
-     * <code>topoSort(new String[] {root}, targets, true)</code>.
-     *
-     * @param root The name of the root target. The sort is created in such
-     *             a way that the sequence of Targets up to the root
-     *             target is the minimum possible such sequence.
-     *             Must not be <code>null</code>.
-     * @param targetTable A Hashtable mapping names to Targets.
-     *                Must not be <code>null</code>.
-     * @return a Vector of ALL Target objects in sorted order.
-     * @exception BuildException if there is a cyclic dependency among the
-     *                           targets, or if a named target does not exist.
-     */
-    public final Vector topoSort(String root, Hashtable targetTable)
-        throws BuildException {
-        return topoSort(new String[] {root}, targetTable, true);
-    }
-
-    /**
-     * Topologically sort a set of targets.  Equivalent to calling
-     * <code>topoSort(new String[] {root}, targets, returnAll)</code>.
-     *
-     * @param root The name of the root target. The sort is created in such
-     *             a way that the sequence of Targets up to the root
-     *             target is the minimum possible such sequence.
-     *             Must not be <code>null</code>.
-     * @param targetTable A Hashtable mapping names to Targets.
-     *                Must not be <code>null</code>.
-     * @param returnAll <code>boolean</code> indicating whether to return all
-     *                  targets, or the execution sequence only.
-     * @return a Vector of Target objects in sorted order.
-     * @exception BuildException if there is a cyclic dependency among the
-     *                           targets, or if a named target does not exist.
-     * @since Ant 1.6.3
-     */
-    public final Vector topoSort(String root, Hashtable targetTable,
-                                 boolean returnAll) throws BuildException {
-        return topoSort(new String[] {root}, targetTable, returnAll);
-    }
-
-    /**
-     * Topologically sort a set of targets.
-     *
-     * @param root <code>String[]</code> containing the names of the root targets.
-     *             The sort is created in such a way that the ordered sequence of
-     *             Targets is the minimum possible such sequence to the specified
-     *             root targets.
-     *             Must not be <code>null</code>.
-     * @param targetTable A map of names to targets (String to Target).
-     *                Must not be <code>null</code>.
-     * @param returnAll <code>boolean</code> indicating whether to return all
-     *                  targets, or the execution sequence only.
-     * @return a Vector of Target objects in sorted order.
-     * @exception BuildException if there is a cyclic dependency among the
-     *                           targets, or if a named target does not exist.
-     * @since Ant 1.6.3
-     */
-    public final Vector topoSort(String[] root, Hashtable targetTable,
-                                 boolean returnAll) throws BuildException {
-        Vector ret = new VectorSet();
-        Hashtable state = new Hashtable();
-        Stack visiting = new Stack();
-
-        // We first run a DFS based sort using each root as a starting node.
-        // This creates the minimum sequence of Targets to the root node(s).
-        // We then do a sort on any remaining unVISITED targets.
-        // This is unnecessary for doing our build, but it catches
-        // circular dependencies or missing Targets on the entire
-        // dependency tree, not just on the Targets that depend on the
-        // build Target.
-
-        for (int i = 0; i < root.length; i++) {
-            String st = (String) (state.get(root[i]));
-            if (st == null) {
-                tsort(root[i], targetTable, state, visiting, ret);
-            } else if (st == VISITING) {
-                throw new RuntimeException("Unexpected node in visiting state: "
-                    + root[i]);
-            }
-        }
-        StringBuffer buf = new StringBuffer("Build sequence for target(s)");
-
-        for (int j = 0; j < root.length; j++) {
-            buf.append((j == 0) ? " `" : ", `").append(root[j]).append('\'');
-        }
-        buf.append(" is " + ret);
-        log(buf.toString(), MSG_VERBOSE);
-
-        Vector complete = (returnAll) ? ret : new Vector(ret);
-        for (Enumeration en = targetTable.keys(); en.hasMoreElements();) {
-            String curTarget = (String) en.nextElement();
-            String st = (String) state.get(curTarget);
-            if (st == null) {
-                tsort(curTarget, targetTable, state, visiting, complete);
-            } else if (st == VISITING) {
-                throw new RuntimeException("Unexpected node in visiting state: "
-                    + curTarget);
-            }
-        }
-        log("Complete build sequence is " + complete, MSG_VERBOSE);
-        return ret;
-    }
-
-    /**
-     * Perform a single step in a recursive depth-first-search traversal of
-     * the target dependency tree.
-     * <p>
-     * The current target is first set to the &quot;visiting&quot; state, and
-     * pushed onto the &quot;visiting&quot; stack.
-     * <p>
-     * An exception is then thrown if any child of the current node is in the
-     * visiting state, as that implies a circular dependency. The exception
-     * contains details of the cycle, using elements of the &quot;visiting&quot;
-     * stack.
-     * <p>
-     * If any child has not already been &quot;visited&quot;, this method is
-     * called recursively on it.
-     * <p>
-     * The current target is then added to the ordered list of targets. Note
-     * that this is performed after the children have been visited in order
-     * to get the correct order. The current target is set to the
-     * &quot;visited&quot; state.
-     * <p>
-     * By the time this method returns, the ordered list contains the sequence
-     * of targets up to and including the current target.
-     *
-     * @param root The current target to inspect.
-     *             Must not be <code>null</code>.
-     * @param targetTable A mapping from names to targets (String to Target).
-     *                Must not be <code>null</code>.
-     * @param state   A mapping from target names to states (String to String).
-     *                The states in question are &quot;VISITING&quot; and
-     *                &quot;VISITED&quot;. Must not be <code>null</code>.
-     * @param visiting A stack of targets which are currently being visited.
-     *                 Must not be <code>null</code>.
-     * @param ret     The list to add target names to. This will end up
-     *                containing the complete list of dependencies in
-     *                dependency order.
-     *                Must not be <code>null</code>.
-     *
-     * @exception BuildException if a non-existent target is specified or if
-     *                           a circular dependency is detected.
-     */
-    private void tsort(String root, Hashtable targetTable,
-                             Hashtable state, Stack visiting,
-                             Vector ret)
-        throws BuildException {
-        state.put(root, VISITING);
-        visiting.push(root);
-
-        Target target = (Target) targetTable.get(root);
-
-        // Make sure we exist
-        if (target == null) {
-            StringBuffer sb = new StringBuffer("Target \"");
-            sb.append(root);
-            sb.append("\" does not exist in the project \"");
-            sb.append(name);
-            sb.append("\". ");
-            visiting.pop();
-            if (!visiting.empty()) {
-                String parent = (String) visiting.peek();
-                sb.append("It is used from target \"");
-                sb.append(parent);
-                sb.append("\".");
-            }
-            throw new BuildException(new String(sb));
-        }
-        for (Enumeration en = target.getDependencies(); en.hasMoreElements();) {
-            String cur = (String) en.nextElement();
-            String m = (String) state.get(cur);
-            if (m == null) {
-                // Not been visited
-                tsort(cur, targetTable, state, visiting, ret);
-            } else if (m == VISITING) {
-                // Currently visiting this node, so have a cycle
-                throw makeCircularException(cur, visiting);
-            }
-        }
-        String p = (String) visiting.pop();
-        if (root != p) {
-            throw new RuntimeException("Unexpected internal error: expected to "
-                + "pop " + root + " but got " + p);
-        }
-        state.put(root, VISITED);
-        ret.addElement(target);
-    }
-
-    /**
-     * Build an appropriate exception detailing a specified circular
-     * dependency.
-     *
-     * @param end The dependency to stop at. Must not be <code>null</code>.
-     * @param stk A stack of dependencies. Must not be <code>null</code>.
-     *
-     * @return a BuildException detailing the specified circular dependency.
-     */
-    private static BuildException makeCircularException(String end, Stack stk) {
-        StringBuffer sb = new StringBuffer("Circular dependency: ");
-        sb.append(end);
-        String c;
-        do {
-            c = (String) stk.pop();
-            sb.append(" <- ");
-            sb.append(c);
-        } while (!c.equals(end));
-        return new BuildException(new String(sb));
-    }
-
-    /**
-     * Inherit the id references.
-     * @param parent the parent project of this project.
-     */
-    public void inheritIDReferences(Project parent) {
-        parentIdProject = parent;
-    }
-
-    /**
-     * Add an id reference.
-     * Used for broken build files.
-     * @param id the id to set.
-     * @param value the value to set it to (Unknown element in this case.
-     */
-    public void addIdReference(String id, Object value) {
-        idReferences.put(id, value);
-    }
-
-    /**
-     * Add a reference to the project.
-     *
-     * @param referenceName The name of the reference. Must not be <code>null</code>.
-     * @param value The value of the reference.
-     */
-    public void addReference(String referenceName, Object value) {
-        Object old = ((AntRefTable) references).getReal(referenceName);
-        if (old == value) {
-            // no warning, this is not changing anything
-            return;
-        }
-        if (old != null && !(old instanceof UnknownElement)) {
-            log("Overriding previous definition of reference to " + referenceName,
-                MSG_VERBOSE);
-        }
-        log("Adding reference: " + referenceName, MSG_DEBUG);
-        references.put(referenceName, value);
-    }
-
-    /**
-     * Return a map of the references in the project (String to Object).
-     * The returned hashtable is &quot;live&quot; and so must not be modified.
-     *
-     * @return a map of the references in the project (String to Object).
-     */
-    public Hashtable getReferences() {
-        return references;
-    }
-
-    /**
-     * Does the project know this reference?
-     *
-     * @since Ant 1.8.0
-     */
-    public boolean hasReference(String key) {
-        return references.containsKey(key);
-    }
-
-    /**
-     * Return a map of the references in the project (String to
-     * Object).  The returned hashtable is a copy of the
-     * &quot;live&quot; references.
-     *
-     * @return a map of the references in the project (String to Object).
-     *
-     * @since Ant 1.8.1
-     */
-    public Map getCopyOfReferences() {
-        return new HashMap(references);
-    }
-
-    /**
-     * Look up a reference by its key (ID).
-     *
-     * @param key The key for the desired reference.
-     *            Must not be <code>null</code>.
-     *
-     * @return the reference with the specified ID, or <code>null</code> if
-     *         there is no such reference in the project.
-     */
-    public Object getReference(String key) {
-        Object ret = references.get(key);
-        if (ret != null) {
-            return ret;
-        }
-        if (!key.equals(MagicNames.REFID_PROPERTY_HELPER)) {
-            try {
-                if (PropertyHelper.getPropertyHelper(this).containsProperties(key)) {
-                    log("Unresolvable reference " + key
-                            + " might be a misuse of property expansion syntax.", MSG_WARN);
-                }
-            } catch (Exception e) {
-                //ignore
-            }
-        }
-        return ret;
-    }
-
-    /**
-     * Return a description of the type of the given element, with
-     * special handling for instances of tasks and data types.
-     * <p>
-     * This is useful for logging purposes.
-     *
-     * @param element The element to describe.
-     *                Must not be <code>null</code>.
-     *
-     * @return a description of the element type.
-     *
-     * @since 1.95, Ant 1.5
-     */
-    public String getElementName(Object element) {
-        return ComponentHelper.getComponentHelper(this).getElementName(element);
-    }
-
-    /**
-     * Send a &quot;build started&quot; event
-     * to the build listeners for this project.
-     */
-    public void fireBuildStarted() {
-        BuildEvent event = new BuildEvent(this);
-        BuildListener[] currListeners = listeners;
-        for (int i = 0; i < currListeners.length; i++) {
-            currListeners[i].buildStarted(event);
-        }
-    }
-
-    /**
-     * Send a &quot;build finished&quot; event to the build listeners
-     * for this project.
-     * @param exception an exception indicating a reason for a build
-     *                  failure. May be <code>null</code>, indicating
-     *                  a successful build.
-     */
-    public void fireBuildFinished(Throwable exception) {
-        BuildEvent event = new BuildEvent(this);
-        event.setException(exception);
-        BuildListener[] currListeners = listeners;
-        for (int i = 0; i < currListeners.length; i++) {
-            currListeners[i].buildFinished(event);
-        }
-        // Inform IH to clear the cache
-        IntrospectionHelper.clearCache();
-    }
-
-    /**
-     * Send a &quot;subbuild started&quot; event to the build listeners for
-     * this project.
-     *
-     * @since Ant 1.6.2
-     */
-    public void fireSubBuildStarted() {
-        BuildEvent event = new BuildEvent(this);
-        BuildListener[] currListeners = listeners;
-        for (int i = 0; i < currListeners.length; i++) {
-            if (currListeners[i] instanceof SubBuildListener) {
-                ((SubBuildListener) currListeners[i]).subBuildStarted(event);
-            }
-        }
-    }
-
-    /**
-     * Send a &quot;subbuild finished&quot; event to the build listeners for
-     * this project.
-     * @param exception an exception indicating a reason for a build
-     *                  failure. May be <code>null</code>, indicating
-     *                  a successful build.
-     *
-     * @since Ant 1.6.2
-     */
-    public void fireSubBuildFinished(Throwable exception) {
-        BuildEvent event = new BuildEvent(this);
-        event.setException(exception);
-        BuildListener[] currListeners = listeners;
-        for (int i = 0; i < currListeners.length; i++) {
-            if (currListeners[i] instanceof SubBuildListener) {
-                ((SubBuildListener) currListeners[i]).subBuildFinished(event);
-            }
-        }
-    }
-
-    /**
-     * Send a &quot;target started&quot; event to the build listeners
-     * for this project.
-     *
-     * @param target The target which is starting to build.
-     *               Must not be <code>null</code>.
-     */
-    protected void fireTargetStarted(Target target) {
-        BuildEvent event = new BuildEvent(target);
-        BuildListener[] currListeners = listeners;
-        for (int i = 0; i < currListeners.length; i++) {
-            currListeners[i].targetStarted(event);
-        }
-
-    }
-
-    /**
-     * Send a &quot;target finished&quot; event to the build listeners
-     * for this project.
-     *
-     * @param target    The target which has finished building.
-     *                  Must not be <code>null</code>.
-     * @param exception an exception indicating a reason for a build
-     *                  failure. May be <code>null</code>, indicating
-     *                  a successful build.
-     */
-    protected void fireTargetFinished(Target target, Throwable exception) {
-        BuildEvent event = new BuildEvent(target);
-        event.setException(exception);
-        BuildListener[] currListeners = listeners;
-        for (int i = 0; i < currListeners.length; i++) {
-            currListeners[i].targetFinished(event);
-        }
-
-    }
-
-    /**
-     * Send a &quot;task started&quot; event to the build listeners
-     * for this project.
-     *
-     * @param task The target which is starting to execute.
-     *               Must not be <code>null</code>.
-     */
-    protected void fireTaskStarted(Task task) {
-        // register this as the current task on the current thread.
-        registerThreadTask(Thread.currentThread(), task);
-        BuildEvent event = new BuildEvent(task);
-        BuildListener[] currListeners = listeners;
-        for (int i = 0; i < currListeners.length; i++) {
-            currListeners[i].taskStarted(event);
-        }
-    }
-
-    /**
-     * Send a &quot;task finished&quot; event to the build listeners for this
-     * project.
-     *
-     * @param task      The task which has finished executing.
-     *                  Must not be <code>null</code>.
-     * @param exception an exception indicating a reason for a build
-     *                  failure. May be <code>null</code>, indicating
-     *                  a successful build.
-     */
-    protected void fireTaskFinished(Task task, Throwable exception) {
-        registerThreadTask(Thread.currentThread(), null);
-        System.out.flush();
-        System.err.flush();
-        BuildEvent event = new BuildEvent(task);
-        event.setException(exception);
-        BuildListener[] currListeners = listeners;
-        for (int i = 0; i < currListeners.length; i++) {
-            currListeners[i].taskFinished(event);
-        }
-
-    }
-
-    /**
-     * Send a &quot;message logged&quot; event to the build listeners
-     * for this project.
-     *
-     * @param event    The event to send. This should be built up with the
-     *                 appropriate task/target/project by the caller, so that
-     *                 this method can set the message and priority, then send
-     *                 the event. Must not be <code>null</code>.
-     * @param message  The message to send. Should not be <code>null</code>.
-     * @param priority The priority of the message.
-     */
-    private void fireMessageLoggedEvent(BuildEvent event, String message,
-                                        int priority) {
-
-        if (message == null) {
-            message = String.valueOf(message);
-        }
-        if (message.endsWith(StringUtils.LINE_SEP)) {
-            int endIndex = message.length() - StringUtils.LINE_SEP.length();
-            event.setMessage(message.substring(0, endIndex), priority);
-        } else {
-            event.setMessage(message, priority);
-        }
-        if (isLoggingMessage.get() != Boolean.FALSE) {
-            /*
-             * One of the Listeners has attempted to access
-             * System.err or System.out.
-             *
-             * We used to throw an exception in this case, but
-             * sometimes Listeners can't prevent it(like our own
-             * Log4jListener which invokes getLogger() which in
-             * turn wants to write to the console).
-             *
-             * @see http://marc.theaimsgroup.com/?t=110538624200006&r=1&w=2
-             *
-             * We now (Ant 1.6.3 and later) simply swallow the message.
-             */
-            return;
-        }
-        try {
-            isLoggingMessage.set(Boolean.TRUE);
-            BuildListener[] currListeners = listeners;
-            for (int i = 0; i < currListeners.length; i++) {
-                currListeners[i].messageLogged(event);
-            }
-        } finally {
-            isLoggingMessage.set(Boolean.FALSE);
-        }
-    }
-
-    /**
-     * Send a &quot;message logged&quot; project level event
-     * to the build listeners for this project.
-     *
-     * @param project  The project generating the event.
-     *                 Should not be <code>null</code>.
-     * @param message  The message to send. Should not be <code>null</code>.
-     * @param priority The priority of the message.
-     */
-    protected void fireMessageLogged(Project project, String message,
-                                     int priority) {
-        fireMessageLogged(project, message, null, priority);
-    }
-
-    /**
-     * Send a &quot;message logged&quot; project level event
-     * to the build listeners for this project.
-     *
-     * @param project  The project generating the event.
-     *                 Should not be <code>null</code>.
-     * @param message  The message to send. Should not be <code>null</code>.
-     * @param throwable The exception that caused this message. May be <code>null</code>.
-     * @param priority The priority of the message.
-     * @since 1.7
-     */
-    protected void fireMessageLogged(Project project, String message,
-            Throwable throwable, int priority) {
-        BuildEvent event = new BuildEvent(project);
-        event.setException(throwable);
-        fireMessageLoggedEvent(event, message, priority);
-    }
-
-    /**
-     * Send a &quot;message logged&quot; target level event
-     * to the build listeners for this project.
-     *
-     * @param target   The target generating the event.
-     *                 Must not be <code>null</code>.
-     * @param message  The message to send. Should not be <code>null</code>.
-     * @param priority The priority of the message.
-     */
-    protected void fireMessageLogged(Target target, String message,
-                                     int priority) {
-        fireMessageLogged(target, message, null, priority);
-    }
-
-    /**
-     * Send a &quot;message logged&quot; target level event
-     * to the build listeners for this project.
-     *
-     * @param target   The target generating the event.
-     *                 Must not be <code>null</code>.
-     * @param message  The message to send. Should not be <code>null</code>.
-     * @param throwable The exception that caused this message. May be <code>null</code>.
-     * @param priority The priority of the message.
-     * @since 1.7
-     */
-    protected void fireMessageLogged(Target target, String message,
-            Throwable throwable, int priority) {
-        BuildEvent event = new BuildEvent(target);
-        event.setException(throwable);
-        fireMessageLoggedEvent(event, message, priority);
-    }
-
-    /**
-     * Send a &quot;message logged&quot; task level event
-     * to the build listeners for this project.
-     *
-     * @param task     The task generating the event.
-     *                 Must not be <code>null</code>.
-     * @param message  The message to send. Should not be <code>null</code>.
-     * @param priority The priority of the message.
-     */
-    protected void fireMessageLogged(Task task, String message, int priority) {
-        fireMessageLogged(task, message, null, priority);
-    }
-
-    /**
-     * Send a &quot;message logged&quot; task level event
-     * to the build listeners for this project.
-     *
-     * @param task     The task generating the event.
-     *                 Must not be <code>null</code>.
-     * @param message  The message to send. Should not be <code>null</code>.
-     * @param throwable The exception that caused this message. May be <code>null</code>.
-     * @param priority The priority of the message.
-     * @since 1.7
-     */
-    protected void fireMessageLogged(Task task, String message,
-            Throwable throwable, int priority) {
-        BuildEvent event = new BuildEvent(task);
-        event.setException(throwable);
-        fireMessageLoggedEvent(event, message, priority);
-    }
-
-    /**
-     * Register a task as the current task for a thread.
-     * If the task is null, the thread's entry is removed.
-     *
-     * @param thread the thread on which the task is registered.
-     * @param task the task to be registered.
-     * @since Ant 1.5
-     */
-    public void registerThreadTask(Thread thread, Task task) {
-        synchronized(threadTasks) {
-            if (task != null) {
-                threadTasks.put(thread, task);
-                threadGroupTasks.put(thread.getThreadGroup(), task);
-            } else {
-                threadTasks.remove(thread);
-                threadGroupTasks.remove(thread.getThreadGroup());
-            }
-        }
-    }
-
-    /**
-     * Get the current task associated with a thread, if any.
-     *
-     * @param thread the thread for which the task is required.
-     * @return the task which is currently registered for the given thread or
-     *         null if no task is registered.
-     */
-    public Task getThreadTask(Thread thread) {
-        synchronized(threadTasks) {
-            Task task = (Task) threadTasks.get(thread);
-            if (task == null) {
-                ThreadGroup group = thread.getThreadGroup();
-                while (task == null && group != null) {
-                    task = (Task) threadGroupTasks.get(group);
-                    group = group.getParent();
-                }
-            }
-            return task;
-        }
-    }
-
-
-    // Should move to a separate public class - and have API to add
-    // listeners, etc.
-    private static class AntRefTable extends Hashtable {
-
-        AntRefTable() {
-            super();
-        }
-
-        /** Returns the unmodified original object.
-         * This method should be called internally to
-         * get the &quot;real&quot; object.
-         * The normal get method will do the replacement
-         * of UnknownElement (this is similar with the JDNI
-         * refs behavior).
-         */
-        private Object getReal(Object key) {
-            return super.get(key);
-        }
-
-        /** Get method for the reference table.
-         *  It can be used to hook dynamic references and to modify
-         * some references on the fly--for example for delayed
-         * evaluation.
-         *
-         * It is important to make sure that the processing that is
-         * done inside is not calling get indirectly.
-         *
-         * @param key lookup key.
-         * @return mapped value.
-         */
-        public Object get(Object key) {
-            //System.out.println("AntRefTable.get " + key);
-            Object o = getReal(key);
-            if (o instanceof UnknownElement) {
-                // Make sure that
-                UnknownElement ue = (UnknownElement) o;
-                ue.maybeConfigure();
-                o = ue.getRealThing();
-            }
-            return o;
-        }
-    }
-
-    /**
-     * Set a reference to this Project on the parameterized object.
-     * Need to set the project before other set/add elements
-     * are called.
-     * @param obj the object to invoke setProject(this) on.
-     */
-    public final void setProjectReference(final Object obj) {
-        if (obj instanceof ProjectComponent) {
-            ((ProjectComponent) obj).setProject(this);
-            return;
-        }
-        try {
-            Method method =
-                obj.getClass().getMethod(
-                    "setProject", new Class[] {Project.class});
-            if (method != null) {
-                method.invoke(obj, new Object[] {this});
-            }
-        } catch (Throwable e) {
-            // ignore this if the object does not have
-            // a set project method or the method
-            // is private/protected.
-        }
-    }
-
-    /**
-     * Resolve the file relative to the project's basedir and return it as a
-     * FileResource.
-     * @param name the name of the file to resolve.
-     * @return the file resource.
-     * @since Ant 1.7
-     */
-    public Resource getResource(String name) {
-        return new FileResource(getBaseDir(), name);
-    }
-}
diff --git a/command-line-debugger/src/main/org/apache/tools/ant/PropertyDebugHelper.java b/command-line-debugger/src/main/org/apache/tools/ant/PropertyDebugHelper.java
new file mode 100644
index 0000000..42cb17c
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/tools/ant/PropertyDebugHelper.java
@@ -0,0 +1,57 @@
+package org.apache.tools.ant;
+
+import org.apache.ant.debugger.Auditor;
+
+/**
+ * Derives almost everything from parent {@link PropertyHelper}. Only difference
+ * being, that it allows an {@link Auditor} instance to attach to itself, which
+ * is informed about attempted property changes, which auditor can then choose
+ * to record them, and probably present them to the end user as needed.
+ * <p />
+ */
+public class PropertyDebugHelper extends PropertyHelper {
+
+	protected Auditor auditor;
+
+	protected Project project;
+
+	public void setAuditor(Auditor auditor) {
+		this.auditor = auditor;
+	}
+
+	public void setProject(Project project) {
+		this.project = project;
+	}
+
+	/*
+	 * Implement a callback mechanism here for all these methods that will allow
+	 * the control to pass back to the listener
+	 */
+
+	public boolean setProperty(String name, Object value, boolean verbose) {
+		project.log("Auditing change to property: " + name, Project.MSG_DEBUG);
+		auditor.auditPropertyChange(name, value, project);
+		// call back can take control before the actual property change is
+		// invoked?
+		return super.setProperty(name, value, verbose);
+	}
+
+	public void setNewProperty(String name, Object value) {
+		project.log("Auditing change to property: " + name, Project.MSG_DEBUG);
+		auditor.auditPropertyChange(name, value, project);
+		super.setNewProperty(name, value);
+	}
+
+	public void setUserProperty(String name, Object value) {
+		project.log("Auditing change to property: " + name, Project.MSG_DEBUG);
+		auditor.auditPropertyChange(name, value, project);
+		super.setUserProperty(name, value);
+	}
+
+	public void setInheritedProperty(String name, Object value) {
+		project.log("Auditing change to property: " + name);
+		auditor.auditPropertyChange(name, value, project);
+		super.setInheritedProperty(name, value);
+	}
+
+}
diff --git a/command-line-debugger/src/main/org/apache/tools/ant/helper/ProjectHelper2.java b/command-line-debugger/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
deleted file mode 100644
index 2876598..0000000
--- a/command-line-debugger/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
+++ /dev/null
@@ -1,1279 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- *
- */
-package org.apache.tools.ant.helper;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.ExtensionPoint;
-import org.apache.tools.ant.Location;
-import org.apache.tools.ant.MagicNames;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.ProjectHelper;
-import org.apache.tools.ant.RuntimeConfigurable;
-import org.apache.tools.ant.Target;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.UnknownElement;
-import org.apache.tools.ant.DebugTask;
-import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.types.resources.FileProvider;
-import org.apache.tools.ant.types.resources.URLProvider;
-import org.apache.tools.ant.util.FileUtils;
-import org.apache.tools.ant.util.JAXPUtils;
-import org.apache.tools.zip.ZipFile;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.DefaultHandler;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Stack;
-
-/**
- * Sax2 based project reader
- *
- */
-public class ProjectHelper2 extends ProjectHelper {
-
-    /** Reference holding the (ordered) target Vector */
-    public static final String REFID_TARGETS = "ant.targets";
-
-    /* Stateless */
-
-    // singletons - since all state is in the context
-    private static AntHandler elementHandler = new ElementHandler();
-    private static AntHandler targetHandler = new TargetHandler();
-    private static AntHandler mainHandler = new MainHandler();
-    private static AntHandler projectHandler = new ProjectHandler();
-
-    /** Specific to ProjectHelper2 so not a true Ant "magic name:" */
-    private static final String REFID_CONTEXT = "ant.parsing.context";
-
-    /**
-     * helper for path -> URI and URI -> path conversions.
-     */
-    private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-
-    /**
-     * Whether this instance of ProjectHelper can parse an Antlib
-     * descriptor given by the URL and return its content as an
-     * UnknownElement ready to be turned into an Antlib task.
-     *
-     * <p>This implementation returns true.</p>
-     *
-     * @since Ant 1.8.0
-     */
-    public boolean canParseAntlibDescriptor(Resource resource) {
-        return true;
-    }
-
-    /**
-     * Parse the given URL as an antlib descriptor and return the
-     * content as something that can be turned into an Antlib task.
-     *
-     * <p>simply delegates to {@link #parseUnknownElement
-     * parseUnknownElement} if the resource provides an URL and throws
-     * an exception otherwise.</p>
-     *
-     * @since Ant 1.8.0
-     */
-    public UnknownElement parseAntlibDescriptor(Project containingProject,
-                                                Resource resource) {
-        URLProvider up = (URLProvider) resource.as(URLProvider.class);
-        if (up == null) {
-            throw new BuildException("Unsupported resource type: " + resource);
-        }
-        return parseUnknownElement(containingProject, up.getURL());
-    }
-
-    /**
-     * Parse an unknown element from a url
-     *
-     * @param project the current project
-     * @param source  the url containing the task
-     * @return a configured task
-     * @exception BuildException if an error occurs
-     */
-    public UnknownElement parseUnknownElement(Project project, URL source)
-        throws BuildException {
-        Target dummyTarget = new Target();
-        dummyTarget.setProject(project);
-
-        AntXMLContext context = new AntXMLContext(project);
-        context.addTarget(dummyTarget);
-        context.setImplicitTarget(dummyTarget);
-
-        parse(context.getProject(), source, new RootHandler(context, elementHandler));
-        Task[] tasks = dummyTarget.getTasks();
-        if (tasks.length != 1) {
-            throw new BuildException("No tasks defined");
-        }
-        return (UnknownElement) tasks[0];
-    }
-
-    /**
-     * Parse a source xml input.
-     *
-     * @param project the current project
-     * @param source  the xml source
-     * @exception BuildException if an error occurs
-     */
-    public void parse(Project project, Object source) throws BuildException {
-        getImportStack().addElement(source);
-        AntXMLContext context = null;
-        context = (AntXMLContext) project.getReference(REFID_CONTEXT);
-        if (context == null) {
-            context = new AntXMLContext(project);
-            project.addReference(REFID_CONTEXT, context);
-            project.addReference(REFID_TARGETS, context.getTargets());
-        }
-        if (getImportStack().size() > 1) {
-            // we are in an imported file.
-            context.setIgnoreProjectTag(true);
-            Target currentTarget = context.getCurrentTarget();
-            Target currentImplicit = context.getImplicitTarget();
-            Map    currentTargets = context.getCurrentTargets();
-            try {
-                Target newCurrent = new Target();
-                newCurrent.setProject(project);
-                newCurrent.setName("");
-                context.setCurrentTarget(newCurrent);
-                context.setCurrentTargets(new HashMap());
-                context.setImplicitTarget(newCurrent);
-                parse(project, source, new RootHandler(context, mainHandler));
-                newCurrent.execute();
-            } finally {
-                context.setCurrentTarget(currentTarget);
-                context.setImplicitTarget(currentImplicit);
-                context.setCurrentTargets(currentTargets);
-            }
-        } else {
-            // top level file
-            context.setCurrentTargets(new HashMap());
-            parse(project, source, new RootHandler(context, mainHandler));
-            // Execute the top-level target
-            context.getImplicitTarget().execute();
-
-            // resolve extensionOf attributes
-            for (Iterator i = getExtensionStack().iterator(); i.hasNext(); ) {
-                String[] extensionInfo = (String[]) i.next();
-                String tgName = extensionInfo[0];
-                String name = extensionInfo[1];
-                OnMissingExtensionPoint missingBehaviour = OnMissingExtensionPoint
-                        .valueOf(extensionInfo[2]);
-                Hashtable projectTargets = project.getTargets();
-                if (!projectTargets.containsKey(tgName)) {
-                    String message = "can't add target " + name
-                        + " to extension-point " + tgName
-                        + " because the extension-point is unknown.";
-                    if (missingBehaviour == OnMissingExtensionPoint.FAIL) {
-                        throw new BuildException(message);
-                    } else if (missingBehaviour == OnMissingExtensionPoint.WARN) {
-                        Target target = (Target) projectTargets.get(name);
-                        context.getProject().log(target,
-                                                 "Warning: " + message,
-                                                 Project.MSG_WARN);
-                    }
-                } else {
-                    Target t = (Target) projectTargets.get(tgName);
-                    if (!(t instanceof ExtensionPoint)) {
-                        throw new BuildException("referenced target "
-                                                 + tgName
-                                                 + " is not an extension-point");
-                    }
-                    t.addDependency(name);
-                }
-            }
-        }
-    }
-
-    /**
-     * Parses the project file, configuring the project as it goes.
-     *
-     * @param project the current project
-     * @param source  the xml source
-     * @param handler the root handler to use (contains the current context)
-     * @exception BuildException if the configuration is invalid or cannot
-     *                           be read
-     */
-    public void parse(Project project, Object source, RootHandler handler) throws BuildException {
-
-        AntXMLContext context = handler.context;
-
-        File buildFile = null;
-        URL  url = null;
-        String buildFileName = null;
-
-        if (source instanceof File) {
-            buildFile = (File) source;
-        } else if (source instanceof URL) {
-            url = (URL) source;
-        } else if (source instanceof Resource) {
-            FileProvider fp =
-                (FileProvider) ((Resource) source).as(FileProvider.class);
-            if (fp != null) {
-                buildFile = fp.getFile();
-            } else {
-                URLProvider up =
-                    (URLProvider) ((Resource) source).as(URLProvider.class);
-                if (up != null) {
-                    url = up.getURL();
-                }
-            }
-        }
-        if (buildFile != null) {
-            buildFile = FILE_UTILS.normalize(buildFile.getAbsolutePath());
-            context.setBuildFile(buildFile);
-            buildFileName = buildFile.toString();
-        } else if (url != null) {
-            try {
-                context.setBuildFile((File) null);
-                context.setBuildFile(url);
-            } catch (java.net.MalformedURLException ex) {
-                throw new BuildException(ex);
-            }
-            buildFileName = url.toString();
-        } else {
-            throw new BuildException("Source " + source.getClass().getName()
-                                     + " not supported by this plugin");
-        }
-        InputStream inputStream = null;
-        InputSource inputSource = null;
-        ZipFile zf = null;
-
-        try {
-            /**
-             * SAX 2 style parser used to parse the given file.
-             */
-            XMLReader parser = JAXPUtils.getNamespaceXMLReader();
-
-            String uri = null;
-            if (buildFile != null) {
-                uri = FILE_UTILS.toURI(buildFile.getAbsolutePath());
-                inputStream = new FileInputStream(buildFile);
-            } else {
-                uri = url.toString();
-                int pling = -1;
-                if (uri.startsWith("jar:file")
-                    && (pling = uri.indexOf("!/")) > -1) {
-                    zf = new ZipFile(org.apache.tools.ant.launch.Locator
-                                     .fromJarURI(uri), "UTF-8");
-                    inputStream =
-                        zf.getInputStream(zf.getEntry(uri.substring(pling + 1)));
-                } else {
-                    inputStream = url.openStream();
-                }
-            }
-
-            inputSource = new InputSource(inputStream);
-            if (uri != null) {
-                inputSource.setSystemId(uri);
-            }
-            project.log("parsing buildfile " + buildFileName + " with URI = "
-                        + uri + (zf != null ? " from a zip file" : ""),
-                        Project.MSG_VERBOSE);
-
-            DefaultHandler hb = handler;
-
-            parser.setContentHandler(hb);
-            parser.setEntityResolver(hb);
-            parser.setErrorHandler(hb);
-            parser.setDTDHandler(hb);
-            parser.parse(inputSource);
-        } catch (SAXParseException exc) {
-            Location location = new Location(exc.getSystemId(), exc.getLineNumber(), exc
-                                             .getColumnNumber());
-
-            Throwable t = exc.getException();
-            if (t instanceof BuildException) {
-                BuildException be = (BuildException) t;
-                if (be.getLocation() == Location.UNKNOWN_LOCATION) {
-                    be.setLocation(location);
-                }
-                throw be;
-            }
-            throw new BuildException(exc.getMessage(), t == null ? exc : t, location);
-        } catch (SAXException exc) {
-            Throwable t = exc.getException();
-            if (t instanceof BuildException) {
-                throw (BuildException) t;
-            }
-            throw new BuildException(exc.getMessage(), t == null ? exc : t);
-        } catch (FileNotFoundException exc) {
-            throw new BuildException(exc);
-        } catch (UnsupportedEncodingException exc) {
-            throw new BuildException("Encoding of project file " + buildFileName + " is invalid.",
-                                     exc);
-        } catch (IOException exc) {
-            throw new BuildException("Error reading project file " + buildFileName + ": "
-                                     + exc.getMessage(), exc);
-        } finally {
-            FileUtils.close(inputStream);
-            ZipFile.closeQuietly(zf);
-        }
-    }
-
-    /**
-     * Returns main handler
-     * @return main handler
-     */
-    protected static AntHandler getMainHandler() {
-        return mainHandler;
-    }
-
-    /**
-     * Sets main handler
-     * @param handler  new main handler
-     */
-    protected static void setMainHandler(AntHandler handler) {
-        mainHandler = handler;
-    }
-
-    /**
-     * Returns project handler
-     * @return project handler
-     */
-    protected static AntHandler getProjectHandler() {
-        return projectHandler;
-    }
-
-    /**
-     * Sets project handler
-     * @param handler  new project handler
-     */
-    protected static void setProjectHandler(AntHandler handler) {
-        projectHandler = handler;
-    }
-
-    /**
-     * Returns target handler
-     * @return target handler
-     */
-    protected static AntHandler getTargetHandler() {
-        return targetHandler;
-    }
-
-    /**
-     * Sets target handler
-     * @param handler  new target handler
-     */
-    protected static void setTargetHandler(AntHandler handler) {
-        targetHandler = handler;
-    }
-
-    /**
-     * Returns element handler
-     * @return element handler
-     */
-    protected static AntHandler getElementHandler() {
-        return elementHandler;
-    }
-
-    /**
-     * Sets element handler
-     * @param handler  new element handler
-     */
-    protected static void setElementHandler(AntHandler handler) {
-        elementHandler = handler;
-    }
-
-    /**
-     * The common superclass for all SAX event handlers used to parse
-     * the configuration file.
-     *
-     * The context will hold all state information. At each time
-     * there is one active handler for the current element. It can
-     * use onStartChild() to set an alternate handler for the child.
-     */
-    public static class AntHandler  {
-        /**
-         * Handles the start of an element. This base implementation does
-         * nothing.
-         *
-         * @param uri the namespace URI for the tag
-         * @param tag The name of the element being started.
-         *            Will not be <code>null</code>.
-         * @param qname The qualified name of the element.
-         * @param attrs Attributes of the element being started.
-         *              Will not be <code>null</code>.
-         * @param context The context that this element is in.
-         *
-         * @exception SAXParseException if this method is not overridden, or in
-         *                              case of error in an overridden version
-         */
-        public void onStartElement(String uri, String tag, String qname, Attributes attrs,
-                                   AntXMLContext context) throws SAXParseException {
-        }
-
-        /**
-         * Handles the start of an element. This base implementation just
-         * throws an exception - you must override this method if you expect
-         * child elements.
-         *
-         * @param uri The namespace uri for this element.
-         * @param tag The name of the element being started.
-         *            Will not be <code>null</code>.
-         * @param qname The qualified name for this element.
-         * @param attrs Attributes of the element being started.
-         *              Will not be <code>null</code>.
-         * @param context The current context.
-         * @return a handler (in the derived classes)
-         *
-         * @exception SAXParseException if this method is not overridden, or in
-         *                              case of error in an overridden version
-         */
-        public AntHandler onStartChild(String uri, String tag, String qname, Attributes attrs,
-                                       AntXMLContext context) throws SAXParseException {
-            throw new SAXParseException("Unexpected element \"" + qname + " \"", context
-                                        .getLocator());
-        }
-
-        /**
-         * Handle the end of a element.
-         *
-         * @param uri the namespace uri of the element
-         * @param tag the tag of the element
-         * @param qname the qualified name of the element
-         * @param context the current context
-         * @exception SAXParseException if an error occurs
-         */
-        public void onEndChild(String uri, String tag, String qname, AntXMLContext context)
-            throws SAXParseException {
-        }
-
-        /**
-         * This method is called when this element and all elements nested into it have been
-         * handled. I.e., this happens at the &lt;/end_tag_of_the_element&gt;.
-         * @param uri the namespace uri for this element
-         * @param tag the element name
-         * @param context the current context
-         */
-        public void onEndElement(String uri, String tag, AntXMLContext context) {
-        }
-
-        /**
-         * Handles text within an element. This base implementation just
-         * throws an exception, you must override it if you expect content.
-         *
-         * @param buf A character array of the text within the element.
-         *            Will not be <code>null</code>.
-         * @param start The start element in the array.
-         * @param count The number of characters to read from the array.
-         * @param context The current context.
-         *
-         * @exception SAXParseException if this method is not overridden, or in
-         *                              case of error in an overridden version
-         */
-        public void characters(char[] buf, int start, int count, AntXMLContext context)
-            throws SAXParseException {
-            String s = new String(buf, start, count).trim();
-
-            if (s.length() > 0) {
-                throw new SAXParseException("Unexpected text \"" + s + "\"", context.getLocator());
-            }
-        }
-
-        /**
-         * Will be called every time a namespace is reached.
-         * It'll verify if the ns was processed, and if not load the task definitions.
-         * @param uri The namespace uri.
-         */
-        protected void checkNamespace(String uri) {
-        }
-    }
-
-    /**
-     * Handler for ant processing. Uses a stack of AntHandlers to
-     * implement each element ( the original parser used a recursive behavior,
-     * with the implicit execution stack )
-     */
-    public static class RootHandler extends DefaultHandler {
-        private Stack antHandlers = new Stack();
-        private AntHandler currentHandler = null;
-        private AntXMLContext context;
-
-        /**
-         * Creates a new RootHandler instance.
-         *
-         * @param context The context for the handler.
-         * @param rootHandler The handler for the root element.
-         */
-        public RootHandler(AntXMLContext context, AntHandler rootHandler) {
-            currentHandler = rootHandler;
-            antHandlers.push(currentHandler);
-            this.context = context;
-        }
-
-        /**
-         * Returns the current ant handler object.
-         * @return the current ant handler.
-         */
-        public AntHandler getCurrentAntHandler() {
-            return currentHandler;
-        }
-
-        /**
-         * Resolves file: URIs relative to the build file.
-         *
-         * @param publicId The public identifier, or <code>null</code>
-         *                 if none is available. Ignored in this
-         *                 implementation.
-         * @param systemId The system identifier provided in the XML
-         *                 document. Will not be <code>null</code>.
-         * @return an inputsource for this identifier
-         */
-        public InputSource resolveEntity(String publicId, String systemId) {
-
-            context.getProject().log("resolving systemId: " + systemId, Project.MSG_VERBOSE);
-
-            if (systemId.startsWith("file:")) {
-                String path = FILE_UTILS.fromURI(systemId);
-
-                File file = new File(path);
-                if (!file.isAbsolute()) {
-                    file = FILE_UTILS.resolveFile(context.getBuildFileParent(), path);
-                    context.getProject().log(
-                                             "Warning: '" + systemId + "' in " + context.getBuildFile()
-                                             + " should be expressed simply as '" + path.replace('\\', '/')
-                                             + "' for compliance with other XML tools", Project.MSG_WARN);
-                }
-                context.getProject().log("file=" + file, Project.MSG_DEBUG);
-                try {
-                    InputSource inputSource = new InputSource(new FileInputStream(file));
-                    inputSource.setSystemId(FILE_UTILS.toURI(file.getAbsolutePath()));
-                    return inputSource;
-                } catch (FileNotFoundException fne) {
-                    context.getProject().log(file.getAbsolutePath() + " could not be found",
-                                             Project.MSG_WARN);
-                }
-
-            }
-            // use default if not file or file not found
-            context.getProject().log("could not resolve systemId", Project.MSG_DEBUG);
-            return null;
-        }
-
-        /**
-         * Handles the start of a project element. A project handler is created
-         * and initialised with the element name and attributes.
-         *
-         * @param uri The namespace uri for this element.
-         * @param tag The name of the element being started.
-         *            Will not be <code>null</code>.
-         * @param qname The qualified name for this element.
-         * @param attrs Attributes of the element being started.
-         *              Will not be <code>null</code>.
-         *
-         * @exception org.xml.sax.SAXParseException if the tag given is not
-         *                              <code>"project"</code>
-         */
-        public void startElement(String uri, String tag, String qname, Attributes attrs)
-            throws SAXParseException {
-            AntHandler next = currentHandler.onStartChild(uri, tag, qname, attrs, context);
-            antHandlers.push(currentHandler);
-            currentHandler = next;
-            currentHandler.onStartElement(uri, tag, qname, attrs, context);
-        }
-
-        /**
-         * Sets the locator in the project helper for future reference.
-         *
-         * @param locator The locator used by the parser.
-         *                Will not be <code>null</code>.
-         */
-        public void setDocumentLocator(Locator locator) {
-            context.setLocator(locator);
-        }
-
-        /**
-         * Handles the end of an element. Any required clean-up is performed
-         * by the onEndElement() method and then the original handler is restored to the parser.
-         *
-         * @param uri  The namespace URI for this element.
-         * @param name The name of the element which is ending.
-         *             Will not be <code>null</code>.
-         * @param qName The qualified name for this element.
-         *
-         * @exception SAXException in case of error (not thrown in this implementation)
-         */
-        public void endElement(String uri, String name, String qName) throws SAXException {
-            currentHandler.onEndElement(uri, name, context);
-            AntHandler prev = (AntHandler) antHandlers.pop();
-            currentHandler = prev;
-            if (currentHandler != null) {
-                currentHandler.onEndChild(uri, name, qName, context);
-            }
-        }
-
-        /**
-         * Handle text within an element, calls currentHandler.characters.
-         *
-         * @param buf  A character array of the test.
-         * @param start The start offset in the array.
-         * @param count The number of characters to read.
-         * @exception SAXParseException if an error occurs
-         */
-        public void characters(char[] buf, int start, int count) throws SAXParseException {
-            currentHandler.characters(buf, start, count, context);
-        }
-
-        /**
-         * Start a namespace prefix to uri mapping
-         *
-         * @param prefix the namespace prefix
-         * @param uri the namespace uri
-         */
-        public void startPrefixMapping(String prefix, String uri) {
-            context.startPrefixMapping(prefix, uri);
-        }
-
-        /**
-         * End a namepace prefix to uri mapping
-         *
-         * @param prefix the prefix that is not mapped anymore
-         */
-        public void endPrefixMapping(String prefix) {
-            context.endPrefixMapping(prefix);
-        }
-    }
-
-    /**
-     * The main handler - it handles the &lt;project&gt; tag.
-     *
-     * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler
-     */
-    public static class MainHandler extends AntHandler {
-
-        /**
-         * Handle the project tag
-         *
-         * @param uri The namespace uri.
-         * @param name The element tag.
-         * @param qname The element qualified name.
-         * @param attrs The attributes of the element.
-         * @param context The current context.
-         * @return The project handler that handles subelements of project
-         * @exception SAXParseException if the qualified name is not "project".
-         */
-        public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
-                                       AntXMLContext context) throws SAXParseException {
-            if (name.equals("project")
-                && (uri.equals("") || uri.equals(ANT_CORE_URI))) {
-                return ProjectHelper2.projectHandler;
-            }
-            if (name.equals(qname)) {
-                throw new SAXParseException("Unexpected element \"{" + uri
-                                            + "}" + name + "\" {" + ANT_CORE_URI + "}" + name, context.getLocator());
-            }
-            throw new SAXParseException("Unexpected element \"" + qname
-                                        + "\" " + name, context.getLocator());
-        }
-    }
-
-    /**
-     * Handler for the top level "project" element.
-     */
-    public static class ProjectHandler extends AntHandler {
-
-        /**
-         * Initialisation routine called after handler creation
-         * with the element name and attributes. The attributes which
-         * this handler can deal with are: <code>"default"</code>,
-         * <code>"name"</code>, <code>"id"</code> and <code>"basedir"</code>.
-         *
-         * @param uri The namespace URI for this element.
-         * @param tag Name of the element which caused this handler
-         *            to be created. Should not be <code>null</code>.
-         *            Ignored in this implementation.
-         * @param qname The qualified name for this element.
-         * @param attrs Attributes of the element which caused this
-         *              handler to be created. Must not be <code>null</code>.
-         * @param context The current context.
-         *
-         * @exception SAXParseException if an unexpected attribute is
-         *            encountered or if the <code>"default"</code> attribute
-         *            is missing.
-         */
-        public void onStartElement(String uri, String tag, String qname, Attributes attrs,
-                                   AntXMLContext context) throws SAXParseException {
-            String baseDir = null;
-            boolean nameAttributeSet = false;
-
-            Project project = context.getProject();
-            // Set the location of the implicit target associated with the project tag
-            context.getImplicitTarget().setLocation(new Location(context.getLocator()));
-
-            /** XXX I really don't like this - the XML processor is still
-             * too 'involved' in the processing. A better solution (IMO)
-             * would be to create UE for Project and Target too, and
-             * then process the tree and have Project/Target deal with
-             * its attributes ( similar with Description ).
-             *
-             * If we eventually switch to ( or add support for ) DOM,
-             * things will work smoothly - UE can be avoided almost completely
-             * ( it could still be created on demand, for backward compatibility )
-             */
-
-            for (int i = 0; i < attrs.getLength(); i++) {
-                String attrUri = attrs.getURI(i);
-                if (attrUri != null && !attrUri.equals("") && !attrUri.equals(uri)) {
-                    continue; // Ignore attributes from unknown uris
-                }
-                String key = attrs.getLocalName(i);
-                String value = attrs.getValue(i);
-
-                if (key.equals("default")) {
-                    if (value != null && !value.equals("")) {
-                        if (!context.isIgnoringProjectTag()) {
-                            project.setDefault(value);
-                        }
-                    }
-                } else if (key.equals("name")) {
-                    if (value != null) {
-                        context.setCurrentProjectName(value);
-                        nameAttributeSet = true;
-                        if (!context.isIgnoringProjectTag()) {
-                            project.setName(value);
-                            project.addReference(value, project);
-                        } else if (isInIncludeMode()) {
-                            if (!"".equals(value)
-                                && (getCurrentTargetPrefix() == null
-                                    || getCurrentTargetPrefix().length() == 0)
-                                ) {
-                                // help nested include tasks
-                                setCurrentTargetPrefix(value);
-                            }
-                        }
-                    }
-                } else if (key.equals("id")) {
-                    if (value != null) {
-                        // What's the difference between id and name ?
-                        if (!context.isIgnoringProjectTag()) {
-                            project.addReference(value, project);
-                        }
-                    }
-                } else if (key.equals("basedir")) {
-                    if (!context.isIgnoringProjectTag()) {
-                        baseDir = value;
-                    }
-                } else {
-                    // XXX ignore attributes in a different NS ( maybe store them ? )
-                    throw new SAXParseException("Unexpected attribute \"" + attrs.getQName(i)
-                                                + "\"", context.getLocator());
-                }
-            }
-
-            // XXX Move to Project ( so it is shared by all helpers )
-            String antFileProp =
-                MagicNames.ANT_FILE + "." + context.getCurrentProjectName();
-            String dup = project.getProperty(antFileProp);
-            String typeProp =
-                MagicNames.ANT_FILE_TYPE + "." + context.getCurrentProjectName();
-            String dupType = project.getProperty(typeProp);
-            if (dup != null && nameAttributeSet) {
-                Object dupFile = null;
-                Object contextFile = null;
-                if (MagicNames.ANT_FILE_TYPE_URL.equals(dupType)) {
-                    try {
-                        dupFile = new URL(dup);
-                    } catch (java.net.MalformedURLException mue) {
-                        throw new BuildException("failed to parse "
-                                                 + dup + " as URL while looking"
-                                                 + " at a duplicate project"
-                                                 + " name.", mue);
-                    }
-                    contextFile = context.getBuildFileURL();
-                } else {
-                    dupFile = new File(dup);
-                    contextFile = context.getBuildFile();
-                }
-
-                if (context.isIgnoringProjectTag() && !dupFile.equals(contextFile)) {
-                    project.log("Duplicated project name in import. Project "
-                                + context.getCurrentProjectName() + " defined first in " + dup
-                                + " and again in " + contextFile, Project.MSG_WARN);
-                }
-            }
-            if (nameAttributeSet) {
-                if (context.getBuildFile() != null) {
-                    project.setUserProperty(antFileProp,
-                                            context.getBuildFile().toString());
-                    project.setUserProperty(typeProp,
-                                            MagicNames.ANT_FILE_TYPE_FILE);
-                } else if (context.getBuildFileURL() != null) {
-                    project.setUserProperty(antFileProp,
-                                            context.getBuildFileURL().toString());
-                    project.setUserProperty(typeProp,
-                                            MagicNames.ANT_FILE_TYPE_URL);
-                }
-            }
-            if (context.isIgnoringProjectTag()) {
-                // no further processing
-                return;
-            }
-            // set explicitly before starting ?
-            if (project.getProperty("basedir") != null) {
-                project.setBasedir(project.getProperty("basedir"));
-            } else {
-                // Default for baseDir is the location of the build file.
-                if (baseDir == null) {
-                    project.setBasedir(context.getBuildFileParent().getAbsolutePath());
-                } else {
-                    // check whether the user has specified an absolute path
-                    if ((new File(baseDir)).isAbsolute()) {
-                        project.setBasedir(baseDir);
-                    } else {
-                        project.setBaseDir(FILE_UTILS.resolveFile(context.getBuildFileParent(),
-                                                                  baseDir));
-                    }
-                }
-            }
-            project.addTarget("", context.getImplicitTarget());
-            context.setCurrentTarget(context.getImplicitTarget());
-        }
-
-        /**
-         * Handles the start of a top-level element within the project. An
-         * appropriate handler is created and initialised with the details
-         * of the element.
-         *
-         * @param uri The namespace URI for this element.
-         * @param name The name of the element being started.
-         *            Will not be <code>null</code>.
-         * @param qname The qualified name for this element.
-         * @param attrs Attributes of the element being started.
-         *              Will not be <code>null</code>.
-         * @param context The context for this element.
-         * @return a target or an element handler.
-         *
-         * @exception org.xml.sax.SAXParseException if the tag given is not
-         *            <code>"taskdef"</code>, <code>"typedef"</code>,
-         *            <code>"property"</code>, <code>"target"</code>,
-         *            <code>"extension-point"</code>
-         *            or a data type definition
-         */
-        public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
-                                       AntXMLContext context) throws SAXParseException {
-            return (name.equals("target") || name.equals("extension-point"))
-                && (uri.equals("") || uri.equals(ANT_CORE_URI))
-                ? ProjectHelper2.targetHandler : ProjectHelper2.elementHandler;
-        }
-    }
-
-    /**
-     * Handler for "target" and "extension-point" elements.
-     */
-    public static class TargetHandler extends AntHandler {
-
-        /**
-         * Initialisation routine called after handler creation
-         * with the element name and attributes. The attributes which
-         * this handler can deal with are: <code>"name"</code>,
-         * <code>"depends"</code>, <code>"if"</code>,
-         * <code>"unless"</code>, <code>"id"</code> and
-         * <code>"description"</code>.
-         *
-         * @param uri The namespace URI for this element.
-         * @param tag Name of the element which caused this handler
-         *            to be created. Should not be <code>null</code>.
-         *            Ignored in this implementation.
-         * @param qname The qualified name for this element.
-         * @param attrs Attributes of the element which caused this
-         *              handler to be created. Must not be <code>null</code>.
-         * @param context The current context.
-         *
-         * @exception SAXParseException if an unexpected attribute is encountered
-         *            or if the <code>"name"</code> attribute is missing.
-         */
-        public void onStartElement(String uri, String tag, String qname, Attributes attrs,
-                                   AntXMLContext context) throws SAXParseException {
-            String name = null;
-            String depends = "";
-            String extensionPoint = null;
-            OnMissingExtensionPoint extensionPointMissing = null;
-
-            Project project = context.getProject();
-            Target target = "target".equals(tag)
-                ? new Target() : new ExtensionPoint();
-            target.setProject(project);
-            target.setLocation(new Location(context.getLocator()));
-            context.addTarget(target);
-            boolean isTarget = false;
-            if(!(target instanceof ExtensionPoint)) {
-            	isTarget = true;
-            }
-            
-            for (int i = 0; i < attrs.getLength(); i++) {
-                String attrUri = attrs.getURI(i);
-                if (attrUri != null && !attrUri.equals("") && !attrUri.equals(uri)) {
-                    continue; // Ignore attributes from unknown uris
-                }
-                String key = attrs.getLocalName(i);
-                String value = attrs.getValue(i);
-
-                if (key.equals("name")) {
-                    name = value;
-                    if ("".equals(name)) {
-                        throw new BuildException("name attribute must " + "not be empty");
-                    }
-                } else if (key.equals("depends")) {
-                    depends = value;
-                } else if (key.equals("if")) {
-                    target.setIf(value);
-                } else if (key.equals("unless")) {
-                    target.setUnless(value);
-                } else if (key.equals("id")) {
-                    if (value != null && !value.equals("")) {
-                        context.getProject().addReference(value, target);
-                    }
-                } else if (key.equals("description")) {
-                    target.setDescription(value);
-                } else if (key.equals("extensionOf")) {
-                    extensionPoint = value;
-                } else if (key.equals("onMissingExtensionPoint")) {
-                    try {
-                        extensionPointMissing = OnMissingExtensionPoint.valueOf(value);
-                    } catch (IllegalArgumentException e) {
-                        throw new BuildException("Invalid onMissingExtensionPoint " + value);
-                    }
-                } else {
-                    throw new SAXParseException("Unexpected attribute \"" + key + "\"", context
-                                                .getLocator());
-                }
-            }
-
-            if (name == null) {
-                throw new SAXParseException("target element appears without a name attribute",
-                                            context.getLocator());
-            }
-
-            String prefix = null;
-            boolean isInIncludeMode =
-                context.isIgnoringProjectTag() && isInIncludeMode();
-            String sep = getCurrentPrefixSeparator();
-
-            if (isInIncludeMode) {
-                prefix = getTargetPrefix(context);
-                if (prefix == null) {
-                    throw new BuildException("can't include build file "
-                                             + context.getBuildFileURL()
-                                             + ", no as attribute has been given"
-                                             + " and the project tag doesn't"
-                                             + " specify a name attribute");
-                }
-                name = prefix + sep + name;
-            }
-
-            // Check if this target is in the current build file
-            if (context.getCurrentTargets().get(name) != null) {
-                throw new BuildException("Duplicate target '" + name + "'",
-                                         target.getLocation());
-            }
-            Hashtable projectTargets = project.getTargets();
-            boolean   usedTarget = false;
-            // If the name has not already been defined define it
-            if (projectTargets.containsKey(name)) {
-                project.log("Already defined in main or a previous import, ignore " + name,
-                            Project.MSG_VERBOSE);
-            } else {
-                target.setName(name);
-                context.getCurrentTargets().put(name, target);
-                project.addOrReplaceTarget(name, target);
-                usedTarget = true;
-            }
-
-            if (depends.length() > 0) {
-                if (!isInIncludeMode) {
-                    target.setDepends(depends);
-                } else {
-                    for (Iterator iter =
-                             Target.parseDepends(depends, name, "depends")
-                             .iterator();
-                         iter.hasNext(); ) {
-                        target.addDependency(prefix + sep + iter.next());
-                    }
-                }
-            }
-
-        	if(isTarget && name.equals(project.getBreakAt())) {
-        		// If the current element is a target and it is the same one as specified
-        		// for Ant to suspend execution at, then add an internal dependency on
-        		// the Debug Target
-        		DebugTask.createDebugTarget(project);
-        		
-        		// add this dependency to the end of the dependency list so that this target 
-        		// executes immediately ahead of the -breakAt target
-        		target.addDependency(DebugTask.DEBUG_TARGET_NAME);
-        	}
-
-            if (!isInIncludeMode && context.isIgnoringProjectTag()
-                && (prefix = getTargetPrefix(context)) != null) {
-                // In an imported file (and not completely
-                // ignoring the project tag or having a preconfigured prefix)
-                String newName = prefix + sep + name;
-                Target newTarget = usedTarget ? new Target(target) : target;
-                newTarget.setName(newName);
-                context.getCurrentTargets().put(newName, newTarget);
-                project.addOrReplaceTarget(newName, newTarget);
-            }
-            if (extensionPointMissing != null && extensionPoint == null) {
-                throw new BuildException("onMissingExtensionPoint attribute cannot " +
-                                         "be specified unless extensionOf is specified", 
-                                         target.getLocation());
-
-            }
-            if (extensionPoint != null) {
-                ProjectHelper helper =
-                    (ProjectHelper) context.getProject().
-                    getReference(ProjectHelper.PROJECTHELPER_REFERENCE);
-                for (Iterator iter =
-                         Target.parseDepends(extensionPoint, name, "extensionOf")
-                         .iterator();
-                     iter.hasNext(); ) {
-                    String tgName = (String) iter.next();
-                    if (isInIncludeMode()) {
-                        tgName = prefix + sep + tgName;
-                    }
-                    if (extensionPointMissing == null) {
-                        extensionPointMissing = OnMissingExtensionPoint.FAIL;
-                    }
-                    // defer extensionpoint resolution until the full
-                    // import stack has been processed
-                    helper.getExtensionStack().add(new String[] {
-                            tgName, name, extensionPointMissing.name() });
-                }
-            }
-        }
-
-        private String getTargetPrefix(AntXMLContext context) {
-            String configuredValue = getCurrentTargetPrefix();
-            if (configuredValue != null && configuredValue.length() == 0) {
-                configuredValue = null;
-            }
-            if (configuredValue != null) {
-                return configuredValue;
-            }
-
-            String projectName = context.getCurrentProjectName();
-            if ("".equals(projectName)) {
-                projectName = null;
-            }
-
-            return projectName;
-        }
-
-        /**
-         * Handles the start of an element within a target.
-         *
-         * @param uri The namespace URI for this element.
-         * @param name The name of the element being started.
-         *            Will not be <code>null</code>.
-         * @param qname The qualified name for this element.
-         * @param attrs Attributes of the element being started.
-         *              Will not be <code>null</code>.
-         * @param context The current context.
-         * @return an element handler.
-         *
-         * @exception SAXParseException if an error occurs when initialising
-         *                              the appropriate child handler
-         */
-        public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
-                                       AntXMLContext context) throws SAXParseException {
-            return ProjectHelper2.elementHandler;
-        }
-
-        /**
-         * Handle the end of the project, sets the current target of the
-         * context to be the implicit target.
-         *
-         * @param uri The namespace URI of the element.
-         * @param tag The name of the element.
-         * @param context The current context.
-         */
-        public void onEndElement(String uri, String tag, AntXMLContext context) {
-            context.setCurrentTarget(context.getImplicitTarget());
-        }
-    }
-
-    /**
-     * Handler for all project elements ( tasks, data types )
-     */
-    public static class ElementHandler extends AntHandler {
-
-        /**
-         * Constructor.
-         */
-        public ElementHandler() {
-        }
-
-        /**
-         * Initialisation routine called after handler creation
-         * with the element name and attributes. This configures
-         * the element with its attributes and sets it up with
-         * its parent container (if any). Nested elements are then
-         * added later as the parser encounters them.
-         *
-         * @param uri The namespace URI for this element.
-         * @param tag Name of the element which caused this handler
-         *            to be created. Must not be <code>null</code>.
-         * @param qname The qualified name for this element.
-         * @param attrs Attributes of the element which caused this
-         *              handler to be created. Must not be <code>null</code>.
-         * @param context The current context.
-         *
-         * @exception SAXParseException in case of error (not thrown in
-         *                              this implementation)
-         */
-        public void onStartElement(String uri, String tag, String qname, Attributes attrs,
-                                   AntXMLContext context) throws SAXParseException {
-            RuntimeConfigurable parentWrapper = context.currentWrapper();
-            Object parent = null;
-
-            if (parentWrapper != null) {
-                parent = parentWrapper.getProxy();
-            }
-
-            /* UnknownElement is used for tasks and data types - with
-               delayed eval */
-            UnknownElement task = new UnknownElement(tag);
-            task.setProject(context.getProject());
-            task.setNamespace(uri);
-            task.setQName(qname);
-            task.setTaskType(ProjectHelper.genComponentName(task.getNamespace(), tag));
-            task.setTaskName(qname);
-
-            Location location = new Location(context.getLocator().getSystemId(), context
-                                             .getLocator().getLineNumber(), context.getLocator().getColumnNumber());
-            task.setLocation(location);
-            task.setOwningTarget(context.getCurrentTarget());
-
-            if (parent != null) {
-                // Nested element
-                ((UnknownElement) parent).addChild(task);
-            }  else {
-                // Task included in a target ( including the default one ).
-                context.getCurrentTarget().addTask(task);
-            }
-
-            context.configureId(task, attrs);
-
-            // container.addTask(task);
-            // This is a nop in UE: task.init();
-
-            RuntimeConfigurable wrapper = new RuntimeConfigurable(task, task.getTaskName());
-
-            for (int i = 0; i < attrs.getLength(); i++) {
-                String name = attrs.getLocalName(i);
-                String attrUri = attrs.getURI(i);
-                if (attrUri != null && !attrUri.equals("") && !attrUri.equals(uri)) {
-                    name = attrUri + ":" + attrs.getQName(i);
-                }
-                String value = attrs.getValue(i);
-                // PR: Hack for ant-type value
-                //  an ant-type is a component name which can
-                // be namespaced, need to extract the name
-                // and convert from qualified name to uri/name
-                if (ANT_TYPE.equals(name)
-                    || (ANT_CORE_URI.equals(attrUri)
-                        && ANT_TYPE.equals(attrs.getLocalName(i)))) {
-                    name = ANT_TYPE;
-                    int index = value.indexOf(":");
-                    if (index >= 0) {
-                        String prefix = value.substring(0, index);
-                        String mappedUri = context.getPrefixMapping(prefix);
-                        if (mappedUri == null) {
-                            throw new BuildException("Unable to find XML NS prefix \"" + prefix
-                                                     + "\"");
-                        }
-                        value = ProjectHelper.genComponentName(mappedUri, value
-                                                               .substring(index + 1));
-                    }
-                }
-                wrapper.setAttribute(name, value);
-            }
-            if (parentWrapper != null) {
-                parentWrapper.addChild(wrapper);
-            }
-            context.pushWrapper(wrapper);
-        }
-
-        /**
-         * Adds text to the task, using the wrapper
-         *
-         * @param buf A character array of the text within the element.
-         *            Will not be <code>null</code>.
-         * @param start The start element in the array.
-         * @param count The number of characters to read from the array.
-         * @param context The current context.
-         *
-         * @exception SAXParseException if the element doesn't support text
-         *
-         * @see ProjectHelper#addText(Project,java.lang.Object,char[],int,int)
-         */
-        public void characters(char[] buf, int start, int count,
-                               AntXMLContext context) throws SAXParseException {
-            RuntimeConfigurable wrapper = context.currentWrapper();
-            wrapper.addText(buf, start, count);
-        }
-
-        /**
-         * Handles the start of an element within a target. Task containers
-         * will always use another task handler, and all other tasks
-         * will always use a nested element handler.
-         *
-         * @param uri The namespace URI for this element.
-         * @param tag The name of the element being started.
-         *            Will not be <code>null</code>.
-         * @param qname The qualified name for this element.
-         * @param attrs Attributes of the element being started.
-         *              Will not be <code>null</code>.
-         * @param context The current context.
-         * @return The handler for elements.
-         *
-         * @exception SAXParseException if an error occurs when initialising
-         *                              the appropriate child handler
-         */
-        public AntHandler onStartChild(String uri, String tag, String qname, Attributes attrs,
-                                       AntXMLContext context) throws SAXParseException {
-            return ProjectHelper2.elementHandler;
-        }
-
-        /**
-         * Handles the end of the element. This pops the wrapper from
-         * the context.
-         *
-         * @param uri The namespace URI for the element.
-         * @param tag The name of the element.
-         * @param context The current context.
-         */
-        public void onEndElement(String uri, String tag, AntXMLContext context) {
-            context.popWrapper();
-        }
-    }
-}
diff --git a/command-line-debugger/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/command-line-debugger/src/main/org/apache/tools/ant/taskdefs/defaults.properties
deleted file mode 100644
index 435a1a2..0000000
--- a/command-line-debugger/src/main/org/apache/tools/ant/taskdefs/defaults.properties
+++ /dev/null
@@ -1,233 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# standard ant tasks
-ant=org.apache.tools.ant.taskdefs.Ant
-antcall=org.apache.tools.ant.taskdefs.CallTarget
-antstructure=org.apache.tools.ant.taskdefs.AntStructure
-antversion=org.apache.tools.ant.taskdefs.condition.AntVersion
-apply=org.apache.tools.ant.taskdefs.Transform
-apt=org.apache.tools.ant.taskdefs.Apt
-augment=org.apache.tools.ant.taskdefs.AugmentReference
-available=org.apache.tools.ant.taskdefs.Available
-basename=org.apache.tools.ant.taskdefs.Basename
-bindtargets=org.apache.tools.ant.taskdefs.BindTargets
-buildnumber=org.apache.tools.ant.taskdefs.BuildNumber
-bunzip2=org.apache.tools.ant.taskdefs.BUnzip2
-bzip2=org.apache.tools.ant.taskdefs.BZip2
-checksum=org.apache.tools.ant.taskdefs.Checksum
-chmod=org.apache.tools.ant.taskdefs.Chmod
-classloader=org.apache.tools.ant.taskdefs.Classloader
-componentdef=org.apache.tools.ant.taskdefs.Componentdef
-concat=org.apache.tools.ant.taskdefs.Concat
-condition=org.apache.tools.ant.taskdefs.ConditionTask
-copy=org.apache.tools.ant.taskdefs.Copy
-cvs=org.apache.tools.ant.taskdefs.Cvs
-cvschangelog=org.apache.tools.ant.taskdefs.cvslib.ChangeLogTask
-cvspass=org.apache.tools.ant.taskdefs.CVSPass
-cvstagdiff=org.apache.tools.ant.taskdefs.cvslib.CvsTagDiff
-cvsversion=org.apache.tools.ant.taskdefs.cvslib.CvsVersion
-defaultexcludes=org.apache.tools.ant.taskdefs.DefaultExcludes
-delete=org.apache.tools.ant.taskdefs.Delete
-dependset=org.apache.tools.ant.taskdefs.DependSet
-diagnostics=org.apache.tools.ant.taskdefs.DiagnosticsTask
-dirname=org.apache.tools.ant.taskdefs.Dirname
-ear=org.apache.tools.ant.taskdefs.Ear
-echo=org.apache.tools.ant.taskdefs.Echo
-echoproperties=org.apache.tools.ant.taskdefs.optional.EchoProperties
-echoxml=org.apache.tools.ant.taskdefs.EchoXML
-exec=org.apache.tools.ant.taskdefs.ExecTask
-fail=org.apache.tools.ant.taskdefs.Exit
-filter=org.apache.tools.ant.taskdefs.Filter
-fixcrlf=org.apache.tools.ant.taskdefs.FixCRLF
-#funtest=org.apache.tools.ant.taskdefs.optional.testing.Funtest
-genkey=org.apache.tools.ant.taskdefs.GenerateKey
-get=org.apache.tools.ant.taskdefs.Get
-gunzip=org.apache.tools.ant.taskdefs.GUnzip
-gzip=org.apache.tools.ant.taskdefs.GZip
-hostinfo=org.apache.tools.ant.taskdefs.HostInfo
-import=org.apache.tools.ant.taskdefs.ImportTask
-include=org.apache.tools.ant.taskdefs.ImportTask
-input=org.apache.tools.ant.taskdefs.Input
-jar=org.apache.tools.ant.taskdefs.Jar
-java=org.apache.tools.ant.taskdefs.Java
-javac=org.apache.tools.ant.taskdefs.Javac
-javadoc=org.apache.tools.ant.taskdefs.Javadoc
-length=org.apache.tools.ant.taskdefs.Length
-loadfile=org.apache.tools.ant.taskdefs.LoadFile
-loadproperties=org.apache.tools.ant.taskdefs.LoadProperties
-loadresource=org.apache.tools.ant.taskdefs.LoadResource
-local=org.apache.tools.ant.taskdefs.Local
-macrodef=org.apache.tools.ant.taskdefs.MacroDef
-mail=org.apache.tools.ant.taskdefs.email.EmailTask
-makeurl=org.apache.tools.ant.taskdefs.MakeUrl
-manifest=org.apache.tools.ant.taskdefs.ManifestTask
-manifestclasspath=org.apache.tools.ant.taskdefs.ManifestClassPath
-mkdir=org.apache.tools.ant.taskdefs.Mkdir
-move=org.apache.tools.ant.taskdefs.Move
-nice=org.apache.tools.ant.taskdefs.Nice
-parallel=org.apache.tools.ant.taskdefs.Parallel
-patch=org.apache.tools.ant.taskdefs.Patch
-pathconvert=org.apache.tools.ant.taskdefs.PathConvert
-presetdef=org.apache.tools.ant.taskdefs.PreSetDef
-projecthelper=org.apache.tools.ant.taskdefs.ProjectHelperTask
-property=org.apache.tools.ant.taskdefs.Property
-propertyhelper=org.apache.tools.ant.taskdefs.PropertyHelperTask
-record=org.apache.tools.ant.taskdefs.Recorder
-replace=org.apache.tools.ant.taskdefs.Replace
-resourcecount=org.apache.tools.ant.taskdefs.ResourceCount
-retry=org.apache.tools.ant.taskdefs.Retry
-rmic=org.apache.tools.ant.taskdefs.Rmic
-sequential=org.apache.tools.ant.taskdefs.Sequential
-signjar=org.apache.tools.ant.taskdefs.SignJar
-sleep=org.apache.tools.ant.taskdefs.Sleep
-sql=org.apache.tools.ant.taskdefs.SQLExec
-subant=org.apache.tools.ant.taskdefs.SubAnt
-sync=org.apache.tools.ant.taskdefs.Sync
-tar=org.apache.tools.ant.taskdefs.Tar
-taskdef=org.apache.tools.ant.taskdefs.Taskdef
-tempfile=org.apache.tools.ant.taskdefs.TempFile
-touch=org.apache.tools.ant.taskdefs.Touch
-tstamp=org.apache.tools.ant.taskdefs.Tstamp
-truncate=org.apache.tools.ant.taskdefs.Truncate
-typedef=org.apache.tools.ant.taskdefs.Typedef
-unjar=org.apache.tools.ant.taskdefs.Expand
-untar=org.apache.tools.ant.taskdefs.Untar
-unwar=org.apache.tools.ant.taskdefs.Expand
-unzip=org.apache.tools.ant.taskdefs.Expand
-uptodate=org.apache.tools.ant.taskdefs.UpToDate
-waitfor=org.apache.tools.ant.taskdefs.WaitFor
-war=org.apache.tools.ant.taskdefs.War
-whichresource=org.apache.tools.ant.taskdefs.WhichResource
-xmlproperty=org.apache.tools.ant.taskdefs.XmlProperty
-xslt=org.apache.tools.ant.taskdefs.XSLTProcess
-zip=org.apache.tools.ant.taskdefs.Zip
-
-# optional tasks
-antlr=org.apache.tools.ant.taskdefs.optional.ANTLR
-attrib=org.apache.tools.ant.taskdefs.optional.windows.Attrib
-blgenclient=org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient
-cab=org.apache.tools.ant.taskdefs.optional.Cab
-cccheckin=org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckin
-cccheckout=org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckout
-cclock=org.apache.tools.ant.taskdefs.optional.clearcase.CCLock
-ccmcheckin=org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckin
-ccmcheckintask=org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckinDefault
-ccmcheckout=org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckout
-ccmcreatetask=org.apache.tools.ant.taskdefs.optional.ccm.CCMCreateTask
-ccmkattr=org.apache.tools.ant.taskdefs.optional.clearcase.CCMkattr
-ccmkbl=org.apache.tools.ant.taskdefs.optional.clearcase.CCMkbl
-ccmkdir=org.apache.tools.ant.taskdefs.optional.clearcase.CCMkdir
-ccmkelem=org.apache.tools.ant.taskdefs.optional.clearcase.CCMkelem
-ccmklabel=org.apache.tools.ant.taskdefs.optional.clearcase.CCMklabel
-ccmklbtype=org.apache.tools.ant.taskdefs.optional.clearcase.CCMklbtype
-ccmreconfigure=org.apache.tools.ant.taskdefs.optional.ccm.CCMReconfigure
-ccrmtype=org.apache.tools.ant.taskdefs.optional.clearcase.CCRmtype
-ccuncheckout=org.apache.tools.ant.taskdefs.optional.clearcase.CCUnCheckout
-ccunlock=org.apache.tools.ant.taskdefs.optional.clearcase.CCUnlock
-ccupdate=org.apache.tools.ant.taskdefs.optional.clearcase.CCUpdate
-chgrp=org.apache.tools.ant.taskdefs.optional.unix.Chgrp
-chown=org.apache.tools.ant.taskdefs.optional.unix.Chown
-ddcreator=org.apache.tools.ant.taskdefs.optional.ejb.DDCreator
-depend=org.apache.tools.ant.taskdefs.optional.depend.Depend
-ejbc=org.apache.tools.ant.taskdefs.optional.ejb.Ejbc
-ejbjar=org.apache.tools.ant.taskdefs.optional.ejb.EjbJar
-ftp=org.apache.tools.ant.taskdefs.optional.net.FTP
-image=org.apache.tools.ant.taskdefs.optional.image.Image
-iplanet-ejbc=org.apache.tools.ant.taskdefs.optional.ejb.IPlanetEjbcTask
-jarlib-available=org.apache.tools.ant.taskdefs.optional.extension.JarLibAvailableTask
-jarlib-display=org.apache.tools.ant.taskdefs.optional.extension.JarLibDisplayTask
-jarlib-manifest=org.apache.tools.ant.taskdefs.optional.extension.JarLibManifestTask
-jarlib-resolve=org.apache.tools.ant.taskdefs.optional.extension.JarLibResolveTask
-javacc=org.apache.tools.ant.taskdefs.optional.javacc.JavaCC
-javah=org.apache.tools.ant.taskdefs.optional.Javah
-jdepend=org.apache.tools.ant.taskdefs.optional.jdepend.JDependTask
-jjdoc=org.apache.tools.ant.taskdefs.optional.javacc.JJDoc
-jjtree=org.apache.tools.ant.taskdefs.optional.javacc.JJTree
-junit=org.apache.tools.ant.taskdefs.optional.junit.JUnitTask
-junitreport=org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator
-native2ascii=org.apache.tools.ant.taskdefs.optional.Native2Ascii
-netrexxc=org.apache.tools.ant.taskdefs.optional.NetRexxC
-p4add=org.apache.tools.ant.taskdefs.optional.perforce.P4Add
-p4change=org.apache.tools.ant.taskdefs.optional.perforce.P4Change
-p4counter=org.apache.tools.ant.taskdefs.optional.perforce.P4Counter
-p4delete=org.apache.tools.ant.taskdefs.optional.perforce.P4Delete
-p4edit=org.apache.tools.ant.taskdefs.optional.perforce.P4Edit
-p4fstat=org.apache.tools.ant.taskdefs.optional.perforce.P4Fstat
-p4have=org.apache.tools.ant.taskdefs.optional.perforce.P4Have
-p4integrate=org.apache.tools.ant.taskdefs.optional.perforce.P4Integrate
-p4label=org.apache.tools.ant.taskdefs.optional.perforce.P4Label
-p4labelsync=org.apache.tools.ant.taskdefs.optional.perforce.P4Labelsync
-p4reopen=org.apache.tools.ant.taskdefs.optional.perforce.P4Reopen
-p4resolve=org.apache.tools.ant.taskdefs.optional.perforce.P4Resolve
-p4revert=org.apache.tools.ant.taskdefs.optional.perforce.P4Revert
-p4submit=org.apache.tools.ant.taskdefs.optional.perforce.P4Submit
-p4sync=org.apache.tools.ant.taskdefs.optional.perforce.P4Sync
-propertyfile=org.apache.tools.ant.taskdefs.optional.PropertyFile
-pvcs=org.apache.tools.ant.taskdefs.optional.pvcs.Pvcs
-replaceregexp=org.apache.tools.ant.taskdefs.optional.ReplaceRegExp
-rexec=org.apache.tools.ant.taskdefs.optional.net.RExecTask
-rpm=org.apache.tools.ant.taskdefs.optional.Rpm
-schemavalidate=org.apache.tools.ant.taskdefs.optional.SchemaValidate
-scp=org.apache.tools.ant.taskdefs.optional.ssh.Scp
-script=org.apache.tools.ant.taskdefs.optional.Script
-scriptdef=org.apache.tools.ant.taskdefs.optional.script.ScriptDef
-serverdeploy=org.apache.tools.ant.taskdefs.optional.j2ee.ServerDeploy
-setproxy=org.apache.tools.ant.taskdefs.optional.net.SetProxy
-soscheckin=org.apache.tools.ant.taskdefs.optional.sos.SOSCheckin
-soscheckout=org.apache.tools.ant.taskdefs.optional.sos.SOSCheckout
-sosget=org.apache.tools.ant.taskdefs.optional.sos.SOSGet
-soslabel=org.apache.tools.ant.taskdefs.optional.sos.SOSLabel
-sound=org.apache.tools.ant.taskdefs.optional.sound.SoundTask
-splash=org.apache.tools.ant.taskdefs.optional.splash.SplashTask
-sshexec=org.apache.tools.ant.taskdefs.optional.ssh.SSHExec
-sshsession=org.apache.tools.ant.taskdefs.optional.ssh.SSHSession
-stcheckin=org.apache.tools.ant.taskdefs.optional.starteam.StarTeamCheckin
-stcheckout=org.apache.tools.ant.taskdefs.optional.starteam.StarTeamCheckout
-stlabel=org.apache.tools.ant.taskdefs.optional.starteam.StarTeamLabel
-stlist=org.apache.tools.ant.taskdefs.optional.starteam.StarTeamList
-symlink=org.apache.tools.ant.taskdefs.optional.unix.Symlink
-telnet=org.apache.tools.ant.taskdefs.optional.net.TelnetTask
-translate=org.apache.tools.ant.taskdefs.optional.i18n.Translate
-verifyjar=org.apache.tools.ant.taskdefs.VerifyJar
-vssadd=org.apache.tools.ant.taskdefs.optional.vss.MSVSSADD
-vsscheckin=org.apache.tools.ant.taskdefs.optional.vss.MSVSSCHECKIN
-vsscheckout=org.apache.tools.ant.taskdefs.optional.vss.MSVSSCHECKOUT
-vsscp=org.apache.tools.ant.taskdefs.optional.vss.MSVSSCP
-vsscreate=org.apache.tools.ant.taskdefs.optional.vss.MSVSSCREATE
-vssget=org.apache.tools.ant.taskdefs.optional.vss.MSVSSGET
-vsshistory=org.apache.tools.ant.taskdefs.optional.vss.MSVSSHISTORY
-vsslabel=org.apache.tools.ant.taskdefs.optional.vss.MSVSSLABEL
-wljspc=org.apache.tools.ant.taskdefs.optional.jsp.WLJspc
-wlrun=org.apache.tools.ant.taskdefs.optional.ejb.WLRun
-wlstop=org.apache.tools.ant.taskdefs.optional.ejb.WLStop
-xmlvalidate=org.apache.tools.ant.taskdefs.optional.XMLValidateTask
-
-
-# deprecated ant tasks (kept for back compatibility)
-copydir=org.apache.tools.ant.taskdefs.Copydir
-copyfile=org.apache.tools.ant.taskdefs.Copyfile
-copypath=org.apache.tools.ant.taskdefs.CopyPath
-deltree=org.apache.tools.ant.taskdefs.Deltree
-execon=org.apache.tools.ant.taskdefs.ExecuteOn
-javadoc2=org.apache.tools.ant.taskdefs.Javadoc
-jlink=org.apache.tools.ant.taskdefs.optional.jlink.JlinkTask
-jspc=org.apache.tools.ant.taskdefs.optional.jsp.JspC
-mimemail=org.apache.tools.ant.taskdefs.optional.net.MimeMail
-rename=org.apache.tools.ant.taskdefs.Rename
-renameext=org.apache.tools.ant.taskdefs.optional.RenameExtensions
-starteam=org.apache.tools.ant.taskdefs.optional.scm.AntStarTeamCheckOut
-style=org.apache.tools.ant.taskdefs.XSLTProcess
-debug=org.apache.tools.ant.DebugTask
\ No newline at end of file
