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