diff --git a/command-line-debugger/patch/patch.txt b/command-line-debugger/patch/patch.txt
new file mode 100644
index 0000000..4ff785a
--- /dev/null
+++ b/command-line-debugger/patch/patch.txt
@@ -0,0 +1,5307 @@
+Index: src/main/org/apache/tools/ant/helper/ProjectHelper2.java
+===================================================================
+--- src/main/org/apache/tools/ant/helper/ProjectHelper2.java	(revision 1132883)
++++ src/main/org/apache/tools/ant/helper/ProjectHelper2.java	(working copy)
+@@ -27,6 +27,7 @@
+ 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;
+@@ -923,7 +924,11 @@
+             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)) {
+@@ -1015,6 +1020,18 @@
+                     }
+                 }
+             }
++
++        	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
+Index: src/main/org/apache/tools/ant/Project.java
+===================================================================
+--- src/main/org/apache/tools/ant/Project.java	(revision 1132883)
++++ src/main/org/apache/tools/ant/Project.java	(working copy)
+@@ -17,29 +17,30 @@
+  */
+ package org.apache.tools.ant;
+ 
++import java.io.EOFException;
+ 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.HashMap;
++import java.util.HashSet;
+ import java.util.Hashtable;
++import java.util.Map;
+ import java.util.Properties;
++import java.util.Set;
+ 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.helper.DefaultExecutor;
+ 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.Description;
+ 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;
+@@ -51,2426 +52,2586 @@
+ 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.
++ * 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.
+- *
++ * 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;
++	/** 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";
++	/**
++	 * 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;
++	/**
++	 * 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;
++	/** 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();
++	/** 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;
++	/** 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 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();
+ 
+-    /** 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;
+ 
+-    /** 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;
+ 
+-    /** 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);
++	}
+ 
+-    /** 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);
+ 
+-    /**
+-     * 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;
+ 
+-    /** Project base directory. */
+-    private File baseDir;
++	/** lock object used when adding/removing listeners */
++	private final Object listenersLock = new Object();
+ 
+-    /** 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];
+ 
+-    /** 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;
++		}
++	};
+ 
+-    /** 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;
+ 
+-    /**
+-     * 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. */
+-    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());
+ 
+-    /** 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;
+ 
+-    /**
+-     * Called to handle any input requests.
+-     */
+-    private InputHandler inputHandler = null;
++	/**
++	 * The default input stream used to read any input.
++	 */
++	private InputStream defaultInputStream = null;
+ 
+-    /**
+-     * The default input stream used to read any input.
+-     */
+-    private InputStream defaultInputStream = null;
++	/**
++	 * Keep going flag.
++	 */
++	private boolean keepGoingMode = false;
+ 
+-    /**
+-     * Keep going flag.
+-     */
+-    private boolean keepGoingMode = false;
++	/**
++	 * Set the input handler.
++	 * 
++	 * @param handler
++	 *            the InputHandler instance to use for gathering input.
++	 */
++	public void setInputHandler(InputHandler handler) {
++		inputHandler = handler;
++	}
+ 
+-    /**
+-     * 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;
++	}
+ 
+-    /**
+-     * 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;
++	}
+ 
+-    /**
+-     * 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;
++	}
+ 
+-    /**
+-     * 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 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;
++	}
+ 
+-    /**
+-     * 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());
++	}
+ 
+-    /**
+-     * 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();
+ 
+-    /**
+-     * 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();
++	}
+ 
+-        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();
++	}
+ 
+-    /**
+-     * 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());
++		}
++	}
+ 
+-    /**
+-     * 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 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);
+-    }
++	/**
++	 * 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;
+-    }
++	/**
++	 * 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;
+-    }
++	/**
++	 * 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;
+-        }
+-    }
++	/**
++	 * 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;
+-                }
+-            }
+-        }
+-    }
++	/**
++	 * 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;
+-        }
+-    }
++	/**
++	 * 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>.
+-     */
++	/**
++	 * 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);
+-    }
++	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 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 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 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 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 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);
+-    }
++	/**
++	 * 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;
+-    }
++	/**
++	 * 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. 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 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.
++	 * 
++	 * @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 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);
+-    }
++	/**
++	 * 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);
+-    }
++	/**
++	 * 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);
+-    }
++	/**
++	 * 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 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 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 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();
+-    }
++	/**
++	 * 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 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);
+-    }
++	/**
++	 * 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);
+-    }
++	/**
++	 * 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;
+-    }
++	/**
++	 * 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 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;
+-    }
++	/**
++	 * 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;
+-    }
++	/**
++	 * 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;
+-    }
++	/**
++	 * 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;
+-    }
++	/**
++	 * 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));
+-    }
++	/**
++	 * 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();
+-    }
++	/**
++	 * 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 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);
+-    }
++	/**
++	 * 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;
+-    }
++	/**
++	 * 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;
+-    }
++	/**
++	 * 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 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();
+-    }
++	/**
++	 * 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);
++	/**
++	 * 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);
++		// 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);
+-    }
++		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 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);
+-    }
++	/**
++	 * 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);
++	/**
++	 * 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);
+-        }
+-    }
++		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 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());
+-    }
++	/**
++	 * 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);
+-    }
++	/**
++	 * 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 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());
+-    }
++	/**
++	 * 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 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 <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 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);
+-    }
++	/**
++	 * 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 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);
+-    }
++	/**
++	 * 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 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);
+-    }
++	/**
++	 * 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);
+-    }
++	/**
++	 * 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;
+-    }
++	/**
++	 * 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()])));
+-    }
++	/**
++	 * 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);
+-            }
+-        }
+-    }
++	/**
++	 * 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");
+-        }
+-    }
++	/**
++	 * 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);
+-        }
+-    }
++	/**
++	 * 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);
+-            }
+-        }
+-    }
++	/**
++	 * 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 {
++	/**
++	 * 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
++		// 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);
+-        }
++		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));
+-    }
++		// 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;
+-        }
+-    }
++	protected String breakAt;
++	
++	public void setBreakAt(String breakAt) {
++		this.breakAt = breakAt;
++	}
++	
++	public String getBreakAt() {
++		return breakAt;
++	}
++	
++	/**
++	 * 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
++//		int i = -1;
++//		for (Enumeration iter = sortedTargets.elements(); iter
++//				.hasMoreElements() && getBreakAt() != null && getBreakAt().trim().length() > 0;) {
++//			i++;
++//			Target curTarget = (Target) iter.nextElement();
++//			if(curTarget.getName().equals(getBreakAt())) {
++//				log("Adding default DebugTarget");
++//				sortedTargets.add(i, DebugTask.createDebugTarget(this));
++//				break;
++//			}
++//		}
++		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
++	 * 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);
+-    }
++	/**
++	 * 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);
+-    }
++	/**
++	 * 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. 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.
++	 * 
++	 * @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 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
++	 * 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. 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.
++	 * 
++	 * @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 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);
+-    }
++	/**
++	 * 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);
+-    }
++	/**
++	 * 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));
+-    }
++	/**
++	 * 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;
+-    }
++	/**
++	 * 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, 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. 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();
++	/**
++	 * 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.
++		// 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 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);
++		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;
+-    }
++		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);
++	/**
++	 * 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);
++		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);
+-    }
++		// 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));
+-    }
++	/**
++	 * 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;
+-    }
++	/**
++	 * 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 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);
+-    }
++	/**
++	 * 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;
+-    }
++	/**
++	 * 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);
+-    }
++	/**
++	 * 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);
+-    }
++	/**
++	 * 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;
+-    }
++	/**
++	 * 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);
+-    }
++	/**
++	 * 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 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;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 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;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 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;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 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;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) {
++	/**
++	 * 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);
+-        }
+-    }
++		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 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; 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 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; 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 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);
+-    }
++	/**
++	 * 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());
+-            }
+-        }
+-    }
++	/**
++	 * 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;
+-        }
+-    }
++	/**
++	 * 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 {
+ 
+-    // Should move to a separate public class - and have API to add
+-    // listeners, etc.
+-    private static class AntRefTable extends Hashtable {
++		AntRefTable() {
++			super();
++		}
+ 
+-        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);
++		}
+ 
+-        /** 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;
++		}
++	}
+ 
+-        /** 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.
++		}
++	}
+ 
+-    /**
+-     * 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);
+-    }
++	/**
++	 * 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);
++	}
+ }
+Index: src/main/org/apache/tools/ant/DebugTask.java
+===================================================================
+--- src/main/org/apache/tools/ant/DebugTask.java	(revision 0)
++++ src/main/org/apache/tools/ant/DebugTask.java	(revision 0)
+@@ -0,0 +1,329 @@
++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");
++		}
++	}
++}
+
+Property changes on: src\main\org\apache\tools\ant\DebugTask.java
+___________________________________________________________________
+Added: svn:eol-style
+   + native
+
+Index: src/main/org/apache/tools/ant/taskdefs/defaults.properties
+===================================================================
+--- src/main/org/apache/tools/ant/taskdefs/defaults.properties	(revision 1132883)
++++ src/main/org/apache/tools/ant/taskdefs/defaults.properties	(working copy)
+@@ -230,3 +230,4 @@
+ 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
+Index: src/main/org/apache/tools/ant/Main.java
+===================================================================
+--- src/main/org/apache/tools/ant/Main.java	(revision 1132883)
++++ src/main/org/apache/tools/ant/Main.java	(working copy)
+@@ -149,6 +149,11 @@
+     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>.
+      *
+@@ -382,6 +387,8 @@
+                 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;
+@@ -761,7 +768,7 @@
+ 
+ 
+                 project.init();
+-
++                project.setBreakAt(breakAt);
+                 // resolve properties
+                 PropertyHelper propertyHelper
+                     = (PropertyHelper) PropertyHelper.getPropertyHelper(project);
diff --git a/command-line-debugger/patch/status.txt b/command-line-debugger/patch/status.txt
new file mode 100644
index 0000000..9ccb7aa
--- /dev/null
+++ b/command-line-debugger/patch/status.txt
@@ -0,0 +1,5 @@
+M       src\main\org\apache\tools\ant\helper\ProjectHelper2.java
+M       src\main\org\apache\tools\ant\Project.java
+A       src\main\org\apache\tools\ant\DebugTask.java
+M       src\main\org\apache\tools\ant\taskdefs\defaults.properties
+M       src\main\org\apache\tools\ant\Main.java
\ No newline at end of file
