You are viewing a plain text version of this content. The canonical link for it is here.
Posted to easyant-commits@incubator.apache.org by hi...@apache.org on 2011/02/22 15:56:09 UTC

svn commit: r1073371 [12/28] - in /incubator/easyant/core/trunk: ./ bin/ example/build-configurations/ example/build-configurations/src/main/java/org/apache/easyant/example/ example/build-configurations/src/test/java/org/apache/easyant/example/ example...

Modified: incubator/easyant/core/trunk/src/main/java/org/apache/easyant/core/EasyAntMagicNames.java
URL: http://svn.apache.org/viewvc/incubator/easyant/core/trunk/src/main/java/org/apache/easyant/core/EasyAntMagicNames.java?rev=1073371&r1=1073370&r2=1073371&view=diff
==============================================================================
--- incubator/easyant/core/trunk/src/main/java/org/apache/easyant/core/EasyAntMagicNames.java (original)
+++ incubator/easyant/core/trunk/src/main/java/org/apache/easyant/core/EasyAntMagicNames.java Tue Feb 22 15:55:55 2011
@@ -28,149 +28,149 @@ import org.apache.easyant.tasks.CoreRevi
  */
 public interface EasyAntMagicNames {
 
-	/**
-	 * property for easyant file name. Value: {@value}
-	 */
-	public static final String EASYANT_FILE = "easyant.file";
-
-	/**
-	 * Name the default ivy instance name used by easyant Value: {@value}
-	 */
-	public static final String EASYANT_IVY_INSTANCE = "easyant.ivy.instance";
-
-	/**
-	 * Name of directory to store EasyAnt modules Value: {@value}
-	 */
-	public static final String EASYANT_MODULES_DIR = "easyant.modules.dir";
-
-	/**
-	 * Name the default ivy instance name used by projects Value: {@value}
-	 */
-	public static final String PROJECT_IVY_INSTANCE = "project.ivy.instance";
-
-	/**
-	 * Name of the property that contains the project ivy setting file Value: *
-	 * {@value}
-	 */
-	public static final String PROJECT_IVY_SETTING_FILE = "project.ivy.settings.file";
-
-	/**
-	 * Name of the property that contains the project ivy setting url Value: *
-	 * {@value}
-	 */
-	public static final String PROJECT_IVY_SETTING_URL = "project.ivy.settings.url";
-
-	/**
-	 * Name of the property that contains active build configuration Value: *
-	 * {@value}
-	 */
-	public static final String ACTIVE_BUILD_CONFIGURATIONS = "active.build.configurations";
-
-	/**
-	 * Name of the property that contains all active build configuration for the
-	 * current project Value: {@value}
-	 */
-	public static final String MAIN_CONFS = "main.confs";
-
-	/**
-	 * Name of the property that contains build configuration available in
-	 * current project Value: {@value}
-	 */
-	public static final String AVAILABLE_BUILD_CONFIGURATIONS = "available.build.configurations";
-
-	/**
-	 * Property name used to disable core revision check if this property is set
-	 * to true it means that corerevision checker feature will be disabled.
-	 * Value: {@value}
-	 * 
-	 * @see CoreRevisionCheckerTask
-	 */
-	public static final String SKIP_CORE_REVISION_CHECKER = "skip.corerevision.checker";
-
-	/**
-	 * Property name containing the target directory Value: {@value}
-	 */
-	public static final String TARGET = "target";
-
-	/**
-	 * Name of the plugin service instance Value: {@value}
-	 */
-	public static final String PLUGIN_SERVICE_INSTANCE = "plugin.service.instance";
-
-	/**
-	 * Name of the property containing the default location of ivysettings file
-	 * used by easyant ivy instance Value: {@value}
-	 */
-	public static final String EASYANT_DEFAULT_IVYSETTINGS = "easyant.default.ivysettings.url";
-
-	/**
-	 * Name of the property containing the default location of ivysettings file
-	 * used by easyant ivy instance with extra modules Value: {@value}
-	 */
-	public static final String EASYANT_EXTRA_IVYSETTINGS = "easyant.extra.ivysettings.url";
-
-	/**
-	 * Name of the property containing the default location of ivysettings file
-	 * used by project ivy instance Value: {@value}
-	 */
-	public static final String PROJECT_DEFAULT_IVYSETTINGS = "project.default.ivysettings.url";
-
-	/**
-	 * Name of the property containing the easyant core repository Value:
-	 * {@value}
-	 */
-	public static final String EASYANT_CORE_REPO_URL = "easyant.core.repo.url";
-
-	/**
-	 * Name of the property containing the easyant extra repository Value:
-	 * {@value}
-	 */
-	public static final String EASYANT_EXTRA_REPO_URL = "easyant.extramodules.repo.url";
-
-	/**
-	 * Name of the property containing the log stategy for easyant modules
-	 * Value: {@value}
-	 */
-	public static final String MODULE_DOWNLOAD_LOG = "easyant.modules.download.log";
-
-	/**
-	 * Name of the property containing the build-scoped repository name, if
-	 * configured Value: {@value}
-	 */
-	public static final String EASYANT_BUILD_REPOSITORY = "easyant.build.repository";
-
-	public static final String META_TARGET = "meta.target";
-
-	/**
-	 * Name of the property containing the appended to menu generator registry
-	 * references Value: {@value}
-	 */
-	public static final String MENU_GENERATOR_REGISTRY_REF = "menugen.ref";
-
-	/**
-	 * Name of the property containing pre module targets. In a multi project
-	 * context, those targets will be executed before delagating to subprojects.
-	 * Value : {@value}
-	 */
-	public static final String PRE_MODULE_TARGETS = "pre.module.targets";
-
-	/**
-	 * Name of the property containing path to user easyant ivysettings file
-	 * Value: {@value}
-	 */
-	public static final String USER_EASYANT_IVYSETTINGS = "user.easyant.ivysettings.file";
-
-	/**
-	 * Name of the property containing path to global easyant ivysettings file
-	 * Value: {@value}
-	 */
-	public static final String GLOBAL_EASYANT_IVYSETTINGS = "global.easyant.ivysettings.file";
-	
-	/**
-	 * Name of the property specifyinf if build repository should be used
-	 * Value: {@value}
-	 */
-	public static final String USE_BUILD_REPOSITORY = "use.build.repository";
+    /**
+     * property for easyant file name. Value: {@value}
+     */
+    public static final String EASYANT_FILE = "easyant.file";
+
+    /**
+     * Name the default ivy instance name used by easyant Value: {@value}
+     */
+    public static final String EASYANT_IVY_INSTANCE = "easyant.ivy.instance";
+
+    /**
+     * Name of directory to store EasyAnt modules Value: {@value}
+     */
+    public static final String EASYANT_MODULES_DIR = "easyant.modules.dir";
+
+    /**
+     * Name the default ivy instance name used by projects Value: {@value}
+     */
+    public static final String PROJECT_IVY_INSTANCE = "project.ivy.instance";
+
+    /**
+     * Name of the property that contains the project ivy setting file Value: *
+     * {@value}
+     */
+    public static final String PROJECT_IVY_SETTING_FILE = "project.ivy.settings.file";
+
+    /**
+     * Name of the property that contains the project ivy setting url Value: *
+     * {@value}
+     */
+    public static final String PROJECT_IVY_SETTING_URL = "project.ivy.settings.url";
+
+    /**
+     * Name of the property that contains active build configuration Value: *
+     * {@value}
+     */
+    public static final String ACTIVE_BUILD_CONFIGURATIONS = "active.build.configurations";
+
+    /**
+     * Name of the property that contains all active build configuration for the
+     * current project Value: {@value}
+     */
+    public static final String MAIN_CONFS = "main.confs";
+
+    /**
+     * Name of the property that contains build configuration available in
+     * current project Value: {@value}
+     */
+    public static final String AVAILABLE_BUILD_CONFIGURATIONS = "available.build.configurations";
+
+    /**
+     * Property name used to disable core revision check if this property is set
+     * to true it means that corerevision checker feature will be disabled.
+     * Value: {@value}
+     * 
+     * @see CoreRevisionCheckerTask
+     */
+    public static final String SKIP_CORE_REVISION_CHECKER = "skip.corerevision.checker";
+
+    /**
+     * Property name containing the target directory Value: {@value}
+     */
+    public static final String TARGET = "target";
+
+    /**
+     * Name of the plugin service instance Value: {@value}
+     */
+    public static final String PLUGIN_SERVICE_INSTANCE = "plugin.service.instance";
+
+    /**
+     * Name of the property containing the default location of ivysettings file
+     * used by easyant ivy instance Value: {@value}
+     */
+    public static final String EASYANT_DEFAULT_IVYSETTINGS = "easyant.default.ivysettings.url";
+
+    /**
+     * Name of the property containing the default location of ivysettings file
+     * used by easyant ivy instance with extra modules Value: {@value}
+     */
+    public static final String EASYANT_EXTRA_IVYSETTINGS = "easyant.extra.ivysettings.url";
+
+    /**
+     * Name of the property containing the default location of ivysettings file
+     * used by project ivy instance Value: {@value}
+     */
+    public static final String PROJECT_DEFAULT_IVYSETTINGS = "project.default.ivysettings.url";
+
+    /**
+     * Name of the property containing the easyant core repository Value:
+     * {@value}
+     */
+    public static final String EASYANT_CORE_REPO_URL = "easyant.core.repo.url";
+
+    /**
+     * Name of the property containing the easyant extra repository Value:
+     * {@value}
+     */
+    public static final String EASYANT_EXTRA_REPO_URL = "easyant.extramodules.repo.url";
+
+    /**
+     * Name of the property containing the log stategy for easyant modules
+     * Value: {@value}
+     */
+    public static final String MODULE_DOWNLOAD_LOG = "easyant.modules.download.log";
+
+    /**
+     * Name of the property containing the build-scoped repository name, if
+     * configured Value: {@value}
+     */
+    public static final String EASYANT_BUILD_REPOSITORY = "easyant.build.repository";
+
+    public static final String META_TARGET = "meta.target";
+
+    /**
+     * Name of the property containing the appended to menu generator registry
+     * references Value: {@value}
+     */
+    public static final String MENU_GENERATOR_REGISTRY_REF = "menugen.ref";
+
+    /**
+     * Name of the property containing pre module targets. In a multi project
+     * context, those targets will be executed before delagating to subprojects.
+     * Value : {@value}
+     */
+    public static final String PRE_MODULE_TARGETS = "pre.module.targets";
+
+    /**
+     * Name of the property containing path to user easyant ivysettings file
+     * Value: {@value}
+     */
+    public static final String USER_EASYANT_IVYSETTINGS = "user.easyant.ivysettings.file";
+
+    /**
+     * Name of the property containing path to global easyant ivysettings file
+     * Value: {@value}
+     */
+    public static final String GLOBAL_EASYANT_IVYSETTINGS = "global.easyant.ivysettings.file";
+    
+    /**
+     * Name of the property specifyinf if build repository should be used
+     * Value: {@value}
+     */
+    public static final String USE_BUILD_REPOSITORY = "use.build.repository";
 
     /**
      * property for easyant offline mode. Value: {@value}
@@ -181,6 +181,6 @@ public interface EasyAntMagicNames {
      * Property specifying if user ivysettings should be ignored
      * Value: {@value}
      */
-	public static final String IGNORE_USER_IVYSETTINGS = "ignore.user.ivysettings";
+    public static final String IGNORE_USER_IVYSETTINGS = "ignore.user.ivysettings";
 
 }

Modified: incubator/easyant/core/trunk/src/main/java/org/apache/easyant/core/EasyAntMain.java
URL: http://svn.apache.org/viewvc/incubator/easyant/core/trunk/src/main/java/org/apache/easyant/core/EasyAntMain.java?rev=1073371&r1=1073370&r2=1073371&view=diff
==============================================================================
--- incubator/easyant/core/trunk/src/main/java/org/apache/easyant/core/EasyAntMain.java (original)
+++ incubator/easyant/core/trunk/src/main/java/org/apache/easyant/core/EasyAntMain.java Tue Feb 22 15:55:55 2011
@@ -56,953 +56,954 @@ import org.apache.tools.ant.util.FileUti
  * </p>
  */
 public class EasyAntMain implements AntMain {
-	/**
-	 * A Set of args are are handled by the launcher and should not be seen by
-	 * Main.
-	 */
-	private static final Set LAUNCH_COMMANDS = new HashSet();
-	private boolean isLogFileUsed;
-	static {
-		LAUNCH_COMMANDS.add("-lib");
-		LAUNCH_COMMANDS.add("-cp");
-		LAUNCH_COMMANDS.add("-noclasspath");
-		LAUNCH_COMMANDS.add("--noclasspath");
-		LAUNCH_COMMANDS.add("-nouserlib");
-		LAUNCH_COMMANDS.add("-main");
-	}
-	private EasyAntConfiguration easyAntConfiguration;
-	private boolean projectHelp;
-	private boolean projectMan;
-
-	private ProjectMan man;
-	
-	/**
-	 * Whether or not this instance has successfully been constructed and is
-	 * ready to run.
-	 */
-	private boolean readyToRun;
-	private Vector propertyFiles = new Vector(1);
-	private File buildFile;
-	private File buildModule;
-	private File easyantConfFile;
-	private String buildConf;
-
-	/**
-	 * Prints the message of the Throwable if it (the message) is not
-	 * <code>null</code>.
-	 * 
-	 * @param t
-	 *            Throwable to print the message of. Must not be
-	 *            <code>null</code>.
-	 */
-	private static void printMessage(Throwable t) {
-		String message = t.getMessage();
-		if (message != null) {
-			System.err.println(message);
-		}
-	}
-
-	/**
-	 * Creates a new instance of this class using the arguments specified, gives
-	 * it any extra user properties which have been specified, and then runs the
-	 * build using the classloader provided.
-	 * 
-	 * @param args
-	 *            Command line arguments. Must not be <code>null</code>.
-	 * @param additionalUserProperties
-	 *            Any extra properties to use in this build. May be
-	 *            <code>null</code>, which is the equivalent to passing in an
-	 *            empty set of properties.
-	 * @param coreLoader
-	 *            Classloader used for core classes. May be <code>null</code> in
-	 *            which case the system classloader is used.
-	 */
-	public static void start(String[] args,
-			Properties additionalUserProperties, ClassLoader coreLoader) {
-		EasyAntMain m = new EasyAntMain();
-		m.startAnt(args, additionalUserProperties, coreLoader);
-	}
-
-	/**
-	 * Start Ant
-	 * 
-	 * @param args
-	 *            command line args
-	 * @param additionalUserProperties
-	 *            properties to set beyond those that may be specified on the
-	 *            args list
-	 * @param coreLoader
-	 *            - not used
-	 * 
-	 * @since Ant 1.6
-	 */
-	public void startAnt(String[] args, Properties additionalUserProperties,
-			ClassLoader coreLoader) {
-		easyAntConfiguration.setCoreLoader(coreLoader);
-		try {
-			Diagnostics.validateVersion();
-			processArgs(args);
-		} catch (Throwable exc) {
-			if (easyAntConfiguration.getMsgOutputLevel() >= Project.MSG_VERBOSE) {
-				exc.printStackTrace();
-			} 
-			handleLogfile();
-			printMessage(exc);
-			exit(1);
-			return;
-		}
-
-		if (additionalUserProperties != null) {
-			for (Enumeration e = additionalUserProperties.keys(); e
-					.hasMoreElements();) {
-				String key = (String) e.nextElement();
-				String property = additionalUserProperties.getProperty(key);
-				easyAntConfiguration.getDefinedProps().put(key, property);
-			}
-		}
-
-		// expect the worst
-		int exitCode = 1;
-		try {
-			try {
-				runBuild(coreLoader);
-				exitCode = 0;
-			} catch (ExitStatusException ese) {
-				exitCode = ese.getStatus();
-				if (exitCode != 0) {
-					throw ese;
-				}
-			}
-		} catch (BuildException be) {
-			if (easyAntConfiguration.getErr() != System.err) {
-				printMessage(be);
-			}
-		} catch (Throwable exc) {
-			exc.printStackTrace();
-			printMessage(exc);
-		} finally {
-			handleLogfile();
-		}
-		exit(exitCode);
-	}
-
-	/**
-	 * This operation is expected to call {@link System#exit(int)}, which is
-	 * what the base version does. However, it is possible to do something else.
-	 * 
-	 * @param exitCode
-	 *            code to exit with
-	 */
-	protected void exit(int exitCode) {
-		System.exit(exitCode);
-	}
-
-	/**
-	 * Close logfiles, if we have been writing to them.
-	 * 
-	 * @since Ant 1.6
-	 */
-	private void handleLogfile() {
-		if (isLogFileUsed && easyAntConfiguration != null) {
-			FileUtils.close(easyAntConfiguration.getOut());
-			FileUtils.close(easyAntConfiguration.getErr());
-		}
-	}
-
-	/**
-	 * Command line entry point. This method kicks off the building of a project
-	 * object and executes a build using either a given target or the default
-	 * target.
-	 * 
-	 * @param args
-	 *            Command line arguments. Must not be <code>null</code>.
-	 */
-	public static void main(String[] args) {
-		start(args, null, null);
-	}
-
-	/**
-	 * Constructor used when creating Main for later arg processing and startup
-	 */
-	public EasyAntMain() {
-		easyAntConfiguration = EasyantConfigurationFactory.getInstance()
-				.createDefaultConfiguration();
-	}
-
-	/**
-	 * Process command line arguments. When ant is started from Launcher,
-	 * launcher-only arguments do not get passed through to this routine.
-	 * 
-	 * @param args
-	 *            the command line arguments.
-	 * 
-	 * @since Ant 1.6
-	 */
-	private void processArgs(String[] args) {
-		String searchForThis = null;
-		PrintStream logTo = null;
-
-		// cycle through given args
-
-		boolean justPrintUsage = false;
-		boolean justPrintVersion = false;
-		boolean justPrintDiagnostics = false;
-
-		for (int i = 0; i < args.length; i++) {
-			String arg = args[i];
-
-			if (arg.equals("-help") || arg.equals("-h")) {
-				justPrintUsage = true;
-			} else if (arg.equals("-version")) {
-				justPrintVersion = true;
-			} else if (arg.equals("-showMemoryDetails")) {
-				easyAntConfiguration.setShowMemoryDetails(true);
-			} else if (arg.equals("-diagnostics")) {
-				justPrintDiagnostics = true;
-			} else if (arg.equals("-quiet") || arg.equals("-q")) {
-				easyAntConfiguration.setMsgOutputLevel(Project.MSG_WARN);
-			} else if (arg.equals("-verbose") || arg.equals("-v")) {
-				easyAntConfiguration.setMsgOutputLevel(Project.MSG_VERBOSE);
-			} else if (arg.equals("-debug") || arg.equals("-d")) {
-				easyAntConfiguration.setMsgOutputLevel(Project.MSG_DEBUG);
-			} else if (arg.equals("-noinput")) {
-				easyAntConfiguration.setAllowInput(false);
-			} else if (arg.equals("-logfile") || arg.equals("-l")) {
-				try {
-					File logFile = new File(args[i + 1]);
-					i++;
-					logTo = new PrintStream(new FileOutputStream(logFile));
-					isLogFileUsed = true;
-				} catch (IOException ioe) {
-					String msg = "Cannot write on the specified log file. "
-							+ "Make sure the path exists and you have write "
-							+ "permissions.";
-					throw new BuildException(msg);
-				} catch (ArrayIndexOutOfBoundsException aioobe) {
-					String msg = "You must specify a log file when "
-							+ "using the -log argument";
-					throw new BuildException(msg);
-				}
-			} else if (arg.equals("-buildmodule") || arg.equals("-file")
-					|| arg.equals("-f")) {
-				i = handleArgBuildModule(args, i);
-				easyAntConfiguration.setBuildModule(buildModule);
-			} else if (arg.equals("-buildfile")) {
-				i = handleArgBuildFile(args, i);
-				easyAntConfiguration.setBuildFile(buildFile);
-			} else if (arg.equals("-buildconf") || arg.equals("-C")) {
-				i = handleArgBuildConf(args,i);
-				easyAntConfiguration.getActiveBuildConfigurations().add(buildConf);
-			} else if (arg.equals("-config-file")) {
-				i = handleArgEasyAntConf(args, i);
-				try {
-					easyAntConfiguration = EasyantConfigurationFactory
-							.getInstance().createConfigurationFromFile(
-									easyAntConfiguration,
-									easyantConfFile.toURL());
-				} catch (Exception e) {
-					throw new BuildException(e);
-				}
-			} else if (arg.equals("-listener")) {
-				i = handleArgListener(args, i);
-			} else if (arg.startsWith("-D")) {
-				i = handleArgDefine(args, i);
-			} else if (arg.equals("-logger")) {
-				i = handleArgLogger(args, i);
-			} else if (arg.equals("-inputhandler")) {
-				i = handleArgInputHandler(args, i);
-			} else if (arg.equals("-emacs") || arg.equals("-e")) {
-				easyAntConfiguration.setEmacsMode(true);
-			} else if (arg.equals("-listTargets")
-					|| arg.equals("-describe")
-					|| arg.equals("-listProps")
-					|| arg.equals("-listPhases")
-					|| arg.equals("-listPlugins")) {
-				projectMan = true;
-				man = new ProjectMan();
-				man.setCommand(arg);
-				if(i < args.length-1 && !args[i+1].startsWith("-")) {
-					man.addParam(args[++i]);
-				}
-			} else if(arg.equals("-projecthelp")
-					|| arg.equals("-p")) {
-				// set the flag to display the targets and quit
-				projectHelp = true;
-			} else if (arg.equals("-find") || arg.equals("-s")) {
-				// eat up next arg if present, default to module.ivy
-				if (i < args.length - 1) {
-					searchForThis = args[++i];
-
-				} else {
-					searchForThis = EasyAntConstants.DEFAULT_BUILD_MODULE;
-				}
-				easyAntConfiguration.setBuildModule(new File(searchForThis));
-				easyAntConfiguration.setBuildModuleLookupEnabled(true);
-			} else if (arg.startsWith("-propertyfile")) {
-				i = handleArgPropertyFile(args, i);
-			} else if (arg.equals("-k") || arg.equals("-keep-going")) {
-				easyAntConfiguration.setKeepGoingMode(true);
+    /**
+     * A Set of args are are handled by the launcher and should not be seen by
+     * Main.
+     */
+    private static final Set LAUNCH_COMMANDS = new HashSet();
+    private boolean isLogFileUsed;
+    static {
+        LAUNCH_COMMANDS.add("-lib");
+        LAUNCH_COMMANDS.add("-cp");
+        LAUNCH_COMMANDS.add("-noclasspath");
+        LAUNCH_COMMANDS.add("--noclasspath");
+        LAUNCH_COMMANDS.add("-nouserlib");
+        LAUNCH_COMMANDS.add("-main");
+    }
+    private EasyAntConfiguration easyAntConfiguration;
+    private boolean projectHelp;
+    private boolean projectMan;
+
+    private ProjectMan man;
+    
+    /**
+     * Whether or not this instance has successfully been constructed and is
+     * ready to run.
+     */
+    private boolean readyToRun;
+    private Vector propertyFiles = new Vector(1);
+    private File buildFile;
+    private File buildModule;
+    private File easyantConfFile;
+    private String buildConf;
+
+    /**
+     * Prints the message of the Throwable if it (the message) is not
+     * <code>null</code>.
+     * 
+     * @param t
+     *            Throwable to print the message of. Must not be
+     *            <code>null</code>.
+     */
+    private static void printMessage(Throwable t) {
+        String message = t.getMessage();
+        if (message != null) {
+            System.err.println(message);
+        }
+    }
+
+    /**
+     * Creates a new instance of this class using the arguments specified, gives
+     * it any extra user properties which have been specified, and then runs the
+     * build using the classloader provided.
+     * 
+     * @param args
+     *            Command line arguments. Must not be <code>null</code>.
+     * @param additionalUserProperties
+     *            Any extra properties to use in this build. May be
+     *            <code>null</code>, which is the equivalent to passing in an
+     *            empty set of properties.
+     * @param coreLoader
+     *            Classloader used for core classes. May be <code>null</code> in
+     *            which case the system classloader is used.
+     */
+    public static void start(String[] args,
+            Properties additionalUserProperties, ClassLoader coreLoader) {
+        EasyAntMain m = new EasyAntMain();
+        m.startAnt(args, additionalUserProperties, coreLoader);
+    }
+
+    /**
+     * Start Ant
+     * 
+     * @param args
+     *            command line args
+     * @param additionalUserProperties
+     *            properties to set beyond those that may be specified on the
+     *            args list
+     * @param coreLoader
+     *            - not used
+     * 
+     * @since Ant 1.6
+     */
+    public void startAnt(String[] args, Properties additionalUserProperties,
+            ClassLoader coreLoader) {
+        easyAntConfiguration.setCoreLoader(coreLoader);
+        try {
+            Diagnostics.validateVersion();
+            processArgs(args);
+        } catch (Throwable exc) {
+            if (easyAntConfiguration.getMsgOutputLevel() >= Project.MSG_VERBOSE) {
+                exc.printStackTrace();
+            } 
+            handleLogfile();
+            printMessage(exc);
+            exit(1);
+            return;
+        }
+
+        if (additionalUserProperties != null) {
+            for (Enumeration e = additionalUserProperties.keys(); e
+                    .hasMoreElements();) {
+                String key = (String) e.nextElement();
+                String property = additionalUserProperties.getProperty(key);
+                easyAntConfiguration.getDefinedProps().put(key, property);
+            }
+        }
+
+        // expect the worst
+        int exitCode = 1;
+        try {
+            try {
+                runBuild(coreLoader);
+                exitCode = 0;
+            } catch (ExitStatusException ese) {
+                exitCode = ese.getStatus();
+                if (exitCode != 0) {
+                    throw ese;
+                }
+            }
+        } catch (BuildException be) {
+            if (easyAntConfiguration.getErr() != System.err) {
+                printMessage(be);
+            }
+        } catch (Throwable exc) {
+            exc.printStackTrace();
+            printMessage(exc);
+        } finally {
+            handleLogfile();
+        }
+        exit(exitCode);
+    }
+
+    /**
+     * This operation is expected to call {@link System#exit(int)}, which is
+     * what the base version does. However, it is possible to do something else.
+     * 
+     * @param exitCode
+     *            code to exit with
+     */
+    protected void exit(int exitCode) {
+        System.exit(exitCode);
+    }
+
+    /**
+     * Close logfiles, if we have been writing to them.
+     * 
+     * @since Ant 1.6
+     */
+    private void handleLogfile() {
+        if (isLogFileUsed && easyAntConfiguration != null) {
+            FileUtils.close(easyAntConfiguration.getOut());
+            FileUtils.close(easyAntConfiguration.getErr());
+        }
+    }
+
+    /**
+     * Command line entry point. This method kicks off the building of a project
+     * object and executes a build using either a given target or the default
+     * target.
+     * 
+     * @param args
+     *            Command line arguments. Must not be <code>null</code>.
+     */
+    public static void main(String[] args) {
+        start(args, null, null);
+    }
+
+    /**
+     * Constructor used when creating Main for later arg processing and startup
+     */
+    public EasyAntMain() {
+        easyAntConfiguration = EasyantConfigurationFactory.getInstance()
+                .createDefaultConfiguration();
+    }
+
+    /**
+     * Process command line arguments. When ant is started from Launcher,
+     * launcher-only arguments do not get passed through to this routine.
+     * 
+     * @param args
+     *            the command line arguments.
+     * 
+     * @since Ant 1.6
+     */
+    private void processArgs(String[] args) {
+        String searchForThis = null;
+        PrintStream logTo = null;
+
+        // cycle through given args
+
+        boolean justPrintUsage = false;
+        boolean justPrintVersion = false;
+        boolean justPrintDiagnostics = false;
+
+        for (int i = 0; i < args.length; i++) {
+            String arg = args[i];
+
+            if (arg.equals("-help") || arg.equals("-h")) {
+                justPrintUsage = true;
+            } else if (arg.equals("-version")) {
+                justPrintVersion = true;
+            } else if (arg.equals("-showMemoryDetails")) {
+                easyAntConfiguration.setShowMemoryDetails(true);
+            } else if (arg.equals("-diagnostics")) {
+                justPrintDiagnostics = true;
+            } else if (arg.equals("-quiet") || arg.equals("-q")) {
+                easyAntConfiguration.setMsgOutputLevel(Project.MSG_WARN);
+            } else if (arg.equals("-verbose") || arg.equals("-v")) {
+                easyAntConfiguration.setMsgOutputLevel(Project.MSG_VERBOSE);
+            } else if (arg.equals("-debug") || arg.equals("-d")) {
+                easyAntConfiguration.setMsgOutputLevel(Project.MSG_DEBUG);
+            } else if (arg.equals("-noinput")) {
+                easyAntConfiguration.setAllowInput(false);
+            } else if (arg.equals("-logfile") || arg.equals("-l")) {
+                try {
+                    File logFile = new File(args[i + 1]);
+                    i++;
+                    logTo = new PrintStream(new FileOutputStream(logFile));
+                    isLogFileUsed = true;
+                } catch (IOException ioe) {
+                    String msg = "Cannot write on the specified log file. "
+                            + "Make sure the path exists and you have write "
+                            + "permissions.";
+                    throw new BuildException(msg);
+                } catch (ArrayIndexOutOfBoundsException aioobe) {
+                    String msg = "You must specify a log file when "
+                            + "using the -log argument";
+                    throw new BuildException(msg);
+                }
+            } else if (arg.equals("-buildmodule") || arg.equals("-file")
+                    || arg.equals("-f")) {
+                i = handleArgBuildModule(args, i);
+                easyAntConfiguration.setBuildModule(buildModule);
+            } else if (arg.equals("-buildfile")) {
+                i = handleArgBuildFile(args, i);
+                easyAntConfiguration.setBuildFile(buildFile);
+            } else if (arg.equals("-buildconf") || arg.equals("-C")) {
+                i = handleArgBuildConf(args,i);
+                easyAntConfiguration.getActiveBuildConfigurations().add(buildConf);
+            } else if (arg.equals("-config-file")) {
+                i = handleArgEasyAntConf(args, i);
+                try {
+                    easyAntConfiguration = EasyantConfigurationFactory
+                            .getInstance().createConfigurationFromFile(
+                                    easyAntConfiguration,
+                                    easyantConfFile.toURL());
+                } catch (Exception e) {
+                    throw new BuildException(e);
+                }
+            } else if (arg.equals("-listener")) {
+                i = handleArgListener(args, i);
+            } else if (arg.startsWith("-D")) {
+                i = handleArgDefine(args, i);
+            } else if (arg.equals("-logger")) {
+                i = handleArgLogger(args, i);
+            } else if (arg.equals("-inputhandler")) {
+                i = handleArgInputHandler(args, i);
+            } else if (arg.equals("-emacs") || arg.equals("-e")) {
+                easyAntConfiguration.setEmacsMode(true);
+            } else if (arg.equals("-listTargets")
+                    || arg.equals("-describe")
+                    || arg.equals("-listProps")
+                    || arg.equals("-listPhases")
+                    || arg.equals("-listPlugins")) {
+                projectMan = true;
+                man = new ProjectMan();
+                man.setCommand(arg);
+                if(i < args.length-1 && !args[i+1].startsWith("-")) {
+                    man.addParam(args[++i]);
+                }
+            } else if(arg.equals("-projecthelp")
+                    || arg.equals("-p")) {
+                // set the flag to display the targets and quit
+                projectHelp = true;
+            } else if (arg.equals("-find") || arg.equals("-s")) {
+                // eat up next arg if present, default to module.ivy
+                if (i < args.length - 1) {
+                    searchForThis = args[++i];
+
+                } else {
+                    searchForThis = EasyAntConstants.DEFAULT_BUILD_MODULE;
+                }
+                easyAntConfiguration.setBuildModule(new File(searchForThis));
+                easyAntConfiguration.setBuildModuleLookupEnabled(true);
+            } else if (arg.startsWith("-propertyfile")) {
+                i = handleArgPropertyFile(args, i);
+            } else if (arg.equals("-k") || arg.equals("-keep-going")) {
+                easyAntConfiguration.setKeepGoingMode(true);
             } else if (arg.equals("-offline") || arg.equals("-o")) {
                 easyAntConfiguration.setOffline(true);
-			} else if (arg.equals("-nice")) {
-				i = handleArgNice(args, i);
-			} else if (LAUNCH_COMMANDS.contains(arg)) {
-				// catch script/ant mismatch with a meaningful message
-				// we could ignore it, but there are likely to be other
-				// version problems, so we stamp down on the configuration now
-				String msg = "Ant's Main method is being handed "
-						+ "an option " + arg
-						+ " that is only for the launcher class."
-						+ "\nThis can be caused by a version mismatch between "
-						+ "the ant script/.bat file and Ant itself.";
-				throw new BuildException(msg);
-			} else if (arg.equals("-autoproxy")) {
-				easyAntConfiguration.setProxy(true);
-			} else if (arg.startsWith("-")) {
-				// we don't have any more args to recognize!
-				String msg = "Unknown argument: " + arg;
-				System.err.println(msg);
-				printUsage();
-				throw new BuildException("");
-			} else {
-				easyAntConfiguration.getTargets().addElement(arg);
-			}
-		}
-
-		if (easyAntConfiguration.getMsgOutputLevel() >= Project.MSG_VERBOSE
-				|| justPrintVersion) {
-			printVersion(easyAntConfiguration.getMsgOutputLevel());
-		}
-
-		if (justPrintUsage || justPrintVersion || justPrintDiagnostics) {
-			if (justPrintUsage) {
-				printUsage();
-			}
-			if (justPrintDiagnostics) {
-				Diagnostics.doReport(System.out, easyAntConfiguration
-						.getMsgOutputLevel());
-			}
-			return;
-		}
-
-		// Load the property files specified by -propertyfile
-		loadPropertyFiles();
-
-		if (logTo != null) {
-			easyAntConfiguration.setOut(logTo);
-			easyAntConfiguration.setErr(logTo);
-			System.setOut(easyAntConfiguration.getOut());
-			System.setErr(easyAntConfiguration.getErr());
-		}
-		readyToRun = true;
-	}
-
-	// --------------------------------------------------------
-	// Methods for handling the command line arguments
-	// --------------------------------------------------------
-
-	/** Handle the -buildfile, -file, -f argument */
-	private int handleArgBuildFile(String[] args, int pos) {
-		try {
-			buildFile = new File(args[++pos].replace('/', File.separatorChar));
-			++pos;
-		} catch (ArrayIndexOutOfBoundsException aioobe) {
-			throw new BuildException(
-					"You must specify a buildfile when using the -buildfile argument");
-		}
-		return pos;
-	}
-
-	private int handleArgBuildModule(String[] args, int pos) {
-		try {
-			buildModule = new File(args[++pos].replace('/', File.separatorChar));
-		} catch (ArrayIndexOutOfBoundsException aioobe) {
-			throw new BuildException(
-					"You must specify a buildfile when using the -buildmodule argument");
-		}
-		return pos;
-	}
-	
-	private int handleArgBuildConf(String[] args, int pos) {
-		try {
-			buildConf = args[++pos];
-		} catch (ArrayIndexOutOfBoundsException aioobe) {
-			throw new BuildException(
-					"You must specify a build configuration when using the -buildconf argument");
-		}
-		return pos;
-	}
-
-	/** Handle -config-file argument */
-	private int handleArgEasyAntConf(String[] args, int pos) {
-		try {
-			easyantConfFile = new File(args[++pos].replace('/',
-					File.separatorChar));
-		} catch (ArrayIndexOutOfBoundsException aioobe) {
-			throw new BuildException(
-					"You must specify an easyant ivy configuration when using the -easyantivyconf argument");
-		}
-		return pos;
-	}
-
-	/** Handle -listener argument */
-	private int handleArgListener(String[] args, int pos) {
-		try {
-			easyAntConfiguration.getListeners().addElement(args[pos + 1]);
-			pos++;
-		} catch (ArrayIndexOutOfBoundsException aioobe) {
-			String msg = "You must specify a classname when "
-					+ "using the -listener argument";
-			throw new BuildException(msg);
-		}
-		return pos;
-	}
-
-	/** Handler -D argument */
-	private int handleArgDefine(String[] args, int argPos) {
-		/*
-		 * Interestingly enough, we get to here when a user uses -Dname=value.
-		 * However, in some cases, the OS goes ahead and parses this out to args
-		 * {"-Dname", "value"} so instead of parsing on "=", we just make the
-		 * "-D" characters go away and skip one argument forward.
-		 * 
-		 * I don't know how to predict when the JDK is going to help or not, so
-		 * we simply look for the equals sign.
-		 */
-		String arg = args[argPos];
-		String name = arg.substring(2, arg.length());
-		String value = null;
-		int posEq = name.indexOf("=");
-		if (posEq > 0) {
-			value = name.substring(posEq + 1);
-			name = name.substring(0, posEq);
-		} else if (argPos < args.length - 1) {
-			value = args[++argPos];
-		} else {
-			throw new BuildException("Missing value for property " + name);
-		}
-		easyAntConfiguration.getDefinedProps().put(name, value);
-		return argPos;
-	}
-
-	/** Handle the -logger argument. */
-	private int handleArgLogger(String[] args, int pos) {
-		if (easyAntConfiguration.getLoggerClassname() != null) {
-			throw new BuildException("Only one logger class may be specified.");
-		}
-		try {
-			easyAntConfiguration.setLoggerClassname(args[++pos]);
-		} catch (ArrayIndexOutOfBoundsException aioobe) {
-			throw new BuildException(
-					"You must specify a classname when using the -logger argument");
-		}
-		return pos;
-	}
-
-	/** Handle the -inputhandler argument. */
-	private int handleArgInputHandler(String[] args, int pos) {
-		if (easyAntConfiguration.getInputHandlerClassname() != null) {
-			throw new BuildException("Only one input handler class may "
-					+ "be specified.");
-		}
-		try {
-			easyAntConfiguration.setInputHandlerClassname(args[++pos]);
-		} catch (ArrayIndexOutOfBoundsException aioobe) {
-			throw new BuildException("You must specify a classname when"
-					+ " using the -inputhandler" + " argument");
-		}
-		return pos;
-	}
-
-	/** Handle the -propertyfile argument. */
-	private int handleArgPropertyFile(String[] args, int pos) {
-		try {
-			propertyFiles.addElement(args[++pos]);
-		} catch (ArrayIndexOutOfBoundsException aioobe) {
-			String msg = "You must specify a property filename when "
-					+ "using the -propertyfile argument";
-			throw new BuildException(msg);
-		}
-		return pos;
-	}
-
-	/** Handle the -nice argument. */
-	private int handleArgNice(String[] args, int pos) {
-		try {
-			easyAntConfiguration.setThreadPriority(Integer.decode(args[++pos]));
-		} catch (ArrayIndexOutOfBoundsException aioobe) {
-			throw new BuildException("You must supply a niceness value (1-10)"
-					+ " after the -nice option");
-		} catch (NumberFormatException e) {
-			throw new BuildException("Unrecognized niceness value: "
-					+ args[pos]);
-		}
-
-		if (easyAntConfiguration.getThreadPriority().intValue() < Thread.MIN_PRIORITY
-				|| easyAntConfiguration.getThreadPriority().intValue() > Thread.MAX_PRIORITY) {
-			throw new BuildException("Niceness value is out of the range 1-10");
-		}
-		return pos;
-	}
-
-	// --------------------------------------------------------
-	// other methods
-	// --------------------------------------------------------
-
-	/** Load the property files specified by -propertyfile */
-	private void loadPropertyFiles() {
-		for (int propertyFileIndex = 0; propertyFileIndex < propertyFiles
-				.size(); propertyFileIndex++) {
-			String filename = (String) propertyFiles
-					.elementAt(propertyFileIndex);
-			Properties props = new Properties();
-			FileInputStream fis = null;
-			try {
-				fis = new FileInputStream(filename);
-				props.load(fis);
-			} catch (IOException e) {
-				System.out.println("Could not load property file " + filename
-						+ ": " + e.getMessage());
-			} finally {
-				FileUtils.close(fis);
-			}
-
-			// ensure that -D properties take precedence
-			Enumeration propertyNames = props.propertyNames();
-			while (propertyNames.hasMoreElements()) {
-				String name = (String) propertyNames.nextElement();
-				if (easyAntConfiguration.getDefinedProps().getProperty(name) == null) {
-					easyAntConfiguration.getDefinedProps().put(name,
-							props.getProperty(name));
-				}
-			}
-		}
-	}
-
-	/**
-	 * Executes the build. If the constructor for this instance failed (e.g.
-	 * returned after issuing a warning), this method returns immediately.
-	 * 
-	 * @param coreLoader
-	 *            The classloader to use to find core classes. May be
-	 *            <code>null</code>, in which case the system classloader is
-	 *            used.
-	 * 
-	 * @exception BuildException
-	 *                if the build fails
-	 */
-	private void runBuild(ClassLoader coreLoader) throws BuildException {
-		Project project = new Project();
-		if (!readyToRun) {
-			return;
-		}
-		if (projectHelp) {
-			displayProjectHelp();
-		} else if(projectMan) {
-			EasyAntEngine.configureAndInitProject(project, easyAntConfiguration);
-			File moduleDescriptor =new File(project.getProperty(EasyAntMagicNames.EASYANT_FILE));
-			if (moduleDescriptor.exists()) {
-				man.setContext(project, moduleDescriptor);
-				man.execute();
-			} else {
-				project.log("Can't print project manual, there is no module descriptor available.");
-			}
-		} else {
-			EasyAntEngine.runBuild(easyAntConfiguration);
-		}
-
-	}
-
-	/**
-	 * Prints the description of a project (if there is one) to
-	 * <code>System.out</code>.
-	 * 
-	 * @param project
-	 *            The project to display a description of. Must not be
-	 *            <code>null</code>.
-	 */
-	protected void printDescription(Project project) {
-		if (project.getDescription() != null) {
-			project.log(project.getDescription());
-		}
-	}
-
-	/**
-	 * Targets in imported files with a project name and not overloaded by the
-	 * main build file will be in the target map twice. This method removes the
-	 * duplicate target.
-	 * 
-	 * @param targets
-	 *            the targets to filter.
-	 * @return the filtered targets.
-	 */
-	private static Map removeDuplicateTargets(Map targets) {
-		Map locationMap = new HashMap();
-		for (Iterator i = targets.entrySet().iterator(); i.hasNext();) {
-			Map.Entry entry = (Map.Entry) i.next();
-			String name = (String) entry.getKey();
-			Target target = (Target) entry.getValue();
-			Target otherTarget = (Target) locationMap.get(target.getLocation());
-			// Place this entry in the location map if
-			// a) location is not in the map
-			// b) location is in map, but it's name is longer
-			// (an imported target will have a name. prefix)
-			if (otherTarget == null
-					|| otherTarget.getName().length() > name.length()) {
-				locationMap.put(target.getLocation(), target); // Smallest name
-				// wins
-			}
-		}
-		Map ret = new HashMap();
-		for (Iterator i = locationMap.values().iterator(); i.hasNext();) {
-			Target target = (Target) i.next();
-			ret.put(target.getName(), target);
-		}
-		return ret;
-	}
-
-	/**
-	 * Searches for the correct place to insert a name into a list so as to keep
-	 * the list sorted alphabetically.
-	 * 
-	 * @param names
-	 *            The current list of names. Must not be <code>null</code>.
-	 * @param name
-	 *            The name to find a place for. Must not be <code>null</code>.
-	 * 
-	 * @return the correct place in the list for the given name
-	 */
-	private static int findTargetPosition(Vector names, String name) {
-		int res = names.size();
-		for (int i = 0; i < names.size() && res == names.size(); i++) {
-			if (name.compareTo((String) names.elementAt(i)) < 0) {
-				res = i;
-			}
-		}
-		return res;
-	}
-
-	/**
-	 * Writes a formatted list of target names to <code>System.out</code> with
-	 * an optional description.
-	 * 
-	 * 
-	 * @param project
-	 *            the project instance.
-	 * @param names
-	 *            The names to be printed. Must not be <code>null</code>.
-	 * @param descriptions
-	 *            The associated target descriptions. May be <code>null</code>,
-	 *            in which case no descriptions are displayed. If non-
-	 *            <code>null</code>, this should have as many elements as
-	 *            <code>names</code>.
-	 * @param heading
-	 *            The heading to display. Should not be <code>null</code>.
-	 * @param maxlen
-	 *            The maximum length of the names of the targets. If
-	 *            descriptions are given, they are padded to this position so
-	 *            they line up (so long as the names really <i>are</i> shorter
-	 *            than this).
-	 */
-	private static void printTargets(Project project, Vector names,
-			Vector descriptions, String heading, int maxlen) {
-		// now, start printing the targets and their descriptions
-		String lSep = System.getProperty("line.separator");
-		// got a bit annoyed that I couldn't find a pad function
-		String spaces = "    ";
-		while (spaces.length() <= maxlen) {
-			spaces += spaces;
-		}
-		StringBuffer msg = new StringBuffer();
-		msg.append(heading + lSep + lSep);
-		for (int i = 0; i < names.size(); i++) {
-			msg.append(" ");
-			msg.append(names.elementAt(i));
-			if (descriptions != null) {
-				msg.append(spaces.substring(0, maxlen
-						- ((String) names.elementAt(i)).length() + 2));
-				msg.append(descriptions.elementAt(i));
-			}
-			msg.append(lSep);
-		}
-		project.log(msg.toString(), Project.MSG_WARN);
-	}
-
-	/**
-	 * Prints a list of all targets in the specified project to
-	 * <code>System.out</code>, optionally including subtargets.
-	 * 
-	 * @param project
-	 *            The project to display a description of. Must not be
-	 *            <code>null</code>.
-	 * @param printSubTargets
-	 *            Whether or not subtarget names should also be printed.
-	 */
-	protected static void printTargets(Project project, boolean printSubTargets) {
-		// find the target with the longest name
-		int maxLength = 0;
-		Map ptargets = removeDuplicateTargets(project.getTargets());
-		String targetName;
-		String targetDescription;
-		Target currentTarget;
-		// split the targets in top-level and sub-targets depending
-		// on the presence of a description
-		Vector topNames = new Vector();
-		Vector topDescriptions = new Vector();
-		Vector subNames = new Vector();
-
-		Vector phases = new Vector();
-		Vector phasesDescriptions = new Vector();
-
-		for (Iterator i = ptargets.values().iterator(); i.hasNext();) {
-			currentTarget = (Target) i.next();
-			targetName = currentTarget.getName();
-			if (targetName.equals("")) {
-				continue;
-			}
-			targetDescription = currentTarget.getDescription();
-			// maintain a sorted list of targets
-			if (targetDescription == null) {
-				int pos = findTargetPosition(subNames, targetName);
-				subNames.insertElementAt(targetName, pos);
-			} else {
-				if (currentTarget instanceof Phase) {
-					int pos = findTargetPosition(phases, targetName);
-					phases.insertElementAt(targetName, pos);
-					phasesDescriptions.insertElementAt(targetDescription, pos);
-				} else {
-					int pos = findTargetPosition(topNames, targetName);
-					topNames.insertElementAt(targetName, pos);
-					topDescriptions.insertElementAt(targetDescription, pos);
-
-				}
-				if (targetName.length() > maxLength) {
-					maxLength = targetName.length();
-				}
-			}
-		}
-
-		printTargets(project, phases, phasesDescriptions, "Main phases:",
-				maxLength);
-		printTargets(project, topNames, topDescriptions, "Main targets:",
-				maxLength);
-		// if there were no main targets, we list all subtargets
-		// as it means nothing has a description
-		if (topNames.size() == 0) {
-			printSubTargets = true;
-		}
-		if (printSubTargets) {
-			printTargets(project, subNames, null, "Other targets:", 0);
-		}
-
-		String defaultTarget = project.getDefaultTarget();
-		if (defaultTarget != null && !"".equals(defaultTarget)) {
-			// shouldn't need to check but...
-			project.log("Default target: " + defaultTarget);
-		}
-	}
-
-	private void displayProjectHelp() {
-		final Project project = new Project();
-		Throwable error = null;
-
-		try {
-
-			PrintStream savedErr = System.err;
-			PrintStream savedOut = System.out;
-			InputStream savedIn = System.in;
-
-			// use a system manager that prevents from System.exit()
-			SecurityManager oldsm = null;
-			oldsm = System.getSecurityManager();
-
-			// SecurityManager can not be installed here for backwards
-			// compatibility reasons (PD). Needs to be loaded prior to
-			// ant class if we are going to implement it.
-			// System.setSecurityManager(new NoExitSecurityManager());
-			try {
-				if (easyAntConfiguration.isAllowInput()) {
-					project.setDefaultInputStream(System.in);
-				}
-				System.setIn(new DemuxInputStream(project));
-				System.setOut(new PrintStream(new DemuxOutputStream(project,
-						false)));
-				System.setErr(new PrintStream(new DemuxOutputStream(project,
-						true)));
-				EasyAntEngine.configureAndInitProject(project, easyAntConfiguration);
-				printDescription(project);
-				printTargets(project,
-						easyAntConfiguration.getMsgOutputLevel() > Project.MSG_INFO);
-			} finally {
-				// put back the original security manager
-				// The following will never eval to true. (PD)
-				if (oldsm != null) {
-					System.setSecurityManager(oldsm);
-				}
-
-				System.setOut(savedOut);
-				System.setErr(savedErr);
-				System.setIn(savedIn);
-			}
-		} catch (RuntimeException exc) {
-			error = exc;
-			throw exc;
-		} catch (Error e) {
-			error = e;
-			throw e;
-		} finally {
-			if (error != null) {
-				project.log(error.toString(), Project.MSG_ERR);
-			}
-		}
-	}
-	
-	/**
-	 * Prints the usage information for this class to <code>System.out</code>.
-	 */
-	private static void printUsage() {
-		String lSep = System.getProperty("line.separator");
-		StringBuffer msg = new StringBuffer();
-		msg.append("easyant [options] [target [target2 [target3] ...]]" + lSep);
-		msg.append("Options: " + lSep);
-		msg.append("  -help, -h              print this message" + lSep);
-		msg.append("  -projecthelp, -p       print project help information"
-				+ lSep);
-		msg
-				.append("  -version               print the version information and exit"
-						+ lSep);
-		msg
-				.append("  -diagnostics           print information that might be helpful to"
-						+ lSep);
-		msg.append("                         diagnose or report problems."
-				+ lSep);
-		msg
-				.append("  -showMemoryDetails     print memory details (used/free/total)"
-						+ lSep);
-		msg.append("  -quiet, -q             be extra quiet" + lSep);
-		msg.append("  -verbose, -v           be extra verbose" + lSep);
-		msg.append("  -debug, -d             print debugging information"
-				+ lSep);
-		msg
-				.append("  -emacs, -e             produce logging information without adornments"
-						+ lSep);
-		msg
-				.append("  -lib <path>            specifies a path to search for jars and classes"
-						+ lSep);
-		msg.append("  -logfile <file>        use given file for log" + lSep);
-		msg.append("    -l     <file>                ''" + lSep);
-		msg
-				.append("  -logger <classname>    the class which is to perform logging"
-						+ lSep);
-		msg
-				.append("  -listener <classname>  add an instance of class as a project listener"
-						+ lSep);
-		msg.append("  -noinput               do not allow interactive input"
-				+ lSep);
-		msg.append("  -buildmodule <file>    use given buildmodule" + lSep);
-		msg.append("    -file    <file>              ''" + lSep);
-		msg.append("    -f       <file>              ''" + lSep);
-		msg.append("  -listTargets           Lists all targets available"+lSep);
-		msg.append("  -listTargets <arg>     Lists all targets associated with specified phase / plugin as argument"+lSep);
-		msg.append("  -listPhases            Lists all phases available"+lSep);
-		msg.append("  -listPlugins           Lists all plugins / modules imported by specified build module"+lSep);
-		msg.append("  -listProps <plugin>    Lists all properties available in the specified imported module"+lSep);
-		msg.append("  -describe <arg>        Describes the phase / target / property specified by the argument"+lSep);
-		msg.append("  -buildconf <confs>     specify build configurations (profiles)"+lSep);
-		msg.append("    -C  <confs>                  ''"+lSep);
-		msg.append("  -buildfile <file>      use given buildfile" + lSep);
-		msg.append("  -config-file <file>    use given easyant configuration"
-				+ lSep);
-		msg.append("  -D<property>=<value>   use value for given property"
-				+ lSep);
-		msg
-				.append("  -keep-going, -k        execute all targets that do not depend"
-						+ lSep);
-		msg.append("                         on failed target(s)" + lSep);
-		msg
-				.append("  -propertyfile <name>   load all properties from file with -D"
-						+ lSep);
-		msg.append("                         properties taking precedence"
-				+ lSep);
-		msg
-				.append("  -inputhandler <class>  the class which will handle input requests"
-						+ lSep);
-		msg
-				.append("  -find <file>           (s)earch for buildfile towards the root of"
-						+ lSep);
-		msg.append("    -s  <file>           the filesystem and use it" + lSep);
-		msg
-				.append("  -nice  number          A niceness value for the main thread:"
-						+ lSep
-						+ "                         1 (lowest) to 10 (highest); 5 is the default"
-						+ lSep);
-		msg
-				.append("  -nouserlib             Run ant without using the jar files from"
-						+ lSep
-						+ "                         ${user.home}/.ant/lib"
-						+ lSep);
-		msg.append("  -noclasspath           Run ant without using CLASSPATH"
-				+ lSep);
-		msg
-				.append("  -autoproxy             Java1.5+: use the OS proxy settings"
-						+ lSep);
-		msg
-				.append("  -main <class>          override Ant's normal entry point");
-		System.out.println(msg.toString());
-	}
-
-	/**
-	 * Prints the EasyAnt version information to <code>System.out</code>.
-	 * 
-	 * @exception BuildException
-	 *                if the version information is unavailable
-	 */
-	private static void printVersion(int logLevel) throws BuildException {
-		System.out.println(EasyAntEngine.getEasyAntVersion());
-		System.out.println(getAntVersion());
-	}
-
-	/**
-	 * Cache of the Ant version information when it has been loaded.
-	 */
-	private static String antVersion = null;
-
-	/**
-	 * Returns the Ant version information, if available. Once the information
-	 * has been loaded once, it's cached and returned from the cache on future
-	 * calls.
-	 * 
-	 * @return the Ant version information as a String (always non-
-	 *         <code>null</code>)
-	 * 
-	 * @exception BuildException
-	 *                if the version information is unavailable
-	 */
-	public static synchronized String getAntVersion() throws BuildException {
-		if (antVersion == null) {
-			try {
-				Properties props = new Properties();
-				InputStream in = Main.class
-						.getResourceAsStream("/org/apache/tools/ant/version.txt");
-				props.load(in);
-				in.close();
-
-				StringBuffer msg = new StringBuffer();
-				msg.append("Apache Ant version ");
-				msg.append(props.getProperty("VERSION"));
-				msg.append(" compiled on ");
-				msg.append(props.getProperty("DATE"));
-				antVersion = msg.toString();
-			} catch (IOException ioe) {
-				throw new BuildException(
-						"Could not load the version information:"
-								+ ioe.getMessage());
-			} catch (NullPointerException npe) {
-				throw new BuildException(
-						"Could not load the version information.");
-			}
-		}
-		return antVersion;
-	}
+            } else if (arg.equals("-nice")) {
+                i = handleArgNice(args, i);
+            } else if (LAUNCH_COMMANDS.contains(arg)) {
+                // catch script/ant mismatch with a meaningful message
+                // we could ignore it, but there are likely to be other
+                // version problems, so we stamp down on the configuration now
+                String msg = "Ant's Main method is being handed "
+                        + "an option " + arg
+                        + " that is only for the launcher class."
+                        + "
+This can be caused by a version mismatch between "
+                        + "the ant script/.bat file and Ant itself.";
+                throw new BuildException(msg);
+            } else if (arg.equals("-autoproxy")) {
+                easyAntConfiguration.setProxy(true);
+            } else if (arg.startsWith("-")) {
+                // we don't have any more args to recognize!
+                String msg = "Unknown argument: " + arg;
+                System.err.println(msg);
+                printUsage();
+                throw new BuildException("");
+            } else {
+                easyAntConfiguration.getTargets().addElement(arg);
+            }
+        }
+
+        if (easyAntConfiguration.getMsgOutputLevel() >= Project.MSG_VERBOSE
+                || justPrintVersion) {
+            printVersion(easyAntConfiguration.getMsgOutputLevel());
+        }
+
+        if (justPrintUsage || justPrintVersion || justPrintDiagnostics) {
+            if (justPrintUsage) {
+                printUsage();
+            }
+            if (justPrintDiagnostics) {
+                Diagnostics.doReport(System.out, easyAntConfiguration
+                        .getMsgOutputLevel());
+            }
+            return;
+        }
+
+        // Load the property files specified by -propertyfile
+        loadPropertyFiles();
+
+        if (logTo != null) {
+            easyAntConfiguration.setOut(logTo);
+            easyAntConfiguration.setErr(logTo);
+            System.setOut(easyAntConfiguration.getOut());
+            System.setErr(easyAntConfiguration.getErr());
+        }
+        readyToRun = true;
+    }
+
+    // --------------------------------------------------------
+    // Methods for handling the command line arguments
+    // --------------------------------------------------------
+
+    /** Handle the -buildfile, -file, -f argument */
+    private int handleArgBuildFile(String[] args, int pos) {
+        try {
+            buildFile = new File(args[++pos].replace('/', File.separatorChar));
+            ++pos;
+        } catch (ArrayIndexOutOfBoundsException aioobe) {
+            throw new BuildException(
+                    "You must specify a buildfile when using the -buildfile argument");
+        }
+        return pos;
+    }
+
+    private int handleArgBuildModule(String[] args, int pos) {
+        try {
+            buildModule = new File(args[++pos].replace('/', File.separatorChar));
+        } catch (ArrayIndexOutOfBoundsException aioobe) {
+            throw new BuildException(
+                    "You must specify a buildfile when using the -buildmodule argument");
+        }
+        return pos;
+    }
+    
+    private int handleArgBuildConf(String[] args, int pos) {
+        try {
+            buildConf = args[++pos];
+        } catch (ArrayIndexOutOfBoundsException aioobe) {
+            throw new BuildException(
+                    "You must specify a build configuration when using the -buildconf argument");
+        }
+        return pos;
+    }
+
+    /** Handle -config-file argument */
+    private int handleArgEasyAntConf(String[] args, int pos) {
+        try {
+            easyantConfFile = new File(args[++pos].replace('/',
+                    File.separatorChar));
+        } catch (ArrayIndexOutOfBoundsException aioobe) {
+            throw new BuildException(
+                    "You must specify an easyant ivy configuration when using the -easyantivyconf argument");
+        }
+        return pos;
+    }
+
+    /** Handle -listener argument */
+    private int handleArgListener(String[] args, int pos) {
+        try {
+            easyAntConfiguration.getListeners().addElement(args[pos + 1]);
+            pos++;
+        } catch (ArrayIndexOutOfBoundsException aioobe) {
+            String msg = "You must specify a classname when "
+                    + "using the -listener argument";
+            throw new BuildException(msg);
+        }
+        return pos;
+    }
+
+    /** Handler -D argument */
+    private int handleArgDefine(String[] args, int argPos) {
+        /*
+         * Interestingly enough, we get to here when a user uses -Dname=value.
+         * However, in some cases, the OS goes ahead and parses this out to args
+         * {"-Dname", "value"} so instead of parsing on "=", we just make the
+         * "-D" characters go away and skip one argument forward.
+         * 
+         * I don't know how to predict when the JDK is going to help or not, so
+         * we simply look for the equals sign.
+         */
+        String arg = args[argPos];
+        String name = arg.substring(2, arg.length());
+        String value = null;
+        int posEq = name.indexOf("=");
+        if (posEq > 0) {
+            value = name.substring(posEq + 1);
+            name = name.substring(0, posEq);
+        } else if (argPos < args.length - 1) {
+            value = args[++argPos];
+        } else {
+            throw new BuildException("Missing value for property " + name);
+        }
+        easyAntConfiguration.getDefinedProps().put(name, value);
+        return argPos;
+    }
+
+    /** Handle the -logger argument. */
+    private int handleArgLogger(String[] args, int pos) {
+        if (easyAntConfiguration.getLoggerClassname() != null) {
+            throw new BuildException("Only one logger class may be specified.");
+        }
+        try {
+            easyAntConfiguration.setLoggerClassname(args[++pos]);
+        } catch (ArrayIndexOutOfBoundsException aioobe) {
+            throw new BuildException(
+                    "You must specify a classname when using the -logger argument");
+        }
+        return pos;
+    }
+
+    /** Handle the -inputhandler argument. */
+    private int handleArgInputHandler(String[] args, int pos) {
+        if (easyAntConfiguration.getInputHandlerClassname() != null) {
+            throw new BuildException("Only one input handler class may "
+                    + "be specified.");
+        }
+        try {
+            easyAntConfiguration.setInputHandlerClassname(args[++pos]);
+        } catch (ArrayIndexOutOfBoundsException aioobe) {
+            throw new BuildException("You must specify a classname when"
+                    + " using the -inputhandler" + " argument");
+        }
+        return pos;
+    }
+
+    /** Handle the -propertyfile argument. */
+    private int handleArgPropertyFile(String[] args, int pos) {
+        try {
+            propertyFiles.addElement(args[++pos]);
+        } catch (ArrayIndexOutOfBoundsException aioobe) {
+            String msg = "You must specify a property filename when "
+                    + "using the -propertyfile argument";
+            throw new BuildException(msg);
+        }
+        return pos;
+    }
+
+    /** Handle the -nice argument. */
+    private int handleArgNice(String[] args, int pos) {
+        try {
+            easyAntConfiguration.setThreadPriority(Integer.decode(args[++pos]));
+        } catch (ArrayIndexOutOfBoundsException aioobe) {
+            throw new BuildException("You must supply a niceness value (1-10)"
+                    + " after the -nice option");
+        } catch (NumberFormatException e) {
+            throw new BuildException("Unrecognized niceness value: "
+                    + args[pos]);
+        }
+
+        if (easyAntConfiguration.getThreadPriority().intValue() < Thread.MIN_PRIORITY
+                || easyAntConfiguration.getThreadPriority().intValue() > Thread.MAX_PRIORITY) {
+            throw new BuildException("Niceness value is out of the range 1-10");
+        }
+        return pos;
+    }
+
+    // --------------------------------------------------------
+    // other methods
+    // --------------------------------------------------------
+
+    /** Load the property files specified by -propertyfile */
+    private void loadPropertyFiles() {
+        for (int propertyFileIndex = 0; propertyFileIndex < propertyFiles
+                .size(); propertyFileIndex++) {
+            String filename = (String) propertyFiles
+                    .elementAt(propertyFileIndex);
+            Properties props = new Properties();
+            FileInputStream fis = null;
+            try {
+                fis = new FileInputStream(filename);
+                props.load(fis);
+            } catch (IOException e) {
+                System.out.println("Could not load property file " + filename
+                        + ": " + e.getMessage());
+            } finally {
+                FileUtils.close(fis);
+            }
+
+            // ensure that -D properties take precedence
+            Enumeration propertyNames = props.propertyNames();
+            while (propertyNames.hasMoreElements()) {
+                String name = (String) propertyNames.nextElement();
+                if (easyAntConfiguration.getDefinedProps().getProperty(name) == null) {
+                    easyAntConfiguration.getDefinedProps().put(name,
+                            props.getProperty(name));
+                }
+            }
+        }
+    }
+
+    /**
+     * Executes the build. If the constructor for this instance failed (e.g.
+     * returned after issuing a warning), this method returns immediately.
+     * 
+     * @param coreLoader
+     *            The classloader to use to find core classes. May be
+     *            <code>null</code>, in which case the system classloader is
+     *            used.
+     * 
+     * @exception BuildException
+     *                if the build fails
+     */
+    private void runBuild(ClassLoader coreLoader) throws BuildException {
+        Project project = new Project();
+        if (!readyToRun) {
+            return;
+        }
+        if (projectHelp) {
+            displayProjectHelp();
+        } else if(projectMan) {
+            EasyAntEngine.configureAndInitProject(project, easyAntConfiguration);
+            File moduleDescriptor =new File(project.getProperty(EasyAntMagicNames.EASYANT_FILE));
+            if (moduleDescriptor.exists()) {
+                man.setContext(project, moduleDescriptor);
+                man.execute();
+            } else {
+                project.log("Can't print project manual, there is no module descriptor available.");
+            }
+        } else {
+            EasyAntEngine.runBuild(easyAntConfiguration);
+        }
+
+    }
+
+    /**
+     * Prints the description of a project (if there is one) to
+     * <code>System.out</code>.
+     * 
+     * @param project
+     *            The project to display a description of. Must not be
+     *            <code>null</code>.
+     */
+    protected void printDescription(Project project) {
+        if (project.getDescription() != null) {
+            project.log(project.getDescription());
+        }
+    }
+
+    /**
+     * Targets in imported files with a project name and not overloaded by the
+     * main build file will be in the target map twice. This method removes the
+     * duplicate target.
+     * 
+     * @param targets
+     *            the targets to filter.
+     * @return the filtered targets.
+     */
+    private static Map removeDuplicateTargets(Map targets) {
+        Map locationMap = new HashMap();
+        for (Iterator i = targets.entrySet().iterator(); i.hasNext();) {
+            Map.Entry entry = (Map.Entry) i.next();
+            String name = (String) entry.getKey();
+            Target target = (Target) entry.getValue();
+            Target otherTarget = (Target) locationMap.get(target.getLocation());
+            // Place this entry in the location map if
+            // a) location is not in the map
+            // b) location is in map, but it's name is longer
+            // (an imported target will have a name. prefix)
+            if (otherTarget == null
+                    || otherTarget.getName().length() > name.length()) {
+                locationMap.put(target.getLocation(), target); // Smallest name
+                // wins
+            }
+        }
+        Map ret = new HashMap();
+        for (Iterator i = locationMap.values().iterator(); i.hasNext();) {
+            Target target = (Target) i.next();
+            ret.put(target.getName(), target);
+        }
+        return ret;
+    }
+
+    /**
+     * Searches for the correct place to insert a name into a list so as to keep
+     * the list sorted alphabetically.
+     * 
+     * @param names
+     *            The current list of names. Must not be <code>null</code>.
+     * @param name
+     *            The name to find a place for. Must not be <code>null</code>.
+     * 
+     * @return the correct place in the list for the given name
+     */
+    private static int findTargetPosition(Vector names, String name) {
+        int res = names.size();
+        for (int i = 0; i < names.size() && res == names.size(); i++) {
+            if (name.compareTo((String) names.elementAt(i)) < 0) {
+                res = i;
+            }
+        }
+        return res;
+    }
+
+    /**
+     * Writes a formatted list of target names to <code>System.out</code> with
+     * an optional description.
+     * 
+     * 
+     * @param project
+     *            the project instance.
+     * @param names
+     *            The names to be printed. Must not be <code>null</code>.
+     * @param descriptions
+     *            The associated target descriptions. May be <code>null</code>,
+     *            in which case no descriptions are displayed. If non-
+     *            <code>null</code>, this should have as many elements as
+     *            <code>names</code>.
+     * @param heading
+     *            The heading to display. Should not be <code>null</code>.
+     * @param maxlen
+     *            The maximum length of the names of the targets. If
+     *            descriptions are given, they are padded to this position so
+     *            they line up (so long as the names really <i>are</i> shorter
+     *            than this).
+     */
+    private static void printTargets(Project project, Vector names,
+            Vector descriptions, String heading, int maxlen) {
+        // now, start printing the targets and their descriptions
+        String lSep = System.getProperty("line.separator");
+        // got a bit annoyed that I couldn't find a pad function
+        String spaces = "    ";
+        while (spaces.length() <= maxlen) {
+            spaces += spaces;
+        }
+        StringBuffer msg = new StringBuffer();
+        msg.append(heading + lSep + lSep);
+        for (int i = 0; i < names.size(); i++) {
+            msg.append(" ");
+            msg.append(names.elementAt(i));
+            if (descriptions != null) {
+                msg.append(spaces.substring(0, maxlen
+                        - ((String) names.elementAt(i)).length() + 2));
+                msg.append(descriptions.elementAt(i));
+            }
+            msg.append(lSep);
+        }
+        project.log(msg.toString(), Project.MSG_WARN);
+    }
+
+    /**
+     * Prints a list of all targets in the specified project to
+     * <code>System.out</code>, optionally including subtargets.
+     * 
+     * @param project
+     *            The project to display a description of. Must not be
+     *            <code>null</code>.
+     * @param printSubTargets
+     *            Whether or not subtarget names should also be printed.
+     */
+    protected static void printTargets(Project project, boolean printSubTargets) {
+        // find the target with the longest name
+        int maxLength = 0;
+        Map ptargets = removeDuplicateTargets(project.getTargets());
+        String targetName;
+        String targetDescription;
+        Target currentTarget;
+        // split the targets in top-level and sub-targets depending
+        // on the presence of a description
+        Vector topNames = new Vector();
+        Vector topDescriptions = new Vector();
+        Vector subNames = new Vector();
+
+        Vector phases = new Vector();
+        Vector phasesDescriptions = new Vector();
+
+        for (Iterator i = ptargets.values().iterator(); i.hasNext();) {
+            currentTarget = (Target) i.next();
+            targetName = currentTarget.getName();
+            if (targetName.equals("")) {
+                continue;
+            }
+            targetDescription = currentTarget.getDescription();
+            // maintain a sorted list of targets
+            if (targetDescription == null) {
+                int pos = findTargetPosition(subNames, targetName);
+                subNames.insertElementAt(targetName, pos);
+            } else {
+                if (currentTarget instanceof Phase) {
+                    int pos = findTargetPosition(phases, targetName);
+                    phases.insertElementAt(targetName, pos);
+                    phasesDescriptions.insertElementAt(targetDescription, pos);
+                } else {
+                    int pos = findTargetPosition(topNames, targetName);
+                    topNames.insertElementAt(targetName, pos);
+                    topDescriptions.insertElementAt(targetDescription, pos);
+
+                }
+                if (targetName.length() > maxLength) {
+                    maxLength = targetName.length();
+                }
+            }
+        }
+
+        printTargets(project, phases, phasesDescriptions, "Main phases:",
+                maxLength);
+        printTargets(project, topNames, topDescriptions, "Main targets:",
+                maxLength);
+        // if there were no main targets, we list all subtargets
+        // as it means nothing has a description
+        if (topNames.size() == 0) {
+            printSubTargets = true;
+        }
+        if (printSubTargets) {
+            printTargets(project, subNames, null, "Other targets:", 0);
+        }
+
+        String defaultTarget = project.getDefaultTarget();
+        if (defaultTarget != null && !"".equals(defaultTarget)) {
+            // shouldn't need to check but...
+            project.log("Default target: " + defaultTarget);
+        }
+    }
+
+    private void displayProjectHelp() {
+        final Project project = new Project();
+        Throwable error = null;
+
+        try {
+
+            PrintStream savedErr = System.err;
+            PrintStream savedOut = System.out;
+            InputStream savedIn = System.in;
+
+            // use a system manager that prevents from System.exit()
+            SecurityManager oldsm = null;
+            oldsm = System.getSecurityManager();
+
+            // SecurityManager can not be installed here for backwards
+            // compatibility reasons (PD). Needs to be loaded prior to
+            // ant class if we are going to implement it.
+            // System.setSecurityManager(new NoExitSecurityManager());
+            try {
+                if (easyAntConfiguration.isAllowInput()) {
+                    project.setDefaultInputStream(System.in);
+                }
+                System.setIn(new DemuxInputStream(project));
+                System.setOut(new PrintStream(new DemuxOutputStream(project,
+                        false)));
+                System.setErr(new PrintStream(new DemuxOutputStream(project,
+                        true)));
+                EasyAntEngine.configureAndInitProject(project, easyAntConfiguration);
+                printDescription(project);
+                printTargets(project,
+                        easyAntConfiguration.getMsgOutputLevel() > Project.MSG_INFO);
+            } finally {
+                // put back the original security manager
+                // The following will never eval to true. (PD)
+                if (oldsm != null) {
+                    System.setSecurityManager(oldsm);
+                }
+
+                System.setOut(savedOut);
+                System.setErr(savedErr);
+                System.setIn(savedIn);
+            }
+        } catch (RuntimeException exc) {
+            error = exc;
+            throw exc;
+        } catch (Error e) {
+            error = e;
+            throw e;
+        } finally {
+            if (error != null) {
+                project.log(error.toString(), Project.MSG_ERR);
+            }
+        }
+    }
+    
+    /**
+     * Prints the usage information for this class to <code>System.out</code>.
+     */
+    private static void printUsage() {
+        String lSep = System.getProperty("line.separator");
+        StringBuffer msg = new StringBuffer();
+        msg.append("easyant [options] [target [target2 [target3] ...]]" + lSep);
+        msg.append("Options: " + lSep);
+        msg.append("  -help, -h              print this message" + lSep);
+        msg.append("  -projecthelp, -p       print project help information"
+                + lSep);
+        msg
+                .append("  -version               print the version information and exit"
+                        + lSep);
+        msg
+                .append("  -diagnostics           print information that might be helpful to"
+                        + lSep);
+        msg.append("                         diagnose or report problems."
+                + lSep);
+        msg
+                .append("  -showMemoryDetails     print memory details (used/free/total)"
+                        + lSep);
+        msg.append("  -quiet, -q             be extra quiet" + lSep);
+        msg.append("  -verbose, -v           be extra verbose" + lSep);
+        msg.append("  -debug, -d             print debugging information"
+                + lSep);
+        msg
+                .append("  -emacs, -e             produce logging information without adornments"
+                        + lSep);
+        msg
+                .append("  -lib <path>            specifies a path to search for jars and classes"
+                        + lSep);
+        msg.append("  -logfile <file>        use given file for log" + lSep);
+        msg.append("    -l     <file>                ''" + lSep);
+        msg
+                .append("  -logger <classname>    the class which is to perform logging"
+                        + lSep);
+        msg
+                .append("  -listener <classname>  add an instance of class as a project listener"
+                        + lSep);
+        msg.append("  -noinput               do not allow interactive input"
+                + lSep);
+        msg.append("  -buildmodule <file>    use given buildmodule" + lSep);
+        msg.append("    -file    <file>              ''" + lSep);
+        msg.append("    -f       <file>              ''" + lSep);
+        msg.append("  -listTargets           Lists all targets available"+lSep);
+        msg.append("  -listTargets <arg>     Lists all targets associated with specified phase / plugin as argument"+lSep);
+        msg.append("  -listPhases            Lists all phases available"+lSep);
+        msg.append("  -listPlugins           Lists all plugins / modules imported by specified build module"+lSep);
+        msg.append("  -listProps <plugin>    Lists all properties available in the specified imported module"+lSep);
+        msg.append("  -describe <arg>        Describes the phase / target / property specified by the argument"+lSep);
+        msg.append("  -buildconf <confs>     specify build configurations (profiles)"+lSep);
+        msg.append("    -C  <confs>                  ''"+lSep);
+        msg.append("  -buildfile <file>      use given buildfile" + lSep);
+        msg.append("  -config-file <file>    use given easyant configuration"
+                + lSep);
+        msg.append("  -D<property>=<value>   use value for given property"
+                + lSep);
+        msg
+                .append("  -keep-going, -k        execute all targets that do not depend"
+                        + lSep);
+        msg.append("                         on failed target(s)" + lSep);
+        msg
+                .append("  -propertyfile <name>   load all properties from file with -D"
+                        + lSep);
+        msg.append("                         properties taking precedence"
+                + lSep);
+        msg
+                .append("  -inputhandler <class>  the class which will handle input requests"
+                        + lSep);
+        msg
+                .append("  -find <file>           (s)earch for buildfile towards the root of"
+                        + lSep);
+        msg.append("    -s  <file>           the filesystem and use it" + lSep);
+        msg
+                .append("  -nice  number          A niceness value for the main thread:"
+                        + lSep
+                        + "                         1 (lowest) to 10 (highest); 5 is the default"
+                        + lSep);
+        msg
+                .append("  -nouserlib             Run ant without using the jar files from"
+                        + lSep
+                        + "                         ${user.home}/.ant/lib"
+                        + lSep);
+        msg.append("  -noclasspath           Run ant without using CLASSPATH"
+                + lSep);
+        msg
+                .append("  -autoproxy             Java1.5+: use the OS proxy settings"
+                        + lSep);
+        msg
+                .append("  -main <class>          override Ant's normal entry point");
+        System.out.println(msg.toString());
+    }
+
+    /**
+     * Prints the EasyAnt version information to <code>System.out</code>.
+     * 
+     * @exception BuildException
+     *                if the version information is unavailable
+     */
+    private static void printVersion(int logLevel) throws BuildException {
+        System.out.println(EasyAntEngine.getEasyAntVersion());
+        System.out.println(getAntVersion());
+    }
+
+    /**
+     * Cache of the Ant version information when it has been loaded.
+     */
+    private static String antVersion = null;
+
+    /**
+     * Returns the Ant version information, if available. Once the information
+     * has been loaded once, it's cached and returned from the cache on future
+     * calls.
+     * 
+     * @return the Ant version information as a String (always non-
+     *         <code>null</code>)
+     * 
+     * @exception BuildException
+     *                if the version information is unavailable
+     */
+    public static synchronized String getAntVersion() throws BuildException {
+        if (antVersion == null) {
+            try {
+                Properties props = new Properties();
+                InputStream in = Main.class
+                        .getResourceAsStream("/org/apache/tools/ant/version.txt");
+                props.load(in);
+                in.close();
+
+                StringBuffer msg = new StringBuffer();
+                msg.append("Apache Ant version ");
+                msg.append(props.getProperty("VERSION"));
+                msg.append(" compiled on ");
+                msg.append(props.getProperty("DATE"));
+                antVersion = msg.toString();
+            } catch (IOException ioe) {
+                throw new BuildException(
+                        "Could not load the version information:"
+                                + ioe.getMessage());
+            } catch (NullPointerException npe) {
+                throw new BuildException(
+                        "Could not load the version information.");
+            }
+        }
+        return antVersion;
+    }
 
 }