You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@taverna.apache.org by re...@apache.org on 2015/03/24 11:45:25 UTC

[3/5] incubator-taverna-commandline git commit: package name changes

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/9965dffe/taverna-commandline-launcher/src/main/java/org/apache/taverna/commandline/TavernaCommandLine.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-launcher/src/main/java/org/apache/taverna/commandline/TavernaCommandLine.java b/taverna-commandline-launcher/src/main/java/org/apache/taverna/commandline/TavernaCommandLine.java
new file mode 100644
index 0000000..64a7f38
--- /dev/null
+++ b/taverna-commandline-launcher/src/main/java/org/apache/taverna/commandline/TavernaCommandLine.java
@@ -0,0 +1,142 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.commandline;
+
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.taverna.commandline.exceptions.ArgumentsParsingException;
+import org.apache.taverna.commandline.exceptions.InvalidOptionException;
+import org.apache.taverna.commandline.options.CommandLineOptions;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+
+import uk.org.taverna.commons.profile.xml.jaxb.ApplicationProfile;
+import uk.org.taverna.commons.profile.xml.jaxb.BundleInfo;
+import uk.org.taverna.commons.profile.xml.jaxb.FrameworkConfiguration;
+import uk.org.taverna.configuration.app.ApplicationConfiguration;
+import uk.org.taverna.configuration.app.impl.ApplicationConfigurationImpl;
+import uk.org.taverna.configuration.app.impl.Log4JConfiguration;
+import uk.org.taverna.osgi.OsgiLauncher;
+
+/**
+ * Main entry point for starting the Taverna Command Line Tool.
+ *
+ * @author David Withers
+ */
+public class TavernaCommandLine {
+
+	private static final String COMMANDLINE_BUNDLE_NAME = "org.apache.taverna.commandline.taverna-commandline-common";
+
+	private static File commandlineBundle = null;
+
+	private static ApplicationConfiguration applicationConfiguration = new ApplicationConfigurationImpl();
+
+	private static Log4JConfiguration log4jConfiguration = new Log4JConfiguration();
+
+	/**
+	 * Starts the Taverna Command Line Tool.
+	 *
+	 * @param args
+	 *            Taverna Command Line arguments
+	 */
+	public static void main(final String[] args) {
+		try {
+			CommandLineOptions commandLineOptions = new CommandLineOptionsImpl(args);
+			if (commandLineOptions.askedForHelp()) {
+				commandLineOptions.displayHelp();
+			} else {
+				log4jConfiguration.setApplicationConfiguration(applicationConfiguration);
+				log4jConfiguration.prepareLog4J();
+				setDerbyPaths();
+				OsgiLauncher osgilauncher = new OsgiLauncher(getAppDirectory(), getBundleURIs());
+				setFrameworkConfiguration(osgilauncher);
+				osgilauncher.start();
+				BundleContext context = osgilauncher.getContext();
+				context.registerService("org.apache.taverna.commandline.options.CommandLineOptions",
+						commandLineOptions, null);
+				osgilauncher.startServices(true);
+        if (commandlineBundle == null) {
+          System.err.println("Can't locate command line bundle " + COMMANDLINE_BUNDLE_NAME);
+          System.exit(1);
+        }
+				osgilauncher.startBundle(osgilauncher.installBundle(commandlineBundle.toURI()));
+			}
+		} catch (ArgumentsParsingException e) {
+			System.out.println(e.getMessage());
+		} catch (InvalidOptionException e) {
+			System.out.println(e.getMessage());
+		} catch (BundleException e) {
+			System.out.println(e.getMessage());
+		}
+	}
+
+	/**
+	 * Sets the OSGi Framework configuration.
+	 *
+	 * @param osgilauncher
+	 */
+	private static void setFrameworkConfiguration(OsgiLauncher osgilauncher) {
+		ApplicationProfile applicationProfile = applicationConfiguration.getApplicationProfile();
+		List<FrameworkConfiguration> frameworkConfigurations = applicationProfile
+				.getFrameworkConfiguration();
+		if (!frameworkConfigurations.isEmpty()) {
+			Map<String, String> configurationMap = new HashMap<String, String>();
+			for (FrameworkConfiguration frameworkConfiguration : frameworkConfigurations) {
+				configurationMap.put(frameworkConfiguration.getName(),
+						frameworkConfiguration.getValue());
+			}
+			osgilauncher.setFrameworkConfiguration(configurationMap);
+		}
+	}
+
+	private static List<URI> getBundleURIs() {
+		List<URI> bundleURIs = new ArrayList<URI>();
+		ApplicationProfile applicationProfile = applicationConfiguration.getApplicationProfile();
+		File libDir = new File(applicationConfiguration.getStartupDir(), "lib");
+		if (applicationProfile != null) {
+			for (BundleInfo bundle : applicationProfile.getBundle()) {
+				File bundleFile = new File(libDir, bundle.getFileName());
+				if (bundle.getSymbolicName().equals(COMMANDLINE_BUNDLE_NAME)) {
+					commandlineBundle = bundleFile;
+				} else {
+					bundleURIs.add(bundleFile.toURI());
+				}
+			}
+		}
+		return bundleURIs;
+	}
+
+	private static File getAppDirectory() {
+		return new File(applicationConfiguration.getApplicationHomeDir().getAbsolutePath());
+	}
+
+	private static void setDerbyPaths() {
+		System.setProperty("derby.system.home", getAppDirectory().getAbsolutePath());
+		File logFile = new File(applicationConfiguration.getLogDir(), "derby.log");
+		System.setProperty("derby.stream.error.file", logFile.getAbsolutePath());
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/9965dffe/taverna-commandline-launcher/src/main/java/uk/org/taverna/commandline/CommandLineOptionsImpl.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-launcher/src/main/java/uk/org/taverna/commandline/CommandLineOptionsImpl.java b/taverna-commandline-launcher/src/main/java/uk/org/taverna/commandline/CommandLineOptionsImpl.java
deleted file mode 100644
index b702e03..0000000
--- a/taverna-commandline-launcher/src/main/java/uk/org/taverna/commandline/CommandLineOptionsImpl.java
+++ /dev/null
@@ -1,445 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- *  Modifications to the initial code base are copyright of their
- *  respective authors, or their employers as appropriate.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public License
- *  as published by the Free Software Foundation; either version 2.1 of
- *  the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- ******************************************************************************/
-package uk.org.taverna.commandline;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import net.sf.taverna.t2.commandline.exceptions.ArgumentsParsingException;
-import net.sf.taverna.t2.commandline.exceptions.InvalidOptionException;
-import net.sf.taverna.t2.commandline.options.CommandLineOptions;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.GnuParser;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.Option;
-import org.apache.commons.cli.OptionBuilder;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.commons.io.IOUtils;
-import org.apache.log4j.Logger;
-
-/**
- * Handles the processing of command line arguments for enacting a workflow.
- * This class encapsulates all command line options, and exposes them through higher-level
- * accessors. Upon creation it checks the validity of the command line options and raises an
- * {@link InvalidOptionException} if they are invalid.
- *
- * @author Stuart Owen
- * @author David Withers
- */
-public class CommandLineOptionsImpl implements CommandLineOptions {
-
-	private static final String OUTPUTDIR = "outputdir";
-	private static final String BUNDLE = "bundle";
-	private static final Logger logger = Logger.getLogger(CommandLineOptionsImpl.class);
-	private Options options;
-	private CommandLine commandLine;
-
-	public CommandLineOptionsImpl(String[] args) throws ArgumentsParsingException, InvalidOptionException {
-		this.options = intitialiseOptions();
-		this.commandLine = processArgs(args);
-		checkForInvalid();
-	}
-
-	@Override
-	public boolean askedForHelp() {
-		return hasOption("help") || (getArgs().length==0 && getOptions().length==0);
-	}
-
-	@Override
-	public boolean isProvenanceEnabled() {
-		return hasOption("provenance");
-	}
-
-	protected void checkForInvalid() throws InvalidOptionException {
-		if (askedForHelp()) return;
-		if (isProvenanceEnabled()
-				&& !(hasOption("embedded") || hasOption("clientserver") || hasOption("dbproperties")))
-			throw new InvalidOptionException(
-					"You should be running with a database to use provenance");
-		if (isProvenanceEnabled() && hasOption("inmemory"))
-			throw new InvalidOptionException(
-					"You should be running with a database to use provenance");
-		if ((hasOption("inputfile") || hasOption("inputvalue"))
-				&& hasOption("inputdoc"))
-			throw new InvalidOptionException(
-					"You can't provide both -input and -inputdoc arguments");
-
-		if (hasOption("inputdelimiter") && hasOption("inputdoc"))
-			throw new InvalidOptionException("You cannot combine the -inputdelimiter and -inputdoc arguments");
-
-		if (getArgs().length == 0
-				&& !(hasOption("help") || hasOption("startdb")))
-			throw new InvalidOptionException("You must specify a workflow");
-
-		if (hasOption("inmemory") && hasOption("embedded"))
-			throw new InvalidOptionException(
-					"The options -embedded, -clientserver and -inmemory cannot be used together");
-		if (hasOption("inmemory") && hasOption("clientserver"))
-			throw new InvalidOptionException(
-					"The options -embedded, -clientserver and -inmemory cannot be used together");
-		if (hasOption("embedded") && hasOption("clientserver"))
-			throw new InvalidOptionException(
-					"The options -embedded, -clientserver and -inmemory cannot be used together");
-	}
-
-	@Override
-	public void displayHelp() {
-		boolean full = false;
-		if (hasOption("help")) full=true;
-		displayHelp(full);
-	}
-
-	@Override
-	public void displayHelp(boolean showFullText) {
-
-		HelpFormatter formatter = new HelpFormatter();
-		try {
-			formatter
-					.printHelp("executeworkflow [options] [workflow]", options);
-			if (showFullText) {
-				InputStream helpStream = CommandLineOptionsImpl.class
-						.getClassLoader().getResourceAsStream("help.txt");
-				String helpText = IOUtils.toString(helpStream);
-				System.out.println(helpText);
-			}
-
-		} catch (IOException e) {
-			logger.error("Failed to load the help document", e);
-			System.out.println("Failed to load the help document");
-			//System.exit(-1);
-		}
-	}
-
-	@Override
-	public String[] getArgs() {
-		return commandLine.getArgs();
-	}
-
-	/**
-	 *
-	 * @return the port that the database should run on
-	 */
-	@Override
-	public String getDatabasePort() {
-		return getOptionValue("port");
-	}
-
-	/**
-	 *
-	 * @return a path to a properties file that contains database configuration
-	 *         settings
-	 */
-	@Override
-	public String getDatabaseProperties() {
-		return getOptionValue("dbproperties");
-	}
-
-	/**
-	 * Returns an array that alternates between a portname and path to a file
-	 * containing the input values. Therefore the array will always contain an
-	 * even number of elements
-	 *
-	 * @return an array of portname and path to files containing individual
-	 *         inputs.
-	 */
-	@Override
-	public String[] getInputFiles() {
-		if (hasInputFiles()) {
-			return getOptionValues("inputfile");
-		} else {
-			return new String[] {};
-		}
-	}
-
-	@Override
-	public String[] getInputValues() {
-		if (hasInputValues()) {
-			return getOptionValues("inputvalue");
-		} else {
-			return new String[] {};
-		}
-	}
-
-	@Override
-	public String getLogFile() {
-		return getOptionValue("logfile");
-	}
-
-	public Option [] getOptions() {
-		return commandLine.getOptions();
-	}
-
-	private String getOptionValue(String opt) {
-		return commandLine.getOptionValue(opt);
-	}
-
-	private String[] getOptionValues(String arg0) {
-		return commandLine.getOptionValues(arg0);
-	}
-
-	/**
-	 *
-	 * @return the directory to write the results to
-	 */
-	@Override
-	public String getOutputDirectory() {
-		return getOptionValue(OUTPUTDIR);
-	}
-
-	@Override
-	public boolean getStartDatabase() {
-		return hasOption("startdb");
-	}
-
-	/**
-	 * @return the directory with Credential Manager's files
-	 */
-	@Override
-	public String getCredentialManagerDir() {
-		return getOptionValue(CREDENTIAL_MANAGER_DIR_OPTION);
-	}
-
-	@Override
-	public boolean getStartDatabaseOnly() throws InvalidOptionException {
-		return (getStartDatabase() && (getWorkflow() == null));
-	}
-
-	@Override
-	public String getWorkflow() throws InvalidOptionException {
-		if (getArgs().length == 0) {
-			return null;
-		} else if (getArgs().length != 1) {
-			throw new InvalidOptionException(
-					"You should only specify one workflow file");
-		} else {
-			return getArgs()[0];
-		}
-	}
-
-	@Override
-	public boolean hasDelimiterFor(String inputName) {
-		boolean result = false;
-		if (hasOption("inputdelimiter")) {
-			String [] values = getOptionValues("inputdelimiter");
-			for (int i=0;i<values.length;i+=2) {
-				if (values[i].equals(inputName))
-				{
-					result=true;
-					break;
-				}
-			}
-		}
-		return result;
-	}
-
-	@Override
-	public boolean hasInputFiles() {
-		return hasOption("inputfile");
-	}
-
-	@Override
-	public boolean hasInputValues() {
-		return hasOption("inputvalue");
-	}
-
-	@Override
-	public boolean hasLogFile() {
-		return hasOption("logfile");
-	}
-
-	@Override
-	public boolean hasOption(String option) {
-		return commandLine.hasOption(option);
-	}
-
-	@Override
-	public String inputDelimiter(String inputName) {
-		String result = null;
-		if (hasOption("inputdelimiter")) {
-			String [] values = getOptionValues("inputdelimiter");
-			for (int i=0;i<values.length;i+=2) {
-				if (values[i].equals(inputName))
-				{
-					result=values[i+1];
-					break;
-				}
-			}
-		}
-		return result;
-	}
-
-	@SuppressWarnings("static-access")
-	private Options intitialiseOptions() {
-		Option helpOption = new Option("help", "Display comprehensive help information.");
-
-		Option outputOption = OptionBuilder
-				.withArgName("directory")
-				.hasArg()
-				.withDescription(
-						"Save outputs as files in directory, default "
-								+ "is to make a new directory workflowName_output.")
-				.create(OUTPUTDIR);
-
-		Option bundleOption = OptionBuilder.withArgName(BUNDLE).hasArg()
-				.withDescription("Save outputs to a new Workflow Run Bundle (zip).")
-				.create(BUNDLE);
-
-		Option logFileOption = OptionBuilder
-				.withArgName("filename")
-				.hasArg()
-				.withDescription(
-						"The logfile to which more verbose logging will be written to.")
-				.create("logfile");
-
-		Option inputdocOption = OptionBuilder.withArgName("document").hasArg()
-				.withDescription("Load inputs from a Baclava document.").create(
-						"inputdoc");
-
-		Option inputFileOption = OptionBuilder
-				.withArgName("inputname filename").hasArgs(2)
-				.withValueSeparator(' ').withDescription(
-						"Load the named input from file or URL.").create(
-						"inputfile");
-
-		Option inputValueOption = OptionBuilder.withArgName("inputname value")
-				.hasArgs(2).withValueSeparator(' ').withDescription(
-						"Directly use the value for the named input.").create(
-						"inputvalue");
-
-		Option inputDelimiterOption = OptionBuilder
-				.withArgName("inputname delimiter")
-				.hasArgs(2)
-				.withValueSeparator(' ')
-				.withDescription(
-						"Cause an inputvalue or inputfile to be split into a list according to the delimiter. The associated workflow input must be expected to receive a list.")
-				.create("inputdelimiter");
-
-		Option dbProperties = OptionBuilder.withArgName("filename").hasArg()
-				.withDescription(
-						"Load a properties file to configure the database.")
-				.create("dbproperties");
-
-		Option port = OptionBuilder
-				.withArgName("portnumber")
-				.hasArg()
-				.withDescription(
-						"The port that the database is running on. If set requested to start its own internal server, this is the start port that will be used.")
-				.create("port");
-
-		Option embedded = new Option("embedded",
-				"Connect to an embedded Derby database. This can prevent mulitple invocations.");
-		Option clientserver = new Option("clientserver",
-				"Connect as a client to a derby server instance.");
-		Option inMemOption = new Option(
-				"inmemory",
-				"Run the workflow with data stored in-memory rather than in a database (this is the default option). This can give performance inprovements, at the cost of overall memory usage.");
-		Option startDB = new Option("startdb",
-				"Automatically start an internal Derby database server.");
-		Option provenance = new Option("provenance",
-				"Generate provenance information and store it in the database.");
-
-
-		Option credentialManagerDirectory = OptionBuilder.withArgName("directory path").
-		hasArg().withDescription(
-				"Absolute path to a directory where Credential Manager's files (keystore and truststore) are located.")
-		.create(CREDENTIAL_MANAGER_DIR_OPTION);
-		Option credentialManagerPassword = new Option(CREDENTIAL_MANAGER_PASSWORD_OPTION, "Indicate that the master password for Credential Manager will be provided on standard input."); // optional password option, to be read from standard input
-
-		Options options = new Options();
-		options.addOption(helpOption);
-		options.addOption(inputFileOption);
-		options.addOption(inputValueOption);
-		options.addOption(inputDelimiterOption);
-		options.addOption(inputdocOption);
-		options.addOption(outputOption);
-		options.addOption(bundleOption);
-		options.addOption(inMemOption);
-		options.addOption(embedded);
-		options.addOption(clientserver);
-		options.addOption(dbProperties);
-		options.addOption(port);
-		options.addOption(startDB);
-		options.addOption(provenance);
-		options.addOption(logFileOption);
-		options.addOption(credentialManagerDirectory);
-		options.addOption(credentialManagerPassword);
-
-		return options;
-	}
-
-	@Override
-	public boolean isClientServer() {
-		return hasOption("clientserver");
-	}
-
-	@Override
-	public boolean isEmbedded() {
-		return hasOption("embedded");
-	}
-
-	@Override
-	public boolean isInMemory() {
-		return hasOption("inmemory");
-	}
-
-	private CommandLine processArgs(String[] args) throws ArgumentsParsingException {
-		CommandLineParser parser = new GnuParser();
-		CommandLine line = null;
-		try {
-			// parse the command line arguments
-			line = parser.parse(options, args);
-		} catch (ParseException exp) {
-			// oops, something went wrong
-//			System.err.println("Taverna command line arguments' parsing failed. Reason: " + exp.getMessage());
-//			System.exit(1);
-			throw new ArgumentsParsingException("Taverna command line arguments' parsing failed. Reason: " + exp.getMessage(), exp);
-		}
-		return line;
-	}
-
-	/**
-	 * Save the results to a directory if -outputdir has been explicitly defined,
-	 * or if -outputdoc has not been defined.
-	 *
-	 * @return boolean
-	 */
-	@Override
-	public boolean saveResultsToDirectory() {
-		return (options.hasOption(OUTPUTDIR) || !hasSaveResultsToBundle());
-	}
-
-	@Override
-	public String saveResultsToBundle() {
-		if (! hasSaveResultsToBundle()) { 
-			return null;
-		}
-		return getOptionValue(BUNDLE);
-	}
-
-	@Override
-	public boolean hasSaveResultsToBundle() {
-		return hasOption(BUNDLE);
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/9965dffe/taverna-commandline-launcher/src/main/java/uk/org/taverna/commandline/TavernaCommandLine.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-launcher/src/main/java/uk/org/taverna/commandline/TavernaCommandLine.java b/taverna-commandline-launcher/src/main/java/uk/org/taverna/commandline/TavernaCommandLine.java
deleted file mode 100644
index 426ab98..0000000
--- a/taverna-commandline-launcher/src/main/java/uk/org/taverna/commandline/TavernaCommandLine.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2012 The University of Manchester
- *
- *  Modifications to the initial code base are copyright of their
- *  respective authors, or their employers as appropriate.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public License
- *  as published by the Free Software Foundation; either version 2.1 of
- *  the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- ******************************************************************************/
-package uk.org.taverna.commandline;
-
-import java.io.File;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import net.sf.taverna.t2.commandline.exceptions.ArgumentsParsingException;
-import net.sf.taverna.t2.commandline.exceptions.InvalidOptionException;
-import net.sf.taverna.t2.commandline.options.CommandLineOptions;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-
-import uk.org.taverna.commons.profile.xml.jaxb.ApplicationProfile;
-import uk.org.taverna.commons.profile.xml.jaxb.BundleInfo;
-import uk.org.taverna.commons.profile.xml.jaxb.FrameworkConfiguration;
-import uk.org.taverna.configuration.app.ApplicationConfiguration;
-import uk.org.taverna.configuration.app.impl.ApplicationConfigurationImpl;
-import uk.org.taverna.configuration.app.impl.Log4JConfiguration;
-import uk.org.taverna.osgi.OsgiLauncher;
-
-/**
- * Main entry point for starting the Taverna Command Line Tool.
- *
- * @author David Withers
- */
-public class TavernaCommandLine {
-
-	private static final String COMMANDLINE_BUNDLE_NAME = "org.apache.taverna.commandline.taverna-commandline-common";
-
-	private static File commandlineBundle = null;
-
-	private static ApplicationConfiguration applicationConfiguration = new ApplicationConfigurationImpl();
-
-	private static Log4JConfiguration log4jConfiguration = new Log4JConfiguration();
-
-	/**
-	 * Starts the Taverna Command Line Tool.
-	 *
-	 * @param args
-	 *            Taverna Command Line arguments
-	 */
-	public static void main(final String[] args) {
-		try {
-			CommandLineOptions commandLineOptions = new CommandLineOptionsImpl(args);
-			if (commandLineOptions.askedForHelp()) {
-				commandLineOptions.displayHelp();
-			} else {
-				log4jConfiguration.setApplicationConfiguration(applicationConfiguration);
-				log4jConfiguration.prepareLog4J();
-				setDerbyPaths();
-				OsgiLauncher osgilauncher = new OsgiLauncher(getAppDirectory(), getBundleURIs());
-				setFrameworkConfiguration(osgilauncher);
-				osgilauncher.start();
-				BundleContext context = osgilauncher.getContext();
-				context.registerService("net.sf.taverna.t2.commandline.options.CommandLineOptions",
-						commandLineOptions, null);
-				osgilauncher.startServices(true);
-        if (commandlineBundle == null) {
-          System.err.println("Can't locate command line bundle " + COMMANDLINE_BUNDLE_NAME);
-          System.exit(1);
-        }
-				osgilauncher.startBundle(osgilauncher.installBundle(commandlineBundle.toURI()));
-			}
-		} catch (ArgumentsParsingException e) {
-			System.out.println(e.getMessage());
-		} catch (InvalidOptionException e) {
-			System.out.println(e.getMessage());
-		} catch (BundleException e) {
-			System.out.println(e.getMessage());
-		}
-	}
-
-	/**
-	 * Sets the OSGi Framework configuration.
-	 *
-	 * @param osgilauncher
-	 */
-	private static void setFrameworkConfiguration(OsgiLauncher osgilauncher) {
-		ApplicationProfile applicationProfile = applicationConfiguration.getApplicationProfile();
-		List<FrameworkConfiguration> frameworkConfigurations = applicationProfile
-				.getFrameworkConfiguration();
-		if (!frameworkConfigurations.isEmpty()) {
-			Map<String, String> configurationMap = new HashMap<String, String>();
-			for (FrameworkConfiguration frameworkConfiguration : frameworkConfigurations) {
-				configurationMap.put(frameworkConfiguration.getName(),
-						frameworkConfiguration.getValue());
-			}
-			osgilauncher.setFrameworkConfiguration(configurationMap);
-		}
-	}
-
-	private static List<URI> getBundleURIs() {
-		List<URI> bundleURIs = new ArrayList<URI>();
-		ApplicationProfile applicationProfile = applicationConfiguration.getApplicationProfile();
-		File libDir = new File(applicationConfiguration.getStartupDir(), "lib");
-		if (applicationProfile != null) {
-			for (BundleInfo bundle : applicationProfile.getBundle()) {
-				File bundleFile = new File(libDir, bundle.getFileName());
-				if (bundle.getSymbolicName().equals(COMMANDLINE_BUNDLE_NAME)) {
-					commandlineBundle = bundleFile;
-				} else {
-					bundleURIs.add(bundleFile.toURI());
-				}
-			}
-		}
-		return bundleURIs;
-	}
-
-	private static File getAppDirectory() {
-		return new File(applicationConfiguration.getApplicationHomeDir().getAbsolutePath());
-	}
-
-	private static void setDerbyPaths() {
-		System.setProperty("derby.system.home", getAppDirectory().getAbsolutePath());
-		File logFile = new File(applicationConfiguration.getLogDir(), "derby.log");
-		System.setProperty("derby.stream.error.file", logFile.getAbsolutePath());
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/9965dffe/taverna-commandline-launcher/src/test/java/org/apache/taverna/commandline/TestCommandLineOptionsHandler.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-launcher/src/test/java/org/apache/taverna/commandline/TestCommandLineOptionsHandler.java b/taverna-commandline-launcher/src/test/java/org/apache/taverna/commandline/TestCommandLineOptionsHandler.java
new file mode 100644
index 0000000..9fb1bf3
--- /dev/null
+++ b/taverna-commandline-launcher/src/test/java/org/apache/taverna/commandline/TestCommandLineOptionsHandler.java
@@ -0,0 +1,286 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.commandline;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import org.apache.taverna.commandline.exceptions.InvalidOptionException;
+import org.apache.taverna.commandline.options.CommandLineOptions;
+
+import org.junit.Test;
+
+public class TestCommandLineOptionsHandler {
+
+	@Test
+	public void testWorkflowName() throws Exception {
+		CommandLineOptions handler = new CommandLineOptionsImpl(
+				new String[] { "myworkflow.t2flow" });
+		assertEquals("myworkflow.t2flow", handler.getWorkflow());
+	}
+
+	@Test
+	public void shouldShowHelp() throws Exception {
+		CommandLineOptions options = new CommandLineOptionsImpl(
+				new String[] { "-help" });
+		assertTrue(options.askedForHelp());
+		options = new CommandLineOptionsImpl(
+				new String[] {});
+		assertTrue(options.askedForHelp());
+		options = new CommandLineOptionsImpl(new String[] { "myworkflow.t2flow" });
+		assertFalse(options.askedForHelp());
+	}
+
+	@Test
+	public void getWorkflow() throws Exception {
+		CommandLineOptions options = new CommandLineOptionsImpl(
+				new String[] { "-help" });
+		assertNull(options.getWorkflow());
+		options = new CommandLineOptionsImpl(new String[] { "myworkflow.t2flow" });
+		assertEquals("myworkflow.t2flow", options.getWorkflow());
+	}
+
+	@Test(expected = InvalidOptionException.class)
+	public void cannotProvideInputFileAndInputDoc() throws Exception {
+		new CommandLineOptionsImpl(new String[] { "-inputfile", "fred", "fred.txt",
+				"-inputdoc", "myworkflow.t2flow" });
+	}
+
+	@Test(expected = InvalidOptionException.class)
+	public void cannotProvideInputValueAndInputDoc() throws Exception {
+		new CommandLineOptionsImpl(new String[] { "-inputvalue", "fred", "fred.txt",
+				"-inputdoc", "myworkflow.t2flow" });
+	}
+
+	@Test
+	public void canProvideInputValueAndFileTogether() throws Exception {
+		//should not be an error
+		new CommandLineOptionsImpl(new String[] { "-inputvalue", "fred", "abc",
+				"-inputfile","fred2","fred2.txt","myworkflow.t2flow" });
+	}
+
+	@Test
+	public void getInputs() throws Exception {
+		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
+				"-inputfile", "fred", "fred.txt", "myworkflow.t2flow" });
+		assertEquals(2, options.getInputFiles().length);
+		assertEquals("fred", options.getInputFiles()[0]);
+		assertEquals("fred.txt", options.getInputFiles()[1]);
+
+		options = new CommandLineOptionsImpl(new String[] { "-inputfile", "fred",
+				"fred.txt", "-inputfile", "fred2", "fred2.txt",
+				"myworkflow.t2flow" });
+		assertEquals(4, options.getInputFiles().length);
+		assertEquals("fred", options.getInputFiles()[0]);
+		assertEquals("fred.txt", options.getInputFiles()[1]);
+		assertEquals("fred2", options.getInputFiles()[2]);
+		assertEquals("fred2.txt", options.getInputFiles()[3]);
+
+		options = new CommandLineOptionsImpl(new String[] { "myworkflow.t2flow" });
+		assertNotNull(options.getInputFiles());
+		assertEquals(0, options.getInputFiles().length);
+
+	}
+
+	@Test
+	public void hasInputValue() throws Exception {
+		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
+				"-inputvalue", "fred", "abc", "myworkflow.t2flow" });
+		assertTrue(options.hasInputValues());
+
+		options = new CommandLineOptionsImpl(new String[] { "myworkflow.t2flow" });
+		assertFalse(options.hasInputValues());
+	}
+
+	@Test
+	public void getInputValues() throws Exception {
+		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
+				"-inputvalue", "fred", "abc", "myworkflow.t2flow" });
+		assertEquals(2, options.getInputValues().length);
+
+		options = new CommandLineOptionsImpl(new String[] { "myworkflow.t2flow" });
+		assertNotNull(options.getInputValues());
+		assertEquals(0,options.getInputValues().length);
+	}
+
+	@Test
+	public void hasInputs() throws Exception {
+		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
+				"-inputfile", "fred", "fred.txt", "myworkflow.t2flow" });
+		assertTrue(options.hasInputFiles());
+
+		options = new CommandLineOptionsImpl(new String[] { "myworkflow.t2flow" });
+		assertFalse(options.hasInputFiles());
+	}
+
+	@Test
+	public void noWorkflowNameButStartDB() throws Exception {
+		// should not throw an error
+		CommandLineOptions options = new CommandLineOptionsImpl(
+				new String[] { "-startdb" });
+		assertTrue(options.getStartDatabase());
+		assertTrue(options.getStartDatabaseOnly());
+	}
+
+	@Test
+	public void workflowNameAndStartDB() throws Exception {
+		// should not throw an error
+		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
+				"-startdb", "myworkflow.t2flow" });
+		assertTrue(options.getStartDatabase());
+		assertFalse(options.getStartDatabaseOnly());
+	}
+
+	@Test(expected = InvalidOptionException.class)
+	public void provenanceButNoDatabase() throws Exception {
+		new CommandLineOptionsImpl(new String[] { "-provenance",
+				"myworkflow.t2flow" });
+	}
+
+	@Test(expected = InvalidOptionException.class)
+	public void provenanceButNoDatabase2() throws Exception {
+		new CommandLineOptionsImpl(new String[] { "-provenance", "-inmemory",
+				"myworkflow.t2flow" });
+	}
+
+	@Test
+	public void provenanceDatabase() throws Exception {
+		// should be no errors
+		new CommandLineOptionsImpl(new String[] { "-provenance", "-embedded",
+				"myworkflow.t2flow" });
+		new CommandLineOptionsImpl(new String[] { "-provenance", "-clientserver",
+				"myworkflow.t2flow" });
+		new CommandLineOptionsImpl(new String[] { "-provenance", "-dbproperties",
+				"dbproperties.properties", "myworkflow.t2flow" });
+	}
+
+	@Test
+	public void testHasInputDelimiter() throws Exception {
+		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
+				"-inputvalue","in1","1,2,3","-inputdelimiter","in1",",","-inputdelimiter","in2",",","myworkflow.t2flow" });
+		assertTrue(options.hasDelimiterFor("in1"));
+		assertTrue(options.hasDelimiterFor("in2"));
+		assertFalse(options.hasDelimiterFor("in3"));
+	}
+
+	@Test(expected = InvalidOptionException.class)
+	public void testInputDelimiterInvalidWithInputDoc() throws Exception {
+		new CommandLineOptionsImpl(new String[] {
+				"-inputdoc","doc.xml","-inputdelimiter","in1",",","myworkflow.t2flow" });
+	}
+
+
+	@Test
+	public void testInputDelimiter() throws Exception {
+		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
+				"-inputvalue","in1","1,2,3","-inputdelimiter","in1",",","-inputdelimiter","in2","!","myworkflow.t2flow" });
+		assertEquals(",",options.inputDelimiter("in1"));
+		assertEquals("!",options.inputDelimiter("in2"));
+		assertNull(options.inputDelimiter("in3"));
+	}
+
+	@Test
+	public void testInMemory() throws Exception {
+		CommandLineOptions handler = new CommandLineOptionsImpl(new String[] {
+				"-inmemory", "myworkflow.t2flow" });
+		assertTrue(handler.hasOption("inmemory"));
+	}
+
+	@Test
+	public void testEmbedded() throws Exception {
+		CommandLineOptions handler = new CommandLineOptionsImpl(new String[] {
+				"-embedded", "myworkflow.t2flow" });
+		assertTrue(handler.hasOption("embedded"));
+	}
+
+	@Test
+	public void testClientServer() throws Exception {
+		CommandLineOptions handler = new CommandLineOptionsImpl(new String[] {
+				"-clientserver", "myworkflow.t2flow" });
+		assertTrue(handler.hasOption("clientserver"));
+	}
+
+	@Test(expected = InvalidOptionException.class)
+	public void testInvalidEmbeddedAndClientServer() throws Exception {
+		new CommandLineOptionsImpl(new String[] { "-clientserver", "-embedded",
+				"myworkflow.t2flow" });
+	}
+
+	@Test(expected = InvalidOptionException.class)
+	public void testInvalidEmbeddedAndMemory() throws Exception {
+		new CommandLineOptionsImpl(new String[] { "-embedded", "-inmemory",
+				"myworkflow.t2flow" });
+	}
+
+	@Test(expected = InvalidOptionException.class)
+	public void testInvalidClientServerAndInMemory() throws Exception {
+		new CommandLineOptionsImpl(new String[] { "-clientserver", "-inmemory",
+				"myworkflow.t2flow" });
+	}
+
+	@Test
+	public void isInMemory() throws Exception {
+		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
+				"-inmemory", "myworkflow.t2flow" });
+
+		assertTrue(options.isInMemory());
+		assertFalse(options.isClientServer());
+		assertFalse(options.isEmbedded());
+	}
+
+	@Test
+	public void isClientServer() throws Exception {
+		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
+				"-clientserver", "myworkflow.t2flow" });
+
+		assertTrue(options.isClientServer());
+		assertFalse(options.isInMemory());
+		assertFalse(options.isEmbedded());
+	}
+
+	@Test
+	public void hasLogFile() throws Exception {
+		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
+				"-logfile","/tmp/logging", "myworkflow.t2flow" });
+
+		assertTrue(options.hasLogFile());
+		assertEquals("/tmp/logging", options.getLogFile());
+	}
+
+	@Test(expected = InvalidOptionException.class)
+	@SuppressWarnings("unused")
+	public void hasLogFileNotValidWithoutWorkflow() throws Exception{
+		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
+				"-logfile","/tmp/logging"});
+	}
+
+	@Test
+	public void isEmbedded() throws Exception {
+		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
+				"-embedded", "myworkflow.t2flow" });
+
+		assertTrue(options.isEmbedded());
+		assertFalse(options.isInMemory());
+		assertFalse(options.isClientServer());
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/9965dffe/taverna-commandline-launcher/src/test/java/uk/org/taverna/commandline/TestCommandLineOptionsHandler.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-launcher/src/test/java/uk/org/taverna/commandline/TestCommandLineOptionsHandler.java b/taverna-commandline-launcher/src/test/java/uk/org/taverna/commandline/TestCommandLineOptionsHandler.java
deleted file mode 100644
index 3e1d0f4..0000000
--- a/taverna-commandline-launcher/src/test/java/uk/org/taverna/commandline/TestCommandLineOptionsHandler.java
+++ /dev/null
@@ -1,267 +0,0 @@
-package uk.org.taverna.commandline;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import net.sf.taverna.t2.commandline.exceptions.InvalidOptionException;
-import net.sf.taverna.t2.commandline.options.CommandLineOptions;
-
-import org.junit.Test;
-
-public class TestCommandLineOptionsHandler {
-
-	@Test
-	public void testWorkflowName() throws Exception {
-		CommandLineOptions handler = new CommandLineOptionsImpl(
-				new String[] { "myworkflow.t2flow" });
-		assertEquals("myworkflow.t2flow", handler.getWorkflow());
-	}
-
-	@Test
-	public void shouldShowHelp() throws Exception {
-		CommandLineOptions options = new CommandLineOptionsImpl(
-				new String[] { "-help" });
-		assertTrue(options.askedForHelp());
-		options = new CommandLineOptionsImpl(
-				new String[] {});
-		assertTrue(options.askedForHelp());
-		options = new CommandLineOptionsImpl(new String[] { "myworkflow.t2flow" });
-		assertFalse(options.askedForHelp());
-	}
-
-	@Test
-	public void getWorkflow() throws Exception {
-		CommandLineOptions options = new CommandLineOptionsImpl(
-				new String[] { "-help" });
-		assertNull(options.getWorkflow());
-		options = new CommandLineOptionsImpl(new String[] { "myworkflow.t2flow" });
-		assertEquals("myworkflow.t2flow", options.getWorkflow());
-	}
-
-	@Test(expected = InvalidOptionException.class)
-	public void cannotProvideInputFileAndInputDoc() throws Exception {
-		new CommandLineOptionsImpl(new String[] { "-inputfile", "fred", "fred.txt",
-				"-inputdoc", "myworkflow.t2flow" });
-	}
-
-	@Test(expected = InvalidOptionException.class)
-	public void cannotProvideInputValueAndInputDoc() throws Exception {
-		new CommandLineOptionsImpl(new String[] { "-inputvalue", "fred", "fred.txt",
-				"-inputdoc", "myworkflow.t2flow" });
-	}
-
-	@Test
-	public void canProvideInputValueAndFileTogether() throws Exception {
-		//should not be an error
-		new CommandLineOptionsImpl(new String[] { "-inputvalue", "fred", "abc",
-				"-inputfile","fred2","fred2.txt","myworkflow.t2flow" });
-	}
-
-	@Test
-	public void getInputs() throws Exception {
-		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
-				"-inputfile", "fred", "fred.txt", "myworkflow.t2flow" });
-		assertEquals(2, options.getInputFiles().length);
-		assertEquals("fred", options.getInputFiles()[0]);
-		assertEquals("fred.txt", options.getInputFiles()[1]);
-
-		options = new CommandLineOptionsImpl(new String[] { "-inputfile", "fred",
-				"fred.txt", "-inputfile", "fred2", "fred2.txt",
-				"myworkflow.t2flow" });
-		assertEquals(4, options.getInputFiles().length);
-		assertEquals("fred", options.getInputFiles()[0]);
-		assertEquals("fred.txt", options.getInputFiles()[1]);
-		assertEquals("fred2", options.getInputFiles()[2]);
-		assertEquals("fred2.txt", options.getInputFiles()[3]);
-
-		options = new CommandLineOptionsImpl(new String[] { "myworkflow.t2flow" });
-		assertNotNull(options.getInputFiles());
-		assertEquals(0, options.getInputFiles().length);
-
-	}
-
-	@Test
-	public void hasInputValue() throws Exception {
-		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
-				"-inputvalue", "fred", "abc", "myworkflow.t2flow" });
-		assertTrue(options.hasInputValues());
-
-		options = new CommandLineOptionsImpl(new String[] { "myworkflow.t2flow" });
-		assertFalse(options.hasInputValues());
-	}
-
-	@Test
-	public void getInputValues() throws Exception {
-		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
-				"-inputvalue", "fred", "abc", "myworkflow.t2flow" });
-		assertEquals(2, options.getInputValues().length);
-
-		options = new CommandLineOptionsImpl(new String[] { "myworkflow.t2flow" });
-		assertNotNull(options.getInputValues());
-		assertEquals(0,options.getInputValues().length);
-	}
-
-	@Test
-	public void hasInputs() throws Exception {
-		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
-				"-inputfile", "fred", "fred.txt", "myworkflow.t2flow" });
-		assertTrue(options.hasInputFiles());
-
-		options = new CommandLineOptionsImpl(new String[] { "myworkflow.t2flow" });
-		assertFalse(options.hasInputFiles());
-	}
-
-	@Test
-	public void noWorkflowNameButStartDB() throws Exception {
-		// should not throw an error
-		CommandLineOptions options = new CommandLineOptionsImpl(
-				new String[] { "-startdb" });
-		assertTrue(options.getStartDatabase());
-		assertTrue(options.getStartDatabaseOnly());
-	}
-
-	@Test
-	public void workflowNameAndStartDB() throws Exception {
-		// should not throw an error
-		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
-				"-startdb", "myworkflow.t2flow" });
-		assertTrue(options.getStartDatabase());
-		assertFalse(options.getStartDatabaseOnly());
-	}
-
-	@Test(expected = InvalidOptionException.class)
-	public void provenanceButNoDatabase() throws Exception {
-		new CommandLineOptionsImpl(new String[] { "-provenance",
-				"myworkflow.t2flow" });
-	}
-
-	@Test(expected = InvalidOptionException.class)
-	public void provenanceButNoDatabase2() throws Exception {
-		new CommandLineOptionsImpl(new String[] { "-provenance", "-inmemory",
-				"myworkflow.t2flow" });
-	}
-
-	@Test
-	public void provenanceDatabase() throws Exception {
-		// should be no errors
-		new CommandLineOptionsImpl(new String[] { "-provenance", "-embedded",
-				"myworkflow.t2flow" });
-		new CommandLineOptionsImpl(new String[] { "-provenance", "-clientserver",
-				"myworkflow.t2flow" });
-		new CommandLineOptionsImpl(new String[] { "-provenance", "-dbproperties",
-				"dbproperties.properties", "myworkflow.t2flow" });
-	}
-
-	@Test
-	public void testHasInputDelimiter() throws Exception {
-		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
-				"-inputvalue","in1","1,2,3","-inputdelimiter","in1",",","-inputdelimiter","in2",",","myworkflow.t2flow" });
-		assertTrue(options.hasDelimiterFor("in1"));
-		assertTrue(options.hasDelimiterFor("in2"));
-		assertFalse(options.hasDelimiterFor("in3"));
-	}
-
-	@Test(expected = InvalidOptionException.class)
-	public void testInputDelimiterInvalidWithInputDoc() throws Exception {
-		new CommandLineOptionsImpl(new String[] {
-				"-inputdoc","doc.xml","-inputdelimiter","in1",",","myworkflow.t2flow" });
-	}
-
-
-	@Test
-	public void testInputDelimiter() throws Exception {
-		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
-				"-inputvalue","in1","1,2,3","-inputdelimiter","in1",",","-inputdelimiter","in2","!","myworkflow.t2flow" });
-		assertEquals(",",options.inputDelimiter("in1"));
-		assertEquals("!",options.inputDelimiter("in2"));
-		assertNull(options.inputDelimiter("in3"));
-	}
-
-	@Test
-	public void testInMemory() throws Exception {
-		CommandLineOptions handler = new CommandLineOptionsImpl(new String[] {
-				"-inmemory", "myworkflow.t2flow" });
-		assertTrue(handler.hasOption("inmemory"));
-	}
-
-	@Test
-	public void testEmbedded() throws Exception {
-		CommandLineOptions handler = new CommandLineOptionsImpl(new String[] {
-				"-embedded", "myworkflow.t2flow" });
-		assertTrue(handler.hasOption("embedded"));
-	}
-
-	@Test
-	public void testClientServer() throws Exception {
-		CommandLineOptions handler = new CommandLineOptionsImpl(new String[] {
-				"-clientserver", "myworkflow.t2flow" });
-		assertTrue(handler.hasOption("clientserver"));
-	}
-
-	@Test(expected = InvalidOptionException.class)
-	public void testInvalidEmbeddedAndClientServer() throws Exception {
-		new CommandLineOptionsImpl(new String[] { "-clientserver", "-embedded",
-				"myworkflow.t2flow" });
-	}
-
-	@Test(expected = InvalidOptionException.class)
-	public void testInvalidEmbeddedAndMemory() throws Exception {
-		new CommandLineOptionsImpl(new String[] { "-embedded", "-inmemory",
-				"myworkflow.t2flow" });
-	}
-
-	@Test(expected = InvalidOptionException.class)
-	public void testInvalidClientServerAndInMemory() throws Exception {
-		new CommandLineOptionsImpl(new String[] { "-clientserver", "-inmemory",
-				"myworkflow.t2flow" });
-	}
-
-	@Test
-	public void isInMemory() throws Exception {
-		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
-				"-inmemory", "myworkflow.t2flow" });
-
-		assertTrue(options.isInMemory());
-		assertFalse(options.isClientServer());
-		assertFalse(options.isEmbedded());
-	}
-
-	@Test
-	public void isClientServer() throws Exception {
-		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
-				"-clientserver", "myworkflow.t2flow" });
-
-		assertTrue(options.isClientServer());
-		assertFalse(options.isInMemory());
-		assertFalse(options.isEmbedded());
-	}
-
-	@Test
-	public void hasLogFile() throws Exception {
-		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
-				"-logfile","/tmp/logging", "myworkflow.t2flow" });
-
-		assertTrue(options.hasLogFile());
-		assertEquals("/tmp/logging", options.getLogFile());
-	}
-
-	@Test(expected = InvalidOptionException.class)
-	@SuppressWarnings("unused")
-	public void hasLogFileNotValidWithoutWorkflow() throws Exception{
-		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
-				"-logfile","/tmp/logging"});
-	}
-
-	@Test
-	public void isEmbedded() throws Exception {
-		CommandLineOptions options = new CommandLineOptionsImpl(new String[] {
-				"-embedded", "myworkflow.t2flow" });
-
-		assertTrue(options.isEmbedded());
-		assertFalse(options.isInMemory());
-		assertFalse(options.isClientServer());
-	}
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/9965dffe/taverna-commandline-product/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-commandline-product/pom.xml b/taverna-commandline-product/pom.xml
index 5751c3d..df940b5 100644
--- a/taverna-commandline-product/pom.xml
+++ b/taverna-commandline-product/pom.xml
@@ -5,7 +5,7 @@
 	<parent>
 		<groupId>org.apache.taverna.commandline</groupId>
 		<artifactId>taverna-commandline</artifactId>
-		<version>3.1.0.incubating-SNAPSHOT</version>
+		<version>3.1.0-incubating-SNAPSHOT</version>
 	</parent>
 	<artifactId>taverna-command-line-product</artifactId>
 	<name>Apache Taverna Commandline Product</name>
@@ -100,7 +100,7 @@
 						</frameworkConfiguration>
 						<frameworkConfiguration>
 							<name>org.osgi.framework.system.packages.extra</name>
-              <value>com.sun.org.apache.xml.internal.utils,com.sun.source.util,com.sun.source.tree,org.apache.log4j;version=${log4j.version},net.sf.taverna.t2.commandline.options;version=${project.parent.version}</value>
+              <value>com.sun.org.apache.xml.internal.utils,com.sun.source.util,com.sun.source.tree,org.apache.log4j;version=${log4j.version},org.apache.taverna.commandline.options;version=${project.parent.version}</value>
 						</frameworkConfiguration>
 						<frameworkConfiguration>
 							<name>org.osgi.framework.storage.clean</name>
@@ -431,7 +431,7 @@
 		<dependency>
 			<groupId>org.apache.jena</groupId>
 			<artifactId>jena-osgi</artifactId>
-			<version>2.12.2-SNAPSHOT</version>
+			<version>2.13.0</version>
 		</dependency>
 		<!-- slf4j implementation -->
                 <!-- The bundle "org.purl.wf4ever.robundle_0.3.1 " could not be resolved. Reason: Missing Constraint: Import-Package: org.slf4j; version="[1.7.0,2.0.0)"-->

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/9965dffe/taverna-commandline-tests/pom.xml
----------------------------------------------------------------------
diff --git a/taverna-commandline-tests/pom.xml b/taverna-commandline-tests/pom.xml
index 1fe77cd..b62b356 100644
--- a/taverna-commandline-tests/pom.xml
+++ b/taverna-commandline-tests/pom.xml
@@ -32,8 +32,9 @@
 		<dependency>
 			<groupId>org.apache.taverna.language</groupId>
 			<artifactId>taverna-scufl2-wfbundle</artifactId>
-			<version>${taverna.language.version}</version>
+			<version>0.15.0-incubating-SNAPSHOT</version>
 			<scope>test</scope>
+		 <type>jar</type>
 		</dependency>
 		<dependency>
 			<groupId>junit</groupId>
@@ -67,5 +68,12 @@
 			<version>1.1.2</version>
 			<scope>test</scope>
 		</dependency> -->
+	 <dependency>
+	  <groupId>org.apache.taverna.language</groupId>
+	  <artifactId>taverna-scufl2-api</artifactId>
+	  <version>0.15.0-incubating-SNAPSHOT</version>
+	  <scope>test</scope>
+	  <type>jar</type>
+	 </dependency>
 	</dependencies>
 </project>

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/9965dffe/taverna-commandline-tests/src/test/java/org/apache/taverna/commandline/TavernaCommandLineTest.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-tests/src/test/java/org/apache/taverna/commandline/TavernaCommandLineTest.java b/taverna-commandline-tests/src/test/java/org/apache/taverna/commandline/TavernaCommandLineTest.java
new file mode 100644
index 0000000..2ed7a11
--- /dev/null
+++ b/taverna-commandline-tests/src/test/java/org/apache/taverna/commandline/TavernaCommandLineTest.java
@@ -0,0 +1,485 @@
+/*******************************************************************************
+ * Copyright (C) 2012 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package org.apache.taverna.commandline;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.URI;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.comparator.NameFileComparator;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.apache.taverna.commandline.WorkflowTestSuite.Workflows;
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.scufl2.api.io.WorkflowBundleIO;
+import org.apache.taverna.scufl2.rdfxml.RDFXMLReader;
+
+/**
+ * Regression tests for Taverna Command Line Tool.
+ *
+ * @author David Withers
+ */
+@RunWith(WorkflowTestSuite.class)
+public class TavernaCommandLineTest {
+
+	private static String baseVersion = "2.4.0";
+	private static boolean baseVersionReleased = true;
+
+	private static String testVersion = "3.0.1-SNAPSHOT";
+	private static boolean testVersionReleased = false;
+	private static boolean testVersionSupportsScufl2 = true;
+
+	private static String script = "executeworkflow.sh";
+	private static String baseName = "taverna-commandline-" + baseVersion;
+	private static String testName = "taverna-command-line-" + testVersion;
+	private static String releasedLocation = "https://launchpad.net/taverna/t2/";
+	private static String unreleasedLocation = "http://build.mygrid.org.uk/ci/job/t3-taverna-commandline-product/lastSuccessfulBuild/net.sf.taverna.t2$taverna-commandline/artifact/net.sf.taverna.t2/taverna-commandline/";
+
+	private static String baseVersionLocation = (baseVersionReleased ? releasedLocation
+			: unreleasedLocation) + baseVersion + "/+download/" + baseName + ".zip";
+	private static String testVersionLocation = (testVersionReleased ? releasedLocation
+			: unreleasedLocation)
+			+ testVersion
+			+ "/"
+			+ testName
+			+ (testVersionReleased ? ".zip" : "-bin.zip");
+
+	private static String baseCommand;
+	private static String testCommand;
+
+	private static File buildDirectory;
+
+	private File workflowDirectory;
+	private File baseOutput;
+	private File testOutput;
+	private boolean secure;
+	private List<File> inputs;
+	private String ignorePort;
+	private String message;
+
+	public TavernaCommandLineTest(File workflowDirectory) throws Exception {
+		this.workflowDirectory = workflowDirectory;
+		if (buildDirectory == null) {
+			String buildDirectoryLocation = System.getProperty("buildDirectory");
+			if (buildDirectoryLocation == null) {
+				buildDirectoryLocation = System.getProperty("user.dir")
+						+ System.getProperty("file.separator") + "target";
+			}
+			buildDirectory = new File(buildDirectoryLocation);
+			buildDirectory.mkdirs();
+		}
+		if (baseCommand == null) {
+			File commandDirectory = new File(buildDirectory, baseName);
+			if (!commandDirectory.exists()) {
+				System.out.println("Fetching " + baseName);
+				fetchTaverna(baseVersionLocation, baseName);
+			}
+			baseCommand = new File(baseName, script).getPath();
+		}
+		if (testCommand == null) {
+			File commandDirectory = new File(buildDirectory, testName);
+			if (!commandDirectory.exists()) {
+				System.out.println("Fetching " + testName);
+				fetchTaverna(testVersionLocation, testName);
+			}
+			testCommand = new File(testName, script).getPath();
+		}
+		File outputsDirectory = new File(buildDirectory, "test-outputs");
+		baseOutput = new File(outputsDirectory, workflowDirectory.getName() + "-" + baseVersion);
+		testOutput = new File(outputsDirectory, workflowDirectory.getName() + "-" + testVersion);
+		secure = workflowDirectory.getName().startsWith("secure");
+		inputs = getInputs();
+		ignorePort = getIgnorePort();
+		message = "Running {0} with version {1}";
+	}
+
+	@Workflows
+	public static List<File> workflows() {
+		List<File> workflows = new ArrayList<File>();
+		for (File workflowDirectory : getResources("workflows")) {
+			workflows.add(workflowDirectory);
+		}
+		for (File workflowDirectory : getResources("myexperiment")) {
+			workflows.add(workflowDirectory);
+		}
+		return workflows;
+	}
+
+	@Before
+	public void setup() throws Exception {
+		if (!baseOutput.exists()) {
+			if (baseVersion.equals("2.3.0") && workflowDirectory.getName().equals("tool"))
+				return;// version 2.3.0 is missing tool plugin
+			String workflow = getWorkflow().toASCIIString();
+			System.out.println(MessageFormat.format(message, workflow, baseVersion)
+					+ (inputs.size() > 0 ? " using input values" : ""));
+			runWorkflow(baseCommand, workflow, baseOutput, true, secure, false);
+			assertTrue(String.format("No output produced for %s", workflowDirectory.getName()),
+					baseOutput.exists());
+		}
+	}
+
+	public boolean testExcluded() {
+		// version 3.0.0 is missing biomoby activity
+		if (testVersion.startsWith("3.") && workflowDirectory.getName().contains("biomoby"))
+			return true;
+		// version 3.0.0 is missing tool activity
+		if (testVersion.startsWith("3.")
+				&& workflowDirectory.getName().equals("unix_external_tools_with_zip_and_unzip"))
+			return true;
+		if (testVersion.startsWith("3.")
+				&& workflowDirectory.getName().equals("unix_numerically_adding_two_values"))
+			return true;
+		if (testVersion.startsWith("3.")
+				&& workflowDirectory.getName().equals("unix_tool_service_using_string_replacement"))
+			return true;
+		// version 3.0.0 is missing looping configuration
+		if (testVersion.startsWith("3.")
+				&& workflowDirectory.getName().equals("ebi_interproscan_newservices"))
+			return true;
+		if (testVersion.startsWith("3.")
+				&& workflowDirectory.getName().equals("biomartandembossanalysis"))
+			return true;
+		return false;
+	}
+
+	@Test
+	public void testWorkflowWithoutInputs() throws Exception {
+		assumeTrue(!testExcluded());
+		assumeTrue(baseOutput.exists());
+		assumeTrue(inputs.isEmpty());
+		FileUtils.deleteDirectory(testOutput);
+		String workflow = getWorkflow().toASCIIString();
+		System.out.println(MessageFormat.format(message, workflow, testVersion));
+		runWorkflow(testCommand, workflow, testOutput, true, secure, false);
+		assertTrue(String.format("No output produced for %s", workflowDirectory.getName()),
+				testOutput.exists());
+		assertOutputsEquals(baseOutput, testOutput);
+	}
+
+	@Test
+	public void testWorkflowWithInputValues() throws Exception {
+		assumeTrue(!testExcluded());
+		assumeTrue(baseOutput.exists());
+		assumeTrue(inputs.size() > 0);
+		FileUtils.deleteDirectory(testOutput);
+		String workflow = getWorkflow().toASCIIString();
+		System.out.println(MessageFormat.format(message, workflow, testVersion)
+				+ " using input values");
+		runWorkflow(testCommand, workflow, testOutput, true, secure, false);
+		assertTrue(String.format("No output produced for %s", workflowDirectory.getName()),
+				testOutput.exists());
+		assertOutputsEquals(baseOutput, testOutput);
+	}
+
+	@Test
+	public void testWorkflowWithInputFiles() throws Exception {
+		assumeTrue(!testExcluded());
+		assumeTrue(baseOutput.exists());
+		assumeTrue(inputs.size() > 0);
+		FileUtils.deleteDirectory(testOutput);
+		String workflow = getWorkflow().toASCIIString();
+		System.out.println(MessageFormat.format(message, workflow, testVersion)
+				+ " using input files");
+		runWorkflow(testCommand, workflow, testOutput, false, secure, false);
+		assertTrue(String.format("No output produced for %s", workflowDirectory.getName()),
+				testOutput.exists());
+		assertOutputsEquals(baseOutput, testOutput);
+	}
+
+	@Test
+	@Ignore
+	public void testWorkflowWithDatabase() throws Exception {
+		assumeTrue(!testExcluded());
+		assumeTrue(baseOutput.exists());
+		assumeTrue(inputs.size() > 0);
+		FileUtils.deleteDirectory(testOutput);
+		String workflow = getWorkflow().toASCIIString();
+		System.out
+				.println(MessageFormat.format(message, workflow, testVersion) + " using database");
+		runWorkflow(testCommand, workflow, testOutput, true, secure, true);
+		assertTrue(String.format("No output produced for %s", workflowDirectory.getName()),
+				testOutput.exists());
+		assertOutputsEquals(baseOutput, testOutput);
+	}
+
+	@Test
+	public void testScufl2Workflow() throws Exception {
+		assumeTrue(!testExcluded());
+		assumeTrue(baseOutput.exists());
+		assumeTrue(testVersionSupportsScufl2);
+
+		FileUtils.deleteDirectory(testOutput);
+		String workflow = getScufl2Workflow().toASCIIString();
+		System.out.println(MessageFormat.format(message, workflow, testVersion)
+				+ (inputs.size() > 0 ? " using input values" : ""));
+		runWorkflow(testCommand, workflow, testOutput, true, secure, true);
+		assertTrue(String.format("No output produced for %s", workflowDirectory.getName()),
+				testOutput.exists());
+		assertOutputsEquals(baseOutput, testOutput);
+	}
+
+	private synchronized void runWorkflow(String command, String workflow, File outputsDirectory,
+			boolean inputValues, boolean secure, boolean database) throws Exception {
+		ProcessBuilder processBuilder = new ProcessBuilder("sh", command);
+		processBuilder.redirectErrorStream(true);
+		processBuilder.directory(buildDirectory);
+		List<String> args = processBuilder.command();
+		for (File input : inputs) {
+			if (inputValues) {
+				args.add("-inputvalue");
+				args.add(input.getName());
+				args.add(IOUtils.toString(new FileReader(input)));
+			} else {
+				args.add("-inputfile");
+				args.add(input.getName());
+				args.add(input.getAbsolutePath());
+			}
+		}
+		args.add("-outputdir");
+		args.add(outputsDirectory.getPath());
+		if (secure) {
+			args.add("-cmdir");
+			args.add(getClass().getResource("/security").getFile());
+			args.add("-cmpassword");
+		}
+		if (database) {
+			args.add("-embedded");
+		}
+		args.add(workflow);
+		Process process = processBuilder.start();
+		if (secure) {
+			PrintStream outputStream = new PrintStream(process.getOutputStream());
+			outputStream.println("test");
+			outputStream.flush();
+		}
+		waitFor(process);
+	}
+
+	private URI getWorkflow() throws Exception {
+		File workflow = new File(workflowDirectory, workflowDirectory.getName() + ".t2flow");
+		if (!workflow.exists()) {
+			workflow = new File(workflowDirectory, workflowDirectory.getName() + ".url");
+			return new URI(IOUtils.toString(new FileReader(workflow)));
+		}
+		return workflow.toURI();
+	}
+
+	private URI getScufl2Workflow() throws Exception {
+		File workflow = new File(buildDirectory, workflowDirectory.getName() + ".wfbundle");
+		// if (!workflow.exists()) {
+		WorkflowBundleIO workflowBundleIO = new WorkflowBundleIO();
+		WorkflowBundle bundle = workflowBundleIO.readBundle(getWorkflow().toURL(), null);
+		workflowBundleIO.writeBundle(bundle, workflow,
+				RDFXMLReader.APPLICATION_VND_TAVERNA_SCUFL2_WORKFLOW_BUNDLE);
+		// }
+		return workflow.toURI();
+	}
+
+	private synchronized int waitFor(Process process) throws IOException {
+		while (true) {
+			try {
+				wait(500);
+			} catch (InterruptedException e) {
+			}
+			IOUtils.copy(process.getInputStream(), System.out);
+			try {
+				return process.exitValue();
+			} catch (IllegalThreadStateException e) {
+			}
+		}
+	}
+
+	private void assertOutputsEquals(File directory1, File directory2) {
+		File[] directory1Files = directory1.listFiles();
+		File[] directory2Files = directory2.listFiles();
+		// assert directories contain same number of files
+		assertEquals(String.format("%s has %s files but %s has %s files", directory1.getName(),
+				directory1Files.length, directory2.getName(), directory2Files.length),
+				directory1Files.length, directory2Files.length);
+		// sort files in directory
+		Arrays.sort(directory1Files, NameFileComparator.NAME_SYSTEM_COMPARATOR);
+		Arrays.sort(directory2Files, NameFileComparator.NAME_SYSTEM_COMPARATOR);
+		for (int i = 0; i < directory1Files.length; i++) {
+			assertFilesEqual(directory1Files[i], directory2Files[i], !directory1Files[i].getName()
+					.equals(ignorePort));
+		}
+	}
+
+	private void assertDirectoriesEquals(File directory1, File directory2, boolean checkFileContents) {
+		if (directory1.exists()) {
+			assertTrue(String.format("%s exists but %s does not", directory1, directory2),
+					directory2.exists());
+		} else {
+			assertFalse(String.format("%s does not exists but %s does", directory1, directory2),
+					directory2.exists());
+		}
+		File[] directory1Files = directory1.listFiles();
+		File[] directory2Files = directory2.listFiles();
+		// assert directories contain same number of files
+		assertEquals(String.format("%s has %s files but %s has %s files", directory1.getName(),
+				directory1Files.length, directory2.getName(), directory2Files.length),
+				directory1Files.length, directory2Files.length);
+		// sort files in directory
+		Arrays.sort(directory1Files, NameFileComparator.NAME_SYSTEM_COMPARATOR);
+		Arrays.sort(directory2Files, NameFileComparator.NAME_SYSTEM_COMPARATOR);
+		for (int i = 0; i < directory1Files.length; i++) {
+			assertFilesEqual(directory1Files[i], directory2Files[i], checkFileContents);
+		}
+	}
+
+	private void assertFilesEqual(File file1, File file2, boolean checkFileContents) {
+		if (file1.isHidden()) {
+			assertTrue(String.format("%s is hidden but %s is not", file1, file2), file2.isHidden());
+		} else {
+			assertFalse(String.format("%s is not hidden but %s is", file1, file2), file2.isHidden());
+			assertEquals(file1.getName(), file2.getName());
+			if (file1.isDirectory()) {
+				assertTrue(String.format("%s is a directory but %s is not", file1, file2),
+						file2.isDirectory());
+				assertDirectoriesEquals(file1, file2, checkFileContents);
+			} else {
+				assertFalse(String.format("%s is not a directory but %s is", file1, file2),
+						file2.isDirectory());
+				if (isZipFile(file1)) {
+					assertZipFilesEqual(file1, file2);
+				} else if (checkFileContents) {
+					assertEquals(String.format("%s is a different length to %s", file1, file2),
+							file1.length(), file2.length());
+					try {
+						byte[] byteArray1 = IOUtils.toByteArray(new FileReader(file1));
+						byte[] byteArray2 = IOUtils.toByteArray(new FileReader(file2));
+						assertArrayEquals(String.format("%s != %s", file1, file2), byteArray1,
+								byteArray2);
+					} catch (FileNotFoundException e) {
+						fail(e.getMessage());
+					} catch (IOException e) {
+						fail(e.getMessage());
+					}
+				}
+			}
+		}
+	}
+
+	private void assertZipFilesEqual(File file1, File file2) {
+		ZipFile zipFile1 = null;
+		ZipFile zipFile2 = null;
+		try {
+			zipFile1 = new ZipFile(file1);
+			zipFile2 = new ZipFile(file2);
+		} catch (Exception e) {
+			assertTrue(String.format("%s and %s are not both zip files"), zipFile1 == null);
+		}
+		if (zipFile1 != null && zipFile2 != null) {
+			Enumeration<? extends ZipEntry> entries1 = zipFile1.entries();
+			Enumeration<? extends ZipEntry> entries2 = zipFile2.entries();
+			while (entries1.hasMoreElements()) {
+				assertTrue(entries2.hasMoreElements());
+				ZipEntry zipEntry1 = entries1.nextElement();
+				ZipEntry zipEntry2 = entries2.nextElement();
+				assertEquals(
+						String.format("%s and %s are not both directories", zipEntry1, zipEntry2),
+						zipEntry1.isDirectory(), zipEntry2.isDirectory());
+				assertEquals(String.format("%s and %s have different names", zipEntry1, zipEntry2),
+						zipEntry1.getName(), zipEntry2.getName());
+				assertEquals(String.format("%s and %s have different sizes", zipEntry1, zipEntry2),
+						zipEntry1.getSize(), zipEntry2.getSize());
+				try {
+					byte[] byteArray1 = IOUtils.toByteArray(zipFile1.getInputStream(zipEntry1));
+					byte[] byteArray2 = IOUtils.toByteArray(zipFile2.getInputStream(zipEntry2));
+					assertArrayEquals(String.format("%s != %s", zipEntry1, zipEntry2), byteArray1,
+							byteArray2);
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+			assertFalse(entries2.hasMoreElements());
+		}
+	}
+
+	private boolean isZipFile(File file) {
+		try {
+			new ZipFile(file);
+			return true;
+		} catch (Exception e) {
+			return false;
+		}
+	}
+
+	private static File[] getResources(String directory) {
+		return new File(TavernaCommandLineTest.class.getResource("/" + directory).getFile())
+				.listFiles();
+	}
+
+	private List<File> getInputs() {
+		File inputsDirectory = new File(workflowDirectory, "inputs");
+		if (inputsDirectory.exists() && inputsDirectory.isDirectory()) {
+			return Arrays.asList(inputsDirectory.listFiles());
+		}
+		return Collections.emptyList();
+	}
+
+	private String getIgnorePort() throws Exception {
+		File ignorePort = new File(workflowDirectory, "ignorePort");
+		if (ignorePort.exists()) {
+			return IOUtils.toString(new FileReader(ignorePort));
+		}
+		return "";
+	}
+
+	private void fetchTaverna(String location, String name) throws Exception {
+		File zipFile = new File(buildDirectory, name + ".zip");
+		IOUtils.copy(new URL(location).openStream(), new FileOutputStream(zipFile));
+		ProcessBuilder processBuilder = new ProcessBuilder("unzip", "-q", name);
+		processBuilder.redirectErrorStream(true);
+		processBuilder.directory(buildDirectory);
+		System.out.println(processBuilder.command());
+		Process process = processBuilder.start();
+		waitFor(process);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/9965dffe/taverna-commandline-tests/src/test/java/org/apache/taverna/commandline/WorkflowTestRunner.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-tests/src/test/java/org/apache/taverna/commandline/WorkflowTestRunner.java b/taverna-commandline-tests/src/test/java/org/apache/taverna/commandline/WorkflowTestRunner.java
new file mode 100644
index 0000000..7fca90e
--- /dev/null
+++ b/taverna-commandline-tests/src/test/java/org/apache/taverna/commandline/WorkflowTestRunner.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (C) 2012 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package org.apache.taverna.commandline;
+
+import java.io.File;
+import java.util.List;
+
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.Statement;
+
+/**
+ * Test runner for running workflows.
+ *
+ * @author David Withers
+ */
+public class WorkflowTestRunner extends BlockJUnit4ClassRunner {
+	private File workflow;
+
+	public WorkflowTestRunner(Class<?> type, File workflow) throws InitializationError {
+		super(type);
+		this.workflow = workflow;
+	}
+
+	@Override
+	public Object createTest() throws Exception {
+		return getTestClass().getOnlyConstructor().newInstance(workflow);
+	}
+
+	@Override
+	protected String getName() {
+		return String.format("[%s]", workflow.getName());
+	}
+
+	@Override
+	protected String testName(final FrameworkMethod method) {
+		return String.format("%s[%s]", method.getName(), workflow.getName());
+	}
+
+	@Override
+	protected void validateConstructor(List<Throwable> errors) {
+		validateOnlyOneConstructor(errors);
+	}
+
+	@Override
+	protected Statement classBlock(RunNotifier notifier) {
+		return childrenInvoker(notifier);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-commandline/blob/9965dffe/taverna-commandline-tests/src/test/java/org/apache/taverna/commandline/WorkflowTestSuite.java
----------------------------------------------------------------------
diff --git a/taverna-commandline-tests/src/test/java/org/apache/taverna/commandline/WorkflowTestSuite.java b/taverna-commandline-tests/src/test/java/org/apache/taverna/commandline/WorkflowTestSuite.java
new file mode 100644
index 0000000..a441aea
--- /dev/null
+++ b/taverna-commandline-tests/src/test/java/org/apache/taverna/commandline/WorkflowTestSuite.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (C) 2012 The University of Manchester
+ *
+ *  Modifications to the initial code base are copyright of their
+ *  respective authors, or their employers as appropriate.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public License
+ *  as published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ ******************************************************************************/
+package org.apache.taverna.commandline;
+
+import java.io.File;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.runner.Runner;
+import org.junit.runners.Suite;
+import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.TestClass;
+
+/**
+ * Test suite for running workflows specified by a method annotated by &#064;Workflows.
+ *
+ * @author David Withers
+ */
+public class WorkflowTestSuite extends Suite {
+
+	@Retention(RetentionPolicy.RUNTIME)
+	@Target(ElementType.METHOD)
+	public static @interface Workflows {}
+
+	private ArrayList<Runner> runners = new ArrayList<Runner>();
+
+	public WorkflowTestSuite(Class<?> klass) throws Throwable {
+		super(klass, Collections.<Runner>emptyList());
+		for (File workflow : getWorkflows(getTestClass())) {
+			runners.add(new WorkflowTestRunner(getTestClass().getJavaClass(), workflow));
+		}
+	}
+
+	@Override
+	protected List<Runner> getChildren() {
+		return runners;
+	}
+
+	@SuppressWarnings("unchecked")
+	private List<File> getWorkflows(TestClass klass) throws Throwable {
+		return (List<File>) getWorkflowsMethod(klass).invokeExplosively(null);
+	}
+
+	public FrameworkMethod getWorkflowsMethod(TestClass testClass) throws Exception {
+		List<FrameworkMethod> methods = testClass.getAnnotatedMethods(Workflows.class);
+		for (FrameworkMethod method : methods) {
+			int modifiers = method.getMethod().getModifiers();
+			if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)) {
+				return method;
+			}
+		}
+		throw new Exception("No public static Workflows annotated method on class " + testClass.getName());
+	}
+
+}